Skip to content

Commit 22e2a42

Browse files
committed
Fix some mathtext scaling bugs
Add new mathtext symbols Use mathtext to render math in the docs (the dog-fooding patch!) Move PNG reading/writing to its own module and remove it from _backend_agg and _image svn path=/trunk/matplotlib/; revision=5471
1 parent e024ab7 commit 22e2a42

22 files changed

Lines changed: 422 additions & 458 deletions

CHANGELOG

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2008-06-11 Use matplotlib.mathtext to render math expressions in
2+
online docs - MGD
3+
4+
2008-06-11 Move PNG loading/saving to its own extension module, and
5+
remove duplicate code in _backend_agg.cpp and _image.cpp
6+
that does the same thing - MGD
7+
8+
2008-06-11 Numerous mathtext bugfixes, primarily related to
9+
dpi-independence - MGD
10+
111
2008-06-10 Bar now applies the label only to the first patch only, and
212
sets '_nolegend_' for the other patch labels. This lets
313
autolegend work as expected for hist and bar - see

doc/conf.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
# Add any Sphinx extension module names here, as strings. They can be extensions
2929
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
30-
extensions = ['mathpng', 'sphinx.ext.autodoc']
30+
extensions = ['mathpng', 'math_symbol_table', 'sphinx.ext.autodoc']
3131

3232
# Add any paths that contain templates here, relative to this directory.
3333
templates_path = ['_templates']
@@ -150,7 +150,11 @@
150150
latex_logo = None
151151

152152
# Additional stuff for the LaTeX preamble.
153-
latex_preamble = ''
153+
latex_preamble = """
154+
\usepackage{amsmath}
155+
\usepackage{amsfonts}
156+
\usepackage{amssymb}
157+
"""
154158

155159
# Documents to append as an appendix to all manuals.
156160
latex_appendices = []

doc/devel/outline.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,29 @@ minor things to close the book on this chapter:
113113
ported over to rest and included in the API so the links from the
114114
user's guide tutorial work.
115115

116+
- There's nothing in the mathtext module that I really consider a
117+
"public" API (i.e. that would be useful to people just doing
118+
plots). If mathtext.py were to be documented, I would put it in
119+
the developer's docs. Maybe I should just take the link in the
120+
user's guide out. - MGD
121+
116122
#. This section might also benefit from a little more detail on the
117123
customizations that are possible (eg an example fleshing out the rc
118124
options a little bit). Admittedly, this is pretty clear from
119125
readin ghte rc file, but it might be helpful to a newbie.
120126

127+
- The only rcParam that is currently useful is mathtext.fontset,
128+
which is documented here. The others only apply when
129+
mathtext.fontset == 'custom', which I'd like to declare
130+
"unsupported". It's really hard to get a good set of math fonts
131+
working that way, though it might be useful in a bind when
132+
someone has to use a specific wacky font for mathtext and only
133+
needs basics, like sub/superscripts. - MGD
134+
121135
#. There is still a TODO in the file to include a complete list of symbols
122136

137+
- Done. It's pretty extensive, thanks to STIX... - MGD
138+
123139
coding guide (reviewed by EF)
124140
-----------------------------
125141

