ftw.pdfgenerator is meant to be used for generating PDFs from structured
data using predefined LaTeX views. It is not useful for converting
full HTML pages into LaTeX / PDFs, although it is able to convert small HTML
chunks into LaTeX.
ftw.pdfgenerator requires a TeX distribution with a pdflatex executable to be installed.
These TeX distributions are recommended:
The package is compatible with Plone 4.3 and 5.1.
Add ftw.pdfgenerator to your buildout configuration:
[instance] eggs = ftw.pdfgenerator
The pdfgenerator uses LaTeX for generating the PDF. You need to provide a layout and a view for your context for being able to create a PDF.
Some packages using ftw.pdfgenerator:
ftw.meetinghas a PDF export of the meeting minutes: https://github.com/4teamwork/ftw.meeting/tree/master/ftw/meeting/latexftw.bookproduces a PDF of the book recursively: https://github.com/4teamwork/ftw.book/tree/master/ftw/book/latex
A layout is a multi adapter addapting context, request, builder. You can
easily define a new layout using the mako templating engine
(example: layout.py):
>>> from example.conference.session import ISession
>>> from ftw.pdfgenerator.interfaces import IBuilder
>>> from ftw.pdfgenerator.interfaces import ICustomizableLayout
>>> from ftw.pdfgenerator.layout.customizable import CustomizableLayout
>>> from zope.component import adapts
>>> from zope.interface import Interface
>>> from zope.interface import implements
>>> class SessionLayout(MakoLayoutBase):
... adapts(ISession, Interface, IBuilder)
... implements(ICustomizableLayout)
...
... template_directories = ['session_templates']
... template_name = 'layout.tex'
...
... def before_render_hook(self):
... self.use_babel()
... self.use_package('inputenc', options='utf8')
... self.use_package('fontenc', options='T1')
Register the layout with zcml (example: configure.zcml):
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">
<adapter factory=".layout.SessionLayout"
provides="ftw.pdfgenerator.interfaces.ILaTeXLayout" />
</configure>
Create a template as defined in SessionLayout.template_name
(example: session_templates/layout.tex):
<%block name="documentclass">
\documentclass[a4paper,10pt]{article}
</%block>
<%block name="usePackages">
${packages}
</%block>
<%block name="beneathPackages">
</%block>
<%block name="aboveDocument">
</%block>
\begin{document}
<%block name="documentTop">
% if logo:
${logo}
% endif
</%block>
${content}
<%block name="documentBottom">
</%block>
\end{document}
There are more methods on the layout, see the definition in
ftw.pdfgenerator.interfaces.ILaTeXLayout.
For every context for which a PDF is generated a LaTeX view (ILaTeXView)
is rendered. The view is a multi adapter adapting context, request, layout.
There is a view based on the mako templating engine which can be extended
(example: views.py):
>>> from example.conference.session import ISession
>>> from ftw.pdfgenerator.interfaces import ILaTeXLayout
>>> from ftw.pdfgenerator.interfaces import ILaTeXView
>>> from ftw.pdfgenerator.view import MakoLaTeXView
>>> from zope.component import adapts
>>> from zope.interface import Interface
>>> from zope.interface import implements
>>> class SessionLaTeXView(MakoLaTeXView):
... adapts(ISession, Interface, ILaTeXLayout)
... implements(ILaTeXView)
...
... template_directories = ['session_templates']
... template_name = 'view.tex'
...
... def get_render_arguments(self):
... return {'title': self.convert(self.context.Title()),
... 'description': self.convert(self.context.description),
... 'details': self.convert(self.context.details)}
Register the view with zcml (example: configure.zcml):
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">
<adapter factory=".views.SessionLaTeXView"
provides="ftw.pdfgenerator.interfaces.ILaTeXView" />
</configure>
Create a template with the name defined in the class
(example: session_templates/view.tex):
\section*{${title}}
% if description:
\small ${description}
% endif
\normalsize ${details}
When a layout and a view for the context are registered the PDF can be
generated by simply calling the view @@export_pdf on the context.
When extending from ftw.pdfgenerator.view.RecursiveLaTeXView and inserting
the variable latex_content in your template, the view automatically renders
all children for which a ILaTeXView is found.
ftw.pdfgenerator comes with a simple but powerful HTML to LaTeX converter
which is optimized for the common WYSIWYG-Editors used in Plone.
The converter can be used:
- in views, using
self.convert(html) - in layouts, using
self.get_converter().convert(html)
It uses regular expressions for the simple conversions and python subconverters for the more complicated conversions. The converter is heavily customizable.
Generate a footnote by wrapping any text in a span with the
class footnote. Specify the footnote text in the data-footnote attribute.
Example:
<span class="footnote" data-footnote="text in footnote">text on the page</span>
When using multiple, independent addon packages using ftw.pdfgenerator,
every package may implement a new, specific layout. This can be painful if
there is a need to customize all layouts and add a logo image for example.
For making this easier all customizable layouts can be customized with one
single adapter. This only works for layouts subclassing
ftw.pdfgenerator.layout.customizable.CustomizableLayout. Those layouts
need to follow certain concepts and provide inheritable blocks in the mako
template. Ensure you follow the standards by subclassing and running the
tests from
ftw.pdfgenerator.tests.test_customizable_layout.TestCustomizableLayout.
Implementing customization adapter is very simple when customizable layouts
are used. For example we change the logo image (assume the logo is at
custom/mylogo.png):
>>> from ftw.pdfgenerator.customization import LayoutCustomization
>>> from ftw.pdfgenerator.interfaces import ILayoutCustomization
>>> from zope.interface import implements
>>>
>>> class MyCustomization(LayoutCustomization):
... implements(ILayoutCustomization)
...
... template_directories = ['custom']
... template_name = 'layout_customization.tex'
...
... def before_render_hook(self):
... self.add_raw_template_file('mylogo.png')
... self.layout.use_package('graphicx')
...
... def get_render_arguments(self, args):
... args['logo'] = r'\includegraphics{mylogo.png}'
... return args
It is also possible to change the template and fill predefined slots
(example: custom/layout_customization.tex):
<%inherit file="original_layout" /> <%block name="documentTop"> my branding </%block>
The layout customization adapter adapts context, request and the original
layout.
ftw.pdfgenerator is able to convert HTML-Tables to LaTeX. Since HTML and LaTeX
have completely different presentation concepts the convertion is limitted.
For getting the best results theese rules should be followed:
- Define the width of every column. The table will be streched to the text width in the defined proportions. Without defining the widths LaTeX is unable to insert newlines dynamically.
- Use relative widths (%).
- Define table headings using
<thead>for long tables which may be splitted over multiple pages.
CSS classes:
page-break(<table>)- Force the
longtableenvironment, allowing LaTeX to split up the table over multiple pages. no-page-break(<table>)- Force the
tabularenvironment, prohibiting LaTeX from splitting the table up over multiple pages. If the table is longer than the page it is truncated - content may be missing in this case. border-grid/listing(<table>)- Display the table in a grid: every cell has a border on every side.
notListed(<table>)- When using a
<caption>, do not list the table in the list of tables. border-left(<td>, <th>)- Display a border on the left side of the cell.
border-right(<td>, <th>)- Display a border on the right side of the cell.
border-top(<td>, <th>)- Display a border on the top side of the cell.
border-bottom(<td>, <th>)- Display a border on the bottom side of the cell.
right(<td>, <th>)- Right align the content of the cell.
left(<td>, <th>)- Left align the content of the cell.
center(<td>, <th>)- Center the content of the cell.
indent2(<td>, <th>)- Indent the content by 0.2 cm.
indent10(<td>, <th>)- Indent the content by 1 cm.
bold(<td>, <th>)- Display cell contents in bold font.
grey(<td>, <th>)- Display cell content with grey text color.
footnotesize(<td>, <th>)- Display cell content with smaller font size (
\footnotesize). scriptsize(<td>, <th>)- Display cell content with smaller font size (
\scriptsize).
- Github: https://github.com/4teamwork/ftw.pdfgenerator
- Issues: https://github.com/4teamwork/ftw.pdfgenerator/issues
- Pypi: http://pypi.python.org/pypi/ftw.pdfgenerator
- Continuous integration: https://jenkins.4teamwork.ch/search?q=ftw.pdfgenerator
This package is copyright by 4teamwork.
ftw.pdfgenerator is licensed under GNU General Public License, version 2.
