From a3fd7c06beb9d43548137205149fc72503363ebd Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Sat, 4 Jun 2016 18:29:10 +0100 Subject: [PATCH] Further pylint improvements to document generators --- gramps/plugins/docgen/gtkprint.py | 42 +- gramps/plugins/docgen/latexdoc.py | 312 ++++----- gramps/plugins/docgen/odfdoc.py | 955 +++++++++++++--------------- gramps/plugins/docgen/rtfdoc.py | 286 ++++----- gramps/plugins/docgen/svgdrawdoc.py | 141 ++-- 5 files changed, 839 insertions(+), 897 deletions(-) diff --git a/gramps/plugins/docgen/gtkprint.py b/gramps/plugins/docgen/gtkprint.py index 0dbf3d7fe..bd5ba6363 100644 --- a/gramps/plugins/docgen/gtkprint.py +++ b/gramps/plugins/docgen/gtkprint.py @@ -27,27 +27,8 @@ # Python modules # #------------------------------------------------------------------------ -from gramps.gen.const import GRAMPS_LOCALE as glocale -_ = glocale.translation.gettext from math import radians - -#------------------------------------------------------------------------ -# -# Gramps modules -# -#------------------------------------------------------------------------ -from gramps.gen.plug.docgen import PAPER_PORTRAIT -import gramps.plugins.lib.libcairodoc as libcairodoc -from gramps.gen.errors import UnavailableError -#import constfunc - -#------------------------------------------------------------------------ -# -# Set up logging -# -#------------------------------------------------------------------------ import logging -log = logging.getLogger(".GtkPrint") #------------------------------------------------------------------------- # @@ -61,6 +42,23 @@ try: # the Gramps-Connect server has no DISPLAY except: pass +#------------------------------------------------------------------------ +# +# Gramps modules +# +#------------------------------------------------------------------------ +from gramps.gen.plug.docgen import PAPER_PORTRAIT +import gramps.plugins.lib.libcairodoc as libcairodoc +from gramps.gen.const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext + +#------------------------------------------------------------------------ +# +# Set up logging +# +#------------------------------------------------------------------------ +LOG = logging.getLogger(".GtkPrint") + #------------------------------------------------------------------------ # # Constants @@ -128,7 +126,7 @@ def paperstyle_to_pagesetup(paper_style): # are handled as custom format, because we are not intelligent enough. if gramps_paper_name in gramps_to_gtk: paper_size = Gtk.PaperSize.new(name=gramps_to_gtk[gramps_paper_name]) - log.debug("Selected paper size: %s" % gramps_to_gtk[gramps_paper_name]) + LOG.debug("Selected paper size: %s", gramps_to_gtk[gramps_paper_name]) else: if paper_style.get_orientation() == PAPER_PORTRAIT: paper_width = gramps_paper_size.get_width() * 10 @@ -139,7 +137,7 @@ def paperstyle_to_pagesetup(paper_style): paper_size = Gtk.PaperSize.new_custom("custom", "Custom Size", paper_width, paper_height, Gtk.Unit.MM) - log.debug("Selected paper size: (%f,%f)" % (paper_width, paper_height)) + LOG.debug("Selected paper size: (%f,%f)", paper_width, paper_height) page_setup = Gtk.PageSetup() page_setup.set_paper_size(paper_size) @@ -234,7 +232,7 @@ class PrintPreview: ##""" ##if page_no >= len(self._page_numbers): - ##log.debug("Page number %d doesn't exist." % page_no) + ##LOG.debug("Page number %d doesn't exist." % page_no) ##page_no = 0 ##if page_no not in self._page_surfaces: diff --git a/gramps/plugins/docgen/latexdoc.py b/gramps/plugins/docgen/latexdoc.py index 443d79f84..56455fecb 100644 --- a/gramps/plugins/docgen/latexdoc.py +++ b/gramps/plugins/docgen/latexdoc.py @@ -32,28 +32,34 @@ #------------------------------------------------------------------------ # -# python modules +# Python modules # #------------------------------------------------------------------------ -from gramps.gen.const import GRAMPS_LOCALE as glocale -_ = glocale.translation.gettext from bisect import bisect -import re, os, sys +import re +import os import logging -_LOG = logging.getLogger(".latexdoc") -#----------------------------------------------------------------------- - -# -# gramps modules -# -#------------------------------------------------------------------------ -from gramps.gen.plug.docgen import BaseDoc, TextDoc, PAPER_LANDSCAPE, FONT_SANS_SERIF, URL_PATTERN -from gramps.gen.plug.docbackend import DocBackend -HAVE_PIL = False try: from PIL import Image HAVE_PIL = True -except: +except ImportError: + HAVE_PIL = False + +#----------------------------------------------------------------------- - +# +# Gramps modules +# +#------------------------------------------------------------------------ +from gramps.gen.plug.docgen import (BaseDoc, TextDoc, PAPER_LANDSCAPE, + FONT_SANS_SERIF, URL_PATTERN) +from gramps.gen.plug.docbackend import DocBackend +from gramps.gen.const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext + + +_LOG = logging.getLogger(".latexdoc") +if not HAVE_PIL: _LOG.warning(_("PIL (Python Imaging Library) not loaded. " "Production of jpg images from non-jpg images " "in LaTeX documents will not be available. " @@ -435,8 +441,8 @@ def map_font_size(fontsize): TBLFMT_PAT = re.compile(r'({\|?)l(\|?})') # constants for routing in table construction: -(CELL_BEG, CELL_TEXT, CELL_END, - ROW_BEG, ROW_END, TAB_BEG, TAB_END) = list(range(7)) +(CELL_BEG, CELL_TEXT, CELL_END, ROW_BEG, ROW_END, TAB_BEG, + TAB_END) = list(range(7)) FIRST_ROW, SUBSEQ_ROW = list(range(2)) @@ -489,22 +495,22 @@ def str_incr(str_counter): # #------------------------------------------------------------------------ -class Tab_Cell: +class TabCell: def __init__(self, colchar, span, head, content): self.colchar = colchar self.span = span self.head = head self.content = content -class Tab_Row: +class TabRow: def __init__(self): - self.cells =[] + self.cells = [] self.tail = '' self.addit = '' # for: \\hline, \\cline{} -class Tab_Mem: +class TabMem: def __init__(self, head): self.head = head - self.tail ='' - self.rows =[] + self.tail = '' + self.rows = [] #------------------------------------------------------------------------ # @@ -513,25 +519,7 @@ class Tab_Mem: #------------------------------------------------------------------------ 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('}','\\}') - # replace character unknown to LaTeX - text = text.replace('→','$\\longrightarrow$') - 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 + Escape the following special characters: & $ % # _ { } """ text = text.replace('&', '\\&') text = text.replace('$', '\\$') @@ -540,14 +528,22 @@ def latexescapeverbatim(text): text = text.replace('_', '\\_') text = text.replace('{', '\\{') text = text.replace('}', '\\}') + # replace character unknown to LaTeX + text = text.replace('→', '$\\longrightarrow$') + return text + +def latexescapeverbatim(text): + """ + Escape special characters and also make sure that LaTeX respects whitespace + and newlines correctly. + """ + text = latexescape(text) 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.1\\grbaseindent}\\ ') - # replace character unknown to LaTeX - text = text.replace('→','$\\longrightarrow$') return text #------------------------------------------------------------------------ @@ -563,12 +559,12 @@ class LateXBackend(DocBackend): """ # overwrite base class attributes, they become static var of LaTeXDoc SUPPORTED_MARKUP = [ - DocBackend.BOLD, - DocBackend.ITALIC, - DocBackend.UNDERLINE, - DocBackend.FONTSIZE, - DocBackend.FONTFACE, - DocBackend.SUPERSCRIPT ] + DocBackend.BOLD, + DocBackend.ITALIC, + DocBackend.UNDERLINE, + DocBackend.FONTSIZE, + DocBackend.FONTFACE, + DocBackend.SUPERSCRIPT] STYLETAG_MARKUP = { DocBackend.BOLD : ("\\textbf{", "}"), @@ -634,13 +630,13 @@ class TexFont: if style: self.font_beg = style.font_beg self.font_end = style.font_end - self.leftIndent = style.left_indent - self.firstLineIndent = style.firstLineIndent + self.left_indent = style.left_indent + self.first_line_indent = style.first_line_indent else: self.font_beg = "" self.font_end = "" - self.leftIndent = "" - self.firstLineIndent = "" + self.left_indent = "" + self.first_line_indent = "" #------------------------------------------------------------------ @@ -691,9 +687,9 @@ class LaTeXDoc(BaseDoc, TextDoc): if span > 1: # phantom columns prior to multicolumns for col in range(self.curcol - span, self.curcol - 1): col_char = get_charform(col) - phantom = Tab_Cell(col_char, 0, '', '') + phantom = TabCell(col_char, 0, '', '') self.tabrow.cells.append(phantom) - self.tabcell = Tab_Cell(self.curcol_char, span, text, '') + self.tabcell = TabCell(self.curcol_char, span, text, '') elif tab_state == CELL_TEXT: self.textmem.append(text) elif tab_state == CELL_END: # text == '' @@ -701,13 +697,13 @@ class LaTeXDoc(BaseDoc, TextDoc): if self.tabcell.content.find('\\centering') != -1: self.tabcell.content = self.tabcell.content.replace( - '\\centering', '') + '\\centering', '') self.tabcell.head = re.sub( TBLFMT_PAT, '\\1c\\2', self.tabcell.head) self.tabrow.cells.append(self.tabcell) self.textmem = [] elif tab_state == ROW_BEG: - self.tabrow = Tab_Row() + self.tabrow = TabRow() elif tab_state == ROW_END: self.tabrow.addit = text # text: \\hline, \\cline{} self.tabrow.tail = ''.join(self.textmem) # \\\\ row-termination @@ -717,8 +713,8 @@ class LaTeXDoc(BaseDoc, TextDoc): self.tabmem.rows.append(self.tabrow) elif tab_state == TAB_BEG: # text: \\begin{longtable}[l]{ self._backend.write(''.join(('\\grinittab{\\textwidth}{', - repr(1.0/self.numcols), '}%\n'))) - self.tabmem = Tab_Mem(text) + repr(1.0/self.numcols), '}%\n'))) + self.tabmem = TabMem(text) elif tab_state == TAB_END: # text: \\end{longtable} self.tabmem.tail = text @@ -740,8 +736,8 @@ class LaTeXDoc(BaseDoc, TextDoc): # extract cell.contents bare_contents = [cell.content.strip(SEPARATION_PAT).replace( - '\n', '').split(SEPARATION_PAT) - for cell in self.tabrow.cells] + '\n', '').split(SEPARATION_PAT) for cell in self.tabrow.cells] + # mk equal length & transpose num_new_rows = max([len(mult_row_cont) for mult_row_cont in bare_contents]) @@ -759,17 +755,20 @@ class LaTeXDoc(BaseDoc, TextDoc): self.pict = transp_cont[0][-1] last_cell -= 1 self.numcols -= 1 - self._backend.write(''.join(('\\addtolength{\\grtabwidth}{-', - repr(self.pict_width), '\\grbaseindent -2\\tabcolsep}%\n'))) + self._backend.write(''.join( + ('\\addtolength{\\grtabwidth}{-', + repr(self.pict_width), + '\\grbaseindent -2\\tabcolsep}%\n'))) self.pict_in_table = False # new row-col structure for row in range(num_new_rows): - new_row = Tab_Row() + new_row = TabRow() for i in range(first_cell, last_cell): - new_cell = Tab_Cell(get_charform(i + first_cell), - self.tabrow.cells[i].span, self.tabrow.cells[i].head, - transp_cont[row][i + first_cell]) + new_cell = TabCell( + get_charform(i + first_cell), + self.tabrow.cells[i].span, self.tabrow.cells[i].head, + transp_cont[row][i + first_cell]) new_row.cells.append(new_cell) new_row.tail = self.tabrow.tail new_row.addit = '' @@ -796,80 +795,91 @@ class LaTeXDoc(BaseDoc, TextDoc): if cell.span == 0: continue if cell.content.startswith('\\grmkpicture'): - self._backend.write(''.join(('\\setlength{\\grpictsize}{', - self.pict_width, '\\grbaseindent}%\n'))) + self._backend.write( + ''.join(('\\setlength{\\grpictsize}{', + self.pict_width, '\\grbaseindent}%\n'))) else: for part in cell.content.split(SEPARATION_PAT): - self._backend.write(''.join(('\\grtextneedwidth{', - part, '}%\n'))) + self._backend.write( + ''.join(('\\grtextneedwidth{', part, '}%\n'))) row.cells[col_num].content = cell.content.replace( - SEPARATION_PAT, '~\\newline \n') + SEPARATION_PAT, '~\\newline \n') if cell.span == 1: self._backend.write(''.join(('\\grsetreqfull%\n'))) elif cell.span > 1: - self._backend.write(''.join(('\\grsetreqpart{\\grcolbeg', - get_charform(get_numform(cell.colchar) - cell.span +1), - '}%\n'))) + self._backend.write( + ''.join(('\\grsetreqpart{\\grcolbeg', + get_charform(get_numform(cell.colchar) - + cell.span +1), + '}%\n'))) - self._backend.write(''.join(('\\grcolsfirstfix', - ' {\\grcolbeg', col_char, '}{\\grtempwidth', col_char, - '}{\\grfinalwidth', col_char, '}{\\grpictreq', col_char, - '}{\\grtextreq', col_char, '}%\n'))) + self._backend.write( + ''.join(('\\grcolsfirstfix', + ' {\\grcolbeg', col_char, '}{\\grtempwidth', col_char, + '}{\\grfinalwidth', col_char, '}{\\grpictreq', + col_char, '}{\\grtextreq', col_char, '}%\n'))) self._backend.write(''.join(('\\grdividelength%\n'))) for col_char in tabcol_chars: - self._backend.write(''.join(('\\grcolssecondfix', - ' {\\grcolbeg', col_char, '}{\\grtempwidth', col_char, - '}{\\grfinalwidth', col_char, '}{\\grpictreq', col_char, - '}%\n'))) + self._backend.write( + ''.join(('\\grcolssecondfix', + ' {\\grcolbeg', col_char, '}{\\grtempwidth', col_char, + '}{\\grfinalwidth', col_char, '}{\\grpictreq', + col_char, '}%\n'))) self._backend.write(''.join(('\\grdividelength%\n'))) for col_char in tabcol_chars: - self._backend.write(''.join(('\\grcolsthirdfix', - ' {\\grcolbeg', col_char, '}{\\grtempwidth', col_char, - '}{\\grfinalwidth', col_char, '}%\n'))) + self._backend.write( + ''.join(('\\grcolsthirdfix', + ' {\\grcolbeg', col_char, '}{\\grtempwidth', col_char, + '}{\\grfinalwidth', col_char, '}%\n'))) self._backend.write(''.join(('\\grdividelength%\n'))) for col_char in tabcol_chars: - self._backend.write(''.join(('\\grcolsfourthfix', - ' {\\grcolbeg', col_char, '}{\\grtempwidth', col_char, - '}{\\grfinalwidth', col_char, '}%\n'))) + self._backend.write( + ''.join(('\\grcolsfourthfix', + ' {\\grcolbeg', col_char, '}{\\grtempwidth', col_char, + '}{\\grfinalwidth', col_char, '}%\n'))) self.multcol_alph_counter = str_incr(MULTCOL_COUNT_BASE) for row in self.tabmem.rows: for cell in row.cells: if cell.span > 1: multcol_alph_id = next(self.multcol_alph_counter) - self._backend.write(''.join(('\\grgetspanwidth{', - '\\grspanwidth', multcol_alph_id, - '}{\\grcolbeg', get_charform(get_numform(cell.colchar)- - cell.span + 1), - '}{\\grcolbeg', cell.colchar, - '}{\\grtempwidth', cell.colchar, - '}%\n'))) + self._backend.write( + ''.join(('\\grgetspanwidth{', + '\\grspanwidth', multcol_alph_id, + '}{\\grcolbeg', get_charform( + get_numform(cell.colchar)- cell.span + 1), + '}{\\grcolbeg', cell.colchar, + '}{\\grtempwidth', cell.colchar, + '}%\n'))) def write_table(self): # Choosing RaggedRight (with hyphenation) in table and # provide manually adjusting of column widths - self._backend.write(''.join(( - '%\n', self.pict, - '%\n%\n', - '% ==> Comment out one of the two lines ', - 'by a leading "%" (first position)\n', - '{ \\RaggedRight% left align with hyphenation in table \n', - '%{% no left align in table \n%\n', - '% ==> You may add pos or neg values ', - 'to the following ', repr(self.numcols), ' column widths %\n'))) + self._backend.write( + ''.join(( + '%\n', self.pict, + '%\n%\n', + '% ==> Comment out one of the two lines ', + 'by a leading "%" (first position)\n', + '{ \\RaggedRight% left align with hyphenation in table \n', + '%{% no left align in table \n%\n', + '% ==> You may add pos or neg values ', + 'to the following ', repr(self.numcols), ' column widths %\n'))) for col_num in range(self.numcols): - self._backend.write(''.join(('\\addtolength{\\grtempwidth', - get_charform(col_num), '}{+0.0cm}%\n'))) + self._backend.write( + ''.join(('\\addtolength{\\grtempwidth', + get_charform(col_num), '}{+0.0cm}%\n'))) self._backend.write('% === %\n') # adjust & open table': if self.pict: - self._backend.write(''.join(('%\n\\vspace{\\grtabprepos}%\n', - '\\setlength{\\grtabprepos}{0ex}%\n'))) + self._backend.write( + ''.join(('%\n\\vspace{\\grtabprepos}%\n', + '\\setlength{\\grtabprepos}{0ex}%\n'))) self.pict = '' self._backend.write(''.join(self.tabmem.head)) @@ -887,7 +897,7 @@ class LaTeXDoc(BaseDoc, TextDoc): self._backend.write('\\endfoot%\n') if self.head_line: self._backend.write('\\hline%\n') - self.head_line= False + self.head_line = False else: self._backend.write('%\n') self._backend.write(complete_row) @@ -902,7 +912,7 @@ class LaTeXDoc(BaseDoc, TextDoc): self._backend.write(''.join((''.join(self.tabmem.tail), '}%\n\n'))) def mk_splitting_row(self, row): - splitting =[] + splitting = [] add_vdots = '\\grempty' for cell in row.cells: if cell.span == 0: @@ -914,13 +924,14 @@ class LaTeXDoc(BaseDoc, TextDoc): cell_width = ''.join(('\\grtempwidth', cell.colchar)) else: cell_width = ''.join(('\\grspanwidth', - next(self.multcol_alph_counter))) - splitting.append(''.join(('\\grtabpgbreak{', cell.head, '}{', - cell_width, '}{', add_vdots, '}{+2ex}%\n'))) + next(self.multcol_alph_counter))) + splitting.append( + ''.join(('\\grtabpgbreak{', cell.head, '}{', + cell_width, '}{', add_vdots, '}{+2ex}%\n'))) return ''.join((' & '.join(splitting), '%\n', row.tail)) def mk_complete_row(self, row): - complete =[] + complete = [] for cell in row.cells: if cell.span == 0: continue @@ -928,9 +939,10 @@ class LaTeXDoc(BaseDoc, TextDoc): cell_width = ''.join(('\\grtempwidth', cell.colchar)) else: cell_width = ''.join(('\\grspanwidth', - next(self.multcol_alph_counter))) - complete.append(''.join(('\\grcolpart{%\n ', cell.head, - '}{%\n', cell_width, '}{%\n ', cell.content, '%\n}%\n'))) + next(self.multcol_alph_counter))) + complete.append( + ''.join(('\\grcolpart{%\n ', cell.head, '}{%\n', cell_width, + '}{%\n ', cell.content, '%\n}%\n'))) return ''.join((' & '.join(complete), '%\n', row.tail, row.addit)) # --------------------------------------------------------------------- @@ -1014,10 +1026,10 @@ class LaTeXDoc(BaseDoc, TextDoc): thisstyle.font_beg += " " thisstyle.font_end += " " - left = style.get_left_margin() + left = style.get_left_margin() first = style.get_first_indent() + left - thisstyle.leftIndent = left - thisstyle.firstLineIndent = first + thisstyle.left_indent = left + thisstyle.first_line_indent = first self.latexstyle[style_name] = thisstyle @@ -1045,10 +1057,10 @@ class LaTeXDoc(BaseDoc, TextDoc): self.fbeg = ltxstyle.font_beg self.fend = ltxstyle.font_end - self.indent = ltxstyle.leftIndent - self.FLindent = ltxstyle.firstLineIndent + self.indent = ltxstyle.left_indent + self.first_line_indent = ltxstyle.first_line_indent if self.indent == 0: - self.indent = self.FLindent + self.indent = self.first_line_indent # For additional vertical space beneath title line(s) # i.e. when the first centering ended: @@ -1059,8 +1071,8 @@ class LaTeXDoc(BaseDoc, TextDoc): self.in_multrow_cell = True else: if leader: - self._backend.write(''.join(('\\grprepleader{', leader, - '}%\n'))) + self._backend.write( + ''.join(('\\grprepleader{', leader, '}%\n'))) else: self._backend.write('\\grprepnoleader%\n') @@ -1070,14 +1082,15 @@ class LaTeXDoc(BaseDoc, TextDoc): # there another value might be choosen. # ------------------------------------------------------------------- if self.indent is not None: - self._backend.write(''.join(('\\grminpghead{', - repr(self.indent), '}{', repr(self.pict_width), '}%\n'))) + self._backend.write( + ''.join(('\\grminpghead{', repr(self.indent), '}{', + repr(self.pict_width), '}%\n'))) self.fix_indent = True if leader is not None and not self.in_list: self.in_list = True self._backend.write(''.join(('\\grlisthead{', leader, - '}%\n'))) + '}%\n'))) if leader is None: self.emit('\n') @@ -1116,7 +1129,7 @@ class LaTeXDoc(BaseDoc, TextDoc): def end_superscript(self): self.emit('}') - def start_table(self, name,style_name): + def start_table(self, name, style_name): """Begin new table""" self.in_table = True self.currow = 0 @@ -1149,7 +1162,7 @@ class LaTeXDoc(BaseDoc, TextDoc): if self.doline: if self.skipfirst: self.emit(''.join((('\\cline{2-%d}' % - self.numcols), '%\n')), ROW_END) + self.numcols), '%\n')), ROW_END) else: self.emit('\\hline %\n', ROW_END) else: @@ -1171,10 +1184,10 @@ class LaTeXDoc(BaseDoc, TextDoc): # values imported here are used for test '==1' and '!=0'. To get # local boolean values the tests are now transfered to the import lines # ------------------------------------------------------------------ - self.lborder = 1 == self.cstyle.get_left_border() - self.rborder = 1 == self.cstyle.get_right_border() - self.bborder = 1 == self.cstyle.get_bottom_border() - self.tborder = 0 != self.cstyle.get_top_border() + self.lborder = self.cstyle.get_left_border() == 1 + self.rborder = self.cstyle.get_right_border() == 1 + self.bborder = self.cstyle.get_bottom_border() == 1 + self.tborder = self.cstyle.get_top_border() != 0 # self.llist not needed any longer. # now column widths are arranged in self.calc_latex_widths() @@ -1207,45 +1220,44 @@ class LaTeXDoc(BaseDoc, TextDoc): self.emit('', CELL_END) - def add_media(self, infile, pos, x, y, alt='', - style_name=None, crop=None): + def add_media(self, infile, pos, x, y, alt='', style_name=None, crop=None): """Add photo to report""" outfile = os.path.splitext(infile)[0] pictname = latexescape(os.path.split(outfile)[1]) outfile = ''.join((outfile, '.jpg')) outfile2 = ''.join((outfile, '.jpeg')) outfile3 = ''.join((outfile, '.png')) - if HAVE_PIL and infile not in [outfile, outfile2, outfile3] : + if HAVE_PIL and infile not in [outfile, outfile2, outfile3]: try: curr_img = Image.open(infile) curr_img.save(outfile) - px, py = curr_img.size - if py > px: - y = y*py/px + width, height = curr_img.size + if height > width: + y = y*height/width except IOError: self.emit(''.join(('%\n *** Error: cannot convert ', infile, - '\n *** to ', outfile, - '%\n'))) + '\n *** to ', outfile, + '%\n'))) elif not HAVE_PIL: - self.emit(''.join(('%\n *** Error: cannot convert ', infile, - '\n *** to ', outfile, - 'PIL not installed %\n'))) + self.emit(''.join(('%\n *** Error: cannot convert ', infile, + '\n *** to ', outfile, + 'PIL not installed %\n'))) if self.in_table: self.pict_in_table = True self.emit(''.join(('\\grmkpicture{', outfile, '}{', repr(x), '}{', - repr(y), '}{', pictname, '}%\n'))) + repr(y), '}{', pictname, '}%\n'))) self.pict_width = x self.pict_height = y - def write_text(self,text,mark=None,links=False): + def write_text(self, text, mark=None, links=False): """Write the text to the file""" if text == '\n': text = '' text = latexescape(text) - if links == True: + if links is True: text = re.sub(URL_PATTERN, _CLICKABLE, text) #hard coded replace of the underline used for missing names/data @@ -1277,7 +1289,7 @@ class LaTeXDoc(BaseDoc, TextDoc): markuptext = self._backend.add_markup_from_styled(text, s_tags) - if links == True: + if links is True: markuptext = re.sub(URL_PATTERN, _CLICKABLE, markuptext) markuptext = self._backend.add_markup_from_styled(text, s_tags) diff --git a/gramps/plugins/docgen/odfdoc.py b/gramps/plugins/docgen/odfdoc.py index af2d13ae1..229079f10 100644 --- a/gramps/plugins/docgen/odfdoc.py +++ b/gramps/plugins/docgen/odfdoc.py @@ -28,34 +28,6 @@ ODFDoc : used to generate Open Office Document """ -#------------------------------------------------------------------------- -# -# pylint : disable messages ... -# -#------------------------------------------------------------------------- -# disable-msg=C0302 # Too many lines in module -# pylint: disable-msg=C0302 -# disable-msg # Regular expression which should only match -# pylint: disable-msg=C0103 -# disable-msg=R0902 # Too many instance attributes -# pylint: disable-msg=R0902 -# disable-msg=R0904 # Too many public methods -# pylint: disable-msg=R0904 -# disable-msg=R0912 # Too many branches -# pylint: disable-msg=R0912 -# disable-msg=R0913 # Too many arguments -# pylint: disable-msg=R0913 -# disable-msg=R0914 # Too many local variables -# pylint: disable-msg=R0914 -# disable-msg=R0915 # Too many statements -# pylint: disable-msg=R0915 -# warnings : -# disable-msg=W0613 # Unused argument -# pylint: disable-msg=W0613 -# errors : -# disable-msg=E1101 # has no member -# pylint: disable-msg=E1101 - #------------------------------------------------------------------------- # # Standard Python Modules @@ -66,26 +38,27 @@ from hashlib import md5 import zipfile import time from io import StringIO -from math import pi, cos, sin, degrees, radians +from math import cos, sin, radians from xml.sax.saxutils import escape +import re #------------------------------------------------------------------------- # # Gramps modules # #------------------------------------------------------------------------- -from gramps.gen.plug.docgen import (BaseDoc, TextDoc, DrawDoc, graphicstyle, - FONT_SANS_SERIF, SOLID, PAPER_PORTRAIT, - INDEX_TYPE_TOC, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT, - INDEX_TYPE_ALP, PARA_ALIGN_RIGHT, URL_PATTERN, - LOCAL_HYPERLINK, LOCAL_TARGET) +from gramps.gen.plug.docgen import ( + BaseDoc, TextDoc, DrawDoc, graphicstyle, FONT_SANS_SERIF, SOLID, + PAPER_PORTRAIT, INDEX_TYPE_TOC, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT, + INDEX_TYPE_ALP, PARA_ALIGN_RIGHT, URL_PATTERN, LOCAL_HYPERLINK, + LOCAL_TARGET) from gramps.gen.plug.docgen.fontscale import string_width from gramps.plugins.lib.libodfbackend import OdfBackend from gramps.gen.const import PROGRAM_NAME, URL_HOMEPAGE from gramps.version import VERSION from gramps.gen.plug.report import utils as ReportUtils from gramps.gen.utils.image import (image_size, image_dpi, image_actual_size, - crop_percentage_to_subpixel) + crop_percentage_to_subpixel) from gramps.gen.errors import ReportError #------------------------------------------------------------------------- @@ -96,9 +69,9 @@ from gramps.gen.errors import ReportError from gramps.gen.const import GRAMPS_LOCALE as glocale _ = glocale.translation.gettext -_apptype = 'application/vnd.oasis.opendocument.text' +APP_TYPE = 'application/vnd.oasis.opendocument.text' -_esc_map = { +ESC_MAP = { '\x1a' : '', '\x0c' : '', '\n' : '', @@ -110,9 +83,8 @@ _esc_map = { # regexp for Styled Notes ... # #------------------------------------------------------------------------- -import re # Hyphen is added because it is used to replace spaces in the font name -NewStyle = re.compile('style-name="([a-zA-Z0-9]*)__([#a-zA-Z0-9 -]*)__">') +NEW_STYLE = re.compile('style-name="([a-zA-Z0-9]*)__([#a-zA-Z0-9 -]*)__">') #------------------------------------------------------------------------- # @@ -457,15 +429,15 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): self.new_cell = 0 self.page = 0 self.first_page = 1 - self.StyleList_notes = [] # styles to create depending on styled notes. - self.StyleList_photos = [] # styles to create depending on clipped images. + self.stylelist_notes = [] # styles to create for styled notes. + self.stylelist_photos = [] # styles to create for clipped images. def open(self, filename): """ Open the new document """ - t = time.localtime(time.time()) - self.time = "%04d-%02d-%02dT%02d:%02d:%02d" % t[:6] + now = time.localtime(time.time()) + self.time = "%04d-%02d-%02dT%02d:%02d:%02d" % now[:6] self.filename = filename if not filename.endswith("odt"): @@ -482,7 +454,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): Create the document header """ - assert (not self.init_called) + assert not self.init_called self.init_called = True wrt = self.cntnt.write wrt1, wrt2 = self.cntnt1.write, self.cntnt2.write @@ -490,59 +462,78 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): self.lang = glocale.lang self.lang = self.lang.replace('_', '-') if self.lang else "en-US" - self.StyleList_notes = [] # styles to create depending on styled notes. - wrt1('\n' - '\n' + - '\n' + self.stylelist_notes = [] # styles to create depending on styled notes. + wrt1('\n' + + '\n' + + '\n' ) wrt1('\n' + - _FONTS + _FONTS ) - wrt2( - '\n' + - '\n' + - _AUTOMATIC_STYLES + wrt2('\n' + + '\n' + + _AUTOMATIC_STYLES ) styles = self.get_style_sheet() for style_name in styles.get_draw_style_names(): style = styles.get_draw_style(style_name) - wrt( - '\n' - '\n' + '\n' + '\n' + ) wrt( - 'svg:fill-color="#%02x%02x%02x" ' - % style.get_color() + - 'draw:fill-color="#%02x%02x%02x" ' - % style.get_fill_color() + + '\n' + '\n' ) - wrt( - '\n' - '\n' - '\n' - ) - # Graphic style for items with a clear background wrt( _CLEAR_STYLE @@ -589,16 +557,16 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): wrt( '\n' % style_name + - '\n' + + 'style:family="paragraph" ' + + 'style:parent-style-name="%s">\n' % style_name + + '\n' + '\n' + '\n' + - '\n' + + '\n' + '\n' - ) + ) - wrt( - '\n' + - '\n' + + ' ' % font.get_size() + '\n' - ) + ) for style_name in styles.get_table_style_names(): style = styles.get_table_style(style_name) table_width = float(self.get_usable_width()) table_width_str = "%.2f" % table_width - wrt( - '\n' '\n' + + 'style:width="%scm" ' % table_width_str + + '/>\n' + '\n' - ) + ) for col in range(0, min(style.get_columns(), 50)): width = table_width * float(style.get_column_width(col) / 100.0) width_str = "%.4f" % width - wrt( - '' + - '' % width_str + + wrt('' + + '' % width_str + '\n' - ) + ) for cell in styles.get_cell_style_names(): cell_style = styles.get_cell_style(cell) - wrt( - '\n' + '\n' + wrt('/>\n' '\n' - ) + ) wrt( _OTHER_STYLES @@ -771,7 +721,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): We want no duplicate in the list """ # order preserving - funct = funct or (lambda x:x) + funct = funct or (lambda x: x) seen = set() result = [] for item in list_: @@ -789,7 +739,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): The content.xml file is closed. """ self.cntntx = StringIO() - self.StyleList_notes = self.uniq(self.StyleList_notes) + self.stylelist_notes = self.uniq(self.stylelist_notes) self.add_styled_notes_fonts() self.add_styled_notes_styles() self.add_styled_photo_styles() @@ -823,16 +773,15 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): """ # Need to add new font for styled notes here. wrt1 = self.cntnt1.write - for style in self.StyleList_notes: + for style in self.stylelist_notes: if style[1] == "FontFace": # Restore any spaces that were replaced by hyphens in # libodfbackend - wrt1( - '\n\n' + wrt1('\n\n' ) def add_styled_notes_styles(self): @@ -841,53 +790,49 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): """ # Need to add new style for styled notes here. wrt2 = self.cntnt2.write - for style in self.StyleList_notes: + for style in self.stylelist_notes: if style[1] == "FontSize": - wrt2( - '\n' + - ' \n' % style[2] + - '\n\n' + wrt2('\n' + + ' \n' % style[2] + + '\n\n' ) elif style[1] == "FontColor": # Restore the hash at the start that was removed by # libodfbackend - wrt2( - '\n' + - ' \n' % style[2] + - '\n\n' + wrt2('\n' + + ' \n' % style[2] + + '\n\n' ) elif style[1] == "FontHighlight": - wrt2( - '\n' + - ' \n' % style[2] + - '\n\n' + wrt2('\n' + + ' \n' % style[2] + + '\n\n' ) elif style[1] == "FontFace": # Restore any spaces that were replaced by hyphens in # libodfbackend - wrt2( - '\n' + - ' \n' + - '\n\n' + wrt2('\n' + + ' \n' + + '\n\n' ) def add_styled_photo_styles(self): @@ -895,110 +840,107 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): Add the new styles for clipped images in the automatic-styles section. """ wrt2 = self.cntnt2.write - for style in self.StyleList_photos: + for style in self.stylelist_photos: if style[0] == "Left": - wrt2( - '' + - '' + - '\n' + wrt2('' + + '' + + '\n' ) elif style[0] == "Right": - wrt2( - '' + - '' + - '\n' + wrt2('' + + '' + + '\n' ) elif style[0] == "Single": - wrt2( - '' + - '' + - '\n' + wrt2('' + + '' + + '\n' ) else: - wrt2( - '' + - '' + - '\n' + wrt2('' + + '' + + '\n' ) - def add_media(self, file_name, pos, x_cm, y_cm, alt='', style_name=None, crop=None): + def add_media(self, file_name, pos, x_cm, y_cm, alt='', style_name=None, + crop=None): """ Add multi-media documents : photos """ @@ -1015,7 +957,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): odf_name = md5(file_name_hash).hexdigest() + extension media_list_item = (file_name, odf_name) - if not media_list_item in self.media_list: + if media_list_item not in self.media_list: self.media_list.append(media_list_item) base = escape(os.path.basename(file_name)) @@ -1027,11 +969,11 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): pos = pos.title() if pos in ['left', 'right', 'single'] else 'Row' if crop: - (start_x, start_y, end_x, end_y - ) = crop_percentage_to_subpixel(x, y, crop) + (start_x, start_y, + end_x, end_y) = crop_percentage_to_subpixel(x, y, crop) - # Need to keep the ratio intact, otherwise scaled images look stretched - # if the dimensions aren't close in size + # Need to keep the ratio intact, otherwise scaled images look + # stretched if the dimensions aren't close in size (act_width, act_height) = image_actual_size( x_cm, y_cm, int(end_x-start_x), int(end_y-start_y) ) @@ -1045,7 +987,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): bottom = (y - end_y)/dpi[1] crop = (top, right, bottom, left) - self.StyleList_photos.append( + self.stylelist_photos.append( [pos, crop] ) @@ -1057,25 +999,25 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): if len(alt): self.cntnt.write( ' ' + - ' ' % act_height + - '' % style_name - ) + 'draw:name="caption_%s" ' % tag + + 'text:anchor-type="paragraph" ' + + 'svg:y="0in" ' + + 'svg:width="%.2fcm" ' % act_width + + 'draw:z-index="34"> ' + + ' ' % act_height + + '' % style_name + ) self.cntnt.write( '' + - '\n' + + 'draw:name="%s" ' % tag + + 'text:anchor-type="paragraph" ' + + 'svg:width="%.2fcm" ' % act_width + + 'svg:height="%.2fcm" ' % act_height + + 'draw:z-index="1" >' + + '\n' + '\n' ) @@ -1096,7 +1038,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): """ self.cntnt.write( '\n' % style_name + 'table:style-name="%s">\n' % style_name ) styles = self.get_style_sheet() @@ -1133,7 +1075,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): self.span = span self.cntnt.write( ' 1: self.cntnt.write(' table:number-columns-spanned="%s">\n' % span) @@ -1174,12 +1116,12 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): """ self.cntnt.write('') - def _add_zip(self, zfile, name, data, t): + def _add_zip(self, zfile, name, data, date_time): """ Add a zip file to an archive """ zipinfo = zipfile.ZipInfo(name) - zipinfo.date_time = t + zipinfo.date_time = date_time zipinfo.compress_type = zipfile.ZIP_DEFLATED zipinfo.external_attr = 0o644 << 16 zfile.writestr(zipinfo, data) @@ -1196,14 +1138,15 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): except: raise ReportError(_("Could not create %s") % self.filename) - t = time.localtime(time.time())[:6] + now = time.localtime(time.time())[:6] - self._add_zip(zfile, "META-INF/manifest.xml", self.mfile.getvalue(), t) - self._add_zip(zfile, "content.xml", self.cntntx.getvalue(), t) - self._add_zip(zfile, "meta.xml", self.meta.getvalue(), t) - self._add_zip(zfile, "settings.xml", self.stfile.getvalue(), t) - self._add_zip(zfile, "styles.xml", self.sfile.getvalue(), t) - self._add_zip(zfile, "mimetype", self.mimetype.getvalue(), t) + self._add_zip(zfile, "META-INF/manifest.xml", self.mfile.getvalue(), + now) + self._add_zip(zfile, "content.xml", self.cntntx.getvalue(), now) + self._add_zip(zfile, "meta.xml", self.meta.getvalue(), now) + self._add_zip(zfile, "settings.xml", self.stfile.getvalue(), now) + self._add_zip(zfile, "styles.xml", self.sfile.getvalue(), now) + self._add_zip(zfile, "mimetype", self.mimetype.getvalue(), now) self.mfile.close() self.cntnt.close() @@ -1215,7 +1158,8 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): for image in self.media_list: try: with open(image[0], mode='rb') as ifile: - self._add_zip(zfile, "Pictures/%s" % image[1], ifile.read(), t) + self._add_zip(zfile, "Pictures/%s" % image[1], + ifile.read(), now) except OSError as msg: errmsg = "%s\n%s" % (_("Could not open %s") % image[0], msg) @@ -1231,37 +1175,36 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): wrtf('\n') wrtf('\n' + _XMLNS + + 'office:version="1.0">\n' ) wrtf('\n' + - _FONTS + - '\n' + _FONTS + + '\n' ) wrtf('\n' + - _STYLES + _STYLES ) styles = self.get_style_sheet() for style_name in styles.get_paragraph_style_names(): style = styles.get_paragraph_style(style_name) - wrtf( - '\n' + - '\n' + + ' ' + - ' ' + + '\n' - '\n' + wrtf('/>\n' + '\n' ) # Dash lengths are based on the OpenOffice Ultrafine Dashed line style. for line_style in graphicstyle.line_style_names: dash_array = graphicstyle.get_line_style_by_name(line_style) wrtf('\n' % (line_style, dash_array[0], dash_array[0], dash_array[1] * 0.051)) + 'draw:dots1="%d" draw:dots1-length="0.102cm" ' + 'draw:dots2="%d" draw:dots2-length="0.102cm" ' + 'draw:distance="%5.3fcm" />\n' % + (line_style, dash_array[0], dash_array[0], + dash_array[1] * 0.051)) # Current no leading number format for headers @@ -1360,115 +1299,105 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): #wrtf('text:level="10" style:num-format=""/>\n') #wrtf('\n') - wrtf( - ' ' + wrtf(' ' ) - wrtf( - ' ' + wrtf(' ' ) - wrtf( - ' ' + wrtf(' ' ) wrtf('\n') - wrtf( - '\n' + - _SHEADER_FOOTER + - '\n' + - '\n' + + _SHEADER_FOOTER + + '\n' + + '\n' + - '\n' + - '\n' + wrtf('fo:margin-top="%.2fcm" ' + % self.paper.get_top_margin() + + 'fo:margin-bottom="%.2fcm" ' + % self.paper.get_bottom_margin() + + 'fo:margin-left="%.2fcm" ' + % self.paper.get_left_margin() + + 'fo:margin-right="%.2fcm" ' + % self.paper.get_right_margin() + + 'style:writing-mode="lr-tb" ' + + 'style:footnote-max-height="0cm">\n' + + '\n' + + '\n' ) # header - wrtf( - '\n' - '\n' - '\n' + wrtf('\n' + '\n' + '\n' ) # footer - wrtf( - '\n' - '\n' - '\n' + wrtf('\n' + '\n' + '\n' ) # End of page layout - wrtf( - '\n' - '\n' + wrtf('\n' + '\n' ) # Master Styles - wrtf( - '\n' - '\n' - # header - #'' - #'' - # How to get the document title here ? - #' TITRE : %s' % self.title - #'' - #'' - # footer - #'' - #'' - #'1' - #'/' - #'1' - #'' - #'' - #'' - # - '' - '\n' + wrtf('\n' + '\n' + # header + #'' + #'' + # How to get the document title here ? + #' TITRE : %s' % self.title + #'' + #'' + # footer + #'' + #'' + #'1' + #'/' + #'1' + #'' + #'' + #'' + # + '' + '\n' ) # End of document styles wrtf('\n') @@ -1540,7 +1469,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): s_tags = styledtext.get_tags() markuptext = self._backend.add_markup_from_styled(text, s_tags, '\n') - if links == True: + if links is True: markuptext = re.sub(URL_PATTERN, _CLICKABLE, markuptext) # we need to know if we have new styles to add. @@ -1551,12 +1480,12 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): # The first element is the StyleType and the second one is the value start = 0 while 1: - m = NewStyle.search(markuptext, start) + m = NEW_STYLE.search(markuptext, start) if not m: break - self.StyleList_notes.append([m.group(1)+m.group(2), - m.group(1), - m.group(2)]) + self.stylelist_notes.append([m.group(1)+m.group(2), + m.group(1), + m.group(2)]) start = m.end() linenb = 1 self.start_paragraph(style_name) @@ -1567,7 +1496,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): self.start_paragraph(style_name) linenb = 1 else: - if ( linenb > 1 ): + if linenb > 1: self.cntnt.write('') self.cntnt.write(line) linenb += 1 @@ -1576,13 +1505,13 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): def write_text(self, text, mark=None, links=False): """ Uses the xml.sax.saxutils.escape function to convert XML - entities. The _esc_map dictionary allows us to add our own + entities. The ESC_MAP dictionary allows us to add our own mappings. @param mark: IndexMark to use for indexing """ - text = escape(text, _esc_map) + text = escape(text, ESC_MAP) - if links == True: + if links is True: text = re.sub(URL_PATTERN, _CLICKABLE, text) self._write_mark(mark, text) @@ -1594,7 +1523,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): Insert a mark at this point in the document. """ if mark: - key = escape(mark.key, _esc_map) + key = escape(mark.key, ESC_MAP) key = key.replace('"', '"') if mark.type == INDEX_TYPE_ALP: self.cntnt.write( @@ -1650,7 +1579,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): self.cntnt.write('') self.cntnt.write('') self.cntnt.write('%s' % - title) + title) self.cntnt.write('') self.cntnt.write('') @@ -1686,7 +1615,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): self.cntnt.write('') self.cntnt.write('') self.cntnt.write('%s' % - title) + title) self.cntnt.write('') self.cntnt.write('') @@ -1705,7 +1634,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): 'xmlns:manifest="urn:oasis:names:tc:opendocument' + ':xmlns:manifest:1.0">' + '' ) @@ -1713,23 +1642,23 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): for image in self.media_list: self.mfile.write( '' ) # Footer self.mfile.write( '' + 'manifest:full-path="Pictures/"/>' '' + 'manifest:full-path="content.xml"/>' '' + 'manifest:full-path="styles.xml"/>' '' + 'manifest:full-path="settings.xml"/>' '' + 'manifest:full-path="meta.xml"/>' '\n' ) @@ -1742,12 +1671,12 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): # http://mashupguide.net/1.0/html/ch17s03.xhtml (Creative commons # licence): http://mashupguide.net/1.0/html/apas02.xhtml self.stfile.write( - '\n' + - '' + '\n' + + '' ) def _write_mimetype_file(self): @@ -1780,8 +1709,8 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): style_sheet = self.get_style_sheet() stype = style_sheet.get_draw_style(style) pname = stype.get_paragraph_style() - p = style_sheet.get_paragraph_style(pname) - font = p.get_font() + para = style_sheet.get_paragraph_style(pname) + font = para.get_font() size = font.get_size() height = size * (len(text)) @@ -1809,7 +1738,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): '\n' + '' % pname + '' % pname + - escape('\n'.join(text), _esc_map) + + escape('\n'.join(text), ESC_MAP) + '\n\n' + '\n') @@ -1833,9 +1762,9 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): 'draw:layer="layout" ' + 'draw:z-index="1" ' + 'svg:x="%2fcm" svg:y="%2fcm" ' - % (float(minx), float(miny)) + + % (float(minx), float(miny)) + 'svg:viewBox="0 0 %d %d" ' - % (int((maxx - minx) * 1000), int((maxy - miny) * 1000)) + + % (int((maxx - minx) * 1000), int((maxy - miny) * 1000)) + 'svg:width="%.4fcm" ' % (maxx - minx) + 'svg:height="%.4fcm" ' % (maxy - miny) ) @@ -1887,14 +1816,14 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): 'draw:style-name="%s" ' % style + 'svg:width="%.2fcm" ' % sw + 'svg:height="%.2fcm" ' - % (ReportUtils.pt2cm(font.get_size() * 1.4)) + + % (ReportUtils.pt2cm(font.get_size() * 1.4)) + 'svg:x="%.2fcm" ' % float(x) + 'svg:y="%.2fcm">' % float(y) + ' ' + '' % para_name + '' % para_name + #' fo:max-height="%.2f">' % font.get_size() + - escape(text, _esc_map) + + escape(text, ESC_MAP) + '' + '' + '\n' + @@ -1940,7 +1869,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): self.cntnt.write( '' % para_name + '' % para_name + - escape(text, _esc_map) + + escape(text, ESC_MAP) + '' '\n' ) @@ -1976,7 +1905,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): '' + '' % para_name + '' % para_name + - escape(text, _esc_map) + + escape(text, ESC_MAP) + '\n' + '\n' + '' @@ -1991,27 +1920,29 @@ def process_spaces(line, format): If the text is flowed (format==0), then leading spaces (after ignoring XML) are removed. Embedded multiple spaces are reduced to one by ODF - If the text is pre-formatted (format==1). then all spaces (after ignoring XML) - are replaced by "" + If the text is pre-formatted (format==1), then all spaces (after ignoring + XML) are replaced by "" - Returns the processed text, and the number of significant (i.e. non-white-space) chars. + Returns the processed text, and the number of significant + (i.e. non-white-space) chars. """ txt = "" xml = False sigcount = 0 - # we loop through every character, which is very inefficient, but an attempt to use - # a regex replace didn't always work. This was the code that was replaced. + # We loop through every character, which is very inefficient, but an attempt + # to use a regex replace didn't always work. This was the code that was + # replaced. # Problem, we may not replace ' ' in xml tags, so we use a regex # self.cntnt.write(re.sub(' (?=([^(<|>)]*<[^>]*>)*[^>]*$)', # "", line)) for char in line: - if char == '<' and xml == False: + if char == '<' and xml is False: xml = True txt += char - elif char == '>' and xml == True: + elif char == '>' and xml is True: xml = False txt += char - elif xml == True: + elif xml is True: txt += char elif char == " " or char == "\t": if format == 0 and sigcount == 0: diff --git a/gramps/plugins/docgen/rtfdoc.py b/gramps/plugins/docgen/rtfdoc.py index 7ee48e97c..7e8e3df07 100644 --- a/gramps/plugins/docgen/rtfdoc.py +++ b/gramps/plugins/docgen/rtfdoc.py @@ -24,24 +24,26 @@ #------------------------------------------------------------------------ # -# python modules +# Python modules # #------------------------------------------------------------------------ -from gramps.gen.const import GRAMPS_LOCALE as glocale -_ = glocale.translation.gettext import logging -LOG = logging.getLogger(".rtfdoc") #------------------------------------------------------------------------ # -# Load the base BaseDoc class +# Gramps modules # #------------------------------------------------------------------------ -from gramps.gen.plug.docgen import (BaseDoc, TextDoc, FONT_SERIF, PARA_ALIGN_RIGHT, - PARA_ALIGN_CENTER, PARA_ALIGN_JUSTIFY, - URL_PATTERN) -from gramps.gen.utils.image import image_size, image_actual_size, resize_to_jpeg_buffer +from gramps.gen.plug.docgen import ( + BaseDoc, TextDoc, FONT_SERIF, PARA_ALIGN_RIGHT, PARA_ALIGN_CENTER, + PARA_ALIGN_JUSTIFY, URL_PATTERN) +from gramps.gen.utils.image import (image_size, image_actual_size, + resize_to_jpeg_buffer) from gramps.gen.errors import ReportError +from gramps.gen.const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext + +LOG = logging.getLogger(".rtfdoc") #------------------------------------------------------------------------ # @@ -52,15 +54,18 @@ _CLICKABLE = r'''{\\field{\\*\\fldinst HYPERLINK "\1"}{\\fldrslt \1}}''' #------------------------------------------------------------------------ # -# RTF uses a unit called "twips" for its measurements. According to the -# RTF specification, 1 point is 20 twips. This routines converts -# centimeters to twips -# -# 2.54 cm/inch 72pts/inch, 20twips/pt +# Functions # #------------------------------------------------------------------------ -def twips(cm): - return int(((cm/2.54)*72)+0.5)*20 +def twips(length_cm): + """ + RTF uses a unit called "twips" for its measurements. According to the + RTF specification, 1 point is 20 twips. This routines converts + centimeters to twips + + 2.54 cm/inch 72pts/inch, 20twips/pt + """ + return int(((length_cm/2.54)*72)+0.5)*20 #------------------------------------------------------------------------ # @@ -68,25 +73,21 @@ def twips(cm): # use style sheets. Instead it writes raw formatting. # #------------------------------------------------------------------------ -class RTFDoc(BaseDoc,TextDoc): - - #-------------------------------------------------------------------- - # - # Opens the file, and writes the header. Builds the color and font - # tables. Fonts are chosen using the MS TrueType fonts, since it - # is assumed that if you are generating RTF, you are probably - # targeting Word. This generator assumes a Western Europe character - # set. - # - #-------------------------------------------------------------------- - def open(self,filename): +class RTFDoc(BaseDoc, TextDoc): + """ + Opens the file, and writes the header. Builds the color and font tables. + Fonts are chosen using the MS TrueType fonts, since it is assumed that if + you are generating RTF, you are probably targeting Word. This generator + assumes a Western Europe character set. + """ + def open(self, filename): if filename[-4:] != ".rtf": self.filename = filename + ".rtf" else: self.filename = filename try: - self.f = open(self.filename,"w") + self.file = open(self.filename, "w") except IOError as msg: errmsg = "%s\n%s" % (_("Could not create %s") % self.filename, msg) raise ReportError(errmsg) @@ -95,7 +96,7 @@ class RTFDoc(BaseDoc,TextDoc): style_sheet = self.get_style_sheet() - self.f.write( + self.file.write( '{\\rtf1\\ansi\\ansicpg1252\\deff0\n' '{\\fonttbl\n' '{\\f0\\froman\\fcharset0\\fprq0 Times New Roman;}\n' @@ -105,22 +106,22 @@ class RTFDoc(BaseDoc,TextDoc): self.color_map = {} index = 1 - self.color_map[(0,0,0)] = 0 - self.f.write('\\red0\\green0\\blue0;') + self.color_map[(0, 0, 0)] = 0 + self.file.write('\\red0\\green0\\blue0;') for style_name in style_sheet.get_paragraph_style_names(): style = style_sheet.get_paragraph_style(style_name) fgcolor = style.get_font().get_color() bgcolor = style.get_background_color() if fgcolor not in self.color_map: self.color_map[fgcolor] = index - self.f.write('\\red%d\\green%d\\blue%d;' % fgcolor) + self.file.write('\\red%d\\green%d\\blue%d;' % fgcolor) index += 1 if bgcolor not in self.color_map: - self.f.write('\\red%d\\green%d\\blue%d;' % bgcolor) + self.file.write('\\red%d\\green%d\\blue%d;' % bgcolor) self.color_map[bgcolor] = index index += 1 - self.f.write('}\n') - self.f.write( + self.file.write('}\n') + self.file.write( '\\kerning0\\cf0\\viewkind1' + '\\paperw%d' % twips(self.paper.get_size().get_width()) + '\\paperh%d' % twips(self.paper.get_size().get_height()) + @@ -139,8 +140,8 @@ class RTFDoc(BaseDoc,TextDoc): # #-------------------------------------------------------------------- def close(self): - self.f.write('}\n') - self.f.close() + self.file.write('}\n') + self.file.close() #-------------------------------------------------------------------- # @@ -148,7 +149,7 @@ class RTFDoc(BaseDoc,TextDoc): # #-------------------------------------------------------------------- def end_page(self): - self.f.write('\\sbkpage\n') + self.file.write('\\sbkpage\n') #-------------------------------------------------------------------- # @@ -157,70 +158,70 @@ class RTFDoc(BaseDoc,TextDoc): # does work. # #-------------------------------------------------------------------- - def start_paragraph(self,style_name,leader=None): + def start_paragraph(self, style_name, leader=None): self.opened = 0 style_sheet = self.get_style_sheet() - p = style_sheet.get_paragraph_style(style_name) + para = style_sheet.get_paragraph_style(style_name) # build font information - f = p.get_font() - size = f.get_size()*2 - bgindex = self.color_map[p.get_background_color()] - fgindex = self.color_map[f.get_color()] - if f.get_type_face() == FONT_SERIF: + font = para.get_font() + size = font.get_size()*2 + bgindex = self.color_map[para.get_background_color()] + fgindex = self.color_map[font.get_color()] + if font.get_type_face() == FONT_SERIF: self.font_type = '\\f0' else: self.font_type = '\\f1' - self.font_type += '\\fs%d\\cf%d\\cb%d' % (size,fgindex,bgindex) + self.font_type += '\\fs%d\\cf%d\\cb%d' % (size, fgindex, bgindex) - if f.get_bold(): + if font.get_bold(): self.font_type += "\\b" - if f.get_underline(): + if font.get_underline(): self.font_type += "\\ul" - if f.get_italic(): + if font.get_italic(): self.font_type += "\\i" # build paragraph information if not self.in_table: - self.f.write('\\pard') - if p.get_alignment() == PARA_ALIGN_RIGHT: - self.f.write('\\qr') - elif p.get_alignment() == PARA_ALIGN_CENTER: - self.f.write('\\qc') - self.f.write( - '\\ri%d' % twips(p.get_right_margin()) + - '\\li%d' % twips(p.get_left_margin()) + - '\\fi%d' % twips(p.get_first_indent()) + self.file.write('\\pard') + if para.get_alignment() == PARA_ALIGN_RIGHT: + self.file.write('\\qr') + elif para.get_alignment() == PARA_ALIGN_CENTER: + self.file.write('\\qc') + self.file.write( + '\\ri%d' % twips(para.get_right_margin()) + + '\\li%d' % twips(para.get_left_margin()) + + '\\fi%d' % twips(para.get_first_indent()) ) - if p.get_alignment() == PARA_ALIGN_JUSTIFY: - self.f.write('\\qj') - if p.get_padding(): - self.f.write('\\sa%d' % twips(p.get_padding()/2.0)) - if p.get_top_border(): - self.f.write('\\brdrt\\brdrs') - if p.get_bottom_border(): - self.f.write('\\brdrb\\brdrs') - if p.get_left_border(): - self.f.write('\\brdrl\\brdrs') - if p.get_right_border(): - self.f.write('\\brdrr\\brdrs') - if p.get_first_indent(): - self.f.write('\\fi%d' % twips(p.get_first_indent())) - if p.get_left_margin(): - self.f.write('\\li%d' % twips(p.get_left_margin())) - if p.get_right_margin(): - self.f.write('\\ri%d' % twips(p.get_right_margin())) + if para.get_alignment() == PARA_ALIGN_JUSTIFY: + self.file.write('\\qj') + if para.get_padding(): + self.file.write('\\sa%d' % twips(para.get_padding()/2.0)) + if para.get_top_border(): + self.file.write('\\brdrt\\brdrs') + if para.get_bottom_border(): + self.file.write('\\brdrb\\brdrs') + if para.get_left_border(): + self.file.write('\\brdrl\\brdrs') + if para.get_right_border(): + self.file.write('\\brdrr\\brdrs') + if para.get_first_indent(): + self.file.write('\\fi%d' % twips(para.get_first_indent())) + if para.get_left_margin(): + self.file.write('\\li%d' % twips(para.get_left_margin())) + if para.get_right_margin(): + self.file.write('\\ri%d' % twips(para.get_right_margin())) if leader: self.opened = 1 - self.f.write('\\tx%d' % twips(p.get_left_margin())) - self.f.write('{%s ' % self.font_type) + self.file.write('\\tx%d' % twips(para.get_left_margin())) + self.file.write('{%s ' % self.font_type) self.write_text(leader) - self.f.write(self.text) + self.file.write(self.text) self.text = "" - self.f.write('\\tab}') + self.file.write('\\tab}') self.opened = 0 #-------------------------------------------------------------------- @@ -233,20 +234,21 @@ class RTFDoc(BaseDoc,TextDoc): #-------------------------------------------------------------------- def end_paragraph(self): # FIXME: I don't understand why no end paragraph marker is output when - # we are inside a table. Since at least version 3.2.2, this seems to mean that - # there is no new paragraph after the first line of a table entry. + # we are inside a table. Since at least version 3.2.2, this seems to + # mean that there is no new paragraph after the first line of a table + # entry. # For example in the birth cell, the first paragraph should be the - # description (21 Jan 1900 in London); if there is a note following this, - # there is no newline between the description and the note. + # description (21 Jan 1900 in London); if there is a note following + # this, there is no newline between the description and the note. if not self.in_table: - self.f.write(self.text) - LOG.debug("end_paragraph: opened: %d write: %s" % - (self.opened, - self.text + '}' if self.opened else "" + "newline")) + self.file.write(self.text) + LOG.debug("end_paragraph: opened: %d write: %s", + self.opened, + self.text + '}' if self.opened else "" + "newline") if self.opened: - self.f.write('}') + self.file.write('}') self.opened = 0 - self.f.write('\n\\par') + self.file.write('\n\\par') self.text = "" else: if self.text == "": @@ -259,7 +261,7 @@ class RTFDoc(BaseDoc,TextDoc): # #-------------------------------------------------------------------- def page_break(self): - self.f.write('\\page\n') + self.file.write('\\page\n') #-------------------------------------------------------------------- # @@ -267,9 +269,8 @@ class RTFDoc(BaseDoc,TextDoc): # #-------------------------------------------------------------------- def start_bold(self): - LOG.debug("start_bold: opened: %d saved text: %s" % - (self.opened, - '}' if self.opened else "" + '{%s\\b ' % self.font_type)) + LOG.debug("start_bold: opened: %d saved text: %s", self.opened, + '}' if self.opened else "" + '{%s\\b ' % self.font_type) if self.opened: self.text += '}' self.text += '{%s\\b ' % self.font_type @@ -281,9 +282,8 @@ class RTFDoc(BaseDoc,TextDoc): # #-------------------------------------------------------------------- def end_bold(self): - LOG.debug("end_bold: opened: %d saved text: %s" % - (self.opened, - self.text + '}')) + LOG.debug("end_bold: opened: %d saved text: %s", self.opened, + self.text + '}') if not self.opened == 1: print(self.opened) raise RuntimeError @@ -304,7 +304,7 @@ class RTFDoc(BaseDoc,TextDoc): # table, since a table is treated as a bunch of rows. # #-------------------------------------------------------------------- - def start_table(self, name,style_name): + def start_table(self, name, style_name): self.in_table = 1 styles = self.get_style_sheet() self.tbl_style = styles.get_table_style(style_name) @@ -330,7 +330,7 @@ class RTFDoc(BaseDoc,TextDoc): self.cell = 0 self.prev = 0 self.cell_percent = 0.0 - self.f.write('\\trowd\n') + self.file.write('\\trowd\n') #-------------------------------------------------------------------- # @@ -339,11 +339,11 @@ class RTFDoc(BaseDoc,TextDoc): # #-------------------------------------------------------------------- def end_row(self): - self.f.write('{') + self.file.write('{') for line in self.contents: - self.f.write(line) - self.f.write('\\cell ') - self.f.write('}\\pard\\intbl\\row\n') + self.file.write(line) + self.file.write('\\cell ') + self.file.write('}\\pard\\intbl\\row\n') #-------------------------------------------------------------------- # @@ -354,23 +354,23 @@ class RTFDoc(BaseDoc,TextDoc): # previous cells plus its own width. # #-------------------------------------------------------------------- - def start_cell(self,style_name,span=1): + def start_cell(self, style_name, span=1): styles = self.get_style_sheet() s = styles.get_cell_style(style_name) self.remain = span -1 if s.get_top_border(): - self.f.write('\\clbrdrt\\brdrs\\brdrw10\n') + self.file.write('\\clbrdrt\\brdrs\\brdrw10\n') if s.get_bottom_border(): - self.f.write('\\clbrdrb\\brdrs\\brdrw10\n') + self.file.write('\\clbrdrb\\brdrs\\brdrw10\n') if s.get_left_border(): - self.f.write('\\clbrdrl\\brdrs\\brdrw10\n') + self.file.write('\\clbrdrl\\brdrs\\brdrw10\n') if s.get_right_border(): - self.f.write('\\clbrdrr\\brdrs\\brdrw10\n') + self.file.write('\\clbrdrr\\brdrs\\brdrw10\n') table_width = float(self.paper.get_usable_width()) - for cell in range(self.cell,self.cell+span): + for cell in range(self.cell, self.cell+span): self.cell_percent += float(self.tbl_style.get_column_width(cell)) cell_width = twips((table_width * self.cell_percent)/100.0) - self.f.write('\\cellx%d\\pard\intbl\n' % cell_width) + self.file.write('\\cellx%d\\pard\intbl\n' % cell_width) self.cell += 1 #-------------------------------------------------------------------- @@ -391,35 +391,37 @@ class RTFDoc(BaseDoc,TextDoc): # dumped as a string of HEX numbers. # #-------------------------------------------------------------------- - def add_media(self, name, pos, x_cm, y_cm, alt='', style_name=None, crop=None): + def add_media(self, name, pos, x_cm, y_cm, alt='', style_name=None, + crop=None): - nx, ny = image_size(name) + width, height = image_size(name) - if (nx, ny) == (0,0): + if (width, height) == (0, 0): return - (act_width, act_height) = image_actual_size(x_cm, y_cm, nx, ny) + (act_width, act_height) = image_actual_size(x_cm, y_cm, width, height) act_width = twips(act_width) act_height = twips(act_height) size = [act_width, act_height] buf = resize_to_jpeg_buffer(name, size, crop=crop) - act_width = size[0] # In case it changed because of cropping or keeping the ratio + # The size may change because of cropping or keeping the ratio + act_width = size[0] act_height = size[1] - self.f.write('{\*\shppict{\\pict\\jpegblip') - self.f.write('\\picwgoal%d\\pichgoal%d\n' % (act_width,act_height)) + self.file.write('{\*\shppict{\\pict\\jpegblip') + self.file.write('\\picwgoal%d\\pichgoal%d\n' % (act_width, act_height)) index = 1 for i in buf: - self.f.write('%02x' % i) - if index%32==0: - self.f.write('\n') + self.file.write('%02x' % i) + if index%32 == 0: + self.file.write('\n') index = index+1 - self.f.write('}}\\par\n') + self.file.write('}}\\par\n') if len(alt): - self.f.write('%s\n\\par\n' % '\\par'.join(alt)) + self.file.write('%s\n\\par\n' % '\\par'.join(alt)) def write_styled_note(self, styledtext, format, style_name, contains_html=False, links=False): @@ -447,15 +449,15 @@ class RTFDoc(BaseDoc,TextDoc): self.start_paragraph(style_name) linenb = 1 else: - if ( linenb > 1 ): + if linenb > 1: self.write_text('\\line ') self.write_text(line, links=links) linenb += 1 # FIXME: I don't understand why these newlines are necessary. - # It may be related to the behaviour of end_paragraph inside tables, and - # write_text converting \n to end paragraph. - # This code prevents the whole document going wrong, but seems to produce an extra - # paragraph mark at the end of each table cell. + # It may be related to the behaviour of end_paragraph inside tables, + # and write_text converting \n to end paragraph. + # This code prevents the whole document going wrong, but seems to + # produce an extra paragraph mark at the end of each table cell. if self.in_table: # # Add LF when in table as in indiv_complete report self.write_text('\n') @@ -472,9 +474,7 @@ class RTFDoc(BaseDoc,TextDoc): def write_text(self, text, mark=None, links=False): # Convert to unicode, just in case it's not. Fix of bug 2449. text = str(text) - LOG.debug("write_text: opened: %d input text: %s" % - (self.opened, - text)) + LOG.debug("write_text: opened: %d input text: %s", self.opened, text) if self.opened == 0: self.opened = 1 self.text += '{%s ' % self.font_type @@ -488,18 +488,17 @@ class RTFDoc(BaseDoc,TextDoc): # RTF req valus in decimal, not hex. self.text += '{\\uc1\\u%d\\uc0}' % ord(i) elif i == '\n': - self.text += '\n\\par '; + self.text += '\n\\par ' elif i == '{' or i == '}' or i == '\\': self.text += '\\%s' % i else: self.text += i - if links == True: + if links is True: import re self.text = re.sub(URL_PATTERN, _CLICKABLE, self.text) - LOG.debug("write_text, exit: opened: %d saved text: %s" % - (self.opened, - self.text)) + LOG.debug("write_text, exit: opened: %d saved text: %s", self.opened, + self.text) def process_spaces(line, format): """ @@ -511,26 +510,27 @@ def process_spaces(line, format): are removed, and multiple spaces are reduced to one. If the text is pre-formatted (format==1). then all spaces are preserved - Note that xml is just treated like any other text, - because it will be from the original note, and it is just printed, not interpreted. - Returns the processed text, and the number of significant (i.e. non-white-space) chars. + Note that xml is just treated like any other text, because it will be from + the original note, and it is just printed, not interpreted. + Returns the processed text, and the number of significant + (i.e. non-white-space) chars. """ txt = "" xml = False space = False sigcount = 0 - # we loop through every character, which is very inefficient, but an attempt to use - # a regex replace didn't always work. + # we loop through every character, which is very inefficient, but an + # attempt to use a regex replace didn't always work. for char in line: if char == " " or char == "\t": if format == 1: txt += char elif format == 0 and sigcount == 0: pass - elif format == 0 and space == False: + elif format == 0 and space is False: space = True txt += char - elif format == 0 and space == True: + elif format == 0 and space is True: pass else: sigcount += 1 diff --git a/gramps/plugins/docgen/svgdrawdoc.py b/gramps/plugins/docgen/svgdrawdoc.py index eb0fe5ace..adad8a03c 100644 --- a/gramps/plugins/docgen/svgdrawdoc.py +++ b/gramps/plugins/docgen/svgdrawdoc.py @@ -27,7 +27,7 @@ SVG document generator. #------------------------------------------------------------------------- # -# python modules +# Python modules # #------------------------------------------------------------------------- from io import StringIO @@ -37,12 +37,12 @@ from io import StringIO # Gramps modules # #------------------------------------------------------------------------- -from gramps.gen.const import GRAMPS_LOCALE as glocale -_ = glocale.translation.gettext from gramps.gen.plug.docgen import BaseDoc, DrawDoc, SOLID, FONT_SANS_SERIF from gramps.gen.errors import ReportError from gramps.gen.plug.menu import EnumeratedListOption from gramps.gen.plug.report import DocOptions +from gramps.gen.const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext #------------------------------------------------------------------------- # @@ -53,7 +53,7 @@ class SvgDrawDoc(BaseDoc, DrawDoc): def __init__(self, styles, type, options=None): BaseDoc.__init__(self, styles, type) - self.f = None + self.file = None self.filename = None self.level = 0 self.time = "0000-00-00T00:00:00" @@ -83,18 +83,18 @@ class SvgDrawDoc(BaseDoc, DrawDoc): name = "%s.svg" % self.root try: - self.f = open(name,"w", encoding="utf-8") + self.file = open(name, "w", encoding="utf-8") except IOError as msg: raise ReportError(_("Could not create %s") % name, msg) except: raise ReportError(_("Could not create %s") % name) - self.t = StringIO() + self.buffer = StringIO() width = self.paper.get_size().get_width() height = self.paper.get_size().get_height() - self.f.write( + self.file.write( '\n' '\n' @@ -102,7 +102,7 @@ class SvgDrawDoc(BaseDoc, DrawDoc): 'xmlns="http://www.w3.org/2000/svg">\n' '\n' - % (width, height, width, height, self._bg) + % (width, height, width, height, self._bg) ) def rotate_text(self, style, text, x, y, angle, mark=None): @@ -110,8 +110,8 @@ class SvgDrawDoc(BaseDoc, DrawDoc): style_sheet = self.get_style_sheet() stype = style_sheet.get_draw_style(style) pname = stype.get_paragraph_style() - p = style_sheet.get_paragraph_style(pname) - font = p.get_font() + para = style_sheet.get_paragraph_style(pname) + font = para.get_font() size = font.get_size() width = height = 0 @@ -119,45 +119,45 @@ class SvgDrawDoc(BaseDoc, DrawDoc): width = max(width, self.string_width(font, line)) height += size - centerx, centery = units(( x+self.paper.get_left_margin(), - y+self.paper.get_top_margin() )) + centerx, centery = units((x+self.paper.get_left_margin(), + y+self.paper.get_top_margin())) xpos = (centerx - (width/2.0)) ypos = (centery - (height/2.0)) - self.t.write( + self.buffer.write( '') + self.buffer.write('font-family:serif;') + self.buffer.write('">') for line in text: # Center this line relative to the rest of the text - linex = xpos + (width - self.string_width(font, line) ) / 2 - self.t.write( + linex = xpos + (width - self.string_width(font, line)) / 2 + self.buffer.write( '' % (linex, size) + line + '' ) - self.t.write('\n') + self.buffer.write('\n') def end_page(self): # Print the text last for each page so that it is rendered on top of # other graphic elements. - self.f.write(self.t.getvalue()) - self.t.close() - self.f.write('\n') - self.f.close() + self.file.write(self.buffer.getvalue()) + self.buffer.close() + self.file.write('\n') + self.file.close() def draw_line(self, style, x1, y1, x2, y2): x1 += self.paper.get_left_margin() @@ -166,17 +166,17 @@ class SvgDrawDoc(BaseDoc, DrawDoc): y2 += self.paper.get_top_margin() style_sheet = self.get_style_sheet() - s = style_sheet.get_draw_style(style) + draw_style = style_sheet.get_draw_style(style) line_out = '\n') + self.file.write('"/>\n') def draw_box(self, style, text, x, y, w, h, mark=None): """ @param mark: IndexMark to use for indexing (not supported) """ @@ -211,7 +212,7 @@ class SvgDrawDoc(BaseDoc, DrawDoc): shadow_width = box_style.get_shadow_space() if box_style.get_shadow() and shadow_width > 0: - self.f.write( + self.file.write( '' + line + '\n' @@ -276,27 +277,27 @@ class SvgDrawDoc(BaseDoc, DrawDoc): style_sheet = self.get_style_sheet() box_style = style_sheet.get_draw_style(style) para_name = box_style.get_paragraph_style() - p = style_sheet.get_paragraph_style(para_name) + para = style_sheet.get_paragraph_style(para_name) - font = p.get_font() + font = para.get_font() font_size = font.get_size() - fs = (font_size/28.35) * 1.2 - self.t.write( + fsize = (font_size/28.35) * 1.2 + self.buffer.write( '' + text + '\n' @@ -307,8 +308,8 @@ class SvgDrawDoc(BaseDoc, DrawDoc): style_sheet = self.get_style_sheet() box_style = style_sheet.get_draw_style(style) para_name = box_style.get_paragraph_style() - p = style_sheet.get_paragraph_style(para_name) - font = p.get_font() + para = style_sheet.get_paragraph_style(para_name) + font = para.get_font() width = self.string_width(font, text) / 72 x -= width self.draw_text(style, text, x, y) @@ -336,7 +337,7 @@ class SvgDrawDocOptions(DocOptions): category_name = 'Document Options' # internal name: don't translate background = EnumeratedListOption(_('SVG background color'), - 'transparent') + 'transparent') background.set_items([('transparent', _('transparent background')), ('white', _('white')), ('black', _('black')), @@ -345,6 +346,6 @@ class SvgDrawDocOptions(DocOptions): ('blue', _('blue')), ('cyan', _('cyan')), ('magenta', _('magenta')), - ('yellow', _('yellow')) ]) + ('yellow', _('yellow'))]) background.set_help(_('The color, if any, of the SVG background')) menu.add_option(category_name, 'svg_background', background)