|
From: <md...@us...> - 2007-07-16 15:08:16
|
Revision: 3540
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3540&view=rev
Author: mdboom
Date: 2007-07-16 08:08:12 -0700 (Mon, 16 Jul 2007)
Log Message:
-----------
Got nested sub/superscripts working. Improved formatting of grammar
to be more readable to newbies (like me).
Modified Paths:
--------------
branches/mathtext_mgd/lib/matplotlib/mathtext.py
Modified: branches/mathtext_mgd/lib/matplotlib/mathtext.py
===================================================================
--- branches/mathtext_mgd/lib/matplotlib/mathtext.py 2007-07-16 14:06:59 UTC (rev 3539)
+++ branches/mathtext_mgd/lib/matplotlib/mathtext.py 2007-07-16 15:08:12 UTC (rev 3540)
@@ -119,7 +119,6 @@
KNOWN ISSUES:
- - nested subscripts, eg, x_i_j not working; but you can do x_{i_j}
- nesting fonts changes in sub/superscript groups not parsing
- I would also like to add a few more layout commands, like \frac.
@@ -136,7 +135,7 @@
from matplotlib.pyparsing import Literal, Word, OneOrMore, ZeroOrMore, \
Combine, Group, Optional, Forward, NotAny, alphas, nums, alphanums, \
StringStart, StringEnd, ParseException, FollowedBy, Regex, \
- operatorPrecedence, opAssoc, ParseResults
+ operatorPrecedence, opAssoc, ParseResults, Or
from matplotlib.afm import AFM
from matplotlib.cbook import enumerate, iterable, Bunch
@@ -1014,6 +1013,7 @@
self.dpi = dpi
for loc, element in self.neighbors.items():
if loc in ('subscript', 'superscript'):
+ print type(element), element
element.set_size_info(0.7*self.fontsize, dpi)
else:
element.set_size_info(self.fontsize, dpi)
@@ -1257,8 +1257,10 @@
def clear(self):
self.symbols = []
+ self.subscript_stack = []
def expression(self, s, loc, toks):
+ print "expression", toks
self.expr = ExpressionElement(toks)
return [self.expr]
@@ -1279,7 +1281,7 @@
assert(len(toks)==1)
s = toks[0]
- #~ print 'sym', toks[0]
+ print 'sym', toks[0]
if charOverChars.has_key(s):
under, over, pad = charOverChars[s]
font, tok, scale = under
@@ -1360,172 +1362,209 @@
grp.set_font(name[1:]) # suppress the slash
return [grp]
- def subscript(self, s, loc, toks):
+ _subsuperscript_names = {
+ 'normal': ['subscript', 'superscript'],
+ 'overUnder': ['below', 'above']
+ }
+
+ _subsuperscript_indices = {
+ '_': (0, 1),
+ '^': (1, 0)
+ }
+
+ def subsuperscript(self, s, loc, toks):
assert(len(toks)==1)
- #print 'subsup', toks
- if len(toks[0])==2:
- under, next = toks[0]
- prev = SpaceElement(0)
- else:
- prev, under, next = toks[0]
+ print 'subscript', toks
- if self.is_overunder(prev):
- prev.neighbors['below'] = next
- else:
- prev.neighbors['subscript'] = next
+ if len(toks[0])==3:
+ prev, op, next = toks[0]
+ index, other_index = self._subsuperscript_indices[op]
+ if self.is_overunder(prev):
+ names = self._subsuperscript_names['overUnder']
+ else:
+ names = self._subsuperscript_names['normal']
+
+ prev.neighbors[names[index]] = next
- return loc, [prev]
+ for compound in self._subsuperscript_names.values():
+ if compound[other_index] in next.neighbors:
+ prev.neighbors[names[other_index]] = next.neighbors[compound[other_index]]
+ del next.neighbors[compound[other_index]]
+ return [prev]
+ return toks[0].asList()
def is_overunder(self, prev):
return isinstance(prev, SymbolElement) and overunder.has_key(prev.sym)
- def superscript(self, s, loc, toks):
- assert(len(toks)==1)
- #print 'subsup', toks
- if len(toks[0])==2:
- under, next = toks[0]
- prev = SpaceElement(0,0.6)
- else:
- prev, under, next = toks[0]
- if self.is_overunder(prev):
- prev.neighbors['above'] = next
- else:
- prev.neighbors['superscript'] = next
-
- return [prev]
-
- def subsuperscript(self, s, loc, toks):
- assert(len(toks)==1)
- #print 'subsup', toks
- prev, undersym, down, oversym, up = toks[0]
-
- if self.is_overunder(prev):
- prev.neighbors['below'] = down
- prev.neighbors['above'] = up
- else:
- prev.neighbors['subscript'] = down
- prev.neighbors['superscript'] = up
-
- return [prev]
-
-
-
handler = Handler()
-lbrace = Literal('{').suppress()
-rbrace = Literal('}').suppress()
-lbrack = Literal('[')
-rbrack = Literal(']')
-lparen = Literal('(')
-rparen = Literal(')')
-grouping = lbrack | rbrack | lparen | rparen
+# All forward declarations are here
+font = Forward().setParseAction(handler.font).setName("font")
+subsuper = Forward().setParseAction(handler.subsuperscript).setName("subsuper")
+placeable = Forward().setName("placeable")
-bslash = Literal('\\')
+lbrace = Literal('{').suppress()
+rbrace = Literal('}').suppress()
+lbrack = Literal('[')
+rbrack = Literal(']')
+lparen = Literal('(')
+rparen = Literal(')')
+grouping =(lbrack
+ | rbrack
+ | lparen
+ | rparen)
-langle = Literal('<')
-rangle = Literal('>')
-equals = Literal('=')
-relation = langle | rangle | equals
+subscript = Literal('_')
+superscript = Literal('^')
-colon = Literal(':')
-comma = Literal(',')
-period = Literal('.')
-semicolon = Literal(';')
-exclamation = Literal('!')
+bslash = Literal('\\')
-punctuation = colon | comma | period | semicolon
+langle = Literal('<')
+rangle = Literal('>')
+equals = Literal('=')
+relation =(langle
+ | rangle
+ | equals)
-at = Literal('@')
-percent = Literal('%')
-ampersand = Literal('&')
-misc = exclamation | at | percent | ampersand
+colon = Literal(':')
+comma = Literal(',')
+period = Literal('.')
+semicolon = Literal(';')
+exclamation = Literal('!')
+punctuation =(colon
+ | comma
+ | period
+ | semicolon)
-over = Literal('over')
-under = Literal('under')
-#~ composite = over | under
-overUnder = over | under
+at = Literal('@')
+percent = Literal('%')
+ampersand = Literal('&')
+misc =(exclamation
+ | at
+ | percent
+ | ampersand)
-accent = Literal('hat') | Literal('check') | Literal('dot') | \
- Literal('breve') | Literal('acute') | Literal('ddot') | \
- Literal('grave') | Literal('tilde') | Literal('bar') | \
- Literal('vec') | Literal('"') | Literal("`") | Literal("'") |\
- Literal('~') | Literal('.') | Literal('^')
+over = Literal('over')
+under = Literal('under')
+overUnder =(over
+ | under)
+accent =(Literal('hat') | Literal('check') | Literal('dot') |
+ Literal('breve') | Literal('acute') | Literal('ddot') |
+ Literal('grave') | Literal('tilde') | Literal('bar') |
+ Literal('vec') | Literal('"') | Literal("`") | Literal("'") |
+ Literal('~') | Literal('.') | Literal('^'))
+number = Combine(Word(nums) + Optional(Literal('.')) + Optional( Word(nums) ))
+plus = Literal('+')
+minus = Literal('-')
+times = Literal('*')
+div = Literal('/')
+binop =(plus
+ | minus
+ | times
+ | div)
-number = Combine(Word(nums) + Optional(Literal('.')) + Optional( Word(nums) ))
+roman = Literal('rm')
+cal = Literal('cal')
+italics = Literal('it')
+typewriter = Literal('tt')
+fontname =(roman
+ | cal
+ | italics
+ | typewriter)
-plus = Literal('+')
-minus = Literal('-')
-times = Literal('*')
-div = Literal('/')
-binop = plus | minus | times | div
+texsym = Combine(bslash + Word(alphanums) + NotAny("{"))
+char = Word(alphanums + ' ', exact=1).leaveWhitespace()
-roman = Literal('rm')
-cal = Literal('cal')
-italics = Literal('it')
-typewriter = Literal('tt')
-fontname = roman | cal | italics | typewriter
+space =(FollowedBy(bslash)
+ + (Literal(r'\ ')
+ | Literal(r'\/')
+ | Group(Literal(r'\hspace{') + number + Literal('}'))
+ )
+ ).setParseAction(handler.space).setName('space')
-texsym = Combine(bslash + Word(alphanums) + NotAny("{"))
+symbol = Regex("(" + ")|(".join(
+ [
+ r"\\[a-zA-Z0-9]+(?!{)",
+ r"[a-zA-Z0-9 ]",
+ r"[+\-*/]",
+ r"[<>=]",
+ r"[:,.;!]",
+ r"[!@%&]",
+ r"[[\]()]",
+ ])
+ + ")"
+ ).setParseAction(handler.symbol).leaveWhitespace()
-char = Word(alphanums + ' ', exact=1).leaveWhitespace()
+_symbol =(texsym
+ | char
+ | binop
+ | relation
+ | punctuation
+ | misc
+ | grouping
+ ).setParseAction(handler.symbol).leaveWhitespace()
-space = FollowedBy(bslash) + (Literal(r'\ ') | Literal(r'\/') | Group(Literal(r'\hspace{') + number + Literal('}'))).setParseAction(handler.space).setName('space')
+accent = Group(
+ Combine(bslash + accent)
+ + Optional(lbrace)
+ + symbol
+ + Optional(rbrace)
+ ).setParseAction(handler.accent).setName("accent")
-symbol = Regex("("+")|(".join(
- [
- r"\\[a-zA-Z0-9]+(?!{)",
- r"[a-zA-Z0-9 ]",
- r"[+\-*/]",
- r"[<>=]",
- r"[:,.;!]",
- r"[!@%&]",
- r"[[\]()]",
- ])+")"
- ).setParseAction(handler.symbol).leaveWhitespace()
+group = Group(
+ lbrace
+ + OneOrMore(
+ space
+ ^ font
+ ^ subsuper
+ ^ placeable
+ )
+ + rbrace
+ ).setParseAction(handler.group).setName("group")
-#~ symbol = (texsym ^ char ^ binop ^ relation ^ punctuation ^ misc ^ grouping ).setParseAction(handler.symbol).leaveWhitespace()
-_symbol = (texsym | char | binop | relation | punctuation | misc | grouping ).setParseAction(handler.symbol).leaveWhitespace()
+composite = Group(
+ Combine(
+ bslash
+ + overUnder
+ )
+ + group
+ + group
+ ).setParseAction(handler.composite).setName("composite")
-subscript = Forward().setParseAction(handler.subscript).setName("subscript")
-superscript = Forward().setParseAction(handler.superscript).setName("superscript")
-subsuperscript = Forward().setParseAction(handler.subsuperscript).setName("subsuperscript")
+font << Group(
+ Combine(
+ bslash
+ + fontname)
+ + group)
-font = Forward().setParseAction(handler.font).setName("font")
+placeable <<(accent
+ ^ symbol
+ ^ group
+ ^ composite
+ )
+subsuper << Group(
+ placeable
+ + ZeroOrMore(
+ ( subscript
+ | superscript
+ )
+ + subsuper
+ )
+ )
-accent = Group( Combine(bslash + accent) + Optional(lbrace) + symbol + Optional(rbrace)).setParseAction(handler.accent).setName("accent")
-group = Group( lbrace + OneOrMore(symbol^subscript^superscript^subsuperscript^space^font^accent) + rbrace).setParseAction(handler.group).setName("group")
-#~ group = Group( lbrace + OneOrMore(subsuperscript | subscript | superscript | symbol | space ) + rbrace).setParseAction(handler.group).setName("group")
+expression = OneOrMore(
+ space
+ ^ font
+ ^ subsuper
+ ^ placeable
+ ).setParseAction(handler.expression).setName("expression")
-#composite = Group( Combine(bslash + composite) + lbrace + symbol + rbrace + lbrace + symbol + rbrace).setParseAction(handler.composite).setName("composite")
-#~ composite = Group( Combine(bslash + composite) + group + group).setParseAction(handler.composite).setName("composite")
-composite = Group( Combine(bslash + overUnder) + group + group).setParseAction(handler.composite).setName("composite")
-
-
-
-
-
-
-symgroup = font | group | symbol
-
-subscript << Group( Optional(symgroup) + Literal('_') + symgroup )
-superscript << Group( Optional(symgroup) + Literal('^') + symgroup )
-subsuperscript << Group( symgroup + Literal('_') + symgroup + Literal('^') + symgroup )
-
-font << Group( Combine(bslash + fontname) + group)
-
-
-
-expression = OneOrMore(
- space ^ font ^ accent ^ symbol ^ subscript ^ superscript ^ subsuperscript ^ group ^ composite ).setParseAction(handler.expression).setName("expression")
-#~ expression = OneOrMore(
- #~ group | composite | space | font | subsuperscript | subscript | superscript | symbol ).setParseAction(handler.expression).setName("expression")
-
####
@@ -1577,7 +1616,9 @@
expression.parseString( s )
handler.expr.set_size_info(fontsize, dpi)
-
+ print handler.expr
+ print handler.symbols
+
# set the origin once to allow w, h compution
handler.expr.set_origin(0, 0)
xmin = min([e.xmin() for e in handler.symbols])
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|