#
# $Id: tex2libplot.py,v 1.5 2002/08/18 22:04:07 mrnolta Exp $
#
# Copyright (C) 2000 Mike Nolta <mrnolta@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
#
# This is just a quick and dirty converter from simple TeX strings
# to libplot Hershey font strings. Basically just a lookup table.
#
import re, string
class TeXLexer:
re_control_sequence = re.compile( r"^\\[a-zA-Z]+[ ]?|^\\[^a-zA-Z][ ]?" )
def __init__( self, str ):
self.str = str
self.len = len(str)
self.pos = 0
self.token_stack = []
def get_token( self ):
if self.pos == self.len:
return None
if len(self.token_stack) > 0:
return self.token_stack.pop()
str = self.str[self.pos:]
m = self.re_control_sequence.match(str)
if m is not None:
token = m.group()
self.pos = self.pos + len(token)
## consume trailing space
if len(token) > 2 and token[-1] == ' ':
token = token[:-1]
else:
token = str[0]
self.pos = self.pos + 1
return token
def put_token( self, token ):
self.token_stack.append( token )
def peek( self ):
token = self.get_token()
self.put_token( token )
return token
_common_token_dict = {
r'\\' : '\\',
r'\$' : r'$',
r'\%' : r'%',
r'\#' : r'#',
r'\&' : r'&',
# r'\~' : r'~',
r'\{' : r'{',
r'\}' : r'}',
r'\_' : r'_',
# r'\^' : r'^',
r'~' : r' ',
r'\/' : r'\r^',
## special letters (p52)
# r'\oe' : r'',
# r'\OE' : r'',
r'\ae' : r'\ae',
r'\AE' : r'\AE',
r'\aa' : r'\oa',
r'\AA' : r'\oA',
r'\o' : r'\/o',
r'\O' : r'\/O',
# r'\l' : r'',
# r'\L' : r'',
r'\ss' : r'\ss',
## ignore stray brackets
r'{' : r'',
r'}' : r'',
}
_text_token_dict = {
## punctuation (p52)
r'\`' : r'\`',
r"\'" : r"\'",
r'\^' : r'\^',
r'\"' : r'\:',
r'\~' : r'\~',
r'\c' : r'\,',
## non-math symbols (p438)
r'\S' : r'\sc',
r'\P' : r'\ps',
r'\dag' : r'\dg',
r'\ddag' : r'\dd',
}
_math_token_dict = {
r'*' : r'\**',
## spacing
# r' ' : r'',
r'\ ' : r' ',
r'\quad' : r'\r1', # 1 em
r'\qquad' : r'\r1\r1', # 2 em
r'\,' : r'\r6', # 3/18 em
# r'\>' : r'', # 4/18 em
# r'\;' : r'', # 5/18 em
r'\!' : r'\l6', # -1/6 em
## lowercase greek
r'\alpha' : r'\*a',
r'\beta' : r'\*b',
r'\gamma' : r'\*g',
r'\delta' : r'\*d',
r'\epsilon' : r'\*e',
# r'\varepsilon' : r'',
r'\zeta' : r'\*z',
r'\eta' : r'\*y',
r'\theta' : r'\*h',
r'\vartheta' : r'\+h',
r'\iota' : r'\*i',
r'\kappa' : r'\*k',
r'\lambda' : r'\*l',
r'\mu' : r'\*m',
r'\nu' : r'\*n',
r'\xi' : r'\*c',
r'\pi' : r'\*p',
# r'\varpi' : r'',
r'\rho' : r'\*r',
# r'\varrho' : r'',
r'\sigma' : r'\*s',
r'\varsigma' : r'\ts',
r'\tau' : r'\*t',
r'\upsilon' : r'\*u',
r'\phi' : r'\*f',
r'\varphi' : r'\+f',
r'\chi' : r'\*x',
r'\psi' : r'\*q',
r'\omega' : r'\*w',
## uppercase greek
r'\Alpha' : r'\*A',
r'\Beta' : r'\*B',
r'\Gamma' : r'\*G',
r'\Delta' : r'\*D',
r'\Epsilon' : r'\*E',
r'\Zeta' : r'\*Z',
r'\Eta' : r'\*Y',
r'\Theta' : r'\*H',
r'\Iota' : r'\*I',
r'\Kappa' : r'\*K',
r'\Lambda' : r'\*L',
r'\Mu' : r'\*M',
r'\Nu' : r'\*N',
r'\Xi' : r'\*C',
r'\Pi' : r'\*P',
r'\Rho' : r'\*R',
r'\Sigma' : r'\*S',
r'\Tau' : r'\*T',
r'\Upsilon' : r'\*U',
r'\Phi' : r'\*F',
r'\Chi' : r'\*X',
r'\Psi' : r'\*Q',
r'\Omega' : r'\*W',
## miscellaneous
r'\aleph' : r'\Ah',
r'\hbar' : r'\hb',
r'\ell' : r'\#H0662',
r'\wp' : r'\wp',
r'\Re' : r'\Re',
r'\Im' : r'\Im',
r'\partial' : r'\pd',
r'\infty' : r'\if',
r'\prime' : r'\fm',
r'\emptyset' : r'\es',
r'\nabla' : r'\gr',
r'\surd' : r'\sr',
# r'\top' : r'',
# r'\bot' : r'',
r'\|' : r'\||',
r'\angle' : r'\/_',
# r'\triangle' : r'',
r'\backslash' : r'\\',
r'\forall' : r'\fa',
r'\exists' : r'\te',
r'\neg' : r'\no',
# r'\flat' : r'',
# r'\natural' : r'',
# r'\sharp' : r'',
r'\clubsuit' : r'\CL',
r'\diamondsuit' : r'\DI',
r'\heartsuit' : r'\HE',
r'\spadesuit' : r'\SP',
## binary operations
r'\pm' : r'\+-',
r'\mp' : r'\-+',
# r'\setminus' : r'',
r'\cdot' : r'\md',
r'\times' : r'\mu',
r'\ast' : r'\**',
# r'\star' : r'',
# r'\diamond' : r'',
# r'\circ' : r'',
r'\bullet' : r'\bu',
r'\div' : r'\di',
r'\cap' : r'\ca',
r'\cup' : r'\cu',
# r'\uplus' : r'',
# r'\sqcap' : r'',
# r'\sqcup' : r'',
# r'\triangleleft' : r'',
# r'\triangleright' : r'',
# r'\wr' : r'',
# r'\bigcirc' : r'',
# r'\bigtriangleup' : r'',
# r'\bigtriangledown' : r'',
# r'\vee' : r'',
# r'\wedge' : r'',
r'\oplus' : r'\c+',
# r'\ominus' : r'',
r'\otimes' : r'\c*',
# r'\oslash' : r'',
# r'\odot' : r'',
r'\dagger' : r'\dg',
r'\ddagger' : r'\dd',
# r'\amalg' : r'',
## relations
r'\leq' : r'\<=',
# r'\prec' : r'',
# r'\preceq' : r'',
r'\ll' : r'<<',
r'\subset' : r'\SB',
# r'\subseteq' : r'',
# r'\sqsubseteq' : r'',
r'\in' : r'\mo',
# r'\vdash' : r'',
# r'\smile' : r'',
# r'\frown' : r'',
r'\geq' : r'\>=',
# r'\succ' : r'',
# r'\succeq' : r'',
r'\gg' : r'>>',
r'\supset' : r'\SS',
# r'\supseteq' : r'',
# r'\sqsupseteq' : r'',
# r'\ni' : r'',
# r'\dashv' : r'',
r'\mid' : r'|',
r'\parallel' : r'\||',
r'\equiv' : r'\==',
r'\sim' : r'\ap',
r'\simeq' : r'\~-',
# r'\asymp' : r'',
r'\approx' : r'\~~',
r'\cong' : r'\=~',
# r'\bowtie' : r'',
r'\propto' : r'\pt',
# r'\models' : r'',
# r'\doteq' : r'',
r'\perp' : r'\pp',
## arrows
r'\leftarrow' : r'\<-',
r'\Leftarrow' : r'\lA',
r'\rightarrow' : r'\->',
r'\Rightarrow' : r'\rA',
r'\leftrightarrow' : r'\<>',
r'\Leftrightarrow' : r'\hA',
# r'\mapsto' : r'',
# r'\hookleftarrow' : r'',
# r'\leftharpoonup' : r'',
# r'\leftharpoondown' : r'',
# r'\rightleftharpoons' : r'',
# ...
r'\uparrow' : r'\ua',
r'\Uparrow' : r'\uA',
r'\downarrow' : r'\da',
r'\Downarrow' : r'\dA',
# r'\updownarrow' : r'',
# r'\Updownarrow' : r'',
# r'\nearrow' : r'',
# r'\searrow' : r'',
# r'\swarrow' : r'',
# r'\nwarrow' : r'',
## openings
r'\lbrack' : r'[',
r'\lbrace' : r'{',
r'\langle' : r'\la',
# r'\lfloor' : r'',
# r'\lceil' : r'',
## closings
r'\rbrack' : r']',
r'\rbrace' : r'}',
r'\rangle' : r'\ra',
# r'\rfloor' : r'',
# r'\rceil' : r'',
## alternate names
r'\ne' : r'\!=',
r'\neq' : r'\!=',
r'\le' : r'\<=',
r'\ge' : r'\>=',
r'\to' : r'\->',
r'\gets' : r'\<-',
# r'\owns' : r'',
r'\land' : r'\AN',
r'\lor' : r'\OR',
r'\lnot' : r'\no',
r'\vert' : r'|',
r'\Vert' : r'\||',
## extensions
r'\degree' : r'\de',
r'\deg' : r'\de',
r'\degr' : r'\de',
r'\arcdeg' : r'\de',
}
def map_text_token( token ):
if _text_token_dict.has_key(token):
return _text_token_dict[token]
else:
return _common_token_dict.get( token, token )
def map_math_token( token ):
if _math_token_dict.has_key(token):
return _math_token_dict[token]
else:
return _common_token_dict.get( token, token )
def math_group( lexer ):
output = ''
bracketmode = 0
while 1:
token = lexer.get_token()
if token is None:
break
if token == '{':
bracketmode = 1
elif token == '}':
break
else:
output = output + map_math_token( token )
if not bracketmode:
break
return output
font_code = [ r'\f0', r'\f1', r'\f2', r'\f3' ]
def tex2libplot( str ):
output = ''
mathmode = 0
font_stack = []
font = 1
lexer = TeXLexer( str )
while 1:
token = lexer.get_token()
if token is None:
break
append = ''
if token == '$':
mathmode = not mathmode
elif token == '{':
font_stack.append( font )
elif token == '}':
old_font = font_stack.pop()
if old_font != font:
font = old_font
append = font_code[font]
elif token == r'\rm':
font = 1
append = font_code[font]
elif token == r'\it':
font = 2
append = font_code[font]
elif token == r'\bf':
font = 3
append = font_code[font]
elif not mathmode:
append = map_text_token( token )
elif token == '_':
append = r'\sb' + math_group(lexer) + r'\eb'
if lexer.peek() == '^':
append = r'\mk' + append + r'\rt'
elif token == '^':
append = r'\sp' + math_group(lexer) + r'\ep'
if lexer.peek() == '_':
append = r'\mk' + append + r'\rt'
else:
append = map_math_token( token )
output = output + append
return output
|