Part 1 basedoc changes: move out backend stuff from BaseDoc, use backend in

the docs. As a dir change will be done, backend itself will be committed 
later, trunk will be broken till then


svn: r12590
This commit is contained in:
Benny Malengier 2009-05-29 19:52:57 +00:00
parent e4b2162bd1
commit f999ba9cc4
4 changed files with 95 additions and 416 deletions

View File

@ -1405,41 +1405,13 @@ class BaseDoc(object):
# TextDoc
#
#------------------------------------------------------------------------
def noescape(text):
return text
class TextDoc(object):
"""
Abstract Interface for text document generators. Output formats for
text reports must implment this interface to be used by the report
system.
"""
BOLD = 0
ITALIC = 1
UNDERLINE = 2
FONTFACE = 3
FONTSIZE = 4
FONTCOLOR = 5
HIGHLIGHT = 6
SUPERSCRIPT = 7
SUPPORTED_MARKUP = []
ESCAPE_FUNC = lambda x: noescape
#Map between styletypes and internally used values. This map is needed
# to make TextDoc officially independant of gen.lib.styledtexttag
STYLETYPE_MAP = {
}
CLASSMAP = None
#STYLETAGTABLE to store markup for write_markup associated with style tags
STYLETAG_MARKUP = {
BOLD : ("", ""),
ITALIC : ("", ""),
UNDERLINE : ("", ""),
SUPERSCRIPT : ("", ""),
}
def page_break(self):
"Forces a page break, creating a new page"
raise NotImplementedError
@ -1592,159 +1564,6 @@ class TextDoc(object):
@param h_cm: height in centimeters
"""
raise NotImplementedError
def find_tag_by_stag(self, s_tag):
"""
@param s_tag: object: assumed styledtexttag
@param s_tagvalue: None/int/str: value associated with the tag
A styled tag is type with a value.
Every styled tag must be converted to the tags used in the corresponding
markup for the backend, eg <b>text</b> for bold in html.
These markups are stored in STYLETAG_MARKUP. They are tuples for begin
and end tag
If a markup is not present yet, it is created, using the
_create_xmltag method you can overwrite
"""
type = s_tag.name
if not self.STYLETYPE_MAP or \
self.CLASSMAP <> type.__class__.__name__ :
self.CLASSMAP == type.__class__.__name__
self.STYLETYPE_MAP[type.__class__.BOLD] = self.BOLD
self.STYLETYPE_MAP[type.ITALIC] = self.ITALIC
self.STYLETYPE_MAP[type.UNDERLINE] = self.UNDERLINE
self.STYLETYPE_MAP[type.FONTFACE] = self.FONTFACE
self.STYLETYPE_MAP[type.FONTSIZE] = self.FONTSIZE
self.STYLETYPE_MAP[type.FONTCOLOR] = self.FONTCOLOR
self.STYLETYPE_MAP[type.HIGHLIGHT] = self.HIGHLIGHT
self.STYLETYPE_MAP[type.SUPERSCRIPT] = self.SUPERSCRIPT
typeval = int(s_tag.name)
s_tagvalue = s_tag.value
tag_name = None
if type.STYLE_TYPE[typeval] == bool:
return self.STYLETAG_MARKUP[self.STYLETYPE_MAP[typeval]]
elif type.STYLE_TYPE[typeval] == str:
tag_name = "%d %s" % (typeval, s_tagvalue)
elif type.STYLE_TYPE[typeval] == int:
tag_name = "%d %d" % (typeval, s_tagvalue)
if not tag_name:
return None
tags = self.STYLETAG_MARKUP.get(tag_name)
if tags is not None:
return tags
#no tag known yet, create the markup, add to lookup, and return
tags = self._create_xmltag(self.STYLETYPE_MAP[typeval], s_tagvalue)
self.STYLETAG_MARKUP[tag_name] = tags
return tags
def _create_xmltag(self, type, value):
"""
Create the xmltags for the backend.
Overwrite this method to create functionality with a backend
"""
if type not in self.SUPPORTED_MARKUP:
return None
return ('', '')
def _add_markup_from_styled(self, text, s_tags, split=''):
"""
Input is plain text, output is text with markup added according to the
s_tags which are assumed to be styledtexttags.
When split is given the text will be split over the value given, and
tags applied in such a way that it the text can be safely splitted in
pieces along split
@param text : str, a piece of text
@param s_tags : styledtexttags that must be applied to the text
@param split : str, optional. A string along which the output can
be safely split without breaking the styling.
As adding markup means original text must be escaped, ESCAPE_FUNC is
used
This can be used to convert the text of a styledtext to the format
needed for a document backend
Do not call this method in a report, use the write_markup method
@note: the algorithm is complex as it assumes mixing of tags is not
allowed: eg <b>text<i> here</b> not</i> is assumed invalid
as markup. If the s_tags require such a setup, what is returned
is <b>text</b><i><b> here</b> not</i>
overwrite this method if this complexity is not needed.
"""
FIRST = 0
LAST = 1
tagspos = {}
for s_tag in s_tags:
tag = self.find_tag_by_stag(s_tag)
if tag is not None:
for (start, end) in s_tag.ranges:
if start in tagspos:
tagspos[start] += [(tag, FIRST)]
else:
tagspos[start] = [(tag, FIRST)]
if end in tagspos:
tagspos[end] += [(tag, LAST)]
else:
tagspos[end] = [(tag, LAST)]
start = 0
end = len(text)
keylist = tagspos.keys()
keylist.sort()
keylist = [x for x in keylist if x<=len(text)]
opentags = []
otext = u"" #the output, text with markup
lensplit = len(split)
for pos in keylist:
#write text up to tag
if pos > start:
if split:
#make sure text can split
splitpos = text[start:pos].find(split)
while splitpos <> -1:
otext += self.ESCAPE_FUNC()(text[start:start+splitpos])
#close open tags
for opentag in reversed(opentags):
otext += opentag[1]
#add split text
otext += self.ESCAPE_FUNC()(split)
#open the tags again
for opentag in opentags:
otext += opentag[0]
#obtain new values
start = start + splitpos + lensplit
splitpos = text[start:pos].find(split)
otext += self.ESCAPE_FUNC()(text[start:pos])
#write out tags
for tag in tagspos[pos]:
#close open tags starting from last open
for opentag in reversed(opentags):
otext += opentag[1]
#if start, add to opentag in beginning as first to open
if tag[1] == FIRST:
opentags = [tag[0]] + opentags
else:
#end tag, is closed already, remove from opentag
opentags = [x for x in opentags if not x == tag[0] ]
#now all tags are closed, open the ones that should open
for opentag in opentags:
otext += opentag[0]
start = pos
#add remainder of text, no markup present there
otext += self.ESCAPE_FUNC()(text[start:end])
#opentags should be empty. If not, user gave tags on positions that
# are over the end of the text. Just close the tags still open
if opentags:
print 'WARNING: TextDoc : More style tags in text than length '\
'of text allows.\n', opentags
for opentag in reversed(opentags):
otext += opentag[1]
return otext
#------------------------------------------------------------------------
#

View File

@ -40,6 +40,7 @@ from gettext import gettext as _
#
#------------------------------------------------------------------------
import BaseDoc
from docbackend.latexbackend import LateXBackend, latexescape
from gen.plug import PluginManager, DocGenPlugin
import ImgManip
import Errors
@ -128,81 +129,18 @@ class TexFont(object):
#
#------------------------------------------------------------------------
def latexescape(text):
"""
change text in text that latex shows correctly
special characters: \& \$ \% \# \_ \{ \}
"""
text = text.replace('&','\\&')
text = text.replace('$','\\$')
text = text.replace('%','\\%')
text = text.replace('#','\\#')
text = text.replace('_','\\_')
text = text.replace('{','\\{')
text = text.replace('}','\\}')
return text
def latexescapeverbatim(text):
"""
change text in text that latex shows correctly respecting whitespace
special characters: \& \$ \% \# \_ \{ \}
Now also make sure space and newline is respected
"""
text = text.replace('&', '\\&')
text = text.replace('$', '\\$')
text = text.replace('%', '\\%')
text = text.replace('#', '\\#')
text = text.replace('_', '\\_')
text = text.replace('{', '\\{')
text = text.replace('}', '\\}')
text = text.replace(' ', '\\ ')
text = text.replace('\n', '\\newline\n')
#spaces at begin are normally ignored, make sure they are not.
#due to above a space at begin is now \newline\n\
text = text.replace('\\newline\n\\ ', '\\newline\n\\hspace*{0.1cm}\\ ')
return text
class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
"""LaTeX document interface class. Derived from BaseDoc"""
# overwrite base class attributes, they become static var of LaTeXDoc
SUPPORTED_MARKUP = [
BaseDoc.TextDoc.BOLD,
BaseDoc.TextDoc.ITALIC,
BaseDoc.TextDoc.UNDERLINE,
BaseDoc.TextDoc.FONTSIZE,
BaseDoc.TextDoc.FONTFACE,
BaseDoc.TextDoc.SUPERSCRIPT ]
STYLETAG_MARKUP = {
BaseDoc.TextDoc.BOLD : ("\\textbf{", "}"),
BaseDoc.TextDoc.ITALIC : ("\\textit{", "}"),
BaseDoc.TextDoc.UNDERLINE : ("\\underline{", "}"),
BaseDoc.TextDoc.SUPERSCRIPT : ("\\textsuperscript{", "}"),
}
ESCAPE_FUNC = lambda x: latexescape
def page_break(self):
"Forces a page break, creating a new page"
self.f.write('\\newpage ')
self._backend.write('\\newpage ')
def open(self,filename):
def open(self, filename):
"""Opens the specified file, making sure that it has the
extension of .tex"""
if filename[-4:] != ".tex":
self.filename = filename + ".tex"
else:
self.filename = 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)
self._backend = LateXBackend(filename)
self._backend.open()
# Font size control seems to be limited. For now, ignore
# any style constraints, and use 12pt has the default
@ -229,45 +167,45 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
# Use the article template, T1 font encodings, and specify
# that we should use Latin1 and unicode character encodings.
self.f.write('\\documentclass[%s]{article}\n' % options)
self.f.write('\\usepackage[T1]{fontenc}\n')
self.f.write('%\n% We use latin1 encoding at a minimum by default.\n')
self.f.write('% GRAMPS uses unicode UTF-8 encoding for its\n')
self.f.write('% international support. LaTeX can deal gracefully\n')
self.f.write('% with unicode encoding by using the ucs style invoked\n')
self.f.write('% when utf8 is specified as an option to the inputenc\n')
self.f.write('% package. This package is included by default in some\n')
self.f.write('% installations, but not in others, so we do not make it\n')
self.f.write('% the default. Uncomment the second line if you wish to use it\n')
self.f.write('% (If you do not have ucs.sty, you may obtain it from\n')
self.f.write('% http://www.tug.org/tex-archive/macros/latex/contrib/supported/unicode/)\n')
self.f.write('%\n')
self.f.write('\\usepackage[latin1]{inputenc}\n')
self.f.write('%\\usepackage[latin1,utf8]{inputenc}\n')
self._backend.write('\\documentclass[%s]{article}\n' % options)
self._backend.write('\\usepackage[T1]{fontenc}\n')
self._backend.write('%\n% We use latin1 encoding at a minimum by default.\n')
self._backend.write('% GRAMPS uses unicode UTF-8 encoding for its\n')
self._backend.write('% international support. LaTeX can deal gracefully\n')
self._backend.write('% with unicode encoding by using the ucs style invoked\n')
self._backend.write('% when utf8 is specified as an option to the inputenc\n')
self._backend.write('% package. This package is included by default in some\n')
self._backend.write('% installations, but not in others, so we do not make it\n')
self._backend.write('% the default. Uncomment the second line if you wish to use it\n')
self._backend.write('% (If you do not have ucs.sty, you may obtain it from\n')
self._backend.write('% http://www.tug.org/tex-archive/macros/latex/contrib/supported/unicode/)\n')
self._backend.write('%\n')
self._backend.write('\\usepackage[latin1]{inputenc}\n')
self._backend.write('%\\usepackage[latin1,utf8]{inputenc}\n')
# add packages (should be standard on a default installation)
# for finer output control. Put comments in file for user to read
self.f.write('\\usepackage{graphicx} % Extended graphics support\n')
self.f.write('\\usepackage{longtable} % For multi-page tables\n')
self.f.write('\\usepackage{calc} % For margin indents\n')
self.f.write('%\n% Depending on your LaTeX installation, the')
self.f.write(' margins may be too\n% narrow. ')
self.f.write(' This can be corrected by uncommenting the following\n')
self.f.write('% two lines and adjusting the width appropriately.')
self.f.write(' The example\n% removes 0.5in from each margin.')
self.f.write(' (Adds 1 inch to the text)\n')
self.f.write('%\\addtolength{\\oddsidemargin}{-0.5in}\n')
self.f.write('%\\addtolength{\\textwidth}{1.0in}\n%\n')
self.f.write('% Create a margin-adjusting command that allows LaTeX\n')
self.f.write('% to behave like the other gramps-supported output formats\n')
self.f.write('\\newlength{\\leftedge}\n')
self.f.write('\\setlength{\\leftedge}{\\parindent}\n')
self.f.write('\\newlength{\\grampstext}\n')
self.f.write('\\setlength{\\grampstext}{\\textwidth}\n')
self.f.write('\\newcommand{\\grampsindent}[1]{%\n')
self.f.write(' \\setlength{\\parindent}{\\leftedge + #1}%\n')
self.f.write(' \\setlength{\\textwidth}{\\grampstext - #1}%\n')
self.f.write('}\n\n')
self.f.write('\\begin{document}\n\n')
self._backend.write('\\usepackage{graphicx} % Extended graphics support\n')
self._backend.write('\\usepackage{longtable} % For multi-page tables\n')
self._backend.write('\\usepackage{calc} % For margin indents\n')
self._backend.write('%\n% Depending on your LaTeX installation, the')
self._backend.write(' margins may be too\n% narrow. ')
self._backend.write(' This can be corrected by uncommenting the following\n')
self._backend.write('% two lines and adjusting the width appropriately.')
self._backend.write(' The example\n% removes 0.5in from each margin.')
self._backend.write(' (Adds 1 inch to the text)\n')
self._backend.write('%\\addtolength{\\oddsidemargin}{-0.5in}\n')
self._backend.write('%\\addtolength{\\textwidth}{1.0in}\n%\n')
self._backend.write('% Create a margin-adjusting command that allows LaTeX\n')
self._backend.write('% to behave like the other gramps-supported output formats\n')
self._backend.write('\\newlength{\\leftedge}\n')
self._backend.write('\\setlength{\\leftedge}{\\parindent}\n')
self._backend.write('\\newlength{\\grampstext}\n')
self._backend.write('\\setlength{\\grampstext}{\\textwidth}\n')
self._backend.write('\\newcommand{\\grampsindent}[1]{%\n')
self._backend.write(' \\setlength{\\parindent}{\\leftedge + #1}%\n')
self._backend.write(' \\setlength{\\textwidth}{\\grampstext - #1}%\n')
self._backend.write('}\n\n')
self._backend.write('\\begin{document}\n\n')
self.in_list = 0
self.in_table = 0
@ -351,15 +289,15 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
def close(self):
"""Clean up and close the document"""
if self.in_list:
self.f.write('\\end{enumerate}\n')
self.f.write('\n\\end{document}\n')
self.f.close()
self._backend.write('\\end{enumerate}\n')
self._backend.write('\n\\end{document}\n')
self._backend.close()
if self.open_req:
Utils.open_file_with_default_application(self.filename)
Utils.open_file_with_default_application(self._backend.filename)
def end_page(self):
"""Issue a new page command"""
self.f.write('\\newpage')
self._backend.write('\\newpage')
def start_paragraph(self,style_name,leader=None):
"""Paragraphs handling - A Gramps paragraph is any
@ -378,11 +316,11 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
if self.indent is not None and not self.in_table:
myspace = '%scm' % str(self.indent)
self.f.write('\\grampsindent{%s}\n' % myspace)
self._backend.write('\\grampsindent{%s}\n' % myspace)
self.fix_indent = 1
if leader is not None and not self.in_list:
self.f.write('\\begin{enumerate}\n')
self._backend.write('\\begin{enumerate}\n')
self.in_list = 1
if leader is not None:
# try obtaining integer
@ -394,22 +332,22 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
num = int(leader_1)
except ValueError:
num = 1
self.f.write(' \\renewcommand\\theenumi{\\arabic{enumi}}')
self._backend.write(' \\renewcommand\\theenumi{\\arabic{enumi}}')
else:
# roman, set the case correctly
if leader_1.islower():
self.f.write(' \\renewcommand\\theenumi{\\roman{enumi}}')
self._backend.write(' \\renewcommand\\theenumi{\\roman{enumi}}')
else:
self.f.write(' \\renewcommand\\theenumi{\\Roman{enumi}}')
self._backend.write(' \\renewcommand\\theenumi{\\Roman{enumi}}')
self.f.write(' \\setcounter{enumi}{%d} ' % num)
self.f.write(' \\addtocounter{enumi}{-1}\n')
self.f.write(' \\item ')
self._backend.write(' \\setcounter{enumi}{%d} ' % num)
self._backend.write(' \\addtocounter{enumi}{-1}\n')
self._backend.write(' \\item ')
if leader is None and not self.in_list and not self.in_table:
self.f.write('\n')
self._backend.write('\n')
self.f.write('%s ' % self.fbeg)
self._backend.write('%s ' % self.fbeg)
def end_paragraph(self):
"""End the current paragraph"""
@ -417,30 +355,30 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
if self.in_list:
self.in_list = 0
self.f.write('\n\\end{enumerate}\n')
self._backend.write('\n\\end{enumerate}\n')
newline = ''
elif self.in_table:
newline = ('')
self.f.write('%s%s' % (self.fend, newline))
self._backend.write('%s%s' % (self.fend, newline))
if self.fix_indent == 1:
self.fix_indent = 0
self.f.write('\\grampsindent{0cm}\n')
self._backend.write('\\grampsindent{0cm}\n')
def start_bold(self):
"""Bold face"""
self.f.write('\\textbf{')
self._backend.write('\\textbf{')
def end_bold(self):
"""End bold face"""
self.f.write('}')
self._backend.write('}')
def start_superscript(self):
self.f.write('\\textsuperscript{')
self._backend.write('\\textsuperscript{')
def end_superscript(self):
self.f.write('}')
self._backend.write('}')
def start_table(self, name,style_name):
"""Begin new table"""
@ -453,13 +391,13 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
self.numcols = self.tblstyle.get_columns()
tblfmt = '*{%d}{l}' % self.numcols
self.f.write('\n\n\\begin{longtable}[l]{%s}\n' % tblfmt)
self._backend.write('\n\n\\begin{longtable}[l]{%s}\n' % tblfmt)
def end_table(self):
"""Close the table environment"""
self.in_table = 0
# Create a paragraph separation below the table.
self.f.write('\\end{longtable}\n\\par\n')
self._backend.write('\\end{longtable}\n\\par\n')
def start_row(self):
"""Begin a new row"""
@ -471,14 +409,14 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
def end_row(self):
"""End the row (new line)"""
self.f.write('\\\\ ')
self._backend.write('\\\\ ')
if self.doline == 1:
if self.skipfirst == 1:
self.f.write('\\cline{2-%d}\n' % self.numcols)
self._backend.write('\\cline{2-%d}\n' % self.numcols)
else:
self.f.write('\\hline \\\\ \n')
self._backend.write('\\hline \\\\ \n')
else:
self.f.write('\n')
self._backend.write('\n')
def start_cell(self,style_name,span=1):
"""Add an entry to the table.
@ -513,14 +451,14 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
self.skipfirst = 1
if self.tborder != 0:
self.f.write('\\hline\n')
self.f.write ('\\multicolumn{%d}{%s}{' % (span,cellfmt))
self._backend.write('\\hline\n')
self._backend.write ('\\multicolumn{%d}{%s}{' % (span,cellfmt))
def end_cell(self):
"""Prepares for next cell"""
self.f.write('} ')
self._backend.write('} ')
if self.curcol < self.numcols:
self.f.write('& ')
self._backend.write('& ')
def add_media_object(self, name,pos,x,y):
"""Add photo to report"""
@ -538,11 +476,11 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
# x and y will be maximum width OR height in units of cm
mysize = 'width=%dcm, height=%dcm,keepaspectratio' % (x,y)
if pos == "right":
self.f.write('\\hfill\\includegraphics[%s]{%s}\n' % (mysize,picf))
self._backend.write('\\hfill\\includegraphics[%s]{%s}\n' % (mysize,picf))
elif pos == "left":
self.f.write('\\includegraphics[%s]{%s}\\hfill\n' % (mysize,picf))
self._backend.write('\\includegraphics[%s]{%s}\\hfill\n' % (mysize,picf))
else:
self.f.write('\\centerline{\\includegraphics[%s]{%s}}\n' % (mysize,picf))
self._backend.write('\\centerline{\\includegraphics[%s]{%s}}\n' % (mysize,picf))
def write_text(self,text,mark=None):
"""Write the text to the file"""
@ -552,7 +490,7 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
#hard coded replace of the underline used for missing names/data
text = text.replace('\\_\\_\\_\\_\\_\\_\\_\\_\\_\\_\\_\\_\\_',
'\\underline{\hspace{3cm}}')
self.f.write(text)
self._backend.write(text)
def write_styled_note(self, styledtext, format, style_name):
"""
@ -569,72 +507,34 @@ class LaTeXDoc(BaseDoc.BaseDoc,BaseDoc.TextDoc):
s_tags = styledtext.get_tags()
if format == 1:
#preformatted, use different escape function
BaseDoc.TextDoc.ESCAPE_FUNC = lambda x: latexescapeverbatim
self._backend.setescape(True)
markuptext = self._add_markup_from_styled(text, s_tags)
markuptext = self._backend.add_markup_from_styled(text, s_tags)
#there is a problem if we write out a note in a table. No newline is
# possible, the note runs over the margin into infinity.
# A good solution for this ???
# A quick solution: create a minipage for the note and add that always
# hoping that the user will have left sufficient room for the page
self.f.write("\\begin{minipage}{{0.8\\linewidth}}\n")
self._backend.write("\\begin{minipage}{{0.8\\linewidth}}\n")
self.start_paragraph(style_name)
self.f.write(markuptext)
self._backend.write(markuptext)
self.end_paragraph()
#end the minipage, add trick to have a white line at bottom of note,
# we assume here a note should be distinct from its surrounding.
self.f.write("\n\\vspace*{0.5cm} \n\end{minipage}\n")
self._backend.write("\n\\vspace*{0.5cm} \n\end{minipage}\n\n")
if format == 1:
#preformatted finished, go back to normal escape function
BaseDoc.TextDoc.ESCAPE_FUNC = lambda x: latexescape
def _create_xmltag(self, type, value):
"""
overwrites the method in BaseDoc.TextDoc.
creates the latex tags needed for non bool style types we support:
BaseDoc.TextDoc.FONTSIZE : use different \large denomination based
on size
: very basic, in mono in the font face
then we use {\ttfamily }
"""
if type not in self.SUPPORTED_MARKUP:
return None
elif type == BaseDoc.TextDoc.FONTSIZE:
#translate size in point to something LaTeX can work with
if value >= 22:
return ("{\\Huge ", "}")
elif value >= 20:
return ("{\\huge ", "}")
elif value >= 18:
return ("{\\LARGE ", "}")
elif value >= 16:
return ("{\\Large ", "}")
elif value >= 14:
return ("{\\large ", "}")
elif value < 8:
return ("{\\scriptsize ", "}")
elif value < 10:
return ("{\\footnotesize ", "}")
elif value < 12:
return ("{\\small ", "}")
else:
return ("", "")
elif type == BaseDoc.TextDoc.FONTFACE:
if 'MONO' in value.upper():
return ("{\\ttfamily ", "}")
elif 'ROMAN' in value.upper():
return ("{\\rmfamily ", "}")
return None
self._backend.setescape(False)
def write_note(self,text,format,style_name):
"""Write the note's text to the file, respecting the format"""
self.start_paragraph(style_name)
if format == 1:
self.f.write('\\begin{verbatim}')
self._backend.write('\\begin{verbatim}')
self.write_text(text)
if format == 1:
self.f.write('\\end{verbatim}')
self._backend.write('\\end{verbatim}')
self.end_paragraph()
#------------------------------------------------------------------------

