diff --git a/example.md b/example.md
index 3b36983..6c4ae75 100644
--- a/example.md
+++ b/example.md
@@ -22,7 +22,7 @@ This is the *blah blah*.
hijkl
- Continued
+ Cross reference to `rule 1`_
(2) DEF
diff --git a/example.pdf b/example.pdf
index 50fdf72..96b89b8 100644
Binary files a/example.pdf and b/example.pdf differ
diff --git a/example.rtf b/example.rtf
index 157b11c..14ceecb 100644
--- a/example.rtf
+++ b/example.rtf
@@ -1 +1 @@
-{\rtf1\deff0{\fonttbl{\f0 TeX Gyre Heros{\*\falt FreeSans}{\*\falt Liberation Sans}{\*\falt Arial};}}\paperw11905\paperh16837\margl1133\margr1133\margt1133\margb1133{\header\f0\fs16\tqr\tx9637 Example Legal Document\tab }{\footer\f0\fs16\tqr\tx9637 \tab\chpgn}\sa198\fs1\~\fs24 {\fs20\li566{\b Note:} This is a note.\par}{\sb566\keepn\b\fs26\qc\caps Part 1\u8212?Preliminary\par}{\keepn\b\fi-566\li566 1\tab Short title\par}{\li566 This is the {\i blah blah}.\par}{\keepn\b\fi-566\li566 2\tab Another heading\par}{\fi-566\li1133 (1)\tab ABC\par}{\li1133 Continued\par}{\fi-566\li1700 (a)\tab asdf\par}{\fi-566\li1700 (b)\tab abcdefg\par}{\li1700 hijkl\par}{\li1133 Continued\par}{\fi-566\li1133 (2)\tab DEF\par}{\keepn\b\fi-566\li566 3\tab Table example\par}{\sa0\trowd\trgaph120\trleft566\clbrdrt\brdrs\clbrdrb\brdrs\cellx2380\clbrdrt\brdrs\clbrdrb\brdrs\cellx9636 {\b Column 1\intbl\cell}{\b Column 2\intbl\cell}\row{\b This is a long column header that will overflow onto multiple lines\intbl\cell}{\b Second column\intbl\cell}\row {1. First row\intbl\cell}{Foo bar\intbl\cell}\row {2. Second row\intbl\cell}{Baz qux\intbl\cell}\row }}
+{\rtf1\deff0{\fonttbl{\f0 TeX Gyre Heros{\*\falt FreeSans}{\*\falt Liberation Sans}{\*\falt Arial};}}\paperw11905\paperh16837\margl1133\margr1133\margt1133\margb1133{\header\f0\fs16\tqr\tx9637 Example Legal Document\tab }{\footer\f0\fs16\tqr\tx9637 \tab\chpgn}\sa198\fs1\~\fs24 {\fs20\li566{\b Note:} This is a note.\par}{\sb566\keepn\b\fs26\qc\caps Part 1\u8212?Preliminary\par}{\keepn\b\fi-566\li566 1\tab Short title\par}{\li566 This is the {\i blah blah}.\par}{\keepn\b\fi-566\li566 2\tab Another heading\par}{\fi-566\li1133 (1)\tab ABC\par}{\li1133 Continued\par}{\fi-566\li1700 (a)\tab asdf\par}{\fi-566\li1700 (b)\tab abcdefg\par}{\li1700 hijkl\par}{\li1133 Cross reference to rule\u160?1\par}{\fi-566\li1133 (2)\tab DEF\par}{\keepn\b\fi-566\li566 3\tab Table example\par}{\sa0\trowd\trgaph120\trleft566\clbrdrt\brdrs\clbrdrb\brdrs\cellx2380\clbrdrt\brdrs\clbrdrb\brdrs\cellx9636 {\b Column 1\intbl\cell}{\b Column 2\intbl\cell}\row{\b This is a long column header that will overflow onto multiple lines\intbl\cell}{\b Second column\intbl\cell}\row {1. First row\intbl\cell}{Foo bar\intbl\cell}\row {2. Second row\intbl\cell}{Baz qux\intbl\cell}\row }}
diff --git a/legalmd/__main__.py b/legalmd/__main__.py
index da86322..11c3f11 100644
--- a/legalmd/__main__.py
+++ b/legalmd/__main__.py
@@ -40,4 +40,22 @@ with renderer_cls() as renderer:
doc.author = rawdoc.get('author', '')
doc.footer = rawdoc.get('footer', '')
+ doc.full_label_map = {}
+
+ # Preprocess custom tokens
+ def walk_elem(elem, parent=None):
+ elem.doc = doc
+ elem.parent = parent
+
+ if isinstance(elem, legal_token.NumberedHeading) or isinstance(elem, legal_token.SubrulesItem):
+ full_label = elem.full_label()
+ if full_label:
+ doc.full_label_map[full_label] = elem
+
+ if hasattr(elem, 'children'):
+ for child in elem.children:
+ walk_elem(child, elem)
+
+ walk_elem(doc)
+
print(renderer.render(doc))
diff --git a/legalmd/latex_renderer.py b/legalmd/latex_renderer.py
index d78f5ff..19345a4 100644
--- a/legalmd/latex_renderer.py
+++ b/legalmd/latex_renderer.py
@@ -14,6 +14,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
+import hashlib
+
import mistletoe
import mistletoe.latex_renderer
@@ -35,6 +37,8 @@ class LaTeXRenderer(mistletoe.latex_renderer.LaTeXRenderer):
def __init__(self, *extras):
super().__init__(*extras)
+ self.render_map['CrossReference'] = self.render_cross_reference
+
self.render_map['NumberedHeading'] = self.render_numbered_heading
self.render_map['Subrules'] = self.render_subrules
self.render_map['SubrulesItem'] = self.render_subrules_item
@@ -48,6 +52,20 @@ class LaTeXRenderer(mistletoe.latex_renderer.LaTeXRenderer):
result = result.replace('★★★', r'\texorpdfstring{\freeserif ★★★}{★★★}')
return result
+ def render_cross_reference(self, token):
+ reference = token.get_reference()
+ if not reference:
+ raise Exception('Unable to resolve reference "{}"'.format(token.reference_num))
+
+ sha = hashlib.sha256()
+ sha.update(reference.full_label().encode('utf-8'))
+
+ return format(r'\hyperlink{}{}',
+ linkname=sha.hexdigest(),
+ reference_type=(token.reference_type + '~') if token.reference_type else '',
+ reference_num=token.reference_num
+ )
+
def render_heading(self, token):
if token.level == 1:
heading_last, self.heading_last = self.heading_last, True
@@ -69,10 +87,17 @@ class LaTeXRenderer(mistletoe.latex_renderer.LaTeXRenderer):
)
def render_numbered_heading(self, token):
+ sha = hashlib.sha256()
+ sha.update(token.full_label().encode('utf-8'))
+ hyperlink = format(r'\hypertarget{}{}',
+ linkname=sha.hexdigest()
+ )
+
if token.level == 1:
# Part
heading_last, self.heading_last = self.heading_last, True
- return format(r'{\par\vspace{1cm plus 0.3cm minus 0.3cm}\bfseries\fontsize{13pt}{15pt}\selectfont\centering\uppercase{Part