PDF Output: Allow use of _SECTION_ in header/footer templates

This commit is contained in:
Kovid Goyal 2013-04-01 15:16:50 +05:30
parent 6201e2a19b
commit a688a8018c
5 changed files with 47 additions and 6 deletions

View File

@ -794,6 +794,16 @@ template::
This will display the title at the left and the author at the right, in a font
size smaller than the main text.
Finally, you can also use the current section in templates, as shown below::
<p style="text-align:right">_SECTION_</p>
_SECTION_ is replaced by whatever the name of the current section is. These
names are taken from the metadata Table of Contents in the document (the PDF
Outline). If the document has no table of contents then it will be replaced by
empty text. If a single PDF page has multiple sections, the first section on
the page will be used.
.. note:: When adding headers and footers make sure you set the page top and
bottom margins to large enough values, under the Page Setup section of the
conversion dialog.

Binary file not shown.

View File

@ -104,11 +104,11 @@ class PDFOutput(OutputFormatPlugin):
'specify a footer template, it will take precedence '
'over this option.')),
OptionRecommendation(name='pdf_footer_template', recommended_value=None,
help=_('An HTML template used to generate footers on every page.'
' The strings _PAGENUM_, _TITLE_ and _AUTHOR_ will be replaced by their current values.')),
help=_('An HTML template used to generate %s on every page.'
' The strings _PAGENUM_, _TITLE_, _AUTHOR_ and _SECTION_ will be replaced by their current values.')%_('footers')),
OptionRecommendation(name='pdf_header_template', recommended_value=None,
help=_('An HTML template used to generate headers on every page.'
' The strings _PAGENUM_, _TITLE_ and _AUTHOR_ will be replaced by their current values.')),
help=_('An HTML template used to generate %s on every page.'
' The strings _PAGENUM_, _TITLE_, _AUTHOR_ and _SECTION_ will be replaced by their current values.')%_('headers')),
])
def convert(self, oeb_book, output_path, input_plugin, opts, log):

View File

@ -216,10 +216,11 @@ class PagedDisplay
this.hf_style.innerHTML = "#pdf_page_header_#{ this.hf_uuid } .#{ cls }, #pdf_page_footer_#{ this.hf_uuid } .#{ cls } { display: none }"
title = py_bridge.title()
author = py_bridge.author()
section = py_bridge.section()
if this.header != null
this.header.innerHTML = this.header_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"")
this.header.innerHTML = this.header_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"").replace(/_SECTION_/g, section+"")
if this.footer != null
this.footer.innerHTML = this.footer_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"")
this.footer.innerHTML = this.footer_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"").replace(/_SECTION_/g, section+"")
fit_images: () ->
# Ensure no images are wider than the available width in a column. Note

View File

@ -138,6 +138,10 @@ class PDFWriter(QObject):
def author(self):
return self.doc_author
@pyqtSlot(result=unicode)
def section(self):
return self.current_section
def __init__(self, opts, log, cover_data=None, toc=None):
from calibre.gui2 import is_ok_to_use_qt
if not is_ok_to_use_qt():
@ -162,6 +166,7 @@ class PDFWriter(QObject):
self.view.page().mainFrame().setScrollBarPolicy(x,
Qt.ScrollBarAlwaysOff)
self.report_progress = lambda x, y: x
self.current_section = ''
def dump(self, items, out_stream, pdf_metadata):
opts = self.opts
@ -287,6 +292,25 @@ class PDFWriter(QObject):
self.loop.processEvents(self.loop.ExcludeUserInputEvents)
evaljs('document.getElementById("MathJax_Message").style.display="none";')
def get_sections(self, anchor_map):
sections = {}
ci = os.path.abspath(os.path.normcase(self.current_item))
if self.toc is not None:
for toc in self.toc.flat():
path = toc.abspath or None
frag = toc.fragment or None
if path is None:
continue
path = os.path.abspath(os.path.normcase(path))
if path == ci:
col = 0
if frag and frag in anchor_map:
col = anchor_map[frag]['column']
if col not in sections:
sections[col] = toc.text or _('Untitled')
return sections
def do_paged_render(self):
if self.paged_js is None:
import uuid
@ -321,6 +345,8 @@ class PDFWriter(QObject):
amap = self.bridge_value
if not isinstance(amap, dict):
amap = {'links':[], 'anchors':{}} # Some javascript error occurred
sections = self.get_sections(amap['anchors'])
col = 0
if self.header:
self.bridge_value = self.header
@ -335,6 +361,8 @@ class PDFWriter(QObject):
mf = self.view.page().mainFrame()
while True:
if col in sections:
self.current_section = sections[col]
self.doc.init_page()
if self.header or self.footer:
evaljs('paged_display.update_header_footer(%d)'%self.current_page_num)
@ -348,8 +376,10 @@ class PDFWriter(QObject):
evaljs('window.scrollTo(%d, 0); paged_display.position_header_footer();'%nsl[0])
if self.doc.errors_occurred:
break
col += 1
if not self.doc.errors_occurred:
self.doc.add_links(self.current_item, start_page, amap['links'],
amap['anchors'])