From 7597719b41037cfa989c6f2c5f0fe76f842b4624 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 6 May 2018 12:31:57 +0200 Subject: [PATCH] doxygen: avoid needless dependency on Pelican and docutils. These were pulled in transitively from m.math and I was not aware of that. Sorry. Now it's just jinja2 and Pygments needed, as documented. --- doxygen/dox2html5.py | 10 ++--- pelican-plugins/latex2svgextra.py | 73 +++++++++++++++++++++++++++++++ pelican-plugins/m/math.py | 45 +++---------------- 3 files changed, 83 insertions(+), 45 deletions(-) create mode 100644 pelican-plugins/latex2svgextra.py diff --git a/doxygen/dox2html5.py b/doxygen/dox2html5.py index 6f3a53bd..602fea4b 100755 --- a/doxygen/dox2html5.py +++ b/doxygen/dox2html5.py @@ -51,7 +51,7 @@ from pygments.lexers import TextLexer, BashSessionLexer, get_lexer_by_name, find sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../pelican-plugins')) import latex2svg -import m.math +import latex2svgextra import ansilexer class Trie: @@ -1147,7 +1147,7 @@ def parse_desc_internal(state: State, element: ET.Element, immediate_parent: ET. # Assume that Doxygen wrapped the formula properly to distinguish # between inline, block or special environment - rendered = latex2svg.latex2svg('{}'.format(i.text), params=m.math.latex2svg_params) + rendered = latex2svg.latex2svg('{}'.format(i.text), params=latex2svgextra.params) # We should have decided about block/inline above assert formula_block is not None @@ -1155,7 +1155,7 @@ def parse_desc_internal(state: State, element: ET.Element, immediate_parent: ET. has_block_elements = True out.parsed += '
{}
'.format( ' ' + add_css_class if add_css_class else '', - m.math._patch(i.text, rendered, '')) + latex2svgextra.patch(i.text, rendered, '')) else: # 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 @@ -1163,7 +1163,7 @@ def parse_desc_internal(state: State, element: ET.Element, immediate_parent: ET. attribs = ' class="m-math{}" style="vertical-align: -{:.1f}pt;"'.format( ' ' + add_inline_css_class if add_inline_css_class else '', (rendered['depth'] or 0.0)*12*1.25) - out.parsed += m.math._patch(i.text, rendered, attribs) + out.parsed += latex2svgextra.patch(i.text, rendered, attribs) # Inline elements elif i.tag == 'linebreak': @@ -1923,7 +1923,7 @@ def base85encode_search_data(data: bytearray) -> bytearray: def parse_xml(state: State, xml: str): # Reset counter for unique math formulas - m.math.counter = 0 + latex2svgextra.counter = 0 state.current = os.path.basename(xml) diff --git a/pelican-plugins/latex2svgextra.py b/pelican-plugins/latex2svgextra.py new file mode 100644 index 00000000..0386d5fe --- /dev/null +++ b/pelican-plugins/latex2svgextra.py @@ -0,0 +1,73 @@ +# +# This file is part of m.css. +# +# Copyright © 2017, 2018 Vladimír Vondruš +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +import re + +import latex2svg + +# Extracted common code used by both dox2html5.py and the m.math plugin to +# avoid dependency of dox2html5.py on Pelican + +# Modified params to use for math rendering +params = latex2svg.default_params.copy() +params.update({ + # Don't use libertine fonts as they mess up things + 'preamble': r""" +\usepackage[utf8x]{inputenc} +\usepackage{amsmath} +\usepackage{amsfonts} +\usepackage{amssymb} +\usepackage{newtxtext} +""", + # Zoom the letters a bit to match page font size + 'dvisvgm_cmd': 'dvisvgm --no-fonts -Z 1.25', + }) + +_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'> +""") + +_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 to ensure unique IDs for multiple SVG elements on the same page. +# Reset back to zero on start of a new page for reproducible behavior. +counter = 0 + +# Patches the output from dvisvgm +# - w/o the XML preamble and needless xmlns attributes +# - unique element IDs (see `counter`) +# - adds additional `attribs` to the element +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'])) diff --git a/pelican-plugins/m/math.py b/pelican-plugins/m/math.py index 5129206e..188d57c1 100644 --- a/pelican-plugins/m/math.py +++ b/pelican-plugins/m/math.py @@ -32,45 +32,10 @@ from docutils.parsers.rst.roles import set_classes import pelican.signals import latex2svg - -latex2svg_params = latex2svg.default_params.copy() -latex2svg_params.update({ - # Don't use libertine fonts as they mess up things - 'preamble': r""" -\usepackage[utf8x]{inputenc} -\usepackage{amsmath} -\usepackage{amsfonts} -\usepackage{amssymb} -\usepackage{newtxtext} -""", - # Zoom the letters a bit to match page font size - 'dvisvgm_cmd': 'dvisvgm --no-fonts -Z 1.25', - }) - -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'> -""") - -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 +import latex2svgextra render_as_code = False -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} @@ -94,11 +59,11 @@ class Math(rst.Directive): if not block: continue - out = latex2svg.latex2svg("$$" + block + "$$", params=latex2svg_params) + out = latex2svg.latex2svg("$$" + block + "$$", params=latex2svgextra.params) container = nodes.container(**self.options) container['classes'] += ['m-math'] - node = nodes.raw(self.block_text, _patch(block, out, ''), format='html') + node = nodes.raw(self.block_text, latex2svgextra.patch(block, out, ''), format='html') node.line = self.content_offset + 1 self.add_name(node) container.append(node) @@ -134,14 +99,14 @@ 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=latex2svgextra.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, _patch(text, out, attribs), format='html', **options) + node = nodes.raw(rawtext, latex2svgextra.patch(text, out, attribs), format='html', **options) return [node], [] def configure_pelican(pelicanobj): -- 2.30.2