source: doc/user-guide/genhelp.py @ 9740ce9

Last change on this file since 9740ce9 was 9740ce9, checked in by dequis <dx@…>, at 2015-05-16T04:55:14Z

Add python script to generate help.txt, replacing xslt stuff

This would mean changing one build dependency for another, but one that
is way more common at least. (Fun fact: the xslt stuff depends on perl)

It generates *almost* the same thing as the xslt - a bit better if you
ask me, since it correctly handles a few <emphasis> tags in the middle
of the text, which were previously stripped. One example of that is:

Favo<emphasis>u</emphasis>rite the given user [...]

Outputs "Favo\x02u\x02rite" with this script, "Favorite" with the xslt.
(That's actually an accidental feature)

The script works in python2 and python3 and only uses the stdlib

  • Property mode set to 100644
File size: 4.5 KB
Line 
1import re
2import xml.etree.ElementTree as ET
3
4IN_FILE = 'help.xml'
5OUT_FILE = 'help.txt'
6NORMALIZE_RE = re.compile(r"([^<>\s\t])[\s\t]+([^<>\s\t])")
7
8def join(list):
9    return ''.join([str(x) for x in list])
10
11def normalize(x):
12    x = NORMALIZE_RE.sub(r"\1 \2", x or '')
13    return x.replace("\n", "").replace("\t", "")
14
15def fix_tree(tag, lvl=''):
16    if tag.tag.count("XInclude"):
17        tag.tag = 'include'
18
19    #print("%s<%s>%r" % (lvl, tag.tag, [tag.text, normalize(tag.text)]))
20
21    for subtag in tag:
22        fix_tree(subtag, lvl + "  ")
23
24    #print("%s</%s>%r" % (lvl, tag.tag, [tag.tail, normalize(tag.tail)]))
25
26    tag.text = normalize(tag.text)
27    tag.tail = normalize(tag.tail)
28
29def parse_file(filename, parent=None):
30    tree = ET.parse(open(filename)).getroot()
31    fix_tree(tree)
32    return parse_tag(tree, parent)
33
34def parse_tag(tag, parent):
35    fun = globals()["tag_%s" % tag.tag.replace("-", "_")]
36    return join(fun(tag, parent))
37
38def parse_subtags(tag, parent=None):
39    yield tag.text
40
41    for subtag in tag:
42        yield parse_tag(subtag, tag)
43
44    yield tag.tail
45
46def handle_subject(tag, parent):
47    yield '?%s\n' % tag.attrib['id']
48
49    first = True
50    for element in tag:
51        if element.tag in ["para", "variablelist", "simplelist",
52                           "command-list", "ircexample"]:
53            if not first:
54                yield "\n"
55            first = False
56
57            if element.attrib.get('title', ''):
58                yield element.attrib['title']
59                yield "\n"
60            yield join(parse_tag(element, tag)).rstrip("\n")
61            yield "\n"
62
63    yield "%\n"
64
65    for element in tag:
66        if element.tag in ["sect1", "sect2"]:
67            yield join(handle_subject(element, tag))
68
69    for element in tag.findall("bitlbee-command"):
70        yield join(handle_command(element))
71
72    for element in tag.findall("bitlbee-setting"):
73        yield join(handle_setting(element))
74
75def handle_command(tag, prefix=''):
76    this_cmd = prefix + tag.attrib['name']
77
78    yield "?%s\n" % this_cmd
79    for syntax in tag.findall("syntax"):
80        yield '\x02Syntax:\x02 %s\n' % syntax.text
81
82    yield "\n"
83    yield join(parse_subtags(tag.find("description"))).rstrip()
84    yield "\n"
85
86    for example in tag.findall("ircexample"):
87        yield "\n\x02Example:\x02\n"
88        yield join(parse_subtags(example)).rstrip()
89        yield "\n"
90
91    yield "%\n"
92
93    for element in tag.findall("bitlbee-command"):
94        yield join(handle_command(element, this_cmd + " "))
95
96def handle_setting(tag):
97    yield "?set %s\n" % tag.attrib['name']
98    yield "\x02Type:\x02 %s\n" % tag.attrib["type"]
99    yield "\x02Scope:\x02 %s\n" % tag.attrib["scope"]
100
101    if tag.find("default") is not None:
102        yield "\x02Default:\x02 %s\n" % tag.findtext("default")
103
104    if tag.find("possible-values") is not None:
105        yield "\x02Possible Values:\x02 %s\n" % tag.findtext("possible-values")
106
107    yield "\n"
108    yield join(parse_subtags(tag.find("description"))).rstrip()
109    yield "\n%\n"
110
111tag_preface = handle_subject
112tag_chapter = handle_subject
113tag_sect1 = handle_subject
114tag_sect2 = handle_subject
115
116tag_ulink = parse_subtags
117tag_note = parse_subtags
118tag_book = parse_subtags
119tag_ircexample = parse_subtags
120
121def tag_include(tag, parent):
122    return parse_file(tag.attrib['href'], tag)
123
124def tag_para(tag, parent):
125    return join(parse_subtags(tag)) + "\n\n"
126
127def tag_emphasis(tag, parent):
128    return "\x02%s\x02%s" % (tag.text, tag.tail)
129
130def tag_ircline(tag, parent):
131    return "\x02<%s>\x02 %s\n" % (tag.attrib['nick'], join(parse_subtags(tag)))
132
133def tag_ircaction(tag, parent):
134    return "\x02* %s\x02 %s\n" % (tag.attrib['nick'], join(parse_subtags(tag)))
135
136def tag_command_list(tag, parent):
137    yield "These are all root commands. See \x02help <command name>\x02 " \
138          "for more details on each command.\n\n"
139
140    for subtag in parent.findall("bitlbee-command"):
141        yield " * \x02%s\x02 - %s\n" % \
142            (subtag.attrib['name'],
143             subtag.findtext("short-description"))
144
145    yield "\nMost commands can be shortened. For example instead of " \
146          "\x02account list\x02, try \x02ac l\x02.\n\n"
147
148def tag_variablelist(tag, parent):
149    for subtag in tag:
150        yield " \x02%s\x02 - %s\n" % \
151            (subtag.findtext("term"),
152             join(parse_subtags(subtag.find("listitem/para"))))
153    yield '\n'
154
155def tag_simplelist(tag, parent):
156    for subtag in tag:
157        yield " - %s\n" % join(parse_subtags(subtag))
158    yield '\n'
159
160def main():
161    txt = parse_file(IN_FILE)
162    open(OUT_FILE, "w").write(txt)
163
164if __name__ == '__main__':
165    main()
Note: See TracBrowser for help on using the repository browser.