doc/sphinxext/math_symbol_table.py

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
symbols = [
2+
["Lower-case Greek",
3+
5,
4+
r"""\alpha \beta \gamma \chi \delta \epsilon \eta \iota \kappa
5+
\lambda \mu \nu \omega \phi \pi \psi \rho \sigma \tau \theta
6+
\upsilon \xi \zeta \digamma \varepsilon \varkappa \varphi
7+
\varpi \varrho \varsigma \vartheta"""],
8+
["Upper-case Greek",
9+
6,
10+
r"""\Delta \Gamma \Lambda \Omega \Phi \Pi \Psi \Sigma \Theta
11+
\Upsilon \Xi \mho \nabla"""],
12+
["Hebrew",
13+
4,
14+
r"""\aleph \beth \daleth \gimel"""],
15+
["Delimiters",
16+
6,
17+
r"""| \{ \lfloor / \Uparrow \llcorner \vert \} \rfloor \backslash
18+
\uparrow \lrcorner \| \langle \lceil [ \Downarrow \ulcorner
19+
\Vert \rangle \rceil ] \downarrow \urcorner"""],
20+
["Big symbols",
21+
5,
22+
r"""\bigcap \bigcup \bigodot \bigoplus \bigotimes \biguplus
23+
\bigvee \bigwedge \coprod \oint \prod \sum \int"""],
24+
["Standard Function Names",
25+
4,
26+
r"""\arccos \csc \ker \min \arcsin \deg \lg \Pr \arctan \det \lim
27+
\gcd \ln \sup \cot \hom \log \tan \coth \inf \max \tanh
28+
\sec \arg \dim \liminf \sin \cos \exp \limsup \sinh \cosh"""],
29+
["Binary Operation and Relation Symbols",
30+
3,
31+
r"""\ast \pm \slash \cap \star \mp \cup \cdot \uplus
32+
\triangleleft \circ \odot \sqcap \triangleright \bullet \ominus
33+
\sqcup \bigcirc \oplus \wedge \diamond \oslash \vee
34+
\bigtriangledown \times \otimes \dag \bigtriangleup \div \wr
35+
\ddag \barwedge \veebar \boxplus \curlywedge \curlyvee \boxminus
36+
\Cap \Cup \boxtimes \bot \top \dotplus \boxdot \intercal
37+
\rightthreetimes \divideontimes \leftthreetimes \equiv \leq \geq
38+
\perp \cong \prec \succ \mid \neq \preceq \succeq \parallel \sim
39+
\ll \gg \bowtie \simeq \subset \supset \Join \approx \subseteq
40+
\supseteq \ltimes \asymp \sqsubset \sqsupset \rtimes \doteq
41+
\sqsubseteq \sqsupseteq \smile \propto \dashv \vdash \frown
42+
\models \in \ni \notin \approxeq \leqq \geqq \lessgtr \leqslant
43+
\geqslant \lesseqgtr \backsim \lessapprox \gtrapprox \lesseqqgtr
44+
\backsimeq \lll \ggg \gtreqqless \triangleq \lessdot \gtrdot
45+
\gtreqless \circeq \lesssim \gtrsim \gtrless \bumpeq \eqslantless
46+
\eqslantgtr \backepsilon \Bumpeq \precsim \succsim \between
47+
\doteqdot \precapprox \succapprox \pitchfork \Subset \Supset
48+
\fallingdotseq \subseteqq \supseteqq \risingdotseq \sqsubset
49+
\sqsupset \varpropto \preccurlyeq \succcurlyeq \Vdash \therefore
50+
\curlyeqprec \curlyeqsucc \vDash \because \blacktriangleleft
51+
\blacktriangleright \Vvdash \eqcirc \trianglelefteq
52+
\trianglerighteq \neq \vartriangleleft \vartriangleright \ncong
53+
\nleq \ngeq \nsubseteq \nmid \nsupseteq \nparallel \nless \ngtr
54+
\nprec \nsucc \subsetneq \nsim \supsetneq \nVDash \precnapprox
55+
\succnapprox \subsetneqq \nvDash \precnsim \succnsim \supsetneqq
56+
\nvdash \lnapprox \gnapprox \ntriangleleft \ntrianglelefteq
57+
\lneqq \gneqq \ntriangleright \lnsim \gnsim \ntrianglerighteq
58+
\approxident \origof \imageof \coloneq \triangleeq \stareq \nsime
59+
\dotminus \eqsim \nequiv \Equiv \measeq \napprox \eqless
60+
\kernelcontraction \nsupset \doublebarwedge \nVdash \arceq
61+
\backcong \Doteq \eqdef \wedgeq \questeq \eqgtr \cupdot
62+
\veeeq \nsubset \eqcolon \ne
63+
"""],
64+
["Arrow Symbols",
65+
2,
66+
r"""\leftarrow \longleftarrow \uparrow \Leftarrow \Longleftarrow
67+
\Uparrow \rightarrow \longrightarrow \downarrow \Rightarrow
68+
\Longrightarrow \Downarrow \leftrightarrow \updownarrow
69+
\longleftrightarrow \updownarrow \Leftrightarrow
70+
\Longleftrightarrow \Updownarrow \mapsto \longmapsto \nearrow
71+
\hookleftarrow \hookrightarrow \searrow \leftharpoonup
72+
\rightharpoonup \swarrow \leftharpoondown \rightharpoondown
73+
\nwarrow \rightleftharpoons \leadsto \dashrightarrow
74+
\dashleftarrow \leftleftarrows \leftrightarrows \Lleftarrow
75+
\Rrightarrow \twoheadleftarrow \leftarrowtail \looparrowleft
76+
\leftrightharpoons \curvearrowleft \circlearrowleft \Lsh
77+
\upuparrows \upharpoonleft \downharpoonleft \multimap
78+
\leftrightsquigarrow \rightrightarrows \rightleftarrows
79+
\rightrightarrows \rightleftarrows \twoheadrightarrow
80+
\rightarrowtail \looparrowright \rightleftharpoons
81+
\curvearrowright \circlearrowright \Rsh \downdownarrows
82+
\upharpoonright \downharpoonright \rightsquigarrow \nleftarrow
83+
\nrightarrow \nLeftarrow \nRightarrow \nleftrightarrow
84+
\nLeftrightarrow \to \Swarrow \Searrow \Nwarrow \Nearrow
85+
\barleftarrow \mapsup \mapsdown \mapsfrom \rightarrowbar
86+
\twoheaduparrow \updownarrowbar \leftsquigarrow \rightzigzagarrow
87+
\twoheaddownarrow \downzigzagarrow
88+
"""],
89+
["Miscellaneous Symbols",
90+
3,
91+
r"""\neg \invnot \turnednot \infty \forall \wp \exists \bigstar
92+
\angle \partial \nexists \measuredangle \eth \emptyset
93+
\sphericalangle \clubsuit \varnothing \complement \diamondsuit
94+
\imath \Finv \triangledown \heartsuit \jmath \Game \spadesuit
95+
\ell \hbar \vartriangle \cdots \hslash \vdots \blacksquare \ldots
96+
\blacktriangle \ddots \sharp \prime \blacktriangledown \Im \flat
97+
\backprime \Re \natural \circledS \P \O \copyright \ss \Ldsh
98+
\frakZ \l \carriagereturn \circledR \S \sterling \L \yen \danger
99+
\d \OE \AA \AE \scurel \oe \o \checkmark \Rdsh \ae \ac \prurel \$
100+
\iiint \iint \iint \oiiint"""]
101+
]
102+
103+
from docutils import nodes, statemachine
104+
from docutils.parsers.rst import Directive
105+
class math_symbol_table_directive(Directive):
106+
has_content = True
107+
def run(self):
108+
def get_n(n, l):
109+
part = []
110+
for x in l:
111+
part.append(x)
112+
if len(part) == n:
113+
yield part
114+
part = []
115+
yield part
116+
117+
lines = []
118+
for category, columns, syms in symbols:
119+
syms = syms.split()
120+
syms.sort()
121+
lines.append("**%s**" % category)
122+
lines.append('')
123+
max_width = 0
124+
for sym in syms:
125+
max_width = max(max_width, len(sym))
126+
max_width = max_width * 2 + 16
127+
header = " " + (('=' * max_width) + ' ') * columns
128+
format = '%%%ds' % max_width
129+
for chunk in get_n(20, get_n(columns, syms)):
130+
lines.append(header)
131+
for part in chunk:
132+
line = []
133+
for sym in part:
134+
line.append(format % (":math:`%s` ``%s``" % (sym, sym)))
135+
lines.append(" " + " ".join(line))
136+
lines.append(header)
137+
lines.append('')
138+
self.state_machine.insert_input(lines, "Symbol table")
139+
return []
140+
141+
from docutils.parsers.rst import directives
142+
directives.register_directive('math_symbol_table',
143+
math_symbol_table_directive)
144+
145+
if __name__ == "__main__":
146+
# Do some verification of the tables
147+
from matplotlib import _mathtext_data
148+
149+
print "SYMBOLS NOT IN STIX:"
150+
all_symbols = {}
151+
for category, columns, syms in symbols:
152+
if category == "Standard Function Names":
153+
continue
154+
syms = syms.split()
155+
for sym in syms:
156+
if len(sym) > 1:
157+
all_symbols[sym[1:]] = None
158+
if sym[1:] not in _mathtext_data.tex2uni:
159+
print sym
160+
161+
print "SYMBOLS NOT IN TABLE:"
162+
for sym in _mathtext_data.tex2uni:
163+
if sym not in all_symbols:
164+
print sym

