Commit 94abb6c5 94abb6c53288c539cbc827c6fea15a8046d8a2e5 by Sam Roberts

Converts doxygen XML output to texinfo function documentation.

1 parent e0efc54b
1 #!/usr/local/bin/ruby -w
2
3 if ! ARGV[0]
4 print <<USAGE
5 Usage: xml2texi.rb xml-file
6
7 The texinfo for function documentation found in xml-file
8 is dumped to stdout.
9 USAGE
10 exit 0
11 end
12
13 $\ = "\n"
14
15 require "rexml/document"
16 include REXML
17
18 # Utility functions
19
20 def printPara(p)
21 if p.name != "para"
22 raise "printPara: " + p.name + " not a paragraph!\n"
23 end
24
25 p.each do |c|
26 if c.kind_of? Text
27 print c
28 else
29 if c.name == "parameterlist"
30 # print "!! skipping parameterlist"
31 else
32 print "\n!! Unknown element type: ", c.name, "\n"
33 end
34 end
35 end
36 print "\n"
37 print "\n"
38 end
39
40 # Open the document, compress whitespace.
41
42 doc = Document.new File.new(ARGV[0]), { :compress_whitespace => :all }
43
44 # <?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>
45 # <doxygen version="1.2.15-20020430">
46 # <compounddef id="smtp_8c" kind="file">
47 # -- ...
48
49 #print "doc.whitespace: ", doc.whitespace
50 #print "doc.version: ", doc.version
51 #print "doc.encoding: ", doc.encoding
52 #print "doc.standalone: ", doc.standalone?
53
54
55 # Input:
56 #
57 # <sectiondef kind="func">
58 # <memberdef kind="function" id="smtp_8c_1a7" virt="normal" prot="public" const="no" volatile="no">
59 # <type>int</type>
60 # <name>smtp_open</name>
61 # <param>
62 # <type>mailer_t</type>
63 # <defname>mailer</defname>
64 # </param>
65 # <param>
66 # <type>int</type>
67 # <defname>flags</defname>
68 # </param>
69 # <briefdescription>
70 # <para>Open an SMTP mailer. </para>
71 # </briefdescription>
72 # <detaileddescription>
73 # <para>An SMTP mailer must be opened before any messages can be sent. <parameterlist kind="param"><title>Parameters: </title><parametername>mailer</parametername><parameterdescription><para>the mailer created by smtp_create() </para>
74 # </parameterdescription><parametername>flags</parametername><parameterdescription><para>the mailer flags </para>
75 # </parameterdescription></parameterlist></para>
76 # </detaileddescription>
77 # <location file="/home/sam/p/gnu/mailutils/mailbox/smtp.c" line="223" bodystart="289" bodyend="434"/>
78 # </memberdef>
79
80 # - Why do I always get XML, even for undocumented functions and macros?
81 # - Why is # there no markup that I can use to determine that the function
82 # was undocumented?
83 # - Why sometimes declname, sometimes defname, in param?
84 # - why is the parameter list jammed into the last paragraph of the
85 # detailed description?
86 # - Why is there always a detailed description, even when there isn't?
87 # - Why the duplication beteen the beginning list of <param> (which is
88 # lacking the <parameterdescription>, and the <parameterlist>?
89 # - Why is parameterlist just an alternating list of names and descriptions,
90 # with no markup to bind a name to a description?
91
92 # Overall: this appears to be half visual markup, and half logical. If
93 # it was entirely visual, there would be the one-line summary of the
94 # documented functions, followed by the details.
95 # If it was entirely markup, then the
96 # parameter info wouldn't be split into two different locations.
97
98
99
100 # Output:
101 #
102 # @deftypefun int smtp_open (
103 # mailer_t @var{mailer},
104 # int @var{flags})
105 # Open an SMTP mailer.
106 # An SMTP mailer must be opened before any messages can be sent.
107 #
108 # Parameters:
109 # @itemize
110 # @item @code{mailer} - the mailer created by smtp_create()
111 # @item @code{flags} - the mailer flags
112 # @end itemize
113 # @end deftypefun
114
115
116 doc.elements.each("*/*/sectiondef[@kind='func']") { |e|
117 print "section: ", e.name, "/", e.attributes["kind"]
118
119 e.elements.each("memberdef") { |m|
120 # If there is no brief description, don't document this member.
121 next unless m.elements["briefdescription"].elements["para"]
122
123 $\ = ""
124 print "@deftypefun "
125 if m.elements["type"].text
126 print m.elements["type"].text, " "
127 else
128 print "int "
129 end
130
131 print m.elements["name"].text, " (\n "
132
133 first = true
134
135 m.elements.each("param") { |p|
136 if(first)
137 first = false
138 else
139 print ",\n "
140 end
141
142 p.elements["type"].each { |c|
143 if c.kind_of? Text
144 print c, " "
145 else
146 c.each { |c2|
147 if c2.kind_of? Text
148 print c2, " "
149 end
150 }
151 end
152 }
153 name = p.elements["declname"];
154 if ! name
155 name = p.elements["defname"];
156 end
157 if name
158 print "@var{", name.text, "}"
159 end
160 }
161 print ")\n"
162
163 print m.elements["briefdescription"].elements["para"].text
164
165 dd = m.elements["detaileddescription"]
166
167 if dd
168 print "\n"
169 dd.each do |dde|
170 if dde.kind_of? Text
171 # Top level Text is empty.
172 else
173 # We should have a string of "para" elements, the last of which
174 # has the parameter list.
175 printPara dde
176 end
177 end
178
179 print "Parameters:\n"
180 print "@itemize\n"
181
182 dd.elements.each("*/parameterlist/*") do |pl|
183 if pl.name == "title"
184 # ignore
185 elsif pl.name == "parametername"
186 print "@item @code{", pl.text, "}"
187 elsif pl.name == "parameterdescription"
188 if pl.elements["para"]
189 print " - ", pl.elements["para"].text, "\n"
190 end
191 end
192 end
193
194 print "@end itemize\n"
195
196 end
197
198 print "@end deftypefun\n"
199 print "\n"
200 }
201 }
202