--- svgmath/fonts/afm.py.orig 2022-03-18 18:47:45 UTC +++ svgmath/fonts/afm.py @@ -1,5 +1,5 @@ import sys, glyphlist -from metric import FontMetric, CharMetric, FontFormatError +from .metric import FontMetric, CharMetric, FontFormatError def parseLength(s): return 0.001 * float(s) @@ -23,7 +23,7 @@ class AFMMetric (FontMetric): def readFontMetrics(self, afmfile): line = afmfile.readline() if not line.startswith("StartFontMetrics"): - raise AFMFormatError, "File is not an AFM file" + raise AFMFormatError("File is not an AFM file") # TODO: AFM version control while True: @@ -49,7 +49,7 @@ class AFMMetric (FontMetric): elif tokens[0] == "Weight": self.weight = tokens[1].strip() elif tokens[0] == "FontBBox": - self.bbox = map (parseLength, tokens[1].split()) + self.bbox = list(map (parseLength, tokens[1].split())) elif tokens[0] == "CapHeight": self.capheight = parseLength(tokens[1]) elif tokens[0] == "XHeight": @@ -88,7 +88,7 @@ class AFMMetric (FontMetric): if d[0] == "W" or d[0] == "WX" or d[0] == "W0X": width = parseLength(d[1]) elif d[0] == "B" and len(d) == 5: - bbox = map (parseLength, d[1:]) + bbox = list(map (parseLength, d[1:])) elif d[0] == "N": glyphname = d[1] @@ -137,6 +137,6 @@ def main(): if len (sys.argv) == 2: AFMMetric(sys.argv[1], log=sys.stderr).dump() else: - print """Usage: AFM.py """ + print("""Usage: AFM.py """) if __name__ == "__main__": main() --- svgmath/fonts/glyphlist.py.orig 2022-03-18 18:47:45 UTC +++ svgmath/fonts/glyphlist.py @@ -15,13 +15,13 @@ class GlyphList(dict): if len (codelist) != 1: continue # no support for compounds codepoint = int (codelist[0], 16) - if glyph in self.keys(): + if glyph in list(self.keys()): self[glyph].append(codepoint) else: self[glyph] = [codepoint] def lookup(self, glyphname): - if glyphname in self.keys(): return self.get(glyphname) + if glyphname in list(self.keys()): return self.get(glyphname) else: return defaultGlyphList.get(glyphname) @@ -34,8 +34,8 @@ def main(): else: glyphList = defaultGlyphList - for entry, value in glyphList.items(): - print entry, " => ", value + for entry, value in list(glyphList.items()): + print(entry, " => ", value) if __name__ == "__main__": main() --- svgmath/fonts/metric.py.orig 2022-03-18 18:47:45 UTC +++ svgmath/fonts/metric.py @@ -37,28 +37,28 @@ class FontMetric: def postParse(self): # Get Ascender from the 'd' glyph if self.ascender is None: - cm = self.chardata.get(ord(u'd')) + cm = self.chardata.get(ord('d')) if cm is not None: self.descender = cm.bbox[3] else: self.ascender = 0.7 # Get Descender from the 'p' glyph if self.descender is None: - cm = self.chardata.get(ord(u'p')) + cm = self.chardata.get(ord('p')) if cm is not None: self.descender = cm.bbox[1] else: self.descender = -0.2 # Get CapHeight from the 'H' glyph if self.capheight is None: - cm = self.chardata.get(ord(u'H')) + cm = self.chardata.get(ord('H')) if cm is not None: self.capheight = cm.bbox[3] else: self.capheight = self.ascender # Get XHeight from the 'H' glyph if self.xheight is None: - cm = self.chardata.get(ord(u'x')) + cm = self.chardata.get(ord('x')) if cm is not None: self.xheight = cm.bbox[3] else: self.xheight = 0.45 @@ -69,7 +69,7 @@ class FontMetric: # "equal", "minus", "plus", "less", "greater", "periodcentered") # Default is CapHeight / 2, or 0.3 if there's no CapHeight. if self.axisposition is None: - for ch in [ord(u'+'), 0x2212, ord(u'='), ord(u'<'), ord(u'>'), 0xB7]: + for ch in [ord('+'), 0x2212, ord('='), ord('<'), ord('>'), 0xB7]: cm = self.chardata.get(ch) if cm is not None: self.axisposition = (cm.bbox[1] + cm.bbox[3]) / 2 @@ -80,7 +80,7 @@ class FontMetric: if self.underlinethickness is not None: self.rulewidth = self.underlinethickness else: - for ch in [0x2013, 0x2014, 0x2015, 0x2212, ord(u'-')]: + for ch in [0x2013, 0x2014, 0x2015, 0x2212, ord('-')]: cm = self.chardata.get(ch) if cm is not None: self.rulewidth = cm.bbox[3] - cm.bbox[1] @@ -107,35 +107,35 @@ class FontMetric: else: self.vgap = self.rulewidth * 2 # Set missing glyph to be a space - self.missingGlyph = self.chardata.get(ord(u' ')) or self.chardata.get(0xA0) + self.missingGlyph = self.chardata.get(ord(' ')) or self.chardata.get(0xA0) def dump(self): - print "FontName: ", self.fontname - print "FullName: ", self.fullname - print "FontFamily: ", self.family - print "Weight: ", self.weight - print "FontBBox: ", + print("FontName: ", self.fontname) + print("FullName: ", self.fullname) + print("FontFamily: ", self.family) + print("Weight: ", self.weight) + print("FontBBox: ", end=' ') for x in self.bbox: - print x, - print - print "CapHeight: ", self.capheight - print "XHeight: ", self.xheight - print "Ascender: ", self.ascender - print "Descender: ", self.descender - print "StdHW: ", self.stdhw - print "StdVW: ", self.stdvw - print "UnderlinePosition: ", self.underlineposition - print "UnderlineThickness: ", self.underlinethickness - print "ItalicAngle: ", self.italicangle - print "CharWidth: ", self.charwidth - print "MathematicalBaseline: ", self.axisposition - print "Character data: " - chars = self.chardata.items() + print(x, end=' ') + print() + print("CapHeight: ", self.capheight) + print("XHeight: ", self.xheight) + print("Ascender: ", self.ascender) + print("Descender: ", self.descender) + print("StdHW: ", self.stdhw) + print("StdVW: ", self.stdvw) + print("UnderlinePosition: ", self.underlineposition) + print("UnderlineThickness: ", self.underlinethickness) + print("ItalicAngle: ", self.italicangle) + print("CharWidth: ", self.charwidth) + print("MathematicalBaseline: ", self.axisposition) + print("Character data: ") + chars = list(self.chardata.items()) chars.sort(key = lambda c: c[0]) for i, cm in chars: if cm is None: continue - print " ", ("U+%04X" % i), cm.name+":", " W", cm.width, " B", + print(" ", ("U+%04X" % i), cm.name+":", " W", cm.width, " B", end=' ') for x in cm.bbox: - print x, - print + print(x, end=' ') + print() \ No newline at end of file --- svgmath/fonts/ttf.py.orig 2022-03-18 18:47:45 UTC +++ svgmath/fonts/ttf.py @@ -1,5 +1,5 @@ import sys -from metric import FontMetric, CharMetric, FontFormatError +from .metric import FontMetric, CharMetric, FontFormatError def readUnsigned(ff, size): res = 0; @@ -41,14 +41,14 @@ class TTFMetric (FontMetric): def readFontMetrics(self, ff): version = ff.read(4) - if map(ord, version) == [0, 1, 0, 0]: + if list(map(ord, version)) == [0, 1, 0, 0]: self.fonttype="TTF" elif version == "OTTO": # self.fonttype="OTF" # At the moment, I cannot parse bbox data out from CFF - raise TTFFormatError, "OpenType/CFF fonts are unsupported" + raise TTFFormatError("OpenType/CFF fonts are unsupported") else: - raise TTFFormatError, "Not a TrueType file" + raise TTFFormatError("Not a TrueType file") numTables = readUnsigned(ff, 2) tables = {} @@ -61,15 +61,15 @@ class TTFMetric (FontMetric): tables[tag] = (offset, length) def switchTable(tableTag): - if tableTag not in tables.keys(): - raise TTFFormatError, "Required table "+tableTag+" missing in TrueType file" + if tableTag not in list(tables.keys()): + raise TTFFormatError("Required table "+tableTag+" missing in TrueType file") return tables[tableTag] (offset, length) = switchTable("head") ff.seek(offset+12) magic = readUnsigned(ff, 4) if magic != 0x5F0F3CF5: - raise TTFFormatError, "Magic number in 'head' table does not match the spec" + raise TTFFormatError("Magic number in 'head' table does not match the spec") skip(ff, 2) self.unitsPerEm = readUnsigned(ff, 2) emScale = 1.0 / self.unitsPerEm @@ -107,24 +107,24 @@ class TTFMetric (FontMetric): nameOffset = readUnsigned(ff, 2) if platformID == 3 and encodingID == 1: - if languageID in englishCodes or nameID not in uniNames.keys(): + if languageID in englishCodes or nameID not in list(uniNames.keys()): uniNames[nameID] = (nameOffset, nameLength) elif platformID == 1 and encodingID == 0: - if languageID == 0 or nameID not in macNames.keys(): + if languageID == 0 or nameID not in list(macNames.keys()): macNames[nameID] = (nameOffset, nameLength) def getName (code): - if code in macNames.keys(): + if code in list(macNames.keys()): (nameOffset, nameLength) = macNames[code] ff.seek (storageOffset + nameOffset) return ff.read(nameLength) # FIXME: repair Mac encoding here - elif code in uniNames.keys(): + elif code in list(uniNames.keys()): (nameOffset, nameLength) = uniNames[code] ff.seek (storageOffset + nameOffset) - result = u"" + result = "" for i in range (0, nameLength/2): - result += unichr(readUnsigned(ff, 2)) + result += chr(readUnsigned(ff, 2)) return result self.family = getName(1) @@ -198,7 +198,7 @@ class TTFMetric (FontMetric): encodingScheme = "Symbol" subtableOffset = cmapEncodings.get((3, 0)) if subtableOffset is None: - raise TTFFormatError, "Cannot use font '%s': no known subtable in 'cmap' table" % self.fullname + raise TTFFormatError("Cannot use font '%s': no known subtable in 'cmap' table" % self.fullname) else: if self.log: self.log.write("WARNING: font '%s' is a symbolic font - Unicode mapping may be unreliable\n" % self.fullname) @@ -207,7 +207,7 @@ class TTFMetric (FontMetric): tableFormat = readUnsigned(ff, 2) if tableFormat != 4: - raise TTFFormatError, "Unsupported format in 'cmap' table: %d" % tableFormat + raise TTFFormatError("Unsupported format in 'cmap' table: %d" % tableFormat) subtableLength = readUnsigned(ff, 2) skip (ff, 2) @@ -264,7 +264,7 @@ class TTFMetric (FontMetric): for i in range (0, self.numGlyphs+1): glyphIndex.append(readUnsigned(ff, 4)) else: - raise TTFFormatError, "Invalid indexToLocFormat value (%d) in 'head' table" % str(self.indexToLocFormat) + raise TTFFormatError("Invalid indexToLocFormat value (%d) in 'head' table" % str(self.indexToLocFormat)) (offset, length) = switchTable("glyf") for i in range (0, self.numGlyphs): @@ -284,6 +284,6 @@ def main(): if len (sys.argv) == 2: TTFMetric(sys.argv[1], log=sys.stderr).dump() else: - print """Usage: TTF.py """ + print("""Usage: TTF.py """) if __name__ == "__main__": main() --- svgmath/mathconfig.py.orig 2022-03-18 18:47:45 UTC +++ svgmath/mathconfig.py @@ -2,9 +2,9 @@ import os, sys from xml import sax -from fonts.afm import AFMMetric -from fonts.ttf import TTFMetric -from fonts.metric import FontFormatError +from .fonts.afm import AFMMetric +from .fonts.ttf import TTFMetric +from .fonts.metric import FontFormatError class MathConfig(sax.ContentHandler): """Configuration for MathML-to-SVG formatter. @@ -26,47 +26,47 @@ class MathConfig(sax.ContentHandler): parser.setContentHandler(self) parser.setFeature(sax.handler.feature_namespaces, 0) parser.parse(configfile) - except sax.SAXException, xcpt: - print "Error parsing configuration file ", configfile, ": ", xcpt.getMessage() + except sax.SAXException as xcpt: + print("Error parsing configuration file ", configfile, ": ", xcpt.getMessage()) sys.exit(1) def startElement(self, name, attributes): - if name == u"config": - self.verbose = (attributes.get(u"verbose") == u"true") - self.debug = (attributes.get(u"debug", u"")).replace(u",", u" ").split() + if name == "config": + self.verbose = (attributes.get("verbose") == "true") + self.debug = (attributes.get("debug", "")).replace(",", " ").split() - elif name == u"defaults": + elif name == "defaults": self.defaults.update(attributes) - elif name == u"fallback": - familyattr = attributes.get(u"family", u"") - self.fallbackFamilies = [" ".join(x.split()) for x in familyattr.split(u",")] + elif name == "fallback": + familyattr = attributes.get("family", "") + self.fallbackFamilies = [" ".join(x.split()) for x in familyattr.split(",")] - elif name == u"family": - self.currentFamily = attributes.get(u"name", u"") + elif name == "family": + self.currentFamily = attributes.get("name", "") self.currentFamily = "".join(self.currentFamily.lower().split()) - elif name == u"font": - weight = attributes.get(u"weight", u"normal") - style = attributes.get(u"style", u"normal") + elif name == "font": + weight = attributes.get("weight", "normal") + style = attributes.get("style", "normal") fontfullname = self.currentFamily; - if weight != u"normal": - fontfullname += u" " + weight - if style != u"normal": - fontfullname += u" " + style + if weight != "normal": + fontfullname += " " + weight + if style != "normal": + fontfullname += " " + style try: - if u"afm" in attributes.keys(): - fontpath = attributes.get(u"afm") - metric = AFMMetric(fontpath, attributes.get(u"glyph-list"), sys.stderr) - elif u"ttf" in attributes.keys(): - fontpath = attributes.get(u"ttf") + if "afm" in list(attributes.keys()): + fontpath = attributes.get("afm") + metric = AFMMetric(fontpath, attributes.get("glyph-list"), sys.stderr) + elif "ttf" in list(attributes.keys()): + fontpath = attributes.get("ttf") metric = TTFMetric(fontpath, sys.stderr) else: sys.stderr.write("Bad record in configuration file: font is neither AFM nor TTF\n") sys.stderr.write("Font entry for '%s' ignored\n" % fontfullname) return - except FontFormatError, err: + except FontFormatError as err: sys.stderr.write("Invalid or unsupported file format in '%s': %s\n" % (fontpath, err.message)) sys.stderr.write("Font entry for '%s' ignored\n" % fontfullname) return @@ -76,41 +76,41 @@ class MathConfig(sax.ContentHandler): sys.stderr.write("Font entry for '%s' ignored\n" % fontfullname) return - self.fonts[weight+u" "+style+u" "+self.currentFamily] = metric + self.fonts[weight+" "+style+" "+self.currentFamily] = metric - elif name == u"mathvariant": - variantattr = attributes.get(u"name") - familyattr = attributes.get(u"family", "") - splitFamily = [" ".join(x.split()) for x in familyattr.split(u",")] - weightattr = attributes.get(u"weight", u"normal") - styleattr = attributes.get(u"style", u"normal") + elif name == "mathvariant": + variantattr = attributes.get("name") + familyattr = attributes.get("family", "") + splitFamily = [" ".join(x.split()) for x in familyattr.split(",")] + weightattr = attributes.get("weight", "normal") + styleattr = attributes.get("style", "normal") self.variants[variantattr] = (weightattr, styleattr, splitFamily) - elif name == u"operator-style": - opname = attributes.get(u"operator") + elif name == "operator-style": + opname = attributes.get("operator") if opname: styling = {} styling.update(attributes) - del styling[u"operator"] + del styling["operator"] self.opstyles[opname] = styling else: sys.stderr.write("Bad record in configuration file: operator-style with no operator attribute\n") def endElement(self, name): - if name == u"family": + if name == "family": self.currentFamily = None def findfont(self, weight, style, family): """Finds a metric for family+weight+style.""" - weight = (weight or u"normal").strip() - style = (style or u"normal").strip() - family = "".join((family or u"").lower().split()) + weight = (weight or "normal").strip() + style = (style or "normal").strip() + family = "".join((family or "").lower().split()) - for w in [weight, u"normal"]: - for s in [style, u"normal"]: - metric = self.fonts.get(w+u" "+s+u" "+family) + for w in [weight, "normal"]: + for s in [style, "normal"]: + metric = self.fonts.get(w+" "+s+" "+family) if metric: return metric return None @@ -121,20 +121,20 @@ def main(): else: config = MathConfig(sys.argv[1]) - print "Options: verbose =", config.verbose, " debug =", config.debug - print "Fonts:" - for (font, metric) in config.fonts.items(): - print " ", font, "-->", metric.fontname - print "Math variants:" - for (variant, value) in config.variants.items(): - print " ", variant, "-->", value - print "Defaults:" - for (attr, value) in config.defaults.items(): - print " ", attr, "=", value - print "Operator styling:" - for (opname, value) in config.opstyles.items(): - print " ", repr(opname), ":", value - print "Fallback font families:", config.fallbackFamilies + print("Options: verbose =", config.verbose, " debug =", config.debug) + print("Fonts:") + for (font, metric) in list(config.fonts.items()): + print(" ", font, "-->", metric.fontname) + print("Math variants:") + for (variant, value) in list(config.variants.items()): + print(" ", variant, "-->", value) + print("Defaults:") + for (attr, value) in list(config.defaults.items()): + print(" ", attr, "=", value) + print("Operator styling:") + for (opname, value) in list(config.opstyles.items()): + print(" ", repr(opname), ":", value) + print("Fallback font families:", config.fallbackFamilies) if __name__ == "__main__": main()