View File

@ -86,7 +86,7 @@ class PdfDoc(libcairodoc.CairoDoc):
top_margin = self.paper.get_top_margin() * DPI / 2.54
# create cairo context and pango layout
surface = cairo.PDFSurface(self._filename, paper_width, paper_height)
surface = cairo.PDFSurface(self._backend.filename, paper_width, paper_height)
surface.set_fallback_resolution(300, 300)
cr = pangocairo.CairoContext(cairo.Context(surface))
@ -125,7 +125,7 @@ class PdfDoc(libcairodoc.CairoDoc):
# load the result into an external viewer
if self.open_req:
Utils.open_file_with_default_application(self._filename)
Utils.open_file_with_default_application(self._backend.filename)
#------------------------------------------------------------------------
#

View File

@ -32,7 +32,6 @@
#------------------------------------------------------------------------
from gettext import gettext as _
from math import radians
from xml.sax.saxutils import escape
#------------------------------------------------------------------------
#
@ -43,6 +42,7 @@ import BaseDoc
from ReportBase import ReportUtils
from Errors import PluginError
from gen.plug import PluginManager, Plugin
from docbackend import CairoBackend
#------------------------------------------------------------------------
#
@ -1200,37 +1200,11 @@ class CairoDoc(BaseDoc.BaseDoc, BaseDoc.TextDoc, BaseDoc.DrawDoc):
page style.
"""
STYLETAG_TO_PROPERTY = {
BaseDoc.TextDoc.FONTCOLOR : 'foreground',
BaseDoc.TextDoc.HIGHLIGHT : 'background',
BaseDoc.TextDoc.FONTFACE : 'face',
BaseDoc.TextDoc.FONTSIZE : 'size',
}
# overwrite base class attributes, they become static var of CairoDoc
SUPPORTED_MARKUP = [
BaseDoc.TextDoc.BOLD,
BaseDoc.TextDoc.ITALIC,
BaseDoc.TextDoc.UNDERLINE,
BaseDoc.TextDoc.FONTFACE,
BaseDoc.TextDoc.FONTSIZE,
BaseDoc.TextDoc.FONTCOLOR,
BaseDoc.TextDoc.HIGHLIGHT,
BaseDoc.TextDoc.SUPERSCRIPT ]
STYLETAG_MARKUP = {
BaseDoc.TextDoc.BOLD : ("<b>", "</b>"),
BaseDoc.TextDoc.ITALIC : ("<i>", "</i>"),
BaseDoc.TextDoc.UNDERLINE : ("<u>", "</u>"),
BaseDoc.TextDoc.SUPERSCRIPT : ("<sup>", "</sup>"),
}
ESCAPE_FUNC = lambda x: escape
# BaseDoc implementation
def open(self, filename):
self._filename = filename
self._backend = CairoBackend(filename)
self._doc = GtkDocDocument()
self._active_element = self._doc
self._pages = []
@ -1303,21 +1277,6 @@ class CairoDoc(BaseDoc.BaseDoc, BaseDoc.TextDoc, BaseDoc.DrawDoc):
def end_cell(self):
self._active_element = self._active_element.get_parent()
def _create_xmltag(self, type, value):
"""
overwrites the method in BaseDoc.TextDoc.
creates the pango xml tags needed for non bool style types
"""
if type not in self.SUPPORTED_MARKUP:
return None
if type == BaseDoc.TextDoc.FONTSIZE:
#size is in thousandths of a point in pango
value = str(1000 * value)
return ('<span %s="%s">' % (self.STYLETAG_TO_PROPERTY[type],
self.ESCAPE_FUNC()(value)),
'</span>')
def write_note(self, text, format, style_name):
"""
Method to write the note objects text on a
@ -1358,7 +1317,8 @@ class CairoDoc(BaseDoc.BaseDoc, BaseDoc.TextDoc, BaseDoc.DrawDoc):
s_tags = styledtext.get_tags()
#FIXME: following split should be regex to match \n\s*\n instead?
markuptext = self._add_markup_from_styled(text, s_tags, split='\n\n')
markuptext = self._backend.add_markup_from_styled(text, s_tags,
split='\n\n')
if format == 1:
#preformatted, retain whitespace. Cairo retains \n automatically,
@ -1391,7 +1351,7 @@ class CairoDoc(BaseDoc.BaseDoc, BaseDoc.TextDoc, BaseDoc.DrawDoc):
# calls. This way we save the markup created by the report
# The markup in the note editor is not in the text so is not
# considered. It must be added by pango too
text = escape(text)
text = self._backend.ESCAPE_FUNC()(text)
self._active_element.add_text(text)
def write_text(self, text, mark=None):
@ -1411,7 +1371,7 @@ class CairoDoc(BaseDoc.BaseDoc, BaseDoc.TextDoc, BaseDoc.DrawDoc):
@param s_tags: assumed to be list of styledtexttags to apply to the
text
"""
markuptext = self._add_markup_from_styled(text, s_tags)
markuptext = self._backend.add_markup_from_styled(text, s_tags)
self.__write_text(text, markup=True)
def add_media_object(self, name, pos, x_cm, y_cm):