Further pylint improvements to document generators

This commit is contained in:
Nick Hall 2016-06-04 18:29:10 +01:00
parent 36f5a6addc
commit a3fd7c06be
5 changed files with 839 additions and 897 deletions

View File

@ -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:

View File

@ -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)

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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(
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'
'<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" '
'"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">\n'
@ -102,7 +102,7 @@ class SvgDrawDoc(BaseDoc, DrawDoc):
'xmlns="http://www.w3.org/2000/svg">\n'
'<rect width="%4.2fcm" height="%4.2fcm" '
'style="fill: %s;"/>\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(
'<text ' +
'x="%4.2f" y="%4.2f" ' % (xpos, ypos) +
'transform="rotate(%d %4.2f %4.2f)" ' % (angle, centerx, centery) +
'style="fill:#%02x%02x%02x; '% font.get_color()
)
if font.get_bold():
self.t.write('font-weight:bold;')
self.buffer.write('font-weight:bold;')
if font.get_italic():
self.t.write('font-style:italic;')
self.t.write('font-size:%dpt; ' % size)
self.buffer.write('font-style:italic;')
self.buffer.write('font-size:%dpt; ' % size)
if font.get_type_face() == FONT_SANS_SERIF:
self.t.write('font-family:sans-serif;')
self.buffer.write('font-family:sans-serif;')
else:
self.t.write('font-family:serif;')
self.t.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(
'<tspan x="%4.2f" dy="%d">' % (linex, size) +
line +
'</tspan>'
)
self.t.write('</text>\n')
self.buffer.write('</text>\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('</svg>\n')
self.f.close()
self.file.write(self.buffer.getvalue())
self.buffer.close()
self.file.write('</svg>\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 = '<line x1="%4.2fcm" y1="%4.2fcm" ' % (x1, y1)
line_out += 'x2="%4.2fcm" y2="%4.2fcm" ' % (x2, y2)
line_out += 'style="stroke:#%02x%02x%02x; ' % s.get_color()
if s.get_line_style() != SOLID:
line_out += 'style="stroke:#%02x%02x%02x; ' % draw_style.get_color()
if draw_style.get_line_style() != SOLID:
line_out += 'stroke-dasharray: %s; ' % (
",".join(map(str, s.get_dash_style()))
",".join(map(str, draw_style.get_dash_style()))
)
line_out += 'stroke-width:%.2fpt;"/>\n' % s.get_line_width()
self.f.write(line_out)
line_out += 'stroke-width:%.2fpt;"/>\n' % draw_style.get_line_width()
self.file.write(line_out)
def draw_path(self, style, path):
style_sheet = self.get_style_sheet()
@ -190,16 +190,17 @@ class SvgDrawDoc(BaseDoc, DrawDoc):
",".join(map(str, stype.get_dash_style()))
)
line_out += ' stroke-width:%.2fpt;"' % stype.get_line_width()
line_out += ' points="%.2f,%.2f' % units((point[0]+self.paper.get_left_margin(),
point[1]+self.paper.get_top_margin()))
self.f.write(line_out)
line_out += ' points="%.2f,%.2f' % units(
(point[0]+self.paper.get_left_margin(),
point[1]+self.paper.get_top_margin()))
self.file.write(line_out)
for point in path[1:]:
self.f.write(
self.file.write(
' %.2f,%.2f'
% units((point[0]+self.paper.get_left_margin(),
point[1]+self.paper.get_top_margin()))
% units((point[0]+self.paper.get_left_margin(),
point[1]+self.paper.get_top_margin()))
)
self.f.write('"/>\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(
'<rect ' +
'x="%4.2fcm" ' % (x + shadow_width) +
'y="%4.2fcm" ' % (y + shadow_width) +
@ -232,37 +233,37 @@ class SvgDrawDoc(BaseDoc, DrawDoc):
",".join(map(str, box_style.get_dash_style()))
)
line_out += 'stroke-width:%f;"/>\n' % box_style.get_line_width()
self.f.write(line_out)
self.file.write(line_out)
if text:
para_name = box_style.get_paragraph_style()
assert( para_name != '' )
p = style_sheet.get_paragraph_style(para_name)
font = p.get_font()
assert para_name != ''
para = style_sheet.get_paragraph_style(para_name)
font = para.get_font()
font_size = font.get_size()
lines = text.split('\n')
mar = 10/28.35
fs = (font_size/28.35) * 1.2
center = y + (h + fs)/2.0 + (fs*0.2)
ystart = center - (fs/2.0) * len(lines)
fsize = (font_size/28.35) * 1.2
center = y + (h + fsize)/2.0 + (fsize*0.2)
ystart = center - (fsize/2.0) * len(lines)
for i, line in enumerate(lines):
ypos = ystart + (i * fs)
self.t.write(
ypos = ystart + (i * fsize)
self.buffer.write(
'<text ' +
'x="%4.2fcm" ' % (x+mar) +
'y="%4.2fcm" ' % ypos +
'style="fill:#%02x%02x%02x; '% font.get_color()
)
if font.get_bold():
self.t.write(' font-weight:bold;')
self.buffer.write(' font-weight:bold;')
if font.get_italic():
self.t.write(' font-style:italic;')
self.t.write(' font-size:%dpt;' % font_size)
self.buffer.write(' font-style:italic;')
self.buffer.write(' font-size:%dpt;' % font_size)
if font.get_type_face() == FONT_SANS_SERIF:
self.t.write(' font-family:sans-serif;')
self.buffer.write(' font-family:sans-serif;')
else:
self.t.write(' font-family:serif;')
self.t.write(
self.buffer.write(' font-family:serif;')
self.buffer.write(
'">' +
line +
'</text>\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 ' +
'x="%4.2fcm" ' % x +
'y="%4.2fcm" ' % (y+fs) +
'y="%4.2fcm" ' % (y+fsize) +
'style="fill:#%02x%02x%02x;'% font.get_color()
)
if font.get_bold():
self.t.write('font-weight:bold;')
self.buffer.write('font-weight:bold;')
if font.get_italic():
self.t.write('font-style:italic;')
self.t.write('font-size:%dpt; ' % font_size)
self.buffer.write('font-style:italic;')
self.buffer.write('font-size:%dpt; ' % font_size)
if font.get_type_face() == FONT_SANS_SERIF:
self.t.write('font-family:sans-serif;')
self.buffer.write('font-family:sans-serif;')
else:
self.t.write('font-family:serif;')
self.t.write(
self.buffer.write('font-family:serif;')
self.buffer.write(
'">' +
text +
'</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)