Converts doxygen XML output to texinfo function documentation.
Showing
1 changed file
with
202 additions
and
0 deletions
doc/xml2texi.rb
0 → 100755
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 |
-
Please register or sign in to post a comment