1#! /usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# file generate_symbols_images.py 5# This file is part of LyX, the document processor. 6# Licence details can be found in the file COPYING. 7 8# Full author contact details are available in file CREDITS 9 10from __future__ import print_function 11import sys,string,re,os,os.path 12import io 13 14def get_code(code, font): 15 # computer modern fonts use a strange encoding 16 cmfonts = ["cmex", "cmr", "cmm", "cmsy"] 17 if font not in cmfonts: 18 return code 19 if code < 10: 20 return code+161 21 if code < 11: 22 return code+162 23 elif code <= 32: 24 return code+163 25 else: 26 return code 27 28font_names = {} 29symbols = {} 30xsymbols = {} 31 32ignore_list = ["not", "braceld", "bracerd", "bracelu", "braceru", 33 "lmoustache", "rmoustache", "lgroup", "rgroup", "bracevert"] 34 35def process(file): 36 fh = io.open(file, 'r', encoding='ascii') 37 lines = fh.readlines() 38 fh.close() 39 package, ext = os.path.splitext(os.path.basename(file)) 40 if ext != ".sty": 41 package = '' 42 mdsymbolcode = 0 43 44 n = len(lines) 45 for i in range(n): 46 line = lines[i] 47 mo = re.match(r'\s*%.*', line) 48 if mo != None: 49 continue 50 next_line = "" 51 if i+1 < n: 52 next_line = lines[i+1] 53 54 # some entries are spread over two lines so we join the next line 55 # to the current one, (if current line contains a comment, we remove it) 56 line = line.split('%')[0]+next_line 57 58 mo = re.match(r'.*\\DeclareSymbolFont\s*\{(.*?)\}\s*\{(.*?)\}\s*\{(.*?)\}.*', line) 59 if mo != None: 60 font_names[mo.group(1)] = mo.group(3) 61 62 mo = re.match(r'^\s*\\mdsy\@DeclareSymbolFont\s*\{(.*?)\}\s*\{(.*?)\}\s*\{(.*?)\}.*', line) 63 if mo != None: 64 font_names[mo.group(1)] = mo.group(3) 65 66 # \mdsy@setslot resets the counter for \mdsy@DeclareSymbol 67 mo = re.match(r'^\s*\\mdsy\@setslot\s*\{(.*?)\}.*', line) 68 if mo != None: 69 mdsymbolcode = int(mo.group(1)) 70 71 # \mdsy@nextslot increments the counter for \mdsy@DeclareSymbol 72 mo = re.match(r'^\s*\\mdsy\@nextslot.*', line) 73 if mo != None: 74 mdsymbolcode = mdsymbolcode + 1 75 76 mo = re.match(r'.*\\(\\mdsy\@)?DeclareMath(Symbol|Delimiter)\s*\{?\\(\w*?)\}?\s*\{?\\(.*?)\}?\s*\{(.*?)\}\s*\{([\'"]?)(.*?)\}.*', line) 77 code = -1 78 try: 79 if mo != None: 80 symbol = mo.group(3) 81 type = mo.group(4) 82 font = mo.group(5) 83 if mo.group(6) == '': 84 code = int(mo.group(7)) 85 elif mo.group(6) == '"': 86 code = int(mo.group(7), 16) 87 else: 88 code = int(mo.group(7), 8) 89 else: 90 mo = re.match(r'.*\\edef\\(\w*?)\{.*?\{\\hexnumber@\\sym(.*?)\}(.*?)\}', line) 91 if mo != None: 92 symbol = mo.group(1) 93 type = "mathord" 94 font = mo.group(2) 95 code = int(mo.group(3), 16) 96 except ValueError: 97 code = -1 98 99 if mo == None: 100 mo = re.match(r'^\s*\\mdsy\@DeclareSymbol\s*\{(.*?)\}\s*\{(.*?)\}\s*\{\\(.*?)\}.*', line) 101 if mo != None: 102 symbol = mo.group(1) 103 type = mo.group(3) 104 font = mo.group(2) 105 code = mdsymbolcode 106 mdsymbolcode = mdsymbolcode + 1 107 108 if mo == None: 109 mo = re.match(r'^\s*\\mdsy\@DeclareAlias\s*\{(.*?)\}\s*\{(.*?)\}\s*\{\\(.*?)\}.*', line) 110 if mo != None: 111 symbol = mo.group(1) 112 type = mo.group(3) 113 font = mo.group(2) 114 code = mdsymbolcode - 1 115 116 if mo != None and symbol not in ignore_list: 117 mo2 = re.match(r'\s*\\def\\(.*?)\{', next_line) 118 if mo2 != None and symbol == mo2.group(1)+"op": 119 sys.stderr.write("%s -> %s\n" % (symbol, mo2.group(1))) 120 symbol = mo2.group(1) 121 122 if font in font_names: 123 font = font_names[font] 124 125 code = get_code(code, font) 126 if code < 0: 127 continue 128 129 xcode = 0 130 if symbol in xsymbols: 131 xcode = xsymbols[symbol] 132 del xsymbols[symbol] 133 134 if symbol in symbols: 135 sys.stderr.write(symbol+ " exists\n") 136 if code != symbols[symbol]: 137 sys.stderr.write("code is not equal!!!\n") 138 else: 139 symbols[symbol] = code 140 if package == '': 141 print("%-18s %-4s %3d %3d %-6s" % (symbol,font,code,xcode,type)) 142 else: 143 print("%-18s %-4s %3d %3d %-9s x %s" % (symbol,font,code,xcode,type,package)) 144 145 146path = os.path.split(sys.argv[0])[0] 147fh = io.open(os.path.join(path, "x-font"), 'r', encoding='ascii') 148lines = fh.readlines() 149fh.close() 150for line in lines: 151 x = line.split() 152 symbol = x[0] 153 code = int(x[1], 16) 154 xsymbols[symbol] = code 155 156for file in sys.argv[1:]: 157 print("# Generated from " + os.path.basename(file) + "\n") 158 process(file) 159 print() 160 161exceptions = [ 162 ("neq", "x", 0, 185, "mathrel"), 163 ("textdegree", "x", 0, 176, "mathord"), 164 ("cong", "x", 0, 64, "mathrel"), 165 ("surd", "x", 0, 214, "mathord") 166] 167 168if "leq" in xsymbols: 169 sys.exit(0) 170 171for x in exceptions: 172 print("%-18s %-4s %3d %3d %-6s" % x) 173 if x[0] in xsymbols: 174 del xsymbols[x[0]] 175 176print (""" 177lyxbar cmsy 161 0 mathord 178lyxeq cmr 61 0 mathord 179lyxdabar msa 57 0 mathord 180lyxright msa 75 0 mathord 181lyxleft msa 76 0 mathord 182""") 183 184for symbol in xsymbols.keys(): 185 sys.stderr.write(symbol+"\n") 186