2002-10-20 19:55:16 +05:30
|
|
|
#
|
|
|
|
# Gramps - a GTK+/GNOME based genealogy program
|
|
|
|
#
|
2006-03-01 05:56:29 +05:30
|
|
|
# Copyright (C) 2000-2006 Donald N. Allingham
|
2009-03-19 07:54:29 +05:30
|
|
|
# Copyright (C) 2007-2009 Brian G. Matherly
|
2010-09-24 02:33:15 +05:30
|
|
|
# Copyright (C) 2009-2010 Benny Malengier <benny.malengier@gramps-project.org>
|
2010-01-14 00:10:55 +05:30
|
|
|
# Copyright (C) 2010 Peter Landgren
|
2010-09-24 02:33:15 +05:30
|
|
|
# Copyright (C) 2010 Tim Lyons
|
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
#
|
|
|
|
# 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
|
|
|
|
#
|
|
|
|
|
2008-02-18 15:39:50 +05:30
|
|
|
# $Id:HtmlDoc.py 9912 2008-01-22 09:17:46Z acraphae $
|
2003-11-14 00:20:01 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
|
|
|
|
"""
|
|
|
|
Report output generator for html documents, based on Html and HtmlBackend
|
|
|
|
"""
|
|
|
|
|
2005-12-06 12:08:09 +05:30
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# python modules
|
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
2002-10-20 19:55:16 +05:30
|
|
|
import os
|
2009-06-09 04:49:37 +05:30
|
|
|
import shutil
|
2002-10-20 19:55:16 +05:30
|
|
|
import time
|
2010-01-18 10:12:17 +05:30
|
|
|
from gen.ggettext import gettext as _
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2005-12-06 12:08:09 +05:30
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# GRAMPS modules
|
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
2002-10-20 19:55:16 +05:30
|
|
|
import ImgManip
|
|
|
|
import const
|
2009-05-31 20:29:56 +05:30
|
|
|
from gen.plug.docgen import BaseDoc, TextDoc, FONT_SANS_SERIF
|
2010-09-24 02:33:15 +05:30
|
|
|
from libhtmlbackend import HtmlBackend, process_spaces
|
2009-06-09 04:49:37 +05:30
|
|
|
from libhtml import Html
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
2009-06-09 04:49:37 +05:30
|
|
|
# Set up logging
|
2002-10-20 19:55:16 +05:30
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
2009-06-09 04:49:37 +05:30
|
|
|
import logging
|
|
|
|
LOG = logging.getLogger(".htmldoc")
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-06-11 18:31:27 +05:30
|
|
|
_TEXTDOCSCREEN = 'grampstextdoc.css'
|
2009-06-09 04:49:37 +05:30
|
|
|
_HTMLSCREEN = 'grampshtml.css'
|
2009-06-11 18:31:27 +05:30
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# HtmlDoc
|
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
2009-06-06 15:19:40 +05:30
|
|
|
class HtmlDoc(BaseDoc, TextDoc):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""Implementation of the BaseDoc and TextDoc gen.plug.docgen api for the
|
|
|
|
creation of Html files. This is achieved by writing on a HtmlBackend
|
|
|
|
object
|
2009-06-10 02:17:32 +05:30
|
|
|
|
|
|
|
div id's defined here:
|
|
|
|
id="grampstextdoc" : the entire text report
|
|
|
|
id="grampsheading" : a small defined heading, but not h1 to h6 !
|
|
|
|
id="grampsstylednote" : start of part with a styled note, divided in
|
|
|
|
paragraphs
|
|
|
|
id="grampsnote" : start of part with a note. This id is normally not
|
|
|
|
used
|
2009-06-11 18:31:27 +05:30
|
|
|
|
|
|
|
The styles as defined in the stylesheed of the textdoc, will be converted
|
|
|
|
to css class. Color is removed to avoid conflicts with the css. Also
|
|
|
|
Fontface is removed. Size, italic, bold, margins, borders are retained
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
def __init__(self, styles, paper_style):
|
2009-06-06 15:19:40 +05:30
|
|
|
BaseDoc.__init__(self, styles, None)
|
2009-06-09 04:49:37 +05:30
|
|
|
self.style_declaration = ''
|
|
|
|
self.htmllist = []
|
|
|
|
self._backend = None
|
2009-06-11 18:31:27 +05:30
|
|
|
self.css_filename = ''
|
2009-06-09 04:49:37 +05:30
|
|
|
self.warn_dir = True
|
|
|
|
self._col = 0
|
|
|
|
self._tbl = None
|
|
|
|
self._empty = 1
|
2009-06-10 02:17:32 +05:30
|
|
|
self.title = ''
|
|
|
|
self.__title_written = -1 # -1 = not written, 0 = writing, 1 = written
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-06-06 15:19:40 +05:30
|
|
|
def set_css_filename(self, css_filename):
|
|
|
|
"""
|
|
|
|
Set the css file to use. The path must be included.
|
|
|
|
Note: DocReportDialog sets this for html doc
|
|
|
|
"""
|
2009-06-11 18:31:27 +05:30
|
|
|
if os.path.basename(css_filename):
|
|
|
|
self.css_filename = css_filename
|
|
|
|
else:
|
|
|
|
self.css_filename = ''
|
2009-06-06 15:19:40 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
def open(self, filename):
|
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self._backend = HtmlBackend(filename)
|
|
|
|
self._backend.open()
|
|
|
|
self.htmllist += [self._backend.html_body]
|
2009-06-10 02:17:32 +05:30
|
|
|
#start a gramps report
|
|
|
|
self.htmllist += [Html('div', id="grampstextdoc")]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
self.build_header()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def build_header(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Build up the header of the html file over the defaults of Html()
|
|
|
|
"""
|
|
|
|
# add additional meta tags and stylesheet links to head section
|
|
|
|
# create additional meta tags
|
|
|
|
_meta1 = 'name="generator" content="%s %s %s"' % (const.PROGRAM_NAME,
|
|
|
|
const.VERSION, const.URL_HOMEPAGE)
|
|
|
|
meta = Html('meta', attr = _meta1)
|
|
|
|
|
|
|
|
#set styles of the report as inline css
|
|
|
|
self.build_style_declaration()
|
2009-06-11 18:31:27 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
|
|
|
|
# GRAMPS favicon en css
|
2009-06-11 18:31:27 +05:30
|
|
|
fname1 = '/'.join([self._backend.datadir(), 'favicon.ico'])
|
|
|
|
fname2 = '/'.join([self._backend.datadir(), _TEXTDOCSCREEN])
|
|
|
|
fname3 = '/'.join([self._backend.datadir(), _HTMLSCREEN])
|
2009-06-09 04:49:37 +05:30
|
|
|
|
|
|
|
# links for GRAMPS favicon and stylesheets
|
|
|
|
links = Html('link', rel='shortcut icon', href=fname1,
|
|
|
|
type='image/x-icon') + (
|
|
|
|
Html('link', rel='stylesheet', href=fname2, type='text/css',
|
2009-06-11 18:31:27 +05:30
|
|
|
media='screen', indent=False),)
|
|
|
|
if self.css_filename:
|
|
|
|
links += (Html('link', rel='stylesheet', href=fname3,
|
|
|
|
type='text/css', media='screen', indent=False),
|
2009-06-09 04:49:37 +05:30
|
|
|
)
|
|
|
|
self._backend.html_header += (meta, links)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def build_style_declaration(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Convert the styles of the report into inline css for the html doc
|
|
|
|
"""
|
2007-04-23 17:16:26 +05:30
|
|
|
styles = self.get_style_sheet()
|
|
|
|
|
2009-10-07 18:48:51 +05:30
|
|
|
text = []
|
2007-04-23 17:16:26 +05:30
|
|
|
|
|
|
|
for sname in styles.get_cell_style_names():
|
|
|
|
style = styles.get_cell_style(sname)
|
2002-10-20 19:55:16 +05:30
|
|
|
pad = "%.3fcm" % style.get_padding()
|
|
|
|
top = bottom = left = right = 'none'
|
|
|
|
if style.get_top_border():
|
|
|
|
top = 'thin solid #000000'
|
|
|
|
if style.get_bottom_border():
|
|
|
|
bottom = 'thin solid #000000'
|
|
|
|
if style.get_left_border():
|
2008-01-06 01:40:26 +05:30
|
|
|
left = 'thin solid #000000'
|
2002-10-20 19:55:16 +05:30
|
|
|
if style.get_right_border():
|
|
|
|
right = 'thin solid #000000'
|
2009-06-10 02:17:32 +05:30
|
|
|
text.append('#grampstextdoc .%s {\n'
|
2002-10-20 19:55:16 +05:30
|
|
|
'\tpadding: %s %s %s %s;\n'
|
|
|
|
'\tborder-top:%s; border-bottom:%s;\n'
|
|
|
|
'\tborder-left:%s; border-right:%s;\n}'
|
2009-06-09 04:49:37 +05:30
|
|
|
% (sname, pad, pad, pad, pad, top, bottom, left, right))
|
2007-04-23 17:16:26 +05:30
|
|
|
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2007-04-23 17:16:26 +05:30
|
|
|
for style_name in styles.get_paragraph_style_names():
|
|
|
|
style = styles.get_paragraph_style(style_name)
|
2002-10-20 19:55:16 +05:30
|
|
|
font = style.get_font()
|
|
|
|
font_size = font.get_size()
|
2009-06-10 02:17:32 +05:30
|
|
|
#font_color = '#%02x%02x%02x' % font.get_color()
|
2002-10-20 19:55:16 +05:30
|
|
|
align = style.get_alignment_text()
|
|
|
|
text_indent = "%.2f" % style.get_first_indent()
|
|
|
|
right_margin = "%.2f" % style.get_right_margin()
|
|
|
|
left_margin = "%.2f" % style.get_left_margin()
|
2005-12-06 12:08:09 +05:30
|
|
|
top_margin = "%.2f" % style.get_top_margin()
|
|
|
|
bottom_margin = "%.2f" % style.get_bottom_margin()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
top = bottom = left = right = 'none'
|
|
|
|
if style.get_top_border():
|
|
|
|
top = 'thin solid #000000'
|
|
|
|
if style.get_bottom_border():
|
|
|
|
bottom = 'thin solid #000000'
|
|
|
|
if style.get_left_border():
|
2008-01-06 01:40:26 +05:30
|
|
|
left = 'thin solid #000000'
|
2002-10-20 19:55:16 +05:30
|
|
|
if style.get_right_border():
|
|
|
|
right = 'thin solid #000000'
|
|
|
|
|
|
|
|
italic = bold = ''
|
|
|
|
if font.get_italic():
|
|
|
|
italic = 'font-style:italic; '
|
|
|
|
if font.get_bold():
|
|
|
|
bold = 'font-weight:bold; '
|
2009-06-10 02:17:32 +05:30
|
|
|
#if font.get_type_face() == FONT_SANS_SERIF:
|
|
|
|
# family = '"Helvetica","Arial","sans-serif"'
|
|
|
|
#else:
|
|
|
|
# family = '"Times New Roman","Times","serif"'
|
|
|
|
# do not allow color, set in base css !
|
|
|
|
# so no : 'color: %s' % font_color
|
|
|
|
# so no : 'font-family:%s;' % family
|
|
|
|
text.append('#grampstextdoc .%s {\n'
|
|
|
|
'\tfont-size: %dpt;\n'
|
2002-10-20 19:55:16 +05:30
|
|
|
'\ttext-align: %s; text-indent: %scm;\n'
|
|
|
|
'\tmargin-right: %scm; margin-left: %scm;\n'
|
2005-12-06 12:08:09 +05:30
|
|
|
'\tmargin-top: %scm; margin-bottom: %scm;\n'
|
2002-10-20 19:55:16 +05:30
|
|
|
'\tborder-top:%s; border-bottom:%s;\n'
|
|
|
|
'\tborder-left:%s; border-right:%s;\n'
|
2009-06-10 02:17:32 +05:30
|
|
|
'\t%s%s\n}'
|
|
|
|
% (style_name, font_size,
|
2002-10-20 19:55:16 +05:30
|
|
|
align, text_indent,
|
|
|
|
right_margin, left_margin,
|
2005-12-06 12:08:09 +05:30
|
|
|
top_margin, bottom_margin,
|
2002-10-20 19:55:16 +05:30
|
|
|
top, bottom, left, right,
|
2009-06-10 02:17:32 +05:30
|
|
|
italic, bold))
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2005-12-06 12:08:09 +05:30
|
|
|
self.style_declaration = '\n'.join(text)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def close(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
while len(self.htmllist)>1 :
|
|
|
|
self.__reduce_list()
|
|
|
|
#now write the actual file
|
|
|
|
self._backend.close()
|
2003-03-23 09:46:29 +05:30
|
|
|
self.write_support_files()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
def copy_file(self, from_fname, to_fname, to_dir=''):
|
|
|
|
"""
|
|
|
|
Copy a file from a source to a (report) destination.
|
|
|
|
If to_dir is not present, then the destination directory will be created.
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
Normally 'to_fname' will be just a filename, without directory path.
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
'to_dir' is the relative path name in the destination root. It will
|
|
|
|
be prepended before 'to_fname'.
|
|
|
|
"""
|
2009-06-11 18:31:27 +05:30
|
|
|
#build absolute path
|
|
|
|
dest = os.path.join(self._backend.datadirfull(), to_dir, to_fname)
|
2009-06-09 04:49:37 +05:30
|
|
|
|
|
|
|
destdir = os.path.dirname(dest)
|
|
|
|
if not os.path.isdir(destdir):
|
|
|
|
os.makedirs(destdir)
|
|
|
|
|
|
|
|
if from_fname != dest:
|
|
|
|
shutil.copyfile(from_fname, dest)
|
|
|
|
elif self.warn_dir:
|
2009-11-17 04:09:54 +05:30
|
|
|
from QuestionDialog import WarningDialog
|
2009-06-09 04:49:37 +05:30
|
|
|
WarningDialog(
|
|
|
|
_("Possible destination error") + "\n" +
|
|
|
|
_("You appear to have set your target directory "
|
|
|
|
"to a directory used for data storage. This "
|
|
|
|
"could create problems with file management. "
|
|
|
|
"It is recommended that you consider using "
|
|
|
|
"a different directory to store your generated "
|
|
|
|
"web pages."))
|
|
|
|
self.warn_dir = False
|
|
|
|
|
|
|
|
def write_support_files(self):
|
|
|
|
"""
|
|
|
|
Copy support files to the datadir that needs to hold them
|
|
|
|
"""
|
2009-06-11 18:31:27 +05:30
|
|
|
#css of textdoc styles
|
|
|
|
tdfile = open(os.path.join(self._backend.datadirfull(),
|
|
|
|
_TEXTDOCSCREEN), 'w')
|
|
|
|
tdfile.write(self.style_declaration)
|
|
|
|
tdfile.close()
|
2009-06-09 04:49:37 +05:30
|
|
|
#css file
|
2009-06-11 18:31:27 +05:30
|
|
|
if self.css_filename:
|
2009-07-16 18:18:31 +05:30
|
|
|
#we do an extra check in case file does not exist, eg cli call
|
|
|
|
fullpath = os.path.join(const.DATA_DIR, self.css_filename)
|
|
|
|
if os.path.exists(fullpath):
|
|
|
|
self.copy_file(fullpath, _HTMLSCREEN)
|
2009-06-09 04:49:37 +05:30
|
|
|
#favicon
|
|
|
|
self.copy_file(os.path.join(const.IMAGE_DIR, 'favicon.ico'),
|
|
|
|
'favicon.ico')
|
|
|
|
|
|
|
|
def __reduce_list(self):
|
|
|
|
"""
|
|
|
|
Takes the internal list of html objects, and adds the last to the
|
|
|
|
previous. This closes the upper tag
|
|
|
|
"""
|
|
|
|
self.htmllist[-2] += self.htmllist[-1]
|
|
|
|
self.htmllist.pop()
|
|
|
|
|
|
|
|
def __write_text(self, text, mark=None, markup=False):
|
|
|
|
"""
|
|
|
|
@param text: text to write.
|
|
|
|
@param mark: IndexMark to use for indexing (if supported)
|
|
|
|
@param markup: True if text already contains markup info.
|
|
|
|
Then text will no longer be escaped
|
|
|
|
"""
|
|
|
|
if not markup:
|
|
|
|
text = self._backend.ESCAPE_FUNC()(text)
|
2009-06-10 02:17:32 +05:30
|
|
|
if self.__title_written == 0 :
|
|
|
|
self.title += text
|
2009-06-09 04:49:37 +05:30
|
|
|
self.htmllist[-1] += text
|
|
|
|
|
|
|
|
def __empty_char(self):
|
|
|
|
"""
|
|
|
|
Output a non breaking whitespace so as to have browser behave ok on
|
|
|
|
empty content
|
|
|
|
"""
|
|
|
|
self.__write_text(' ', markup=True)
|
|
|
|
|
|
|
|
def write_text(self, text, mark=None):
|
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
if text != "":
|
|
|
|
self._empty = 0
|
|
|
|
self.__write_text(text, mark)
|
2009-06-10 02:17:32 +05:30
|
|
|
|
|
|
|
def write_title(self):
|
|
|
|
"""
|
|
|
|
Add title field to header
|
|
|
|
"""
|
|
|
|
self._backend.html_header += Html('title', self.title,
|
2009-06-11 18:31:27 +05:30
|
|
|
inline=True)
|
2009-06-10 02:17:32 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
def start_table(self, name, style):
|
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
2007-04-23 17:16:26 +05:30
|
|
|
styles = self.get_style_sheet()
|
2009-06-09 04:49:37 +05:30
|
|
|
self._tbl = styles.get_table_style(style)
|
2009-11-23 07:09:29 +05:30
|
|
|
self.htmllist += [Html('table', width=str(self._tbl.get_width())+'%',
|
2009-06-09 04:49:37 +05:30
|
|
|
cellspacing='0')]
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def end_table(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self.__reduce_list()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def start_row(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self.htmllist += [Html('tr')]
|
|
|
|
self._col = 0
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def end_row(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self.__reduce_list()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
def start_cell(self, style_name, span=1):
|
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self._empty = 1
|
2002-10-20 19:55:16 +05:30
|
|
|
if span > 1:
|
2009-06-11 18:31:27 +05:30
|
|
|
self.htmllist += (Html('td', colspan=str(span),
|
|
|
|
class_=style_name),)
|
2009-06-09 04:49:37 +05:30
|
|
|
self._col += span
|
2002-10-20 19:55:16 +05:30
|
|
|
else:
|
2009-06-11 18:31:27 +05:30
|
|
|
self.htmllist += (Html('td', colspan=str(span),
|
2009-06-09 04:49:37 +05:30
|
|
|
width=str(self._tbl.get_column_width(
|
2009-11-23 07:09:29 +05:30
|
|
|
self._col))+ '%',
|
2009-06-11 18:31:27 +05:30
|
|
|
class_=style_name),)
|
2009-06-09 04:49:37 +05:30
|
|
|
self._col += 1
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def end_cell(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self.__reduce_list()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2009-06-09 04:49:37 +05:30
|
|
|
def start_paragraph(self, style_name, leader=None):
|
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
2009-06-10 02:17:32 +05:30
|
|
|
style_sheet = self.get_style_sheet()
|
|
|
|
style = style_sheet.get_paragraph_style(style_name)
|
|
|
|
level = style.get_header_level()
|
|
|
|
if level == 0:
|
|
|
|
#a normal paragraph
|
2009-10-28 13:45:16 +05:30
|
|
|
self.htmllist += (Html('p', class_=style_name, inline=True),)
|
2009-06-10 02:17:32 +05:30
|
|
|
elif level == 1:
|
|
|
|
if self.__title_written == -1 and \
|
|
|
|
style_name.upper().find('TITLE') != -1:
|
2009-06-11 18:31:27 +05:30
|
|
|
self.__title_written = 0
|
|
|
|
self.htmllist += (Html('div', id="header"),)
|
2009-10-28 13:45:16 +05:30
|
|
|
self.htmllist += (Html('h1', class_=style_name, id='SiteTitle',
|
|
|
|
inline=True),)
|
2009-06-10 02:17:32 +05:30
|
|
|
else:
|
2009-10-28 13:45:16 +05:30
|
|
|
self.htmllist += (Html('h1', class_=style_name, inline=True),)
|
2009-06-10 02:17:32 +05:30
|
|
|
elif 2<= level <= 5:
|
|
|
|
tag = 'h'+str(level+1)
|
2009-10-28 13:45:16 +05:30
|
|
|
self.htmllist += (Html(tag, class_=style_name, inline=True),)
|
2009-06-10 02:17:32 +05:30
|
|
|
else:
|
|
|
|
# a low level header
|
2009-06-11 18:31:27 +05:30
|
|
|
self.htmllist += (Html('div', id='grampsheading',
|
|
|
|
class_=style_name),)
|
2008-06-16 20:31:46 +05:30
|
|
|
if leader is not None:
|
2009-06-09 04:49:37 +05:30
|
|
|
self.write_text(leader+' ')
|
2002-10-20 19:55:16 +05:30
|
|
|
|
|
|
|
def end_paragraph(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
if self._empty == 1:
|
|
|
|
self.__empty_char()
|
|
|
|
self._empty = 0
|
|
|
|
self.__reduce_list()
|
2009-06-10 02:17:32 +05:30
|
|
|
if self.__title_written == 0:
|
|
|
|
self.__title_written = 1
|
|
|
|
#close div statement
|
|
|
|
self.__reduce_list()
|
|
|
|
self.write_title()
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2003-11-14 00:20:01 +05:30
|
|
|
def start_bold(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self.htmllist += [Html('strong')]
|
2003-11-14 00:20:01 +05:30
|
|
|
|
|
|
|
def end_bold(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self.__reduce_list()
|
2007-01-31 08:43:31 +05:30
|
|
|
|
|
|
|
def start_superscript(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self.htmllist += [Html('sup')]
|
2007-01-31 08:43:31 +05:30
|
|
|
|
|
|
|
def end_superscript(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self.__reduce_list()
|
2003-11-14 00:20:01 +05:30
|
|
|
|
2010-01-14 00:10:55 +05:30
|
|
|
def write_endnotes_ref(self, text, style_name):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
2010-01-14 00:10:55 +05:30
|
|
|
Overwrite base method for lines of endnotes references
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
2009-06-10 02:17:32 +05:30
|
|
|
self.htmllist += [Html('div', id='grampsstylednote')]
|
2010-01-14 00:10:55 +05:30
|
|
|
for line in text.split('\n'):
|
|
|
|
# more basic method we convert all to a monospace character
|
2009-06-10 02:17:32 +05:30
|
|
|
self.htmllist += [Html('pre', class_=style_name,
|
2010-01-14 00:10:55 +05:30
|
|
|
style = 'font-family: courier, monospace',
|
|
|
|
indent=None, inline=True)]
|
|
|
|
self.write_text(line)
|
2009-06-10 02:17:32 +05:30
|
|
|
#end pre element
|
2009-06-09 04:49:37 +05:30
|
|
|
self.__reduce_list()
|
2009-06-10 02:17:32 +05:30
|
|
|
#end div element
|
|
|
|
self.__reduce_list()
|
2003-12-11 09:19:44 +05:30
|
|
|
|
2010-04-17 02:29:10 +05:30
|
|
|
def write_styled_note(self, styledtext, format, style_name,
|
|
|
|
contains_html=False):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
Convenience function to write a styledtext to the html doc.
|
|
|
|
styledtext : assumed a StyledText object to write
|
|
|
|
format : = 0 : Flowed, = 1 : Preformatted
|
|
|
|
style_name : name of the style to use for default presentation
|
2010-04-17 02:29:10 +05:30
|
|
|
contains_html: bool, the backend should not check if html is present.
|
|
|
|
If contains_html=True, then the textdoc is free to handle that in
|
|
|
|
some way. Eg, a textdoc could remove all tags, or could make sure
|
|
|
|
a link is clickable. HtmlDoc will show the html as pure text, so
|
|
|
|
no escaping will happen.
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
text = str(styledtext)
|
|
|
|
|
2009-06-10 02:17:32 +05:30
|
|
|
self.htmllist += [Html('div', id='grampsstylednote')]
|
2010-04-17 02:29:10 +05:30
|
|
|
if contains_html:
|
|
|
|
#just dump the note out as it is. Adding markup would be dangerous
|
|
|
|
# as it could destroy the html. If html code, one can do the
|
|
|
|
self.start_paragraph(style_name)
|
|
|
|
self.__write_text(text, markup=True)
|
|
|
|
self.end_paragraph()
|
2010-09-24 02:33:15 +05:30
|
|
|
else:
|
|
|
|
s_tags = styledtext.get_tags()
|
|
|
|
markuptext = self._backend.add_markup_from_styled(text, s_tags,
|
|
|
|
split='\n')
|
|
|
|
self.start_paragraph(style_name)
|
|
|
|
inpara = True
|
|
|
|
self._empty = 1 # para is empty
|
|
|
|
# we explicitly set _empty because start and end para do not seem
|
|
|
|
# to do a very good job at setting them
|
|
|
|
linenb = 1
|
|
|
|
# The code is tricky here, because we don't want to start a new para
|
|
|
|
# at the end of the last line if there is no newline there.
|
|
|
|
# Instead, we want to just end the current para.
|
|
|
|
for line in markuptext.split('\n'):
|
|
|
|
[line, sigcount] = process_spaces(line, format)
|
|
|
|
if sigcount == 0:
|
|
|
|
if inpara == False:
|
|
|
|
# needed for runs of three or more newlines
|
|
|
|
self.start_paragraph(style_name)
|
|
|
|
inpara = True
|
|
|
|
self._empty = 1 # para is empty
|
|
|
|
self.end_paragraph()
|
|
|
|
inpara = False
|
|
|
|
linenb = 1
|
|
|
|
else:
|
|
|
|
if inpara == False:
|
|
|
|
self.start_paragraph(style_name)
|
|
|
|
inpara = True
|
|
|
|
self._empty = 1 # para is empty
|
|
|
|
if linenb > 1:
|
|
|
|
self.htmllist[-1] += Html('br')
|
|
|
|
self.__write_text(line, markup=True)
|
|
|
|
self._empty = 0 # para is not empty
|
|
|
|
linenb += 1
|
|
|
|
if inpara == True:
|
2009-06-09 04:49:37 +05:30
|
|
|
self.end_paragraph()
|
2010-09-24 02:33:15 +05:30
|
|
|
if sigcount == 0:
|
|
|
|
# if the last line was blank, then as well as outputting the previous para,
|
|
|
|
# which we have just done,
|
|
|
|
# we also output a new blank para
|
2009-06-09 04:49:37 +05:30
|
|
|
self.start_paragraph(style_name)
|
2010-09-24 02:33:15 +05:30
|
|
|
self._empty = 1 # para is empty
|
2009-06-09 04:49:37 +05:30
|
|
|
self.end_paragraph()
|
2009-06-10 02:17:32 +05:30
|
|
|
#end div element
|
|
|
|
self.__reduce_list()
|
2009-06-09 04:49:37 +05:30
|
|
|
|
|
|
|
def add_media_object(self, name, pos, w_cm, h_cm, alt=''):
|
|
|
|
"""
|
|
|
|
Overwrite base method
|
|
|
|
"""
|
|
|
|
self._empty = 0
|
|
|
|
size = int(max(w_cm, h_cm) * float(150.0/2.54))
|
|
|
|
refname = "is%s" % os.path.basename(name)
|
|
|
|
|
2009-06-11 18:31:27 +05:30
|
|
|
imdir = self._backend.datadirfull()
|
2009-06-09 04:49:37 +05:30
|
|
|
|
|
|
|
try:
|
|
|
|
ImgManip.resize_to_jpeg(name, imdir + os.sep + refname, size, size)
|
|
|
|
except:
|
|
|
|
LOG.warn(_("Could not create jpeg version of image %(name)s") %
|
|
|
|
{'name' : name})
|
|
|
|
return
|
|
|
|
|
|
|
|
if pos not in ["right", "left"] :
|
|
|
|
self.htmllist[-1] += Html('img', src= imdir + os.sep + refname,
|
|
|
|
border = '0', alt=alt)
|
|
|
|
else:
|
|
|
|
self.htmllist[-1] += Html('img', src= imdir + os.sep + refname,
|
|
|
|
border = '0', alt=alt, align=pos)
|
2002-10-20 19:55:16 +05:30
|
|
|
|
2008-03-05 04:53:08 +05:30
|
|
|
def page_break(self):
|
2009-06-09 04:49:37 +05:30
|
|
|
"""
|
|
|
|
overwrite base method so page break has no effect
|
|
|
|
"""
|
2008-03-05 01:17:52 +05:30
|
|
|
pass
|
2009-11-15 18:45:54 +05:30
|
|
|
|
|
|
|
def start_link(self, link):
|
|
|
|
"""
|
|
|
|
Starts a section to add a link. Link is a URI.
|
|
|
|
"""
|
|
|
|
self.htmllist += [Html('a', href=link)]
|
|
|
|
|
|
|
|
def stop_link(self):
|
|
|
|
"""
|
|
|
|
Stop a section of a link.
|
|
|
|
"""
|
|
|
|
self.__reduce_list()
|
|
|
|
|
|
|
|
def start_underline(self):
|
|
|
|
"""
|
|
|
|
Starts a section of underlining.
|
|
|
|
"""
|
|
|
|
self.htmllist += [Html('u')]
|
|
|
|
|
|
|
|
def stop_underline(self):
|
|
|
|
"""
|
|
|
|
Stop underlining.
|
|
|
|
"""
|
|
|
|
self.__reduce_list()
|