from docutils.parsers.rst import directives
from docutils.parsers.rst.roles import set_classes
+import pelican.signals
+
from . import latex2svg
latex2svg_params = latex2svg.default_params.copy()
'dvisvgm_cmd': 'dvisvgm --no-fonts -Z 1.25',
})
-uncrap_src = re.compile(r"""<\?xml version='1.0' encoding='UTF-8'\?>
+patch_src = re.compile(r"""<\?xml version='1.0' encoding='UTF-8'\?>
<!-- This file was generated by dvisvgm \d+\.\d+\.\d+ -->
<svg (?P<attribs>.+) xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
""")
-uncrap_dst = r"""<svg{attribs} \g<attribs>>
+patch_dst = r"""<svg{attribs} \g<attribs>>
<title>LaTeX Math</title>
<description>
{formula}
</description>
"""
+unique_src = re.compile(r"""(?P<name> id|xlink:href)='(?P<ref>#?)(?P<id>g\d+-\d+|page\d+)'""")
+unique_dst = r"""\g<name>='\g<ref>eq{counter}-\g<id>'"""
+
+counter = 0
+
+def _patch(formula, out, attribs):
+ global counter
+ counter += 1
+ return unique_src.sub(unique_dst.format(counter=counter), patch_src.sub(patch_dst.format(attribs=attribs, formula=formula.replace('\\', '\\\\')), out['svg']))
+
class Math(rst.Directive):
option_spec = {'class': directives.class_option,
'name': directives.unchanged}
if not block:
continue
+ out = latex2svg.latex2svg("$$" + block + "$$", params=latex2svg_params)
+
container = nodes.container(**self.options)
container['classes'] += ['m-math']
- node = nodes.raw(self.block_text, uncrap_src.sub(
- uncrap_dst.format(attribs='', formula=block.replace('\\', '\\\\')),
- latex2svg.latex2svg("$$" + block + "$$", params=latex2svg_params)['svg']), format='html')
+ node = nodes.raw(self.block_text, _patch(block, out, ''), format='html')
node.line = self.content_offset + 1
self.add_name(node)
container.append(node)
_nodes.append(container)
return _nodes
+def new_page(content):
+ global counter
+ counter = 0
+
def math(role, rawtext, text, lineno, inliner, options={}, content=[]):
# Otherwise the backslashes do quite a mess there
i = rawtext.find('`')
classes += ' ' + ' '.join(options['classes'])
del options['classes']
- out = latex2svg.latex2svg("$" + text + "$", params=latex2svg_params);
+ out = latex2svg.latex2svg("$" + text + "$", params=latex2svg_params)
# CSS classes and styling for proper vertical alignment. Depth is relative
# to font size, describes how below the line the text is. Scaling it back
# to 12pt font, scaled by 125% as set above in the config.
attribs = ' class="{}" style="vertical-align: -{:.1f}pt;"'.format(classes, out['depth']*12*1.25)
- node = nodes.raw(rawtext, uncrap_src.sub(
- uncrap_dst.format(attribs=attribs, formula=text.replace('\\', '\\\\')),
- out['svg']), format='html', **options)
+ node = nodes.raw(rawtext, _patch(text, out, attribs), format='html', **options)
return [node], []
def register():
+ pelican.signals.content_object_init.connect(new_page)
rst.directives.register_directive('math', Math)
rst.roles.register_canonical_role('math', math)