summaryrefslogtreecommitdiff
path: root/docutils
diff options
context:
space:
mode:
authormilde <milde@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2022-11-04 10:55:05 +0000
committermilde <milde@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2022-11-04 10:55:05 +0000
commitfc989749e8bf3da71ca6862896aee2876268bcb6 (patch)
tree4f1e721f298b0932c96b15643340fad44137ac63 /docutils
parentb474683a76a66a446924814744d24e8bf3516bd1 (diff)
downloaddocutils-fc989749e8bf3da71ca6862896aee2876268bcb6.tar.gz
MathML: support "mod" notation for modulo operation/arithmetic.
TeX to HTML/css support still missing, cf. [feature-requests:#93]. git-svn-id: https://svn.code.sf.net/p/docutils/code/trunk@9213 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
Diffstat (limited to 'docutils')
-rw-r--r--docutils/HISTORY.txt3
-rw-r--r--docutils/docs/ref/rst/mathematics.txt58
-rw-r--r--docutils/docutils/utils/math/latex2mathml.py57
3 files changed, 93 insertions, 25 deletions
diff --git a/docutils/HISTORY.txt b/docutils/HISTORY.txt
index eb859ab17..0d745e85e 100644
--- a/docutils/HISTORY.txt
+++ b/docutils/HISTORY.txt
@@ -52,6 +52,9 @@ Changes Since 0.19
- Fix previous_sibling() method that led to invalid HTML in some cases
(cf. patch #195).
+* docutils/utils/math/latex2mathml.py
+
+ - Support "mod" notation for modulo operation/modulus arithmetic.
* test/coverage.sh
diff --git a/docutils/docs/ref/rst/mathematics.txt b/docutils/docs/ref/rst/mathematics.txt
index d66fd6bf5..6d5086907 100644
--- a/docutils/docs/ref/rst/mathematics.txt
+++ b/docutils/docs/ref/rst/mathematics.txt
@@ -10,7 +10,7 @@ LaTeX syntax for mathematics
:abstract: Docutils supports mathematical content with a `"math"
directive`__ and `role`__. The input format is *LaTeX math
- syntax*\ [#math-syntax]_ with support for Unicode symbols.
+ syntax*\ [#math-syntax]_ with support for literal Unicode symbols.
.. sectnum::
.. contents::
@@ -313,6 +313,7 @@ Letterlike symbols
`\mho` ``\mho`` `\eth` ``\eth`` `\Bbbk` ``\Bbbk``
============= =============== ========== ============ ========== ============ =========== =============
+
Mathematical Alphabets
----------------------
@@ -414,6 +415,7 @@ Punctuation
.. [#] Punctuation (not ratio):
Compare spacing in `a\colon b\to c` to `a:b = c`.
+
Relation symbols
----------------
@@ -534,6 +536,7 @@ The commands ``\varsubsetneq``, ``\varsubsetneqq``, ``\varsupsetneq``,
and ``\varsupsetneqq`` are not supported by LateX2MathML, as there is no
corresponding Unicode character.
+
Variable-sized operators
------------------------
.. class:: colwidths-auto
@@ -552,6 +555,7 @@ indices above/below the symbol (see also `scripts and limits`_):
\int_0^1f(x)\,dx \qquad
\prod_{i=1}^{10} b_i \ldots
+
Notations
=========
@@ -560,6 +564,7 @@ Top and bottom embellishments
See `Accents and embellishments`_.
+
Extensible arrows
-----------------
@@ -574,6 +579,7 @@ results in
.. math:: A \xleftarrow{n+\mu-1} B \xrightarrow[T]{n\pm i-1} C
+
Affixing symbols to other symbols
---------------------------------
@@ -620,6 +626,7 @@ For piecewise function definitions there is a ``cases`` environment:
\phantom{-}1 & x>0
\end{cases}
+
Spacing commands
----------------
@@ -659,6 +666,31 @@ The commands ``\hphantom`` and ``\vphantom`` insert space with the
width or height of the argument. They are not supported with `math_output`_
MathML.
+
+Modular arithmetic and modulo operation
+---------------------------------------
+
+The commands ``\bmod``, ``\pmod``, ``\mod``, and ``\pod`` deal with the
+special spacing conventions of the “mod” notation. [#]_
+
+.. class:: colwidths-auto
+
+ ========= =========================== =========================
+ command example result
+ ========= =========================== =========================
+ ``\bmod`` ``\gcd(n,m \bmod n)`` `\gcd(n,m \bmod n)`
+ ``\pmod`` ``x\equiv y \pmod b`` `x\equiv y \pmod b`
+ ``\mod`` ``x\equiv y \mod c`` `x\equiv y \mod c`
+ ``\pod`` ``x\equiv y \pod d`` `x\equiv y \pod d`
+ .. ``\operatorname{mod}(m,n)`` `\operatorname{mod}(m,n)`
+ ========= =========================== =========================
+
+.. [#] Currently `not supported`__ by the "HTML" math_output_ option
+ of the HTML writer.
+
+__ https://sourceforge.net/p/docutils/feature-requests/93/
+
+
Roots
-----
@@ -672,6 +704,7 @@ Roots
.. ``\sqrt\frac{1}{2}`` `\sqrt\frac{1}{2}`
========= ==================== ==================
+
Boxed formulas
--------------
@@ -680,7 +713,6 @@ The command ``\boxed`` puts a box around its argument:
.. math:: \boxed{\eta \leq C(\delta(\eta) +\Lambda_M(0,\delta))}
-
Fractions and related constructions
===================================
@@ -782,6 +814,7 @@ than the base size but still able to fit within the normal line spacing:
`\left(\begin{smallmatrix} a & b \\ c & d \end{smallmatrix}\right)`
vs. `\Bigl(\begin{smallmatrix} a & b \\ c & d \end{smallmatrix}\Bigr)`.
+
Text
====
@@ -803,24 +836,6 @@ The text may contain math commands wrapped in ``$`` signs, e.g.
.. TODO ignore {}, handle text-mode commands
- 
-``\mod`` and its relatives
---------------------------
-
-Commands ``\mod``, ``\bmod``, ``\pmod``, ``\pod`` deal with the special
-spacing conventions of “mod” notation.
-``\mod`` and ``\pod`` are variants of ``\pmod`` preferred by some
-authors; ``\mod`` omits the parentheses, whereas ``\pod`` omits the
-“mod” and retains the parentheses.
-
-TODO:
- Currently not supported by the "HTML" and "MathML" math_output_
- options of the HTML writer (cf. `feature-request #93
- <https://sourceforge.net/p/docutils/feature-requests/93/>`__).
-
-.. \gcd(n,m\bmod n) ;\quad x\equiv y\pmod b
- ;\quad x\equiv y\mod c ;\quad x\equiv y\pod d
-
Integrals and sums
==================
@@ -834,6 +849,7 @@ similar symbols like
move to index positions: `\lim_{n\to\infty} \sum_1^n \frac{1}{n}`.
+
Altering the placement of limits
--------------------------------
@@ -903,7 +919,6 @@ Appendix
Tests
-----
-
Font changes
~~~~~~~~~~~~
@@ -959,6 +974,7 @@ tex-token returns "{" for nested groups:
.. math:: \text{das ist ein {toller} text (unescaped \{ and \} is
ignored by LaTeX)}
+
Big delimiters and symbols
~~~~~~~~~~~~~~~~~~~~~~~~~~
Compare automatic sizing with fixed sizes:
diff --git a/docutils/docutils/utils/math/latex2mathml.py b/docutils/docutils/utils/math/latex2mathml.py
index 277663fc2..ade0e8e47 100644
--- a/docutils/docutils/utils/math/latex2mathml.py
+++ b/docutils/docutils/utils/math/latex2mathml.py
@@ -73,6 +73,15 @@ functions.update((name, name) for name in
# Function with limits: 'lim', 'sup', 'inf', 'max', 'min':
# use <mo> to allow "movablelimits" attribute (see below).
+# modulo operator/arithmetic
+modulo_functions = {
+ # cmdname: (binary, named, parentheses, padding)
+ 'bmod': (True, True, False, '0.278em'), # a mod n
+ 'pmod': (False, True, True, '0.444em'), # a (mod n)
+ 'mod': (False, True, False, '0.667em'), # a mod n
+ 'pod': (False, False, True, '0.444em'), # a (n)
+ }
+
# math font selection -> <mi mathvariant=...> or <mstyle mathvariant=...>
math_alphabets = {
@@ -433,6 +442,16 @@ class math:
xml.extend(['\n', ' ' * level])
return xml
+ def is_block(self):
+ """Return true, if `self` or a parent has ``display='block'``."""
+ try:
+ return self['display'] == 'block'
+ except KeyError:
+ try:
+ return self.parent.is_block()
+ except AttributeError:
+ return False
+
# >>> n2 = math(mn(2))
# >>> n2
# math(mn(2))
@@ -442,13 +461,23 @@ class math:
# 1
# >>> eq3 = math(id='eq3', display='block')
# >>> eq3
-# math(display='block', id='eq3')
+# math(id='eq3', display='block')
# >>> eq3.toprettyxml()
-# '<math display="block" id="eq3">\n</math>'
+# '<math id="eq3" display="block">\n</math>'
# >>> len(eq3)
# 0
# >>> math(CLASS='bold').xml_starttag()
# '<math class="bold">'
+# >>> n2.is_block()
+# False
+# >>> node = n2.append(mrow())
+# >>> node.is_block()
+# False
+# >>> eq3.is_block()
+# True
+# >>> node = eq3.append(mrow())
+# >>> node.is_block()
+# True
class mtable(math): pass
@@ -945,6 +974,26 @@ def handle_cmd(name, node, string): # noqa: C901 TODO make this less complex
node = node.append(mo('\u2061')) # &ApplyFunction;
return node, string
+ if name in modulo_functions:
+ (binary, named, parentheses, padding) = modulo_functions[name]
+ if binary:
+ node = node.append(mo('mod', lspace=padding, rspace=padding))
+ return node, string
+ # left padding
+ if node.is_block():
+ padding = '1em'
+ node = node.append(mspace(width=padding))
+ if parentheses:
+ node = node.append(mo('(', stretchy=False))
+ if named:
+ node = node.append(mi('mod'))
+ node = node.append(mspace(width='0.333em'))
+ arg, string = tex_token_or_group(string)
+ node = parse_latex_math(node, arg)
+ if parentheses:
+ node = node.append(mo(')', stretchy=False))
+ return node, string
+
if name in math_alphabets:
if name == 'boldsymbol':
attributes = {'class': 'boldsymbol'}
@@ -1212,7 +1261,7 @@ def handle_cmd(name, node, string): # noqa: C901 TODO make this less complex
# >>> handle_cmd('mathrm', math(), '{out} = 3')
# (math(mi('out', mathvariant='normal')), ' = 3')
# >>> handle_cmd('overline', math(), '{981}')
-# (mover(mo('¯', accent=True), switch=True, accent=False), '{981}')
+# (mover(mo('_', accent=True), switch=True, accent=False), '{981}')
# >>> handle_cmd('bar', math(), '{x}')
# (mover(mo('ˉ', stretchy=False), switch=True), '{x}')
# >>> handle_cmd('xleftarrow', math(), r'[\alpha]{10}')
@@ -1366,7 +1415,7 @@ def tex2mathml(tex_math, inline=True):
# </math>
# >>> print(tex2mathml(r'a & b \\ c & d', inline=False))
# <math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
-# <mtable class="align" columnalign="right left" columnspacing="0" displaystyle="true">
+# <mtable class="align" displaystyle="true" columnalign="right left" columnspacing="0">
# <mtr>
# <mtd>
# <mi>a</mi>