# # $Id: tex2libplot.py,v 1.5 2002/08/18 22:04:07 mrnolta Exp $ # # Copyright (C) 2000 Mike Nolta # # 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