paragraph_count = 0
has_block_elements = False
+ # So we are able to merge content of adjacent sections. Tuple of (tag,
+ # kind), set only if there is no i.tail, reset in the next iteration.
+ previous_section = None
+
i: ET.Element
for i in element:
# State used later
code_block = None
formula_block = None
+ # A section was left open, but there's nothing to continue it, close
+ # it. Expect that there was nothing after that would mess with us.
+ if previous_section and i.tag != 'simplesect':
+ previous_section = None
+ assert not out.write_paragraph_close_tag
+ out.parsed = out.parsed.rstrip() + '</aside>'
+
# DOXYGEN <PARA> PATCHING 2/4
#
# Upon encountering a block element nested in <para>, we need to act.
out.return_value = parse_desc(state, i)
else:
has_block_elements = True
- if i.attrib['kind'] == 'see':
- out.parsed += '<aside class="m-note m-default"><h4>See also</h4>'
- elif i.attrib['kind'] == 'note':
- out.parsed += '<aside class="m-note m-info"><h4>Note</h4>'
- elif i.attrib['kind'] == 'attention':
- out.parsed += '<aside class="m-note m-warning"><h4>Attention</h4>'
- else: # pragma: no cover
- out.parsed += '<aside class="m-note">'
- logging.warning("ignoring {} kind of <simplesect>".format(i.attrib['kind']))
+
+ # There was a section open, but it differs from this one, close
+ # it
+ if previous_section and previous_section != i.attrib['kind']:
+ out.parsed = out.parsed.rstrip() + '</aside>'
+
+ # Not continuing with a section from before, put a header in
+ if not previous_section or previous_section != i.attrib['kind']:
+ if i.attrib['kind'] == 'see':
+ out.parsed += '<aside class="m-note m-default"><h4>See also</h4>'
+ elif i.attrib['kind'] == 'note':
+ out.parsed += '<aside class="m-note m-info"><h4>Note</h4>'
+ elif i.attrib['kind'] == 'attention':
+ out.parsed += '<aside class="m-note m-warning"><h4>Attention</h4>'
+ else: # pragma: no cover
+ out.parsed += '<aside class="m-note">'
+ logging.warning("ignoring {} kind of <simplesect>".format(i.attrib['kind']))
+
out.parsed += parse_desc(state, i)
- out.parsed += '</aside>'
+
+ # There's something after, close it
+ if i.tail and i.tail.strip():
+ out.parsed += '</aside>'
+ previous_section = None
+
+ # Otherwise put the responsibility on the next iteration, maybe
+ # there are more paragraphs that should be merged
+ else:
+ previous_section = i.attrib['kind']
elif i.tag == 'xrefsect':
assert element.tag == 'para' # is inside a paragraph :/
has_block_elements = True
+ # Not merging these, as every has usually a different ID each. (And
+ # apparently Doxygen is able to merge them *but only if* they
+ # describe some symbol, not on a page.)
id = i.attrib['id']
match = xref_id_rx.match(id)
file = match.group(1)
tail = tail.lstrip()
out.parsed += tail
+ # A section was left open in the last iteration, close it. Expect that
+ # there was nothing after that would mess with us.
+ if previous_section:
+ assert not out.write_paragraph_close_tag
+ out.parsed = out.parsed.rstrip() + '</aside>'
+
# Brief description always needs to be single paragraph because we're
# sending it out without enclosing <p>.
if element.tag == 'briefdescription':
-INPUT = input.dox
+INPUT = input.dox File.h
QUIET = YES
GENERATE_HTML = NO
GENERATE_LATEX = NO
--- /dev/null
+/** @file
+ * @brief A file
+ */
+
+/**
+@brief A foo
+
+@xrefitem old "Old stuff" "Just old" Xrefitem, gets merged
+@xrefitem old "Old stuff" "Just old" with this one by Doxygen itself.
+*/
+int foo();
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>File.h file | My Project</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+ <link rel="stylesheet" href="m-dark+doxygen.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta name="theme-color" content="#22272e" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="index.html" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">My Project</a>
+ <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+ <div class="m-row">
+ <ol class="m-col-t-6 m-col-m-none">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="namespaces.html">Namespaces</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="3">
+ <li><a href="annotated.html">Classes</a></li>
+ <li><a href="files.html" id="m-navbar-current">Files</a></li>
+ </ol>
+ </div>
+ </div>
+ </div>
+ </div>
+</nav></header>
+<main><article>
+ <div class="m-container m-container-inflatable">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <h1>
+ File.h <span class="m-thin">file</span>
+ </h1>
+ <p>A file.</p>
+ <div class="m-block m-default">
+ <h3>Contents</h3>
+ <ul>
+ <li>
+ Reference
+ <ul>
+ <li><a href="#func-members">Functions</a></li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ <section id="func-members">
+ <h2><a href="#func-members">Functions</a></h3>
+ <dl class="m-dox">
+ <dt>
+ <span class="m-dox-wrap-bumper">auto <a href="#a14bcd2d544b22300bba3863251393e0f" class="m-dox">foo</a>(</span><span class="m-dox-wrap">) -> int</span>
+ </dt>
+ <dd>A foo.</dd>
+ </dl>
+ </section>
+ <section>
+ <h2>Function documentation</h2>
+ <section class="m-dox-details" id="a14bcd2d544b22300bba3863251393e0f"><div>
+ <h3>
+ <span class="m-dox-wrap-bumper">int </span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#a14bcd2d544b22300bba3863251393e0f" class="m-dox-self">foo</a>(</span><span class="m-dox-wrap">)</span></span>
+ </h3>
+ <p>A foo.</p>
+<aside class="m-note m-default"><h4><a href="old.html#_old000004" class="m-dox">Old stuff</a></h4><p>Xrefitem, gets merged</p><p>with this one by Doxygen itself.</p></aside>
+ </div></section>
+ </section>
+ </div>
+ </div>
+ </div>
+</article></main>
+<footer><nav>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <p>My Project. Created by <a href="http://doxygen.org/">Doxygen</a> and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+ </div>
+ </div>
+ </div>
+</nav></footer>
+</body>
+</html>
<h1>
My Project
</h1>
-<p>First paragraph containing some content.</p><aside class="m-note m-warning"><h4>Attention</h4><p>An attention section.</p></aside><aside class="m-note m-default"><h4>See also</h4><p>Other section.</p></aside><p>Paragraph following the sections.</p><aside class="m-note m-info"><h4>Note</h4><p>A note.</p></aside><aside class="m-note m-danger"><h4><a href="bug.html#_bug000001" class="m-dox">Bug</a></h4><p>This is a bug.</p></aside><aside class="m-note m-dim"><h4><a href="todo.html#_todo000001" class="m-dox">Todo</a></h4><p>Or a TODO.</p></aside><aside class="m-note m-danger"><h4><a href="deprecated.html#_deprecated000001" class="m-dox">Deprecated</a></h4><p>Which is deprecated.</p></aside><aside class="m-note m-default"><h4><a href="old.html#_old000001" class="m-dox">Old stuff</a></h4><p>This is old.</p></aside><blockquote><p>A blockquote</p></blockquote><p>Text right after that blockquote should be a new paragraph.</p><ul><li>A simple</li><li>List<ol><li>With one line</li><li>for each</li></ol></li><li>item, so paragraphs are removed</li></ul><ul><li>A simple</li><li>List<ol><li>With the sublist delimited</li><li>by blank lines</li></ol></li><li>should behave the same as above</li></ul><ul><li><p>A new list</p><p>of multiple</p><p>paragraphs.</p></li><li><p>Another item</p><ul><li><p>A sub list</p><p>Another paragraph</p></li></ul></li></ul><p>A paragraph after that list.</p><table class="m-table"><thead><tr><th>Table header</th><th>Another</th><th>Third</th></tr></thead><tbody><tr><td>Cell</td><td>Another cell</td><td>3rd</td></tr><tr><td>Next row</td><td></td><td>This</td></tr><tr><td>is a table</td><td><em>really</em></td><td>yes.</td></tr></tbody></table>
+<p>First paragraph containing some content.</p><aside class="m-note m-warning"><h4>Attention</h4><p>An attention section.</p></aside><aside class="m-note m-default"><h4>See also</h4><p>Other section.</p></aside><p>Paragraph following the sections.</p><aside class="m-note m-info"><h4>Note</h4><p>A note.</p></aside><aside class="m-note m-danger"><h4><a href="bug.html#_bug000001" class="m-dox">Bug</a></h4><p>This is a bug.</p></aside><aside class="m-note m-dim"><h4><a href="todo.html#_todo000001" class="m-dox">Todo</a></h4><p>Or a TODO.</p></aside><aside class="m-note m-danger"><h4><a href="deprecated.html#_deprecated000001" class="m-dox">Deprecated</a></h4><p>Which is deprecated.</p></aside><aside class="m-note m-default"><h4><a href="old.html#_old000001" class="m-dox">Old stuff</a></h4><p>This is old.</p></aside><blockquote><p>A blockquote</p></blockquote><p>Text right after that blockquote should be a new paragraph.</p><ul><li>A simple</li><li>List<ol><li>With one line</li><li>for each</li></ol></li><li>item, so paragraphs are removed</li></ul><ul><li>A simple</li><li>List<ol><li>With the sublist delimited</li><li>by blank lines</li></ol></li><li>should behave the same as above</li></ul><ul><li><p>A new list</p><p>of multiple</p><p>paragraphs.</p></li><li><p>Another item</p><ul><li><p>A sub list</p><p>Another paragraph</p></li></ul></li></ul><p>A paragraph after that list.</p><table class="m-table"><thead><tr><th>Table header</th><th>Another</th><th>Third</th></tr></thead><tbody><tr><td>Cell</td><td>Another cell</td><td>3rd</td></tr><tr><td>Next row</td><td></td><td>This</td></tr><tr><td>is a table</td><td><em>really</em></td><td>yes.</td></tr></tbody></table><aside class="m-note m-warning"><h4>Attention</h4><p>Attention, first paragraph.</p><p>Attention, second paragraph.</p><p>Attention, third paragraph.</p></aside><aside class="m-note m-info"><h4>Note</h4><p>A note, not merged with the above.</p></aside><aside class="m-note m-default"><h4><a href="old.html#_old000002" class="m-dox">Old stuff</a></h4><p>This is not merged.</p></aside><aside class="m-note m-default"><h4><a href="old.html#_old000003" class="m-dox">Old stuff</a></h4><p>With this. Only on the listing page.</p></aside>
</div>
</div>
</div>
Next row | | This
is a table | *really* | yes.
+@attention
+ Attention, first paragraph.
+@attention
+ Attention, second paragraph.
+@attention
+ Attention, third paragraph.
+@note
+ A note, not merged with the above.
+
+@xrefitem old "Old stuff" "Just old" This is not merged.
+
+@xrefitem old "Old stuff" "Just old" With this. Only on the listing page.
+
*/
/** @page other Other page
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Just old | My Project</title>
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
+ <link rel="stylesheet" href="m-dark+doxygen.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta name="theme-color" content="#22272e" />
+</head>
+<body>
+<header><nav id="navigation">
+ <div class="m-container">
+ <div class="m-row">
+ <a href="index.html" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">My Project</a>
+ <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+ <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+ <div class="m-row">
+ <ol class="m-col-t-6 m-col-m-none">
+ <li><a href="pages.html" id="m-navbar-current">Pages</a></li>
+ <li><a href="namespaces.html">Namespaces</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="3">
+ <li><a href="annotated.html">Classes</a></li>
+ <li><a href="files.html">Files</a></li>
+ </ol>
+ </div>
+ </div>
+ </div>
+ </div>
+</nav></header>
+<main><article>
+ <div class="m-container m-container-inflatable">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <h1>
+ Just old
+ </h1>
+<dl class="m-dox"><dt><a name="_old000004"></a>Member <a href="File_8h.html#a14bcd2d544b22300bba3863251393e0f" class="m-dox">foo</a> ()</dt><dd><p>Xrefitem, gets merged</p><p>with this one by Doxygen itself.</p></dd><dt><a name="_old000001"></a>page <a href="index.html" class="m-dox">Main Page</a></dt><dd><p>This is old.</p><p>This is not merged.</p><p>With this. Only on the listing page.</p></dd></dl>
+ </div>
+ </div>
+ </div>
+</article></main>
+<footer><nav>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-l-10 m-push-l-1">
+ <p>My Project. Created by <a href="http://doxygen.org/">Doxygen</a> and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+ </div>
+ </div>
+ </div>
+</nav></footer>
+</body>
+</html>
<span class="c1">// a block</span>
<span class="c1">// that is indented</span>
<span class="c1">// but has a lot of trailing whitespace which should be removed</span>
-<span class="p">}</span></pre><p>Code block inside a list (has to be done using HTML):</p><ul><li><p>A paragraph.</p><pre class="m-code"><span class="cp">#include</span> <span class="cpf"><os></span><span class="cp"></span></pre></li><li><p>Another paragraph.</p><p>Yet another</p></li><li>A single paragraph, rendered without the wrapping tag</li></ul>
+<span class="p">}</span></pre><p>Code block inside a list (has to be done using HTML):</p><ul><li><p>A paragraph.</p><pre class="m-code"><span class="cp">#include</span> <span class="cpf"><os></span><span class="cp"></span></pre></li><li><p>Another paragraph.</p><p>Yet another</p></li><li>A single paragraph, rendered without the wrapping tag</li></ul><aside class="m-note m-info"><h4>Note</h4><p>Code block inside a note:</p><pre class="m-code"><span class="c1">// code block</span></pre><p>Another paragraph of that note.</p></aside>
</div>
</div>
</div>
<li>A single paragraph, rendered without the wrapping tag</li>
</ul>
+@note
+ Code block inside a note:
+@note
+ @code{.cpp}
+ // code block
+ @endcode
+@note
+ Another paragraph of that note.
+
*/
/** @page warnings Code that produces warnings
self.run_dox2html5(wildcard='todo.xml')
self.assertEqual(*self.actual_expected_contents('todo.html'))
+ def test_builtin_xrefitem_merging(self):
+ # Multiple xrefitems should be merged into one here
+ self.run_dox2html5(wildcard='File_8h.xml')
+ self.run_dox2html5(wildcard='old.xml')
+ self.assertEqual(*self.actual_expected_contents('File_8h.html'))
+ self.assertEqual(*self.actual_expected_contents('old.html'))
+
class Code(IntegrationTestCase):
def __init__(self, *args, **kwargs):
super().__init__(__file__, 'code', *args, **kwargs)