Source

TracMathJaxPlugin / tracmathjax / tracmathjax.py

Full commit
from trac.core import Component, implements
from trac.web.api import IRequestFilter
from trac.web.chrome import ITemplateProvider, add_script
from trac.wiki.api import IWikiSyntaxProvider, IWikiMacroProvider
        
MACRO_DESCRIPTION = \
"""Renders a LaTeX using MathJax.

Usage:
{{{
{{{
#!latex
\left( \sum_{k=1}^n a_k b_k \\right)^{\!\!2} \leq
\left( \sum_{k=1}^n a_k^2 \\right) \left( \sum_{k=1}^n b_k^2 \\right)
}}}
}}}

results in output like:
{{{
#!latex
\left( \sum_{k=1}^n a_k b_k \\right)^{\!\!2} \leq
\left( \sum_{k=1}^n a_k^2 \\right) \left( \sum_{k=1}^n b_k^2 \\right)
}}}
"""

class TracMathJax(Component):
    implements(ITemplateProvider, 
               IRequestFilter, 
               IWikiSyntaxProvider,
               IWikiMacroProvider)

    # ITemplateProvider methods
    def get_htdocs_dirs(self):
        mathjax_path = self.config.get('tracmathjax', 'mathjax_path')
        self.log.debug("MathJax path: %s" % mathjax_path)
        return [("MathJax", mathjax_path)]

    def get_templates_dirs(self):
        # we have no templates
        return []

    # IRequestFilter methods
    def pre_process_request(self, req, handler):
        return handler

    def post_process_request(self, req, template, data, content_type):
        add_script(req, "/chrome/MathJax/MathJax.js")
        return template, data, content_type

    # IWikiSyntaxProvider methods
    def get_wiki_syntax(self):
        # Capture text in between MathJax delimiters to keep other wiki syntax
        # from being applied.
        yield (r"(?P<mathjax_inline>\\(.*\\)|\$\$.*\$\$)", self._render_inline)

    def get_link_resolvers(self):
        # we have no link resolvers
        return []

    # IWikiMacroProvider methods
    def get_macros(self):
        return ('latex', 'Latex', 'LaTeX')

    def get_macro_description(self, name):
        return MACRO_DESCRIPTION

    def expand_macro(self, formatter, name, content):
        if name.lower() == "latex":
            return "<p>\\[\n%s\n\\]</p>" % content

    def _render_inline(self, formatter, ns, match):
        """Inline rendering function."""
        return match.group("mathjax_inline")