#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#------------------------------------------------------------------------
#
# python modules
#
#------------------------------------------------------------------------
import os
import re
import time
from gettext import gettext as _
#------------------------------------------------------------------------
#
# GRAMPS modules
#
#------------------------------------------------------------------------
from PluginUtils import register_text_doc
import ImgManip
import tarfile
import const
import Errors
import BaseDoc
import QuestionDialog
import Mime
import Utils
#------------------------------------------------------------------------
#
# Constant regular expressions
#
#------------------------------------------------------------------------
t_header_line_re = re.compile(
r"(.*)
(.*)(.*)",
re.DOTALL|re.IGNORECASE|re.MULTILINE)
t_keyword_line_re = re.compile(
r'(.*name="keywords"\s+content=")([^\"]*)(".*)$',
re.DOTALL|re.IGNORECASE|re.MULTILINE)
#------------------------------------------------------------------------
#
# Default template
#
#------------------------------------------------------------------------
_top = [
'\n',
'\n',
'\n',
' \n',
' \n',
' \n',
' \n',
' \n',
'\n',
'\n',
' \n'
]
_bottom = [
' \n',
'\n',
'\n'
]
#------------------------------------------------------------------------
#
# HtmlDoc
#
#------------------------------------------------------------------------
class HtmlDoc(BaseDoc.BaseDoc):
def __init__(self,styles,type,template,orientation,source=None):
BaseDoc.BaseDoc.__init__(self,styles,BaseDoc.PaperStyle("",0,0),template,None)
self.year = time.localtime(time.time())[0]
self.ext = '.html'
if source == None:
self.meta = ""
self.copyright = 'Copyright © %d' % (self.year)
self.map = None
self.f = None
self.filename = None
self.top = []
self.bottom = []
self.base = ""
self.load_template()
self.build_header()
self.style_declaration = None
self.image_dir = "images"
else:
self.meta = source.meta
self.owner = source.owner
self.copyright = 'Copyright © %d %s' % (self.year,self.owner)
self.map = source.map
self.f = None
self.filename = source.filename
self.template = None
self.top = source.top
self.bottom = source.bottom
self.base = source.base
self.fix_title(source.file_header)
self.style_declaration = source.style_declaration
self.table_styles = source.table_styles;
self.cell_styles = source.cell_styles;
self.image_dir = source.image_dir
def set_extension(self,val):
if val[0] != '.':
val = "." + val
self.ext = val
def set_owner(self,owner):
BaseDoc.BaseDoc.set_owner(self,owner)
self.copyright = 'Copyright © %d %s' % (self.year,self.owner)
def set_image_dir(self,dirname):
self.image_dir = dirname
def set_keywords(self,keywords):
self.meta = ",".join(keywords)
def load_tpkg(self):
start = re.compile(r"")
stop = re.compile(r"")
top_add = 1
bottom_add = 0
archive = tarfile.open(self.template)
for tarinfo in archive:
self.map[tarinfo.name] = archive.extractfile(tarinfo)
archive.close()
templateFile = self.map['template.html']
while 1:
line = templateFile.readline()
if line == '':
break
if top_add == 1:
self.top.append(line)
match = start.search(line)
if match:
top_add = 0
elif bottom_add == 0:
match = stop.search(line)
if match != None:
bottom_add = 1
self.bottom.append(line)
else:
self.bottom.append(line)
templateFile.close()
if top_add == 1:
mymsg = _("The marker '' was not in the template")
QuestionDialog.ErrorDialog(_("Template Error"),mymsg)
def load_html(self):
start = re.compile(r"")
stop = re.compile(r"")
top_add = 1
bottom_add = 0
templateFile = open(self.template,"r")
for line in templateFile.readlines():
if top_add == 1:
self.top.append(line)
match = start.search(line)
if match:
top_add = 0
elif bottom_add == 0:
match = stop.search(line)
if match != None:
bottom_add = 1
self.bottom.append(line)
else:
self.bottom.append(line)
templateFile.close()
if top_add == 1:
mymsg = _("The marker '' was not in the template")
QuestionDialog.ErrorDialog(_("Template Error"),mymsg)
def load_template(self):
if self.template:
try:
if self.template[-4:] == 'tpkg':
self.load_tpkg()
else:
self.load_html()
except IOError,msg:
mymsg = _("Could not open %s\nUsing the default template") % \
self.template
QuestionDialog.WarningDialog(mymsg,str(msg))
self.bottom = _bottom
self.top = _top
except:
mymsg = _("Could not open %s\nUsing the default template") % \
self.template
QuestionDialog.WarningDialog(mymsg)
self.bottom = _bottom
self.top = _top
else:
self.bottom = _bottom
self.top = _top
def process_line(self,line):
l = line.replace('$VERSION',const.version)
return l.replace('$COPYRIGHT',self.copyright)
def open(self,filename):
(r,e) = os.path.splitext(filename)
if e == self.ext:
self.filename = filename
else:
self.filename = filename + self.ext
self.base = os.path.dirname(self.filename)
try:
self.f = open(self.filename,"w")
except IOError,msg:
errmsg = "%s\n%s" % (_("Could not create %s") % self.filename, msg)
raise Errors.ReportError(errmsg)
except:
raise Errors.ReportError(_("Could not create %s") % self.filename)
if self.meta:
match = t_keyword_line_re.match(self.file_header)
if match:
g = match.groups()
line = "%s%s%s" % (g[0],self.meta,g[2])
else:
line = self.file_header
else:
line = self.file_header
self.f.write(line)
if not self.style_declaration:
self.build_style_declaration()
self.f.write(self.style_declaration)
def build_header(self):
self.fix_title("".join(self.top))
def fix_title(self,msg=None):
if msg == None:
match = t_header_line_re.match(self.file_header)
else:
match = t_header_line_re.match(msg)
if match:
m = match.groups()
if self.title:
msg = self.title
else:
msg = m[1]
self.file_header = '%s%s%s\n' % (m[0],msg,m[2])
else:
self.file_header = self.top
self.file_header = self.process_line(self.file_header)
def build_style_declaration(self):
text = ['')
self.style_declaration = '\n'.join(text)
def close(self):
for line in self.bottom:
self.f.write(self.process_line(line))
self.f.close()
self.write_support_files()
if self.print_req:
apptype = 'text/html'
app = Mime.get_application(apptype)
Utils.launch(app[0],self.filename)
def write_support_files(self):
if self.map:
for name in self.map.keys():
if name == 'template.html':
continue
fname = '%s/%s' % (self.base,name)
try:
f = open(fname, 'wb')
f.write(self.map[name].read())
f.close()
except IOError,msg:
errmsg = "%s\n%s" % (_("Could not create %s") % fname, msg)
raise Errors.ReportError(errmsg)
except:
raise Errors.ReportError(_("Could not create %s") % fname)
def add_media_object(self,name,pos,x,y,alt=''):
self.empty = 0
size = int(max(x,y) * float(150.0/2.54))
refname = "is%s" % os.path.basename(name)
if self.image_dir:
imdir = "%s/%s" % (self.base,self.image_dir)
else:
imdir = self.base
if not os.path.isdir(imdir):
try:
os.mkdir(imdir)
except:
return
try:
img = ImgManip.ImgManip(name)
img.jpg_thumbnail("%s/%s" % (imdir,refname),size,size)
except:
return
if pos == "right":
xtra = ' align="right"'
elif pos == "left" :
xtra = ' align="left"'
else:
xtra = ''
imgsize = img.size()
if imgsize[0] > imgsize[1]:
size_str = "width"
else:
size_str = "height"
if self.image_dir:
self.f.write('\n' % \
(self.image_dir,refname,size_str,size,alt,xtra))
else:
self.f.write('\n'
% (refname,size_str,size,alt,xtra))
def start_table(self,name,style):
self.tbl = self.table_styles[style]
self.f.write('\n')
def end_table(self):
self.f.write('
\n')
def start_row(self):
self.col = 0
self.f.write('\n')
def end_row(self):
self.f.write('
\n')
def start_cell(self,style_name,span=1):
self.empty = 1
self.f.write(' 1:
self.f.write(' colspan="' + str(span) + '"')
self.col = self.col + 1
else:
self.f.write(' width="')
self.f.write(str(self.tbl.get_column_width(self.col)))
self.f.write('%"')
self.f.write(' class="')
self.f.write(style_name)
self.f.write('">')
self.col = self.col + 1
def end_cell(self):
self.f.write(' | \n')
def start_paragraph(self,style_name,leader=None):
self.f.write('')
if leader != None:
self.f.write(leader)
self.f.write(' ')
def end_paragraph(self):
if self.empty == 1:
self.f.write(' ')
self.empty = 0
self.f.write('
\n')
def start_bold(self):
self.f.write('')
def end_bold(self):
self.f.write('')
def write_note(self,text,format,style_name):
if format == 1:
self.f.write('' % style_name)
self.write_text(text)
self.f.write('
')
elif format == 0:
for line in text.split('\n\n'):
self.start_paragraph(style_name)
self.write_text(line.strip().replace('\n',' '))
self.end_paragraph()
def write_text(self,text,mark=None):
text = text.replace('&','&'); # Must be first
text = text.replace('<','<');
text = text.replace('>','>');
text = text.replace('\n','
')
text = text.replace('<super>','')
text = text.replace('</super>','')
if text != "":
self.empty = 0
self.f.write(text)
#------------------------------------------------------------------------
#
# Register the document generator with the GRAMPS plugin system
#
#------------------------------------------------------------------------
print_label = None
try:
prog = Mime.get_application("text/html")
mtype = Mime.get_description("text/html")
if Utils.search_for(prog[0]):
print_label=_("Open in %s") % prog[1]
else:
print_label=None
if mtype == _("unknown"):
mtype = _('HTML')
register_text_doc(mtype,HtmlDoc,1,0,1,".html", print_label)
except:
register_text_doc(_('HTML'),HtmlDoc,1,0,1,".html", None)