|  | # Version of mathdef.py for bikeshed build. | 
|  | # Tweaked to generate single page links. | 
|  | # TODO(bradnelson): Figure out a way to merge this back into | 
|  | # mathdef.py controlled by buildername. | 
|  |  | 
|  | from sphinx.ext.mathbase import math | 
|  | from sphinx.ext.mathbase import displaymath | 
|  | from sphinx.ext.mathbase import math_role | 
|  | from sphinx.ext.mathbase import MathDirective | 
|  | from sphinx.ext.mathbase import latex_visit_math | 
|  | from sphinx.ext.mathbase import latex_visit_displaymath | 
|  | from sphinx.ext.mathjax import html_visit_math | 
|  | from sphinx.ext.mathjax import html_visit_displaymath | 
|  | from sphinx.util.texescape import tex_escape_map, tex_replace_map | 
|  | from docutils.parsers.rst.directives.misc import Replace | 
|  | from six import text_type | 
|  | import re | 
|  |  | 
|  |  | 
|  | # Transform \xref in math nodes | 
|  |  | 
|  | xref_re = re.compile('\\\\xref\{([^}]*)\}\{([^}]*)\}', re.M) | 
|  |  | 
|  | def html_hyperlink(file, id): | 
|  | return '\\href{#%s}' % (id.replace('_', '-')) | 
|  |  | 
|  | def html_transform_math_xref(node): | 
|  | node['latex'] = \ | 
|  | xref_re.sub(lambda m: html_hyperlink(m.group(1), m.group(2)), node['latex']) | 
|  |  | 
|  | def ext_html_visit_math(self, node): | 
|  | html_transform_math_xref(node) | 
|  | html_visit_math(self, node) | 
|  |  | 
|  | def ext_html_visit_displaymath(self, node): | 
|  | html_transform_math_xref(node) | 
|  | html_visit_displaymath(self, node) | 
|  |  | 
|  | # Mirrors sphinx/writers/latex | 
|  | def latex_hyperlink(file, id): | 
|  | id = text_type(id).translate(tex_replace_map).\ | 
|  | encode('ascii', 'backslashreplace').decode('ascii').\ | 
|  | replace('_', '-').replace('\\', '_') | 
|  | return '\\hyperref[%s:%s]' % (file, id) | 
|  |  | 
|  | def latex_transform_math_xref(node): | 
|  | node['latex'] = \ | 
|  | xref_re.sub(lambda m: latex_hyperlink(m.group(1), m.group(2)), node['latex']) | 
|  |  | 
|  | def ext_latex_visit_math(self, node): | 
|  | latex_transform_math_xref(node) | 
|  | latex_visit_math(self, node) | 
|  |  | 
|  | def ext_latex_visit_displaymath(self, node): | 
|  | latex_transform_math_xref(node) | 
|  | latex_visit_displaymath(self, node) | 
|  |  | 
|  |  | 
|  | # Expand mathdef names in math roles and directives | 
|  |  | 
|  | def_re = re.compile('\\\\[A-Za-z][0-9A-Za-z]*', re.M) | 
|  |  | 
|  | auxcounter = 0 | 
|  |  | 
|  | def lookup_mathdef(defs, name): | 
|  | if name in defs: | 
|  | [arity, s] = defs[name] | 
|  | if arity > 0: | 
|  | global auxcounter | 
|  | auxcounter = auxcounter + 1 | 
|  | name = "\\mathdef%d" % auxcounter | 
|  | s = "\\def%s#%d{%s}%s" % (name, arity, s, name) | 
|  | return s | 
|  | return name | 
|  |  | 
|  | def replace_mathdefs(doc, s): | 
|  | if not hasattr(doc, 'mathdefs'): | 
|  | return s | 
|  | return def_re.sub(lambda m: lookup_mathdef(doc.mathdefs, m.group(0)), s) | 
|  |  | 
|  | def ext_math_role(role, raw, text, line, inliner, options = {}, content = []): | 
|  | text = replace_mathdefs(inliner.document, raw.split('`')[1]) | 
|  | return math_role(role, raw, text, line, inliner, options = options, | 
|  | content = content) | 
|  |  | 
|  | class ExtMathDirective(MathDirective): | 
|  | def run(self): | 
|  | doc = self.state.document | 
|  | for i, s in enumerate(self.content): | 
|  | self.content[i] = replace_mathdefs(doc, s) | 
|  | for i, s in enumerate(self.arguments): | 
|  | self.arguments[i] = replace_mathdefs(doc, s) | 
|  | return super(ExtMathDirective, self).run() | 
|  |  | 
|  | class MathdefDirective(Replace): | 
|  | def run(self): | 
|  | name = '\\' + self.state.parent.rawsource.split('|')[1] | 
|  | name = name.split('#') | 
|  | if len(name) > 1: | 
|  | arity = int(name[1]) | 
|  | else: | 
|  | arity = 0 | 
|  | name = name[0] | 
|  | doc = self.state.document | 
|  | if not hasattr(doc, 'mathdefs'): | 
|  | doc.mathdefs = {} | 
|  | for i, s in enumerate(self.content): | 
|  | self.content[i] = replace_mathdefs(doc, s) | 
|  | doc.mathdefs[name] = [arity, ''.join(self.content)] | 
|  | self.content[0] = ':math:`' + self.content[0] | 
|  | self.content[-1] = self.content[-1] + '`' | 
|  | return super(MathdefDirective, self).run() | 
|  |  | 
|  |  | 
|  | # Setup | 
|  |  | 
|  | def setup(app): | 
|  | app.add_node(math, | 
|  | html = (ext_html_visit_math, None), | 
|  | latex = (ext_latex_visit_math, None)) | 
|  | app.add_node(displaymath, | 
|  | html = (ext_html_visit_displaymath, None), | 
|  | latex = (ext_latex_visit_displaymath, None)) | 
|  | app.add_role('math', ext_math_role) | 
|  | app.add_directive('math', ExtMathDirective) | 
|  | app.add_directive('mathdef', MathdefDirective) |