1
2
3
4
5
6
7
8
9 """
10 Epydoc parser for U{Javadoc<http://java.sun.com/j2se/javadoc/>}
11 docstrings. Javadoc is an HTML-based markup language that was
12 developed for documenting Java APIs with inline comments. It consists
13 of raw HTML, augmented by Javadoc tags. There are two types of
14 Javadoc tag:
15
16 - X{Javadoc block tags} correspond to Epydoc fields. They are
17 marked by starting a line with a string of the form \"C{@M{tag}
18 [M{arg}]}\", where C{M{tag}} indicates the type of block, and
19 C{M{arg}} is an optional argument. (For fields that take
20 arguments, Javadoc assumes that the single word immediately
21 following the tag is an argument; multi-word arguments cannot be
22 used with javadoc.)
23
24 - X{inline Javadoc tags} are used for inline markup. In particular,
25 epydoc uses them for crossreference links between documentation.
26 Inline tags may appear anywhere in the text, and have the form
27 \"C{{@M{tag} M{[args...]}}}\", where C{M{tag}} indicates the
28 type of inline markup, and C{M{args}} are optional arguments.
29
30 Epydoc supports all Javadoc tags, I{except}:
31 - C{{@docRoot}}, which gives the (relative) URL of the generated
32 documentation's root.
33 - C{{@inheritDoc}}, which copies the documentation of the nearest
34 overridden object. This can be used to combine the documentation
35 of the overridden object with the documentation of the
36 overridding object.
37 - C{@serial}, C{@serialField}, and C{@serialData} which describe the
38 serialization (pickling) of an object.
39 - C{{@value}}, which copies the value of a constant.
40
41 @warning: Epydoc only supports HTML output for Javadoc docstrings.
42 """
43 __docformat__ = 'epytext en'
44
45
46 import re
47 from xml.dom.minidom import *
48 from epydoc.markup import *
49
51 """
52 Parse the given docstring, which is formatted using Javadoc; and
53 return a C{ParsedDocstring} representation of its contents.
54 @param docstring: The docstring to parse
55 @type docstring: C{string}
56 @param errors: A list where any errors generated during parsing
57 will be stored.
58 @type errors: C{list} of L{ParseError}
59 @param options: Extra options. Unknown options are ignored.
60 Currently, no extra options are defined.
61 @rtype: L{ParsedDocstring}
62 """
63 return ParsedJavadocDocstring(docstring, errors)
64
66 """
67 An encoded version of a Javadoc docstring. Since Javadoc is a
68 fairly simple markup language, we don't do any processing in
69 advance; instead, we wait to split fields or resolve
70 crossreference links until we need to.
71
72 @group Field Splitting: split_fields, _ARG_FIELDS, _FIELD_RE
73 @cvar _ARG_FIELDS: A list of the fields that take arguments.
74 Since Javadoc doesn't mark arguments in any special way, we
75 must consult this list to decide whether the first word of a
76 field is an argument or not.
77 @cvar _FIELD_RE: A regular expression used to search for Javadoc
78 block tags.
79
80 @group HTML Output: to_html, _LINK_SPLIT_RE, _LINK_RE
81 @cvar _LINK_SPLIT_RE: A regular expression used to search for
82 Javadoc inline tags.
83 @cvar _LINK_RE: A regular expression used to process Javadoc
84 inline tags.
85 """
86 - def __init__(self, docstring, errors=None):
87 """
88 Create a new C{ParsedJavadocDocstring}.
89
90 @param docstring: The docstring that should be used to
91 construct this C{ParsedJavadocDocstring}.
92 @type docstring: C{string}
93 @param errors: A list where any errors generated during
94 parsing will be stored. If no list is given, then
95 all errors are ignored.
96 @type errors: C{list} of L{ParseError}
97 """
98 self._docstring = docstring
99 if errors is None: errors = []
100 self._check_links(errors)
101
102
103
104
105
106 _ARG_FIELDS = ('group variable var type cvariable cvar ivariable '+
107 'ivar param '+
108 'parameter arg argument raise raises exception '+
109 'except deffield newfield keyword kwarg kwparam').split()
110 _FIELD_RE = re.compile(r'(^\s*\@\w+[\s$])', re.MULTILINE)
111
112
150
151
152
153
154
155 _LINK_SPLIT_RE = re.compile(r'({@link(?:plain)?\s[^}]+})')
156 _LINK_RE = re.compile(r'{@link(?:plain)?\s+' + r'([\w#.]+)' +
157 r'(?:\([^\)]*\))?' + r'(\s+.*)?' + r'}')
158
159
160 - def to_html(self, docstring_linker, **options):
161
162
163 pieces = self._LINK_SPLIT_RE.split(self._docstring)
164
165
166 translate_xref = docstring_linker.translate_identifier_xref
167
168
169
170
171
172 html = ''
173 for i in range(len(pieces)):
174 if i%2 == 0:
175 html += pieces[i]
176 else:
177
178 m = self._LINK_RE.match(pieces[i])
179 if m is None: continue
180 (target, name) = m.groups()
181
182
183 if target[0] == '#': target = target[1:]
184 target = target.replace('#', '.')
185 target = re.sub(r'\(.*\)', '', target)
186
187
188 if name is None: name = target
189 else: name = name.strip()
190
191
192 html += translate_xref(target, name)
193 return html
194
196 """
197 Make sure that all @{link}s are valid. We need a separate
198 method for ths because we want to do this at parse time, not
199 html output time. Any errors found are appended to C{errors}.
200 """
201 pieces = self._LINK_SPLIT_RE.split(self._docstring)
202 linenum = 0
203 for i in range(len(pieces)):
204 if i%2 == 1 and not self._LINK_RE.match(pieces[i]):
205 estr = 'Bad link %r' % pieces[i]
206 errors.append(ParseError(estr, linenum, is_fatal=0))
207 linenum += pieces[i].count('\n')
208
209
210
211
212
213
214
215 - def to_plaintext(self, docstring_linker, **options):
216 return self._docstring
217
218
226
227
228
229
230
231