blob: 5f8c6e835161cb67d98bd86aadc1c26c5367ff17 [file] [log] [blame]
Fred Drake30a68c71998-11-23 16:59:39 +00001#! /usr/bin/env python
2
3"""Convert ESIS events to SGML or XML markup.
4
5This is limited, but seems sufficient for the ESIS generated by the
6latex2esis.py script when run over the Python documentation.
7"""
8__version__ = '$Revision$'
9
10import errno
11import re
12import string
13
14
15_data_rx = re.compile(r"[^\\][^\\]*")
16
17def decode(s):
18 r = ''
19 while s:
20 m = _data_rx.match(s)
21 if m:
22 r = r + m.group()
23 s = s[len(m.group()):]
24 elif s[1] == "\\":
25 r = r + "\\"
26 s = s[2:]
27 elif s[1] == "n":
28 r = r + "\n"
29 s = s[2:]
30 else:
31 raise ValueError, "can't handle " + `s`
32 return r
33
34
35def format_attrs(attrs):
36 attrs = attrs.items()
37 attrs.sort()
38 s = ''
39 for name, value in attrs:
40 s = '%s %s="%s"' % (s, name, value)
41 return s
42
43
44def do_convert(ifp, ofp, knownempties, xml=0):
45 attrs = {}
46 lastopened = None
47 knownempty = 0
48 lastempty = 0
49 while 1:
50 line = ifp.readline()
51 if not line:
52 break
53
54 type = line[0]
55 data = line[1:]
56 if data and data[-1] == "\n":
57 data = data[:-1]
58 if type == "-":
59 data = decode(data)
60 ofp.write(data)
61 if "\n" in data:
62 lastopened = None
63 knownempty = 0
64 lastempty = 0
65 elif type == "(":
66 if knownempty and xml:
67 ofp.write("<%s%s/>" % (data, format_attrs(attrs)))
68 else:
69 ofp.write("<%s%s>" % (data, format_attrs(attrs)))
70 if knownempty and data not in knownempties:
71 # accumulate knowledge!
72 knownempties.append(data)
73 attrs = {}
74 lastopened = data
75 lastempty = knownempty
76 knownempty = 0
77 elif type == ")":
78 if xml:
79 if not lastempty:
80 ofp.write("</%s>" % data)
81 elif data not in knownempties:
82 if lastopened == data:
83 ofp.write("</>")
84 else:
85 ofp.write("</%s>" % data)
86 lastopened = None
87 lastempty = 0
88 elif type == "A":
89 name, type, value = string.split(data, " ", 2)
90 attrs[name] = decode(value)
91 elif type == "e":
92 knownempty = 1
93
94
95def sgml_convert(ifp, ofp, knownempties=()):
96 return do_convert(ifp, ofp, list(knownempties), xml=0)
97
98
99def xml_convert(ifp, ofp, knownempties=()):
100 return do_convert(ifp, ofp, list(knownempties), xml=1)
101
102
103def main():
104 import sys
105 #
106 convert = sgml_convert
107 if sys.argv[1:] and sys.argv[1] in ("-x", "--xml"):
108 convert = xml_convert
109 del sys.argv[1]
110 if len(sys.argv) == 1:
111 ifp = sys.stdin
112 ofp = sys.stdout
113 elif len(sys.argv) == 2:
114 ifp = open(sys.argv[1])
115 ofp = sys.stdout
116 elif len(sys.argv) == 3:
117 ifp = open(sys.argv[1])
118 ofp = open(sys.argv[2], "w")
119 else:
120 usage()
121 sys.exit(2)
122 # knownempties is ignored in the XML version
123 try:
124 convert(ifp, ofp)
125 except IOError, (err, msg):
126 if err != errno.EPIPE:
127 raise
128
129
130if __name__ == "__main__":
131 main()