From 2fa7610d0c4afd60ce19aed20e7963967569ba89 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 1 Nov 2017 13:34:32 +0100 Subject: [PATCH] m.math: unique names for SVG paths and pages. Makes the markup valid HTML5 and avoids strange issues with missing / wrong paths due to conflicting IDs. --- pelican-plugins/m/math.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/pelican-plugins/m/math.py b/pelican-plugins/m/math.py index 9ccae45a..8ece82ee 100644 --- a/pelican-plugins/m/math.py +++ b/pelican-plugins/m/math.py @@ -29,6 +29,8 @@ from docutils.parsers import rst 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() @@ -45,18 +47,28 @@ latex2svg_params.update({ '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'\?> .+) xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> """) -uncrap_dst = r"""> +patch_dst = r"""> LaTeX Math {formula} """ +unique_src = re.compile(r"""(?P id|xlink:href)='(?P#?)(?Pg\d+-\d+|page\d+)'""") +unique_dst = r"""\g='\geq{counter}-\g'""" + +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} @@ -72,17 +84,21 @@ class Math(rst.Directive): 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('`') @@ -95,18 +111,17 @@ def math(role, rawtext, text, lineno, inliner, options={}, content=[]): 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) -- 2.30.2