|
From: <mi...@us...> - 2021-07-12 21:22:28
|
Revision: 8794
http://sourceforge.net/p/docutils/code/8794
Author: milde
Date: 2021-07-12 21:22:20 +0000 (Mon, 12 Jul 2021)
Log Message:
-----------
math2html: support small symbols, refactor math accent handling.
math accents/combining characters:
- insert combining character after first character of argument
(mimic LaTeX behaviour).
- support non alphabetical base-character (\not{\in} and similar).
- use precomposed characters if possible (normalization)
Cleanup: update comments, remove not required code.
Modified Paths:
--------------
trunk/docutils/docs/ref/rst/mathematics.txt
trunk/docutils/docutils/utils/math/math2html.py
trunk/docutils/docutils/writers/html5_polyglot/math.css
trunk/docutils/test/functional/expected/math_output_html.html
Property Changed:
----------------
trunk/docutils/docutils/utils/math/math2html.py
Modified: trunk/docutils/docs/ref/rst/mathematics.txt
===================================================================
--- trunk/docutils/docs/ref/rst/mathematics.txt 2021-07-12 21:22:04 UTC (rev 8793)
+++ trunk/docutils/docs/ref/rst/mathematics.txt 2021-07-12 21:22:20 UTC (rev 8794)
@@ -989,7 +989,6 @@
\left.\vert \frac{b}{a}\right\Vert\ \bigl\vert b\Bigr\Vert\ \biggl\vert b\Biggr\Vert
\quad
-
Variable-sized operators:
Inline: `\sum\ \int\ \oint\ \smallint\ \prod\ \coprod\ \bigwedge\
Modified: trunk/docutils/docutils/utils/math/math2html.py
===================================================================
--- trunk/docutils/docutils/utils/math/math2html.py 2021-07-12 21:22:04 UTC (rev 8793)
+++ trunk/docutils/docutils/utils/math/math2html.py 2021-07-12 21:22:20 UTC (rev 8794)
@@ -24,6 +24,7 @@
import os.path
import sys
+import unicodedata
if sys.version_info >= (3, 0):
from urllib.parse import quote_plus
@@ -94,18 +95,21 @@
extracttext = {
u'allowed': [u'FormulaConstant',],
u'extracted': [
+ u'AlphaCommand',
+ u'Bracket',
+ u'BracketCommand',
+ u'CombiningFunction',
+ u'DecoratingFunction',
+ u'EmptyCommand',
+ u'FontFunction',
u'Formula',
- u'Bracket',
- u'RawText',
u'FormulaNumber',
- u'AlphaCommand',
- u'EmptyCommand',
+ u'FormulaSymbol',
u'OneParamFunction',
- u'SymbolFunction', u'TextFunction',
- u'FontFunction', u'CombiningFunction',
- u'DecoratingFunction',
- u'FormulaSymbol',
- u'BracketCommand',
+ u'RawText',
+ u'SpacedCommand',
+ u'SymbolFunction',
+ u'TextFunction',
],
}
@@ -231,6 +235,13 @@
'\\qquad': u' ',
'\\rVert': u'∥',
'\\rvert': u'∣',
+ '\\shortmid': u'<span class="smallsymbol">∣</span>',
+ '\\shortparallel': u'<span class="smallsymbol">∥</span>',
+ '\\nshortmid': u'<span class="smallsymbol">∤</span>',
+ '\\nshortparallel': u'<span class="smallsymbol">∦</span>',
+ '\\smallfrown': u'<span class="smallsymbol">⌢</span>',
+ '\\smallsmile': u'<span class="smallsymbol">⌣</span>',
+ '\\smallint': u'<span class="smallsymbol">∫</span>',
'\\textasciicircum': u'^',
'\\textasciitilde': u'~',
'\\textbackslash': u'\\',
@@ -471,12 +482,6 @@
# relations (put additional space before and after the symbol)
spacedcommands = {
- # precomposed characters for negated symbols
- '\\not=': u'≠',
- '\\not<': u'≮',
- '\\not>': u'≯',
- # '\\not\\in': u'∉',
- # '\\not\\equiv': u'≢', # TODO why doesn't this work?
# negated symbols without pre-composed Unicode character
'\\nleqq': u'\u2266\u0338', # ≦̸
'\\ngeqq': u'\u2267\u0338', # ≧̸
@@ -665,15 +670,18 @@
create = classmethod(create)
class ContainerExtractor(object):
- "A class to extract certain containers."
+ """A class to extract certain containers.
+ The config parameter is a map containing three lists:
+ allowed, copied and extracted.
+ Each of the three is a list of class names for containers.
+ Allowed containers are included as is into the result.
+ Cloned containers are cloned and placed into the result.
+ Extracted containers are looked into.
+ All other containers are silently ignored.
+ """
+
def __init__(self, config):
- "The config parameter is a map containing three lists: allowed, copied and extracted."
- "Each of the three is a list of class names for containers."
- "Allowed containers are included as is into the result."
- "Cloned containers are cloned and placed into the result."
- "Extracted containers are looked into."
- "All other containers are silently ignored."
self.allowed = config['allowed']
self.extracted = config['extracted']
@@ -718,10 +726,6 @@
def parseparameter(self, reader):
"Parse a parameter"
- if reader.currentline().strip().startswith('<'):
- key, value = self.parsexml(reader)
- self.parameters[key] = value
- return
split = reader.currentline().strip().split(' ', 1)
reader.nextline()
if len(split) == 0:
@@ -736,31 +740,6 @@
doublesplit = split[1].split('"')
self.parameters[key] = doublesplit[1]
- def parsexml(self, reader):
- "Parse a parameter in xml form: <param attr1=value...>"
- strip = reader.currentline().strip()
- reader.nextline()
- if not strip.endswith('>'):
- Trace.error('XML parameter ' + strip + ' should be <...>')
- split = strip[1:-1].split()
- if len(split) == 0:
- Trace.error('Empty XML parameter <>')
- return None, None
- key = split[0]
- del split[0]
- if len(split) == 0:
- return key, dict()
- attrs = dict()
- for attr in split:
- if not '=' in attr:
- Trace.error('Erroneous attribute for ' + key + ': ' + attr)
- attr += '="0"'
- parts = attr.split('=')
- attrkey = parts[0]
- value = parts[1].split('"')[1]
- attrs[attrkey] = value
- return key, attrs
-
def parseending(self, reader, process):
"Parse until the current ending is found"
if not self.ending:
@@ -868,18 +847,8 @@
reader.nextline()
return contents
-class InsetParser(BoundedParser):
- "Parses a LyX inset"
- def parse(self, reader):
- "Parse inset parameters into a dictionary"
- startcommand = ContainerConfig.string['startcommand']
- while reader.currentline() != '' and not reader.currentline().startswith(startcommand):
- self.parseparameter(reader)
- return BoundedParser.parse(self, reader)
-
-
class ContainerOutput(object):
"The generic HTML output for a container."
@@ -1409,9 +1378,7 @@
"Extract all text from allowed containers."
result = ''
constants = ContainerExtractor(ContainerConfig.extracttext).extract(self)
- for constant in constants:
- result += constant.string
- return result
+ return ''.join(constant.string for constant in constants)
def group(self, index, group, isingroup):
"Group some adjoining elements into a group"
@@ -2315,7 +2282,8 @@
def parsebit(self, pos):
"Place as contents the command translated and spaced."
- self.contents = [FormulaConstant(u' ' + self.translated + u' ')]
+ # pad with MEDIUM MATHEMATICAL SPACE
+ self.contents = [FormulaConstant(u'\u205f' + self.translated + u'\u205f')]
class AlphaCommand(EmptyCommand):
"""A command without paramters whose result is alphabetical."""
@@ -2701,7 +2669,6 @@
FormulaCommand.types += [BeginCommand]
-
class CombiningFunction(OneParamFunction):
commandmap = FormulaConfig.combiningfunctions
@@ -2708,27 +2675,37 @@
def parsebit(self, pos):
"Parse a combining function."
- self.type = 'alpha'
combining = self.translated
parameter = self.parsesingleparameter(pos)
if not parameter:
- Trace.error('Empty parameter for combining function ' + self.command)
- elif len(parameter.extracttext()) != 1:
- Trace.error('Applying combining function ' + self.command + ' to invalid string "' + parameter.extracttext() + '"')
- self.contents.append(Constant(combining))
+ Trace.error('Missing parameter for combining function ' + self.command)
+ return
+ # Trace.message('apply %s to %r'%(self.command, parameter.extracttext()))
+ # parameter.tree()
+ if not isinstance(parameter, FormulaConstant):
+ try:
+ extractor = ContainerExtractor(ContainerConfig.extracttext)
+ parameter = extractor.extract(parameter)[0]
+ except IndexError:
+ Trace.error('No base character found for "%s".' % self.command)
+ return
+ # Trace.message(' basechar: %r' % parameter.string)
+ # Insert combining character after the first character:
+ if parameter.string.startswith(u'\u205f'):
+ i = 2 # skip padding by SpacedCommand
+ else:
+ i = 1
+ parameter.string = parameter.string[:i] + combining + parameter.string[i:]
+ # Use pre-composed characters if possible: \not{=} -> ≠, say.
+ # TODO: use overset for mathematical accents.
+ parameter.string = unicodedata.normalize('NFC', parameter.string)
def parsesingleparameter(self, pos):
"Parse a parameter, or a single letter."
self.factory.clearskipped(pos)
if pos.finished():
- Trace.error('Error while parsing single parameter at ' + pos.identifier())
return None
- if self.factory.detecttype(Bracket, pos) \
- or self.factory.detecttype(FormulaCommand, pos):
- return self.parseparameter(pos)
- letter = FormulaConstant(pos.skipcurrent())
- self.add(letter)
- return letter
+ return self.parseparameter(pos)
class DecoratingFunction(OneParamFunction):
"A function that decorates some bit of text"
Property changes on: trunk/docutils/docutils/utils/math/math2html.py
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/docutils/docutils/writers/html5_polyglot/math.css
===================================================================
--- trunk/docutils/docutils/writers/html5_polyglot/math.css 2021-07-12 21:22:04 UTC (rev 8793)
+++ trunk/docutils/docutils/writers/html5_polyglot/math.css 2021-07-12 21:22:20 UTC (rev 8794)
@@ -105,6 +105,9 @@
sub.denominator, sub.unit {
vertical-align: -20%;
}
+span.smallsymbol {
+ font-size: 75%;
+}
span.sqrt {
display: inline-block;
vertical-align: middle;
@@ -117,8 +120,8 @@
span.radical {
display: inline-block;
padding: 0ex;
- font-size: 150%;
- line-height: 97%;
+ font-size: 160%;
+ line-height: 100%;
vertical-align: top;
vertical-align: middle;
}
Modified: trunk/docutils/test/functional/expected/math_output_html.html
===================================================================
--- trunk/docutils/test/functional/expected/math_output_html.html 2021-07-12 21:22:04 UTC (rev 8793)
+++ trunk/docutils/test/functional/expected/math_output_html.html 2021-07-12 21:22:20 UTC (rev 8794)
@@ -68,7 +68,7 @@
directives:</p>
<p>The Schrödinger equation</p>
<div class="formula" id="eq-schrodinger">
-<i>i</i><i>ℏ</i><span class="fraction"><span class="ignored">(</span><span class="numerator">∂</span><span class="ignored">)/(</span><span class="denominator">∂<i>t</i></span><span class="ignored">)</span></span>Ψ = <i>Ĥ</i>Ψ,
+<i>i</i><i>ℏ</i><span class="fraction"><span class="ignored">(</span><span class="numerator">∂</span><span class="ignored">)/(</span><span class="denominator">∂<i>t</i></span><span class="ignored">)</span></span>Ψ = <i>Ĥ</i>Ψ,
</div>
<p>with the <em>wave function</em> <span class="formula">Ψ</span>, describes how the quantum state of a
physical system changes in time.</p>
@@ -81,12 +81,12 @@
<col width="33%" />
</colgroup>
<tbody valign="top">
-<tr><td><span class="formula"><i>á</i></span> <tt class="docutils literal">\acute{a}</tt></td>
-<td><span class="formula"><i>ṫ</i></span> <tt class="docutils literal">\dot{t}</tt></td>
+<tr><td><span class="formula"><i>á</i></span> <tt class="docutils literal">\acute{a}</tt></td>
+<td><span class="formula"><i>ṫ</i></span> <tt class="docutils literal">\dot{t}</tt></td>
<td><span class="formula"><i>γ̂</i></span> <tt class="docutils literal"><span class="pre">\hat{\gamma}</span></tt></td>
</tr>
-<tr><td><span class="formula"><i>à</i></span> <tt class="docutils literal">\grave{a}</tt></td>
-<td><span class="formula"><i>ẗ</i></span> <tt class="docutils literal">\ddot{t}</tt></td>
+<tr><td><span class="formula"><i>à</i></span> <tt class="docutils literal">\grave{a}</tt></td>
+<td><span class="formula"><i>ẗ</i></span> <tt class="docutils literal">\ddot{t}</tt></td>
<td><span class="formula"><i>α̃</i></span> <tt class="docutils literal"><span class="pre">\tilde{\alpha}</span></tt></td>
</tr>
<tr><td><span class="formula"><i>x̆</i></span> <tt class="docutils literal">\breve{x}</tt></td>
@@ -93,7 +93,7 @@
<td><span class="formula"><i>t⃛</i></span> <tt class="docutils literal">\dddot{t}</tt></td>
<td><span class="formula"><i>ı⃗</i></span> <tt class="docutils literal"><span class="pre">\vec{\imath}</span></tt></td>
</tr>
-<tr><td><span class="formula"><i>ǎ</i></span> <tt class="docutils literal">\check{a}</tt></td>
+<tr><td><span class="formula"><i>ǎ</i></span> <tt class="docutils literal">\check{a}</tt></td>
<td><span class="formula"><span class="bar"><i>a</i></span></span> <tt class="docutils literal">\bar{a}</tt></td>
<td><span class="formula"><i>R⃗</i></span> <tt class="docutils literal">\vec{R}</tt></td>
</tr>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|