doc/sphinxext/mathpng.py

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from hashlib import md5
44
except ImportError:
55
from md5 import md5
6-
6+
77
from docutils import nodes
88
from docutils.writers.html4css1 import HTMLTranslator
99
from sphinx.latexwriter import LaTeXTranslator
@@ -39,7 +39,7 @@ def math_directive(name, arguments, options, content, lineno,
3939
else:
4040
class math_directive(Directive):
4141
has_content = True
42-
def run(self):
42+
def run(self):
4343
latex = ' '.join(self.content)
4444
node = latex_math(self.block_text)
4545
node['latex'] = latex
@@ -75,26 +75,44 @@ def depart_latex_math_latex(self, node):
7575
LaTeXTranslator.depart_latex_math = depart_latex_math_latex
7676

7777
from os.path import isfile
78+
79+
# This calls out to LaTeX to render the expression
80+
def latex2png(latex, name):
81+
f = open('math.tex', 'w')
82+
f.write(r"""\documentclass[12pt]{article}
83+
\pagestyle{empty}
84+
\begin{document}""")
85+
if inline:
86+
f.write('$%s$' % latex)
87+
else:
88+
f.write(r'\[ %s \]' % latex)
89+
f.write('\end{document}')
90+
f.close()
91+
os.system('latex --interaction=nonstopmode math.tex > /dev/null')
92+
os.system('dvipng -bgTransparent -Ttight --noghostscript -l10 ' +
93+
'-o %s math.dvi > /dev/null' % name)
94+
95+
# This uses mathtext to render the expression
96+
def latex2png(latex, filename):
97+
from matplotlib import rcParams
98+
from matplotlib import _png
99+
from matplotlib.mathtext import MathTextParser
100+
rcParams['mathtext.fontset'] = 'cm'
101+
mathtext_parser = MathTextParser("Bitmap")
102+
ftimage = mathtext_parser.parse("$%s$" % latex, 120)
103+
_png.write_png(ftimage.as_rgba_str(), ftimage.get_width(),
104+
ftimage.get_height(), filename)
105+
78106
# LaTeX to HTML translation stuff:
79107
def latex2html(node, source):
80108
inline = isinstance(node.parent, nodes.TextElement)
81109
latex = node['latex']
82-
print latex
83-
name = 'math-' + md5(latex).hexdigest()[-10:]
84-
if not isfile('_static/%s.png' % name):
85-
f = open('math.tex', 'w')
86-
f.write(r"""\documentclass[12pt]{article}
87-
\pagestyle{empty}
88-
\begin{document}""")
89-
if inline:
90-
f.write('$%s$' % latex)
91-
else:
92-
f.write(r'\[ %s \]' % latex)
93-
f.write('\end{document}')
94-
f.close()
95-
os.system('latex --interaction=nonstopmode math.tex > /dev/null')
96-
os.system('dvipng -bgTransparent -Ttight --noghostscript -l10 ' +
97-
'-o _static/%s.png math.dvi > /dev/null' % name)
110+
print latex.encode("ascii", "backslashreplace")
111+
name = 'math-%s' % md5(latex).hexdigest()[-10:]
112+
dest = '_static/%s.png' % name
113+
if not isfile(dest):
114+
latex2png(latex, dest)
115+
98116
path = '_static'
99117
count = source.split('/doc/')[-1].count('/')
100118
for i in range(count):
@@ -110,3 +128,4 @@ def latex2html(node, source):
110128
else:
111129
cls = 'class="center" '
112130
return '<img src="%s/%s.png" %s%s/>' % (path, name, align, cls)
131+

0 commit comments

Comments
 (0)