From 65d2604db7d96a5a6347d63bb2c764aa49d39785 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Mon, 22 Feb 2021 00:51:45 +1100 Subject: [PATCH] Implement selective referencing of page numbers for PDF --- extension.py | 73 +++++++++++++++++++++++++++++++++++++++++++++--- preamble.tex.txt | 1 + 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/extension.py b/extension.py index faf426e..6802ecf 100644 --- a/extension.py +++ b/extension.py @@ -9,7 +9,10 @@ def setup(app): app.add_builder(POLaTeXBuilder, override=True) app.add_builder(POEpub3Builder, override=True) + app.add_role('mref', MRefRole()) + app.add_role('mdoc', MDocRole()) app.add_role('subref', SubRefRole()) + app.add_role('msubref', MSubRefRole()) #app.add_source_parser(PORSTParser, override=True) @@ -109,6 +112,15 @@ class POLaTeXTranslator(LaTeXTranslator): #self.body.append(r'\makebox[0pt][r]{{\small\textcolor[HTML]{{AAAAAA}}{{¶{0}}}\hspace{{0.8em}}}}'.format(self.paragraph_num)) #self.body.append(r'{{\small\textcolor[HTML]{{AAAAAA}}{{[¶{0}]}}}} '.format(self.paragraph_num)) self.body.append(r'{{\small\bfseries\sffamily[{0}]}} '.format(self.paragraph_num)) + + def visit_reference(self, node): + if 'po_mref' in node.attributes: + # Force page reference + self.builder.config.latex_show_pagerefs = True + super().visit_reference(node) + self.builder.config.latex_show_pagerefs = False + else: + super().visit_reference(node) class POLaTeXBuilder(LaTeXBuilder): default_translator_class = POLaTeXTranslator @@ -130,12 +142,41 @@ class POEpub3Builder(Epub3Builder): 'text': 'Index' }) -# :subref: Role +# Referencing roles from sphinx.roles import XRefRole -class SubRefRole(XRefRole): +class MRefRole(XRefRole): + # Like :ref:, but in LaTeX includes a page number + def __init__(self, *args, **kwargs): + # cf. sphinx.domains.std.StandardDomain.roles + super().__init__(lowercase=True, innernodeclass=docutils.nodes.inline, warn_dangling=True, *args, **kwargs) + + def run(self): + self.name = 'std:ref' + return super().run() + + def result_nodes(self, document, env, node, is_ref): + result = super().result_nodes(document, env, node, is_ref) + pending_xref = result[0][0] + pending_xref['po_mref'] = True # Flag for StandardDomain._resolve_ref_xref + return result + +class MDocRole(MRefRole): + def __init__(self, *args, **kwargs): + # cf. sphinx.domains.std.StandardDomain.roles + XRefRole.__init__(self, innernodeclass=docutils.nodes.inline, warn_dangling=True, *args, **kwargs) + + def run(self): + self.name = 'std:doc' + return XRefRole.run(self) + +class SubRefRole(XRefRole): + # Like :ref: but uses a substitution text as the label - allows for nested inline formatting + + def __init__(self, *args, **kwargs): + # cf. sphinx.domains.std.StandardDomain.roles super().__init__(lowercase=True, innernodeclass=docutils.nodes.inline, warn_dangling=True, *args, **kwargs) def run(self): @@ -156,6 +197,16 @@ class SubRefRole(XRefRole): return result +class MSubRefRole(SubRefRole, MRefRole): + def __init__(self, *args, **kwargs): + XRefRole.__init__(self, lowercase=True, innernodeclass=docutils.nodes.inline, warn_dangling=True, *args, **kwargs) + + def result_nodes(self, document, env, node, is_ref): + result = SubRefRole.result_nodes(self, document, env, node, is_ref) + pending_xref = result[0][0] + pending_xref['po_mref'] = True # Flag for StandardDomain._resolve_ref_xref + return result + from sphinx.domains.std import StandardDomain __StandardDomain_resolve_ref_xref = StandardDomain._resolve_ref_xref @@ -178,11 +229,25 @@ def _StandardDomain_resolve_ref_xref(self, env, fromdocname, builder, typ, targe # Copy across substitution newnode.children.extend(node.children) - return newnode + + result = newnode + else: + result = __StandardDomain_resolve_ref_xref(self, env, fromdocname, builder, typ, target, node, contnode) - return __StandardDomain_resolve_ref_xref(self, env, fromdocname, builder, typ, target, node, contnode) + if 'po_mref' in node: + result['po_mref'] = True # Propagate flag for POLaTeXTranslator.visit_reference + + return result StandardDomain._resolve_ref_xref = _StandardDomain_resolve_ref_xref +__StandardDomain_resolve_doc_xref = StandardDomain._resolve_doc_xref +def _StandardDomain_resolve_doc_xref(self, env, fromdocname, builder, typ, target, node, contnode): + result = __StandardDomain_resolve_doc_xref(self, env, fromdocname, builder, typ, target, node, contnode) + if 'po_mref' in node: + result['po_mref'] = True # Propagate flag for POLaTeXTranslator.visit_reference + return result +StandardDomain._resolve_doc_xref = _StandardDomain_resolve_doc_xref + # RST Parser from sphinx.parsers import RSTParser diff --git a/preamble.tex.txt b/preamble.tex.txt index 498f098..5efe8eb 100644 --- a/preamble.tex.txt +++ b/preamble.tex.txt @@ -13,6 +13,7 @@ \def\sphinxstyleindexentry#1{#1} % no monospaced index entries \def\sphinxstyleindexextra#1{ (#1)} % no italics \def\sphinxtablecontinued#1{{\sffamily\footnotesize #1}} % add footnotesize +\def\pageautorefname{p.} % Allow line breaks in URLs \usepackage{seqsplit}