From 0c5ba9a93f27023f76c2766fefdd829a8398d0d9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 9 Jun 2020 02:00:27 +0200 Subject: [PATCH] documentation/doxygen: add an ability to run filters on code. Finally I'm able to generate Magnum docs without a hastily patched m.css to convert color literals to color swatches. Ugh this took ages. --- doc/documentation/doxygen.rst | 17 +++++++--- documentation/doxygen.py | 11 +++++++ documentation/test_doxygen/__init__.py | 4 +-- .../contents_code_filters/Doxyfile | 14 ++++++++ .../contents_code_filters/index.html | 33 +++++++++++++++++++ .../contents_code_filters/input.dox | 14 ++++++++ documentation/test_doxygen/test_contents.py | 18 ++++++++++ documentation/test_doxygen/test_doxyfile.py | 2 ++ 8 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 documentation/test_doxygen/contents_code_filters/Doxyfile create mode 100644 documentation/test_doxygen/contents_code_filters/index.html create mode 100644 documentation/test_doxygen/contents_code_filters/input.dox diff --git a/doc/documentation/doxygen.rst b/doc/documentation/doxygen.rst index 7329c876..166d5ca9 100644 --- a/doc/documentation/doxygen.rst +++ b/doc/documentation/doxygen.rst @@ -413,10 +413,19 @@ Variable Description for more information. :py:`M_MATH_CACHE_FILE` File to cache rendered math formulas. If not set, ``m.math.cache`` file in the - output directory is used. Old cached output - is periodically pruned and new formulas - added to the file. Set it empty to disable - caching. + output directory is used. Equivalent to an + option of the same name in the + `m.math plugin <{filename}/plugins/math-and-code.rst#math>`. +:py:`M_CODE_FILTERS_PRE: Dict` Filters to apply before a code snippet is + rendered. Equivalent to an option of the + same name in the `m.code plugin <{filename}/plugins/math-and-code.rst#filters>`. + Note that due to the limitations of Doxygen + markup, named filters are not supported. +:py:`M_CODE_FILTERS_POST: Dict` Filters to apply after a code snippet is + rendered. Equivalent to an option of the + same name in the `m.code plugin <{filename}/plugins/math-and-code.rst#filters>`. + Note that due to the limitations of Doxygen + markup, named filters are not supported. =================================== =========================================== Note that namespace, directory and page lists are always fully expanded as diff --git a/documentation/doxygen.py b/documentation/doxygen.py index 4e82f243..e8b44c24 100755 --- a/documentation/doxygen.py +++ b/documentation/doxygen.py @@ -120,6 +120,8 @@ default_config = { 'CLASS_INDEX_EXPAND_INNER': False, 'M_MATH_CACHE_FILE': 'm.math.cache', + 'M_CODE_FILTERS_PRE': {}, + 'M_CODE_FILTERS_POST': {}, 'SEARCH_DISABLED': False, 'SEARCH_DOWNLOAD_BINARY': False, @@ -1240,10 +1242,19 @@ def parse_desc_internal(state: State, element: ET.Element, immediate_parent: ET. else: formatter = HtmlFormatter(nowrap=True) + # Apply a global pre filter, if any + filter = state.config['M_CODE_FILTERS_PRE'].get(lexer.name) + if filter: code = filter(code) + highlighted = highlight(code, lexer, formatter).rstrip() # Strip whitespace around if inline code, strip only trailing # whitespace if a block if not code_block: highlighted = highlighted.lstrip() + + # Apply a global post filter, if any + filter = state.config['M_CODE_FILTERS_POST'].get(lexer.name) + if filter: highlighted = filter(highlighted) + out.parsed += '<{0} class="{1}{2}">{3}'.format( 'pre' if code_block else 'code', class_, diff --git a/documentation/test_doxygen/__init__.py b/documentation/test_doxygen/__init__.py index 7b94f1d4..f4d8724a 100644 --- a/documentation/test_doxygen/__init__.py +++ b/documentation/test_doxygen/__init__.py @@ -66,8 +66,8 @@ class BaseTestCase(unittest.TestCase): def setUp(self): if os.path.exists(os.path.join(self.path, 'html')): shutil.rmtree(os.path.join(self.path, 'html')) - def run_doxygen(self, templates=default_templates, wildcard=default_wildcard, index_pages=default_index_pages): - state = State(copy.deepcopy(default_config)) + def run_doxygen(self, templates=default_templates, wildcard=default_wildcard, index_pages=default_index_pages, config={}): + state = State({**copy.deepcopy(default_config), **config}) parse_doxyfile(state, os.path.join(self.path, 'Doxyfile')) run(state, templates=templates, wildcard=wildcard, index_pages=index_pages, sort_globbed_files=True) diff --git a/documentation/test_doxygen/contents_code_filters/Doxyfile b/documentation/test_doxygen/contents_code_filters/Doxyfile new file mode 100644 index 00000000..07979766 --- /dev/null +++ b/documentation/test_doxygen/contents_code_filters/Doxyfile @@ -0,0 +1,14 @@ +INPUT = input.dox +QUIET = YES +GENERATE_HTML = NO +GENERATE_LATEX = NO +GENERATE_XML = YES +XML_PROGRAMLISTING = NO +CASE_SENSE_NAMES = YES + +##! M_PAGE_FINE_PRINT = +##! M_THEME_COLOR = +##! M_FAVICON = +##! M_LINKS_NAVBAR1 = +##! M_LINKS_NAVBAR2 = +##! M_SEARCH_DISABLED = YES diff --git a/documentation/test_doxygen/contents_code_filters/index.html b/documentation/test_doxygen/contents_code_filters/index.html new file mode 100644 index 00000000..c8d5dc86 --- /dev/null +++ b/documentation/test_doxygen/contents_code_filters/index.html @@ -0,0 +1,33 @@ + + + + + My Project + + + + + +
+
+
+
+
+

