diff --git a/texlive-20200327-dviasm-py3.patch b/texlive-20200327-dviasm-py3.patch new file mode 100644 index 0000000..399a71c --- /dev/null +++ b/texlive-20200327-dviasm-py3.patch @@ -0,0 +1,318 @@ +diff -up texlive-base-20200327/source/texk/texlive/linked_scripts/dviasm/dviasm.py.py3fix texlive-base-20200327/source/texk/texlive/linked_scripts/dviasm/dviasm.py +--- texlive-base-20200327/source/texk/texlive/linked_scripts/dviasm/dviasm.py.py3fix 2019-11-27 17:03:14.000000000 -0500 ++++ texlive-base-20200327/source/texk/texlive/linked_scripts/dviasm/dviasm.py 2020-09-18 17:30:44.000000000 -0400 +@@ -5,8 +5,8 @@ + # + # Copyright (C) 2007-2008 by Jin-Hwan Cho + # Copyright (C) 2011-2017 by Khaled Hosny +-# Copyright (C) 2019 by Arthur Reutenauer +-# Copyright (C) 2019 by Hironobu Yamashita ++# Copyright (C) 2019 by Arthur Reutenauer ++# Copyright (C) 2019-2020 by Hironobu Yamashita + # + # 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 +@@ -180,22 +180,26 @@ def GetInt(s): + except: return -1 + + def GetStrASCII(s): # used in Parse() +- if len(s) > 1 and ((s[0] == "'" and s[-1] == "'") or (s[0] == '"' and s[-1] == '"')): return [ord(c) for c in s[1:-1].decode('unicode_escape')] ++ if len(s) > 1 and ((s[0] == "'" and s[-1] == "'") or (s[0] == '"' and s[-1] == '"')): ++ return [ord(c) for c in s[1:-1].decode('unicode_escape')] + else: return '' + + def UCS2toJIS(c): +- s = c.encode('iso2022-jp') ++ try: ++ s = c.encode('iso2022-jp') ++ except UnicodeEncodeError: ++ s = c.encode('raw_unicode_escape') + if len(s) == 1: return ord(s) + else: return (s[3] << 8) + s[4] + + def GetStrUTF8(s): # used in Parse() + if len(s) > 1 and ((s[0] == "'" and s[-1] == "'") or (s[0] == '"' and s[-1] == '"')): +- t = s[1:-1] ++ t = s[1:-1].encode('raw_unicode_escape').decode('unicode_escape') + if is_ptex: return [UCS2toJIS(c) for c in t] + else: return [ord(c) for c in t] + else: return '' + +-def PutStrASCII(t): # unsed in Dump() ++def PutStrASCII(t): # used in Dump() + s = '' + for o in t: + if o == 92: s += '\\\\' +@@ -206,7 +210,7 @@ def PutStrASCII(t): # unsed in Dump() + warning('Not support characters > 65535; may skip %d.\n' % o) + return "'%s'" % s + +-def PutStrLatin1(t): # unsed in Dump() ++def PutStrLatin1(t): # used in Dump() + s = '' + for o in t: + if o == 92: s += '\\\\' +@@ -221,14 +225,14 @@ def DecodeISO2022JP(c): + try: + s = bytes.fromhex("1b 24 42 %02x %02x" % (c//256, c%256)).decode('iso2022-jp') + except UnicodeDecodeError: +- s = '' ++ s = chr(c) + return s + +-def PutStrUTF8(t): # unsed in Dump() ++def PutStrUTF8(t): # used in Dump() + s = '' + if is_subfont: + for o in t: +- s += chr((subfont_idx << 8) + o).encode('utf8') ++ s += chr((subfont_idx << 8) + o) + else: # not the case of subfont + for o in t: + if o == 92: s += '\\\\' +@@ -239,16 +243,6 @@ def PutStrUTF8(t): # unsed in Dump() + else: s += chr(o) + return "'%s'" % s + +-def PutStrSJIS(t): # unsed in Dump() +- s = '' +- for o in t: +- if o == 92: s += '\\\\' +- elif 32 <= o < 127: s += chr(o) +- elif o < 128: s += ('\\x%02x' % o) +- else: +- s += DecodeISO2022JP(o).encode('sjis') +- return "'%s'" % s +- + def IsFontChanged(f, z): + global cur_font, cur_ssize, subfont_idx, is_subfont + for n in subfont_list: +@@ -461,7 +455,7 @@ class DVI(object): + if o == SET_RULE: + s.append([SET_RULE, [p, SignedQuad(fp)]]) + elif o in (PUT1, PUT2, PUT3, PUT4): +- s.append([PUT1, p]) ++ s.append([PUT1, [p]]) + elif o == PUT_RULE: + s.append([PUT_RULE, [p, SignedQuad(fp)]]) + elif o == NOP: +@@ -498,7 +492,7 @@ class DVI(object): + elif o < FNT_NUM_0 + 64 or o in (FNT1, FNT2, FNT3, FNT4): + s.append([FNT1, p]) + elif o in (XXX1, XXX2, XXX3, XXX4): +- q = fp.read(p).decode('utf8') ++ q = fp.read(p) + s.append([XXX1, q]) + elif o in (FNT_DEF1, FNT_DEF2, FNT_DEF3, FNT_DEF4): + self.DefineFont(p, fp) +@@ -622,11 +616,11 @@ class DVI(object): + if cmd[0] == SET1: + for o in cmd[1]: + if o < 128: s.append(bytes.fromhex('%02x' % (SET_CHAR_0 + o))) +- else: s.append(self.CmdPair([SET1, o])) ++ else: s.append(self.CmdPairU([SET1, o])) + elif cmd[0] in (SET_RULE, PUT_RULE): + s.append(bytes.fromhex('%02x' % cmd[0]) + PutSignedQuad(cmd[1][0]) + PutSignedQuad(cmd[1][1])) + elif cmd[0] == PUT1: +- s.append(self.CmdPair([PUT1, cmd[1][0]])) ++ s.append(self.CmdPairU([PUT1, cmd[1][0]])) + elif cmd[0] in (RIGHT1, DOWN1): + s.append(self.CmdPair(cmd)) + elif cmd[0] in (W0, X0, Y0, Z0): +@@ -648,12 +642,22 @@ class DVI(object): + z = cmd[1]; s.append(self.CmdPair(cmd)) + elif cmd[0] == FNT1: + if cmd[1] < 64: s.append(bytes.fromhex('%02x' % (FNT_NUM_0 + cmd[1]))) +- else: s.append(self.CmdPair(cmd)) ++ else: s.append(self.CmdPairU(cmd)) + elif cmd[0] == XXX1: +- cmd1 = cmd[1].encode('utf8') +- l = len(cmd[1]) +- if l < 256: s.append(bytes.fromhex('%02x' % XXX1) + bytes.fromhex('%02x' % l) + cmd1) +- else: s.append(bytes.fromhex('%02x' % XXX4) + PutSignedQuad(l) + cmd1) ++ if options.xxx_encoding == "none": ++ l = len(cmd[1]) # leave encoding untouched ++ else: ++ cmd1 = cmd[1].encode(options.xxx_encoding) ++ l = len(cmd1) ++ if l < 256: ++ s.append(bytes.fromhex('%02x' % XXX1) + bytes.fromhex('%02x' % l)) ++ else: ++ s.append(bytes.fromhex('%02x' % XXX4) + PutSignedQuad(l)) ++ if options.xxx_encoding == "none": ++ for o in cmd[1]: ++ s.append(bytes.fromhex('%02x' % ord(o))) ++ else: ++ s.append(cmd1) + elif cmd[0] == DIR: + s.append(bytes.fromhex('%02x' % DIR) + bytes.fromhex('%02x' % cmd[1])) + elif cmd[0] == BEGIN_REFLECT: +@@ -685,7 +689,8 @@ class DVI(object): + def WriteFontDefinitions(self, fp): + s = [] + for e in sorted(self.font_def.keys()): +- if self.font_def[e]['native']: ++ try: ++ self.font_def[e]['native'] + flags = self.font_def[e]['flags'] + s.append(PutByte(NATIVE_FONT_DEF)) + s.append(PutSignedQuad(e)) +@@ -698,7 +703,7 @@ class DVI(object): + if flags & XDV_FLAG_EXTEND: s.append(PutSignedQuad(self.font_def[e]['extend'])) + if flags & XDV_FLAG_SLANT: s.append(PutSignedQuad(self.font_def[e]['slant'])) + if flags & XDV_FLAG_EMBOLDEN: s.append(PutSignedQuad(self.font_def[e]['embolden'])) +- else: ++ except KeyError: + l, q = PutUnsigned(e) + s.append(PutByte(FNT_DEF1 + l)) + s.append(q) +@@ -710,6 +715,10 @@ class DVI(object): + s.append(self.font_def[e]['name'].encode('utf8')) + fp.write(b''.join(s)) + ++ def CmdPairU(self, cmd): ++ l, q = PutUnsigned(cmd[1]) ++ return bytes.fromhex('%02x' % (cmd[0] + l)) + q ++ + def CmdPair(self, cmd): + l, q = PutSigned(cmd[1]) + return bytes.fromhex('%02x' % (cmd[0] + l)) + q +@@ -718,7 +727,7 @@ class DVI(object): + # Parse: Text -> Internal Format + ########################################################## + def Parse(self, fn, encoding=''): +- fp = open(fn, 'r') ++ fp = open(fn, 'r', encoding=encoding) + s = fp.read() + fp.close() + self.ParseFromString(s, encoding=encoding) +@@ -807,7 +816,10 @@ class DVI(object): + else: + self.cur_page.append([SET1, ol]) + elif key == 'put': +- self.cur_page.append([PUT1, GetStr(val)]) ++ ol = GetStr(val) ++ if len(ol) != 1: ++ warning('only one character is allowed for put!') ++ self.cur_page.append([PUT1, ol]) + elif key == 'setrule': + v = val.split(' ') + if len(v) != 2: +@@ -895,7 +907,7 @@ class DVI(object): + # Dump: Internal Format -> Text + ########################################################## + def Dump(self, fn, tabsize=2, encoding=''): +- fp = open(fn, 'w') ++ fp = open(fn, 'w', encoding=encoding) + self.DumpToFile(fp, tabsize=tabsize, encoding=encoding) + fp.close() + +@@ -903,7 +915,6 @@ class DVI(object): + global PutStr + if encoding == 'ascii': PutStr = PutStrASCII + elif encoding == 'latin1': PutStr = PutStrLatin1 +- elif encoding == 'sjis': PutStr = PutStrSJIS + else: PutStr = PutStrUTF8 + # DumpPreamble + fp.write("[preamble]\n") +@@ -921,10 +932,10 @@ class DVI(object): + # DumpFontDefinitions + fp.write("\n[font definitions]\n") + for e in sorted(self.font_def.keys()): +- fp.write("fntdef: %s" % self.font_def[e]['name']) ++ fp.write("fntdef: %s " % self.font_def[e]['name']) + if self.font_def[e]['design_size'] != self.font_def[e]['scaled_size']: +- fp.write(" (%s) " % self.byconv(self.font_def[e]['design_size'])) +- fp.write(" at %s\n" % self.byconv(self.font_def[e]['scaled_size'])) ++ fp.write("(%s) " % self.byconv(self.font_def[e]['design_size'])) ++ fp.write("at %s\n" % self.byconv(self.font_def[e]['scaled_size'])) + # DumpPages + for page in self.pages: + fp.write("\n[page" + (" %d"*10 % tuple(page['count'])) + "]\n") +@@ -939,7 +950,10 @@ class DVI(object): + fp.write("push:\n") + indent += tabsize + elif cmd[0] == XXX1: +- fp.write("xxx: %s\n" % repr(cmd[1])) ++ if options.xxx_encoding == "none": ++ fp.write("xxx: %s\n" % PutStrASCII(cmd[1])) # leave encoding untouched ++ else: ++ fp.write("xxx: '%s'\n" % cmd[1].decode(options.xxx_encoding)) + elif cmd[0] == DIR: + fp.write("dir: %d\n" % cmd[1]) + elif cmd[0] == BEGIN_REFLECT: +@@ -1092,7 +1106,6 @@ class DVI(object): + f['slant'] = slant + f['embolden'] = embolden + else: +- f['native'] = False + f['name'] = n + + if q[:2] == "at": q = q[2:] +@@ -1144,16 +1157,18 @@ def ProcessOptions(): + DVIasm is a Python script to support changing or creating DVI files + via disassembling into text, editing, and then reassembling into + binary format. It is fully documented at ++ http://tug.org/TUGboat/Articles/tb28-2/tb89cho.pdf ++ http://ajt.ktug.kr/assets/2008/5/1/0201cho.pdf + +-http://tug.org/TUGboat/Articles/tb28-2/tb89cho.pdf +-http://ajt.ktug.kr/assets/2008/5/1/0201cho.pdf""" ++Please report bugs to ++ https://github.com/aminophen/dviasm""" ++ ++ version = """This is %prog-20200918 + +- version = """This is %prog-20191126 +- + Copyright (C) 2007-2008 by Jin-Hwan Cho + Copyright (C) 2011-2017 by Khaled Hosny +-Copyright (C) 2019 by Arthur Reutenauer +-Copyright (C) 2019 by Hironobu Yamashita ++Copyright (C) 2019 by Arthur Reutenauer ++Copyright (C) 2019-2020 by Hironobu Yamashita + + This is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -1173,6 +1188,10 @@ the Free Software Foundation, either ver + action="store", type="string", dest="encoding", + metavar="STR", + help="encoding for input/output [default=%default]") ++ parser.add_option("-x", "--xxx-encoding", ++ action="store", type="string", dest="xxx_encoding", ++ metavar="STR", ++ help="encoding for interpreting xxx strings [default=%default]") + parser.add_option("-t", "--tabsize", + action="store", type="int", dest="tabsize", + metavar="INT", +@@ -1184,18 +1203,20 @@ the Free Software Foundation, either ver + action="append", type="string", dest="subfont", + metavar="STR", + help="the list of fonts with UCS2 subfont scheme (comma separated); disable internal subfont list if STR is empty") +- parser.set_defaults(unit='pt', encoding='utf8', tabsize=2) ++ parser.set_defaults(unit='pt', encoding='utf8', xxx_encoding='none', tabsize=2) + (options, args) = parser.parse_args() + if not options.unit in ['sp', 'pt', 'bp', 'mm', 'cm', 'in']: + parser.error("invalid unit name '%s'!" % options.unit) +- if options.tabsize < 0: ++ if options.tabsize < 0: + parser.error("negative tabsize!") +- if not options.encoding in ['ascii', 'latin1', 'utf8', 'sjis']: ++ if not options.xxx_encoding in ['none', 'utf8', 'sjis', 'eucjp']: ++ parser.error("invalid xxx-encoding '%s'!" % options.xxx_encoding) ++ if not options.encoding in ['ascii', 'latin1', 'utf8', 'sjis', 'eucjp']: + parser.error("invalid encoding '%s'!" % options.encoding) + if options.ptex: + global is_ptex + is_ptex = True +- if not options.encoding in ['utf8', 'sjis']: ++ if not options.encoding in ['utf8', 'sjis', 'eucjp']: + parser.error("invalid encoding '%s' for Japanese pTeX!" % options.encoding) + if options.subfont: + global subfont_list +@@ -1235,4 +1256,4 @@ if __name__ == '__main__': + else: # dump -> dvi + aDVI.Parse(args[0], encoding=options.encoding) + if options.output: aDVI.Save(options.output) +- else: aDVI.SaveToFile(sys.stdout) ++ else: aDVI.SaveToFile(sys.stdout.buffer)