From a699cbc09a966132a987369a76cb254ee0a4f3c2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 8 Aug 2016 09:52:46 +0530 Subject: [PATCH] PDF Output: Add a new variable _TOP_LEVEL_SECTION_ for use in header/footer templates that resolves to the current top-most section in the Table of Contents --- manual/conversion.rst | 3 +- resources/compiled_coffeescript.zip | Bin 101460 -> 101615 bytes src/calibre/ebooks/oeb/display/paged.coffee | 5 ++-- src/calibre/ebooks/pdf/render/from_html.py | 29 ++++++++++++-------- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/manual/conversion.rst b/manual/conversion.rst index 93d2a3e087..43fd14378d 100644 --- a/manual/conversion.rst +++ b/manual/conversion.rst @@ -846,7 +846,8 @@ _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. +the page will be used. Similarly, there is a variable named _TOP_LEVEL_SECTION_ +that can be used to ge the name of the current top-level section. You can even use javascript inside the header and footer templates, for example, the following template will cause page numbers to start at 4 instead diff --git a/resources/compiled_coffeescript.zip b/resources/compiled_coffeescript.zip index a000d7c1684528019e5b30962bc1ec891a32b537..b93b2a8de975ef66a685dbf63995553e6829f19c 100644 GIT binary patch delta 340 zcmcaIgYErHwhiC+3LbFf@chx@qRE!azyQM1lO4OoHp}gsX2zqVP?8g0oSIycnV+|L z%a?VGG73l{3bqObmGMbMnJMY1dO(Gf1Hau;2=Nby_i+t#^@$I5bq?|L_lwt0M=?g~ zy9^^iRgBv`V<)4MMv7UINn(<*p`n?nfuRAAFiAB{G)y*6v`90xOtCb!FiJ^Dv`9*x{-Kjm ad~$d<-*o40M(4@7iCoifcQfiT)&c+yAb0Hm delta 256 zcmaDqlkLh3whiC+3Qp5v@m%x7#UeY0fdPc2Cp&hFZI;_N&2005FY6d5&;E9D^VIL$ zjFYE+SK0jahs*>%R2|dhI~gOHCu%WHXY61Unf{@Rkz@MwPDU-3OAd?-)Ax2WN>6_P z;+lH_xrN<~GSjuX7zLO2vRL9EK{d1=wTF}ey*L7ZMtJOqxJOlJwW@`cQA5KU)u%b)^s!a jK*SO{82P4`^e{Suoa8+@H<4@l!5&84>ASiay%}o(h9_Kc diff --git a/src/calibre/ebooks/oeb/display/paged.coffee b/src/calibre/ebooks/oeb/display/paged.coffee index 88d7090d58..2985179706 100644 --- a/src/calibre/ebooks/oeb/display/paged.coffee +++ b/src/calibre/ebooks/oeb/display/paged.coffee @@ -309,11 +309,12 @@ class PagedDisplay title = py_bridge.title() author = py_bridge.author() section = py_bridge.section() + tl_section = py_bridge.tl_section() if this.header != null - this.header.innerHTML = this.header_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"").replace(/_SECTION_/g, section+"") + this.header.innerHTML = this.header_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"").replace(/_TOP_LEVEL_SECTION_/g, tl_section+"").replace(/_SECTION_/g, section+"") runscripts(this.header) if this.footer != null - this.footer.innerHTML = this.footer_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"").replace(/_SECTION_/g, section+"") + this.footer.innerHTML = this.footer_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"").replace(/_TOP_LEVEL_SECTION_/g, tl_section+"").replace(/_SECTION_/g, section+"") runscripts(this.footer) fit_images: () -> diff --git a/src/calibre/ebooks/pdf/render/from_html.py b/src/calibre/ebooks/pdf/render/from_html.py index 5cc54aff1d..2fc45f37bb 100644 --- a/src/calibre/ebooks/pdf/render/from_html.py +++ b/src/calibre/ebooks/pdf/render/from_html.py @@ -145,6 +145,10 @@ class PDFWriter(QObject): def section(self): return self.current_section + @pyqtSlot(result=unicode) + def tl_section(self): + return self.current_tl_section + def __init__(self, opts, log, cover_data=None, toc=None): from calibre.gui2 import must_use_qt must_use_qt() @@ -169,6 +173,7 @@ class PDFWriter(QObject): Qt.ScrollBarAlwaysOff) self.report_progress = lambda x, y: x self.current_section = '' + self.current_tl_section = '' def dump(self, items, out_stream, pdf_metadata): opts = self.opts @@ -310,11 +315,12 @@ class PDFWriter(QObject): self.loop.processEvents(self.loop.ExcludeUserInputEvents) evaljs('document.getElementById("MathJax_Message").style.display="none";') - def get_sections(self, anchor_map): + def get_sections(self, anchor_map, only_top_level=False): sections = defaultdict(list) ci = os.path.abspath(os.path.normcase(self.current_item)) if self.toc is not None: - for toc in self.toc.flat(): + tocentries = self.toc.top_level_items() if only_top_level else self.toc.flat() + for toc in tocentries: path = toc.abspath or None frag = toc.fragment or None if path is None: @@ -362,6 +368,7 @@ class PDFWriter(QObject): if not isinstance(amap, dict): amap = {'links':[], 'anchors':{}} # Some javascript error occurred sections = self.get_sections(amap['anchors']) + tl_sections = self.get_sections(amap['anchors'], True) col = 0 if self.header: @@ -376,13 +383,16 @@ class PDFWriter(QObject): start_page = self.current_page_num mf = self.view.page().mainFrame() + + def set_section(col, sections, attr): + # If this page has no section, use the section from the previous page + idx = col if col in sections else col - 1 if col - 1 in sections else None + if idx is not None: + setattr(self, attr, sections[idx][0]) + while True: - if col in sections: - self.current_section = sections[col][0] - elif col - 1 in sections: - # Ensure we are using the last section on the previous page as - # the section for this page, since this page has no sections - self.current_section = sections[col-1][-1] + set_section(col, sections, 'current_section') + set_section(col, tl_sections, 'current_tl_section') self.doc.init_page() if self.header or self.footer: evaljs('paged_display.update_header_footer(%d)'%self.current_page_num) @@ -404,6 +414,3 @@ class PDFWriter(QObject): if not self.doc.errors_occurred: self.doc.add_links(self.current_item, start_page, amap['links'], amap['anchors']) - - -