+ My Project +

+

Adding typographically correct spaces before and a color swatch after — and for inline as well: p { color: #ff3366; }

p {
+    color: #ff3366;
+}
+
+
+
+
+ + diff --git a/documentation/test_doxygen/contents_code_filters/input.dox b/documentation/test_doxygen/contents_code_filters/input.dox new file mode 100644 index 00000000..deb634e1 --- /dev/null +++ b/documentation/test_doxygen/contents_code_filters/input.dox @@ -0,0 +1,14 @@ +/** @mainpage + +Adding typographically correct spaces before and a color swatch after --- and +for inline as well: @code{.css} p{ color:#ff3366; } @endcode + +@code{.css} + + p{ + color:#ff3366; + } + +@endcode + +*/ diff --git a/documentation/test_doxygen/test_contents.py b/documentation/test_doxygen/test_contents.py index ffaf3a1d..df658017 100644 --- a/documentation/test_doxygen/test_contents.py +++ b/documentation/test_doxygen/test_contents.py @@ -359,3 +359,21 @@ class Htmlinclude(IntegrationTestCase): def test_warnings(self): self.run_doxygen(wildcard='warnings.xml') self.assertEqual(*self.actual_expected_contents('warnings.html')) + +_css_colors_src = re.compile(r"""#(?P[0-9a-f]{6})""") +_css_colors_dst = r"""#\g""" + +def _add_color_swatch(str): + return _css_colors_src.sub(_css_colors_dst, str) + +class CodeFilters(IntegrationTestCase): + def test(self): + self.run_doxygen(wildcard='indexpage.xml', config={ + 'M_CODE_FILTERS_PRE': { + 'CSS': lambda str: str.replace(':', ': ').replace('{', ' {'), + }, + 'M_CODE_FILTERS_POST': { + 'CSS': _add_color_swatch, + } + }) + self.assertEqual(*self.actual_expected_contents('index.html')) diff --git a/documentation/test_doxygen/test_doxyfile.py b/documentation/test_doxygen/test_doxyfile.py index 62c6d00f..252798b6 100644 --- a/documentation/test_doxygen/test_doxyfile.py +++ b/documentation/test_doxygen/test_doxyfile.py @@ -70,6 +70,8 @@ class Doxyfile(unittest.TestCase): 'CLASS_INDEX_EXPAND_INNER': False, 'FILE_INDEX_EXPAND_LEVELS': 1, + 'M_CODE_FILTERS_PRE': {}, + 'M_CODE_FILTERS_POST': {}, 'M_MATH_CACHE_FILE': 'm.math.cache', 'SEARCH_DISABLED': False, -- 2.30.2