From 3ba84dc8ca708a785dabdd26a7ba360f05c0e759 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 19 May 2018 10:29:16 +0200 Subject: [PATCH] doxygen: proper hierarchy for headings in non-top-level description. Also don't emit the \section warning for these, it does not make sense. --- doxygen/dox2html5.py | 46 ++++++++++---- .../contents_section_in_function/Doxyfile | 13 ++++ .../test/contents_section_in_function/File.h | 16 +++++ .../contents_section_in_function/File_8h.html | 61 +++++++++++++++++++ doxygen/test/test_contents.py | 8 +++ 5 files changed, 132 insertions(+), 12 deletions(-) create mode 100644 doxygen/test/contents_section_in_function/Doxyfile create mode 100644 doxygen/test/contents_section_in_function/File.h create mode 100644 doxygen/test/contents_section_in_function/File_8h.html diff --git a/doxygen/dox2html5.py b/doxygen/dox2html5.py index 5c3b78a9..5a03f8f1 100755 --- a/doxygen/dox2html5.py +++ b/doxygen/dox2html5.py @@ -356,6 +356,7 @@ class State: self.current = '' self.current_prefix = [] self.current_compound = None + self.parsing_toplevel_desc = False def slugify(text: str) -> str: # Maybe some Unicode normalization would be nice here? @@ -692,17 +693,36 @@ def parse_desc_internal(state: State, element: ET.Element, immediate_parent: ET. assert element.tag == 'para' # is inside a paragraph :/ has_block_elements = True - if i.attrib['level'] == '1': - tag = 'h2' - elif i.attrib['level'] == '2': - tag = 'h3' - elif i.attrib['level'] == '3': - tag = 'h4' - elif i.attrib['level'] == '4': - tag = 'h5' - else: # pragma: no cover - assert False - logging.warning("{}: prefer @section over Markdown heading for properly generated TOC".format(state.current)) + # Top-level description + if state.parsing_toplevel_desc: + if i.attrib['level'] == '1': + tag = 'h2' + elif i.attrib['level'] == '2': + tag = 'h3' + elif i.attrib['level'] == '3': + tag = 'h4' + elif i.attrib['level'] == '4': + tag = 'h5' + else: # pragma: no cover + assert False + + # Emit this warning only in top-level desc, TOC is not + # generated for function/enum/... descriptions + logging.warning("{}: prefer @section over Markdown heading for properly generated TOC".format(state.current)) + + # Function/enum/... descriptions are inside

for function + # header, which is inside

for detailed definition section, so + # it needs to be

and below + else: + if i.attrib['level'] == '1': + tag = 'h4' + elif i.attrib['level'] == '2': + tag = 'h5' + elif i.attrib['level'] in ['3', '4']: + tag = 'h6' # there is no + else: # pragma: no cover + assert False + out.parsed += '<{0}>{1}'.format(tag, html.escape(i.text)) elif i.tag == 'para': @@ -1344,8 +1364,10 @@ def parse_var_desc(state: State, element: ET.Element) -> str: return (parsed.parsed, parsed.search_keywords, parsed.is_deprecated) def parse_toplevel_desc(state: State, element: ET.Element): - # Verify that we didn't ignore any important info by accident + state.parsing_toplevel_desc = True parsed = parse_desc_internal(state, element) + state.parsing_toplevel_desc = False + # Verify that we didn't ignore any important info by accident assert not parsed.return_value and not parsed.return_values and not parsed.exceptions if parsed.params: logging.warning("{}: use @tparam instead of @param for documenting class templates, @param is ignored".format(state.current)) diff --git a/doxygen/test/contents_section_in_function/Doxyfile b/doxygen/test/contents_section_in_function/Doxyfile new file mode 100644 index 00000000..471f68b7 --- /dev/null +++ b/doxygen/test/contents_section_in_function/Doxyfile @@ -0,0 +1,13 @@ +INPUT = File.h +QUIET = YES +GENERATE_HTML = NO +GENERATE_LATEX = NO +GENERATE_XML = YES +XML_PROGRAMLISTING = NO + +M_PAGE_FINE_PRINT = +M_THEME_COLOR = +M_FAVICON = +M_LINKS_NAVBAR1 = +M_LINKS_NAVBAR2 = +M_SEARCH_DISABLED = YES diff --git a/doxygen/test/contents_section_in_function/File.h b/doxygen/test/contents_section_in_function/File.h new file mode 100644 index 00000000..1fb17128 --- /dev/null +++ b/doxygen/test/contents_section_in_function/File.h @@ -0,0 +1,16 @@ +/** @file + * @brief A file + */ + +/** +@brief A function + +# A top-level header + +## A second-level header + +### A third-level header + +#### A fourth-level header +*/ +void foo(); diff --git a/doxygen/test/contents_section_in_function/File_8h.html b/doxygen/test/contents_section_in_function/File_8h.html new file mode 100644 index 00000000..92a9f755 --- /dev/null +++ b/doxygen/test/contents_section_in_function/File_8h.html @@ -0,0 +1,61 @@ + + + + + File.h file | My Project + + + + + +
+
+
+
+
+

+ File.h file +

+

A file.

+
+

Contents

+ +
+
+

Functions

+
+
+ void foo() +
+
A function.
+
+
+
+

Function documentation

+
+

+ void foo() +

+

A function.

+

A top-level header

A second-level header
A third-level header
A fourth-level header
+
+
+
+
+
+
+ + diff --git a/doxygen/test/test_contents.py b/doxygen/test/test_contents.py index ac5b1d04..be1090e9 100644 --- a/doxygen/test/test_contents.py +++ b/doxygen/test/test_contents.py @@ -184,3 +184,11 @@ class SectionUnderscoreOne(IntegrationTestCase): def test(self): self.run_dox2html5(wildcard='indexpage.xml') self.assertEqual(*self.actual_expected_contents('index.html')) + +class SectionInFunction(IntegrationTestCase): + def __init__(self, *args, **kwargs): + super().__init__(__file__, 'section_in_function', *args, **kwargs) + + def test(self): + self.run_dox2html5(wildcard='File_8h.xml') + self.assertEqual(*self.actual_expected_contents('File_8h.html')) -- 2.30.2