Skip to content

Commit

Permalink
Merge pull request #1075 from sphinx-contrib/introduce-raw-mathjax-su…
Browse files Browse the repository at this point in the history
…pport

Introduce raw mathjax support
  • Loading branch information
jdknight authored Jan 30, 2025
2 parents 16b2b97 + 340d6ea commit 3c5a8a8
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 8 deletions.
40 changes: 39 additions & 1 deletion doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,7 @@ Advanced processing configuration

See also:

- :lref:`confluence_mathjax`
- :ref:`LaTeX directives <latex-directives>`
- :ref:`LaTeX roles <latex-roles>`
- :doc:`guide-math`
Expand All @@ -2022,6 +2023,42 @@ Advanced processing configuration
confluence_link_suffix = '.conf'
.. _confluence_mathjax:

.. confval:: confluence_mathjax

.. important::

This option relies on additional configuration of a Confluence
instance or additional directives such as using an HTML macro.
Both of these approaches may not be available in a default
Confluence configuration. Confluence Cloud may require a custom
marketplace add-on. Confluence Data Center can require a system
administrator configuring site support for MathJax; or environments
that have a Confluence HTML macro enabled, users can attempt to
include MathJax library support via the use of a
:lref:`confluence_html` directive.

While this extension aims to support the capability of generating
raw content that MathJax could render, the complete solution of
using MathJax on a Confluence instance is considered unsupported.

Generate math content into a raw format that can be rendered on a
Confluence instance that has been configured to support `MathJax`_.

.. code-block:: python
confluence_mathjax = True
See also:

- :lref:`confluence_latex_macro`
- :ref:`LaTeX directives <latex-directives>`
- :ref:`LaTeX roles <latex-roles>`
- :doc:`guide-math`

.. versionadded:: 2.10

.. index:: Mentions; Configuration

.. _confluence_mentions:
Expand Down Expand Up @@ -2153,7 +2190,7 @@ Third-party related options
.. warning::

This option relies on an HTML macro which is not available in a
default Confluence configuration. Using this option is only useful
default Confluence configuration. Using this option is only useful
for users that have instances where a system administrator has
enabled their use.

Expand Down Expand Up @@ -2290,6 +2327,7 @@ Deprecated options
.. _Confluence editor: https://support.atlassian.com/confluence-cloud/docs/confluence-cloud-editor-roadmap/
.. _Confluence-supported syntax highlight languages: https://confluence.atlassian.com/confcloud/code-block-macro-724765175.html
.. _Key of the space: https://support.atlassian.com/confluence-cloud/docs/choose-a-space-key/
.. _MathJax: https://www.mathjax.org/
.. _Pygments documented language types: http://pygments.org/docs/lexers/
.. _Requests -- Authentication: https://requests.readthedocs.io/en/stable/user/authentication/
.. _Requests SSL Cert Verification: https://requests.readthedocs.io/en/stable/user/advanced/#ssl-cert-verification
Expand Down
44 changes: 44 additions & 0 deletions doc/guide-math.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Math support
============

.. versionchanged:: 2.10 Limited support for generating MathJax-raw content.
.. versionchanged:: 1.8 Support for using Confluence-supported LaTeX macros.
.. versionchanged:: 1.7 SVG-generated math images requires the
``sphinx.ext.imgmath`` extension to be explicitly
Expand Down Expand Up @@ -192,7 +193,50 @@ determine the name of the macro by:
...
</ac:structured-macro>
.. index:: Math; MathJax

MathJax integration
-------------------

.. important::

While this extension aims to support the capability of generating raw
content that MathJax could render, the complete solution of using
MathJax on a Confluence instance is considered unsupported.

Stock Confluence instances do not include support to render `MathJax`_
content. However, if the instance has been configured to support the
JavaScript engine, the Confluence builder extension can be configured to
generate output that is compatible with MathJax.

Users can use the :lref:`confluence_mathjax` option to output all math
content into a MathJax-compatible format:

.. code-block:: python
confluence_mathjax = True
There are no system administrator guidelines on how to setup a Confluence
instance to provide MathJax support.

Users on a Confluence Data Center instance that has enabled support for
HTML macros may be able to use the :lref:`confluence_html` directive to
enable MathJax support on their pages. For example, adding the following
into a project's ``conf.py``:

.. code-block:: rst
rst_prolog = """
.. confluence_html::
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
"""
User experience may vary.

.. references ------------------------------------------------------------------
.. _MathJax: https://www.mathjax.org/
.. _sphinx.ext.imgmath: https://www.sphinx-doc.org/en/master/usage/extensions/math.html#module-sphinx.ext.imgmath
2 changes: 2 additions & 0 deletions sphinxcontrib/confluencebuilder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ def setup(app):
cm.add_conf('confluence_latex_macro', 'confluence')
# Link suffix for generated files.
cm.add_conf('confluence_link_suffix', 'confluence')
# Enable raw math output for MathJax support
cm.add_conf_bool('confluence_mathjax', 'confluence')
# Mappings for documentation mentions to Confluence keys.
cm.add_conf('confluence_mentions', 'confluence')
# Inject navigational hints into the documentation.
Expand Down
18 changes: 18 additions & 0 deletions sphinxcontrib/confluencebuilder/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,24 @@ class confluence_link_card_inline(nodes.Inline, ConfluenceParams):
"""


class confluence_mathjax_block(nodes.TextElement):
"""
confluence mathjax block node
A Confluence builder defined MathJax block node, used to help manage MathJax
content designed for a block/section.
"""


class confluence_mathjax_inline(nodes.Inline, nodes.TextElement):
"""
confluence mathjax inline node
A Confluence builder defined MathJax inline node, used to help manage MathJax
content designed for an inlined section of a paragraph.
"""


class confluence_mention_inline(nodes.Inline, nodes.TextElement):
"""
confluence mention inline node
Expand Down
41 changes: 41 additions & 0 deletions sphinxcontrib/confluencebuilder/storage/translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2801,6 +2801,47 @@ def visit_confluence_latex_inline(self, node):
param = config.get('inline-macro-param')
self._visit_confluence_latex(node, macro, param=param)

