Patch from Adam Stein <adam@csh.rit.edu>: Add support for links and cropped images in ODF document output. Also related to: http://www.gramps-project.org/bugs/view.php?id=4774
svn: r17451
This commit is contained in:
277
src/ImgManip.py
277
src/ImgManip.py
@@ -2,6 +2,7 @@
|
|||||||
# Gramps - a GTK+/GNOME based genealogy program
|
# Gramps - a GTK+/GNOME based genealogy program
|
||||||
#
|
#
|
||||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||||
|
# Copyright (C) 2011 Adam Stein <adam@csh.rit.edu>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -69,6 +70,150 @@ def resize_to_jpeg(source, destination, width, height):
|
|||||||
scaled = img.scale_simple(width, height, gtk.gdk.INTERP_BILINEAR)
|
scaled = img.scale_simple(width, height, gtk.gdk.INTERP_BILINEAR)
|
||||||
scaled.save(destination, 'jpeg')
|
scaled.save(destination, 'jpeg')
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# image_dpi
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def image_dpi(source):
|
||||||
|
"""
|
||||||
|
Return the dpi found in the image header. None is returned if no dpi attribute
|
||||||
|
is available.
|
||||||
|
|
||||||
|
:param source: source image file, in any format that PIL recognizes
|
||||||
|
:type source: unicode
|
||||||
|
:rtype: int
|
||||||
|
:returns: the DPI setting in the image header
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
import PIL.Image
|
||||||
|
except ImportError:
|
||||||
|
import sys
|
||||||
|
print >> sys.stderr, _("WARNING: PIL module not loaded. "
|
||||||
|
"Image cropping in report files will not be available.")
|
||||||
|
|
||||||
|
dpi = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
img = PIL.Image.open(source)
|
||||||
|
except IOError:
|
||||||
|
dpi = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
dpi = img.info["dpi"]
|
||||||
|
except AttributeError, KeyError:
|
||||||
|
dpi = None
|
||||||
|
|
||||||
|
return dpi
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# image_dpi
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def image_dpi(source):
|
||||||
|
"""
|
||||||
|
Return the dpi found in the image header. None is returned if no dpi attribute
|
||||||
|
is available.
|
||||||
|
|
||||||
|
:param source: source image file, in any format that PIL recognizes
|
||||||
|
:type source: unicode
|
||||||
|
:rtype: int
|
||||||
|
:returns: the DPI setting in the image header
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
import PIL.Image
|
||||||
|
except ImportError:
|
||||||
|
import sys
|
||||||
|
print >> sys.stderr, _("WARNING: PIL module not loaded. "
|
||||||
|
"Image cropping in report files will not be available.")
|
||||||
|
|
||||||
|
dpi = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
img = PIL.Image.open(source)
|
||||||
|
except IOError:
|
||||||
|
dpi = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
dpi = img.info["dpi"]
|
||||||
|
except AttributeError, KeyError:
|
||||||
|
dpi = None
|
||||||
|
|
||||||
|
return dpi
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# image_dpi
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def image_dpi(source):
|
||||||
|
"""
|
||||||
|
Return the dpi found in the image header. None is returned if no dpi attribute
|
||||||
|
is available.
|
||||||
|
|
||||||
|
:param source: source image file, in any format that PIL recognizes
|
||||||
|
:type source: unicode
|
||||||
|
:rtype: int
|
||||||
|
:returns: the DPI setting in the image header
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
import PIL.Image
|
||||||
|
except ImportError:
|
||||||
|
import sys
|
||||||
|
print >> sys.stderr, _("WARNING: PIL module not loaded. "
|
||||||
|
"Image cropping in report files will not be available.")
|
||||||
|
|
||||||
|
dpi = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
img = PIL.Image.open(source)
|
||||||
|
except IOError:
|
||||||
|
dpi = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
dpi = img.info["dpi"]
|
||||||
|
except AttributeError, KeyError:
|
||||||
|
dpi = None
|
||||||
|
|
||||||
|
return dpi
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# image_dpi
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def image_dpi(source):
|
||||||
|
"""
|
||||||
|
Return the dpi found in the image header. None is returned if no dpi attribute
|
||||||
|
is available.
|
||||||
|
|
||||||
|
:param source: source image file, in any format that PIL recognizes
|
||||||
|
:type source: unicode
|
||||||
|
:rtype: int
|
||||||
|
:returns: the DPI setting in the image header
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
import PIL.Image
|
||||||
|
except ImportError:
|
||||||
|
import sys
|
||||||
|
print >> sys.stderr, _("WARNING: PIL module not loaded. "
|
||||||
|
"Image cropping in report files will not be available.")
|
||||||
|
|
||||||
|
dpi = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
img = PIL.Image.open(source)
|
||||||
|
except IOError:
|
||||||
|
dpi = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
dpi = img.info["dpi"]
|
||||||
|
except AttributeError, KeyError:
|
||||||
|
dpi = None
|
||||||
|
|
||||||
|
return dpi
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# image_size
|
# image_size
|
||||||
@@ -94,6 +239,138 @@ def image_size(source):
|
|||||||
height = 0
|
height = 0
|
||||||
return (width, height)
|
return (width, height)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# image_cropped_size
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def image_actual_size(x_cm, y_cm, x, y):
|
||||||
|
"""
|
||||||
|
Calculate what the actual width & height of the image should be.
|
||||||
|
|
||||||
|
:param x_cm: width in centimeters
|
||||||
|
:type source: int
|
||||||
|
:param y_cm: height in centimeters
|
||||||
|
:type source: int
|
||||||
|
:param x: desired width in pixels
|
||||||
|
:type source: int
|
||||||
|
:param y: desired height in pixels
|
||||||
|
:type source: int
|
||||||
|
:rtype: tuple(int, int)
|
||||||
|
:returns: a tuple consisting of the width and height in centimeters
|
||||||
|
"""
|
||||||
|
|
||||||
|
print "[Actual Size] CM = [", x_cm, ",", y_cm, "], Desired = [", x, ",", y, "]"
|
||||||
|
ratio = float(x_cm)*float(y)/(float(y_cm)*float(x))
|
||||||
|
|
||||||
|
if ratio < 1:
|
||||||
|
act_width = x_cm
|
||||||
|
act_height = y_cm*ratio
|
||||||
|
else:
|
||||||
|
act_height = y_cm
|
||||||
|
act_width = x_cm/ratio
|
||||||
|
|
||||||
|
print "[Actual Size] Size = [", act_width, ",", act_height, "]"
|
||||||
|
return (act_width, act_height)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# image_cropped_size
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def image_actual_size(x_cm, y_cm, x, y):
|
||||||
|
"""
|
||||||
|
Calculate what the actual width & height of the image should be.
|
||||||
|
|
||||||
|
:param x_cm: width in centimeters
|
||||||
|
:type source: int
|
||||||
|
:param y_cm: height in centimeters
|
||||||
|
:type source: int
|
||||||
|
:param x: desired width in pixels
|
||||||
|
:type source: int
|
||||||
|
:param y: desired height in pixels
|
||||||
|
:type source: int
|
||||||
|
:rtype: tuple(int, int)
|
||||||
|
:returns: a tuple consisting of the width and height in centimeters
|
||||||
|
"""
|
||||||
|
|
||||||
|
print "[Actual Size] CM = [", x_cm, ",", y_cm, "], Desired = [", x, ",", y, "]"
|
||||||
|
ratio = float(x_cm)*float(y)/(float(y_cm)*float(x))
|
||||||
|
|
||||||
|
if ratio < 1:
|
||||||
|
act_width = x_cm
|
||||||
|
act_height = y_cm*ratio
|
||||||
|
else:
|
||||||
|
act_height = y_cm
|
||||||
|
act_width = x_cm/ratio
|
||||||
|
|
||||||
|
print "[Actual Size] Size = [", act_width, ",", act_height, "]"
|
||||||
|
return (act_width, act_height)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# image_cropped_size
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def image_actual_size(x_cm, y_cm, x, y):
|
||||||
|
"""
|
||||||
|
Calculate what the actual width & height of the image should be.
|
||||||
|
|
||||||
|
:param x_cm: width in centimeters
|
||||||
|
:type source: int
|
||||||
|
:param y_cm: height in centimeters
|
||||||
|
:type source: int
|
||||||
|
:param x: desired width in pixels
|
||||||
|
:type source: int
|
||||||
|
:param y: desired height in pixels
|
||||||
|
:type source: int
|
||||||
|
:rtype: tuple(int, int)
|
||||||
|
:returns: a tuple consisting of the width and height in centimeters
|
||||||
|
"""
|
||||||
|
|
||||||
|
ratio = float(x_cm)*float(y)/(float(y_cm)*float(x))
|
||||||
|
|
||||||
|
if ratio < 1:
|
||||||
|
act_width = x_cm
|
||||||
|
act_height = y_cm*ratio
|
||||||
|
else:
|
||||||
|
act_height = y_cm
|
||||||
|
act_width = x_cm/ratio
|
||||||
|
|
||||||
|
return (act_width, act_height)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# image_cropped_size
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def image_actual_size(x_cm, y_cm, x, y):
|
||||||
|
"""
|
||||||
|
Calculate what the actual width & height of the image should be.
|
||||||
|
|
||||||
|
:param x_cm: width in centimeters
|
||||||
|
:type source: int
|
||||||
|
:param y_cm: height in centimeters
|
||||||
|
:type source: int
|
||||||
|
:param x: desired width in pixels
|
||||||
|
:type source: int
|
||||||
|
:param y: desired height in pixels
|
||||||
|
:type source: int
|
||||||
|
:rtype: tuple(int, int)
|
||||||
|
:returns: a tuple consisting of the width and height in centimeters
|
||||||
|
"""
|
||||||
|
|
||||||
|
ratio = float(x_cm)*float(y)/(float(y_cm)*float(x))
|
||||||
|
|
||||||
|
if ratio < 1:
|
||||||
|
act_width = x_cm
|
||||||
|
act_height = y_cm*ratio
|
||||||
|
else:
|
||||||
|
act_height = y_cm
|
||||||
|
act_width = x_cm/ratio
|
||||||
|
|
||||||
|
return (act_width, act_height)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# resize_to_jpeg_buffer
|
# resize_to_jpeg_buffer
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2009 B. Malengier
|
# Copyright (C) 2009 B. Malengier
|
||||||
# Copyright (C) 2010 Jakim Friant
|
# Copyright (C) 2010 Jakim Friant
|
||||||
|
# Copyright (C) 2011 Adam Stein <adam@csh.rit.edu>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -34,6 +35,6 @@ from paragraphstyle import ParagraphStyle, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT,\
|
|||||||
from tablestyle import TableStyle, TableCellStyle
|
from tablestyle import TableStyle, TableCellStyle
|
||||||
from stylesheet import StyleSheetList, StyleSheet, SheetParser
|
from stylesheet import StyleSheetList, StyleSheet, SheetParser
|
||||||
from graphicstyle import GraphicsStyle, SOLID, DASHED, DOTTED
|
from graphicstyle import GraphicsStyle, SOLID, DASHED, DOTTED
|
||||||
from textdoc import TextDoc, IndexMark,INDEX_TYPE_ALP, INDEX_TYPE_TOC
|
from textdoc import TextDoc, IndexMark,INDEX_TYPE_ALP, INDEX_TYPE_TOC, URL_PATTERN
|
||||||
from drawdoc import DrawDoc
|
from drawdoc import DrawDoc
|
||||||
from graphdoc import GVDoc
|
from graphdoc import GVDoc
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
# Copyright (C) 2009 Benny Malengier
|
# Copyright (C) 2009 Benny Malengier
|
||||||
# Copyright (C) 2009 Gary Burton
|
# Copyright (C) 2009 Gary Burton
|
||||||
# Copyright (C) 2010 Peter Landgren
|
# Copyright (C) 2010 Peter Landgren
|
||||||
|
# Copyright (C) 2011 Adam Stein <adam@csh.rit.edu>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -47,6 +48,13 @@
|
|||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(".textdoc")
|
log = logging.getLogger(".textdoc")
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# URL string pattern
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
URL_PATTERN = r'''(((https?|mailto):)(//([^/?#"]*))?([^?#"]*)(\?([^#"]*))?(#([^"]*))?)'''
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# IndexMark types
|
# IndexMark types
|
||||||
@@ -160,13 +168,14 @@ class TextDoc(object):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def write_text(self, text, mark=None):
|
def write_text(self, text, mark=None, links=False):
|
||||||
"""
|
"""
|
||||||
Writes the text in the current paragraph. Should only be used after a
|
Writes the text in the current paragraph. Should only be used after a
|
||||||
start_paragraph and before an end_paragraph.
|
start_paragraph and before an end_paragraph.
|
||||||
|
|
||||||
@param text: text to write.
|
@param text: text to write.
|
||||||
@param mark: IndexMark to use for indexing (if supported)
|
@param mark: IndexMark to use for indexing (if supported)
|
||||||
|
@param links: make URLs in the text clickable (if supported)
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@@ -194,17 +203,18 @@ class TextDoc(object):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def write_endnotes_ref(self, text, style_name):
|
def write_endnotes_ref(self, text, style_name, links=False):
|
||||||
"""
|
"""
|
||||||
Writes the note's text and take care of paragraphs,
|
Writes the note's text and take care of paragraphs,
|
||||||
|
|
||||||
@param text: text to write.
|
@param text: text to write.
|
||||||
@param style_name: style to be used.
|
@param style_name: style to be used.
|
||||||
|
@param links: make URLs in the text clickable (if supported)
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def write_styled_note(self, styledtext, format, style_name,
|
def write_styled_note(self, styledtext, format, style_name,
|
||||||
contains_html=False):
|
contains_html=False, links=False):
|
||||||
"""
|
"""
|
||||||
Convenience function to write a styledtext to the cairo doc.
|
Convenience function to write a styledtext to the cairo doc.
|
||||||
styledtext : assumed a StyledText object to write
|
styledtext : assumed a StyledText object to write
|
||||||
@@ -214,6 +224,7 @@ class TextDoc(object):
|
|||||||
If contains_html=True, then the textdoc is free to handle that in
|
If contains_html=True, then the textdoc is free to handle that in
|
||||||
some way. Eg, a textdoc could remove all tags, or could make sure
|
some way. Eg, a textdoc could remove all tags, or could make sure
|
||||||
a link is clickable.
|
a link is clickable.
|
||||||
|
links: bool, make URLs in the text clickable (if supported)
|
||||||
|
|
||||||
overwrite this method if the backend supports styled notes
|
overwrite this method if the backend supports styled notes
|
||||||
"""
|
"""
|
||||||
@@ -252,7 +263,7 @@ class TextDoc(object):
|
|||||||
else:
|
else:
|
||||||
self.write_text(piece)
|
self.write_text(piece)
|
||||||
|
|
||||||
def add_media_object(self, name, align, w_cm, h_cm, alt=''):
|
def add_media_object(self, name, align, w_cm, h_cm, alt='', style_name=None, crop=None):
|
||||||
"""
|
"""
|
||||||
Add a photo of the specified width (in centimeters).
|
Add a photo of the specified width (in centimeters).
|
||||||
|
|
||||||
@@ -262,6 +273,8 @@ class TextDoc(object):
|
|||||||
@param w_cm: width in centimeters
|
@param w_cm: width in centimeters
|
||||||
@param h_cm: height in centimeters
|
@param h_cm: height in centimeters
|
||||||
@param alt: an alternative text to use. Useful for eg html reports
|
@param alt: an alternative text to use. Useful for eg html reports
|
||||||
|
@param style_name: style to use for captions
|
||||||
|
@param crop: image cropping parameters
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@@ -293,3 +306,4 @@ class TextDoc(object):
|
|||||||
so that docgen ntypes are not required to have this.
|
so that docgen ntypes are not required to have this.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# Copyright (C) 2007 Brian G. Matherly
|
# Copyright (C) 2007 Brian G. Matherly
|
||||||
# Copyright (C) 2010 Peter Landgren
|
# Copyright (C) 2010 Peter Landgren
|
||||||
# Copyright (C) 2010 Jakim Friant
|
# Copyright (C) 2010 Jakim Friant
|
||||||
|
# Copyright (C) 2011 Adam Stein <adam@csh.rit.edu>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -90,7 +91,7 @@ def cite_source(bibliography, obj):
|
|||||||
txt += key
|
txt += key
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
def write_endnotes(bibliography, database, doc, printnotes=False):
|
def write_endnotes(bibliography, database, doc, printnotes=False, links=False):
|
||||||
"""
|
"""
|
||||||
Write all the entries in the bibliography as endnotes.
|
Write all the entries in the bibliography as endnotes.
|
||||||
|
|
||||||
@@ -103,6 +104,8 @@ def write_endnotes(bibliography, database, doc, printnotes=False):
|
|||||||
@param printnotes: Indicate if the notes attached to a source must be
|
@param printnotes: Indicate if the notes attached to a source must be
|
||||||
written too.
|
written too.
|
||||||
@type printnotes: bool
|
@type printnotes: bool
|
||||||
|
@param links: Indicate if URL links should be makde 'clickable'.
|
||||||
|
@type links: bool
|
||||||
"""
|
"""
|
||||||
if bibliography.get_citation_count() == 0:
|
if bibliography.get_citation_count() == 0:
|
||||||
return
|
return
|
||||||
@@ -121,7 +124,7 @@ def write_endnotes(bibliography, database, doc, printnotes=False):
|
|||||||
|
|
||||||
src_txt = _format_source_text(source)
|
src_txt = _format_source_text(source)
|
||||||
|
|
||||||
doc.write_text(src_txt)
|
doc.write_text(src_txt, links=links)
|
||||||
doc.end_paragraph()
|
doc.end_paragraph()
|
||||||
|
|
||||||
ref_list = citation.get_ref_list()
|
ref_list = citation.get_ref_list()
|
||||||
@@ -136,7 +139,7 @@ def write_endnotes(bibliography, database, doc, printnotes=False):
|
|||||||
first = False
|
first = False
|
||||||
else:
|
else:
|
||||||
reflines += ('\n%s' % txt)
|
reflines += ('\n%s' % txt)
|
||||||
doc.write_endnotes_ref(reflines,'Endnotes-Ref')
|
doc.write_endnotes_ref(reflines,'Endnotes-Ref', links=links)
|
||||||
|
|
||||||
if printnotes:
|
if printnotes:
|
||||||
note_list = source.get_note_list()
|
note_list = source.get_note_list()
|
||||||
@@ -151,7 +154,8 @@ def write_endnotes(bibliography, database, doc, printnotes=False):
|
|||||||
doc.write_styled_note(note.get_styledtext(),
|
doc.write_styled_note(note.get_styledtext(),
|
||||||
note.get_format(),'Endnotes-Notes',
|
note.get_format(),'Endnotes-Notes',
|
||||||
contains_html= note.get_type() \
|
contains_html= note.get_type() \
|
||||||
== NoteType.HTML_CODE)
|
== NoteType.HTML_CODE,
|
||||||
|
links=links)
|
||||||
ind += 1
|
ind += 1
|
||||||
|
|
||||||
def _format_source_text(source):
|
def _format_source_text(source):
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
# Copyright (C) 2007-2009 Brian G. Matherly
|
# Copyright (C) 2007-2009 Brian G. Matherly
|
||||||
# Copyright (C) 2009-2010 Benny Malengier <benny.malengier@gramps-project.org>
|
# Copyright (C) 2009-2010 Benny Malengier <benny.malengier@gramps-project.org>
|
||||||
# Copyright (C) 2010 Peter Landgren
|
# Copyright (C) 2010 Peter Landgren
|
||||||
|
# Copyright (C) 2011 Adam Stein <adam@csh.rit.edu>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -361,7 +362,7 @@ class AsciiDoc(BaseDoc,TextDoc):
|
|||||||
if self.cell_lines[self.cellnum] > self.maxlines:
|
if self.cell_lines[self.cellnum] > self.maxlines:
|
||||||
self.maxlines = self.cell_lines[self.cellnum]
|
self.maxlines = self.cell_lines[self.cellnum]
|
||||||
|
|
||||||
def add_media_object(self, name, align, w_cm, h_cm, alt=''):
|
def add_media_object(self, name, align, w_cm, h_cm, alt='', style_name=None, crop=None):
|
||||||
this_text = '(photo)'
|
this_text = '(photo)'
|
||||||
if self.in_cell:
|
if self.in_cell:
|
||||||
self.cellpars[self.cellnum] += this_text
|
self.cellpars[self.cellnum] += this_text
|
||||||
@@ -369,7 +370,7 @@ class AsciiDoc(BaseDoc,TextDoc):
|
|||||||
self.f.write(this_text)
|
self.f.write(this_text)
|
||||||
|
|
||||||
def write_styled_note(self, styledtext, format, style_name,
|
def write_styled_note(self, styledtext, format, style_name,
|
||||||
contains_html=False):
|
contains_html=False, links=False):
|
||||||
"""
|
"""
|
||||||
Convenience function to write a styledtext to the ASCII doc.
|
Convenience function to write a styledtext to the ASCII doc.
|
||||||
styledtext : assumed a StyledText object to write
|
styledtext : assumed a StyledText object to write
|
||||||
@@ -379,6 +380,7 @@ class AsciiDoc(BaseDoc,TextDoc):
|
|||||||
If contains_html=True, then the textdoc is free to handle that in
|
If contains_html=True, then the textdoc is free to handle that in
|
||||||
some way. Eg, a textdoc could remove all tags, or could make sure
|
some way. Eg, a textdoc could remove all tags, or could make sure
|
||||||
a link is clickable. AsciiDoc prints the html without handling it
|
a link is clickable. AsciiDoc prints the html without handling it
|
||||||
|
links: bool, make the URL in the text clickable (if supported)
|
||||||
"""
|
"""
|
||||||
if contains_html:
|
if contains_html:
|
||||||
return
|
return
|
||||||
@@ -402,7 +404,7 @@ class AsciiDoc(BaseDoc,TextDoc):
|
|||||||
self.write_text(line)
|
self.write_text(line)
|
||||||
self.end_paragraph()
|
self.end_paragraph()
|
||||||
|
|
||||||
def write_endnotes_ref(self, text, style_name):
|
def write_endnotes_ref(self, text, style_name, links=False):
|
||||||
"""
|
"""
|
||||||
Overwrite base method for lines of endnotes references
|
Overwrite base method for lines of endnotes references
|
||||||
"""
|
"""
|
||||||
@@ -415,5 +417,5 @@ class AsciiDoc(BaseDoc,TextDoc):
|
|||||||
#
|
#
|
||||||
# Writes text.
|
# Writes text.
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
def write_text(self,text,mark=None):
|
def write_text(self,text,mark=None,links=False):
|
||||||
self.text = self.text + text
|
self.text = self.text + text
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
# Copyright (C) 2009-2010 Benny Malengier <benny.malengier@gramps-project.org>
|
# Copyright (C) 2009-2010 Benny Malengier <benny.malengier@gramps-project.org>
|
||||||
# Copyright (C) 2010 Peter Landgren
|
# Copyright (C) 2010 Peter Landgren
|
||||||
# Copyright (C) 2010 Tim Lyons
|
# Copyright (C) 2010 Tim Lyons
|
||||||
|
# Copyright (C) 2011 Adam Stein <adam@csh.rit.edu>
|
||||||
|
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
@@ -316,7 +317,7 @@ class HtmlDoc(BaseDoc, TextDoc):
|
|||||||
"""
|
"""
|
||||||
self.__write_text(' ', markup=True)
|
self.__write_text(' ', markup=True)
|
||||||
|
|
||||||
def write_text(self, text, mark=None):
|
def write_text(self, text, mark=None, links=False):
|
||||||
"""
|
"""
|
||||||
Overwrite base method
|
Overwrite base method
|
||||||
"""
|
"""
|
||||||
@@ -448,7 +449,7 @@ class HtmlDoc(BaseDoc, TextDoc):
|
|||||||
"""
|
"""
|
||||||
self.__reduce_list()
|
self.__reduce_list()
|
||||||
|
|
||||||
def write_endnotes_ref(self, text, style_name):
|
def write_endnotes_ref(self, text, style_name, links=False):
|
||||||
"""
|
"""
|
||||||
Overwrite base method for lines of endnotes references
|
Overwrite base method for lines of endnotes references
|
||||||
"""
|
"""
|
||||||
@@ -465,7 +466,7 @@ class HtmlDoc(BaseDoc, TextDoc):
|
|||||||
self.__reduce_list()
|
self.__reduce_list()
|
||||||
|
|
||||||
def write_styled_note(self, styledtext, format, style_name,
|
def write_styled_note(self, styledtext, format, style_name,
|
||||||
contains_html=False):
|
contains_html=False, links=False):
|
||||||
"""
|
"""
|
||||||
Convenience function to write a styledtext to the html doc.
|
Convenience function to write a styledtext to the html doc.
|
||||||
styledtext : assumed a StyledText object to write
|
styledtext : assumed a StyledText object to write
|
||||||
@@ -532,7 +533,7 @@ class HtmlDoc(BaseDoc, TextDoc):
|
|||||||
#end div element
|
#end div element
|
||||||
self.__reduce_list()
|
self.__reduce_list()
|
||||||
|
|
||||||
def add_media_object(self, name, pos, w_cm, h_cm, alt=''):
|
def add_media_object(self, name, pos, w_cm, h_cm, alt='', style_name=None, crop=None):
|
||||||
"""
|
"""
|
||||||
Overwrite base method
|
Overwrite base method
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
# 2003 Alex Roitman
|
# 2003 Alex Roitman
|
||||||
# 2009 Benny Malengier
|
# 2009 Benny Malengier
|
||||||
# 2010 Peter Landgren
|
# 2010 Peter Landgren
|
||||||
|
# Copyright (C) 2011 Adam Stein <adam@csh.rit.edu>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -569,7 +570,7 @@ class LaTeXDoc(BaseDoc, TextDoc):
|
|||||||
if self.curcol < self.numcols:
|
if self.curcol < self.numcols:
|
||||||
self._backend.write('& ')
|
self._backend.write('& ')
|
||||||
|
|
||||||
def add_media_object(self, name, pos, x, y, alt=''):
|
def add_media_object(self, name, pos, x, y, alt='', style_name=None, crop=None):
|
||||||
"""Add photo to report"""
|
"""Add photo to report"""
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -591,7 +592,7 @@ class LaTeXDoc(BaseDoc, TextDoc):
|
|||||||
else:
|
else:
|
||||||
self._backend.write('\\centerline{\\includegraphics[%s]{%s}}\n' % (mysize,picf))
|
self._backend.write('\\centerline{\\includegraphics[%s]{%s}}\n' % (mysize,picf))
|
||||||
|
|
||||||
def write_text(self,text,mark=None):
|
def write_text(self,text,mark=None,links=False):
|
||||||
"""Write the text to the file"""
|
"""Write the text to the file"""
|
||||||
if text == '\n':
|
if text == '\n':
|
||||||
text = '\\newline\n'
|
text = '\\newline\n'
|
||||||
@@ -601,7 +602,7 @@ class LaTeXDoc(BaseDoc, TextDoc):
|
|||||||
self._backend.write(text)
|
self._backend.write(text)
|
||||||
|
|
||||||
def write_styled_note(self, styledtext, format, style_name,
|
def write_styled_note(self, styledtext, format, style_name,
|
||||||
contains_html=False):
|
contains_html=False, links=False):
|
||||||
"""
|
"""
|
||||||
Convenience function to write a styledtext to the latex doc.
|
Convenience function to write a styledtext to the latex doc.
|
||||||
styledtext : assumed a StyledText object to write
|
styledtext : assumed a StyledText object to write
|
||||||
@@ -644,7 +645,7 @@ class LaTeXDoc(BaseDoc, TextDoc):
|
|||||||
self.end_paragraph()
|
self.end_paragraph()
|
||||||
self._backend.write("\n\\vspace*{0.5cm} \n\\end{minipage}\n\n")
|
self._backend.write("\n\\vspace*{0.5cm} \n\\end{minipage}\n\n")
|
||||||
|
|
||||||
def write_endnotes_ref(self, text, style_name):
|
def write_endnotes_ref(self, text, style_name, links=False):
|
||||||
"""
|
"""
|
||||||
Overwrite base method for lines of endnotes references
|
Overwrite base method for lines of endnotes references
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
# Copyright (C) 2007-2009 Brian G. Matherly
|
# Copyright (C) 2007-2009 Brian G. Matherly
|
||||||
# Copyright (C) 2010 Peter Landgren
|
# Copyright (C) 2010 Peter Landgren
|
||||||
# Copyright (C) 2010 Jakim Friant
|
# Copyright (C) 2010 Jakim Friant
|
||||||
|
# Copyright (C) 2011 Adam Stein <adam@csh.rit.edu>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -81,7 +82,7 @@ from xml.sax.saxutils import escape
|
|||||||
from gen.plug.docgen import (BaseDoc, TextDoc, DrawDoc, graphicstyle,
|
from gen.plug.docgen import (BaseDoc, TextDoc, DrawDoc, graphicstyle,
|
||||||
FONT_SANS_SERIF, SOLID, PAPER_PORTRAIT,
|
FONT_SANS_SERIF, SOLID, PAPER_PORTRAIT,
|
||||||
INDEX_TYPE_TOC, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT,
|
INDEX_TYPE_TOC, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT,
|
||||||
INDEX_TYPE_ALP, PARA_ALIGN_RIGHT)
|
INDEX_TYPE_ALP, PARA_ALIGN_RIGHT, URL_PATTERN)
|
||||||
from gen.plug.docgen.fontscale import string_width
|
from gen.plug.docgen.fontscale import string_width
|
||||||
from libodfbackend import OdfBackend
|
from libodfbackend import OdfBackend
|
||||||
import const
|
import const
|
||||||
@@ -416,6 +417,8 @@ _SHEADER_FOOTER = '''\
|
|||||||
</style:style>\n
|
</style:style>\n
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
_CLICKABLE = r'''<text:a xlink:type="simple" xlink:href="\1">\1</text:a>'''
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# ODFDoc
|
# ODFDoc
|
||||||
@@ -451,7 +454,8 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
self.new_cell = 0
|
self.new_cell = 0
|
||||||
self.page = 0
|
self.page = 0
|
||||||
self.first_page = 1
|
self.first_page = 1
|
||||||
self.StyleList = [] # styles to create depending on styled notes.
|
self.StyleList_notes = [] # styles to create depending on styled notes.
|
||||||
|
self.StyleList_photos = [] # styles to create depending on clipped images.
|
||||||
|
|
||||||
def open(self, filename):
|
def open(self, filename):
|
||||||
"""
|
"""
|
||||||
@@ -484,7 +488,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
self.lang = current_locale[0]
|
self.lang = current_locale[0]
|
||||||
self.lang = self.lang.replace('_', '-') if self.lang else "en-US"
|
self.lang = self.lang.replace('_', '-') if self.lang else "en-US"
|
||||||
|
|
||||||
self.StyleList = [] # styles to create depending on styled notes.
|
self.StyleList_notes = [] # styles to create depending on styled notes.
|
||||||
wrt1('<?xml version="1.0" encoding="UTF-8"?>\n'
|
wrt1('<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||||
'<office:document-content\n' +
|
'<office:document-content\n' +
|
||||||
_XMLNS +
|
_XMLNS +
|
||||||
@@ -783,9 +787,11 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
The content.xml file is closed.
|
The content.xml file is closed.
|
||||||
"""
|
"""
|
||||||
self.cntntx = StringIO()
|
self.cntntx = StringIO()
|
||||||
self.StyleList = self.uniq(self.StyleList)
|
self.StyleList_notes = self.uniq(self.StyleList_notes)
|
||||||
self.add_styled_notes_fonts()
|
self.add_styled_notes_fonts()
|
||||||
self.add_styled_notes_styles()
|
self.add_styled_notes_styles()
|
||||||
|
self.StyleList_photos = self.uniq(self.StyleList_photos)
|
||||||
|
self.add_styled_photo_styles()
|
||||||
self.cntntx.write(self.cntnt1.getvalue())
|
self.cntntx.write(self.cntnt1.getvalue())
|
||||||
self.cntntx.write(self.cntnt2.getvalue())
|
self.cntntx.write(self.cntnt2.getvalue())
|
||||||
self.cntntx.write(self.cntnt.getvalue())
|
self.cntntx.write(self.cntnt.getvalue())
|
||||||
@@ -815,7 +821,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
"""
|
"""
|
||||||
# Need to add new font for styled notes here.
|
# Need to add new font for styled notes here.
|
||||||
wrt1 = self.cntnt1.write
|
wrt1 = self.cntnt1.write
|
||||||
for style in self.StyleList:
|
for style in self.StyleList_notes:
|
||||||
if style[1] == "FontFace":
|
if style[1] == "FontFace":
|
||||||
wrt1(
|
wrt1(
|
||||||
'<style:font-face ' +
|
'<style:font-face ' +
|
||||||
@@ -830,7 +836,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
"""
|
"""
|
||||||
# Need to add new style for styled notes here.
|
# Need to add new style for styled notes here.
|
||||||
wrt2 = self.cntnt2.write
|
wrt2 = self.cntnt2.write
|
||||||
for style in self.StyleList:
|
for style in self.StyleList_notes:
|
||||||
if style[1] == "FontSize":
|
if style[1] == "FontSize":
|
||||||
wrt2(
|
wrt2(
|
||||||
'<style:style ' +
|
'<style:style ' +
|
||||||
@@ -874,7 +880,114 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
'</style:style>\n'
|
'</style:style>\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_media_object(self, file_name, pos, x_cm, y_cm, alt=''):
|
def add_styled_photo_styles(self):
|
||||||
|
"""
|
||||||
|
Add the new styles for clipped images in the automatic-styles section.
|
||||||
|
"""
|
||||||
|
wrt2 = self.cntnt2.write
|
||||||
|
for style in self.StyleList_photos:
|
||||||
|
if style[0] == "Left":
|
||||||
|
wrt2(
|
||||||
|
'<style:style ' +
|
||||||
|
'style:name="Left_%s" ' % str(style[1]) +
|
||||||
|
'style:family="graphic" ' +
|
||||||
|
'style:parent-style-name="photo">' +
|
||||||
|
'<style:graphic-properties ' +
|
||||||
|
'style:run-through="foreground" ' +
|
||||||
|
'style:wrap="dynamic" ' +
|
||||||
|
'style:number-wrapped-paragraphs="no-limit" ' +
|
||||||
|
'style:wrap-contour="false" ' +
|
||||||
|
'style:vertical-pos="from-top" ' +
|
||||||
|
'style:vertical-rel="paragraph-content" ' +
|
||||||
|
'style:horizontal-pos="left" ' +
|
||||||
|
'style:horizontal-rel="paragraph-content" ' +
|
||||||
|
'style:mirror="none" ' +
|
||||||
|
'fo:clip="rect(%fin %fin %fin %fin)" ' % style[1] +
|
||||||
|
'draw:luminance="0%" ' +
|
||||||
|
'draw:contrast="0" ' +
|
||||||
|
'draw:red="0%" ' +
|
||||||
|
'draw:green="0%" ' +
|
||||||
|
'draw:blue="0%" ' +
|
||||||
|
'draw:gamma="1" ' +
|
||||||
|
'draw:color-inversion="false" ' +
|
||||||
|
'draw:transparency="-100%" ' +
|
||||||
|
'draw:color-mode="standard"/>' +
|
||||||
|
'</style:style>\n'
|
||||||
|
)
|
||||||
|
elif style[0] == "Right":
|
||||||
|
wrt2(
|
||||||
|
'<style:style ' +
|
||||||
|
'style:name="Right_%s" ' % str(style[1]) +
|
||||||
|
'style:family="graphic" ' +
|
||||||
|
'style:parent-style-name="photo">' +
|
||||||
|
'<style:graphic-properties ' +
|
||||||
|
'style:run-through="foreground" ' +
|
||||||
|
'style:wrap="dynamic" ' +
|
||||||
|
'style:number-wrapped-paragraphs="no-limit" ' +
|
||||||
|
'style:wrap-contour="false" ' +
|
||||||
|
'style:vertical-pos="from-top" ' +
|
||||||
|
'style:vertical-rel="paragraph-content" ' +
|
||||||
|
'style:horizontal-pos="right" ' +
|
||||||
|
'style:horizontal-rel="paragraph-content" ' +
|
||||||
|
'style:mirror="none" ' +
|
||||||
|
'fo:clip="rect(%fin %fin %fin %fin)" ' % style[1] +
|
||||||
|
'draw:luminance="0%" ' +
|
||||||
|
'draw:contrast="0" ' +
|
||||||
|
'draw:red="0%" ' +
|
||||||
|
'draw:green="0%" ' +
|
||||||
|
'draw:blue="0%" ' +
|
||||||
|
'draw:gamma="1" ' +
|
||||||
|
'draw:color-inversion="false" ' +
|
||||||
|
'draw:transparency="-100%" ' +
|
||||||
|
'draw:color-mode="standard"/>' +
|
||||||
|
'</style:style>\n'
|
||||||
|
)
|
||||||
|
elif style[0] == "Single":
|
||||||
|
wrt2(
|
||||||
|
'<style:style ' +
|
||||||
|
'style:name="Single_%s" ' % str(style[1]) +
|
||||||
|
'style:family="graphic" ' +
|
||||||
|
'<style:graphic-properties ' +
|
||||||
|
'style:vertical-pos="from-top" ' +
|
||||||
|
'style:mirror="none" ' +
|
||||||
|
'fo:clip="rect(%fin %fin %fin %fin)" ' % style[1] +
|
||||||
|
'draw:luminance="0%" ' +
|
||||||
|
'draw:contrast="0" ' +
|
||||||
|
'draw:red="0%" ' +
|
||||||
|
'draw:green="0%" ' +
|
||||||
|
'draw:blue="0%" ' +
|
||||||
|
'draw:gamma="1" ' +
|
||||||
|
'draw:color-inversion="false" ' +
|
||||||
|
'draw:transparency="-100%" ' +
|
||||||
|
'draw:color-mode="standard"/>' +
|
||||||
|
'</style:style>\n'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
wrt2(
|
||||||
|
'<style:style ' +
|
||||||
|
'style:name="Row_%s" ' % str(style[1]) +
|
||||||
|
'style:family="graphic" ' +
|
||||||
|
'style:parent-style-name="Graphics">' +
|
||||||
|
'<style:graphic-properties ' +
|
||||||
|
'style:vertical-pos="from-top" ' +
|
||||||
|
'style:vertical-rel="paragraph" ' +
|
||||||
|
'style:horizontal-pos="from-left" ' +
|
||||||
|
'style:horizontal-rel="paragraph" ' +
|
||||||
|
'style:mirror="none" ' +
|
||||||
|
'fo:clip="rect(%fin %fin %fin %fin)" ' % style[1] +
|
||||||
|
'draw:luminance="0%" ' +
|
||||||
|
'draw:contrast="0" ' +
|
||||||
|
'draw:red="0%" ' +
|
||||||
|
'draw:green="0%" ' +
|
||||||
|
'draw:blue="0%" ' +
|
||||||
|
'draw:gamma="1" ' +
|
||||||
|
'draw:color-inversion="false" ' +
|
||||||
|
'draw:transparency="-100%" ' +
|
||||||
|
'draw:color-mode="standard"/>' +
|
||||||
|
'</style:style>\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
def add_media_object(self, file_name, pos, x_cm, y_cm, alt='', style_name=None, crop=None):
|
||||||
"""
|
"""
|
||||||
Add multi-media documents : photos
|
Add multi-media documents : photos
|
||||||
"""
|
"""
|
||||||
@@ -885,14 +998,6 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
if (x, y) == (0, 0):
|
if (x, y) == (0, 0):
|
||||||
return
|
return
|
||||||
|
|
||||||
ratio = float(x_cm) * float(y) / (float(y_cm) * float(x))
|
|
||||||
if ratio < 1:
|
|
||||||
act_width = x_cm
|
|
||||||
act_height = y_cm * ratio
|
|
||||||
else:
|
|
||||||
act_height = y_cm
|
|
||||||
act_width = x_cm / ratio
|
|
||||||
|
|
||||||
not_extension, extension = os.path.splitext(file_name)
|
not_extension, extension = os.path.splitext(file_name)
|
||||||
odf_name = md5(file_name).hexdigest() + extension
|
odf_name = md5(file_name).hexdigest() + extension
|
||||||
|
|
||||||
@@ -907,6 +1012,37 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
self.cntnt.write('<text:p>')
|
self.cntnt.write('<text:p>')
|
||||||
|
|
||||||
pos = pos.title() if pos in ['left', 'right', 'single'] else 'Row'
|
pos = pos.title() if pos in ['left', 'right', 'single'] else 'Row'
|
||||||
|
|
||||||
|
if crop:
|
||||||
|
dpi = ImgManip.image_dpi(file_name)
|
||||||
|
|
||||||
|
if dpi:
|
||||||
|
(act_width, act_height) = ImgManip.image_actual_size(
|
||||||
|
x_cm, y_cm, crop[2] - crop[0], crop[3] - crop[1]
|
||||||
|
)
|
||||||
|
|
||||||
|
left = ((crop[0]/100.0)*x)/dpi[0]
|
||||||
|
right = (x - ((crop[2]/100.0)*x))/dpi[0]
|
||||||
|
top = ((crop[1]/100.0)*y)/dpi[1]
|
||||||
|
bottom = (y - ((crop[3]/100.0)*y))/dpi[1]
|
||||||
|
|
||||||
|
crop = (top, right, bottom, left)
|
||||||
|
|
||||||
|
self.StyleList_photos.append(
|
||||||
|
[pos, crop]
|
||||||
|
)
|
||||||
|
|
||||||
|
pos += "_" + str(crop)
|
||||||
|
else:
|
||||||
|
(act_width, act_height) = ImgManip.image_actual_size(x_cm, y_cm, x, y)
|
||||||
|
else:
|
||||||
|
(act_width, act_height) = ImgManip.image_actual_size(x_cm, y_cm, x, y)
|
||||||
|
|
||||||
|
if len(alt):
|
||||||
|
self.cntnt.write('<draw:frame draw:style-name="%s" draw:name="caption_%s" text:anchor-type="paragraph" svg:y="0in" svg:width="%.2fcm" draw:z-index="34"> ' % (pos, tag, act_width))
|
||||||
|
self.cntnt.write('<draw:text-box fo:min-height="%.2fcm"> ' % act_height)
|
||||||
|
self.cntnt.write('<text:p text:style-name="%s">' % style_name)
|
||||||
|
|
||||||
self.cntnt.write(
|
self.cntnt.write(
|
||||||
'<draw:frame draw:style-name="%s" ' % pos +
|
'<draw:frame draw:style-name="%s" ' % pos +
|
||||||
'draw:name="%s" ' % tag +
|
'draw:name="%s" ' % tag +
|
||||||
@@ -920,6 +1056,14 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
'</draw:frame>\n'
|
'</draw:frame>\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if len(alt):
|
||||||
|
self.cntnt.write(
|
||||||
|
'%s' % alt +
|
||||||
|
'</text:p>' +
|
||||||
|
'</draw:text-box>' +
|
||||||
|
'</draw:frame>'
|
||||||
|
)
|
||||||
|
|
||||||
if self.new_cell:
|
if self.new_cell:
|
||||||
self.cntnt.write('</text:p>\n')
|
self.cntnt.write('</text:p>\n')
|
||||||
|
|
||||||
@@ -1355,7 +1499,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
)
|
)
|
||||||
self.new_cell = 1
|
self.new_cell = 1
|
||||||
|
|
||||||
def write_endnotes_ref(self, text, style_name):
|
def write_endnotes_ref(self, text, style_name, links=False):
|
||||||
"""
|
"""
|
||||||
Overwrite base method for lines of endnotes references
|
Overwrite base method for lines of endnotes references
|
||||||
"""
|
"""
|
||||||
@@ -1364,6 +1508,10 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
# Replace multiple spaces: have to go from the largest number down
|
# Replace multiple spaces: have to go from the largest number down
|
||||||
for n in range(text.count(' '), 1, -1):
|
for n in range(text.count(' '), 1, -1):
|
||||||
text = text.replace(' '*n, ' <text:s text:c="%d"/>' % (n-1) )
|
text = text.replace(' '*n, ' <text:s text:c="%d"/>' % (n-1) )
|
||||||
|
|
||||||
|
if links == True:
|
||||||
|
text = re.sub(URL_PATTERN, _CLICKABLE, text)
|
||||||
|
|
||||||
self.start_paragraph(style_name)
|
self.start_paragraph(style_name)
|
||||||
# self.cntnt.write('<text:span text:style-name="GRAMPS-preformat">')
|
# self.cntnt.write('<text:span text:style-name="GRAMPS-preformat">')
|
||||||
self.cntnt.write(
|
self.cntnt.write(
|
||||||
@@ -1374,7 +1522,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
self.end_paragraph()
|
self.end_paragraph()
|
||||||
|
|
||||||
def write_styled_note(self, styledtext, format, style_name,
|
def write_styled_note(self, styledtext, format, style_name,
|
||||||
contains_html=False):
|
contains_html=False, links=False):
|
||||||
"""
|
"""
|
||||||
Convenience function to write a styledtext to the ODF doc.
|
Convenience function to write a styledtext to the ODF doc.
|
||||||
styledtext : assumed a StyledText object to write
|
styledtext : assumed a StyledText object to write
|
||||||
@@ -1384,10 +1532,15 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
If contains_html=True, then the textdoc is free to handle that in
|
If contains_html=True, then the textdoc is free to handle that in
|
||||||
some way. Eg, a textdoc could remove all tags, or could make sure
|
some way. Eg, a textdoc could remove all tags, or could make sure
|
||||||
a link is clickable. ODFDoc prints the html without handling it
|
a link is clickable. ODFDoc prints the html without handling it
|
||||||
|
links: bool, make URLs clickable if True
|
||||||
"""
|
"""
|
||||||
text = str(styledtext)
|
text = str(styledtext)
|
||||||
s_tags = styledtext.get_tags()
|
s_tags = styledtext.get_tags()
|
||||||
markuptext = self._backend.add_markup_from_styled(text, s_tags, '\n')
|
markuptext = self._backend.add_markup_from_styled(text, s_tags, '\n')
|
||||||
|
|
||||||
|
if links == True:
|
||||||
|
markuptext = re.sub(URL_PATTERN, _CLICKABLE, markuptext)
|
||||||
|
|
||||||
# we need to know if we have new styles to add.
|
# we need to know if we have new styles to add.
|
||||||
# if markuptext contains : FontColor, FontFace, FontSize ...
|
# if markuptext contains : FontColor, FontFace, FontSize ...
|
||||||
# we must prepare the new styles for the styles.xml file.
|
# we must prepare the new styles for the styles.xml file.
|
||||||
@@ -1399,7 +1552,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
m = NewStyle.search(markuptext, start)
|
m = NewStyle.search(markuptext, start)
|
||||||
if not m:
|
if not m:
|
||||||
break
|
break
|
||||||
self.StyleList.append([m.group(1)+m.group(2),
|
self.StyleList_notes.append([m.group(1)+m.group(2),
|
||||||
m.group(1),
|
m.group(1),
|
||||||
m.group(2)])
|
m.group(2)])
|
||||||
start = m.end()
|
start = m.end()
|
||||||
@@ -1418,12 +1571,15 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
|||||||
linenb += 1
|
linenb += 1
|
||||||
self.end_paragraph()
|
self.end_paragraph()
|
||||||
|
|
||||||
def write_text(self, text, mark=None):
|
def write_text(self, text, mark=None, links=False):
|
||||||
"""
|
"""
|
||||||
Uses the xml.sax.saxutils.escape function to convert XML
|
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.
|
mappings.
|
||||||
"""
|
"""
|
||||||
|
if links == True:
|
||||||
|
text = re.sub(URL_PATTERN, _CLICKABLE, text)
|
||||||
|
|
||||||
if mark:
|
if mark:
|
||||||
key = escape(mark.key, _esc_map)
|
key = escape(mark.key, _esc_map)
|
||||||
key = key.replace('"', '"')
|
key = key.replace('"', '"')
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||||
# Copyright (C) 2007-2009 Brian G. Matherly
|
# Copyright (C) 2007-2009 Brian G. Matherly
|
||||||
# Copyright (C) 2010 Jakim Friant
|
# Copyright (C) 2010 Jakim Friant
|
||||||
|
# Copyright (C) 2011 Adam Stein <adam@csh.rit.edu>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -147,7 +148,7 @@ class PSDrawDoc(BaseDoc, DrawDoc):
|
|||||||
)
|
)
|
||||||
self.file.close()
|
self.file.close()
|
||||||
|
|
||||||
def write_text(self, text, mark=None):
|
def write_text(self, text, mark=None, links=False):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def start_page(self):
|
def start_page(self):
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
# Copyright (C) 2007-2009 Brian G. Matherly
|
# Copyright (C) 2007-2009 Brian G. Matherly
|
||||||
# Copyright (C) 2009 Gary Burton
|
# Copyright (C) 2009 Gary Burton
|
||||||
# Copyright (C) 2010 Peter Landgren
|
# Copyright (C) 2010 Peter Landgren
|
||||||
|
# Copyright (C) 2011 Adam Stein <adam@csh.rit.edu>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -372,7 +373,7 @@ class RTFDoc(BaseDoc,TextDoc):
|
|||||||
# dumped as a string of HEX numbers.
|
# dumped as a string of HEX numbers.
|
||||||
#
|
#
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
def add_media_object(self, name, pos, x_cm, y_cm, alt=''):
|
def add_media_object(self, name, pos, x_cm, y_cm, alt='', style_name=None, crop=None):
|
||||||
|
|
||||||
nx, ny = ImgManip.image_size(name)
|
nx, ny = ImgManip.image_size(name)
|
||||||
|
|
||||||
@@ -408,7 +409,7 @@ class RTFDoc(BaseDoc,TextDoc):
|
|||||||
self.f.write('}}\\par\n')
|
self.f.write('}}\\par\n')
|
||||||
|
|
||||||
def write_styled_note(self, styledtext, format, style_name,
|
def write_styled_note(self, styledtext, format, style_name,
|
||||||
contains_html=False):
|
contains_html=False, links=False):
|
||||||
"""
|
"""
|
||||||
Convenience function to write a styledtext to the RTF doc.
|
Convenience function to write a styledtext to the RTF doc.
|
||||||
styledtext : assumed a StyledText object to write
|
styledtext : assumed a StyledText object to write
|
||||||
@@ -446,7 +447,7 @@ class RTFDoc(BaseDoc,TextDoc):
|
|||||||
self.write_text('\n')
|
self.write_text('\n')
|
||||||
self.end_paragraph()
|
self.end_paragraph()
|
||||||
|
|
||||||
def write_endnotes_ref(self,text,style_name):
|
def write_endnotes_ref(self,text,style_name,links=False):
|
||||||
"""
|
"""
|
||||||
Overwrite base method for lines of endnotes references
|
Overwrite base method for lines of endnotes references
|
||||||
"""
|
"""
|
||||||
@@ -469,7 +470,7 @@ class RTFDoc(BaseDoc,TextDoc):
|
|||||||
# the form of \`XX. Make sure to escape braces.
|
# the form of \`XX. Make sure to escape braces.
|
||||||
#
|
#
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
def write_text(self,text,mark=None):
|
def write_text(self,text,mark=None,links=False):
|
||||||
# Convert to unicode, just in case it's not. Fix of bug 2449.
|
# Convert to unicode, just in case it's not. Fix of bug 2449.
|
||||||
text = unicode(text)
|
text = unicode(text)
|
||||||
text = text.replace('\n','\n\\par ')
|
text = text.replace('\n','\n\\par ')
|
||||||
|
|||||||
Reference in New Issue
Block a user