On Nov 12, 12:35 pm, pkienzle <[email protected]> wrote:
> Following the hints in the extension API docs I created an extension
> which allows $tex$ instead of :math:`tex` in rst and py docstrings.
>
> Put this in your extensions directory and add "dollarmath" to your
> configuration file.
>
> - Paul
>
> --dollarmath.py--
> # This program is public domain
> # Author: Paul Kienzle
> r"""
> Allow $math$ markup in text and docstrings, ignoring \$.
>
> The $math$ markup should be separated from the surrounding text by
> spaces. To
> embed markup within a word, place backslash-space before and after.
> For
> convenience, the final $ can be followed by punctuation (period, comma
> or
> semicolon).
> """
>
> import re
>
> _dollar = re.compile(r"(?:^|(?<=\s))[$]([^\n]*?)(?<![\\])[$](?:$|(?=\s|
> [.,;\\]))")
> _notdollar = re.compile(r"\\[$]")
>
> def replace_dollar(content):
> original = content
> content = _dollar.sub(r":math:`\1`",content)
> content = _notdollar.sub("$", content)
> #if '$' in content:
> # import sys
> # sys.stdout.write("\n========> not converted\n")
> # sys.stdout.write(content)
> # sys.stdout.write("\n")
> #elif '$' in original:
> # import sys
> # sys.stdout.write("\n========> converted\n")
> # sys.stdout.write(content)
> # sys.stdout.write("\n")
> return content
>
> def rewrite_rst(app, docname, source):
> source[0] = replace_dollar(source[0])
>
> def rewrite_autodoc(app, what, name, obj, options, lines):
> lines[:] = [replace_dollar(L) for L in lines]
>
> def setup(app):
> app.connect('source-read', rewrite_rst)
> app.connect('autodoc-process-docstring', rewrite_autodoc)
>
> def test_dollar():
> assert replace_dollar(u"no dollar")==u"no dollar"
> assert replace_dollar(u"$only$")==u":math:`only`"
> assert replace_dollar(u"$first$ is good")==u":math:`first` is
> good"
> assert replace_dollar(u"so is $last$")==u"so is :math:`last`"
> assert replace_dollar(u"and $mid$ too")==u"and :math:`mid` too"
> assert replace_dollar(u"$first$, $mid$, $last
> $")==u":math:`first`, :math:`mid`, :math:`last`"
> assert replace_dollar(u"dollar\$ escape")==u"dollar$ escape"
> assert replace_dollar(u"dollar \$escape\$ too")==u"dollar $escape$
> too"
> assert replace_dollar(u"emb\ $ed$\ ed")==u"emb\ :math:`ed`\ ed"
> assert replace_dollar(u"$first$a")==u"$first$a"
> assert replace_dollar(u"a$last$")==u"a$last$"
> assert replace_dollar(u"a $mid$dle a")==u"a $mid$dle a"
>
> if __name__ == "__main__":
> test_dollar()
In Sage [www.sagemath.org], we've been using the following function to
replace dollar signs with backticks (in Sage, we have
default_role = 'math'
in conf.py, so we just need `x=y`, not :math:`x=y`). This one
replaces dollar signs even if they're not surrounded by white space.
I haven't tested it, but you might be able to use this as an
alternative for the function replace_dollar.
- John
def process_dollars(s):
r"""
Replace dollar signs with backticks.
More precisely, do a regular expression search. Replace a plain
dollar sign ($) by a backtick (`). Replace an escaped dollar sign
(\\$) by a dollar sign ($). Don't change a dollar sign preceded
or
followed by a backtick (\`$ or \$`), because of strings like
"``$HOME``". Don't make any changes on lines starting with more
spaces than the first nonempty line in ``s``, because those are
indented and hence part of a block of code or examples.
This also doesn't replaces dollar signs enclosed in curly braces,
to avoid nested math environments.
EXAMPLES::
sage: from sage.misc.sagedoc import process_dollars
sage: process_dollars('hello')
'hello'
sage: process_dollars('some math: $x=y$')
'some math: `x=y`'
Replace \\$ with $, and don't do anything when backticks are
involved::
sage: process_dollars(r'a ``$REAL`` dollar sign: \$')
'a ``$REAL`` dollar sign: $'
Don't make any changes on lines indented more than the first
nonempty line::
sage: s = '\n first line\n indented $x=y$'
sage: s == process_dollars(s)
True
Don't replace dollar signs enclosed in curly braces::
sage: process_dollars(r'f(n) = 0 \text{ if $n$ is prime}')
'f(n) = 0 \\text{ if $n$ is prime}'
This is not perfect::
sage: process_dollars(r'$f(n) = 0 \text{ if $n$ is prime}$')
'`f(n) = 0 \\text{ if $n$ is prime}$'
The regular expression search doesn't find the last $.
Fortunately, there don't seem to be any instances of this kind of
expression in the Sage library, as of this writing.
"""
if s.find("$") == -1:
return s
# find how much leading whitespace s has, for later comparison:
# ignore all $ on lines which start with more whitespace.
whitespace = re.match(r'\s*\S', s.lstrip('\n'))
whitespace = ' ' * (whitespace.end() - 1) # leading whitespace
# Indices will be a list of pairs of positions in s, to search
between.
# If the following search has no matches, then indices will be (0,
len(s)).
indices = [0]
# This searches for "$blah$" inside a pair of curly braces --
# don't change these, since they're probably coming from a nested
# math environment. So for each match, search to the left of its
# start and to the right of its end, but not in between.
for m in re.finditer(r"{[^{}$]*\$([^{}$]*)\$[^{}$]*}", s):
indices[-1] = (indices[-1], m.start())
indices.append(m.end())
indices[-1] = (indices[-1], len(s))
# regular expression for $ (not \$, `$, $`, and only on a line
# with no extra leading whitespace).
#
# in detail:
# re.compile("^" # beginning of line
# + "(%s%)?" % whitespace
# + r"""(\S # non whitespace
# .*?)? # non-greedy match any non-newline
characters
# (?<!`|\\)\$(?!`) # $ with negative
lookbehind and lookahead
# """, re.M | re.X)
#
# except that this doesn't work, so use the equivalent regular
# expression without the 're.X' option. Maybe 'whitespace' gets
# eaten up by re.X?
regexp = "^" + "(%s)?"%whitespace + r"(\S.*?)?(?<!`|\\)\$(?!`)"
dollar = re.compile(regexp, re.M)
# regular expression for \$
slashdollar = re.compile(r"\\\$")
for start, end in indices:
while dollar.search(s, start, end):
m = dollar.search(s, start, end)
s = s[:m.end()-1] + "`" + s[m.end():]
while slashdollar.search(s, start, end):
m = slashdollar.search(s, start, end)
s = s[:m.start()] + "$" + s[m.end():]
return s
--
You received this message because you are subscribed to the Google Groups
"sphinx-dev" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sphinx-dev?hl=en.