|
From: <md...@us...> - 2007-07-16 17:59:18
|
Revision: 3542
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3542&view=rev
Author: mdboom
Date: 2007-07-16 10:59:17 -0700 (Mon, 16 Jul 2007)
Log Message:
-----------
Deal with font tags (\cal \it \rm etc.) more like TeX
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 15:42:25 UTC (rev 3541)
+++ branches/mathtext_mgd/lib/matplotlib/mathtext.py 2007-07-16 17:59:17 UTC (rev 3542)
@@ -135,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, Or
+ operatorPrecedence, opAssoc, ParseResults, Or, Suppress
from matplotlib.afm import AFM
from matplotlib.cbook import enumerate, iterable, Bunch
@@ -927,7 +927,6 @@
class Element:
fontsize = 12
dpi = 72
- font = 'it'
_padx, _pady = 2, 2 # the x and y padding in points
_scale = 1.0
@@ -965,10 +964,14 @@
'get the ymax of ink rect'
raise NotImplementedError('derived must override')
+ def determine_font(self, font_stack):
+ 'a first pass to determine the font of this element (one of tt, it, rm , cal)'
+ raise NotImplementedError('derived must override')
+
def set_font(self, font):
'set the font (one of tt, it, rm , cal)'
raise NotImplementedError('derived must override')
-
+
def render(self):
'render to the fonts canvas'
for element in self.neighbors.values():
@@ -1044,6 +1047,45 @@
def __repr__(self):
return str(self.__class__) + str(self.neighbors)
+class FontElement(Element):
+ def __init__(self, name):
+ Element.__init__(self)
+ self.name = name
+
+ def advance(self):
+ 'get the horiz advance'
+ return 0
+
+ def height(self):
+ 'get the element height: ymax-ymin'
+ return 0
+
+ def width(self):
+ 'get the element width: xmax-xmin'
+ return 0
+
+ def xmin(self):
+ 'get the xmin of ink rect'
+ return 0
+
+ def xmax(self):
+ 'get the xmax of ink rect'
+ return 0
+
+ def ymin(self):
+ 'get the ymin of ink rect'
+ return 0
+
+ def ymax(self):
+ 'get the ymax of ink rect'
+ return 0
+
+ def determine_font(self, font_stack):
+ font_stack[-1] = self.name
+
+ def set_font(self, font):
+ return
+
class SpaceElement(Element):
'blank horizontal space'
def __init__(self, space, height=0):
@@ -1083,10 +1125,17 @@
'get the max ink in y'
return self.oy + self.height()
- def set_font(self, f):
+ def determine_font(self, font_stack):
# space doesn't care about font, only size
+ for neighbor_type in ('above', 'below', 'subscript', 'superscript'):
+ neighbor = self.neighbors.get(neighbor_type)
+ if neighbor is not None:
+ neighbor.determine_font(font_stack)
+
+ def set_font(self, font_stack):
+ # space doesn't care about font, only size
pass
-
+
class SymbolElement(Element):
def __init__(self, sym):
Element.__init__(self)
@@ -1094,10 +1143,19 @@
self.kern = None
self.widthm = 1 # the width of an m; will be resized below
+ def determine_font(self, font_stack):
+ 'set the font (one of tt, it, rm, cal)'
+ self.set_font(font_stack[-1])
+ for neighbor_type in ('above', 'below', 'subscript', 'superscript'):
+ neighbor = self.neighbors.get(neighbor_type)
+ if neighbor is not None:
+ neighbor.determine_font(font_stack)
+
def set_font(self, font):
- 'set the font (one of tt, it, rm , cal)'
+ # space doesn't care about font, only size
+ assert not hasattr(self, 'font')
self.font = font
-
+
def set_origin(self, ox, oy):
Element.set_origin(self, ox, oy)
@@ -1163,6 +1221,8 @@
def __repr__(self):
return self.sym
+class AccentElement(SymbolElement):
+ pass
class GroupElement(Element):
"""
@@ -1174,20 +1234,25 @@
for i in range(len(elements)-1):
self.elements[i].neighbors['right'] = self.elements[i+1]
- def set_font(self, font):
+ def determine_font(self, font_stack):
'set the font (one of tt, it, rm , cal)'
+ font_stack.append(font_stack[-1])
for element in self.elements:
- element.set_font(font)
+ element.determine_font(font_stack)
+ font_stack.pop()
-
+ def set_font(self, font):
+ return
+
+ # MGDTODO: The code below is probably now broken
#print 'set fonts'
- for i in range(len(self.elements)-1):
- if not isinstance(self.elements[i], SymbolElement): continue
- if not isinstance(self.elements[i+1], SymbolElement): continue
- symleft = self.elements[i].sym
- symright = self.elements[i+1].sym
- self.elements[i].kern = None
- #self.elements[i].kern = Element.fonts.get_kern(font, symleft, symright, self.fontsize, self.dpi)
+# for i in range(len(self.elements)-1):
+# if not isinstance(self.elements[i], SymbolElement): continue
+# if not isinstance(self.elements[i+1], SymbolElement): continue
+# symleft = self.elements[i].sym
+# symright = self.elements[i+1].sym
+# self.elements[i].kern = None
+# #self.elements[i].kern = Element.fonts.get_kern(font, symleft, symright, self.fontsize, self.dpi)
def set_size_info(self, fontsize, dpi):
@@ -1250,6 +1315,9 @@
def __repr__(self):
return 'Expression: [ %s ]' % ' '.join([str(e) for e in self.elements])
+ def determine_font(self):
+ font_stack = ['it']
+ GroupElement.determine_font(self, font_stack)
class Handler:
symbols = []
@@ -1275,29 +1343,30 @@
return [element]
def symbol(self, s, loc, toks):
-
assert(len(toks)==1)
-
+ #print "symbol", toks
+
s = toks[0]
- if charOverChars.has_key(s):
- under, over, pad = charOverChars[s]
- font, tok, scale = under
- sym = SymbolElement(tok)
- if font is not None:
- sym.set_font(font)
- sym.set_scale(scale)
- sym.set_pady(pad)
+ # MGDTODO: This clause is probably broken due to font changes
+# if charOverChars.has_key(s):
+# under, over, pad = charOverChars[s]
+# font, tok, scale = under
+# sym = SymbolElement(tok)
+# if font is not None:
+# sym.set_font(font)
+# sym.set_scale(scale)
+# sym.set_pady(pad)
- font, tok, scale = over
- sym2 = SymbolElement(tok)
- if font is not None:
- sym2.set_font(font)
- sym2.set_scale(scale)
+# font, tok, scale = over
+# sym2 = SymbolElement(tok)
+# if font is not None:
+# sym2.set_font(font)
+# sym2.set_scale(scale)
- sym.neighbors['above'] = sym2
- self.symbols.append(sym2)
- else:
- sym = SymbolElement(toks[0])
+# sym.neighbors['above'] = sym2
+# self.symbols.append(sym2)
+# else:
+ sym = SymbolElement(toks[0])
self.symbols.append(sym)
return [sym]
@@ -1339,7 +1408,7 @@
r'\.' : r'\combiningdotabove',
r'\^' : r'\circumflexaccent',
}
- above = SymbolElement(d[accent])
+ above = AccentElement(d[accent])
sym.neighbors['above'] = above
sym.set_pady(1)
self.symbols.append(above)
@@ -1352,12 +1421,11 @@
return [grp]
def font(self, s, loc, toks):
-
assert(len(toks)==1)
- name, grp = toks[0]
+ name = toks[0]
#print 'fontgrp', toks
- grp.set_font(name[1:]) # suppress the slash
- return [grp]
+ font = FontElement(name)
+ return [font]
_subsuperscript_names = {
'normal': ['subscript', 'superscript'],
@@ -1524,8 +1592,8 @@
lbrace
+ OneOrMore(
space
- ^ font
- ^ subsuper
+ | font
+ | subsuper
)
+ rbrace
).setParseAction(handler.group).setName("group")
@@ -1539,11 +1607,8 @@
+ group
).setParseAction(handler.composite).setName("composite")
-font << Group(
- Combine(
- bslash
- + fontname)
- + group)
+font <<(Suppress(bslash)
+ + fontname)
placeable <<(accent
^ symbol
@@ -1566,8 +1631,8 @@
expression = OneOrMore(
space
- ^ font
- ^ subsuper
+ | font
+ | subsuper
).setParseAction(handler.expression).setName("expression")
####
@@ -1616,10 +1681,11 @@
elif self.output == 'PDF':
self.font_object = BakomaPDFFonts(character_tracker)
Element.fonts = self.font_object
-
+
handler.clear()
expression.parseString( s )
+ handler.expr.determine_font()
handler.expr.set_size_info(fontsize, dpi)
# set the origin once to allow w, h compution
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|