# # Gramps - a GTK+/GNOME based genealogy program # # Copyright (C) 2000-2004 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$ import os import string import re import time import gnome.ui import Plugins import ImgManip import TarFile import const import Errors import BaseDoc import QuestionDialog import GrampsMime from gettext import gettext as _ 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 = string.join(keywords,",") def load_tpkg(self): start = re.compile(r"") stop = re.compile(r"") top_add = 1 bottom_add = 0 tf = TarFile.ReadTarFile(self.template,None) self.map = tf.extract_files() 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") gnome.ui.GnomeErrorDialog(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") gnome.ui.GnomeErrorDialog(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 = string.replace(line,'$VERSION',const.version) return string.replace(l,'$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(string.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 = string.join(text,'\n') 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 = GrampsMime.get_application_(apptype) os.environ["FILE"] = self.filename os.system ('%s "$FILE" &' % app[0]) 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('%s\n' % \ (self.image_dir,refname,size_str,size,alt,xtra)) else: self.f.write('%s\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): text = string.replace(text,'&','&'); # Must be first text = string.replace(text,'<','<'); text = string.replace(text,'>','>'); text = string.replace(text,'\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 # #------------------------------------------------------------------------ try: import Utils prog = GrampsMime.get_application("text/html") type = GrampsMime.get_description("text/html") if Utils.search_for(prog[0]): print_label=_("Open in %s") % prog[1] else: print_label=None Plugins.register_text_doc(type,HtmlDoc,1,0,1,".html", print_label) except: Plugins.register_text_doc('HTML',HtmlDoc,1,0,1,".html", None)