# ---------------------------------------------
# confluence-builder -- enhancements -- mathjax
# ---------------------------------------------

def visit_confluence_mathjax_block(self, node):
# if this block is numbered, attempt to align in on the following block
if node.get('from_math') and node.get('number'):
if self.builder.config.math_numfig and self.builder.config.numfig:
figtype = 'displaymath'
if self.builder.name == 'singleconfluence':
key = f'{self._docnames[-1]}/{figtype}'
else:
key = figtype

id_ = node['ids'][0]
number = self.builder.fignumbers.get(key, {}).get(id_, ())
number = '.'.join(map(str, number))
else:
number = node['number']

self.body.append(self.start_tag(node, 'div',
**{'style': 'float: right'}))
self.body.append(f'({number})')
self.body.append(self.end_tag(node))

attribs = {}
alignment = self._fetch_alignment(node)
if alignment and alignment != 'left':
attribs['style'] = f'text-align: {alignment};'

self.body.append(self.start_tag(node, 'div', **attribs))
self.body.append(self.encode(node.rawsource))
self.body.append(self.end_tag(node, suffix=''))
raise nodes.SkipNode

def visit_confluence_mathjax_inline(self, node):
self.body.append(self.start_tag(node, 'span'))
self.body.append(self.encode(node.rawsource))
self.body.append(self.end_tag(node, suffix=''))
raise nodes.SkipNode

# ----------------------------------------------
# confluence-builder -- enhancements -- mentions
# ----------------------------------------------
Expand Down
49 changes: 42 additions & 7 deletions sphinxcontrib/confluencebuilder/transmute/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from sphinxcontrib.confluencebuilder.logger import ConfluenceLogger
from sphinxcontrib.confluencebuilder.nodes import confluence_latex_block
from sphinxcontrib.confluencebuilder.nodes import confluence_latex_inline
from sphinxcontrib.confluencebuilder.nodes import confluence_mathjax_block
from sphinxcontrib.confluencebuilder.nodes import confluence_mathjax_inline
from sphinxcontrib.confluencebuilder.svg import confluence_supported_svg
from sphinxcontrib.confluencebuilder.svg import svg_initialize
from sphinxcontrib.confluencebuilder.transmute.ext_jupyter_sphinx import replace_jupyter_sphinx_nodes
Expand Down Expand Up @@ -65,7 +67,7 @@ def doctree_transmute(builder, doctree):
# replace graphviz nodes with images
replace_graphviz_nodes(builder, doctree)

# replace math blocks with Confluence LaTeX blocks
# replace math blocks with Confluence LaTeX blocks or raw MathJax content
replace_math_blocks(builder, doctree)

# --------------------------
Expand Down Expand Up @@ -109,6 +111,11 @@ def prepare_math_images(builder, doctree):
doctree: the doctree to replace blocks on
"""

# allow users to disabled implemented extension changes
restricted = builder.config.confluence_adv_restricted
if 'ext-imgmath' in restricted:
return

# disable automatic conversion of latex blocks to images if a latex
# macro is configured
if builder.config.confluence_latex_macro:
Expand Down Expand Up @@ -296,7 +303,7 @@ def __init__(self, builder):

def replace_math_blocks(builder, doctree):
"""
replace math blocks with images
replace math blocks with Confluence LaTeX blocks
Math blocks are pre-processed and replaced with Confluence LaTeX blocks.
This is to help prepare nodes that can later be used for user-configured
Expand All @@ -310,26 +317,54 @@ def replace_math_blocks(builder, doctree):

# allow users to disabled implemented extension changes
restricted = builder.config.confluence_adv_restricted
if 'ext-imgmath' in restricted:
if 'ext-math_blocks' in restricted:
return

# check if raw mathjax output is desired
#
# Note that this will only work in Confluence environments that included
# support for rendering MathJax. This extension will only provide raw
# page content that a page can use. Confluence Cloud may only support
# adding MathJax scripts via a Marketplace addon. Cloud Data Center can
# support loading a MathJax script, but can require HTML support or
# registered some other means by a system administrator. This plugin
# will not attempt to handle any of this; it will be up to the end user
# to utilize this for their instance.
mathjax_mode = builder.config.confluence_mathjax

# convert math blocks into Confluence LaTeX blocks
for node in itertools.chain(findall(doctree, nodes.math),
findall(doctree, nodes.math_block)):
if not isinstance(node, nodes.math):

inlined_math = isinstance(node, nodes.math)

if not inlined_math:
if node['nowrap']:
latex = node.astext()
else:
latex = wrap_displaymath(node.astext(), None, numbering=False)
new_node_type = confluence_latex_block

if mathjax_mode:
new_node_type = confluence_mathjax_block
else:
new_node_type = confluence_latex_block
else:
latex = node.astext()

if mathjax_mode:
new_node_type = confluence_mathjax_inline
else:
new_node_type = confluence_latex_inline

if mathjax_mode:
latex = '\\(' + node.astext() + '\\)'
elif inlined_math:
latex = '$' + node.astext() + '$'
new_node_type = confluence_latex_inline

new_node = new_node_type(latex, latex, **node.attributes)
new_node['from_math'] = True

if not isinstance(node, nodes.math):
if not inlined_math:
new_node['align'] = 'center'

node.replace_self(new_node)

0 comments on commit 3c5a8a8

Please sign in to comment.