summaryrefslogtreecommitdiff
path: root/doc/xml2texi.rb
blob: d36919628dba3572351ffedbb72d50ca82cbb6ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#!/usr/local/bin/ruby -w

if ! ARGV[0]
 print <<USAGE
Usage: xml2texi.rb xml-file

The texinfo for function documentation found in xml-file
is dumped to stdout.
USAGE
exit 0
end

$\ = "\n"

require "rexml/document"
include REXML

# Utility functions

def printPara(p)
  if p.name != "para"
    raise "printPara: " + p.name + " not a paragraph!\n"
  end

  p.each do |c|
    if c.kind_of? Text
      print c
    else
      if c.name == "parameterlist"
        # print "!! skipping parameterlist"
      else
        print "\n!! Unknown element type: ", c.name, "\n"
      end
    end
  end
  print "\n"
  print "\n"
end

# Open the document, compress whitespace.

doc = Document.new File.new(ARGV[0]), { :compress_whitespace => :all }

# <?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>
# <doxygen version="1.2.15-20020430">
#   <compounddef id="smtp_8c" kind="file">
# 	-- ...

#print "doc.whitespace: ", doc.whitespace
#print "doc.version: ", doc.version
#print "doc.encoding: ", doc.encoding
#print "doc.standalone: ", doc.standalone?


# Input:
#
#       <sectiondef kind="func">
#       <memberdef kind="function" id="smtp_8c_1a7" virt="normal" prot="public" const="no" volatile="no">
#         <type>int</type>
#         <name>smtp_open</name>
#         <param>
#           <type>mailer_t</type>
#           <defname>mailer</defname>
#         </param>
#         <param>
#           <type>int</type>
#           <defname>flags</defname>
#         </param>
#         <briefdescription>
# <para>Open an SMTP mailer. </para>
#         </briefdescription>
#         <detaileddescription>
# <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>
# </parameterdescription><parametername>flags</parametername><parameterdescription><para>the mailer flags </para>
# </parameterdescription></parameterlist></para>
#         </detaileddescription>
#         <location file="/home/sam/p/gnu/mailutils/mailbox/smtp.c" line="223" bodystart="289" bodyend="434"/>
#       </memberdef>

# - Why do I always get XML, even for undocumented functions and macros?
# - Why is # there no markup that I can use to determine that the function
# was undocumented?
# - Why sometimes declname, sometimes defname, in param?
# - why is the  parameter list jammed into the last paragraph of the
# detailed description?
# - Why is there always a detailed description, even when there isn't?
# - Why the duplication beteen the beginning list of <param> (which is
# lacking the <parameterdescription>, and the <parameterlist>?
# - Why is parameterlist just an alternating list of names and descriptions,
# with no markup to bind a name to a description?

# Overall: this appears to be half visual markup, and half logical. If
# it was entirely visual, there would be the one-line summary of the
# documented functions, followed by the details.
# If it was entirely markup, then the
# parameter info wouldn't be split into two different locations.



# Output:
# 
# @deftypefun int smtp_open (
#   mailer_t @var{mailer},
#   int @var{flags})
# Open an SMTP mailer.
# An SMTP mailer must be opened before any messages can be sent.
# 
# Parameters:
# @itemize
# @item @code{mailer} - the mailer created by smtp_create()
# @item @code{flags} - the mailer flags
# @end itemize
# @end deftypefun


doc.elements.each("*/*/sectiondef[@kind='func']") { |e|
  print "section: ", e.name, "/", e.attributes["kind"]

  e.elements.each("memberdef") { |m|
    # If there is no brief description, don't document this member.
		next unless m.elements["briefdescription"].elements["para"]

    $\ = ""
    print "@deftypefun "
    if m.elements["type"].text
        print m.elements["type"].text, " "
    else
        print "int "
    end

    print m.elements["name"].text, " (\n  "

    first = true

    m.elements.each("param") { |p|
      if(first)
        first = false
      else
        print ",\n  "
      end

      p.elements["type"].each { |c|
        if c.kind_of? Text
          print c, " "
        else
          c.each { |c2|
            if c2.kind_of? Text
              print c2, " "
            end
          }
        end
      }
      name = p.elements["declname"];
			if ! name
        name = p.elements["defname"];
			end
      if name
        print "@var{", name.text, "}"
      end
    }
    print ")\n"

		print m.elements["briefdescription"].elements["para"].text

    dd = m.elements["detaileddescription"]

    if dd
      print "\n"
      dd.each do |dde|
        if dde.kind_of? Text
          # Top level Text is empty.
        else
          # We should have a string of "para" elements, the last of which
          # has the parameter list.
          printPara dde
        end
      end

      print "Parameters:\n"
      print "@itemize\n"

      dd.elements.each("*/parameterlist/*") do |pl|
        if pl.name == "title"
          # ignore
        elsif pl.name  == "parametername"
          print "@item @code{", pl.text, "}"
        elsif pl.name  == "parameterdescription"
          if pl.elements["para"]
            print " - ", pl.elements["para"].text, "\n"
          end
        end
      end

      print "@end itemize\n"

    end

    print "@end deftypefun\n"
    print "\n"
  }
}

Return to:

Send suggestions and report system problems to the System administrator.