chiark / gitweb /
Initial implementation of the Doxygen theme generator.
authorVladimír Vondruš <mosra@centrum.cz>
Sat, 18 Nov 2017 17:42:00 +0000 (18:42 +0100)
committerVladimír Vondruš <mosra@centrum.cz>
Thu, 7 Dec 2017 01:23:41 +0000 (02:23 +0100)
118 files changed:
css/m-dark+doxygen.compiled.css [new file with mode: 0644]
css/m-dark.doxygen.compiled.css [new file with mode: 0644]
css/m-doxygen.css [new file with mode: 0644]
css/m-light+doxygen.compiled.css [new file with mode: 0644]
css/m-light.doxygen.compiled.css [new file with mode: 0644]
doc/doxygen-test.rst [new file with mode: 0644]
doc/doxygen.rst [new file with mode: 0644]
doc/static/m-doxygen.css [new symlink]
doxygen/.gitignore [new file with mode: 0644]
doxygen/dox2html5.py [new file with mode: 0755]
doxygen/templates/.kateconfig [new file with mode: 0644]
doxygen/templates/annotated.html [new file with mode: 0644]
doxygen/templates/base-class-reference.html [new file with mode: 0644]
doxygen/templates/base-index.html [new file with mode: 0644]
doxygen/templates/base-reference.html [new file with mode: 0644]
doxygen/templates/base.html [new file with mode: 0644]
doxygen/templates/class.html [new file with mode: 0644]
doxygen/templates/details-define.html [new file with mode: 0644]
doxygen/templates/details-enum.html [new file with mode: 0644]
doxygen/templates/details-func.html [new file with mode: 0644]
doxygen/templates/details-typedef.html [new file with mode: 0644]
doxygen/templates/details-var.html [new file with mode: 0644]
doxygen/templates/dir.html [new file with mode: 0644]
doxygen/templates/entry-class.html [new file with mode: 0644]
doxygen/templates/entry-define.html [new file with mode: 0644]
doxygen/templates/entry-dir.html [new file with mode: 0644]
doxygen/templates/entry-enum.html [new file with mode: 0644]
doxygen/templates/entry-file.html [new file with mode: 0644]
doxygen/templates/entry-func.html [new file with mode: 0644]
doxygen/templates/entry-namespace.html [new file with mode: 0644]
doxygen/templates/entry-typedef.html [new file with mode: 0644]
doxygen/templates/entry-var.html [new file with mode: 0644]
doxygen/templates/example.html [new file with mode: 0644]
doxygen/templates/file.html [new file with mode: 0644]
doxygen/templates/files.html [new file with mode: 0644]
doxygen/templates/namespace.html [new file with mode: 0644]
doxygen/templates/namespaces.html [new file with mode: 0644]
doxygen/templates/page.html [new file with mode: 0644]
doxygen/templates/pages.html [new file with mode: 0644]
doxygen/templates/struct.html [new file with mode: 0644]
doxygen/templates/union.html [new file with mode: 0644]
doxygen/test/README.rst [new file with mode: 0644]
doxygen/test/__init__.py [new file with mode: 0644]
doxygen/test/compound_detailed/Doxyfile [new file with mode: 0644]
doxygen/test/compound_detailed/File.h [new file with mode: 0644]
doxygen/test/compound_detailed/File_8h.html [new file with mode: 0644]
doxygen/test/compound_detailed/namespaceEno.html [new file with mode: 0644]
doxygen/test/compound_detailed/namespaceFoo.html [new file with mode: 0644]
doxygen/test/compound_detailed/namespaceNamee.html [new file with mode: 0644]
doxygen/test/compound_detailed/namespaceType.html [new file with mode: 0644]
doxygen/test/compound_detailed/namespaceVar.html [new file with mode: 0644]
doxygen/test/compound_detailed/namespaceWarning.html [new file with mode: 0644]
doxygen/test/compound_detailed/structTemplate.html [new file with mode: 0644]
doxygen/test/compound_detailed/structTemplateWarning.html [new file with mode: 0644]
doxygen/test/compound_detailed/structTemplate_3_01void_01_4.html [new file with mode: 0644]
doxygen/test/compound_listing/Another/Some.h [new file with mode: 0644]
doxygen/test/compound_listing/Class_8h.html [new file with mode: 0644]
doxygen/test/compound_listing/Directory/File.h [new file with mode: 0644]
doxygen/test/compound_listing/Directory/Sub/Class.h [new file with mode: 0644]
doxygen/test/compound_listing/Doxyfile [new file with mode: 0644]
doxygen/test/compound_listing/File_8h.html [new file with mode: 0644]
doxygen/test/compound_listing/Root.h [new file with mode: 0644]
doxygen/test/compound_listing/TopLevelFile.h [new file with mode: 0644]
doxygen/test/compound_listing/annotated.html [new file with mode: 0644]
doxygen/test/compound_listing/classRoot_1_1Directory_1_1Sub_1_1Class.html [new file with mode: 0644]
doxygen/test/compound_listing/dir_4b0d5f8864bf89936129251a2d32609b.html [new file with mode: 0644]
doxygen/test/compound_listing/dir_bbe5918fe090eee9db2d9952314b6754.html [new file with mode: 0644]
doxygen/test/compound_listing/files.html [new file with mode: 0644]
doxygen/test/compound_listing/input.dox [new file with mode: 0644]
doxygen/test/compound_listing/namespaceAnother.html [new file with mode: 0644]
doxygen/test/compound_listing/namespaceRoot_1_1Directory.html [new file with mode: 0644]
doxygen/test/compound_listing/namespaces.html [new file with mode: 0644]
doxygen/test/compound_listing/page-no-toc.html [new file with mode: 0644]
doxygen/test/compound_listing/page-toc.html [new file with mode: 0644]
doxygen/test/contents_blocks/Doxyfile [new file with mode: 0644]
doxygen/test/contents_blocks/index.html [new file with mode: 0644]
doxygen/test/contents_blocks/input.dox [new file with mode: 0644]
doxygen/test/contents_blocks/todo.html [new file with mode: 0644]
doxygen/test/contents_code/Doxyfile [new file with mode: 0644]
doxygen/test/contents_code/index.html [new file with mode: 0644]
doxygen/test/contents_code/input.dox [new file with mode: 0644]
doxygen/test/contents_code/warnings.html [new file with mode: 0644]
doxygen/test/contents_image/Doxyfile [new file with mode: 0644]
doxygen/test/contents_image/index.html [new file with mode: 0644]
doxygen/test/contents_image/input.dox [new file with mode: 0644]
doxygen/test/contents_image/tiny.png [new file with mode: 0644]
doxygen/test/contents_image/warnings.html [new file with mode: 0644]
doxygen/test/contents_math/Doxyfile [new file with mode: 0644]
doxygen/test/contents_math/index.html [new file with mode: 0644]
doxygen/test/contents_math/input.dox [new file with mode: 0644]
doxygen/test/contents_tagfile/Doxyfile [new file with mode: 0644]
doxygen/test/contents_tagfile/index.html [new file with mode: 0644]
doxygen/test/contents_tagfile/input.dox [new file with mode: 0644]
doxygen/test/contents_typography/Doxyfile [new file with mode: 0644]
doxygen/test/contents_typography/index.html [new file with mode: 0644]
doxygen/test/contents_typography/input.dox [new file with mode: 0644]
doxygen/test/contents_typography/warnings.html [new file with mode: 0644]
doxygen/test/doxyfile/Doxyfile [new file with mode: 0644]
doxygen/test/doxyfile/Doxyfile-another [new file with mode: 0644]
doxygen/test/page_duplicated_brief/Doxyfile [new file with mode: 0644]
doxygen/test/page_duplicated_brief/input.dox [new file with mode: 0644]
doxygen/test/page_duplicated_brief/page-a.html [new file with mode: 0644]
doxygen/test/page_duplicated_brief/page-b.html [new file with mode: 0644]
doxygen/test/page_order/00-page-order.dox [new file with mode: 0644]
doxygen/test/page_order/01-second.dox [new file with mode: 0644]
doxygen/test/page_order/02-last.dox [new file with mode: 0644]
doxygen/test/page_order/03-first.dox [new file with mode: 0644]
doxygen/test/page_order/Doxyfile [new file with mode: 0644]
doxygen/test/page_order/a-subpage.dox [new file with mode: 0644]
doxygen/test/page_order/other-page.dox [new file with mode: 0644]
doxygen/test/page_order/pages.html [new file with mode: 0644]
doxygen/test/page_order/yet-another-subpage.dox [new file with mode: 0644]
doxygen/test/test_compound.py [new file with mode: 0644]
doxygen/test/test_contents.py [new file with mode: 0644]
doxygen/test/test_doxyfile.py [new file with mode: 0644]
doxygen/test/test_page.py [new file with mode: 0644]
pelican-theme/templates/base.html
site/pelicanconf.py

diff --git a/css/m-dark+doxygen.compiled.css b/css/m-dark+doxygen.compiled.css
new file mode 100644 (file)
index 0000000..284b6e3
--- /dev/null
@@ -0,0 +1,1897 @@
+/* Generated using `./postprocess.py m-dark.css m-doxygen.css -o m-dark+doxygen.compiled.css`. Do not edit. */
+
+/*
+    This file is part of m.css.
+
+    Copyright © 2017 Vladimír Vondruš <mosra@centrum.cz>
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+*/
+
+*, ::before, ::after { box-sizing: border-box; }
+body { margin: 0; }
+.m-container {
+  width: 100%;
+  margin: auto;
+  padding-left: 1rem;
+  padding-right: 1rem;
+}
+.m-row {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+.m-row:after {
+  content: ' ';
+  clear: both;
+  display: table;
+}
+[class*='m-col-'] {
+  position: relative;
+  padding: 1rem;
+}
+[class*='m-clearfix-']::after {
+  display: block;
+  content: ' ';
+  clear: both;
+}
+[class*='m-show-'] {
+  display: none;
+}
+[class*='m-col-'].m-left-s, [class*='m-col-'].m-right-s, [class*='m-col-'].m-center-s,
+[class*='m-col-'].m-left-m, [class*='m-col-'].m-right-m, [class*='m-col-'].m-center-m,
+[class*='m-col-'].m-left-l, [class*='m-col-'].m-right-l, [class*='m-col-'].m-center-l {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+.m-row > [class*='m-col-'].m-left-s, .m-row > [class*='m-col-'].m-right-s, .m-row > [class*='m-col-'].m-center-s,
+.m-row > [class*='m-col-'].m-left-m, .m-row > [class*='m-col-'].m-right-m, .m-row > [class*='m-col-'].m-center-m,
+.m-row > [class*='m-col-'].m-left-l, .m-row > [class*='m-col-'].m-right-l  .m-row > [class*='m-col-'].m-center-l {
+  margin-left: 0;
+  margin-right: 0;
+}
+.m-container.m-nopad, [class*='m-col-'].m-nopad,
+.m-container.m-nopadx, [class*='m-col-'].m-nopadx,
+.m-container.m-nopadl, [class*='m-col-'].m-nopadl {
+  padding-left: 0;
+}
+.m-container.m-nopad, [class*='m-col-'].m-nopad,
+.m-container.m-nopadx, [class*='m-col-'].m-nopadx,
+.m-container.m-nopadr, [class*='m-col-'].m-nopadr {
+  padding-right: 0;
+}
+[class*='m-col-'].m-nopad, [class*='m-col-'].m-nopady, [class*='m-col-'].m-nopadt {
+  padding-top: 0;
+}
+[class*='m-col-'].m-nopad, [class*='m-col-'].m-nopady, [class*='m-col-'].m-nopadb {
+  padding-bottom: 0;
+}
+[class*='m-col-t-'] { float: left; }
+[class*='m-col-t-'].m-left-t, [class*='m-col-t-'].m-right-t {
+  padding-top: 0px;
+  padding-bottom: 0px;
+}
+.m-left-t {
+  float: left;
+}
+.m-right-t, [class*='m-col-t-'].m-right-t {
+  float: right;
+}
+.m-center-t, [class*='m-col-t-'].m-center-t {
+  float: none;
+}
+[class*='m-col-t-'].m-left-t {
+  margin-left: -1rem;
+}
+[class*='m-col-t-'].m-right-t {
+  margin-right: -1rem;
+}
+.m-row > [class*='m-col-t-'].m-left-t {
+  margin-left: 0;
+}
+.m-row > [class*='m-col-t-'].m-right-t {
+  margin-right: 0;
+}
+.m-center-t, [class*='m-col-t-'].m-center-t {
+  margin-left: auto;
+  margin-right: auto;
+  float: none;
+}
+.m-col-t-1  { width: calc(1  * 100% / 12); }
+.m-col-t-2  { width: calc(2  * 100% / 12); }
+.m-col-t-3  { width: calc(3  * 100% / 12); }
+.m-col-t-4  { width: calc(4  * 100% / 12); }
+.m-col-t-5  { width: calc(5  * 100% / 12); }
+.m-col-t-6  { width: calc(6  * 100% / 12); }
+.m-col-t-7  { width: calc(7  * 100% / 12); }
+.m-col-t-8  { width: calc(8  * 100% / 12); }
+.m-col-t-9  { width: calc(9  * 100% / 12); }
+.m-col-t-10 { width: calc(10 * 100% / 12); }
+.m-col-t-11 { width: calc(11 * 100% / 12); }
+.m-col-t-12 { width: calc(12 * 100% / 12); }
+.m-push-t-1  { left: calc(1  * 100% / 12); }
+.m-push-t-2  { left: calc(2  * 100% / 12); }
+.m-push-t-3  { left: calc(3  * 100% / 12); }
+.m-push-t-4  { left: calc(4  * 100% / 12); }
+.m-push-t-5  { left: calc(5  * 100% / 12); }
+.m-push-t-6  { left: calc(6  * 100% / 12); }
+.m-push-t-7  { left: calc(7  * 100% / 12); }
+.m-push-t-8  { left: calc(8  * 100% / 12); }
+.m-push-t-9  { left: calc(9  * 100% / 12); }
+.m-push-t-10 { left: calc(10 * 100% / 12); }
+.m-push-t-11 { left: calc(11 * 100% / 12); }
+.m-pull-t-1  { right: calc(1  * 100% / 12); }
+.m-pull-t-2  { right: calc(2  * 100% / 12); }
+.m-pull-t-3  { right: calc(3  * 100% / 12); }
+.m-pull-t-4  { right: calc(4  * 100% / 12); }
+.m-pull-t-5  { right: calc(5  * 100% / 12); }
+.m-pull-t-6  { right: calc(6  * 100% / 12); }
+.m-pull-t-7  { right: calc(7  * 100% / 12); }
+.m-pull-t-8  { right: calc(8  * 100% / 12); }
+.m-pull-t-9  { right: calc(9  * 100% / 12); }
+.m-pull-t-10 { right: calc(10 * 100% / 12); }
+.m-pull-t-11 { right: calc(11 * 100% / 12); }
+@media screen and (min-width: 576px) {
+  .m-container { width: 560px; }
+  .m-container-inflatable .m-col-s-10 .m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+  [class*='m-col-s-'] { float: left; }
+  [class*='m-col-s-'].m-left-s, [class*='m-col-s-'].m-right-s {
+    padding-top: 0px;
+    padding-bottom: 0px;
+  }
+  .m-left-s {
+    float: left;
+  }
+  .m-right-s, [class*='m-col-s-'].m-right-s {
+    float: right;
+  }
+  [class*='m-col-s-'].m-left-s {
+    margin-left: -1rem;
+    margin-right: 0;
+  }
+  [class*='m-col-s-'].m-right-s {
+    margin-left: 0;
+    margin-right: -1rem;
+  }
+  .m-row > [class*='m-col-s-'].m-left-s {
+    margin-left: 0;
+  }
+  .m-row > [class*='m-col-s-'].m-right-s {
+    margin-right: 0;
+  }
+  .m-center-s, [class*='m-col-s-'].m-center-s {
+    margin-left: auto;
+    margin-right: auto;
+    float: none;
+  }
+  .m-col-s-1  { width: calc(1  * 100% / 12); }
+  .m-col-s-2  { width: calc(2  * 100% / 12); }
+  .m-col-s-3  { width: calc(3  * 100% / 12); }
+  .m-col-s-4  { width: calc(4  * 100% / 12); }
+  .m-col-s-5  { width: calc(5  * 100% / 12); }
+  .m-col-s-6  { width: calc(6  * 100% / 12); }
+  .m-col-s-7  { width: calc(7  * 100% / 12); }
+  .m-col-s-8  { width: calc(8  * 100% / 12); }
+  .m-col-s-9  { width: calc(9  * 100% / 12); }
+  .m-col-s-10 { width: calc(10 * 100% / 12); }
+  .m-col-s-11 { width: calc(11 * 100% / 12); }
+  .m-col-s-12 { width: calc(12 * 100% / 12); }
+  .m-push-s-0  { left: calc(0  * 100% / 12); }
+  .m-push-s-1  { left: calc(1  * 100% / 12); }
+  .m-push-s-2  { left: calc(2  * 100% / 12); }
+  .m-push-s-3  { left: calc(3  * 100% / 12); }
+  .m-push-s-4  { left: calc(4  * 100% / 12); }
+  .m-push-s-5  { left: calc(5  * 100% / 12); }
+  .m-push-s-6  { left: calc(6  * 100% / 12); }
+  .m-push-s-7  { left: calc(7  * 100% / 12); }
+  .m-push-s-8  { left: calc(8  * 100% / 12); }
+  .m-push-s-9  { left: calc(9  * 100% / 12); }
+  .m-push-s-10 { left: calc(10 * 100% / 12); }
+  .m-push-s-11 { left: calc(11 * 100% / 12); }
+  .m-pull-s-0  { right: calc(0  * 100% / 12); }
+  .m-pull-s-1  { right: calc(1  * 100% / 12); }
+  .m-pull-s-2  { right: calc(2  * 100% / 12); }
+  .m-pull-s-3  { right: calc(3  * 100% / 12); }
+  .m-pull-s-4  { right: calc(4  * 100% / 12); }
+  .m-pull-s-5  { right: calc(5  * 100% / 12); }
+  .m-pull-s-6  { right: calc(6  * 100% / 12); }
+  .m-pull-s-7  { right: calc(7  * 100% / 12); }
+  .m-pull-s-8  { right: calc(8  * 100% / 12); }
+  .m-pull-s-9  { right: calc(9  * 100% / 12); }
+  .m-pull-s-10 { right: calc(10 * 100% / 12); }
+  .m-pull-s-11 { right: calc(11 * 100% / 12); }
+  .m-clearfix-t::after { display: none; }
+  .m-hide-s { display: none; }
+  .m-show-s { display: block; }
+  .m-col-s-none {
+    width: auto;
+    float: none;
+  }
+}
+@media screen and (min-width: 768px) {
+  .m-container { width: 750px; }
+  .m-container-inflatable .m-col-m-10 .m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+  [class*='m-col-m-'] { float: left; }
+  [class*='m-col-m-'].m-left-m, [class*='m-col-m-'].m-right-m {
+    padding-top: 0px;
+    padding-bottom: 0px;
+  }
+  .m-left-m {
+    float: left;
+  }
+  .m-right-m, [class*='m-col-m-'].m-right-m {
+    float: right;
+  }
+  [class*='m-col-m-'].m-left-m {
+    margin-left: -1rem;
+    margin-right: 0;
+  }
+  [class*='m-col-m-'].m-right-m {
+    margin-left: 0;
+    margin-right: -1rem;
+  }
+  .m-row > [class*='m-col-m-'].m-left-m {
+    margin-left: 0;
+  }
+  .m-row > [class*='m-col-m-'].m-right-m {
+    margin-right: 0;
+  }
+  .m-center-m, [class*='m-col-m-'].m-center-m {
+    margin-left: auto;
+    margin-right: auto;
+    float: none;
+  }
+  .m-col-m-1  { width: calc(1  * 100% / 12); }
+  .m-col-m-2  { width: calc(2  * 100% / 12); }
+  .m-col-m-3  { width: calc(3  * 100% / 12); }
+  .m-col-m-4  { width: calc(4  * 100% / 12); }
+  .m-col-m-5  { width: calc(5  * 100% / 12); }
+  .m-col-m-6  { width: calc(6  * 100% / 12); }
+  .m-col-m-7  { width: calc(7  * 100% / 12); }
+  .m-col-m-8  { width: calc(8  * 100% / 12); }
+  .m-col-m-9  { width: calc(9  * 100% / 12); }
+  .m-col-m-10 { width: calc(10 * 100% / 12); }
+  .m-col-m-11 { width: calc(11 * 100% / 12); }
+  .m-col-m-12 { width: calc(12 * 100% / 12); }
+  .m-push-m-0  { left: calc(0  * 100% / 12); }
+  .m-push-m-1  { left: calc(1  * 100% / 12); }
+  .m-push-m-2  { left: calc(2  * 100% / 12); }
+  .m-push-m-3  { left: calc(3  * 100% / 12); }
+  .m-push-m-4  { left: calc(4  * 100% / 12); }
+  .m-push-m-5  { left: calc(5  * 100% / 12); }
+  .m-push-m-6  { left: calc(6  * 100% / 12); }
+  .m-push-m-7  { left: calc(7  * 100% / 12); }
+  .m-push-m-8  { left: calc(8  * 100% / 12); }
+  .m-push-m-9  { left: calc(9  * 100% / 12); }
+  .m-push-m-10 { left: calc(10 * 100% / 12); }
+  .m-push-m-11 { left: calc(11 * 100% / 12); }
+  .m-pull-m-0  { right: calc(0  * 100% / 12); }
+  .m-pull-m-1  { right: calc(1  * 100% / 12); }
+  .m-pull-m-2  { right: calc(2  * 100% / 12); }
+  .m-pull-m-3  { right: calc(3  * 100% / 12); }
+  .m-pull-m-4  { right: calc(4  * 100% / 12); }
+  .m-pull-m-5  { right: calc(5  * 100% / 12); }
+  .m-pull-m-6  { right: calc(6  * 100% / 12); }
+  .m-pull-m-7  { right: calc(7  * 100% / 12); }
+  .m-pull-m-8  { right: calc(8  * 100% / 12); }
+  .m-pull-m-9  { right: calc(9  * 100% / 12); }
+  .m-pull-m-10 { right: calc(10 * 100% / 12); }
+  .m-pull-m-11 { right: calc(11 * 100% / 12); }
+  .m-clearfix-s::after { display: none; }
+  .m-hide-m { display: none; }
+  .m-show-m { display: block; }
+  .m-col-m-none {
+    width: auto;
+    float: none;
+  }
+}
+@media screen and (min-width: 992px) {
+  .m-container { width: 960px; }
+  .m-container-inflatable .m-col-l-10 .m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+  [class*='m-col-l-'] { float: left; }
+  [class*='m-col-l-'].m-left-l, [class*='m-col-l-'].m-right-l {
+    padding-top: 0px;
+    padding-bottom: 0px;
+  }
+  .m-left-l {
+    float: left;
+  }
+  .m-right-l, [class*='m-col-l-'].m-right-l {
+    float: right;
+  }
+  [class*='m-col-l-'].m-left-l {
+    margin-left: -1rem;
+    margin-right: 0;
+  }
+  [class*='m-col-l-'].m-right-l {
+    margin-left: 0;
+    margin-right: -1rem;
+  }
+  .m-row > [class*='m-col-l-'].m-left-l {
+    margin-left: 0;
+  }
+  .m-row > [class*='m-col-l-'].m-right-l {
+    margin-right: 0;
+  }
+  .m-center-l, [class*='m-col-l-'].m-center-l {
+    margin-left: auto;
+    margin-right: auto;
+    float: none;
+  }
+  .m-col-l-1  { width: calc(1  * 100% / 12); }
+  .m-col-l-2  { width: calc(2  * 100% / 12); }
+  .m-col-l-3  { width: calc(3  * 100% / 12); }
+  .m-col-l-4  { width: calc(4  * 100% / 12); }
+  .m-col-l-5  { width: calc(5  * 100% / 12); }
+  .m-col-l-6  { width: calc(6  * 100% / 12); }
+  .m-col-l-7  { width: calc(7  * 100% / 12); }
+  .m-col-l-8  { width: calc(8  * 100% / 12); }
+  .m-col-l-9  { width: calc(9  * 100% / 12); }
+  .m-col-l-10 { width: calc(10 * 100% / 12); }
+  .m-col-l-11 { width: calc(11 * 100% / 12); }
+  .m-col-l-12 { width: calc(12 * 100% / 12); }
+  .m-push-l-0  { left: calc(0  * 100% / 12); }
+  .m-push-l-1  { left: calc(1  * 100% / 12); }
+  .m-push-l-2  { left: calc(2  * 100% / 12); }
+  .m-push-l-3  { left: calc(3  * 100% / 12); }
+  .m-push-l-4  { left: calc(4  * 100% / 12); }
+  .m-push-l-5  { left: calc(5  * 100% / 12); }
+  .m-push-l-6  { left: calc(6  * 100% / 12); }
+  .m-push-l-7  { left: calc(7  * 100% / 12); }
+  .m-push-l-8  { left: calc(8  * 100% / 12); }
+  .m-push-l-9  { left: calc(9  * 100% / 12); }
+  .m-push-l-10 { left: calc(10 * 100% / 12); }
+  .m-push-l-11 { left: calc(11 * 100% / 12); }
+  .m-pull-l-0  { right: calc(0  * 100% / 12); }
+  .m-pull-l-1  { right: calc(1  * 100% / 12); }
+  .m-pull-l-2  { right: calc(2  * 100% / 12); }
+  .m-pull-l-3  { right: calc(3  * 100% / 12); }
+  .m-pull-l-4  { right: calc(4  * 100% / 12); }
+  .m-pull-l-5  { right: calc(5  * 100% / 12); }
+  .m-pull-l-6  { right: calc(6  * 100% / 12); }
+  .m-pull-l-7  { right: calc(7  * 100% / 12); }
+  .m-pull-l-8  { right: calc(8  * 100% / 12); }
+  .m-pull-l-9  { right: calc(9  * 100% / 12); }
+  .m-pull-l-10 { right: calc(10 * 100% / 12); }
+  .m-pull-l-11 { right: calc(11 * 100% / 12); }
+  .m-clearfix-m::after { display: none; }
+  .m-hide-l { display: none; }
+  .m-show-l { display: block; }
+  .m-col-l-none {
+    width: auto;
+    float: none;
+  }
+}
+
+html {
+  font-size: 16px;
+  background-color: #2f363f;
+}
+body {
+  font-family: 'Source Sans Pro', sans-serif;
+  font-size: 1rem;
+  color: #dcdcdc;
+}
+h1, h2, h3, h4, h5, h6 {
+  margin-top: 0;
+  font-weight: bold;
+}
+h1 {
+  margin-bottom: 1rem;
+}
+h2, h3, h4, h5, h6 {
+  margin-bottom: 0.5rem;
+}
+p, ul, ol, dl {
+  margin-top: 0;
+}
+ul, ol {
+  padding-left: 2rem;
+}
+ul ol, ul ul, ol ol, ol ul {
+  margin-bottom: 0;
+}
+main p {
+  text-indent: 1.5rem;
+  text-align: justify;
+}
+main p.m-noindent, li p, table.m-table td p {
+  text-indent: 0;
+  text-align: left;
+}
+blockquote {
+  margin-top: 0;
+  margin-left: 1rem;
+  margin-right: 1rem;
+  padding: 1rem;
+  border-left-style: solid;
+  border-left-width: 0.25rem;
+}
+hr {
+  width: 75%;
+  border-width: 0.0625rem;
+  border-style: solid;
+}
+blockquote, hr {
+  border-color: #405363;
+}
+pre {
+  font-family: 'Source Code Pro', monospace, monospace, monospace; /* https://en.wikipedia.org/wiki/User:Davidgothberg/Test59 */
+  font-size: 0.9rem;
+  padding: 0.5rem 1rem;
+  color: #e6e6e6;
+  background-color: #22272e;
+  border-radius: 0.2rem;
+  overflow-x: auto;
+  margin-top: 0;
+}
+pre.m-console {
+  background-color: #000000;
+}
+abbr {
+  cursor: help;
+  text-decoration: underline dotted;
+}
+sub, sup {
+  font-size: 0.75rem;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sup { top: -0.35rem; }
+sub { bottom: -0.2rem; }
+a {
+  color: #5b9dd9;
+}
+a:hover, a:focus, a:active {
+  color: #a5c9ea;
+}
+a img { border: 0; }
+mark {
+  padding: 0.0625rem;
+  background-color: #c7cf2f;
+  color: #2f83cc;
+}
+code {
+  font-family: 'Source Code Pro', monospace, monospace, monospace;
+  font-size: 0.9rem;
+  padding: 0.125rem;
+  color: #e6e6e6;
+  background-color: #22272e;
+}
+code.m-console {
+  background-color: #000000;
+}
+body > header > nav {
+  width: 100%;
+  background-color: #22272e;
+  min-height: 3rem;
+}
+body > header > nav.m-navbar-landing,
+body > header > nav.m-navbar-jumbo {
+  background-color: transparent;
+  position: relative;
+}
+body > header > nav.m-navbar-landing {
+  opacity: 0.8;
+}
+body > header > nav.m-navbar-jumbo {
+  background-color: rgba(34, 39, 46, 0.25);
+  opacity: 1;
+}
+body > header > nav.m-navbar-landing:hover,
+body > header > nav.m-navbar-jumbo:hover {
+  background-color: rgba(34, 39, 46, 0.75);
+  opacity: 1;
+}
+body> header > nav.m-navbar-landing:target,
+body> header > nav.m-navbar-jumbo:target {
+  background-color: #22272e;
+  opacity: 1;
+}
+body > header > nav.m-navbar-landing a#m-navbar-brand.m-navbar-brand-hidden {
+  visibility: hidden;
+}
+body > header > nav.m-navbar-landing:target a#m-navbar-brand.m-navbar-brand-hidden {
+  visibility: visible;
+}
+body > header > nav {
+  margin-left: auto;
+  margin-right: auto;
+  color: #ffffff;
+}
+body > header > nav a {
+  text-decoration: none;
+  text-transform: none;
+  line-height: 1.5rem;
+  display: inline-block;
+  vertical-align: middle;
+  color: #ffffff;
+}
+body > header > nav a#m-navbar-brand, body > header > nav a#m-navbar-show, body > header > nav a#m-navbar-hide {
+  text-transform: uppercase;
+  font-weight: bold;
+  font-size: 1.125rem;
+  line-height: 3rem;
+}
+body > header > nav a#m-navbar-brand .m-thin {
+  font-weight: normal;
+}
+body > header > nav a#m-navbar-show:before, body > header > nav a#m-navbar-hide:before {
+  content:'\2630';
+}
+body > header > nav #m-navbar-collapse {
+  padding-bottom: 1rem;
+}
+body > header > nav #m-navbar-collapse li {
+  border-style: solid;
+  border-color: transparent;
+  border-width: 0 0 0 0.25rem;
+  margin-left: -1rem;
+}
+body > header > nav #m-navbar-collapse li a {
+  border-style: solid;
+  border-color: transparent;
+  margin-left: -0.25rem;
+  padding-left: 0.75rem;
+  border-width: 0 0 0 0.25rem;
+  width: 100%;
+}
+body > header > nav #m-navbar-collapse li a#m-navbar-current {
+  color: #5b9dd9;
+  border-color: #5b9dd9;
+}
+body > header > nav ol {
+  list-style-type: none;
+  margin: 0;
+}
+body > header > nav ol ol {
+  padding-left: 1.5rem;
+}
+body > header > nav [class*='m-col-'] {
+  padding-top: 0;
+  padding-bottom: 0;
+}
+body > header > nav a:hover, body > header > nav a:focus, body > header > nav a:active {
+  color: #a5c9ea;
+}
+body > header > nav #m-navbar-collapse li:hover {
+  border-color: #a5c9ea;
+}
+body > header > nav #m-navbar-collapse li a:hover,
+body > header > nav #m-navbar-collapse li a:focus,
+body > header > nav #m-navbar-collapse li a:active {
+  border-color: #a5c9ea;
+  background-color: #292f37;
+}
+body > header > nav.m-navbar-landing #m-navbar-collapse li a:hover,
+body > header > nav.m-navbar-jumbo #m-navbar-collapse li a:hover,
+body > header > nav.m-navbar-landing #m-navbar-collapse li a:focus,
+body > header > nav.m-navbar-jumbo #m-navbar-collapse li a:focus,
+body > header > nav.m-navbar-landing #m-navbar-collapse li a:active,
+body > header > nav.m-navbar-jumbo #m-navbar-collapse li a:active {
+  background-color: rgba(41, 47, 55, 0.5);
+}
+body > header > nav #m-navbar-hide {
+  display: none;
+}
+body > header > nav:target #m-navbar-collapse {
+  display: block;
+}
+body > header > nav:target #m-navbar-show {
+  display: none;
+}
+body > header > nav:target #m-navbar-hide {
+  display: inline-block;
+}
+@media screen and (min-width: 768px) {
+  body > header > nav #m-navbar-show, body > header > nav #m-navbar-hide,
+  body > header > nav:target #m-navbar-show, body > header > nav:target #m-navbar-hide {
+    display: none;
+  }
+  body > header > nav a {
+    line-height: 3rem;
+    margin-left: 0;
+    padding-left: 1rem;
+    padding-right: 1rem;
+    white-space: nowrap;
+  }
+  body > header > nav #m-navbar-collapse {
+    padding-bottom: 0;
+  }
+  body > header > nav #m-navbar-collapse li ol {
+    background-color: #22272e;
+  }
+  body > header > nav #m-navbar-collapse ol ol li {
+    margin-left: 0;
+    padding-left: 0;
+    border-left-width: 0;
+  }
+  body > header > nav #m-navbar-collapse ol ol li a {
+    margin-left: 0;
+    padding-left: 0.75rem;
+  }
+  body > header > nav #m-navbar-collapse > .m-row > ol > li {
+    margin-left: 0;
+    border-left-width: 0;
+  }
+  body > header > nav a#m-navbar-brand, body > header > nav #m-navbar-collapse > .m-row > ol > li > a {
+    line-height: 2.75rem;
+    margin-left: 0;
+    border-width: 0 0 0.25rem 0;
+  }
+  body > header > nav #m-navbar-collapse ol {
+    padding-left: 0;
+    padding-right: 0;
+  }
+  body > header > nav #m-navbar-collapse > .m-row > ol, body > header > nav #m-navbar-collapse > .m-row > ol > li {
+    float: left;
+  }
+  body > header > nav #m-navbar-collapse ol ol {
+    z-index: 99999;
+    position: absolute;
+    visibility: hidden;
+    min-width: 7.5rem;
+  }
+  body > header > nav #m-navbar-collapse li:hover ol {
+    visibility: visible;
+  }
+}
+body > footer {
+  width: 100%;
+}
+body > footer > nav {
+  padding-top: 1rem;
+  padding-bottom: 1rem;
+  font-size: 0.85rem;
+  text-align: center;
+  color: #c5c5c5;
+  background-color: #444e5c;
+}
+body > footer > nav h3, body > footer > nav h3 a {
+  text-transform: uppercase;
+  font-weight: normal;
+}
+body > footer > nav ul {
+  list-style-type: none;
+  padding: 0;
+  margin: 0;
+}
+body > footer > nav a {
+  text-decoration: none;
+  text-transform: none;
+  color: #ffffff;
+}
+body > footer > nav a:hover, body > footer > nav a:focus, body > footer > nav a:active {
+  color: #a5c9ea;
+}
+body > main {
+  padding-top: 1rem;
+  padding-bottom: 1rem;
+}
+article h1 {
+  font-size: 1.75rem;
+}
+article h1 .m-breadcrumb {
+  color: #747474;
+  font-weight: normal;
+}
+article h1 .m-breadcrumb a {
+  color: #a5c9ea;
+}
+article h1 .m-breadcrumb a:hover, article h1 a:focus, article h1 a:active {
+  color: #dcdcdc;
+}
+article > header h1 {
+  font-size: 2rem;
+  margin-bottom: 0.5rem;
+}
+article h1 a, article > header h1, article > header h1 a,
+article section > h2, article section > h2 a,
+article section > h3, article section > h3 a,
+article section > h4, article section > h4 a,
+article section > h5, article section > h5 a,
+article section > h6, article section > h6 a {
+  color: #a5c9ea;
+}
+article h1 a:hover, article > header h1 a:hover, article > header h1 a:focus, article > header h1 a:active,
+article section > h2 a:hover, article section > h2 a:focus, article section > h2 a:active,
+article section > h3 a:hover, article section > h3 a:focus, article section > h3 a:active,
+article section > h4 a:hover, article section > h4 a:focus, article section > h4 a:active,
+article section > h5 a:hover, article section > h5 a:focus, article section > h5 a:active,
+article section > h6 a:hover, article section > h6 a:focus, article section > h6 a:active {
+  color: #dcdcdc;
+}
+article > header .m-date {
+  display: block;
+  width: 2.5rem;
+  float: left;
+  text-align: center;
+  line-height: 95%;
+  font-size: 0.75rem;
+  font-weight: normal;
+  white-space: nowrap;
+  border-right-style: solid;
+  border-right-width: 0.125rem;
+  border-color: #a5c9ea;
+  padding-right: 0.75rem;
+  margin-top: -0.1rem;
+  margin-right: 0.75rem;
+  margin-bottom: 0.25rem;
+}
+article > header .m-date-day {
+  display: block;
+  font-weight: bold;
+  padding-top: 0.2rem;
+  padding-bottom: 0.15rem;
+  font-size: 1.25rem;
+}
+article > header p {
+  color: #f0f0f0;
+  font-size: 1.125rem;
+}
+article > header h1::after {
+  content: " ";
+  clear: both;
+  display: table;
+}
+article > footer {
+  color: #c5c5c5;
+}
+article > footer p {
+  font-style: italic;
+  font-size: 0.85rem;
+  text-indent: 0;
+}
+article section:target {
+  margin-left: -1.0rem;
+  border-left-style: solid;
+  border-left-width: 0.25rem;
+  padding-left: 0.75rem;
+  border-color: #a5c9ea;
+}
+article h1 a, article > header h1 a, article section > h2 a, article section > h3 a,
+article section > h4 a, article section > h5 a, article section > h6 a {
+  text-decoration: none;
+}
+#m-landing-image {
+  background-size: cover;
+  background-color: #222222;
+  background-position: center center;
+  background-repeat: no-repeat;
+  margin-top: -4rem;
+  padding-top: 5rem;
+  color: #ffffff;
+}
+#m-landing-cover {
+  padding-bottom: 7rem;
+  margin-bottom: -3rem;
+}
+article#m-jumbo {
+  margin-top: -1rem;
+}
+article#m-jumbo > header #m-jumbo-image {
+  background-size: cover;
+  background-color: #222222;
+  background-position: center center;
+  background-repeat: no-repeat;
+  font-size: 2.5vh;
+  height: 60vh;
+  margin-top: -4rem;
+  margin-bottom: 1rem;
+  padding-top: 5rem;
+}
+article#m-jumbo > header #m-jumbo-cover, #m-landing-cover {
+  background: linear-gradient(transparent 0%, transparent 50%, #2f363f 100%);
+  width: 100%;
+  height: 100%;
+}
+article#m-jumbo > header h1, article#m-jumbo > header h2 {
+  text-align: center;
+  font-weight: bold;
+}
+article#m-jumbo > header h1 {
+  font-size: 10vh;
+}
+article#m-jumbo > header h2 {
+  font-size: 3vh;
+}
+article#m-jumbo > header a {
+  text-decoration: none;
+}
+article#m-jumbo > header, article#m-jumbo > header h1, article#m-jumbo > header a {
+  color: #ffffff;
+}
+article#m-jumbo > header a:hover, article#m-jumbo > header a:focus, article#m-jumbo > header a:active {
+  color: #f0f0f0;
+}
+article#m-jumbo.m-inverted > header, article#m-jumbo.m-inverted > header h1, article#m-jumbo.m-inverted > header a {
+  color: #000000;
+}
+article#m-jumbo.m-inverted > header a:hover, article#m-jumbo.m-inverted > header a:focus, article#m-jumbo.m-inverted > header a:active {
+  color: #0f0f0f;
+}
+.m-article-pagination {
+  text-align: center;
+  padding: 1rem;
+}
+nav.m-navpanel {
+  text-align: center;
+}
+nav.m-navpanel h3 {
+  text-transform: uppercase;
+  font-weight: normal;
+}
+nav.m-navpanel ol {
+  text-transform: lowercase;
+}
+nav.m-navpanel ol, nav.m-navpanel ul {
+  list-style-type: none;
+  padding: 0;
+}
+nav.m-navpanel a {
+  color: #ffffff;
+  text-decoration: none;
+}
+nav.m-navpanel a:hover, nav.m-navpanel a:focus, nav.m-navpanel a:active {
+  color: #a5c9ea;
+}
+ul.m-tagcloud li { display: inline; }
+ul.m-tagcloud li.m-tag-1 { font-size: 0.75rem; }
+ul.m-tagcloud li.m-tag-2 { font-size: 0.825rem; }
+ul.m-tagcloud li.m-tag-3 { font-size: 1rem; }
+ul.m-tagcloud li.m-tag-4 { font-size: 1.25rem; }
+ul.m-tagcloud li.m-tag-5 { font-size: 1.5rem; }
+div.m-scroll {
+  max-width: 100%;
+  overflow-x: auto;
+}
+.m-fullwidth {
+  width: 100%;
+}
+.m-text-center, .m-text-center.m-noindent, table.m-table th.m-text-center, .m-text-center p {
+  text-align: center;
+}
+.m-text-left, .m-text-left.m-noindent, table.m-table th.m-text-left, .m-text-right p {
+  text-align: left;
+}
+.m-text-right, .m-text-right.m-noindent, table.m-table th.m-text-right, .m-text-right p {
+  text-align: right;
+}
+.m-text.m-small {
+  font-size: 85.4%;
+}
+.m-text.m-big {
+  font-size: 117%;
+}
+.m-text.m-strong {
+  font-weight: bold;
+}
+.m-text.m-em {
+  font-style: italic;
+}
+h1 .m-thin, h2 .m-thin, h3 .m-thin, h4 .m-thin, h5 .m-thin, h6 .m-thin {
+  font-weight: normal;
+}
+ul.m-unstyled, ol.m-unstyled {
+  list-style-type: none;
+  padding-left: 0;
+}
+ul[class*='m-block-'], ol[class*='m-block-'] {
+  padding-left: 0;
+}
+ul[class*='m-block-'] li, ol[class*='m-block-'] li {
+  display: inline;
+}
+ul[class*='m-block-bar-'] li:not(:last-child)::after, ol[class*='m-block-bar-'] li:not(:last-child)::after {
+  content: " | ";
+}
+@media screen and (min-width: 576px) {
+  ul.m-block-bar-s, ol.m-block-bar-s { padding-left: 2rem; }
+  ul.m-block-bar-s li, ol.m-block-bar-s li { display: list-item; }
+  ul.m-block-bar-s li:not(:last-child)::after, ol.m-block-bar-s li:not(:last-child)::after { content: ""; }
+}
+@media screen and (min-width: 768px) {
+  ul.m-block-bar-m, ol.m-block-bar-m { padding-left: 2rem; }
+  ul.m-block-bar-m li, ol.m-block-bar-m li { display: list-item; }
+  ul.m-block-bar-m li:not(:last-child)::after, ol.m-block-bar-m li:not(:last-child)::after { content: ""; }
+}
+@media screen and (min-width: 992px) {
+  ul.m-block-bar-l, ol.m-block-bar-l { padding-left: 2rem; }
+  ul.m-block-bar-l li, ol.m-block-bar-l li { display: list-item; }
+  ul.m-block-bar-l li:not(:last-child)::after, ol.m-block-bar-l li:not(:last-child)::after { content: ""; }
+}
+p.m-poem {
+  text-indent: 0;
+  text-align: left;
+  margin-left: 1.5rem;
+}
+p.m-transition {
+  color: #405363;
+  text-indent: 0;
+  text-align: center;
+  font-size: 2rem;
+}
+dl.m-diary {
+  margin-bottom: 1.25rem;
+}
+dl.m-diary:last-child {
+  margin-bottom: 0.25rem;
+}
+dl.m-diary dt {
+  font-weight: bold;
+  width: 3.5rem;
+  float: left;
+  clear: both;
+  padding-top: 0.25rem;
+}
+dl.m-diary dd {
+  padding-top: 0.25rem;
+  padding-left: 3.5rem;
+}
+.m-note {
+  border-radius: 0.2rem;
+  padding: 1rem;
+}
+.m-frame {
+  background-color: #2f363f;
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: 0.2rem;
+  border-color: #405363;
+  padding: 0.875rem;
+}
+.m-block {
+  border-style: solid;
+  border-width: 0.0625rem;
+  border-left-width: 0.25rem;
+  border-radius: 0.2rem;
+  border-color: #405363;
+  padding: 0.9375rem 0.9375rem 0.9375rem 0.75rem;
+}
+.m-block.m-badge::after {
+  content: ' ';
+  display: block;
+  clear: both;
+}
+.m-block.m-badge h3 {
+  margin-left: 5rem;
+}
+.m-block.m-badge p {
+  margin-left: 5rem;
+  text-indent: 0;
+}
+.m-block.m-badge img {
+  width: 4rem;
+  height: 4rem;
+  border-radius: 2rem;
+  float: left;
+}
+a.m-button {
+  display: inline-block;
+  border-radius: 0.2rem;
+  padding-top: 0.75rem;
+  padding-bottom: 0.75rem;
+  padding-left: 1.5rem;
+  padding-right: 1.5rem;
+  text-decoration: none;
+  text-align: center;
+  font-size: 1.17rem;
+}
+a.m-button.m-fullwidth {
+  display: block;
+  padding-left: 0;
+  padding-right: 0;
+}
+a.m-button .m-big:first-child {
+  font-size: 1.37rem;
+  font-weight: bold;
+}
+a.m-button .m-small:last-child {
+  font-size: 0.854rem;
+}
+.m-label {
+  border-radius: 0.2rem;
+  font-size: 75%;
+  font-weight: normal;
+  padding: 0.125rem 0.25rem;
+  vertical-align: 7.5%;
+}
+.m-label.m-flat {
+  border-width: 0.0625rem;
+  border-style: solid;
+  border-color: #747474;
+  padding: 0.0625rem 0.1875rem;
+}
+table.m-table {
+  border-collapse: collapse;
+  margin-left: auto;
+  margin-right: auto;
+}
+div.m-scroll > table.m-table:last-child {
+  margin-bottom: 0.0625rem;
+}
+table.m-table:not(.m-flat) tbody tr:hover {
+  background-color: #405363;
+}
+table.m-table th, table.m-table td {
+  vertical-align: top;
+  border-style: solid;
+  border-top-width: 0.0625rem;
+  border-left-width: 0;
+  border-right-width: 0;
+  border-bottom-width: 0;
+  border-color: #405363;
+}
+table.m-table caption {
+  padding-bottom: 0.5rem;
+}
+table.m-table thead tr:first-child th, table.m-table thead tr:first-child td {
+  border-top-width: 0.125rem;
+}
+table.m-table thead th, table.m-table thead td {
+  border-bottom-width: 0.125rem;
+  vertical-align: bottom;
+}
+table.m-table tfoot th, table.m-table tfoot td {
+  border-top-width: 0.125rem;
+}
+table.m-table th, table.m-table td {
+  padding: 0.5rem;
+}
+table.m-table th {
+  text-align: left;
+}
+table.m-table td.m-default, th.m-default,
+table.m-table td.m-primary, th.m-primary,
+table.m-table td.m-success, th.m-success,
+table.m-table td.m-warning, th.m-warning,
+table.m-table td.m-danger, th.m-danger,
+table.m-table td.m-info, th.m-info,
+table.m-table td.m-dim, th.m-dim {
+  padding-left: 0.4375rem;
+  padding-right: 0.4375rem;
+  border-left-width: 0.0625rem;
+}
+table.m-table tr.m-default td, table.m-table td.m-default,
+table.m-table tr.m-default th, table.m-table th.m-default,
+table.m-table tr.m-primary td, table.m-table td.m-primary,
+table.m-table tr.m-primary th, table.m-table th.m-primary,
+table.m-table tr.m-success td, table.m-table td.m-success,
+table.m-table tr.m-success th, table.m-table th.m-success,
+table.m-table tr.m-warning td, table.m-table td.m-warning,
+table.m-table tr.m-warning th, table.m-table th.m-warning,
+table.m-table tr.m-danger td, table.m-table td.m-danger,
+table.m-table tr.m-danger th, table.m-table th.m-danger,
+table.m-table tr.m-info td, table.m-table td.m-info,
+table.m-table tr.m-info th, table.m-table th.m-info,
+table.m-table tr.m-dim td, table.m-table td.m-dim,
+table.m-table tr.m-dim th, table.m-table th.m-dim {
+  border-color: #2f363f;
+}
+.m-block.m-default { border-left-color: #405363; }
+.m-block.m-default h3, .m-block.m-default h4, .m-block.m-default h5, .m-block.m-default h6 {
+  color: #dcdcdc;
+}
+.m-block.m-primary { border-left-color: #a5c9ea; }
+.m-block.m-primary h3, .m-block.m-primary h4, .m-block.m-primary h5, .m-block.m-primary h6 {
+  color: #a5c9ea;
+}
+.m-block.m-success { border-left-color: #3bd267; }
+.m-block.m-success h3, .m-block.m-success h4, .m-block.m-success h5, .m-block.m-success h6 {
+  color: #3bd267;
+}
+.m-block.m-warning { border-left-color: #c7cf2f; }
+.m-block.m-warning h3, .m-block.m-warning h4, .m-block.m-warning h5, .m-block.m-warning h6 {
+  color: #c7cf2f;
+}
+.m-block.m-danger { border-left-color: #cd3431; }
+.m-block.m-danger h3, .m-block.m-danger h4, .m-block.m-danger h5, .m-block.m-danger h6 {
+  color: #cd3431;
+}
+.m-block.m-info { border-left-color: #2f83cc; }
+.m-block.m-info h3, .m-block.m-info h4, .m-block.m-info h5, .m-block.m-info h6 {
+  color: #2f83cc;
+}
+.m-block.m-dim {
+  border-left-color: #747474;
+  color: #747474;
+}
+.m-block.m-dim a { color: #acacac; }
+.m-block.m-dim a:hover, .m-block.m-dim a:focus, .m-block.m-dim a:active {
+  color: #747474;
+}
+.m-block.m-flat { border-color: transparent; }
+.m-block.m-flat h3, .m-block.m-flat h4, .m-block.m-flat h5. .m-block.m-flat h6 {
+  color: #dcdcdc;
+}
+.m-note.m-default { background-color: #34424d; }
+.m-note.m-default, table.m-table tr.m-default td, table.m-table td.m-default,
+                   table.m-table tr.m-default th, table.m-table th.m-default {
+  color: #dcdcdc;
+}
+.m-note.m-default a:hover, table.m-table tr.m-default td a:hover, table.m-table td.m-default a:hover,
+                           table.m-table tr.m-default th a:hover, table.m-table th.m-default a:hover,
+.m-note.m-default a:focus, table.m-table tr.m-default td a:focus, table.m-table td.m-default a:focus,
+                           table.m-table tr.m-default th a:focus, table.m-table th.m-default a:focus,
+.m-note.m-default a:active, table.m-table tr.m-default td a:active, table.m-table td.m-default a:active,
+                            table.m-table tr.m-default th a:active, table.m-table th.m-default a:active {
+  color: #a5c9ea;
+}
+.m-note.m-primary a, table.m-table tr.m-primary td a, table.m-table td.m-primary a,
+                     table.m-table tr.m-primary th a, table.m-table th.m-primary a {
+  color: #5b9dd9;
+}
+.m-note.m-primary, table.m-table tr.m-primary td, table.m-table td.m-primary,
+                   table.m-table tr.m-primary th, table.m-table th.m-primary {
+  background-color: #a5c2db;
+  color: #2f363f;
+}
+.m-note.m-primary a, table.m-table tr.m-primary td a, table.m-table td.m-primary a,
+                     table.m-table tr.m-primary th a, table.m-table th.m-primary a {
+  color: #2a75b6;
+}
+.m-note.m-primary a:hover, table.m-table tr.m-primary td a:hover, table.m-table td.m-primary a:hover,
+                           table.m-table tr.m-primary th a:hover, table.m-table th.m-primary a:hover,
+.m-note.m-primary a:focus, table.m-table tr.m-primary td a:focus, table.m-table td.m-primary a:focus,
+                           table.m-table tr.m-primary th a:focus, table.m-table th.m-primary a:focus,
+.m-note.m-primary a:active, table.m-table tr.m-primary td a:active, table.m-table td.m-primary a:active,
+                            table.m-table tr.m-primary th a:active, table.m-table th.m-primary a:active {
+  color: #2f363f;
+}
+.m-note.m-success, table.m-table tr.m-success td, table.m-table td.m-success,
+                   table.m-table tr.m-success th, table.m-table th.m-success {
+  background-color: #2a703f;
+  color: #acecbe;
+}
+.m-note.m-success a, table.m-table tr.m-success td a, table.m-table td.m-success a,
+                     table.m-table tr.m-success th a, table.m-table th.m-success a {
+  color: #3bd267;
+}
+.m-note.m-success a:hover, table.m-table tr.m-success td a:hover, table.m-table td.m-success a:hover,
+                           table.m-table tr.m-success th a:hover, table.m-table th.m-success a:hover,
+.m-note.m-success a:focus, table.m-table tr.m-success td a:focus, table.m-table td.m-success a:focus,
+                           table.m-table tr.m-success th a:focus, table.m-table th.m-success a:focus,
+.m-note.m-success a:active, table.m-table tr.m-success td a:active, table.m-table td.m-success a:active,
+                            table.m-table tr.m-success th a:active, table.m-table th.m-success a:active {
+  color: #acecbe;
+}
+.m-note.m-warning, table.m-table tr.m-warning td, table.m-table td.m-warning,
+                   table.m-table tr.m-warning th, table.m-table th.m-warning {
+  background-color: #6d702a;
+  color: #e9ecae;
+}
+.m-note.m-warning a, table.m-table tr.m-warning td a, table.m-table td.m-warning a,
+                     table.m-table tr.m-warning th a, table.m-table th.m-warning a {
+  color: #b8bf2b;
+}
+.m-note.m-warning a:hover, table.m-table tr.m-warning td a:hover, table.m-table td.m-warning a:hover,
+                           table.m-table tr.m-warning th a:hover, table.m-table th.m-warning a:hover,
+.m-note.m-warning a:focus, table.m-table tr.m-warning td a:focus, table.m-table td.m-warning a:focus,
+                           table.m-table tr.m-warning th a:focus, table.m-table th.m-warning a:focus,
+.m-note.m-warning a:active, table.m-table tr.m-warning td a:active, table.m-table td.m-warning a:active,
+                            table.m-table tr.m-warning th a:active, table.m-table th.m-warning a:active {
+  color: #e9ecae;
+}
+.m-note.m-danger, table.m-table tr.m-danger td, table.m-table td.m-danger,
+                  table.m-table tr.m-danger th, table.m-table th.m-danger {
+  background-color: #702b2a;
+  color: #ff9391;
+}
+.m-note.m-danger a, table.m-table tr.m-danger td a, table.m-table td.m-danger a,
+                    table.m-table tr.m-danger th a, table.m-table th.m-danger a {
+  color: #d85c59;
+}
+.m-note.m-danger a:hover, table.m-table tr.m-danger td a:hover, table.m-table td.m-danger a:hover,
+                          table.m-table tr.m-danger th a:hover, table.m-table th.m-danger a:hover,
+.m-note.m-danger a:focus, table.m-table tr.m-danger td a:focus, table.m-table td.m-danger a:focus,
+                          table.m-table tr.m-danger th a:focus, table.m-table th.m-danger a:focus,
+.m-note.m-danger a:active, table.m-table tr.m-danger td a:active, table.m-table td.m-danger a:active,
+                           table.m-table tr.m-danger th a:active, table.m-table th.m-danger a:active {
+  color: #ff9391;
+}
+.m-note.m-info, table.m-table tr.m-info td, table.m-table td.m-info,
+                table.m-table tr.m-info th, table.m-table th.m-info {
+  background-color: #2a4f70;
+  color: #a5caeb;
+}
+.m-note.m-info a, table.m-table tr.m-info td a, table.m-table td.m-info a,
+                  table.m-table tr.m-info th a, table.m-table th.m-info a {
+  color: #5297d7;
+}
+.m-note.m-info a:hover, table.m-table tr.m-info td a:hover, table.m-table td.m-info a:hover,
+                        table.m-table tr.m-info th a:hover, table.m-table th.m-info a:hover,
+.m-note.m-info a:focus, table.m-table tr.m-info td a:focus, table.m-table td.m-info a:focus,
+                        table.m-table tr.m-info th a:focus, table.m-table th.m-info a:focus,
+.m-note.m-info a:active, table.m-table tr.m-info td a:active, table.m-table td.m-info a:active,
+                         table.m-table tr.m-info th a:active, table.m-table th.m-info a:active {
+  color: #a5caeb;
+}
+.m-note.m-dim, table.m-table tr.m-dim td, table.m-table td.m-dim,
+               table.m-table tr.m-dim th, table.m-table th.m-dim {
+  background-color: #2d3236;
+  color: #747474;
+}
+.m-note.m-dim a, table.m-table tr.m-dim td a, table.m-table td.m-dim a,
+                 table.m-table tr.m-dim th a, table.m-table th.m-dim a {
+  color: #acacac;
+}
+.m-note.m-dim a:hover, table.m-table tr.m-dim td a:hover, table.m-table td.m-dim a:hover,
+                       table.m-table tr.m-dim th a:hover, table.m-table th.m-dim a:hover,
+.m-note.m-dim a:focus, table.m-table tr.m-dim td a:focus, table.m-table td.m-dim a:focus,
+                       table.m-table tr.m-dim th a:focus, table.m-table th.m-dim a:focus,
+.m-note.m-dim a:active, table.m-table tr.m-dim td a:active, table.m-table td.m-dim a:active,
+                        table.m-table tr.m-dim th a:active, table.m-table th.m-dim a:active {
+  color: #747474;
+}
+.m-text.m-default, .m-label.m-flat.m-default { color: #dcdcdc; }
+.m-text.m-primary, .m-label.m-flat.m-primary { color: #a5c9ea; }
+.m-text.m-success, .m-label.m-flat.m-success { color: #3bd267; }
+.m-text.m-warning, .m-label.m-flat.m-warning { color: #c7cf2f; }
+.m-text.m-danger, .m-label.m-flat.m-danger { color: #cd3431; }
+.m-text.m-info, .m-label.m-flat.m-info { color: #2f83cc; }
+.m-text.m-dim, .m-label.m-flat.m-dim { color: #747474; }
+.m-text.m-dim a { color: #acacac; }
+.m-text.m-dim a:hover, .m-text.m-dim a:focus, .m-text.m-dim a:active {
+  color: #747474;
+}
+a.m-button, .m-label { color: #2f363f; }
+a.m-button.m-default, .m-label:not(.m-flat).m-default { background-color: #dcdcdc; }
+a.m-button.m-primary, .m-label:not(.m-flat).m-primary { background-color: #a5c9ea; }
+a.m-button.m-success, .m-label:not(.m-flat).m-success { background-color: #3bd267; }
+a.m-button.m-warning, .m-label:not(.m-flat).m-warning { background-color: #c7cf2f; }
+a.m-button.m-danger, .m-label:not(.m-flat).m-danger { background-color: #cd3431; }
+a.m-button.m-info, .m-label:not(.m-flat).m-info { background-color: #2f83cc; }
+a.m-button.m-dim, .m-label:not(.m-flat).m-dim { background-color: #747474; }
+a.m-button.m-default:hover, a.m-button.m-default:focus, a.m-button.m-default:active {
+  background-color: #a5c9ea;
+}
+a.m-button.m-primary:hover, a.m-button.m-primary:focus, a.m-button.m-primary:active {
+  background-color: #dcdcdc;
+}
+a.m-button.m-success:hover, a.m-button.m-success:focus, a.m-button.m-success:active {
+  background-color: #acecbe;
+}
+a.m-button.m-warning:hover, a.m-button.m-warning:focus, a.m-button.m-warning:active {
+  background-color: #e9ecae;
+}
+a.m-button.m-danger:hover, a.m-button.m-danger:focus, a.m-button.m-danger:active {
+  background-color: #ff9391;
+}
+a.m-button.m-info:hover, a.m-button.m-info:focus, a.m-button.m-info:active {
+  background-color: #5297d7;
+}
+a.m-button.m-dim:hover, a.m-button.m-dim:focus, a.m-button.m-dim:active {
+  background-color: #acacac;
+}
+img.m-image {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+div.m-image {
+  text-align: center;
+}
+img.m-image, div.m-image img {
+  max-width: 100%;
+  border-radius: 0.2rem;
+}
+div.m-image.m-fullwidth img {
+  width: 100%;
+}
+figure.m-figure {
+  max-width: 100%;
+  margin-top: 0;
+  margin-left: auto;
+  margin-right: auto;
+  position: relative;
+  display: table;
+}
+figure.m-figure:before {
+  position: absolute;
+  content: ' ';
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: -1;
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: 0.2rem;
+  border-color: #405363;
+}
+figure.m-figure.m-flat:before {
+  border-color: transparent;
+}
+figure.m-figure > * {
+  margin-left: 1rem;
+  margin-right: 1rem;
+  display: table-caption;
+  caption-side: bottom;
+}
+figure.m-figure > *:first-child {
+  display: inline;
+}
+figure.m-figure > *:last-child {
+  margin-bottom: 1rem;
+}
+figure.m-figure img {
+  position: relative;
+  margin-left: 0;
+  margin-right: 0;
+  margin-bottom: 0;
+  border-top-left-radius: 0.2rem;
+  border-top-right-radius: 0.2rem;
+  max-width: 100%;
+}
+figure.m-figure figcaption {
+  margin-top: 0.5rem;
+  margin-bottom: 0.5rem;
+  font-weight: bold;
+  font-size: 1.17rem;
+}
+figure.m-figure a img {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+figure.m-figure.m-fullwidth, figure.m-figure.m-fullwidth > * {
+  display: block;
+}
+figure.m-figure.m-fullwidth > *:first-child {
+  display: inline;
+}
+figure.m-figure.m-fullwidth img {
+  width: 100%;
+}
+figure.m-figure.m-fullwidth:after {
+  content: ' ';
+  display: block;
+  margin-top: 1rem;
+  height: 1px;
+}
+figure.m-code-figure, figure.m-console-figure {
+  margin-top: 0;
+  margin-left: 0;
+  margin-right: 0;
+  position: relative;
+  padding: 1rem;
+}
+figure.m-code-figure:before, figure.m-console-figure:before {
+  position: absolute;
+  content: ' ';
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: -1;
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: 0.2rem;
+}
+figure.m-code-figure:before {
+  border-color: #22272e;
+}
+figure.m-console-figure:before {
+  border-color: #000000;
+}
+figure.m-code-figure.m-flat:before, figure.m-console-figure.m-flat:before {
+  border-color: transparent;
+}
+figure.m-code-figure > pre:first-child, figure.m-console-figure > pre:first-child {
+  position: relative;
+  margin: -1rem -1rem 1rem -1rem;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+}
+article section:target figure.m-code-figure, article section:target figure.m-console-figure {
+  z-index: 1;
+}
+.m-imagegrid > div {
+  background-color: #2f363f; /* to avoid section HL shining through */
+}
+.m-imagegrid > div > figure {
+  display: block;
+  float: left;
+  position: relative;
+  margin: 0;
+}
+.m-imagegrid > div > figure > div,
+.m-imagegrid > div > figure > figcaption,
+.m-imagegrid > div > figure > a > div,
+.m-imagegrid > div > figure > a > figcaption {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  border-color: #2f363f;
+  border-style: solid;
+  border-width: 0.25rem;
+  padding: 0.5rem;
+}
+.m-imagegrid > div > figure:first-child > div,
+.m-imagegrid > div > figure:first-child > figcaption,
+.m-imagegrid > div > figure:first-child > a > div,
+.m-imagegrid > div > figure:first-child > a > figcaption {
+  border-left-width: 0;
+}
+.m-imagegrid > div > figure:last-child > div,
+.m-imagegrid > div > figure:last-child > figcaption,
+.m-imagegrid > div > figure:last-child > a > div,
+.m-imagegrid > div > figure:last-child > a > figcaption {
+  border-right-width: 0;
+}
+.m-imagegrid > div > figure > figcaption,
+.m-imagegrid > div > figure > a > figcaption {
+  color: transparent;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  font-size: 0.75rem;
+}
+.m-imagegrid > div > figure > div::before,
+.m-imagegrid > div > figure > figcaption::before,
+.m-imagegrid > div > figure > a > div::before,
+.m-imagegrid > div > figure > a > figcaption::before {
+  content: '';
+  display: inline-block;
+  height: 100%;
+  vertical-align: bottom;
+  width: 0;
+}
+.m-imagegrid > div > figure:hover > figcaption,
+.m-imagegrid > div > figure:hover > a > figcaption {
+  background: linear-gradient(transparent 0%, transparent 75%, rgba(0, 0, 0, 0.85) 100%);
+  color: #ffffff;
+}
+.m-imagegrid > div > figure > img,
+.m-imagegrid > div > figure > a > img {
+  width: 100%;
+  height: 100%;
+}
+.m-imagegrid > div::after {
+  display: block;
+  content: ' ';
+  clear: both;
+}
+@media screen and (max-width: 767px) {
+  .m-imagegrid > div > figure {
+    float: none;
+    width: 100% !important;
+  }
+  .m-imagegrid > div > figure > div,
+  .m-imagegrid > div > figure > figcaption,
+  .m-imagegrid > div > figure > a > div,
+  .m-imagegrid > div > figure > a > figcaption {
+    border-left-width: 0;
+    border-right-width: 0;
+  }
+}
+.m-container-inflatable > .m-row > [class*='m-col-'] > .m-note,
+.m-container-inflatable > .m-row > [class*='m-col-'] > .m-frame,
+.m-container-inflatable > .m-row > [class*='m-col-'] > .m-block,
+.m-container-inflatable > .m-row > [class*='m-col-'] > .m-imagegrid,
+.m-container-inflatable > .m-row > [class*='m-col-'] > pre,
+.m-container-inflatable > .m-row > [class*='m-col-'] > figure.m-code-figure,
+.m-container-inflatable > .m-row > [class*='m-col-'] > figure.m-console-figure,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-note,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-frame,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-block,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-imagegrid,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > pre,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > figure.m-code-figure,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > figure.m-console-figure {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+@media screen and (min-width: 576px) {
+  .m-container-inflatable > .m-row > .m-col-s-10 > .m-imagegrid.m-container-inflate,
+  .m-container-inflatable > .m-row > .m-col-s-10 section > .m-imagegrid.m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+}
+@media screen and (min-width: 768px) {
+  .m-container-inflatable > .m-row > .m-col-m-10 > .m-imagegrid.m-container-inflate,
+  .m-container-inflatable > .m-row > .m-col-m-10 section > .m-imagegrid.m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+}
+@media screen and (min-width: 992px) {
+  .m-container-inflatable > .m-row > .m-col-l-10 > .m-imagegrid.m-container-inflate,
+  .m-container-inflatable > .m-row > .m-col-l-10 section > .m-imagegrid.m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+}
+.m-container-inflatable section:target > .m-note,
+.m-container-inflatable section:target > .m-frame,
+.m-container-inflatable section:target > .m-block,
+.m-container-inflatable section:target > pre,
+.m-container-inflatable section:target > figure.m-code-figure > pre:first-child,
+.m-container-inflatable section:target > figure.m-console-figure > pre:first-child,
+.m-container-inflatable section:target section > .m-note,
+.m-container-inflatable section:target section > .m-frame,
+.m-container-inflatable section:target section > .m-block,
+.m-container-inflatable section:target section > pre,
+.m-container-inflatable section:target section > figure.m-code-figure > pre:first-child,
+.m-container-inflatable section:target section > figure.m-console-figure > pre:first-child {
+  margin-left: -1.0rem;
+  border-left-style: solid;
+  border-left-width: 0.25rem;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+  padding-left: 0.75rem;
+}
+.m-container-inflatable section:target > figure.m-code-figure::before,
+.m-container-inflatable section:target > figure.m-console-figure::before,
+.m-container-inflatable section:target section > figure.m-code-figure::before,
+.m-container-inflatable section:target section > figure.m-console-figure::before {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+  border-left-width: 0.25rem;
+}
+.m-container-inflatable section:target > pre,
+.m-container-inflatable section:target > figure.m-code-figure > pre:first-child,
+.m-container-inflatable section:target > figure.m-console-figure > pre:first-child,
+.m-container-inflatable section:target section > pre,
+.m-container-inflatable section:target section > figure.m-code-figure > pre:first-child,
+.m-container-inflatable section:target section > figure.m-console-figure > pre:first-child {
+  border-color: #405363;
+}
+.m-container-inflatable section:target > figure.m-code-figure::before,
+.m-container-inflatable section:target > figure.m-console-figure::before,
+.m-container-inflatable section:target > .m-note.m-default,
+.m-container-inflatable section:target section > figure.m-code-figure::before,
+.m-container-inflatable section:target section > figure.m-console-figure::before,
+.m-container-inflatable section:target section > .m-note.m-default {
+  border-left-color: #405363;
+}
+.m-container-inflatable section:target > .m-note.m-primary,
+.m-container-inflatable section:target section > .m-note.m-primary {
+  border-left-color: #a5c9ea;
+}
+.m-container-inflatable section:target > .m-note.m-success,
+.m-container-inflatable section:target section > .m-note.m-success {
+  border-left-color: #3bd267;
+}
+.m-container-inflatable section:target > .m-note.m-warning,
+.m-container-inflatable section:target section > .m-note.m-warning {
+  border-left-color: #c7cf2f;
+}
+.m-container-inflatable section:target > .m-note.m-danger,
+.m-container-inflatable section:target section > .m-note.m-danger {
+  border-left-color: #cd3431;
+}
+.m-container-inflatable section:target > .m-note.m-info,
+.m-container-inflatable section:target section > .m-note.m-info {
+  border-left-color: #2f83cc;
+}
+.m-container-inflatable section:target > .m-note.m-dim,
+.m-container-inflatable section:target section > .m-note.m-dim {
+  border-left-color: #747474;
+}
+pre.m-code span.hll {
+  margin-left: -1.0rem;
+  margin-right: -1.0rem;
+  padding-left: 1.0rem;
+}
+pre.m-code.m-inverted {
+  color: rgba(230, 230, 230, 0.33);
+}
+pre.m-code.m-inverted > span {
+  opacity: 0.3333;
+}
+pre.m-code.m-inverted > span.hll {
+  color: #dcdcdc;
+  opacity: 1;
+  background-color: transparent;
+  border-color: transparent;
+}
+div.m-math {
+  overflow-x: auto;
+  overflow-y: hidden;
+  text-align: center;
+}
+div.m-math svg, svg.m-math { fill: #dcdcdc; }
+div.m-math.m-default svg, svg.m-math.m-default { fill: #dcdcdc; }
+div.m-math.m-primary svg, svg.m-math.m-primary { fill: #a5c9ea; }
+div.m-math.m-success svg, svg.m-math.m-success { fill: #3bd267; }
+div.m-math.m-warning svg, svg.m-math.m-warning { fill: #c7cf2f; }
+div.m-math.m-danger svg, svg.m-math.m-danger { fill: #cd3431; }
+div.m-math.m-info svg, svg.m-math.m-info { fill: #2f83cc; }
+div.m-math.m-dim svg, svg.m-math.m-dim { fill: #747474; }
+p, ul, ol, dl, blockquote, pre, figure.m-code-figure, figure.m-console-figure,
+hr, article, article > header, article section,
+.m-note, .m-frame, .m-block, .m-button,
+div.m-scroll, table.m-table, div.m-image, img.m-image,
+figure.m-figure, .m-imagegrid, div.m-math {
+  margin-bottom: 1rem;
+}
+p:last-child, ul:last-child, ol:last-child, dl:last-child, blockquote:last-child,
+pre:last-child, figure.m-code-figure:last-child, figure.m-console-figure:last-child,
+hr:last-child, article:last-child, article section:last-child,
+.m-note:last-child, .m-frame:last-child, .m-block:last-child, .m-button:last-child,
+table.m-table:last-child, img.m-image:last-child, div.m-image:last-child,
+figure.m-figure:last-child, .m-imagegrid:last-child, div.m-math:last-child {
+  margin-bottom: 0;
+}
+li > p:last-child, li > blockquote:last-child, li > pre:last-child,
+li > figure.m-code-figure:last-child, li > figure.m-console-figure:last-child,
+li > .m-note:last-child, li > .m-frame:last-child, li > .m-block:last-child,
+li > .m-button:last-child, li > div.m-scroll:last-child,
+li > table.m-table:last-child, li > div.m-image:last-child,
+li > img.m-image:last-child, li > figure.m-figure:last-child,
+li > div.m-math:last-child {
+  margin-bottom: 1rem;
+}
+li > p:last-child, li:last-child > blockquote:last-child, li:last-child > pre:last-child,
+li:last-child > figure.m-code-figure:last-child, li:last-child > figure.m-console-figure:last-child,
+li:last-child > .m-note:last-child, li:last-child > .m-frame:last-child, li:last-child > .m-block:last-child,
+li:last-child > .m-button:last-child, li:last-child > div.m-scroll:last-child,
+li:last-child > table.m-table:last-child, li:last-child > div.m-image:last-child,
+li:last-child > img.m-image:last-child, li:last-child > figure.m-figure:last-child,
+li:last-child > div.m-math:last-child {
+  margin-bottom: 0;
+}
+
+.m-code .hll { background-color: #34424d }
+.m-code .c { color: #a5c9ea }
+.m-code .k { color: #ffffff; font-weight: bold }
+.m-code .n { color: #dcdcdc }
+.m-code .o { color: #aaaaaa }
+.m-code .p { color: #aaaaaa }
+.m-code .ch { color: #a5c9ea }
+.m-code .cm { color: #a5c9ea }
+.m-code .cp { color: #3bd267 }
+.m-code .cpf { color: #c7cf2f }
+.m-code .c1 { color: #a5c9ea }
+.m-code .cs { color: #a5c9ea }
+.m-code .ge { color: #e6e6e6; font-style: italic }
+.m-code .gh { color: #ffffff; font-weight: bold }
+.m-code .gs { color: #e6e6e6; font-weight: bold }
+.m-code .kc { color: #ffffff; font-weight: bold }
+.m-code .kd { color: #ffffff; font-weight: bold }
+.m-code .kn { color: #ffffff; font-weight: bold }
+.m-code .kp { color: #ffffff; font-weight: bold }
+.m-code .kr { color: #ffffff; font-weight: bold }
+.m-code .kt { color: #ffffff; font-weight: bold }
+.m-code .m { color: #c7cf2f }
+.m-code .s { color: #e07f7c }
+.m-code .na { color: #dcdcdc; font-weight: bold }
+.m-code .nb { color: #ffffff; font-weight: bold }
+.m-code .nc { color: #dcdcdc; font-weight: bold }
+.m-code .no { color: #dcdcdc }
+.m-code .nd { color: #dcdcdc }
+.m-code .ni { color: #dcdcdc }
+.m-code .ne { color: #dcdcdc }
+.m-code .nf { color: #dcdcdc }
+.m-code .nl { color: #dcdcdc }
+.m-code .nn { color: #dcdcdc }
+.m-code .nx { color: #dcdcdc }
+.m-code .py { color: #dcdcdc }
+.m-code .nt { color: #dcdcdc; font-weight: bold }
+.m-code .nv { color: #c7cf2f }
+.m-code .ow { color: #dcdcdc; font-weight: bold }
+.m-code .mb { color: #c7cf2f }
+.m-code .mf { color: #c7cf2f }
+.m-code .mh { color: #c7cf2f }
+.m-code .mi { color: #c7cf2f }
+.m-code .mo { color: #c7cf2f }
+.m-code .sa { color: #e07f7c }
+.m-code .sb { color: #e07f7c }
+.m-code .sc { color: #e07cdc }
+.m-code .dl { color: #e07f7c }
+.m-code .sd { color: #e07f7c }
+.m-code .s2 { color: #e07f7c }
+.m-code .se { color: #e07f7c }
+.m-code .sh { color: #e07f7c }
+.m-code .si { color: #e07f7c }
+.m-code .sx { color: #e07f7c }
+.m-code .sr { color: #e07f7c }
+.m-code .s1 { color: #e07f7c }
+.m-code .ss { color: #e07f7c }
+.m-code .bp { color: #ffffff; font-weight: bold }
+.m-code .fm { color: #dcdcdc }
+.m-code .vc { color: #c7cf2f }
+.m-code .vg { color: #c7cf2f }
+.m-code .vi { color: #c7cf2f }
+.m-code .vm { color: #c7cf2f }
+.m-code .il { color: #c7cf2f }
+
+.m-console .hll { background-color: #ffffcc }
+.m-console .g-AnsiBlack { color: #000000 }
+.m-console .g-AnsiBlue { color: #3f3fd1 }
+.m-console .g-AnsiBrightBlack { color: #686868; font-weight: bold }
+.m-console .g-AnsiBrightBlue { color: #5454ff; font-weight: bold }
+.m-console .g-AnsiBrightCyan { color: #54ffff; font-weight: bold }
+.m-console .g-AnsiBrightDefault { color: #ffffff; font-weight: bold }
+.m-console .g-AnsiBrightGreen { color: #54ff54; font-weight: bold }
+.m-console .g-AnsiBrightMagenta { color: #ff54ff; font-weight: bold }
+.m-console .g-AnsiBrightRed { color: #ff5454; font-weight: bold }
+.m-console .g-AnsiBrightWhite { color: #ffffff; font-weight: bold }
+.m-console .g-AnsiBrightYellow { color: #ffff54; font-weight: bold }
+.m-console .g-AnsiCyan { color: #18b2b2 }
+.m-console .g-AnsiDefault { color: #b2b2b2 }
+.m-console .g-AnsiGreen { color: #18b218 }
+.m-console .g-AnsiMagenta { color: #b218b2 }
+.m-console .g-AnsiRed { color: #b21818 }
+.m-console .g-AnsiWhite { color: #b2b2b2 }
+.m-console .g-AnsiYellow { color: #b26818 }
+.m-console .go { color: #b2b2b2 }
+.m-console .gp { color: #54ffff; font-weight: bold }
+.m-console .w { color: #b2b2b2 }
+
+a.m-dox, a.m-dox-self, a.m-dox-external,
+ul.m-dox li.m-dox-expansible > a:first-child, ul.m-dox li.m-dox-collapsible > a:first-child {
+  text-decoration: none;
+}
+a.m-dox, a.m-dox-self {
+  font-weight: bold;
+}
+ul.m-dox li.m-dox-expansible > a:first-child,
+ul.m-dox li.m-dox-collapsible > a:first-child,
+ul.m-dox li.m-dox-expansible > a:first-child:hover,
+ul.m-dox li.m-dox-expansible > a:first-child:focus,
+ul.m-dox li.m-dox-expansible > a:first-child:active,
+ul.m-dox li.m-dox-collapsible > a:first-child:hover,
+ul.m-dox li.m-dox-collapsible > a:first-child:focus,
+ul.m-dox li.m-dox-collapsible > a:first-child:active {
+  color: #dcdcdc;
+}
+a.m-dox-self,
+ul.m-dox li.m-dox-expansible > a:first-child:before,
+ul.m-dox li.m-dox-collapsible > a:first-child:before {
+  color: #a5c9ea;
+}
+a.m-dox-self:hover, a.m-dox-self:focus, a.m-dox-self:active,
+ul.m-dox li.m-dox-expansible > a:first-child:hover::before,
+ul.m-dox li.m-dox-expansible > a:first-child:focus::before,
+ul.m-dox li.m-dox-expansible > a:first-child:active::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:hover::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:focus::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:active::before {
+  color: #dcdcdc;
+}
+h3 a.m-dox-external {
+  font-weight: normal;
+}
+span.m-dox-wrap-bumper {
+  margin-right: -1rem;
+}
+span.m-dox-wrap {
+  padding-left: 1rem;
+  display: inline-block;
+  vertical-align: text-top;
+  white-space: pre-line;
+  max-width: 100%;
+}
+dl.m-dox dd {
+  margin-bottom: 0.5rem;
+}
+ul.m-dox {
+  list-style: none;
+  margin-left:  1.0375rem;
+  padding-left: 0.9rem;
+  border-left-color: #405363;
+  border-left-width: 0.0625rem;
+  border-left-style: solid;
+}
+ul.m-dox li {
+  text-indent: -1rem;
+  padding-left: 1rem;
+}
+ul.m-dox li.m-dox-expansible > ul {
+  display: none;
+}
+ul.m-dox li.m-dox-expansible, ul.m-dox li.m-dox-collapsible {
+  padding-left: 0.6rem;
+}
+ul.m-dox li.m-dox-expansible > ul.m-dox, ul.m-dox li.m-dox-collapsible > ul.m-dox {
+  margin-left: 0.5rem;
+}
+ul.m-dox li.m-dox-expansible > a:first-child:before, ul.m-dox li.m-dox-collapsible > a:first-child:before {
+  background-color: #2f363f;
+  display: inline-block;
+  width: 0.4rem;
+  font-weight: bold;
+}
+ul.m-dox li.m-dox-expansible > a:first-child:before { content: '⊕'; }
+ul.m-dox li.m-dox-collapsible > a:first-child:before { content: '⊖'; }
+h1 .m-dox-template {
+  font-size: 1.3rem;
+  font-weight: normal;
+}
+h3 .m-dox-template {
+  font-size: 1rem;
+  font-weight: normal;
+}
+.m-dox-template, dl.m-dox dd, ul.m-dox li > span.m-dox {
+  color: #747474;
+}
+.m-dox-template a, dl.m-dox dd a, ul.m-dox li > span.m-dox a {
+  color: #acacac;
+}
+.m-dox-template a:hover, .m-dox-template a:focus, .m-dox-template a:active,
+dl.m-dox dd a:hover, dl.m-dox dd a:focus, dl.m-dox dd a:active,
+ul.m-dox li > span.m-dox a:hover, ul.m-dox li > span.m-dox a:focus, ul.m-dox li > span.m-dox a:active {
+  color: #747474;
+}
+article section.m-dox-details > div {
+  margin-top: 0;
+  margin-left: 0;
+  margin-right: 0;
+  position: relative;
+  padding: 1rem;
+}
+article section.m-dox-details > div::before {
+  position: absolute;
+  content: ' ';
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: -1;
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: 0.2rem;
+  border-color: #22272e;
+}
+article section.m-dox-details > div > h3:first-child {
+  position: relative;
+  margin: -1rem -1rem 1rem -1rem;
+  padding: 0.5rem 1rem;
+  background-color: #22272e;
+  border-top-left-radius: 0.2rem;
+  border-top-right-radius: 0.2rem;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+}
+article section.m-dox-details:target {
+  border-color: transparent;
+}
+article section.m-dox-details:target > div {
+  z-index: 1;
+}
+.m-container-inflatable > .m-row > [class*='m-col-'] section.m-dox-details > div {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+.m-container-inflatable section.m-dox-details:target > div > h3:first-child,
+.m-container-inflatable section.m-dox-details:target section > div > h3:first-child {
+  margin-left: -1.0rem;
+  border-left-style: solid;
+  border-left-color: #dcdcdc;
+  border-left-width: 0.25rem;
+  padding-left: 0.75rem;
+}
+.m-container-inflatable section.m-dox-details:target > div::before,
+.m-container-inflatable section-dox-details:target section > div.m::before {
+  border-left-width: 0.25rem;
+  border-left-color: #a5c9ea;
+}
diff --git a/css/m-dark.doxygen.compiled.css b/css/m-dark.doxygen.compiled.css
new file mode 100644 (file)
index 0000000..cc91775
--- /dev/null
@@ -0,0 +1,174 @@
+/* Generated using `./postprocess.py m-dark.css m-doxygen.css --no-import -o m-dark.doxygen.compiled.css`. Do not edit. */
+
+/*
+    This file is part of m.css.
+
+    Copyright © 2017 Vladimír Vondruš <mosra@centrum.cz>
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+*/
+
+a.m-dox, a.m-dox-self, a.m-dox-external,
+ul.m-dox li.m-dox-expansible > a:first-child, ul.m-dox li.m-dox-collapsible > a:first-child {
+  text-decoration: none;
+}
+a.m-dox, a.m-dox-self {
+  font-weight: bold;
+}
+ul.m-dox li.m-dox-expansible > a:first-child,
+ul.m-dox li.m-dox-collapsible > a:first-child,
+ul.m-dox li.m-dox-expansible > a:first-child:hover,
+ul.m-dox li.m-dox-expansible > a:first-child:focus,
+ul.m-dox li.m-dox-expansible > a:first-child:active,
+ul.m-dox li.m-dox-collapsible > a:first-child:hover,
+ul.m-dox li.m-dox-collapsible > a:first-child:focus,
+ul.m-dox li.m-dox-collapsible > a:first-child:active {
+  color: #dcdcdc;
+}
+a.m-dox-self,
+ul.m-dox li.m-dox-expansible > a:first-child:before,
+ul.m-dox li.m-dox-collapsible > a:first-child:before {
+  color: #a5c9ea;
+}
+a.m-dox-self:hover, a.m-dox-self:focus, a.m-dox-self:active,
+ul.m-dox li.m-dox-expansible > a:first-child:hover::before,
+ul.m-dox li.m-dox-expansible > a:first-child:focus::before,
+ul.m-dox li.m-dox-expansible > a:first-child:active::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:hover::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:focus::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:active::before {
+  color: #dcdcdc;
+}
+h3 a.m-dox-external {
+  font-weight: normal;
+}
+span.m-dox-wrap-bumper {
+  margin-right: -1rem;
+}
+span.m-dox-wrap {
+  padding-left: 1rem;
+  display: inline-block;
+  vertical-align: text-top;
+  white-space: pre-line;
+  max-width: 100%;
+}
+dl.m-dox dd {
+  margin-bottom: 0.5rem;
+}
+ul.m-dox {
+  list-style: none;
+  margin-left:  1.0375rem;
+  padding-left: 0.9rem;
+  border-left-color: #405363;
+  border-left-width: 0.0625rem;
+  border-left-style: solid;
+}
+ul.m-dox li {
+  text-indent: -1rem;
+  padding-left: 1rem;
+}
+ul.m-dox li.m-dox-expansible > ul {
+  display: none;
+}
+ul.m-dox li.m-dox-expansible, ul.m-dox li.m-dox-collapsible {
+  padding-left: 0.6rem;
+}
+ul.m-dox li.m-dox-expansible > ul.m-dox, ul.m-dox li.m-dox-collapsible > ul.m-dox {
+  margin-left: 0.5rem;
+}
+ul.m-dox li.m-dox-expansible > a:first-child:before, ul.m-dox li.m-dox-collapsible > a:first-child:before {
+  background-color: #2f363f;
+  display: inline-block;
+  width: 0.4rem;
+  font-weight: bold;
+}
+ul.m-dox li.m-dox-expansible > a:first-child:before { content: '⊕'; }
+ul.m-dox li.m-dox-collapsible > a:first-child:before { content: '⊖'; }
+h1 .m-dox-template {
+  font-size: 1.3rem;
+  font-weight: normal;
+}
+h3 .m-dox-template {
+  font-size: 1rem;
+  font-weight: normal;
+}
+.m-dox-template, dl.m-dox dd, ul.m-dox li > span.m-dox {
+  color: #747474;
+}
+.m-dox-template a, dl.m-dox dd a, ul.m-dox li > span.m-dox a {
+  color: #acacac;
+}
+.m-dox-template a:hover, .m-dox-template a:focus, .m-dox-template a:active,
+dl.m-dox dd a:hover, dl.m-dox dd a:focus, dl.m-dox dd a:active,
+ul.m-dox li > span.m-dox a:hover, ul.m-dox li > span.m-dox a:focus, ul.m-dox li > span.m-dox a:active {
+  color: #747474;
+}
+article section.m-dox-details > div {
+  margin-top: 0;
+  margin-left: 0;
+  margin-right: 0;
+  position: relative;
+  padding: 1rem;
+}
+article section.m-dox-details > div::before {
+  position: absolute;
+  content: ' ';
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: -1;
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: 0.2rem;
+  border-color: #22272e;
+}
+article section.m-dox-details > div > h3:first-child {
+  position: relative;
+  margin: -1rem -1rem 1rem -1rem;
+  padding: 0.5rem 1rem;
+  background-color: #22272e;
+  border-top-left-radius: 0.2rem;
+  border-top-right-radius: 0.2rem;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+}
+article section.m-dox-details:target {
+  border-color: transparent;
+}
+article section.m-dox-details:target > div {
+  z-index: 1;
+}
+.m-container-inflatable > .m-row > [class*='m-col-'] section.m-dox-details > div {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+.m-container-inflatable section.m-dox-details:target > div > h3:first-child,
+.m-container-inflatable section.m-dox-details:target section > div > h3:first-child {
+  margin-left: -1.0rem;
+  border-left-style: solid;
+  border-left-color: #dcdcdc;
+  border-left-width: 0.25rem;
+  padding-left: 0.75rem;
+}
+.m-container-inflatable section.m-dox-details:target > div::before,
+.m-container-inflatable section-dox-details:target section > div.m::before {
+  border-left-width: 0.25rem;
+  border-left-color: #a5c9ea;
+}
diff --git a/css/m-doxygen.css b/css/m-doxygen.css
new file mode 100644 (file)
index 0000000..5167803
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+    This file is part of m.css.
+
+    Copyright © 2017 Vladimír Vondruš <mosra@centrum.cz>
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+*/
+
+a.m-dox, a.m-dox-self, a.m-dox-external,
+ul.m-dox li.m-dox-expansible > a:first-child, ul.m-dox li.m-dox-collapsible > a:first-child {
+  text-decoration: none;
+}
+a.m-dox, a.m-dox-self {
+  font-weight: bold;
+}
+ul.m-dox li.m-dox-expansible > a:first-child,
+ul.m-dox li.m-dox-collapsible > a:first-child,
+ul.m-dox li.m-dox-expansible > a:first-child:hover,
+ul.m-dox li.m-dox-expansible > a:first-child:focus,
+ul.m-dox li.m-dox-expansible > a:first-child:active,
+ul.m-dox li.m-dox-collapsible > a:first-child:hover,
+ul.m-dox li.m-dox-collapsible > a:first-child:focus,
+ul.m-dox li.m-dox-collapsible > a:first-child:active {
+  color: var(--color);
+}
+a.m-dox-self,
+ul.m-dox li.m-dox-expansible > a:first-child:before,
+ul.m-dox li.m-dox-collapsible > a:first-child:before {
+  color: var(--article-heading-color);
+}
+a.m-dox-self:hover, a.m-dox-self:focus, a.m-dox-self:active,
+ul.m-dox li.m-dox-expansible > a:first-child:hover::before,
+ul.m-dox li.m-dox-expansible > a:first-child:focus::before,
+ul.m-dox li.m-dox-expansible > a:first-child:active::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:hover::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:focus::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:active::before {
+  color: var(--article-heading-active-color);
+}
+h3 a.m-dox-external {
+  font-weight: normal;
+}
+span.m-dox-wrap-bumper {
+  margin-right: -1rem;
+}
+span.m-dox-wrap {
+  padding-left: 1rem;
+  display: inline-block;
+  vertical-align: text-top;
+  white-space: pre-line;
+  max-width: 100%; /* otherwise horizontal scrollbars, wtf */
+}
+dl.m-dox dd {
+  margin-bottom: 0.5rem;
+}
+ul.m-dox {
+  list-style: none;
+  margin-left:  1.0375rem;
+  padding-left: 0.9rem;
+  border-left-color: var(--line-color);
+  border-left-width: 0.0625rem;
+  border-left-style: solid;
+}
+ul.m-dox li {
+  text-indent: -1rem;
+  padding-left: 1rem;
+}
+ul.m-dox li.m-dox-expansible > ul {
+  display: none;
+}
+ul.m-dox li.m-dox-expansible, ul.m-dox li.m-dox-collapsible {
+  padding-left: 0.6rem;
+}
+ul.m-dox li.m-dox-expansible > ul.m-dox, ul.m-dox li.m-dox-collapsible > ul.m-dox {
+  margin-left: 0.5rem;
+}
+ul.m-dox li.m-dox-expansible > a:first-child:before, ul.m-dox li.m-dox-collapsible > a:first-child:before {
+  background-color: var(--background-color);
+  display: inline-block;
+  width: 0.4rem;
+  font-weight: bold;
+}
+ul.m-dox li.m-dox-expansible > a:first-child:before { content: '⊕'; }
+ul.m-dox li.m-dox-collapsible > a:first-child:before { content: '⊖'; }
+
+h1 .m-dox-template {
+  font-size: 1.3rem;
+  font-weight: normal;
+}
+h3 .m-dox-template {
+  font-size: 1rem;
+  font-weight: normal;
+}
+.m-dox-template, dl.m-dox dd, ul.m-dox li > span.m-dox {
+  color: var(--dim-color);
+}
+.m-dox-template a, dl.m-dox dd a, ul.m-dox li > span.m-dox a {
+  color: var(--dim-link-color);
+}
+.m-dox-template a:hover, .m-dox-template a:focus, .m-dox-template a:active,
+dl.m-dox dd a:hover, dl.m-dox dd a:focus, dl.m-dox dd a:active,
+ul.m-dox li > span.m-dox a:hover, ul.m-dox li > span.m-dox a:focus, ul.m-dox li > span.m-dox a:active {
+  color: var(--dim-link-active-color);
+}
+
+article section.m-dox-details > div {
+  margin-top: 0;
+  margin-left: 0;
+  margin-right: 0;
+  position: relative;
+  padding: 1rem;
+}
+article section.m-dox-details > div::before {
+  position: absolute;
+  content: ' ';
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: -1; /* so it doesn't make the contents inactive */
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: var(--border-radius);
+  border-color: var(--code-background-color);
+}
+article section.m-dox-details > div > h3:first-child {
+  position: relative; /* so it's above the border */
+  margin: -1rem -1rem 1rem -1rem;
+  padding: 0.5rem 1rem;
+  background-color: var(--code-background-color);
+  border-top-left-radius: var(--border-radius);
+  border-top-right-radius: var(--border-radius);
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+}
+article section.m-dox-details:target {
+  border-color: transparent; /* to preserve rounded corners */
+}
+article section.m-dox-details:target > div {
+  z-index: 1; /* so the selection border isn't above figure border */
+}
+
+.m-container-inflatable > .m-row > [class*='m-col-'] section.m-dox-details > div {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+
+.m-container-inflatable section.m-dox-details:target > div > h3:first-child,
+.m-container-inflatable section.m-dox-details:target section > div > h3:first-child {
+  margin-left: -1.0rem;
+  border-left-style: solid;
+  border-left-color: var(--article-heading-active-color);
+  border-left-width: 0.25rem;
+  padding-left: 0.75rem;
+}
+.m-container-inflatable section.m-dox-details:target > div::before,
+.m-container-inflatable section-dox-details:target section > div.m::before {
+  border-left-width: 0.25rem;
+  border-left-color: var(--article-heading-color);
+}
+
+/* kate: indent-width 2; */
diff --git a/css/m-light+doxygen.compiled.css b/css/m-light+doxygen.compiled.css
new file mode 100644 (file)
index 0000000..ea4d48a
--- /dev/null
@@ -0,0 +1,1833 @@
+/* Generated using `./postprocess.py m-light.css m-doxygen.css -o m-light+doxygen.compiled.css`. Do not edit. */
+
+/*
+    This file is part of m.css.
+
+    Copyright © 2017 Vladimír Vondruš <mosra@centrum.cz>
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+*/
+
+*, ::before, ::after { box-sizing: border-box; }
+body { margin: 0; }
+.m-container {
+  width: 100%;
+  margin: auto;
+  padding-left: 1rem;
+  padding-right: 1rem;
+}
+.m-row {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+.m-row:after {
+  content: ' ';
+  clear: both;
+  display: table;
+}
+[class*='m-col-'] {
+  position: relative;
+  padding: 1rem;
+}
+[class*='m-clearfix-']::after {
+  display: block;
+  content: ' ';
+  clear: both;
+}
+[class*='m-show-'] {
+  display: none;
+}
+[class*='m-col-'].m-left-s, [class*='m-col-'].m-right-s, [class*='m-col-'].m-center-s,
+[class*='m-col-'].m-left-m, [class*='m-col-'].m-right-m, [class*='m-col-'].m-center-m,
+[class*='m-col-'].m-left-l, [class*='m-col-'].m-right-l, [class*='m-col-'].m-center-l {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+.m-row > [class*='m-col-'].m-left-s, .m-row > [class*='m-col-'].m-right-s, .m-row > [class*='m-col-'].m-center-s,
+.m-row > [class*='m-col-'].m-left-m, .m-row > [class*='m-col-'].m-right-m, .m-row > [class*='m-col-'].m-center-m,
+.m-row > [class*='m-col-'].m-left-l, .m-row > [class*='m-col-'].m-right-l  .m-row > [class*='m-col-'].m-center-l {
+  margin-left: 0;
+  margin-right: 0;
+}
+.m-container.m-nopad, [class*='m-col-'].m-nopad,
+.m-container.m-nopadx, [class*='m-col-'].m-nopadx,
+.m-container.m-nopadl, [class*='m-col-'].m-nopadl {
+  padding-left: 0;
+}
+.m-container.m-nopad, [class*='m-col-'].m-nopad,
+.m-container.m-nopadx, [class*='m-col-'].m-nopadx,
+.m-container.m-nopadr, [class*='m-col-'].m-nopadr {
+  padding-right: 0;
+}
+[class*='m-col-'].m-nopad, [class*='m-col-'].m-nopady, [class*='m-col-'].m-nopadt {
+  padding-top: 0;
+}
+[class*='m-col-'].m-nopad, [class*='m-col-'].m-nopady, [class*='m-col-'].m-nopadb {
+  padding-bottom: 0;
+}
+[class*='m-col-t-'] { float: left; }
+[class*='m-col-t-'].m-left-t, [class*='m-col-t-'].m-right-t {
+  padding-top: 0px;
+  padding-bottom: 0px;
+}
+.m-left-t {
+  float: left;
+}
+.m-right-t, [class*='m-col-t-'].m-right-t {
+  float: right;
+}
+.m-center-t, [class*='m-col-t-'].m-center-t {
+  float: none;
+}
+[class*='m-col-t-'].m-left-t {
+  margin-left: -1rem;
+}
+[class*='m-col-t-'].m-right-t {
+  margin-right: -1rem;
+}
+.m-row > [class*='m-col-t-'].m-left-t {
+  margin-left: 0;
+}
+.m-row > [class*='m-col-t-'].m-right-t {
+  margin-right: 0;
+}
+.m-center-t, [class*='m-col-t-'].m-center-t {
+  margin-left: auto;
+  margin-right: auto;
+  float: none;
+}
+.m-col-t-1  { width: calc(1  * 100% / 12); }
+.m-col-t-2  { width: calc(2  * 100% / 12); }
+.m-col-t-3  { width: calc(3  * 100% / 12); }
+.m-col-t-4  { width: calc(4  * 100% / 12); }
+.m-col-t-5  { width: calc(5  * 100% / 12); }
+.m-col-t-6  { width: calc(6  * 100% / 12); }
+.m-col-t-7  { width: calc(7  * 100% / 12); }
+.m-col-t-8  { width: calc(8  * 100% / 12); }
+.m-col-t-9  { width: calc(9  * 100% / 12); }
+.m-col-t-10 { width: calc(10 * 100% / 12); }
+.m-col-t-11 { width: calc(11 * 100% / 12); }
+.m-col-t-12 { width: calc(12 * 100% / 12); }
+.m-push-t-1  { left: calc(1  * 100% / 12); }
+.m-push-t-2  { left: calc(2  * 100% / 12); }
+.m-push-t-3  { left: calc(3  * 100% / 12); }
+.m-push-t-4  { left: calc(4  * 100% / 12); }
+.m-push-t-5  { left: calc(5  * 100% / 12); }
+.m-push-t-6  { left: calc(6  * 100% / 12); }
+.m-push-t-7  { left: calc(7  * 100% / 12); }
+.m-push-t-8  { left: calc(8  * 100% / 12); }
+.m-push-t-9  { left: calc(9  * 100% / 12); }
+.m-push-t-10 { left: calc(10 * 100% / 12); }
+.m-push-t-11 { left: calc(11 * 100% / 12); }
+.m-pull-t-1  { right: calc(1  * 100% / 12); }
+.m-pull-t-2  { right: calc(2  * 100% / 12); }
+.m-pull-t-3  { right: calc(3  * 100% / 12); }
+.m-pull-t-4  { right: calc(4  * 100% / 12); }
+.m-pull-t-5  { right: calc(5  * 100% / 12); }
+.m-pull-t-6  { right: calc(6  * 100% / 12); }
+.m-pull-t-7  { right: calc(7  * 100% / 12); }
+.m-pull-t-8  { right: calc(8  * 100% / 12); }
+.m-pull-t-9  { right: calc(9  * 100% / 12); }
+.m-pull-t-10 { right: calc(10 * 100% / 12); }
+.m-pull-t-11 { right: calc(11 * 100% / 12); }
+@media screen and (min-width: 576px) {
+  .m-container { width: 560px; }
+  .m-container-inflatable .m-col-s-10 .m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+  [class*='m-col-s-'] { float: left; }
+  [class*='m-col-s-'].m-left-s, [class*='m-col-s-'].m-right-s {
+    padding-top: 0px;
+    padding-bottom: 0px;
+  }
+  .m-left-s {
+    float: left;
+  }
+  .m-right-s, [class*='m-col-s-'].m-right-s {
+    float: right;
+  }
+  [class*='m-col-s-'].m-left-s {
+    margin-left: -1rem;
+    margin-right: 0;
+  }
+  [class*='m-col-s-'].m-right-s {
+    margin-left: 0;
+    margin-right: -1rem;
+  }
+  .m-row > [class*='m-col-s-'].m-left-s {
+    margin-left: 0;
+  }
+  .m-row > [class*='m-col-s-'].m-right-s {
+    margin-right: 0;
+  }
+  .m-center-s, [class*='m-col-s-'].m-center-s {
+    margin-left: auto;
+    margin-right: auto;
+    float: none;
+  }
+  .m-col-s-1  { width: calc(1  * 100% / 12); }
+  .m-col-s-2  { width: calc(2  * 100% / 12); }
+  .m-col-s-3  { width: calc(3  * 100% / 12); }
+  .m-col-s-4  { width: calc(4  * 100% / 12); }
+  .m-col-s-5  { width: calc(5  * 100% / 12); }
+  .m-col-s-6  { width: calc(6  * 100% / 12); }
+  .m-col-s-7  { width: calc(7  * 100% / 12); }
+  .m-col-s-8  { width: calc(8  * 100% / 12); }
+  .m-col-s-9  { width: calc(9  * 100% / 12); }
+  .m-col-s-10 { width: calc(10 * 100% / 12); }
+  .m-col-s-11 { width: calc(11 * 100% / 12); }
+  .m-col-s-12 { width: calc(12 * 100% / 12); }
+  .m-push-s-0  { left: calc(0  * 100% / 12); }
+  .m-push-s-1  { left: calc(1  * 100% / 12); }
+  .m-push-s-2  { left: calc(2  * 100% / 12); }
+  .m-push-s-3  { left: calc(3  * 100% / 12); }
+  .m-push-s-4  { left: calc(4  * 100% / 12); }
+  .m-push-s-5  { left: calc(5  * 100% / 12); }
+  .m-push-s-6  { left: calc(6  * 100% / 12); }
+  .m-push-s-7  { left: calc(7  * 100% / 12); }
+  .m-push-s-8  { left: calc(8  * 100% / 12); }
+  .m-push-s-9  { left: calc(9  * 100% / 12); }
+  .m-push-s-10 { left: calc(10 * 100% / 12); }
+  .m-push-s-11 { left: calc(11 * 100% / 12); }
+  .m-pull-s-0  { right: calc(0  * 100% / 12); }
+  .m-pull-s-1  { right: calc(1  * 100% / 12); }
+  .m-pull-s-2  { right: calc(2  * 100% / 12); }
+  .m-pull-s-3  { right: calc(3  * 100% / 12); }
+  .m-pull-s-4  { right: calc(4  * 100% / 12); }
+  .m-pull-s-5  { right: calc(5  * 100% / 12); }
+  .m-pull-s-6  { right: calc(6  * 100% / 12); }
+  .m-pull-s-7  { right: calc(7  * 100% / 12); }
+  .m-pull-s-8  { right: calc(8  * 100% / 12); }
+  .m-pull-s-9  { right: calc(9  * 100% / 12); }
+  .m-pull-s-10 { right: calc(10 * 100% / 12); }
+  .m-pull-s-11 { right: calc(11 * 100% / 12); }
+  .m-clearfix-t::after { display: none; }
+  .m-hide-s { display: none; }
+  .m-show-s { display: block; }
+  .m-col-s-none {
+    width: auto;
+    float: none;
+  }
+}
+@media screen and (min-width: 768px) {
+  .m-container { width: 750px; }
+  .m-container-inflatable .m-col-m-10 .m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+  [class*='m-col-m-'] { float: left; }
+  [class*='m-col-m-'].m-left-m, [class*='m-col-m-'].m-right-m {
+    padding-top: 0px;
+    padding-bottom: 0px;
+  }
+  .m-left-m {
+    float: left;
+  }
+  .m-right-m, [class*='m-col-m-'].m-right-m {
+    float: right;
+  }
+  [class*='m-col-m-'].m-left-m {
+    margin-left: -1rem;
+    margin-right: 0;
+  }
+  [class*='m-col-m-'].m-right-m {
+    margin-left: 0;
+    margin-right: -1rem;
+  }
+  .m-row > [class*='m-col-m-'].m-left-m {
+    margin-left: 0;
+  }
+  .m-row > [class*='m-col-m-'].m-right-m {
+    margin-right: 0;
+  }
+  .m-center-m, [class*='m-col-m-'].m-center-m {
+    margin-left: auto;
+    margin-right: auto;
+    float: none;
+  }
+  .m-col-m-1  { width: calc(1  * 100% / 12); }
+  .m-col-m-2  { width: calc(2  * 100% / 12); }
+  .m-col-m-3  { width: calc(3  * 100% / 12); }
+  .m-col-m-4  { width: calc(4  * 100% / 12); }
+  .m-col-m-5  { width: calc(5  * 100% / 12); }
+  .m-col-m-6  { width: calc(6  * 100% / 12); }
+  .m-col-m-7  { width: calc(7  * 100% / 12); }
+  .m-col-m-8  { width: calc(8  * 100% / 12); }
+  .m-col-m-9  { width: calc(9  * 100% / 12); }
+  .m-col-m-10 { width: calc(10 * 100% / 12); }
+  .m-col-m-11 { width: calc(11 * 100% / 12); }
+  .m-col-m-12 { width: calc(12 * 100% / 12); }
+  .m-push-m-0  { left: calc(0  * 100% / 12); }
+  .m-push-m-1  { left: calc(1  * 100% / 12); }
+  .m-push-m-2  { left: calc(2  * 100% / 12); }
+  .m-push-m-3  { left: calc(3  * 100% / 12); }
+  .m-push-m-4  { left: calc(4  * 100% / 12); }
+  .m-push-m-5  { left: calc(5  * 100% / 12); }
+  .m-push-m-6  { left: calc(6  * 100% / 12); }
+  .m-push-m-7  { left: calc(7  * 100% / 12); }
+  .m-push-m-8  { left: calc(8  * 100% / 12); }
+  .m-push-m-9  { left: calc(9  * 100% / 12); }
+  .m-push-m-10 { left: calc(10 * 100% / 12); }
+  .m-push-m-11 { left: calc(11 * 100% / 12); }
+  .m-pull-m-0  { right: calc(0  * 100% / 12); }
+  .m-pull-m-1  { right: calc(1  * 100% / 12); }
+  .m-pull-m-2  { right: calc(2  * 100% / 12); }
+  .m-pull-m-3  { right: calc(3  * 100% / 12); }
+  .m-pull-m-4  { right: calc(4  * 100% / 12); }
+  .m-pull-m-5  { right: calc(5  * 100% / 12); }
+  .m-pull-m-6  { right: calc(6  * 100% / 12); }
+  .m-pull-m-7  { right: calc(7  * 100% / 12); }
+  .m-pull-m-8  { right: calc(8  * 100% / 12); }
+  .m-pull-m-9  { right: calc(9  * 100% / 12); }
+  .m-pull-m-10 { right: calc(10 * 100% / 12); }
+  .m-pull-m-11 { right: calc(11 * 100% / 12); }
+  .m-clearfix-s::after { display: none; }
+  .m-hide-m { display: none; }
+  .m-show-m { display: block; }
+  .m-col-m-none {
+    width: auto;
+    float: none;
+  }
+}
+@media screen and (min-width: 992px) {
+  .m-container { width: 960px; }
+  .m-container-inflatable .m-col-l-10 .m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+  [class*='m-col-l-'] { float: left; }
+  [class*='m-col-l-'].m-left-l, [class*='m-col-l-'].m-right-l {
+    padding-top: 0px;
+    padding-bottom: 0px;
+  }
+  .m-left-l {
+    float: left;
+  }
+  .m-right-l, [class*='m-col-l-'].m-right-l {
+    float: right;
+  }
+  [class*='m-col-l-'].m-left-l {
+    margin-left: -1rem;
+    margin-right: 0;
+  }
+  [class*='m-col-l-'].m-right-l {
+    margin-left: 0;
+    margin-right: -1rem;
+  }
+  .m-row > [class*='m-col-l-'].m-left-l {
+    margin-left: 0;
+  }
+  .m-row > [class*='m-col-l-'].m-right-l {
+    margin-right: 0;
+  }
+  .m-center-l, [class*='m-col-l-'].m-center-l {
+    margin-left: auto;
+    margin-right: auto;
+    float: none;
+  }
+  .m-col-l-1  { width: calc(1  * 100% / 12); }
+  .m-col-l-2  { width: calc(2  * 100% / 12); }
+  .m-col-l-3  { width: calc(3  * 100% / 12); }
+  .m-col-l-4  { width: calc(4  * 100% / 12); }
+  .m-col-l-5  { width: calc(5  * 100% / 12); }
+  .m-col-l-6  { width: calc(6  * 100% / 12); }
+  .m-col-l-7  { width: calc(7  * 100% / 12); }
+  .m-col-l-8  { width: calc(8  * 100% / 12); }
+  .m-col-l-9  { width: calc(9  * 100% / 12); }
+  .m-col-l-10 { width: calc(10 * 100% / 12); }
+  .m-col-l-11 { width: calc(11 * 100% / 12); }
+  .m-col-l-12 { width: calc(12 * 100% / 12); }
+  .m-push-l-0  { left: calc(0  * 100% / 12); }
+  .m-push-l-1  { left: calc(1  * 100% / 12); }
+  .m-push-l-2  { left: calc(2  * 100% / 12); }
+  .m-push-l-3  { left: calc(3  * 100% / 12); }
+  .m-push-l-4  { left: calc(4  * 100% / 12); }
+  .m-push-l-5  { left: calc(5  * 100% / 12); }
+  .m-push-l-6  { left: calc(6  * 100% / 12); }
+  .m-push-l-7  { left: calc(7  * 100% / 12); }
+  .m-push-l-8  { left: calc(8  * 100% / 12); }
+  .m-push-l-9  { left: calc(9  * 100% / 12); }
+  .m-push-l-10 { left: calc(10 * 100% / 12); }
+  .m-push-l-11 { left: calc(11 * 100% / 12); }
+  .m-pull-l-0  { right: calc(0  * 100% / 12); }
+  .m-pull-l-1  { right: calc(1  * 100% / 12); }
+  .m-pull-l-2  { right: calc(2  * 100% / 12); }
+  .m-pull-l-3  { right: calc(3  * 100% / 12); }
+  .m-pull-l-4  { right: calc(4  * 100% / 12); }
+  .m-pull-l-5  { right: calc(5  * 100% / 12); }
+  .m-pull-l-6  { right: calc(6  * 100% / 12); }
+  .m-pull-l-7  { right: calc(7  * 100% / 12); }
+  .m-pull-l-8  { right: calc(8  * 100% / 12); }
+  .m-pull-l-9  { right: calc(9  * 100% / 12); }
+  .m-pull-l-10 { right: calc(10 * 100% / 12); }
+  .m-pull-l-11 { right: calc(11 * 100% / 12); }
+  .m-clearfix-m::after { display: none; }
+  .m-hide-l { display: none; }
+  .m-show-l { display: block; }
+  .m-col-l-none {
+    width: auto;
+    float: none;
+  }
+}
+
+html {
+  font-size: 14px;
+  background-color: #ffffff;
+}
+body {
+  font-family: 'Libre Baskerville', serif;
+  font-size: 1rem;
+  color: #000000;
+}
+h1, h2, h3, h4, h5, h6 {
+  margin-top: 0;
+  font-weight: normal;
+}
+h1 {
+  margin-bottom: 1rem;
+}
+h2, h3, h4, h5, h6 {
+  margin-bottom: 0.5rem;
+}
+p, ul, ol, dl {
+  margin-top: 0;
+}
+ul, ol {
+  padding-left: 2rem;
+}
+ul ol, ul ul, ol ol, ol ul {
+  margin-bottom: 0;
+}
+main p {
+  text-indent: 1.5rem;
+  text-align: justify;
+}
+main p.m-noindent, li p, table.m-table td p {
+  text-indent: 0;
+  text-align: left;
+}
+blockquote {
+  margin-top: 0;
+  margin-left: 1rem;
+  margin-right: 1rem;
+  padding: 1rem;
+  border-left-style: solid;
+  border-left-width: 0.25rem;
+}
+hr {
+  width: 75%;
+  border-width: 0.0625rem;
+  border-style: solid;
+}
+blockquote, hr {
+  border-color: #f7e3db;
+}
+pre {
+  font-family: 'Source Code Pro', monospace, monospace, monospace; /* https://en.wikipedia.org/wiki/User:Davidgothberg/Test59 */
+  font-size: 0.9rem;
+  padding: 0.5rem 1rem;
+  color: #5b5b5b;
+  background-color: #fbf0ec;
+  border-radius: 0.2rem;
+  overflow-x: auto;
+  margin-top: 0;
+}
+pre.m-console {
+  background-color: #000000;
+}
+abbr {
+  cursor: help;
+  text-decoration: underline dotted;
+}
+sub, sup {
+  font-size: 0.75rem;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sup { top: -0.35rem; }
+sub { bottom: -0.2rem; }
+a {
+  color: #ea7944;
+}
+a:hover, a:focus, a:active {
+  color: #cb4b16;
+}
+a img { border: 0; }
+mark {
+  padding: 0.0625rem;
+  background-color: #e6e69c;
+  color: #4c93d3;
+}
+code {
+  font-family: 'Source Code Pro', monospace, monospace, monospace;
+  font-size: 0.9rem;
+  padding: 0.125rem;
+  color: #5b5b5b;
+  background-color: #fbf0ec;
+}
+code.m-console {
+  background-color: #000000;
+}
+body > header > nav {
+  width: 100%;
+  background-color: #ffffff;
+  min-height: 3rem;
+}
+body > header > nav.m-navbar-landing,
+body > header > nav.m-navbar-jumbo {
+  background-color: transparent;
+  position: relative;
+}
+body > header > nav.m-navbar-landing {
+  opacity: 0.8;
+}
+body > header > nav.m-navbar-jumbo {
+  background-color: rgba(255, 255, 255, 0.25);
+  opacity: 1;
+}
+body > header > nav.m-navbar-landing:hover,
+body > header > nav.m-navbar-jumbo:hover {
+  background-color: rgba(255, 255, 255, 0.75);
+  opacity: 1;
+}
+body> header > nav.m-navbar-landing:target,
+body> header > nav.m-navbar-jumbo:target {
+  background-color: #ffffff;
+  opacity: 1;
+}
+body > header > nav.m-navbar-landing a#m-navbar-brand.m-navbar-brand-hidden {
+  visibility: hidden;
+}
+body > header > nav.m-navbar-landing:target a#m-navbar-brand.m-navbar-brand-hidden {
+  visibility: visible;
+}
+body > header > nav {
+  margin-left: auto;
+  margin-right: auto;
+  color: #000000;
+}
+body > header > nav a {
+  text-decoration: none;
+  text-transform: lowercase;
+  line-height: 1.5rem;
+  display: inline-block;
+  vertical-align: middle;
+  color: #000000;
+}
+body > header > nav a#m-navbar-brand, body > header > nav a#m-navbar-show, body > header > nav a#m-navbar-hide {
+  text-transform: lowercase;
+  font-weight: normal;
+  font-size: 1.125rem;
+  line-height: 3rem;
+}
+body > header > nav a#m-navbar-brand .m-thin {
+  font-weight: normal;
+}
+body > header > nav a#m-navbar-show:before, body > header > nav a#m-navbar-hide:before {
+  content:'\2630';
+}
+body > header > nav #m-navbar-collapse {
+  padding-bottom: 1rem;
+}
+body > header > nav #m-navbar-collapse li {
+  border-style: solid;
+  border-color: transparent;
+  border-width: 0 0 0 0.25rem;
+  margin-left: -1rem;
+}
+body > header > nav #m-navbar-collapse li a {
+  border-style: solid;
+  border-color: transparent;
+  margin-left: -0.25rem;
+  padding-left: 0.75rem;
+  border-width: 0 0 0 0.25rem;
+  width: 100%;
+}
+body > header > nav #m-navbar-collapse li a#m-navbar-current {
+  color: #ea7944;
+  border-color: #ea7944;
+}
+body > header > nav ol {
+  list-style-type: none;
+  margin: 0;
+}
+body > header > nav ol ol {
+  padding-left: 1.5rem;
+}
+body > header > nav [class*='m-col-'] {
+  padding-top: 0;
+  padding-bottom: 0;
+}
+body > header > nav a:hover, body > header > nav a:focus, body > header > nav a:active {
+  color: #cb4b16;
+}
+body > header > nav #m-navbar-collapse li:hover {
+  border-color: #cb4b16;
+}
+body > header > nav #m-navbar-collapse li a:hover,
+body > header > nav #m-navbar-collapse li a:focus,
+body > header > nav #m-navbar-collapse li a:active {
+  border-color: #cb4b16;
+  background-color: rgba(255, 255, 255, 0.5);
+}
+body > header > nav.m-navbar-landing #m-navbar-collapse li a:hover,
+body > header > nav.m-navbar-jumbo #m-navbar-collapse li a:hover,
+body > header > nav.m-navbar-landing #m-navbar-collapse li a:focus,
+body > header > nav.m-navbar-jumbo #m-navbar-collapse li a:focus,
+body > header > nav.m-navbar-landing #m-navbar-collapse li a:active,
+body > header > nav.m-navbar-jumbo #m-navbar-collapse li a:active {
+  background-color: var(--header-link-active-background-color-semi);
+}
+body > header > nav #m-navbar-hide {
+  display: none;
+}
+body > header > nav:target #m-navbar-collapse {
+  display: block;
+}
+body > header > nav:target #m-navbar-show {
+  display: none;
+}
+body > header > nav:target #m-navbar-hide {
+  display: inline-block;
+}
+@media screen and (min-width: 768px) {
+  body > header > nav #m-navbar-show, body > header > nav #m-navbar-hide,
+  body > header > nav:target #m-navbar-show, body > header > nav:target #m-navbar-hide {
+    display: none;
+  }
+  body > header > nav a {
+    line-height: 3rem;
+    margin-left: 0;
+    padding-left: 1rem;
+    padding-right: 1rem;
+    white-space: nowrap;
+  }
+  body > header > nav #m-navbar-collapse {
+    padding-bottom: 0;
+  }
+  body > header > nav #m-navbar-collapse li ol {
+    background-color: #ffffff;
+  }
+  body > header > nav #m-navbar-collapse ol ol li {
+    margin-left: 0;
+    padding-left: 0;
+    border-left-width: 0;
+  }
+  body > header > nav #m-navbar-collapse ol ol li a {
+    margin-left: 0;
+    padding-left: 0.75rem;
+  }
+  body > header > nav #m-navbar-collapse > .m-row > ol > li {
+    margin-left: 0;
+    border-left-width: 0;
+  }
+  body > header > nav a#m-navbar-brand, body > header > nav #m-navbar-collapse > .m-row > ol > li > a {
+    line-height: 2.75rem;
+    margin-left: 0;
+    border-width: 0.25rem 0 0 0;
+  }
+  body > header > nav #m-navbar-collapse ol {
+    padding-left: 0;
+    padding-right: 0;
+  }
+  body > header > nav #m-navbar-collapse > .m-row > ol, body > header > nav #m-navbar-collapse > .m-row > ol > li {
+    float: left;
+  }
+  body > header > nav #m-navbar-collapse ol ol {
+    z-index: 99999;
+    position: absolute;
+    visibility: hidden;
+    min-width: 7.5rem;
+  }
+  body > header > nav #m-navbar-collapse li:hover ol {
+    visibility: visible;
+  }
+}
+body > footer {
+  width: 100%;
+}
+body > footer > nav {
+  padding-top: 1rem;
+  padding-bottom: 1rem;
+  font-size: 0.85rem;
+  text-align: center;
+  color: #7c7c7c;
+  background-color: #eeeeee;
+}
+body > footer > nav h3, body > footer > nav h3 a {
+  text-transform: uppercase;
+  font-weight: normal;
+}
+body > footer > nav ul {
+  list-style-type: none;
+  padding: 0;
+  margin: 0;
+}
+body > footer > nav a {
+  text-decoration: none;
+  text-transform: lowercase;
+  color: #191919;
+}
+body > footer > nav a:hover, body > footer > nav a:focus, body > footer > nav a:active {
+  color: #494949;
+}
+body > main {
+  padding-top: 1rem;
+  padding-bottom: 1rem;
+}
+article h1 {
+  font-size: 1.75rem;
+}
+article h1 .m-breadcrumb {
+  color: #bdbdbd;
+  font-weight: normal;
+}
+article h1 .m-breadcrumb a {
+  color: #cb4b16;
+}
+article h1 .m-breadcrumb a:hover, article h1 a:focus, article h1 a:active {
+  color: #802f0e;
+}
+article > header h1 {
+  font-size: 2rem;
+  margin-bottom: 0.5rem;
+}
+article h1 a, article > header h1, article > header h1 a,
+article section > h2, article section > h2 a,
+article section > h3, article section > h3 a,
+article section > h4, article section > h4 a,
+article section > h5, article section > h5 a,
+article section > h6, article section > h6 a {
+  color: #cb4b16;
+}
+article h1 a:hover, article > header h1 a:hover, article > header h1 a:focus, article > header h1 a:active,
+article section > h2 a:hover, article section > h2 a:focus, article section > h2 a:active,
+article section > h3 a:hover, article section > h3 a:focus, article section > h3 a:active,
+article section > h4 a:hover, article section > h4 a:focus, article section > h4 a:active,
+article section > h5 a:hover, article section > h5 a:focus, article section > h5 a:active,
+article section > h6 a:hover, article section > h6 a:focus, article section > h6 a:active {
+  color: #802f0e;
+}
+article > header .m-date {
+  display: block;
+  width: 2.5rem;
+  float: left;
+  text-align: center;
+  line-height: 95%;
+  font-size: 0.75rem;
+  font-weight: normal;
+  white-space: nowrap;
+  border-right-style: solid;
+  border-right-width: 0.125rem;
+  border-color: #cb4b16;
+  padding-right: 0.75rem;
+  margin-top: -0.1rem;
+  margin-right: 0.75rem;
+  margin-bottom: 0.25rem;
+}
+article > header .m-date-day {
+  display: block;
+  font-weight: bold;
+  padding-top: 0.2rem;
+  padding-bottom: 0.15rem;
+  font-size: 1.25rem;
+}
+article > header p {
+  color: #7a7a7a;
+  font-size: 1.125rem;
+}
+article > header h1::after {
+  content: " ";
+  clear: both;
+  display: table;
+}
+article > footer {
+  color: #969696;
+}
+article > footer p {
+  font-style: italic;
+  font-size: 0.85rem;
+  text-indent: 0;
+}
+article section:target {
+  margin-left: -1.0rem;
+  border-left-style: solid;
+  border-left-width: 0.25rem;
+  padding-left: 0.75rem;
+  border-color: #cb4b16;
+}
+article h1 a, article > header h1 a, article section > h2 a, article section > h3 a,
+article section > h4 a, article section > h5 a, article section > h6 a {
+  text-decoration: none;
+}
+#m-landing-image {
+  background-size: cover;
+  background-color: #666666;
+  background-position: center center;
+  background-repeat: no-repeat;
+  margin-top: -4rem;
+  padding-top: 5rem;
+  color: #ffffff;
+}
+#m-landing-cover {
+  padding-bottom: 7rem;
+  margin-bottom: -3rem;
+}
+article#m-jumbo {
+  margin-top: -1rem;
+}
+article#m-jumbo > header #m-jumbo-image {
+  background-size: cover;
+  background-color: #666666;
+  background-position: center center;
+  background-repeat: no-repeat;
+  font-size: 2.5vh;
+  height: 60vh;
+  margin-top: -4rem;
+  margin-bottom: 1rem;
+  padding-top: 5rem;
+}
+article#m-jumbo > header #m-jumbo-cover, #m-landing-cover {
+  background: linear-gradient(transparent 0%, transparent 50%, #ffffff 100%);
+  width: 100%;
+  height: 100%;
+}
+article#m-jumbo > header h1, article#m-jumbo > header h2 {
+  text-align: center;
+  font-weight: bold;
+}
+article#m-jumbo > header h1 {
+  font-size: 10vh;
+}
+article#m-jumbo > header h2 {
+  font-size: 3vh;
+}
+article#m-jumbo > header a {
+  text-decoration: none;
+}
+article#m-jumbo > header, article#m-jumbo > header h1, article#m-jumbo > header a {
+  color: #ffffff;
+}
+article#m-jumbo > header a:hover, article#m-jumbo > header a:focus, article#m-jumbo > header a:active {
+  color: #f0f0f0;
+}
+article#m-jumbo.m-inverted > header, article#m-jumbo.m-inverted > header h1, article#m-jumbo.m-inverted > header a {
+  color: #000000;
+}
+article#m-jumbo.m-inverted > header a:hover, article#m-jumbo.m-inverted > header a:focus, article#m-jumbo.m-inverted > header a:active {
+  color: #0f0f0f;
+}
+.m-article-pagination {
+  text-align: center;
+  padding: 1rem;
+}
+nav.m-navpanel {
+  text-align: center;
+}
+nav.m-navpanel h3 {
+  text-transform: uppercase;
+  font-weight: normal;
+}
+nav.m-navpanel ol {
+  text-transform: lowercase;
+}
+nav.m-navpanel ol, nav.m-navpanel ul {
+  list-style-type: none;
+  padding: 0;
+}
+nav.m-navpanel a {
+  color: #292929;
+  text-decoration: none;
+}
+nav.m-navpanel a:hover, nav.m-navpanel a:focus, nav.m-navpanel a:active {
+  color: #cb4b16;
+}
+ul.m-tagcloud li { display: inline; }
+ul.m-tagcloud li.m-tag-1 { font-size: 0.75rem; }
+ul.m-tagcloud li.m-tag-2 { font-size: 0.825rem; }
+ul.m-tagcloud li.m-tag-3 { font-size: 1rem; }
+ul.m-tagcloud li.m-tag-4 { font-size: 1.25rem; }
+ul.m-tagcloud li.m-tag-5 { font-size: 1.5rem; }
+div.m-scroll {
+  max-width: 100%;
+  overflow-x: auto;
+}
+.m-fullwidth {
+  width: 100%;
+}
+.m-text-center, .m-text-center.m-noindent, table.m-table th.m-text-center, .m-text-center p {
+  text-align: center;
+}
+.m-text-left, .m-text-left.m-noindent, table.m-table th.m-text-left, .m-text-right p {
+  text-align: left;
+}
+.m-text-right, .m-text-right.m-noindent, table.m-table th.m-text-right, .m-text-right p {
+  text-align: right;
+}
+.m-text.m-small {
+  font-size: 85.4%;
+}
+.m-text.m-big {
+  font-size: 117%;
+}
+.m-text.m-strong {
+  font-weight: bold;
+}
+.m-text.m-em {
+  font-style: italic;
+}
+h1 .m-thin, h2 .m-thin, h3 .m-thin, h4 .m-thin, h5 .m-thin, h6 .m-thin {
+  font-weight: normal;
+}
+ul.m-unstyled, ol.m-unstyled {
+  list-style-type: none;
+  padding-left: 0;
+}
+ul[class*='m-block-'], ol[class*='m-block-'] {
+  padding-left: 0;
+}
+ul[class*='m-block-'] li, ol[class*='m-block-'] li {
+  display: inline;
+}
+ul[class*='m-block-bar-'] li:not(:last-child)::after, ol[class*='m-block-bar-'] li:not(:last-child)::after {
+  content: " | ";
+}
+@media screen and (min-width: 576px) {
+  ul.m-block-bar-s, ol.m-block-bar-s { padding-left: 2rem; }
+  ul.m-block-bar-s li, ol.m-block-bar-s li { display: list-item; }
+  ul.m-block-bar-s li:not(:last-child)::after, ol.m-block-bar-s li:not(:last-child)::after { content: ""; }
+}
+@media screen and (min-width: 768px) {
+  ul.m-block-bar-m, ol.m-block-bar-m { padding-left: 2rem; }
+  ul.m-block-bar-m li, ol.m-block-bar-m li { display: list-item; }
+  ul.m-block-bar-m li:not(:last-child)::after, ol.m-block-bar-m li:not(:last-child)::after { content: ""; }
+}
+@media screen and (min-width: 992px) {
+  ul.m-block-bar-l, ol.m-block-bar-l { padding-left: 2rem; }
+  ul.m-block-bar-l li, ol.m-block-bar-l li { display: list-item; }
+  ul.m-block-bar-l li:not(:last-child)::after, ol.m-block-bar-l li:not(:last-child)::after { content: ""; }
+}
+p.m-poem {
+  text-indent: 0;
+  text-align: left;
+  margin-left: 1.5rem;
+}
+p.m-transition {
+  color: #f7e3db;
+  text-indent: 0;
+  text-align: center;
+  font-size: 2rem;
+}
+dl.m-diary {
+  margin-bottom: 1.25rem;
+}
+dl.m-diary:last-child {
+  margin-bottom: 0.25rem;
+}
+dl.m-diary dt {
+  font-weight: bold;
+  width: 3.5rem;
+  float: left;
+  clear: both;
+  padding-top: 0.25rem;
+}
+dl.m-diary dd {
+  padding-top: 0.25rem;
+  padding-left: 3.5rem;
+}
+.m-note {
+  border-radius: 0.2rem;
+  padding: 1rem;
+}
+.m-frame {
+  background-color: #ffffff;
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: 0.2rem;
+  border-color: #f7e3db;
+  padding: 0.875rem;
+}
+.m-block {
+  border-style: solid;
+  border-width: 0.0625rem;
+  border-left-width: 0.25rem;
+  border-radius: 0.2rem;
+  border-color: #f7e3db;
+  padding: 0.9375rem 0.9375rem 0.9375rem 0.75rem;
+}
+.m-block.m-badge::after {
+  content: ' ';
+  display: block;
+  clear: both;
+}
+.m-block.m-badge h3 {
+  margin-left: 5rem;
+}
+.m-block.m-badge p {
+  margin-left: 5rem;
+  text-indent: 0;
+}
+.m-block.m-badge img {
+  width: 4rem;
+  height: 4rem;
+  border-radius: 2rem;
+  float: left;
+}
+a.m-button {
+  display: inline-block;
+  border-radius: 0.2rem;
+  padding-top: 0.75rem;
+  padding-bottom: 0.75rem;
+  padding-left: 1.5rem;
+  padding-right: 1.5rem;
+  text-decoration: none;
+  text-align: center;
+  font-size: 1.17rem;
+}
+a.m-button.m-fullwidth {
+  display: block;
+  padding-left: 0;
+  padding-right: 0;
+}
+a.m-button .m-big:first-child {
+  font-size: 1.37rem;
+  font-weight: bold;
+}
+a.m-button .m-small:last-child {
+  font-size: 0.854rem;
+}
+.m-label {
+  border-radius: 0.2rem;
+  font-size: 75%;
+  font-weight: normal;
+  padding: 0.125rem 0.25rem;
+  vertical-align: 7.5%;
+}
+.m-label.m-flat {
+  border-width: 0.0625rem;
+  border-style: solid;
+  border-color: #bdbdbd;
+  padding: 0.0625rem 0.1875rem;
+}
+table.m-table {
+  border-collapse: collapse;
+  margin-left: auto;
+  margin-right: auto;
+}
+div.m-scroll > table.m-table:last-child {
+  margin-bottom: 0.0625rem;
+}
+table.m-table:not(.m-flat) tbody tr:hover {
+  background-color: #f7e3db;
+}
+table.m-table th, table.m-table td {
+  vertical-align: top;
+  border-style: solid;
+  border-top-width: 0.0625rem;
+  border-left-width: 0;
+  border-right-width: 0;
+  border-bottom-width: 0;
+  border-color: #f7e3db;
+}
+table.m-table caption {
+  padding-bottom: 0.5rem;
+}
+table.m-table thead tr:first-child th, table.m-table thead tr:first-child td {
+  border-top-width: 0.125rem;
+}
+table.m-table thead th, table.m-table thead td {
+  border-bottom-width: 0.125rem;
+  vertical-align: bottom;
+}
+table.m-table tfoot th, table.m-table tfoot td {
+  border-top-width: 0.125rem;
+}
+table.m-table th, table.m-table td {
+  padding: 0.5rem;
+}
+table.m-table th {
+  text-align: left;
+}
+table.m-table td.m-default, th.m-default,
+table.m-table td.m-primary, th.m-primary,
+table.m-table td.m-success, th.m-success,
+table.m-table td.m-warning, th.m-warning,
+table.m-table td.m-danger, th.m-danger,
+table.m-table td.m-info, th.m-info,
+table.m-table td.m-dim, th.m-dim {
+  padding-left: 0.4375rem;
+  padding-right: 0.4375rem;
+  border-left-width: 0.0625rem;
+}
+table.m-table tr.m-default td, table.m-table td.m-default,
+table.m-table tr.m-default th, table.m-table th.m-default,
+table.m-table tr.m-primary td, table.m-table td.m-primary,
+table.m-table tr.m-primary th, table.m-table th.m-primary,
+table.m-table tr.m-success td, table.m-table td.m-success,
+table.m-table tr.m-success th, table.m-table th.m-success,
+table.m-table tr.m-warning td, table.m-table td.m-warning,
+table.m-table tr.m-warning th, table.m-table th.m-warning,
+table.m-table tr.m-danger td, table.m-table td.m-danger,
+table.m-table tr.m-danger th, table.m-table th.m-danger,
+table.m-table tr.m-info td, table.m-table td.m-info,
+table.m-table tr.m-info th, table.m-table th.m-info,
+table.m-table tr.m-dim td, table.m-table td.m-dim,
+table.m-table tr.m-dim th, table.m-table th.m-dim {
+  border-color: #ffffff;
+}
+.m-block.m-default { border-left-color: #f7e3db; }
+.m-block.m-default h3, .m-block.m-default h4, .m-block.m-default h5, .m-block.m-default h6 {
+  color: #000000;
+}
+.m-block.m-primary { border-left-color: #cb4b16; }
+.m-block.m-primary h3, .m-block.m-primary h4, .m-block.m-primary h5, .m-block.m-primary h6 {
+  color: #cb4b16;
+}
+.m-block.m-success { border-left-color: #31c25d; }
+.m-block.m-success h3, .m-block.m-success h4, .m-block.m-success h5, .m-block.m-success h6 {
+  color: #31c25d;
+}
+.m-block.m-warning { border-left-color: #c7cf2f; }
+.m-block.m-warning h3, .m-block.m-warning h4, .m-block.m-warning h5, .m-block.m-warning h6 {
+  color: #c7cf2f;
+}
+.m-block.m-danger { border-left-color: #f60000; }
+.m-block.m-danger h3, .m-block.m-danger h4, .m-block.m-danger h5, .m-block.m-danger h6 {
+  color: #f60000;
+}
+.m-block.m-info { border-left-color: #2e7dc5; }
+.m-block.m-info h3, .m-block.m-info h4, .m-block.m-info h5, .m-block.m-info h6 {
+  color: #2e7dc5;
+}
+.m-block.m-dim {
+  border-left-color: #bdbdbd;
+  color: #bdbdbd;
+}
+.m-block.m-dim a { color: #c0c0c0; }
+.m-block.m-dim a:hover, .m-block.m-dim a:focus, .m-block.m-dim a:active {
+  color: #949494;
+}
+.m-block.m-flat { border-color: transparent; }
+.m-block.m-flat h3, .m-block.m-flat h4, .m-block.m-flat h5. .m-block.m-flat h6 {
+  color: #000000;
+}
+.m-note.m-default { background-color: #fbf0ec; }
+.m-note.m-default, table.m-table tr.m-default td, table.m-table td.m-default,
+                   table.m-table tr.m-default th, table.m-table th.m-default {
+  color: #000000;
+}
+.m-note.m-default a:hover, table.m-table tr.m-default td a:hover, table.m-table td.m-default a:hover,
+                           table.m-table tr.m-default th a:hover, table.m-table th.m-default a:hover,
+.m-note.m-default a:focus, table.m-table tr.m-default td a:focus, table.m-table td.m-default a:focus,
+                           table.m-table tr.m-default th a:focus, table.m-table th.m-default a:focus,
+.m-note.m-default a:active, table.m-table tr.m-default td a:active, table.m-table td.m-default a:active,
+                            table.m-table tr.m-default th a:active, table.m-table th.m-default a:active {
+  color: #cb4b16;
+}
+.m-note.m-primary a, table.m-table tr.m-primary td a, table.m-table td.m-primary a,
+                     table.m-table tr.m-primary th a, table.m-table th.m-primary a {
+  color: #ea7944;
+}
+.m-note.m-primary, table.m-table tr.m-primary td, table.m-table td.m-primary,
+                   table.m-table tr.m-primary th, table.m-table th.m-primary {
+  background-color: #ef9069;
+  color: #fbe4d9;
+}
+.m-note.m-primary a, table.m-table tr.m-primary td a, table.m-table td.m-primary a,
+                     table.m-table tr.m-primary th a, table.m-table th.m-primary a {
+  color: #782f0d;
+}
+.m-note.m-primary a:hover, table.m-table tr.m-primary td a:hover, table.m-table td.m-primary a:hover,
+                           table.m-table tr.m-primary th a:hover, table.m-table th.m-primary a:hover,
+.m-note.m-primary a:focus, table.m-table tr.m-primary td a:focus, table.m-table td.m-primary a:focus,
+                           table.m-table tr.m-primary th a:focus, table.m-table th.m-primary a:focus,
+.m-note.m-primary a:active, table.m-table tr.m-primary td a:active, table.m-table td.m-primary a:active,
+                            table.m-table tr.m-primary th a:active, table.m-table th.m-primary a:active {
+  color: #2f1205;
+}
+.m-note.m-success, table.m-table tr.m-success td, table.m-table td.m-success,
+                   table.m-table tr.m-success th, table.m-table th.m-success {
+  background-color: #4dd376;
+  color: #f4fcf6;
+}
+.m-note.m-success a, table.m-table tr.m-success td a, table.m-table td.m-success a,
+                     table.m-table tr.m-success th a, table.m-table th.m-success a {
+  color: #c5f2d1;
+}
+.m-note.m-success a:hover, table.m-table tr.m-success td a:hover, table.m-table td.m-success a:hover,
+                           table.m-table tr.m-success th a:hover, table.m-table th.m-success a:hover,
+.m-note.m-success a:focus, table.m-table tr.m-success td a:focus, table.m-table td.m-success a:focus,
+                           table.m-table tr.m-success th a:focus, table.m-table th.m-success a:focus,
+.m-note.m-success a:active, table.m-table tr.m-success td a:active, table.m-table td.m-success a:active,
+                            table.m-table tr.m-success th a:active, table.m-table th.m-success a:active {
+  color: #dcf6e3;
+}
+.m-note.m-warning, table.m-table tr.m-warning td, table.m-table td.m-warning,
+                   table.m-table tr.m-warning th, table.m-table th.m-warning {
+  background-color: #d1d34d;
+  color: #fcfcf4;
+}
+.m-note.m-warning a, table.m-table tr.m-warning td a, table.m-table td.m-warning a,
+                     table.m-table tr.m-warning th a, table.m-table th.m-warning a {
+  color: #f0f1c7;
+}
+.m-note.m-warning a:hover, table.m-table tr.m-warning td a:hover, table.m-table td.m-warning a:hover,
+                           table.m-table tr.m-warning th a:hover, table.m-table th.m-warning a:hover,
+.m-note.m-warning a:focus, table.m-table tr.m-warning td a:focus, table.m-table td.m-warning a:focus,
+                           table.m-table tr.m-warning th a:focus, table.m-table th.m-warning a:focus,
+.m-note.m-warning a:active, table.m-table tr.m-warning td a:active, table.m-table td.m-warning a:active,
+                            table.m-table tr.m-warning th a:active, table.m-table th.m-warning a:active {
+  color: #f6f6dc;
+}
+.m-note.m-danger, table.m-table tr.m-danger td, table.m-table td.m-danger,
+                  table.m-table tr.m-danger th, table.m-table th.m-danger {
+  background-color: #e23e3e;
+  color: #fdf3f3;
+}
+.m-note.m-danger a, table.m-table tr.m-danger td a, table.m-table td.m-danger a,
+                    table.m-table tr.m-danger th a, table.m-table th.m-danger a {
+  color: #f2c7c6;
+}
+.m-note.m-danger a:hover, table.m-table tr.m-danger td a:hover, table.m-table td.m-danger a:hover,
+                          table.m-table tr.m-danger th a:hover, table.m-table th.m-danger a:hover,
+.m-note.m-danger a:focus, table.m-table tr.m-danger td a:focus, table.m-table td.m-danger a:focus,
+                          table.m-table tr.m-danger th a:focus, table.m-table th.m-danger a:focus,
+.m-note.m-danger a:active, table.m-table tr.m-danger td a:active, table.m-table td.m-danger a:active,
+                           table.m-table tr.m-danger th a:active, table.m-table th.m-danger a:active {
+  color: #f6dddc;
+}
+.m-note.m-info, table.m-table tr.m-info td, table.m-table td.m-info,
+                table.m-table tr.m-info th, table.m-table th.m-info {
+  background-color: #4c93d3;
+  color: #f4f8fc;
+}
+.m-note.m-info a, table.m-table tr.m-info td a, table.m-table td.m-info a,
+                  table.m-table tr.m-info th a, table.m-table th.m-info a {
+  color: #c6ddf2;
+}
+.m-note.m-info a:hover, table.m-table tr.m-info td a:hover, table.m-table td.m-info a:hover,
+                        table.m-table tr.m-info th a:hover, table.m-table th.m-info a:hover,
+.m-note.m-info a:focus, table.m-table tr.m-info td a:focus, table.m-table td.m-info a:focus,
+                        table.m-table tr.m-info th a:focus, table.m-table th.m-info a:focus,
+.m-note.m-info a:active, table.m-table tr.m-info td a:active, table.m-table td.m-info a:active,
+                         table.m-table tr.m-info th a:active, table.m-table th.m-info a:active {
+  color: #dbeaf7;
+}
+.m-note.m-dim, table.m-table tr.m-dim td, table.m-table td.m-dim,
+               table.m-table tr.m-dim th, table.m-table th.m-dim {
+  background-color: #f1f1f1;
+  color: #7c7c7c;
+}
+.m-note.m-dim a, table.m-table tr.m-dim td a, table.m-table td.m-dim a,
+                 table.m-table tr.m-dim th a, table.m-table th.m-dim a {
+  color: #c0c0c0;
+}
+.m-note.m-dim a:hover, table.m-table tr.m-dim td a:hover, table.m-table td.m-dim a:hover,
+                       table.m-table tr.m-dim th a:hover, table.m-table th.m-dim a:hover,
+.m-note.m-dim a:focus, table.m-table tr.m-dim td a:focus, table.m-table td.m-dim a:focus,
+                       table.m-table tr.m-dim th a:focus, table.m-table th.m-dim a:focus,
+.m-note.m-dim a:active, table.m-table tr.m-dim td a:active, table.m-table td.m-dim a:active,
+                        table.m-table tr.m-dim th a:active, table.m-table th.m-dim a:active {
+  color: #949494;
+}
+.m-text.m-default, .m-label.m-flat.m-default { color: #000000; }
+.m-text.m-primary, .m-label.m-flat.m-primary { color: #cb4b16; }
+.m-text.m-success, .m-label.m-flat.m-success { color: #31c25d; }
+.m-text.m-warning, .m-label.m-flat.m-warning { color: #c7cf2f; }
+.m-text.m-danger, .m-label.m-flat.m-danger { color: #f60000; }
+.m-text.m-info, .m-label.m-flat.m-info { color: #2e7dc5; }
+.m-text.m-dim, .m-label.m-flat.m-dim { color: #bdbdbd; }
+.m-text.m-dim a { color: #c0c0c0; }
+.m-text.m-dim a:hover, .m-text.m-dim a:focus, .m-text.m-dim a:active {
+  color: #949494;
+}
+a.m-button, .m-label { color: #ffffff; }
+a.m-button.m-default, .m-label:not(.m-flat).m-default { background-color: #000000; }
+a.m-button.m-primary, .m-label:not(.m-flat).m-primary { background-color: #cb4b16; }
+a.m-button.m-success, .m-label:not(.m-flat).m-success { background-color: #31c25d; }
+a.m-button.m-warning, .m-label:not(.m-flat).m-warning { background-color: #c7cf2f; }
+a.m-button.m-danger, .m-label:not(.m-flat).m-danger { background-color: #f60000; }
+a.m-button.m-info, .m-label:not(.m-flat).m-info { background-color: #2e7dc5; }
+a.m-button.m-dim, .m-label:not(.m-flat).m-dim { background-color: #bdbdbd; }
+a.m-button.m-default:hover, a.m-button.m-default:focus, a.m-button.m-default:active {
+  background-color: #cb4b16;
+}
+a.m-button.m-primary:hover, a.m-button.m-primary:focus, a.m-button.m-primary:active {
+  background-color: #000000;
+}
+a.m-button.m-success:hover, a.m-button.m-success:focus, a.m-button.m-success:active {
+  background-color: #dcf6e3;
+}
+a.m-button.m-warning:hover, a.m-button.m-warning:focus, a.m-button.m-warning:active {
+  background-color: #f6f6dc;
+}
+a.m-button.m-danger:hover, a.m-button.m-danger:focus, a.m-button.m-danger:active {
+  background-color: #f6dddc;
+}
+a.m-button.m-info:hover, a.m-button.m-info:focus, a.m-button.m-info:active {
+  background-color: #c6ddf2;
+}
+a.m-button.m-dim:hover, a.m-button.m-dim:focus, a.m-button.m-dim:active {
+  background-color: #c0c0c0;
+}
+img.m-image {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+div.m-image {
+  text-align: center;
+}
+img.m-image, div.m-image img {
+  max-width: 100%;
+  border-radius: 0.2rem;
+}
+div.m-image.m-fullwidth img {
+  width: 100%;
+}
+figure.m-figure {
+  max-width: 100%;
+  margin-top: 0;
+  margin-left: auto;
+  margin-right: auto;
+  position: relative;
+  display: table;
+}
+figure.m-figure:before {
+  position: absolute;
+  content: ' ';
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: -1;
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: 0.2rem;
+  border-color: #f7e3db;
+}
+figure.m-figure.m-flat:before {
+  border-color: transparent;
+}
+figure.m-figure > * {
+  margin-left: 1rem;
+  margin-right: 1rem;
+  display: table-caption;
+  caption-side: bottom;
+}
+figure.m-figure > *:first-child {
+  display: inline;
+}
+figure.m-figure > *:last-child {
+  margin-bottom: 1rem;
+}
+figure.m-figure img {
+  position: relative;
+  margin-left: 0;
+  margin-right: 0;
+  margin-bottom: 0;
+  border-top-left-radius: 0.2rem;
+  border-top-right-radius: 0.2rem;
+  max-width: 100%;
+}
+figure.m-figure figcaption {
+  margin-top: 0.5rem;
+  margin-bottom: 0.5rem;
+  font-weight: normal;
+  font-size: 1.17rem;
+}
+figure.m-figure a img {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+figure.m-figure.m-fullwidth, figure.m-figure.m-fullwidth > * {
+  display: block;
+}
+figure.m-figure.m-fullwidth > *:first-child {
+  display: inline;
+}
+figure.m-figure.m-fullwidth img {
+  width: 100%;
+}
+figure.m-figure.m-fullwidth:after {
+  content: ' ';
+  display: block;
+  margin-top: 1rem;
+  height: 1px;
+}
+figure.m-code-figure, figure.m-console-figure {
+  margin-top: 0;
+  margin-left: 0;
+  margin-right: 0;
+  position: relative;
+  padding: 1rem;
+}
+figure.m-code-figure:before, figure.m-console-figure:before {
+  position: absolute;
+  content: ' ';
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: -1;
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: 0.2rem;
+}
+figure.m-code-figure:before {
+  border-color: #fbf0ec;
+}
+figure.m-console-figure:before {
+  border-color: #000000;
+}
+figure.m-code-figure.m-flat:before, figure.m-console-figure.m-flat:before {
+  border-color: transparent;
+}
+figure.m-code-figure > pre:first-child, figure.m-console-figure > pre:first-child {
+  position: relative;
+  margin: -1rem -1rem 1rem -1rem;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+}
+article section:target figure.m-code-figure, article section:target figure.m-console-figure {
+  z-index: 1;
+}
+.m-imagegrid > div {
+  background-color: #ffffff; /* to avoid section HL shining through */
+}
+.m-imagegrid > div > figure {
+  display: block;
+  float: left;
+  position: relative;
+  margin: 0;
+}
+.m-imagegrid > div > figure > div,
+.m-imagegrid > div > figure > figcaption,
+.m-imagegrid > div > figure > a > div,
+.m-imagegrid > div > figure > a > figcaption {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  border-color: #ffffff;
+  border-style: solid;
+  border-width: 0.25rem;
+  padding: 0.5rem;
+}
+.m-imagegrid > div > figure:first-child > div,
+.m-imagegrid > div > figure:first-child > figcaption,
+.m-imagegrid > div > figure:first-child > a > div,
+.m-imagegrid > div > figure:first-child > a > figcaption {
+  border-left-width: 0;
+}
+.m-imagegrid > div > figure:last-child > div,
+.m-imagegrid > div > figure:last-child > figcaption,
+.m-imagegrid > div > figure:last-child > a > div,
+.m-imagegrid > div > figure:last-child > a > figcaption {
+  border-right-width: 0;
+}
+.m-imagegrid > div > figure > figcaption,
+.m-imagegrid > div > figure > a > figcaption {
+  color: transparent;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  font-size: 0.75rem;
+}
+.m-imagegrid > div > figure > div::before,
+.m-imagegrid > div > figure > figcaption::before,
+.m-imagegrid > div > figure > a > div::before,
+.m-imagegrid > div > figure > a > figcaption::before {
+  content: '';
+  display: inline-block;
+  height: 100%;
+  vertical-align: bottom;
+  width: 0;
+}
+.m-imagegrid > div > figure:hover > figcaption,
+.m-imagegrid > div > figure:hover > a > figcaption {
+  background: linear-gradient(transparent 0%, transparent 75%, rgba(0, 0, 0, 0.85) 100%);
+  color: #ffffff;
+}
+.m-imagegrid > div > figure > img,
+.m-imagegrid > div > figure > a > img {
+  width: 100%;
+  height: 100%;
+}
+.m-imagegrid > div::after {
+  display: block;
+  content: ' ';
+  clear: both;
+}
+@media screen and (max-width: 767px) {
+  .m-imagegrid > div > figure {
+    float: none;
+    width: 100% !important;
+  }
+  .m-imagegrid > div > figure > div,
+  .m-imagegrid > div > figure > figcaption,
+  .m-imagegrid > div > figure > a > div,
+  .m-imagegrid > div > figure > a > figcaption {
+    border-left-width: 0;
+    border-right-width: 0;
+  }
+}
+.m-container-inflatable > .m-row > [class*='m-col-'] > .m-note,
+.m-container-inflatable > .m-row > [class*='m-col-'] > .m-frame,
+.m-container-inflatable > .m-row > [class*='m-col-'] > .m-block,
+.m-container-inflatable > .m-row > [class*='m-col-'] > .m-imagegrid,
+.m-container-inflatable > .m-row > [class*='m-col-'] > pre,
+.m-container-inflatable > .m-row > [class*='m-col-'] > figure.m-code-figure,
+.m-container-inflatable > .m-row > [class*='m-col-'] > figure.m-console-figure,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-note,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-frame,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-block,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-imagegrid,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > pre,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > figure.m-code-figure,
+.m-container-inflatable > .m-row > [class*='m-col-'] section > figure.m-console-figure {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+@media screen and (min-width: 576px) {
+  .m-container-inflatable > .m-row > .m-col-s-10 > .m-imagegrid.m-container-inflate,
+  .m-container-inflatable > .m-row > .m-col-s-10 section > .m-imagegrid.m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+}
+@media screen and (min-width: 768px) {
+  .m-container-inflatable > .m-row > .m-col-m-10 > .m-imagegrid.m-container-inflate,
+  .m-container-inflatable > .m-row > .m-col-m-10 section > .m-imagegrid.m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+}
+@media screen and (min-width: 992px) {
+  .m-container-inflatable > .m-row > .m-col-l-10 > .m-imagegrid.m-container-inflate,
+  .m-container-inflatable > .m-row > .m-col-l-10 section > .m-imagegrid.m-container-inflate {
+    margin-left: -10%;
+    margin-right: -10%;
+  }
+}
+.m-container-inflatable section:target > .m-note,
+.m-container-inflatable section:target > .m-frame,
+.m-container-inflatable section:target > .m-block,
+.m-container-inflatable section:target > pre,
+.m-container-inflatable section:target > figure.m-code-figure > pre:first-child,
+.m-container-inflatable section:target > figure.m-console-figure > pre:first-child,
+.m-container-inflatable section:target section > .m-note,
+.m-container-inflatable section:target section > .m-frame,
+.m-container-inflatable section:target section > .m-block,
+.m-container-inflatable section:target section > pre,
+.m-container-inflatable section:target section > figure.m-code-figure > pre:first-child,
+.m-container-inflatable section:target section > figure.m-console-figure > pre:first-child {
+  margin-left: -1.0rem;
+  border-left-style: solid;
+  border-left-width: 0.25rem;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+  padding-left: 0.75rem;
+}
+.m-container-inflatable section:target > figure.m-code-figure::before,
+.m-container-inflatable section:target > figure.m-console-figure::before,
+.m-container-inflatable section:target section > figure.m-code-figure::before,
+.m-container-inflatable section:target section > figure.m-console-figure::before {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+  border-left-width: 0.25rem;
+}
+.m-container-inflatable section:target > pre,
+.m-container-inflatable section:target > figure.m-code-figure > pre:first-child,
+.m-container-inflatable section:target > figure.m-console-figure > pre:first-child,
+.m-container-inflatable section:target section > pre,
+.m-container-inflatable section:target section > figure.m-code-figure > pre:first-child,
+.m-container-inflatable section:target section > figure.m-console-figure > pre:first-child {
+  border-color: #f7e3db;
+}
+.m-container-inflatable section:target > figure.m-code-figure::before,
+.m-container-inflatable section:target > figure.m-console-figure::before,
+.m-container-inflatable section:target > .m-note.m-default,
+.m-container-inflatable section:target section > figure.m-code-figure::before,
+.m-container-inflatable section:target section > figure.m-console-figure::before,
+.m-container-inflatable section:target section > .m-note.m-default {
+  border-left-color: #f7e3db;
+}
+.m-container-inflatable section:target > .m-note.m-primary,
+.m-container-inflatable section:target section > .m-note.m-primary {
+  border-left-color: #cb4b16;
+}
+.m-container-inflatable section:target > .m-note.m-success,
+.m-container-inflatable section:target section > .m-note.m-success {
+  border-left-color: #31c25d;
+}
+.m-container-inflatable section:target > .m-note.m-warning,
+.m-container-inflatable section:target section > .m-note.m-warning {
+  border-left-color: #c7cf2f;
+}
+.m-container-inflatable section:target > .m-note.m-danger,
+.m-container-inflatable section:target section > .m-note.m-danger {
+  border-left-color: #f60000;
+}
+.m-container-inflatable section:target > .m-note.m-info,
+.m-container-inflatable section:target section > .m-note.m-info {
+  border-left-color: #2e7dc5;
+}
+.m-container-inflatable section:target > .m-note.m-dim,
+.m-container-inflatable section:target section > .m-note.m-dim {
+  border-left-color: #bdbdbd;
+}
+pre.m-code span.hll {
+  margin-left: -1.0rem;
+  margin-right: -1.0rem;
+  padding-left: 1.0rem;
+}
+pre.m-code.m-inverted {
+  color: rgba(91, 91, 91, 0.33);
+}
+pre.m-code.m-inverted > span {
+  opacity: 0.3333;
+}
+pre.m-code.m-inverted > span.hll {
+  color: #000000;
+  opacity: 1;
+  background-color: transparent;
+  border-color: transparent;
+}
+div.m-math {
+  overflow-x: auto;
+  overflow-y: hidden;
+  text-align: center;
+}
+div.m-math svg, svg.m-math { fill: #000000; }
+div.m-math.m-default svg, svg.m-math.m-default { fill: #000000; }
+div.m-math.m-primary svg, svg.m-math.m-primary { fill: #cb4b16; }
+div.m-math.m-success svg, svg.m-math.m-success { fill: #31c25d; }
+div.m-math.m-warning svg, svg.m-math.m-warning { fill: #c7cf2f; }
+div.m-math.m-danger svg, svg.m-math.m-danger { fill: #f60000; }
+div.m-math.m-info svg, svg.m-math.m-info { fill: #2e7dc5; }
+div.m-math.m-dim svg, svg.m-math.m-dim { fill: #bdbdbd; }
+p, ul, ol, dl, blockquote, pre, figure.m-code-figure, figure.m-console-figure,
+hr, article, article > header, article section,
+.m-note, .m-frame, .m-block, .m-button,
+div.m-scroll, table.m-table, div.m-image, img.m-image,
+figure.m-figure, .m-imagegrid, div.m-math {
+  margin-bottom: 1rem;
+}
+p:last-child, ul:last-child, ol:last-child, dl:last-child, blockquote:last-child,
+pre:last-child, figure.m-code-figure:last-child, figure.m-console-figure:last-child,
+hr:last-child, article:last-child, article section:last-child,
+.m-note:last-child, .m-frame:last-child, .m-block:last-child, .m-button:last-child,
+table.m-table:last-child, img.m-image:last-child, div.m-image:last-child,
+figure.m-figure:last-child, .m-imagegrid:last-child, div.m-math:last-child {
+  margin-bottom: 0;
+}
+li > p:last-child, li > blockquote:last-child, li > pre:last-child,
+li > figure.m-code-figure:last-child, li > figure.m-console-figure:last-child,
+li > .m-note:last-child, li > .m-frame:last-child, li > .m-block:last-child,
+li > .m-button:last-child, li > div.m-scroll:last-child,
+li > table.m-table:last-child, li > div.m-image:last-child,
+li > img.m-image:last-child, li > figure.m-figure:last-child,
+li > div.m-math:last-child {
+  margin-bottom: 1rem;
+}
+li > p:last-child, li:last-child > blockquote:last-child, li:last-child > pre:last-child,
+li:last-child > figure.m-code-figure:last-child, li:last-child > figure.m-console-figure:last-child,
+li:last-child > .m-note:last-child, li:last-child > .m-frame:last-child, li:last-child > .m-block:last-child,
+li:last-child > .m-button:last-child, li:last-child > div.m-scroll:last-child,
+li:last-child > table.m-table:last-child, li:last-child > div.m-image:last-child,
+li:last-child > img.m-image:last-child, li:last-child > figure.m-figure:last-child,
+li:last-child > div.m-math:last-child {
+  margin-bottom: 0;
+}
+
+.m-console .hll { background-color: #ffffcc }
+.m-console .g-AnsiBlack { color: #000000 }
+.m-console .g-AnsiBlue { color: #3f3fd1 }
+.m-console .g-AnsiBrightBlack { color: #686868; font-weight: bold }
+.m-console .g-AnsiBrightBlue { color: #5454ff; font-weight: bold }
+.m-console .g-AnsiBrightCyan { color: #54ffff; font-weight: bold }
+.m-console .g-AnsiBrightDefault { color: #ffffff; font-weight: bold }
+.m-console .g-AnsiBrightGreen { color: #54ff54; font-weight: bold }
+.m-console .g-AnsiBrightMagenta { color: #ff54ff; font-weight: bold }
+.m-console .g-AnsiBrightRed { color: #ff5454; font-weight: bold }
+.m-console .g-AnsiBrightWhite { color: #ffffff; font-weight: bold }
+.m-console .g-AnsiBrightYellow { color: #ffff54; font-weight: bold }
+.m-console .g-AnsiCyan { color: #18b2b2 }
+.m-console .g-AnsiDefault { color: #b2b2b2 }
+.m-console .g-AnsiGreen { color: #18b218 }
+.m-console .g-AnsiMagenta { color: #b218b2 }
+.m-console .g-AnsiRed { color: #b21818 }
+.m-console .g-AnsiWhite { color: #b2b2b2 }
+.m-console .g-AnsiYellow { color: #b26818 }
+.m-console .go { color: #b2b2b2 }
+.m-console .gp { color: #54ffff; font-weight: bold }
+.m-console .w { color: #b2b2b2 }
+
+a.m-dox, a.m-dox-self, a.m-dox-external,
+ul.m-dox li.m-dox-expansible > a:first-child, ul.m-dox li.m-dox-collapsible > a:first-child {
+  text-decoration: none;
+}
+a.m-dox, a.m-dox-self {
+  font-weight: bold;
+}
+ul.m-dox li.m-dox-expansible > a:first-child,
+ul.m-dox li.m-dox-collapsible > a:first-child,
+ul.m-dox li.m-dox-expansible > a:first-child:hover,
+ul.m-dox li.m-dox-expansible > a:first-child:focus,
+ul.m-dox li.m-dox-expansible > a:first-child:active,
+ul.m-dox li.m-dox-collapsible > a:first-child:hover,
+ul.m-dox li.m-dox-collapsible > a:first-child:focus,
+ul.m-dox li.m-dox-collapsible > a:first-child:active {
+  color: #000000;
+}
+a.m-dox-self,
+ul.m-dox li.m-dox-expansible > a:first-child:before,
+ul.m-dox li.m-dox-collapsible > a:first-child:before {
+  color: #cb4b16;
+}
+a.m-dox-self:hover, a.m-dox-self:focus, a.m-dox-self:active,
+ul.m-dox li.m-dox-expansible > a:first-child:hover::before,
+ul.m-dox li.m-dox-expansible > a:first-child:focus::before,
+ul.m-dox li.m-dox-expansible > a:first-child:active::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:hover::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:focus::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:active::before {
+  color: #802f0e;
+}
+h3 a.m-dox-external {
+  font-weight: normal;
+}
+span.m-dox-wrap-bumper {
+  margin-right: -1rem;
+}
+span.m-dox-wrap {
+  padding-left: 1rem;
+  display: inline-block;
+  vertical-align: text-top;
+  white-space: pre-line;
+  max-width: 100%;
+}
+dl.m-dox dd {
+  margin-bottom: 0.5rem;
+}
+ul.m-dox {
+  list-style: none;
+  margin-left:  1.0375rem;
+  padding-left: 0.9rem;
+  border-left-color: #f7e3db;
+  border-left-width: 0.0625rem;
+  border-left-style: solid;
+}
+ul.m-dox li {
+  text-indent: -1rem;
+  padding-left: 1rem;
+}
+ul.m-dox li.m-dox-expansible > ul {
+  display: none;
+}
+ul.m-dox li.m-dox-expansible, ul.m-dox li.m-dox-collapsible {
+  padding-left: 0.6rem;
+}
+ul.m-dox li.m-dox-expansible > ul.m-dox, ul.m-dox li.m-dox-collapsible > ul.m-dox {
+  margin-left: 0.5rem;
+}
+ul.m-dox li.m-dox-expansible > a:first-child:before, ul.m-dox li.m-dox-collapsible > a:first-child:before {
+  background-color: #ffffff;
+  display: inline-block;
+  width: 0.4rem;
+  font-weight: bold;
+}
+ul.m-dox li.m-dox-expansible > a:first-child:before { content: '⊕'; }
+ul.m-dox li.m-dox-collapsible > a:first-child:before { content: '⊖'; }
+h1 .m-dox-template {
+  font-size: 1.3rem;
+  font-weight: normal;
+}
+h3 .m-dox-template {
+  font-size: 1rem;
+  font-weight: normal;
+}
+.m-dox-template, dl.m-dox dd, ul.m-dox li > span.m-dox {
+  color: #bdbdbd;
+}
+.m-dox-template a, dl.m-dox dd a, ul.m-dox li > span.m-dox a {
+  color: #c0c0c0;
+}
+.m-dox-template a:hover, .m-dox-template a:focus, .m-dox-template a:active,
+dl.m-dox dd a:hover, dl.m-dox dd a:focus, dl.m-dox dd a:active,
+ul.m-dox li > span.m-dox a:hover, ul.m-dox li > span.m-dox a:focus, ul.m-dox li > span.m-dox a:active {
+  color: #949494;
+}
+article section.m-dox-details > div {
+  margin-top: 0;
+  margin-left: 0;
+  margin-right: 0;
+  position: relative;
+  padding: 1rem;
+}
+article section.m-dox-details > div::before {
+  position: absolute;
+  content: ' ';
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: -1;
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: 0.2rem;
+  border-color: #fbf0ec;
+}
+article section.m-dox-details > div > h3:first-child {
+  position: relative;
+  margin: -1rem -1rem 1rem -1rem;
+  padding: 0.5rem 1rem;
+  background-color: #fbf0ec;
+  border-top-left-radius: 0.2rem;
+  border-top-right-radius: 0.2rem;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+}
+article section.m-dox-details:target {
+  border-color: transparent;
+}
+article section.m-dox-details:target > div {
+  z-index: 1;
+}
+.m-container-inflatable > .m-row > [class*='m-col-'] section.m-dox-details > div {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+.m-container-inflatable section.m-dox-details:target > div > h3:first-child,
+.m-container-inflatable section.m-dox-details:target section > div > h3:first-child {
+  margin-left: -1.0rem;
+  border-left-style: solid;
+  border-left-color: #802f0e;
+  border-left-width: 0.25rem;
+  padding-left: 0.75rem;
+}
+.m-container-inflatable section.m-dox-details:target > div::before,
+.m-container-inflatable section-dox-details:target section > div.m::before {
+  border-left-width: 0.25rem;
+  border-left-color: #cb4b16;
+}
diff --git a/css/m-light.doxygen.compiled.css b/css/m-light.doxygen.compiled.css
new file mode 100644 (file)
index 0000000..0b02f1c
--- /dev/null
@@ -0,0 +1,174 @@
+/* Generated using `./postprocess.py m-light.css m-doxygen.css --no-import -o m-light.doxygen.compiled.css`. Do not edit. */
+
+/*
+    This file is part of m.css.
+
+    Copyright © 2017 Vladimír Vondruš <mosra@centrum.cz>
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+*/
+
+a.m-dox, a.m-dox-self, a.m-dox-external,
+ul.m-dox li.m-dox-expansible > a:first-child, ul.m-dox li.m-dox-collapsible > a:first-child {
+  text-decoration: none;
+}
+a.m-dox, a.m-dox-self {
+  font-weight: bold;
+}
+ul.m-dox li.m-dox-expansible > a:first-child,
+ul.m-dox li.m-dox-collapsible > a:first-child,
+ul.m-dox li.m-dox-expansible > a:first-child:hover,
+ul.m-dox li.m-dox-expansible > a:first-child:focus,
+ul.m-dox li.m-dox-expansible > a:first-child:active,
+ul.m-dox li.m-dox-collapsible > a:first-child:hover,
+ul.m-dox li.m-dox-collapsible > a:first-child:focus,
+ul.m-dox li.m-dox-collapsible > a:first-child:active {
+  color: #000000;
+}
+a.m-dox-self,
+ul.m-dox li.m-dox-expansible > a:first-child:before,
+ul.m-dox li.m-dox-collapsible > a:first-child:before {
+  color: #cb4b16;
+}
+a.m-dox-self:hover, a.m-dox-self:focus, a.m-dox-self:active,
+ul.m-dox li.m-dox-expansible > a:first-child:hover::before,
+ul.m-dox li.m-dox-expansible > a:first-child:focus::before,
+ul.m-dox li.m-dox-expansible > a:first-child:active::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:hover::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:focus::before,
+ul.m-dox li.m-dox-collapsible > a:first-child:active::before {
+  color: #802f0e;
+}
+h3 a.m-dox-external {
+  font-weight: normal;
+}
+span.m-dox-wrap-bumper {
+  margin-right: -1rem;
+}
+span.m-dox-wrap {
+  padding-left: 1rem;
+  display: inline-block;
+  vertical-align: text-top;
+  white-space: pre-line;
+  max-width: 100%;
+}
+dl.m-dox dd {
+  margin-bottom: 0.5rem;
+}
+ul.m-dox {
+  list-style: none;
+  margin-left:  1.0375rem;
+  padding-left: 0.9rem;
+  border-left-color: #f7e3db;
+  border-left-width: 0.0625rem;
+  border-left-style: solid;
+}
+ul.m-dox li {
+  text-indent: -1rem;
+  padding-left: 1rem;
+}
+ul.m-dox li.m-dox-expansible > ul {
+  display: none;
+}
+ul.m-dox li.m-dox-expansible, ul.m-dox li.m-dox-collapsible {
+  padding-left: 0.6rem;
+}
+ul.m-dox li.m-dox-expansible > ul.m-dox, ul.m-dox li.m-dox-collapsible > ul.m-dox {
+  margin-left: 0.5rem;
+}
+ul.m-dox li.m-dox-expansible > a:first-child:before, ul.m-dox li.m-dox-collapsible > a:first-child:before {
+  background-color: #ffffff;
+  display: inline-block;
+  width: 0.4rem;
+  font-weight: bold;
+}
+ul.m-dox li.m-dox-expansible > a:first-child:before { content: '⊕'; }
+ul.m-dox li.m-dox-collapsible > a:first-child:before { content: '⊖'; }
+h1 .m-dox-template {
+  font-size: 1.3rem;
+  font-weight: normal;
+}
+h3 .m-dox-template {
+  font-size: 1rem;
+  font-weight: normal;
+}
+.m-dox-template, dl.m-dox dd, ul.m-dox li > span.m-dox {
+  color: #bdbdbd;
+}
+.m-dox-template a, dl.m-dox dd a, ul.m-dox li > span.m-dox a {
+  color: #c0c0c0;
+}
+.m-dox-template a:hover, .m-dox-template a:focus, .m-dox-template a:active,
+dl.m-dox dd a:hover, dl.m-dox dd a:focus, dl.m-dox dd a:active,
+ul.m-dox li > span.m-dox a:hover, ul.m-dox li > span.m-dox a:focus, ul.m-dox li > span.m-dox a:active {
+  color: #949494;
+}
+article section.m-dox-details > div {
+  margin-top: 0;
+  margin-left: 0;
+  margin-right: 0;
+  position: relative;
+  padding: 1rem;
+}
+article section.m-dox-details > div::before {
+  position: absolute;
+  content: ' ';
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: -1;
+  border-style: solid;
+  border-width: 0.125rem;
+  border-radius: 0.2rem;
+  border-color: #fbf0ec;
+}
+article section.m-dox-details > div > h3:first-child {
+  position: relative;
+  margin: -1rem -1rem 1rem -1rem;
+  padding: 0.5rem 1rem;
+  background-color: #fbf0ec;
+  border-top-left-radius: 0.2rem;
+  border-top-right-radius: 0.2rem;
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+}
+article section.m-dox-details:target {
+  border-color: transparent;
+}
+article section.m-dox-details:target > div {
+  z-index: 1;
+}
+.m-container-inflatable > .m-row > [class*='m-col-'] section.m-dox-details > div {
+  margin-left: -1rem;
+  margin-right: -1rem;
+}
+.m-container-inflatable section.m-dox-details:target > div > h3:first-child,
+.m-container-inflatable section.m-dox-details:target section > div > h3:first-child {
+  margin-left: -1.0rem;
+  border-left-style: solid;
+  border-left-color: #802f0e;
+  border-left-width: 0.25rem;
+  padding-left: 0.75rem;
+}
+.m-container-inflatable section.m-dox-details:target > div::before,
+.m-container-inflatable section-dox-details:target section > div.m::before {
+  border-left-width: 0.25rem;
+  border-left-color: #cb4b16;
+}
diff --git a/doc/doxygen-test.rst b/doc/doxygen-test.rst
new file mode 100644 (file)
index 0000000..886cfa1
--- /dev/null
@@ -0,0 +1,64 @@
+..
+    This file is part of m.css.
+
+    Copyright © 2017 Vladimír Vondruš <mosra@centrum.cz>
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+..
+
+Test
+####
+
+:save_as: doxygen/test/index.html
+:breadcrumb: {filename}/doxygen.rst Doxygen
+:css: {filename}/static/m-doxygen.css
+
+Lists
+=====
+
+Compound lists should have the same indentation as normal ones.
+
+.. raw:: html
+
+    <ul>
+      <li>An item</li>
+      <li>Another
+        <ul>
+          <li>Subitem</li>
+        </ul>
+      <li>Another</li>
+    </ul>
+
+    <ul class="m-dox">
+      <li>An item</li>
+      <li class="m-dox-expansible"><a href="#"></a>An expansible item. Verify that the indentation works. <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit.</span>
+        <ul class="m-dox">
+          <li>Subitem</li>
+          <li>Subitem</li>
+          <li>Subitem</li>
+          <li>Subitem</li>
+        </ul>
+      </li>
+      <li class="m-dox-collapsible"><a href="#"></a>A collapsible item
+        <ul class="m-dox">
+          <li>Subitem</li>
+        </ul>
+      </li>
+      <li>Another item. Verify that the indentation works. <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultrices a erat eu suscipit.</span></li>
+    </ul>
diff --git a/doc/doxygen.rst b/doc/doxygen.rst
new file mode 100644 (file)
index 0000000..7af90e0
--- /dev/null
@@ -0,0 +1,1109 @@
+..
+    This file is part of m.css.
+
+    Copyright © 2017 Vladimír Vondruš <mosra@centrum.cz>
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+..
+
+Doxygen theme
+#############
+
+.. role:: cpp(code)
+    :language: cpp
+.. role:: html(code)
+    :language: html
+.. role:: ini(code)
+    :language: ini
+.. role:: jinja(code)
+    :language: jinja
+.. role:: py(code)
+    :language: py
+.. role:: sh(code)
+    :language: sh
+
+A drop-in replacement for the stock `Doxygen <http://www.doxygen.org>`_ HTML
+output, generated from Doxygen-produced XML files. Generated filenames and URLs
+are fully compatible with the stock output to avoid broken links once you
+switch.
+
+.. contents::
+    :class: m-block m-default
+
+`Basic usage`_
+==============
+
+Everything you need is a Python script and a bunch of template files. You can
+get that by cloning :gh:`the m.css GitHub repository <mosra/m.css$master/doxygen>`
+and looking into the ``doxygen/`` directory:
+
+.. code:: sh
+
+    git clone git://github.com/mosra/m.css
+    cd m.css/doxygen
+
+The script requires Python 3.6, depends on `Jinja2 <http://jinja.pocoo.org/>`_
+for templating and `Pygments <http://pygments.org/>`_ for code block
+highlighting. You can install the dependencies via ``pip`` or your distribution
+package manager:
+
+.. code:: sh
+
+    pip install jinja2 Pygments
+
+If your documentation includes math formulas, in addition you need some LaTeX
+distribution installed. Use your distribution package manager, for example on
+Ubuntu:
+
+.. code:: sh
+
+    sudo apt-get install texlive-base texlive-latex-extra texlive-fonts-extra
+
+.. note-success::
+
+    This tool makes use of the ``latex2svg.py`` utility from :gh:`tuxu/latex2svg`,
+    © 2017 `Tino Wagner <http://www.tinowagner.com/>`_, licensed under
+    :gh:`MIT <tuxu/latex2svg$master/LICENSE.md>`.
+
+Now, in order to preserve your original Doxygen configuration, create a new
+``Doxyfile-mcss`` file next to your original ``Doxyfile`` and put the following
+inside:
+
+.. code:: ini
+
+    @INCLUDE               = Doxyfile
+    GENERATE_HTML          = NO
+    GENERATE_XML           = YES
+    XML_PROGRAMLISTING     = NO
+
+This will derive the configuration from the original ``Doxyfile``, disables
+builtin Doxygen HTML output and enables XML output instead, with some unneeded
+features disabled for faster processing. Now run ``dox2html5.py`` and point it
+to your ``Doxyfile-mcss``:
+
+.. code:: sh
+
+    ./dox2html5.py path/to/your/Doxyfile-mcss
+
+It will run ``doxygen`` to generate the XML output, processes it and generates
+the HTML output in the configured output directory. After the script is done,
+just open generated ``index.html`` to see the result.
+
+`Features`_
+===========
+
+-   Modern, valid, mobile-friendly HTML5 markup without table layouts
+-   Minimalistic design without unnecessary chrome and UI elements
+-   URLs fully compatible with stock Doxygen HTML output to preserve existing
+    links
+-   Focused on presenting the actual written documentation while reducing
+    questionable auto-generated content
+-   Math rendered as `embedded SVG <{filename}/css/components.rst#math>`_
+    instead of raster images / MathJax
+-   Uses Pygments for better code highlighting
+
+`Important differences to stock HTML output`_
+---------------------------------------------
+
+-   Detailed description is put first and foremost on a page, *before* the
+    member listing
+-   Table of contents is generated for compound references as well, containing
+    all sections of detailed description together with anchors to member
+    listings.
+-   Private members and anonymous namespaces are always ignored, however
+    private virtual functions are listed in case they are documented
+    (`why? <http://www.gotw.ca/publications/mill18.htm>`_)
+-   Inner classes are listed in the public/protected type sections instead of
+    being listed in a separate section ignoring their public/private status
+-   Class references contain also their template specification on the linked
+    page
+-   Function signatures don't contain :cpp:`constexpr` and :cpp:`noexcept`
+    anymore. These keywords are instead added as flags to the function
+    description together with :cpp:`virtual`\ ness and :cpp:`explicit`\ ity. On
+    the other hand, important properties like :cpp:`static`, :cpp:`const` and
+    r-value overloads *are* part of function signature.
+-   For better visual alignment, function listing is done using the C++11
+    trailing return type (:cpp:`auto` in front) and typedef listing is done
+    with :cpp:`using`). However, the detailed documentation is kept in the
+    original form.
+-   Function and macro parameters and enum values are vertically aligned in
+    the member listing for better readability.
+-   Default class template parameters are not needlessly repeated in each
+    member detailed docs
+
+`Intentionally unsupported features`_
+-------------------------------------
+
+.. note-danger:: Warning: opinions
+
+    This list presents my opinions. Not everybody likes my opinions.
+
+Features that I don't see a point in because they just artifically inflate the
+amount of generated content for no added value.
+
+-   Class hierarchy graphs are ignored (it only inflates the documentation with
+    little added value)
+-   Alphabetical list of symbols and alphabetical list of all members of a
+    class is not created (the API *should be* organized in a way that makes
+    this unnecessary)
+-   Verbatim listing of parsed headers, "Includes" and "Included By" lists are
+    not present (use your IDE or GitHub instead)
+-   Undocumented or private members and content of anonymous namespaces are
+    ignored (if things are undocumented or intentionally hidden, why put them
+    in the documentation)
+-   Brief description for enum values is ignored (only the detailed description
+    is used, as the brief description was never used anywhere else than next to
+    the detailed description)
+-   Initializers of defines and variables are unconditionally ignored (look in
+    the sources, if you *really* need that)
+-   No section with list of examples or linking from function/class
+    documentation to related example code (he example code should be
+    accompanied with corresponding tutorial page instead)
+-   :cpp:`inline` functions are not marked as such (I see it as an unimportant
+    implementation detail)
+
+`Not yet implemented features`_
+-------------------------------
+
+-   Code search. I want to provide something that's actually usable to replace
+    the terribly slow stock client-side search, but I'm not there yet.
+-   Clickable symbols in code snippets. Doxygen has quite a lot of false
+    positives while a lot of symbols stay unmatched. I need to find a way
+    around that.
+
+`Configuration`_
+================
+
+The script takes most of the configuration from the ``Doxyfile`` itself,
+(ab)using the following builtin options:
+
+.. class:: m-table m-fullwidth
+
+=============================== ===============================================
+Variable                        Description
+=============================== ===============================================
+:ini:`@INCLUDE`                 Includes in ``Doxyfile``\ s are supported
+:ini:`PROJECT_NAME`             Rendered in top navbar, footer fine print and
+                                page title
+:ini:`PROJECT_BRIEF`            If set, appended in a thinner font to
+                                :ini:`PROJECT_NAME`
+:ini:`OUTPUT_DIRECTORY`         Used to discover where Doxygen generates the
+                                files
+:ini:`XML_OUTPUT`               Used to discover where Doxygen puts the
+                                generated XML
+:ini:`HTML_OUTPUT`              The output will be written here
+:ini:`TAGFILES`                 Used to discover what base URL to prepend to
+                                external references
+:ini:`IMAGE_PATHS`              Used to discover where Doxygen gets the image
+                                files
+:ini:`HTML_EXTRA_STYLESHEET`    List of CSS files to include. Relative paths
+                                are also searched relative to the
+                                ``dox2html5.py`` script. See below for more
+                                information.
+:ini:`HTML_EXTRA_FILES`         List of extra files to copy (for example
+                                additional CSS files that are :css:`@import`\ ed
+                                from the primary one). Relative paths are also
+                                searched relative to the ``dox2html5.py``
+                                script.
+=============================== ===============================================
+
+In addition, the m.css Doxygen theme recognizes the following extra options:
+
+.. class:: m-table m-fullwidth
+
+=================================== =======================================
+Variable                            Description
+=================================== =======================================
+:ini:`M_THEME_COLOR`                Color for :html:`<meta name="theme-color"/>`,
+                                    corresponding to the CSS style. See below
+                                    for more information.
+:ini:`M_PAGE_HEADER`                HTML code to put at the top of every page.
+                                    Useful for example to link to different
+                                    versions of the same documentation. The
+                                    ``{filename}`` placeholder is replaced with
+                                    current file name.
+:ini:`M_CLASS_TREE_EXPAND_LEVELS`   How many levels of the class tree to
+                                    expand. ``0`` means only the top-level
+                                    symbols are shown. If not set, ``1`` is
+                                    used.
+:ini:`M_FILE_TREE_EXPAND_LEVELS`    How many levels of the file tree to expand.
+                                    ``0`` means only the top-level dirs/files
+                                    are shown. If not set, ``1`` is used.
+:ini:`M_EXPAND_INNER_TYPES`         Whether to expand inner types (e.g. a class
+                                    inside a class) in the symbol tree. If not
+                                    set, ``0`` is used.
+=================================== =======================================
+
+Note that namespace, directory and page lists are always fully expanded as
+these are not expected to be excessively large.
+
+By default, the `dark m.css theme <{filename}/css/themes.rst#dark>`_ together
+with Doxygen-theme-specific additions is used, which corresponds to the
+following configuration:
+
+.. code:: ini
+
+    HTML_EXTRA_STYLESHEET = \
+        https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600 \
+        ../css/m-dark+doxygen.compiled.css
+    M_THEME_COLOR = #22272e
+
+If you have a site already using the ``m-dark.compiled.css`` file, there's
+another file called ``m-dark.doxygen.compiled.css``, which contains just the
+Doxygen-theme-specific additions so you can reuse the already cached
+``m-dark.compiled.css`` file from your main site:
+
+.. code:: ini
+
+    HTML_EXTRA_STYLESHEET = \
+        https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600 \
+        ../css/m-dark.compiled.css \
+        ../css/m-dark.doxygen.compiled.css
+    M_THEME_COLOR = #22272e
+
+If you prefer the `light m.css theme <{filename}/css/themes.rst#light>`_
+instead, use the following configuration (and, similarly, you can use
+``m-light.compiled.css`` together with ``m-light.doxygen.compiled-css`` in
+place of ``m-light+doxygen.compiled.css``:
+
+.. code:: ini
+
+    HTML_EXTRA_STYLESHEET = \
+        https://fonts.googleapis.com/css?family=Libre+Baskerville:400,400i,700,700i%7CSource+Code+Pro:400,400i,600 \
+        ../css/m-light+doxygen.compiled.css
+    M_THEME_COLOR = #cb4b16
+
+See the `CSS files`_ section below for more information about customizing the
+CSS files.
+
+`Text content`_
+===============
+
+Brief and detailed description is parsed as-is with the following
+modifications:
+
+-   Function parameter documentation, return value documentation and template
+    parameter documentation is extracted out of the text flow to allow for more
+    flexible styling, it's also reordered to match parameter order and warnings
+    are emitted if there are mismatches.
+-   To make text content wrap better on narrow screens, :html:`<wbr/>` tags are
+    added after ``::`` and ``_`` in long symbols in link titles and after ``/``
+    in URLs.
+
+`Pages, sections and table of contents`_
+========================================
+
+Table of contents is unconditionally generated for all compound documentation
+pages and includes both ``@section`` blocks in the detailed documentation as
+well as the reference sections. If your documentation is using Markdown-style
+headers (prefixed with ``##``, for example), the script is not able to generate
+TOC entries for these. Upon encountering them, tt will warn and suggest to use
+the ``@section`` command instead.
+
+Table of contents for pages is generated only if they specify
+``@tableofcontents`` in their documentation block.
+
+.. block-warning:: Doxygen patches
+
+    Note that recognition of the ``@tableofcontents`` command requires Doxygen
+    with :gh:`doxygen/doxygen#625` applied. Brief description of pages is
+    ignored and not extracted to the page index unless Doxygen has
+    :gh:`doxygen/doxygen#624` applied.
+
+`C++ support`_
+==============
+
+.. block-warning:: Doxygen patches
+
+    In order to properly detect template parameters for type aliases (the
+    :cpp:`using` keyword), Doxygen with :gh:`doxygen/doxygen#626` applied is
+    required. Rendering underlying enum types and enum strongness then requires
+    :gh:`doxygen/doxygen#627`.
+
+`Code highlighting`_
+====================
+
+Every code snippet should be annotated with language-specific extension like in
+the example below. If not, the theme will assume C++ and emit a warning on
+output. Language of snippets included via ``@include`` and related commands is
+autodetected from filename.
+
+.. code:: c++
+
+    /**
+    @code{.cpp}
+    int main() { }
+    @endcode
+    */
+
+Besides native Pygments mapping of file extensions to languages, there are the
+following special cases:
+
+.. class:: m-table m-fullwidth
+
+=================== ===========================================================
+Filename suffix     Detected language
+=================== ===========================================================
+``.h``              C++ (instead of C)
+``.h.cmake``        C++ (instead of CMake), as this extension is often used for
+                    C++ headers that are preprocessed with CMake
+``.h.nostrip``      C++. Useful for embedding code snippets with Doxygen
+                    comment block, as Doxygen would strip them with plain
+                    ``.h``.
+``.glsl``           GLSL. For some reason, stock Pygments detect only
+                    ``.vert``, ``.frag`` and ``.geo`` extensions as GLSL.
+``.conf``           INI (key-value configuration files)
+``.ansi``           `Colored terminal output <{filename}/css/components.rst#colored-terminal-output>`_.
+                    Use ``.shell-session`` pseudo-extension for simple
+                    uncolored terminal output.
+=================== ===========================================================
+
+The theme has experimental support for inline code highlighting. Inline code is
+distinguished from code blocks using the following rules:
+
+-   Code that is delimited from surrounding paragraphs with an empty line is
+    considered as block.
+-   Code that is not alone in a paragraph is considered as inline.
+-   For compatibility reasons, if code that is detected as inline consists of
+    more than one line, it's rendered as code block and a warning is printed to
+    output.
+
+Inline highlighted code is written also using the ``@code`` command, but as
+writing things like
+
+.. code:: c++
+
+    /** Returns @code{.cpp} Magnum::Vector2 @endcode, which is
+        @code{.glsl} vec2 @endcode in GLSL. */
+
+is too verbose, it's advised to configure some aliases in your ``Doxyfile-mcss``.
+For example, you can configure an alias for general inline code snippets and
+shorter versions for commonly used languages like C++ and CMake.
+
+.. code:: ini
+
+    ALIASES += \
+        "cb{1}=@code{\1}" \
+        "ce=@endcode" \
+        "cpp=@code{.cpp}" \
+        "cmake=@code{.cmake}"
+
+With this in place the above could be then written simply as:
+
+.. code:: c++
+
+    /** Returns @cpp Magnum::Vector2 @ce, which is @cb{.glsl} vec2 @ce in GLSL. */
+
+If you need to preserve compatibility with stock Doxygen HTML output (because
+it renders all ``@code`` sections as blocks), use the following fallback
+aliases in the original ``Doxyfile``:
+
+.. code:: ini
+
+    ALIASES += \
+        "cb{1}=<tt>" \
+        "ce=</tt>" \
+        "cpp=<tt>" \
+        "cmake=<tt>"
+
+.. block-warning:: Doxygen limitations
+
+    Due to Doxygen limitations, sometimes a single-line code block coming from
+    ``@skipline`` and related commands is detected as inline code and prepended
+    to the immediately following paragraph. In order to prevent that, add a
+    stray :html:`<p>` tag right
+    after the block:
+
+    .. code:: c++
+
+        /**
+        Text paragraph before a code block.
+
+        @skipline foo
+        <p>
+
+        Next text paragraph after a code block.
+        */
+
+    Besides that, it's not possible to use inline code highlighting in
+    ``@brief`` description. Code placed there is moved by Doxygen to the
+    detailed description.
+
+.. block-warning:: Doxygen patches
+
+    Note that proper language detection for code snippets requires Doxygen with
+    :gh:`doxygen/doxygen#621` applied, otherwise all snippets will fall back to
+    C++ highlighting. Using ANSI color escape codes in terminal output require
+    Doxygen with :gh:`doxygen/doxygen#623` applied, otherwise the codes will be
+    present in the rendered output in their raw form.
+
+`Command-line options`_
+=======================
+
+::
+
+    ./dox2html5.py [-h] [--templates TEMPLATES] [--wildcard WILDCARD]
+                   [--index-pages INDEX_PAGES [INDEX_PAGES ...]]
+                   [--no-doxygen] [--debug]
+                   doxyfile
+
+Arguments:
+
+-   ``doxyfile`` --- where the Doxyfile is
+
+Options:
+
+-   ``-h``, ``--help`` --- show this help message and exit
+-   ``--templates TEMPLATES`` --- template directory. Defaults to the
+    ``templates/`` subdirectory if not set.
+-   ``--wildcard WILDCARD`` --- only process files matching the wildcard.
+    Useful for debugging to speed up / restrict the processing to a subset of
+    files. Defaults to ``*.xml`` if not set.
+-   ``--index-pages INDEX_PAGES [INDEX_PAGES ...]`` --- index page templates.
+    By default, if not set, the index pages are matching stock Doxygen, i.e.
+    ``annotated.html``, ``files.html``, ``namespaces.html`` and ``pages.html``.
+    See `Navigation page templates`_ section below for more information.
+-   ``--no-doxygen`` --- don't run Doxygen before. By default Doxygen is run
+    before the script to refresh the generated XML output.
+-   ``--debug`` --- verbose debug output. Useful for debugging.
+
+`Customizing the template`_
+===========================
+
+The rest of the documentation explains how to customize the builtin template to
+better suit your needs. Each documentation file is generated from one of the
+template files that are bundled with the script. However, it's possible to
+provide your own Jinja2 template files for customized experience as well as
+modify the CSS styling.
+
+`CSS files`_
+------------
+
+By default, compiled CSS files are used to reduce amount of HTTP requests and
+bandwidth needed for viewing the documentation. However, for easier
+customization and debugging it's better to use the unprocessed stylesheets. The
+:ini:`HTML_EXTRA_STYLESHEET` lists all files that go to the :html:`<link rel="stylesheet" />`
+in the resulting HTML markup, while :ini:`HTML_EXTRA_FILES` lists the
+indirectly referenced files that need to be copied to the output as well. Below
+is an example configuration corresponding to the dark theme:
+
+.. code:: ini
+
+    HTML_EXTRA_STYLESHEET = \
+        https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600 \
+        ../css/m-dark.css \
+        ../css/m-doxygen.css
+    HTML_EXTRA_FILES = \
+        ../css/m-grid.css \
+        ../css/m-components.css \
+        ../css/pygments-dark.css \
+        ../css/pygments-console.css
+    M_THEME_COLOR = #22272e
+
+After making desired changes to the source files, it's possible to postprocess
+them back to the compiled version using the ``postprocess.py`` utility as
+explained in the `CSS themes <{filename}/css/themes.rst#make-your-own>`_
+documentation. In case of the dark theme, the ``m-dark+doxygen.compiled.css``
+and ``m-dark.doxygen.compiled.css`` files are produced like this:
+
+.. code:: sh
+
+    cd css
+    ./postprocess.py m-dark.css m-doxygen.css -o m-dark+doxygen.compiled.css
+    ./postprocess.py m-dark.css m-doxygen.css --no-import -o m-dark.doxygen.compiled.css
+
+`Compound documentation template`_
+----------------------------------
+
+For compound documentation one output HTML file corresponds to one input XML
+file and there are some naming conventions imposed by Doxygen.
+
+.. class:: m-table m-fullwidth
+
+======================= =======================================================
+Filename                Use
+======================= =======================================================
+``class.html``          Class documentation, read from ``class*.xml`` and saved
+                        as ``class*.html``
+``dir.html``            Directory documentation, read from ``dir_*.xml`` and
+                        saved as ``dir_*.html``
+``example.html``        Example code listing, read from ``*-example.xml`` and
+                        saved as ``*-example.html``
+``file.html``           File documentation, read from ``*.xml`` and saved as
+                        ``*.html``
+``namespace.html``      Namespace documentation, read fron ``namespace*.xml``
+                        and saved as ``namespace*.html``
+``page.html``           Page, read from ``*.xml``/``indexpage.xml`` and saved
+                        as ``*.html``/``index.html``
+``struct.html``         Struct documentation, read from ``struct*.xml`` and
+                        saved as ``struct*.html``
+``union.html``          Union documentation, read from ``union*.xml`` and saved
+                        as ``union*.html``
+======================= =======================================================
+
+Each template is passed a subset of the ``Doxyfile`` configuration values from
+the above table and in addition the following variables:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Variable                    Description
+=========================== ===================================================
+:py:`FILENAME`              Name of given output file
+:py:`DOXYGEN_VERSION`       Version of Doxygen that generated given XML file
+=========================== ===================================================
+
+In addition to builtin Jinja2 filters, the the ``basename_or_url`` filter
+returns either a basename of file path, if the path is relative; or a full URL,
+if the argument is an absolute URL. It's useful in cases like this:
+
+.. code:: html+jinja
+
+  {% for css in HTML_EXTRA_STYLESHEET %}
+  <link rel="stylesheet" href="{{ css|basename_or_url }}" />
+  {% endfor %}
+
+The actual page contents are provided in a :py:`compound` object, which has the
+following properties. All exposed data are meant to be pasted directly to the
+HTML code without any escaping.
+
+.. class:: m-table m-fullwidth
+
+======================================= =======================================
+Property                                Description
+======================================= =======================================
+:py:`compound.kind`                     One of :py:`'class'`, :py:`'dir'`,
+                                        :py:`'example'`, :py:`'file'`,
+                                        :py:`'namespace'`, :py:`'page'`,
+                                        :py:`'struct'`, :py:`'union'`, used to
+                                        choose a template file from above
+:py:`compound.id`                       Unique compound identifier, usually
+                                        corresponding to output file name
+:py:`compound.name`                     Compound name
+:py:`compound.templates`                Template specification. Set only for
+                                        classes. See `Template properties`_ for
+                                        details.
+:py:`compound.has_template_details`     If there is a detailed documentation
+                                        of template parameters
+:py:`compound.sections`                 Sections of detailed description. See
+                                        `Section properties`_ for details.
+:py:`compound.brief`                    Brief description. Can be empty. [1]_
+:py:`compound.description`              Detailed description. Can be empty. [2]_
+:py:`compound.dirs`                     List of directories in this compound.
+                                        Set only for directories. See
+                                        `Directory properties`_ for details.
+:py:`compound.files`                    List of files in this compound. Set
+                                        only for directories and files. See
+                                        `File properties`_ for details.
+:py:`compound.namespaces`               List of namespaces in this compound.
+                                        Set only for files and namespaces. See
+                                        `Namespace properties`_ for details.
+:py:`compound.classes`                  List of classes in this compound. Set
+                                        only for files and namespaces. See
+                                        `Class properties`_ for details.
+:py:`compound.enums`                    List of enums in this compound. Set
+                                        only for files and namespaces. See
+                                        `Enum properties`_ for details.
+:py:`compound.typedefs`                 List of typedefs in this compound. Set
+                                        only for files and namespaces. See
+                                        `Typedef properties`_ for details.
+:py:`compound.funcs`                    List of functions in this compound. Set
+                                        only for files and namespaces. See
+                                        `Function properties`_ for details.
+:py:`compound.vars`                     List of variables in this compound. Set
+                                        only for files and namespaces. See
+                                        `Variable properties`_ for details.
+:py:`compound.defines`                  List of defines in this compound. Set
+                                        only for files. See `Define properties`_
+                                        for details.
+:py:`compound.public_types`             List of public types. Set only for
+                                        classes. See `Type properties`_ for
+                                        details.
+:py:`compound.public_static_funcs`      List of public static functions. Set
+                                        only for classes. See
+                                        `Function properties`_ for details.
+:py:`compound.public_funcs`             List of public functions. Set only for
+                                        classes. See `Function properties`_ for
+                                        details.
+:py:`compound.public_static_vars`       List of public static variables. Set
+                                        only for classes. See
+                                        `Variable properties`_ for details.
+:py:`compound.public_vars`              List of public variables. Set only for
+                                        classes. See `Variable properties`_ for
+                                        details.
+:py:`compound.protected_types`          List of protected types. Set only for
+                                        classes. See `Type properties`_ for
+                                        details.
+:py:`compound.protected_static_funcs`   List of protected static functions. Set
+                                        only for classes. See
+                                        `Function properties`_ for details.
+:py:`compound.protected_funcs`          List of protected functions. Set only
+                                        for classes. See `Function properties`_
+                                        for details.
+:py:`compound.protected_static_vars`    List of protected static variables. Set
+                                        only for classes. See
+                                        `Variable properties`_ for details.
+:py:`compound.protected_vars`           List of protected variables. Set only
+                                        for classes. See `Variable properties`_
+                                        for details.
+:py:`compound.private_funcs`            List of documented private virtual
+                                        functions. Set only for classes. See
+                                        `Function properties`_ for details.
+:py:`compound.related`                  List of related non-member symbols. Set
+                                        only for classes. See
+                                        `Related properties`_ for details.
+:py:`compound.groups`                   List of user-defined groups in this
+                                        compound. See `Group properties`_ for
+                                        details.
+:py:`compound.has_enum_details`         If there is at least one enum with full
+                                        description block [5]_
+:py:`compound.has_typedef_details`      If there is at least one typedef with
+                                        full description block [5]_
+:py:`compound.has_func_details`         If there is at least one function with
+                                        full description block [5]_
+:py:`compound.has_var_details`          If there is at least one variable with
+                                        full description block [5]_
+:py:`compound.has_define_details`       If there is at least one define with
+                                        full description block [5]_
+:py:`compound.breadcrumb`               List of :py:`(title, URL)` tuples for
+                                        breadcrumb navigation. Set only for
+                                        classes, directories, files, namespaces
+                                        and pages.
+:py:`compound.prefix_wbr`               Fully-qualified symbol prefix for given
+                                        compound with trailing ``::`` with
+                                        :html:`<wbr/>` tag before every ``::``.
+                                        Set only for classes, namespaces,
+                                        structs and unions; on templated
+                                        classes contains also the list of
+                                        template parameter names.
+:py:`compound.save_as`                  Filename including extension where the
+                                        result will be saved
+======================================= =======================================
+
+`Section properties`_
+`````````````````````
+
+The :py:`compound.sections` property defines a Table of Contents for given
+detailed description. It's a list of :py:`(id, title, children)` tuples, where
+:py:`id` is the link anchor, :py:`title` is section title and :py:`children` is
+a recursive list of nested sections. If the list is empty, given detailed
+description either has no sections or the TOC was not explicitly requested via
+``@tableofcontents`` in case of pages.
+
+`Directory properties`_
+```````````````````````
+
+The :py:`compound.dirs` property contains a list of directories, where every
+item has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`dir.url`               URL of the file containing detailed directory docs
+:py:`dir.name`              Directory name (just the leaf)
+:py:`dir.brief`             Brief description. Can be empty. [1]_
+=========================== ===================================================
+
+`File properties`_
+``````````````````
+
+The :py:`compound.files` property contains a list of files, where every item
+has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`file.url`              URL of the file containing detailed file docs
+:py:`file.name`             File name (just the leaf)
+:py:`file.brief`            Brief description. Can be empty. [1]_
+=========================== ===================================================
+
+`Namespace properties`_
+```````````````````````
+
+The :py:`compound.namespaces` property contains a list of namespaces, where
+every item has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`namespace.url`         URL of the file containing detailed namespace docs
+:py:`namespace.name`        Namespace name. Fully qualified in case it's in a
+                            file documentation, just the leaf name if in a
+                            namespace documentation.
+:py:`namespace.brief`       Brief description. Can be empty. [1]_
+=========================== ===================================================
+
+`Class properties`_
+```````````````````
+
+The :py:`compound.classes` property contains a list of classes, where every
+item has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`class_.kind`           One of :py:`'class'`, :py:`'struct'`, :py:`'union'`
+:py:`class_.url`            URL of the file containing detailed class docs
+:py:`class_.name`           Class name. Fully qualified in case it's in a file
+                            documentation, just the leaf name if in a namespace
+                            documentation.
+:py:`class_.templates`      Template specification. See `Template properties`_
+                            for details.
+:py:`class_.brief`          Brief description. Can be empty. [1]_
+=========================== ===================================================
+
+`Enum properties`_
+``````````````````
+
+The :py:`compound.enums` property contains a list of enums, where every item
+has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=============================== ===============================================
+Property                        Description
+=============================== ===============================================
+:py:`enum.id`                   Identifier hash [3]_
+:py:`enum.type`                 Enum type or empty if implicitly typed [6]_
+:py:`enum.is_strong`            If the enum is strong
+:py:`enum.name`                 Enum name [4]_
+:py:`enum.brief`                Brief description. Can be empty. [1]_
+:py:`enum.description`          Detailed description. Can be empty. [2]_
+:py:`enum.has_details`          If there is enough content for the full
+                                description block [5]_
+:py:`enum.is_protected`         If the enum is :cpp:`protected`. Set only for
+                                member types.
+:py:`enum.values`               List of enum values
+:py:`enum.has_value_details`    If the enum values have description
+=============================== ===============================================
+
+Every item of :py:`enum.values` has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`value.id`              Identifier hash [3]_
+:py:`value.name`            Value name [4]_
+:py:`value.initializer`     Value initializer. Can be empty. [1]_
+:py:`value.description`     Detailed description. Can be empty. [2]_
+=========================== ===================================================
+
+`Typedef properties`_
+`````````````````````
+
+The :py:`compound.typedefs` property contains a list of typedefs, where every
+item has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`typedef.id`            Identifier hash [3]_
+:py:`typedef.is_using`      Whether it is a :cpp:`typedef` or an :cpp:`using`
+:py:`typedef.type`          Typedef type, or what all goes before the name for
+                            function pointer typedefs [6]_
+:py:`typedef.args`          Typedef arguments, or what all goes after the name
+                            for function pointer typedefs [6]_
+:py:`typedef.name`          Typedef name [4]_
+:py:`typedef.templates`     Template specification. Set only in case of
+                            :cpp:`using`. . See `Template properties`_ for
+                            details.
+:py:`typedef.brief`         Brief description. Can be empty. [1]_
+:py:`typedef.description`   Detailed description. Can be empty. [2]_
+:py:`typedef.has_details`   If there is enough content for the full description
+                            block [4]_
+:py:`typedef.is_protected`  If the typedef is :cpp:`protected`. Set only for
+                            member types.
+=========================== ===================================================
+
+`Function properties`_
+``````````````````````
+
+The :py:`commpound.funcs`, :py:`compound.public_static_funcs`,
+:py:`compound.public_funcs`, :py:`compound.protected_static_funcs`,
+:py:`compound.protected_funcs`, :py:`compound.private_funcs` and
+:py:`compound.related_funcs` properties contain a list of functions, where
+every item has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=============================== ===============================================
+Property                        Description
+=============================== ===============================================
+:py:`func.id`                   Identifier hash [3]_
+:py:`func.type`                 Function return type [6]_
+:py:`func.name`                 Function name [4]_
+:py:`func.templates`            Template specification. See
+                                `Template properties`_ for details.
+:py:`func.has_template_details` If template parameters have description
+:py:`func.params`               List of function parameters. See below for
+                                details.
+:py:`func.has_param_details`    If function parameters have description
+:py:`func.return_value`         Return value description. Can be empty.
+:py:`func.brief`                Brief description. Can be empty. [1]_
+:py:`func.description`          Detailed description. Can be empty. [2]_
+:py:`func.has_details`          If there is enough content for the full
+                                description block [5]_
+:py:`func.prefix`               Function signature prefix, containing keywords
+                                such as :cpp:`static`. Information about
+                                :cpp:`constexpr`\ ness, :cpp:`explicit`\ ness
+                                and :cpp:`virtual`\ ity is removed from the
+                                prefix and available via other properties.
+:py:`func.suffix`               Function signature suffix, containing keywords
+                                such as :cpp:`const` and r-value overloads.
+                                Information about :cpp:`noexcept`, pure
+                                :cpp:`virtual`\ ity and :cpp:`delete`\ d /
+                                :cpp:`default`\ ed functions is removed from
+                                the suffix and available via other properties.
+:py:`func.is_protected`         If the function is :cpp:`protected`. Set only
+                                for member functions.
+:py:`func.is_private`           If the function is :cpp:`private`. Set only for
+                                member functions.
+:py:`func.is_explicit`          If the function is :cpp:`explicit`. Set only
+                                for member functions.
+:py:`func.is_virtual`           If the function is :cpp:`virtual`. Set only for
+                                member functions.
+:py:`func.is_pure_virtual`      If the function is pure :cpp:`virtual`. Set
+                                only for member functions.
+:py:`func.is_noexcept`          If the function is :cpp:`noexcept`
+:py:`func.is_constexpr`         If the function is :cpp:`constexpr`
+:py:`func.is_defaulted`         If the function is :cpp:`default`\ ed
+:py:`func.is_deleted`           If the function is :cpp:`delete`\ d
+=============================== ===============================================
+
+The :py:`func.params` is a list of function parameters and their description.
+Each item has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`param.name`            Parameter name (if not anonymous)
+:py:`param.type`            Parameter type, together with name and array
+                            specification [6]_
+:py:`param.default`         Default parameter value, if any [6]_
+:py:`param.description`     Optional parameter description. If set,
+                            :py:`func.has_param_details` is set as well.
+:py:`param.direction`       Parameter direction. One of :py:`'in'`, :py:`'out'`,
+                            :py:`'inout'` or :py:`''` if unspecified.
+=========================== ===================================================
+
+`Variable properties`_
+``````````````````````
+
+The :py:`compound.vars`, :py:`compound.public_vars` and
+:py:`compound.protected_vars` properties contain a list of variables, where
+every item has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`var.id`                Identifier hash [3]_
+:py:`var.type`              Variable type [6]_
+:py:`var.name`              Variable name [4]_
+:py:`var.brief`             Brief description. Can be empty. [1]_
+:py:`var.description`       Detailed description. Can be empty. [2]_
+:py:`var.has_details`       If there is enough content for the full description
+                            block [5]_
+:py:`var.is_static`         If the variable is :cpp:`static`. Set only for
+                            member variables.
+:py:`var.is_protected`      If the variable is :cpp:`protected`. Set only for
+                            member variables.
+:py:`var.is_constexpr`      If the variable is :cpp:`constexpr`
+=========================== ===================================================
+
+`Define properties`_
+````````````````````
+
+The :py:`compound.defines` property contains a list of defines, where every
+item has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=============================== ===============================================
+Property                        Description
+=============================== ===============================================
+:py:`define.id`                 Identifier hash [3]_
+:py:`define.name`               Define name
+:py:`define.params`             List of macro parameter names. See below for
+                                details.
+:py:`define.has_param_details`  If define parameters have description
+:py:`define.return_value`       Return value description. Can be empty.
+:py:`define.brief`              Brief description. Can be empty. [1]_
+:py:`define.description`        Detailed description. Can be empty. [2]_
+:py:`define.has_details`        If there is enough content for the full
+                                description block [5]_
+=============================== ===============================================
+
+The :py:`define.params` is set to :py:`None` if the macro is just a variable.
+If it's a function, each item is a tuple consisting of name and optional
+description. If the description is set, :py:`define.has_param_details` is set
+as well. You can use :jinja:`{% if define.params != None %}` to disambiguate
+between preprocessor macros and variables in your code.
+
+`Type properties`_
+``````````````````
+
+For classes, the :py:`compound.public_types` and :py:`compound.protected_types`
+contains a list of :py:`(kind, type)` tuples, where ``kind`` is one of
+:py:`'class'`, :py:`'enum'` or :py:`'typedef'` and ``type`` is a corresponding
+type of object described above.
+
+`Template properties`_
+``````````````````````
+
+The :py:`compound.templates`, :py:`typedef.templates` and :py:`func.templates`
+properties contain either :py:`None` if given symbol is a full template
+specialization or a list of template parameters, where every item has the
+following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`template.type`         Template parameter type (:cpp:`class`,
+                            :cpp:`typename` or a type)
+:py:`template.name`         Template parameter name
+:py:`template.default`      Template default value. Can be empty.
+:py:`template.description`  Optional template description. If set,
+                            :py:`i.has_template_details` is set as well.
+=========================== ===================================================
+
+You can use :jinja:`{% if i.templates != None %}` to test for the field
+presence in your code.
+
+`Related properties`_
+`````````````````````
+
+The :py:`compound.related` contains a list of related non-member symbols. Each
+symbol is a tuple of :py:`(kind, member)`, where :py:`kind` is one of
+:py:`'dir'`, :py:`'file'`, :py:`'namespace'`, :py:`'class'`, :py:`'enum'`,
+:py:`'typedef'`, :py:`'func'`, :py:`'var'` or :py:`'define'` and :py:`member`
+is a corresponding type of object described above.
+
+`Group properties`_
+```````````````````
+
+The :py:`compound.groups` contains a list of user-defined groups. Each item has
+the following properties:
+
+======================= =======================================================
+Property                Description
+======================= =======================================================
+:py:`group.id`          Group identifier [3]_
+:py:`group.name`        Group name
+:py:`group.description` Group description [2]_
+:py:`group.members`     Group members. Each item is a tuple of
+                        :py:`(kind, member)`, where :py:`kind` is one of
+                        :py:`'namespace'`, :py:`'class'`, :py:`'enum'`,
+                        :py:`'typedef'`, :py:`'func'`, :py:`'var'` or
+                        :py:`'define'` and :py:`member` is a corresponding type
+                        of object described above.
+======================= =======================================================
+
+.. [1] :py:`i.brief` is a single-line paragraph without the enclosing :html:`<p>`
+    element, rendered as HTML. Can be empty in case of function overloads.
+.. [2] :py:`i.description` is HTML code with the full description, containing
+    paragraphs, notes, code blocks, images etc. Can be empty in case just the
+    brief description is present.
+.. [3] :py:`i.id` is a hash used to link to the member on the page, usually
+    appearing after ``#`` in page URL
+.. [4] :py:`i.name` is just the member name, not qualified. Prepend
+    :py:`compound.prefix_wbr` to it to get the fully qualified name.
+.. [5] :py:`compound.has_*_details` and :py:`i.has_details` are :py:`True` if
+    there is detailed description, function/template/macro parameter
+    documentation or enum value listing that makes it worth to render the full
+    description block. If :py:`False`, the member should be included only in
+    the brief listing on top of the page to avoid unnecessary repetition.
+.. [6] :py:`i.type` and :py:`param.default` is rendered as HTML and usually
+    contains links to related documentation
+
+`Navigation page templates`_
+----------------------------
+
+By default the theme tries to match the original Doxygen listing pages. These
+pages are generated from the ``index.xml`` file and their template name
+corresponds to output file name.
+
+.. class:: m-table m-fullwidth
+
+======================= =======================================================
+Filename                Use
+======================= =======================================================
+``annotated.html``      Class listing
+``files.html``          File and directory listing
+``namespaces.html``     Namespace listing
+``pages.html``          Page listing
+======================= =======================================================
+
+By default it's those four pages, but you can configure any other pages via
+the ``--index-pages`` option as mentioned in the `Command-line options`_
+section.
+
+Each template is passed a subset of the ``Doxyfile`` configuration values from
+the above table and in addition the :py:`FILENAME` and :py:`DOXYGEN_VERSION`
+variables as above. The navigation tree is provided in an :py:`index` object,
+which has the following properties:
+
+.. class:: m-table m-fullwidth
+
+=========================== ===================================================
+Property                    Description
+=========================== ===================================================
+:py:`index.symbols`         List of all namespaces + classes
+:py:`index.files`           List of all dirs + files
+:py:`index.pages`           List of all pages
+=========================== ===================================================
+
+The form of each list entry is the same:
+
+.. class:: m-table m-fullwidth
+
+=============================== ===============================================
+Property                        Description
+=============================== ===============================================
+:py:`i.kind`                    Entry kind (one of :py:`'namespace'`,
+                                :py:`'class'`, :py:`'struct'`, :py:`'union'`,
+                                :py:`'dir'`, :py:`'file'`, :py:`'page'`)
+:py:`i.name`                    Name
+:py:`i.url`                     URL of the file with detailed documentation
+:py:`i.brief`                   Brief documentation
+:py:`i.has_nestable_children`   If the list has nestable children (i.e., dirs
+                                or namespaces)
+:py:`i.children`                Recursive list of child entries
+=============================== ===============================================
+
+Each list is ordered in a way that all namespaces are before all classes and
+all directories are before all files.
diff --git a/doc/static/m-doxygen.css b/doc/static/m-doxygen.css
new file mode 120000 (symlink)
index 0000000..2f4a4ad
--- /dev/null
@@ -0,0 +1 @@
+../../css/m-doxygen.css
\ No newline at end of file
diff --git a/doxygen/.gitignore b/doxygen/.gitignore
new file mode 100644 (file)
index 0000000..02d74de
--- /dev/null
@@ -0,0 +1,5 @@
+__pycache__
+htmlcov
+test/*/html/
+test/*/xml/
+.coverage
diff --git a/doxygen/dox2html5.py b/doxygen/dox2html5.py
new file mode 100755 (executable)
index 0000000..9d64b58
--- /dev/null
@@ -0,0 +1,1602 @@
+#!/usr/bin/env python
+
+#
+#   This file is part of m.css.
+#
+#   Copyright © 2017 Vladimír Vondruš <mosra@centrum.cz>
+#
+#   Permission is hereby granted, free of charge, to any person obtaining a
+#   copy of this software and associated documentation files (the "Software"),
+#   to deal in the Software without restriction, including without limitation
+#   the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#   and/or sell copies of the Software, and to permit persons to whom the
+#   Software is furnished to do so, subject to the following conditions:
+#
+#   The above copyright notice and this permission notice shall be included
+#   in all copies or substantial portions of the Software.
+#
+#   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+#   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#   DEALINGS IN THE SOFTWARE.
+#
+
+import xml.etree.ElementTree as ET
+import argparse
+import sys
+import re
+import html
+import os
+import glob
+import shutil
+import subprocess
+import urllib.parse
+import logging
+from types import SimpleNamespace as Empty
+from typing import Tuple, Dict, Any, List
+
+from jinja2 import Environment, FileSystemLoader
+
+from pygments import highlight
+from pygments.formatters import HtmlFormatter
+from pygments.lexers import TextLexer, BashSessionLexer, get_lexer_by_name, find_lexer_class_for_filename
+
+sys.path.append("../pelican-plugins")
+import m.latex2svg
+import m.math
+import m.ansilexer
+
+xref_id_rx = re.compile(r"""(.*)_1(_[a-z-]+[0-9]+)$""")
+slugify_nonalnum_rx = re.compile(r"""[^\w\s-]""")
+slugify_hyphens_rx = re.compile(r"""[-\s]+""")
+
+class State:
+    def __init__(self):
+        self.basedir = ''
+        self.compounds: Dict[str, Any] = {}
+        self.doxyfile: Dict[str, str] = {}
+        self.images: List[str] = []
+
+def slugify(text: str) -> str:
+    # Maybe some Unicode normalization would be nice here?
+    return slugify_hyphens_rx.sub('-', slugify_nonalnum_rx.sub('', text.lower()).strip())
+
+def add_wbr(text: str) -> str:
+    if '::' in text: # C++ names
+        return text.replace('::', '::<wbr/>')
+    elif '_' in text: # VERY_LONG_UPPER_CASE macro names
+        return text.replace('_', '_<wbr/>')
+
+    # These characters are quite common, so at least check that there is no
+    # space (which may hint that the text is actually some human language):
+    elif '/' in text and not ' ' in text: # URLs
+        return text.replace('/', '/<wbr/>')
+    else:
+        return text
+
+def parse_ref(state: State, element: ET.Element) -> str:
+    id = element.attrib['refid']
+
+    if element.attrib['kindref'] == 'compound':
+        url = id + '.html'
+    elif element.attrib['kindref'] == 'member':
+        i = id.rindex('_1')
+        url = id[:i] + '.html' + '#' + id[i+2:]
+    else: # pragma: no cover
+        logging.critical("unknown <ref> kind {}".format(element.attrib['kindref']))
+        assert False
+
+    if 'external' in element.attrib:
+        for i in state.doxyfile['TAGFILES']:
+            name, _, baseurl = i.partition('=')
+            if os.path.basename(name) == os.path.basename(element.attrib['external']):
+                url = os.path.join(baseurl, url)
+                break
+        else: # pragma: no cover
+            logging.critical("tagfile {} not specified in Doxyfile".format(element.attrib['external']))
+            assert False
+        class_ = 'm-dox-external'
+    else:
+        class_ = 'm-dox'
+
+    return '<a href="{}" class="{}">{}</a>'.format(url, class_, add_wbr(html.escape(element.text)))
+
+def extract_id(element: ET.Element) -> str:
+    id = element.attrib['id']
+    i = id.rindex('_1')
+    return id[i+2:]
+
+def fix_type_spacing(type: str) -> str:
+    return type.replace('&lt; ', '&lt;').replace(' &gt;', '&gt;').replace(' &amp;', '&amp;').replace(' *', '*')
+
+def parse_type(state: State, type: ET.Element) -> str:
+    # Constructors and typeless enums might not have it
+    if type is None: return None
+    out = html.escape(type.text) if type.text else ''
+
+    i: ET.Element
+    for i in type:
+        if i.tag == 'ref':
+            out += parse_ref(state, i)
+        elif i.tag == 'anchor':
+            out += '<a name="{}"></a>'.format(extract_id(i))
+        else: # pragma: no cover
+            logging.warning("ignoring {} in <type>".format(i.tag))
+
+        if i.tail: out += html.escape(i.tail)
+
+    # Remove spacing inside <> and before & and *
+    return fix_type_spacing(out)
+
+def parse_desc_internal(state: State, element: ET.Element, trim = True):
+    out = Empty()
+    out.write_start_tag = True
+    out.write_close_tag = True
+    out.section = None
+    out.templates = {}
+    out.params = {}
+    out.return_value = None
+
+    out.parsed: str = ''
+    if element.text:
+        out.parsed = html.escape(element.text.strip() if trim else element.text)
+
+    i: ET.Element
+    for i in element:
+        # Doxygen puts the following *block* elements inside a <para> element
+        # instead of closing it before and then opening it again after. Nested
+        # paragraphs are ugly and also not valid HTML, so we have to patch that
+        # up. If there was any content before, we close the paragraph. If there
+        # wasn't, we tell the caller to not even open the paragraph. After
+        # processing the following tag, there won't be any paragraph open, so
+        # we also tell the caller that there's no need to close anything.
+        #
+        # Note that <parameterlist> and <simplesect kind="return"> are
+        # extracted out of the text flow, so these are removed from this check.
+        #
+        # It's not that simple, see for more patching at the end of the cycle
+        # iteration.
+        if (i.tag in ['blockquote', 'xrefsect', 'variablelist', 'verbatim'] or (i.tag == 'simplesect' and i.attrib['kind'] != 'return') or (i.tag == 'formula' and i.text.startswith('\[ ') and i.text.endswith(' \]'))) and element.tag == 'para' and out.write_close_tag:
+            out.parsed = out.parsed.rstrip()
+            if not out.parsed:
+                out.write_start_tag = False
+            else:
+                out.parsed += '</p>'
+            out.write_close_tag = False
+
+        # Block elements
+        if i.tag in ['sect1', 'sect2', 'sect3']:
+            parsed = parse_desc_internal(state, i)
+            assert parsed.section
+            assert not parsed.templates and not parsed.params and not parsed.return_value
+
+            # Top-level section has no ID or title
+            if not out.section: out.section = ('', '', [])
+            out.section = (out.section[0], out.section[1], out.section[2] + [parsed.section])
+            out.parsed += '<section id="{}">{}</section>'.format(extract_id(i), parsed.parsed)
+
+        elif i.tag == 'title':
+            if element.tag == 'sect1':
+                tag = 'h2'
+            elif element.tag == 'sect2':
+                tag = 'h3'
+            elif element.tag == 'sect3':
+                tag = 'h4'
+            else: # pragma: no cover
+                assert False
+            id = extract_id(element)
+            title = html.escape(i.text)
+
+            # Populate section info
+            assert not out.section
+            out.section = (id, title, [])
+            out.parsed += '<{0}><a href="#{1}">{2}</a></{0}>'.format(tag, id, title)
+
+        elif i.tag == 'heading':
+            if i.attrib['level'] == '1':
+                tag = 'h2'
+            elif i.attrib['level'] == '2':
+                tag = 'h3'
+            elif i.attrib['level'] == '3':
+                tag = 'h4'
+            else: # pragma: no cover
+                assert False
+            logging.warning("Prefer @section over Markdown heading for properly generated TOC")
+            out.parsed += '<{0}>{1}</{0}>'.format(tag, html.escape(i.text))
+
+        elif i.tag == 'para':
+            # Parse contents of the paragraph, don't trim whitespace around
+            # nested elements but trim it at the begin and end of the paragraph
+            # itself. Also, some paragraphs are actually block content and we
+            # might not want to write the start/closing tag.
+            parsed = parse_desc_internal(state, i, False)
+            parsed.parsed = parsed.parsed.strip()
+
+            # Inherit parameter and return value description, assume it's not
+            # scattered all over the place (ugh)
+            if parsed.templates:
+                assert not out.templates
+                out.templates = parsed.templates
+            if parsed.params:
+                assert not out.params
+                out.params = parsed.params
+            if parsed.return_value:
+                assert not out.return_value
+                out.return_value = parsed.return_value
+
+            # Assert we didn't miss anything important
+            assert not parsed.section
+
+            # Omit superfluous <p> for simple elments (list items, brief,
+            # parameter and return value description)
+            if not parsed.write_start_tag or element.tag in ['listitem', 'briefdescription', 'parameterdescription'] or element.tag == 'simplesect' and element.attrib['kind'] == 'return':
+                out.parsed += parsed.parsed
+            elif parsed.parsed:
+                if parsed.write_close_tag:
+                    out.parsed += '<p>{}</p>'.format(parsed.parsed)
+                else:
+                    out.parsed += '<p>{}'.format(parsed.parsed)
+
+        elif i.tag == 'blockquote':
+            out.parsed += '<blockquote>{}</blockquote>'.format(parse_desc(state, i))
+
+        elif i.tag == 'itemizedlist':
+            out.parsed += '<ul>{}</ul>'.format(parse_desc(state, i))
+
+        elif i.tag == 'orderedlist':
+            out.parsed += '<ol>{}</ol>'.format(parse_desc(state, i))
+
+        elif i.tag == 'listitem':
+            out.parsed += '<li>{}</li>'.format(parse_desc(state, i))
+
+        elif i.tag == 'simplesect':
+            # Return value is separated from the text flow
+            if i.attrib['kind'] == 'return':
+                assert not out.return_value
+                out.return_value = parse_desc(state, i)
+            else:
+                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>'
+
+        elif i.tag == 'xrefsect':
+            id = i.attrib['id']
+            match = xref_id_rx.match(id)
+            file = match.group(1)
+            if file.startswith(('deprecated', 'bug')):
+                color = 'm-danger'
+            elif file.startswith('todo'):
+                color = 'm-dim'
+            else:
+                color = 'm-default'
+            out.parsed += '<aside class="m-note {}"><h4><a href="{}.html#{}" class="m-dox">{}</a></h4>{}</aside>'.format(
+                color, file, match.group(2), i.find('xreftitle').text, parse_desc(state, i.find('xrefdescription')))
+
+        elif i.tag == 'parameterlist':
+            out.param_kind = i.attrib['kind']
+            assert out.param_kind in ['param', 'templateparam']
+            for param in i:
+                # This is an overcomplicated shit, so check sanity
+                assert param.tag == 'parameteritem'
+                assert len(param.findall('parameternamelist')) == 1
+                assert param.find('parameternamelist').find('parametertype') is None
+                assert len(param.find('parameternamelist').findall('parametername')) == 1
+
+                name = param.find('parameternamelist').find('parametername')
+                description = parse_desc(state, param.find('parameterdescription'))
+                if i.attrib['kind'] == 'param':
+                    out.params[name.text] = (description, name.attrib['direction'] if 'direction' in name.attrib else '')
+                elif i.attrib['kind'] == 'templateparam':
+                    out.templates[name.text] = description
+
+        elif i.tag == 'variablelist':
+            out.parsed += '<dl class="m-dox">'
+
+            for var in i:
+                if var.tag == 'varlistentry':
+                    out.parsed += '<dt>{}</dt>'.format(parse_type(state, var.find('term')).strip())
+                elif var.tag == 'listitem':
+                    out.parsed += '<dd>{}</dd>'.format(parse_desc(state, var))
+
+            out.parsed += '</dl>'
+
+        elif i.tag == 'verbatim':
+            out.parsed += '<pre class="m-code">{}</pre>'.format(html.escape(i.text))
+
+        elif i.tag == 'programlisting':
+            # Seems to be a standalone code paragraph, don't wrap it in <p>
+            # and use <pre>
+            if element.tag == 'para' and (not element.text or not element.text.strip()) and (not i.tail or not i.tail.strip()) and len([listing for listing in element]) == 1:
+                code_block = True
+
+            # Looks like inline code, but has multiple code lines, so it's
+            # suspicious. Use code block, but warn.
+            elif len([codeline for codeline in i]) > 1:
+                code_block = True
+                logging.warning("Inline code has multiple lines, fallback to a code block")
+
+            # Otherwise wrap it in <p> and use <code>
+            else:
+                code_block = False
+
+                # Doxygen doesn't add a space before <programlisting> if it's
+                # inline, add it manually in case there should be a space
+                # before it. However, it does add a space after it always.
+                # TODO: could this be used to detect the problematic case?
+                if out.parsed and not out.parsed[-1].isspace() and not out.parsed[-1] in '([{':
+                    out.parsed += ' '
+
+            # Specialization of similar paragraph cleanup code above
+            if code_block:
+                out.parsed = out.parsed.rstrip()
+                if not out.parsed:
+                    out.write_start_tag = False
+                else:
+                    out.parsed += '</p>'
+                out.write_close_tag = False
+
+            # Hammer unhighlighted code out of the block
+            # TODO: preserve links
+            code = ''
+            codeline: ET.Element
+            for codeline in i:
+                assert codeline.tag == 'codeline'
+
+                tag: ET.Element
+                for tag in codeline:
+                    assert tag.tag == 'highlight'
+                    if tag.text: code += tag.text
+
+                    token: ET.Element
+                    for token in tag:
+                        if token.tag == 'sp':
+                            if 'value' in token.attrib:
+                                code += chr(int(token.attrib['value']))
+                            else:
+                                code += ' '
+                        elif token.tag == 'ref':
+                            # Ignoring <ref> until a robust solution is found
+                            # (i.e., also ignoring false positives)
+                            code += token.text
+                        else: # pragma: no cover
+                            logging.warning("Unknown {} in a code block ".format(token.tag))
+
+                        if token.tail: code += token.tail
+
+                    if tag.tail: code += tag.tail
+
+                code += '\n'
+
+            # Strip whitespace around if inline code, strip only trailing
+            # whitespace if a block
+            if not code_block: code = code.strip()
+
+            if not 'filename' in i.attrib:
+                logging.warning("No filename attribute in <programlisting>, assuming C++")
+                filename = 'file.cpp'
+            else:
+                filename = i.attrib['filename']
+
+            # Custom mapping of filenames to languages
+            mapping = [('.h', 'c++'),
+                       ('.h.cmake', 'c++'),
+                       ('.h.nostrip', 'c++'),
+                       # Pygments knows only .vert, .frag, .geo
+                       ('.glsl', 'glsl'),
+                       ('.conf', 'ini'),
+                       ('.ansi', m.ansilexer.AnsiLexer)]
+            for key, v in mapping:
+                if not filename.endswith(key): continue
+
+                if isinstance(v, str):
+                    lexer = get_lexer_by_name(v)
+                else:
+                    lexer = v()
+                break
+
+            # Otherwise try to find lexer by filename
+            else:
+                # Put some bogus prefix to the filename in case it is just
+                # `.ext`
+                lexer = find_lexer_class_for_filename("code" + filename)
+                if not lexer:
+                    logging.warning("Unrecognized language of {} in <programlisting>, highlighting disabled".format(filename))
+                    lexer = TextLexer()
+                else: lexer = lexer()
+
+            # Style console sessions differently
+            if (isinstance(lexer, BashSessionLexer) or
+                isinstance(lexer, m.ansilexer.AnsiLexer)):
+                class_ = 'm-console'
+            else:
+                class_ = 'm-code'
+
+            formatter = HtmlFormatter(nowrap=True)
+            highlighted = highlight(code, lexer, formatter)
+            # Strip whitespace around if inline code, strip only trailing
+            # whitespace if a block
+            highlighted = highlighted.rstrip() if code_block else highlighted.strip()
+            out.parsed += '<{0} class="{1}">{2}</{0}>'.format('pre' if code_block else 'code', class_, highlighted)
+
+        elif i.tag == 'image':
+            name = i.attrib['name']
+            path = None
+
+            if i.attrib['type'] == 'html':
+                # Discover the real path of the image
+                for candidate in state.doxyfile['IMAGE_PATH']:
+                    path = os.path.join(state.basedir, candidate, name)
+                    if os.path.exists(path):
+                        state.images += [path]
+                        break
+                else:
+                    logging.warning("Image {} was not found in any IMAGE_PATH".format(name))
+
+                alt = i.text
+                if not alt:
+                    alt = 'Image'
+                    logging.warning("Image {} has no alt text".format(name))
+
+                out.parsed += '<img class="m-image" src="{}" alt="{}" />'.format(name, html.escape(alt))
+
+        # Either block or inline because DOXYGEN!!! WHAT!!!
+        elif i.tag == 'formula':
+            # Inline formula
+            if i.text.startswith('$ ') and i.text.endswith(' $'):
+                rendered = m.latex2svg.latex2svg('${}$'.format(i.text[2:-2]), params=m.math.latex2svg_params)
+
+                # CSS classes and styling for proper vertical alignment. Depth is relative
+                # to font size, describes how below the line the text is. Scaling it back
+                # to 12pt font, scaled by 125% as set above in the config.
+                attribs = ' class="m-math" style="vertical-align: -{:.1f}pt;"'.format(rendered['depth']*12*1.25)
+                out.parsed += m.math._patch(i.text, rendered, attribs)
+
+            # Block formula
+            elif i.text.startswith('\[ ') and i.text.endswith(' \]'):
+                rendered = m.latex2svg.latex2svg('$${}$$'.format(i.text[3:-3]), params=m.math.latex2svg_params)
+                out.parsed += '<div class="m-math">{}</div>'.format(m.math._patch(i.text, rendered, ''))
+
+            # Shouldn't happen
+            else: # pragma: no cover
+                assert False
+
+        # Inline elements
+        elif i.tag == 'anchor':
+            out.parsed += '<a name="{}"></a>'.format(extract_id(i))
+
+        elif i.tag == 'computeroutput':
+            out.parsed += '<code>{}</code>'.format(parse_inline_desc(state, i))
+
+        elif i.tag == 'emphasis':
+            out.parsed += '<em>{}</em>'.format(parse_inline_desc(state, i))
+
+        elif i.tag == 'bold':
+            out.parsed += '<strong>{}</strong>'.format(parse_inline_desc(state, i))
+
+        elif i.tag == 'ref':
+            out.parsed += parse_ref(state, i)
+
+        elif i.tag == 'ulink':
+            out.parsed += '<a href="{}">{}</a>'.format(html.escape(i.attrib['url']), add_wbr(parse_inline_desc(state, i)))
+
+        # WHAT THE HELL WHY IS THIS NOT AN XML ENTITY
+        elif i.tag == 'ndash': out.parsed += '&ndash;'
+        elif i.tag == 'mdash': out.parsed += '&mdash;'
+
+        # Something new :O
+        else: # pragma: no cover
+            logging.warning("Ignoring <{}> in desc".format(i.tag))
+
+        # Besides putting notes and blockquotes and shit inside paragraphs,
+        # Doxygen also doesn't attempt to open a new <para> for the ACTUAL NEW
+        # PARAGRAPH after they end. So I do it myself and give a hint to the
+        # caller that they should close the <p> again.
+        if element.tag == 'para' and not out.write_close_tag and i.tail and i.tail.strip():
+            out.parsed += '<p>'
+            out.write_close_tag = True
+
+        if i.tail:
+            out.parsed += html.escape(i.tail.strip() if trim else i.tail)
+
+    return out
+
+def parse_desc(state: State, element: ET.Element) -> str:
+    if element is None: return ''
+
+    # Verify that we didn't ignore any important info by accident
+    parsed = parse_desc_internal(state, element)
+    assert not parsed.templates and not parsed.params and not parsed.return_value
+    assert not parsed.section # might be problematic
+    return parsed.parsed
+
+def parse_var_desc(state: State, element: ET.Element) -> str:
+    # Verify that we didn't ignore any important info by accident
+    parsed = parse_desc_internal(state, element.find('detaileddescription'))
+    parsed.parsed += parse_desc(state, element.find('inbodydescription'))
+    assert not parsed.templates and not parsed.params and not parsed.return_value
+    assert not parsed.section # might be problematic
+    return parsed.parsed
+
+def parse_toplevel_desc(state: State, element: ET.Element):
+    # Verify that we didn't ignore any important info by accident
+    parsed = parse_desc_internal(state, element)
+    assert not parsed.return_value
+    if parsed.params:
+        logging.warning("Use @tparam instead of @param for documenting class templates, @param is ignored")
+    return (parsed.parsed, parsed.templates, parsed.section[2] if parsed.section else '')
+
+def parse_typedef_desc(state: State, element: ET.Element):
+    # Verify that we didn't ignore any important info by accident
+    parsed = parse_desc_internal(state, element.find('detaileddescription'))
+    parsed.parsed += parse_desc(state, element.find('inbodydescription'))
+    assert not parsed.params and not parsed.return_value
+    assert not parsed.section # might be problematic
+    return (parsed.parsed, parsed.templates)
+
+def parse_func_desc(state: State, element: ET.Element):
+    # Verify that we didn't ignore any important info by accident
+    parsed = parse_desc_internal(state, element.find('detaileddescription'))
+    parsed.parsed += parse_desc(state, element.find('inbodydescription'))
+    assert not parsed.section # might be problematic
+    return (parsed.parsed, parsed.templates, parsed.params, parsed.return_value)
+
+def parse_define_desc(state: State, element: ET.Element):
+    # Verify that we didn't ignore any important info by accident
+    parsed = parse_desc_internal(state, element.find('detaileddescription'))
+    parsed.parsed += parse_desc(state, element.find('inbodydescription'))
+    assert not parsed.templates
+    assert not parsed.section # might be problematic
+    return (parsed.parsed, parsed.params, parsed.return_value)
+
+def parse_inline_desc(state: State, element: ET.Element) -> str:
+    if element is None: return ''
+
+    # Verify that we didn't ignore any important info by accident
+    parsed = parse_desc_internal(state, element)
+    assert not parsed.templates and not parsed.params and not parsed.return_value
+    assert not parsed.section
+    return parsed.parsed
+
+def parse_enum(state: State, element: ET.Element):
+    assert element.tag == 'memberdef' and element.attrib['kind'] == 'enum'
+
+    enum = Empty()
+    enum.id = extract_id(element)
+    enum.type = parse_type(state, element.find('type'))
+    enum.name = element.find('name').text
+    if enum.name.startswith('@'): enum.name = '(anonymous)'
+    enum.brief = parse_desc(state, element.find('briefdescription'))
+    enum.description = parse_desc(state, element.find('detaileddescription')) + parse_desc(state, element.find('inbodydescription'))
+    enum.is_protected = element.attrib['prot'] == 'protected'
+    enum.is_strong = False
+    if 'strong' in element.attrib:
+        enum.is_strong = element.attrib['strong'] == 'yes'
+    enum.values = []
+
+    enum.has_value_details = False
+    enumvalue: ET.Element
+    for enumvalue in element.findall('enumvalue'):
+        value = Empty()
+        value.id = extract_id(enumvalue)
+        value.name = enumvalue.find('name').text
+        # There can be an implicit initializer for enum value
+        value.initializer = html.escape(enumvalue.findtext('initializer', ''))
+        if ''.join(enumvalue.find('briefdescription').itertext()).strip():
+            logging.warning("Ignoring brief description of enum value {}::{}".format(enum.name, value.name))
+        value.description = parse_desc(state, enumvalue.find('detaileddescription'))
+        if value.description: enum.has_value_details = True
+        enum.values += [value]
+
+    enum.has_details = enum.description or enum.has_value_details
+    return enum if enum.brief or enum.has_details or enum.has_value_details else None
+
+def parse_template_params(state: State, element: ET.Element, description):
+    if element is None: return False, None
+    assert element.tag == 'templateparamlist'
+
+    has_template_details = False
+    templates = []
+    i: ET.Element
+    for i in element:
+        assert i.tag == 'param'
+
+        template = Empty()
+        template.type = parse_type(state, i.find('type'))
+        declname = i.find('declname')
+        if declname is not None:
+            # declname or decltype?!
+            template.name = declname.text
+        else:
+            # Doxygen sometimes puts both in type, extract that
+            parts = template.type.partition(' ')
+            template.type = parts[0]
+            template.name = parts[2]
+        default = i.find('defval')
+        template.default = parse_type(state, default) if default is not None else ''
+        if template.name in description:
+            template.description = description[template.name]
+            del description[template.name]
+            has_template_details = True
+        else:
+            template.description = ''
+        templates += [template]
+
+    # Some param description got unused
+    if description:
+        logging.warning("Template parameter description doesn't match parameter names: {}".format(repr(description)))
+
+    return has_template_details, templates
+
+def parse_typedef(state: State, element: ET.Element):
+    assert element.tag == 'memberdef' and element.attrib['kind'] == 'typedef'
+
+    typedef = Empty()
+    typedef.id = extract_id(element)
+    typedef.is_using = element.findtext('definition', '').startswith('using')
+    typedef.type = parse_type(state, element.find('type'))
+    typedef.args = parse_type(state, element.find('argsstring'))
+    typedef.name = element.find('name').text
+    typedef.brief = parse_desc(state, element.find('briefdescription'))
+    typedef.description, templates = parse_typedef_desc(state, element)
+    typedef.is_protected = element.attrib['prot'] == 'protected'
+    typedef.has_template_details, typedef.templates = parse_template_params(state, element.find('templateparamlist'), templates)
+
+    typedef.has_details = typedef.description or typedef.has_template_details
+    return typedef if typedef.brief or typedef.has_details else None
+
+def parse_func(state: State, element: ET.Element):
+    assert element.tag == 'memberdef' and element.attrib['kind'] == 'function'
+
+    func = Empty()
+    func.id = extract_id(element)
+    func.type = parse_type(state, element.find('type'))
+    func.name = fix_type_spacing(html.escape(element.find('name').text))
+    func.brief = parse_desc(state, element.find('briefdescription'))
+    func.description, templates, params, func.return_value = parse_func_desc(state, element)
+
+    # Extract function signature to prefix, suffix and various flags. Important
+    # things affecting caller such as static or const (and rvalue overloads)
+    # are put into signature prefix/suffix, other things to various is_*
+    # properties.
+    if func.type == 'constexpr': # Constructors
+        func.type = ''
+        func.is_constexpr = True
+    elif func.type.startswith('constexpr'):
+        func.type = func.type[10:]
+        func.is_constexpr = True
+    else:
+        func.is_constexpr = False
+    func.prefix = ''
+    func.is_explicit = element.attrib['explicit'] == 'yes'
+    func.is_virtual = element.attrib['virt'] != 'non-virtual'
+    if element.attrib['static'] == 'yes':
+        func.prefix += 'static '
+    signature = element.find('argsstring').text
+    if signature.endswith(' noexcept'):
+        signature = signature[:-9]
+        func.is_noexcept = True
+    else:
+        func.is_noexcept = False
+    if signature.endswith('=default'):
+        signature = signature[:-8]
+        func.is_defaulted = True
+    else:
+        func.is_defaulted = False
+    if signature.endswith('=delete'):
+        signature = signature[:-7]
+        func.is_deleted = True
+    else:
+        func.is_deleted = False
+    if signature.endswith('=0'):
+        signature = signature[:-2]
+        func.is_pure_virtual = True
+    else:
+        func.is_pure_virtual = False
+    func.suffix = html.escape(signature[signature.rindex(')') + 1:].strip())
+    if func.suffix: func.suffix = ' ' + func.suffix
+    func.is_protected = element.attrib['prot'] == 'protected'
+    func.is_private = element.attrib['prot'] == 'private'
+
+    func.has_template_details, func.templates = parse_template_params(state, element.find('templateparamlist'), templates)
+
+    func.has_param_details = False
+    func.params = []
+    for p in element.findall('param'):
+        name = p.find('declname')
+        param = Empty()
+        param.name = name.text if name is not None else ''
+        param.type = parse_type(state, p.find('type'))
+
+        # Recombine parameter name and array information back
+        array = p.find('array')
+        if array is not None:
+            if name is not None:
+                assert param.type.endswith(')')
+                param.type = param.type[:-1] + name.text + ')' + array.text
+            else:
+                param.type += array.text
+        elif name is not None:
+            param.type += ' ' + name.text
+
+        param.default = parse_type(state, p.find('defval'))
+        if param.name in params:
+            param.description, param.direction = params[param.name]
+            del params[param.name]
+            func.has_param_details = True
+        else:
+            param.description, param.direction = '', ''
+        func.params += [param]
+
+    # Some param description got unused
+    if params: logging.warning("Function parameter description doesn't match parameter names: {}".format(repr(params)))
+
+    func.has_details = func.description or func.has_template_details or func.has_param_details or func.return_value
+    return func if func.brief or func.has_details else None
+
+def parse_var(state: State, element: ET.Element):
+    assert element.tag == 'memberdef' and element.attrib['kind'] == 'variable'
+
+    var = Empty()
+    var.id = extract_id(element)
+    var.type = parse_type(state, element.find('type'))
+    if var.type.startswith('constexpr'):
+        var.type = var.type[10:]
+        var.is_constexpr = True
+    else:
+        var.is_constexpr = False
+    var.is_static = element.attrib['static'] == 'yes'
+    var.is_protected = element.attrib['prot'] == 'protected'
+    var.is_private = element.attrib['prot'] == 'private'
+    var.name = element.find('name').text
+    var.brief = parse_desc(state, element.find('briefdescription'))
+    var.description = parse_var_desc(state, element)
+
+    var.has_details = not not var.description
+    return var if var.brief or var.has_details else None
+
+def parse_define(state: State, element: ET.Element):
+    assert element.tag == 'memberdef' and element.attrib['kind'] == 'define'
+
+    define = Empty()
+    define.id = extract_id(element)
+    define.name = element.find('name').text
+    define.brief = parse_desc(state, element.find('briefdescription'))
+    define.description, params, define.return_value = parse_define_desc(state, element)
+
+    define.has_param_details = False
+    define.params = None
+    for p in element.findall('param'):
+        if define.params is None: define.params = []
+        name = p.find('defname')
+        if name is not None:
+            if name.text in params:
+                description, _ = params[name.text]
+                del params[name.text]
+                define.has_param_details = True
+            else:
+                description = ''
+            define.params += [(name.text, description)]
+
+    # Some param description got unused
+    if params: logging.warning("Define parameter description doesn't match parameter names: {}".format(repr(params)))
+
+    define.has_details = define.description or define.return_value
+    return define if define.brief or define.has_details else None
+
+def extract_metadata(state: State, xml):
+    # index.xml will be parsed later in parse_index_xml()
+    if os.path.basename(xml) == 'index.xml': return
+
+    logging.debug("Extracting metadata from {}".format(os.path.basename(xml)))
+
+    tree = ET.parse(xml)
+    root = tree.getroot()
+
+    compounddef: ET.Element = root.find('compounddef')
+    if compounddef.attrib['kind'] not in ['namespace', 'class', 'struct', 'union', 'dir', 'file', 'page']:
+        logging.debug("No useful info in {}, skipping".format(os.path.basename(xml)))
+        return
+
+    compound = Empty()
+    compound.id  = compounddef.attrib['id']
+    compound.kind = compounddef.attrib['kind']
+    # Compound name is page filename, so we have to use title there
+    compound.name = html.escape(compounddef.find('title').text if compound.kind == 'page' else compounddef.find('compoundname').text)
+    compound.url = compound.id + '.html'
+    compound.brief = parse_desc(state, compounddef.find('briefdescription'))
+    compound.has_details = compound.brief or compounddef.find('detaileddescription')
+    compound.children = []
+    compound.parent = None # is filled in by build_tree()
+
+    if compound.kind in ['class', 'struct', 'union']:
+        # Fix type spacing
+        compound.name = fix_type_spacing(compound.name)
+
+        # Parse template list for classes
+        _, compound.templates = parse_template_params(state, compounddef.find('templateparamlist'), {})
+
+    # Files have <innerclass> and <innernamespace> but that's not what we want,
+    # so separate the children queries based on compound type
+    if compounddef.attrib['kind'] in ['namespace', 'class', 'struct', 'union']:
+        for i in compounddef.findall('innerclass'):
+            compound.children += [i.attrib['refid']]
+        for i in compounddef.findall('innernamespace'):
+            compound.children += [i.attrib['refid']]
+    elif compounddef.attrib['kind'] in ['dir', 'file']:
+        for i in compounddef.findall('innerdir'):
+            compound.children += [i.attrib['refid']]
+        for i in compounddef.findall('innerfile'):
+            compound.children += [i.attrib['refid']]
+    elif compounddef.attrib['kind'] == 'page':
+        for i in compounddef.findall('innerpage'):
+            compound.children += [i.attrib['refid']]
+
+    state.compounds[compound.id] = compound
+
+def build_tree(state: State):
+    for _, compound in state.compounds.items():
+        for child in compound.children:
+            if child in state.compounds:
+                state.compounds[child].parent = compound.id
+
+    # Strip name of parent symbols from names to get leaf names
+    for _, compound in state.compounds.items():
+        if not compound.parent or compound.kind in ['file', 'page']:
+            compound.leaf_name = compound.name
+            continue
+
+        # Strip parent namespace/class from symbol name
+        if compound.kind in ['namespace', 'struct', 'class', 'union']:
+            prefix = state.compounds[compound.parent].name + '::'
+            assert compound.name.startswith(prefix)
+            compound.leaf_name = compound.name[len(prefix):]
+
+        # Strip parent dir from dir name
+        elif compound.kind == 'dir':
+            prefix = state.compounds[compound.parent].name + '/'
+            assert compound.name.startswith(prefix)
+            compound.leaf_name = compound.name[len(prefix):]
+
+        # Other compounds are not in any index pages or breadcrumb, so leaf
+        # name not needed
+
+def parse_xml(state: State, xml: str):
+    # Reset counter for unique math formulas
+    m.math.counter = 0
+
+    logging.info("Parsing {}".format(os.path.basename(xml)))
+
+    tree = ET.parse(xml)
+    root = tree.getroot()
+    assert root.tag == 'doxygen'
+
+    compounddef: ET.Element = root[0]
+    assert compounddef.tag == 'compounddef'
+    assert len([i for i in root]) == 1
+
+    # Ignoring private structs/classes, unnamed namespaces, files and
+    # directories that have absolute location (i.e., outside of the
+    # main source tree)
+    if ((compounddef.attrib['kind'] in ['struct', 'class', 'union'] and compounddef.attrib['prot'] == 'private') or
+        (compounddef.attrib['kind'] == 'namespace' and '@' in compounddef.find('compoundname').text) or
+        (compounddef.attrib['kind'] in ['dir', 'file'] and os.path.isabs(compounddef.find('location').attrib['file']))):
+        logging.debug("only private things in {}, skipping".format(os.path.basename(xml)))
+        return None
+
+    compound = Empty()
+    compound.kind = compounddef.attrib['kind']
+    compound.id = compounddef.attrib['id']
+    # Compound name is page filename, so we have to use title there
+    compound.name = compounddef.find('title').text if compound.kind == 'page' else compounddef.find('compoundname').text
+    compound.has_template_details = False
+    compound.templates = None
+    compound.brief = parse_desc(state, compounddef.find('briefdescription'))
+    compound.description, templates, compound.sections = parse_toplevel_desc(state, compounddef.find('detaileddescription'))
+    compound.dirs = []
+    compound.files = []
+    compound.namespaces = []
+    compound.classes = []
+    compound.enums = []
+    compound.typedefs = []
+    compound.funcs = []
+    compound.vars = []
+    compound.defines = []
+    compound.public_types = []
+    compound.public_static_funcs = []
+    compound.typeless_funcs = []
+    compound.public_funcs = []
+    compound.public_static_vars = []
+    compound.public_vars = []
+    compound.protected_types = []
+    compound.protected_static_funcs = []
+    compound.protected_funcs = []
+    compound.protected_static_vars = []
+    compound.protected_vars = []
+    compound.private_funcs = []
+    compound.related = []
+    compound.groups = []
+    compound.has_enum_details = False
+    compound.has_typedef_details = False
+    compound.has_func_details = False
+    compound.has_var_details = False
+    compound.has_define_details = False
+
+    # Build breadcrumb
+    if compound.kind in ['namespace', 'struct', 'class', 'union', 'file', 'dir', 'page']:
+        # Gather parent compounds
+        path_reverse = [compound.id]
+        while path_reverse[-1] in state.compounds and state.compounds[path_reverse[-1]].parent:
+            path_reverse += [state.compounds[path_reverse[-1]].parent]
+
+        # Fill breadcrumb with leaf names and URLs
+        compound.breadcrumb = []
+        for i in reversed(path_reverse):
+            compound.breadcrumb += [(state.compounds[i].leaf_name, state.compounds[i].url)]
+
+    if compound.kind == 'page':
+        # Drop TOC for pages, if not requested
+        if compounddef.find('tableofcontents') is None:
+            compound.sections = []
+
+        if compound.brief:
+            # Remove duplicated brief in pages. Doxygen sometimes adds a period
+            # at the end, try without it also.
+            # TODO: create follow-up to https://github.com/doxygen/doxygen/pull/624
+            wrapped_brief = '<p>{}</p>'.format(compound.brief)
+            if compound.description.startswith(wrapped_brief):
+                compound.description = compound.description[len(wrapped_brief):]
+            elif compound.brief[-1] == '.':
+                wrapped_brief = '<p>{}</p>'.format(compound.brief[:-1])
+                if compound.description.startswith(wrapped_brief):
+                    compound.description = compound.description[len(wrapped_brief):]
+
+    compounddef_child: ET.Element
+    for compounddef_child in compounddef:
+        # Directory / file
+        if compounddef_child.tag in ['innerdir', 'innerfile']:
+            id = compounddef_child.attrib['refid']
+
+            # Add it only if we have documentation for it
+            if id in state.compounds and state.compounds[id].has_details:
+                file = state.compounds[id]
+
+                f = Empty()
+                f.url = file.url
+                f.name = file.leaf_name
+                f.brief = file.brief
+
+                if compounddef_child.tag == 'innerdir':
+                    compound.dirs += [f]
+                else:
+                    assert compounddef_child.tag == 'innerfile'
+                    compound.files += [f]
+
+        # Namespace / class
+        elif compounddef_child.tag in ['innernamespace', 'innerclass']:
+            id = compounddef_child.attrib['refid']
+
+            # Add it only if it's not private and we have documentation for it
+            if (compounddef_child.tag != 'innerclass' or not compounddef_child.attrib['prot'] == 'private') and id in state.compounds and state.compounds[id].has_details:
+                symbol = state.compounds[id]
+
+                if compounddef_child.tag == 'innernamespace':
+                    namespace = Empty()
+                    namespace.url = symbol.url
+                    namespace.name = symbol.leaf_name if compound.kind == 'namespace' else symbol.name
+                    namespace.brief = symbol.brief
+                    compound.namespaces += [namespace]
+
+                else:
+                    assert compounddef_child.tag == 'innerclass'
+
+                    class_ = Empty()
+                    class_.kind = symbol.kind
+                    class_.url = symbol.url
+                    class_.name = symbol.leaf_name if compound.kind in ['namespace', 'class', 'struct', 'union'] else symbol.name
+                    class_.brief = symbol.brief
+                    class_.templates = symbol.templates
+
+                    # Put classes into the public/protected section for
+                    # inner classes
+                    if compound.kind in ['class', 'struct', 'union']:
+                        if compounddef_child.attrib['prot'] == 'public':
+                            compound.public_types += [('class', class_)]
+                        else:
+                            assert compounddef_child.attrib['prot'] == 'protected'
+                            compound.protected_types += [('class', class_)]
+                    else:
+                        assert compound.kind in ['namespace', 'file']
+                        compound.classes += [class_]
+
+        # Other, grouped in sections
+        elif compounddef_child.tag == 'sectiondef':
+            if compounddef_child.attrib['kind'] == 'enum':
+                for memberdef in compounddef_child:
+                    enum = parse_enum(state, memberdef)
+                    if enum:
+                        compound.enums += [enum]
+                        if enum.has_details: compound.has_enum_details = True
+
+            elif compounddef_child.attrib['kind'] == 'typedef':
+                for memberdef in compounddef_child:
+                    typedef = parse_typedef(state, memberdef)
+                    if typedef:
+                        compound.typedefs += [typedef]
+                        if typedef.has_details: compound.has_typedef_details = True
+
+            elif compounddef_child.attrib['kind'] == 'func':
+                for memberdef in compounddef_child:
+                    func = parse_func(state, memberdef)
+                    if func:
+                        compound.funcs += [func]
+                        if func.has_details: compound.has_func_details = True
+
+            elif compounddef_child.attrib['kind'] == 'var':
+                for memberdef in compounddef_child:
+                    var = parse_var(state, memberdef)
+                    if var:
+                        compound.vars += [var]
+                        if var.has_details: compound.has_var_details = True
+
+            elif compounddef_child.attrib['kind'] == 'define':
+                for memberdef in compounddef_child:
+                    define = parse_define(state, memberdef)
+                    if define:
+                        compound.defines += [define]
+                        if define.has_details: compound.has_define_details = True
+
+            elif compounddef_child.attrib['kind'] == 'public-type':
+                for memberdef in compounddef_child:
+                    if memberdef.attrib['kind'] == 'enum':
+                        member = parse_enum(state, memberdef)
+                        if member and member.has_details: compound.has_enum_details = True
+                    else:
+                        assert memberdef.attrib['kind'] == 'typedef'
+                        member = parse_typedef(state, memberdef)
+                        if member and member.has_details: compound.has_typedef_details = True
+
+                    if member: compound.public_types += [(memberdef.attrib['kind'], member)]
+
+            elif compounddef_child.attrib['kind'] == 'public-static-func':
+                for memberdef in compounddef_child:
+                    func = parse_func(state, memberdef)
+                    if func:
+                        compound.public_static_funcs += [func]
+                        if func.has_details: compound.has_func_details = True
+
+            elif compounddef_child.attrib['kind'] == 'public-func':
+                for memberdef in compounddef_child:
+                    func = parse_func(state, memberdef)
+                    if func:
+                        if func.type:
+                            compound.public_funcs += [func]
+                        else:
+                            compound.typeless_funcs += [func]
+                        if func.has_details: compound.has_func_details = True
+
+            elif compounddef_child.attrib['kind'] == 'public-static-attrib':
+                for memberdef in compounddef_child:
+                    var = parse_var(state, memberdef)
+                    if var:
+                        compound.public_static_vars += [var]
+                        if var.has_details: compound.has_var_details = True
+
+            elif compounddef_child.attrib['kind'] == 'public-attrib':
+                for memberdef in compounddef_child:
+                    var = parse_var(state, memberdef)
+                    if var:
+                        compound.public_vars += [var]
+                        if var.has_details: compound.has_var_details = True
+
+            elif compounddef_child.attrib['kind'] == 'protected-type':
+                for memberdef in compounddef_child:
+                    if memberdef.attrib['kind'] == 'enum':
+                        member = parse_enum(state, memberdef)
+                        if member and member.has_details: compound.has_enum_details = True
+                    else:
+                        assert memberdef.attrib['kind'] == 'typedef'
+                        member = parse_typedef(state, memberdef)
+                        if member and member.has_details: compound.has_typedef_details = True
+
+                    if member: compound.protected_types += [(memberdef.attrib['kind'], member)]
+
+            elif compounddef_child.attrib['kind'] == 'protected-static-func':
+                for memberdef in compounddef_child:
+                    func = parse_func(state, memberdef)
+                    if func:
+                        compound.protected_static_funcs += [func]
+                        if func.has_details: compound.has_func_details = True
+
+            elif compounddef_child.attrib['kind'] == 'protected-func':
+                for memberdef in compounddef_child:
+                    func = parse_func(state, memberdef)
+                    if func:
+                        if func.type:
+                            compound.protected_funcs += [func]
+                        else:
+                            compound.typeless_funcs += [func]
+                        if func.has_details: compound.has_func_details = True
+
+            elif compounddef_child.attrib['kind'] == 'protected-static-attrib':
+                for memberdef in compounddef_child:
+                    var = parse_var(state, memberdef)
+                    if var:
+                        compound.protected_static_vars += [var]
+                        if var.has_details: compound.has_var_details = True
+
+            elif compounddef_child.attrib['kind'] == 'protected-attrib':
+                for memberdef in compounddef_child:
+                    var = parse_var(state, memberdef)
+                    if var:
+                        compound.protected_vars += [var]
+                        if var.has_details: compound.has_var_details = True
+
+            elif compounddef_child.attrib['kind'] == 'private-func':
+                # Gather only private functions that are virtual and
+                # documented
+                for memberdef in compounddef_child:
+                    if memberdef.attrib['virt'] == 'non-virtual' or (not memberdef.find('briefdescription').text and not memberdef.find('detaileddescription').text):
+                        assert True # only because coverage.py can't handle continue :/
+                        continue # pragma: no cover
+
+                    func = parse_func(state, memberdef)
+                    if func:
+                        compound.private_funcs += [func]
+                        if func.has_details: compound.has_func_details = True
+
+            elif compounddef_child.attrib['kind'] == 'related':
+                for memberdef in compounddef_child:
+                    if memberdef.attrib['kind'] == 'enum':
+                        enum = parse_enum(state, memberdef)
+                        if enum:
+                            compound.related += [('enum', enum)]
+                            if enum.has_details: compound.has_enum_details = True
+                    elif memberdef.attrib['kind'] == 'typedef':
+                        typedef = parse_typedef(state, memberdef)
+                        if typedef:
+                            compound.related += [('typedef', typedef)]
+                            if typedef.has_details: compound.has_typedef_details = True
+                    elif memberdef.attrib['kind'] == 'function':
+                        func = parse_func(state, memberdef)
+                        if func:
+                            compound.related += [('func', func)]
+                            if func.has_details: compound.has_func_details = True
+                    elif memberdef.attrib['kind'] == 'variable':
+                        var = parse_var(state, memberdef)
+                        if var:
+                            compound.related += [('var', var)]
+                            if var.has_details: compound.has_var_details = True
+                    elif memberdef.attrib['kind'] == 'define':
+                        define = parse_define(state, memberdef)
+                        if define:
+                            compound.related += [('define', define)]
+                            if define.has_details: compound.has_define_details = True
+                    else: # pragma: no cover
+                        logging.warning("unknown related <memberdef> kind {}".format(memberdef.attrib['kind']))
+
+            elif compounddef_child.attrib['kind'] == 'user-defined':
+                list = []
+
+                memberdef: ET.Element
+                for memberdef in compounddef_child.findall('memberdef'):
+                    if memberdef.attrib['kind'] == 'enum':
+                        enum = parse_enum(state, memberdef)
+                        if enum:
+                            list += [('enum', enum)]
+                            if enum.has_details: compound.has_enum_details = True
+                    elif memberdef.attrib['kind'] == 'typedef':
+                        typedef = parse_typedef(state, memberdef)
+                        if typedef:
+                            list += [('typedef', typedef)]
+                            if typedef.has_details: compound.has_typedef_details = True
+                    elif memberdef.attrib['kind'] == 'function':
+                        func = parse_func(state, memberdef)
+                        if func:
+                            list += [('func', func)]
+                            if func.has_details: compound.has_func_details = True
+                    elif memberdef.attrib['kind'] == 'variable':
+                        var = parse_var(state, memberdef)
+                        if var:
+                            list += [('var', var)]
+                            if var.has_details: compound.has_var_details = True
+                    elif memberdef.attrib['kind'] == 'define':
+                        define = parse_define(state, memberdef)
+                        if define:
+                            list += [('define', define)]
+                            if define.has_details: compound.has_define_details = True
+                    else: # pragma: no cover
+                        logging.warning("unknown user-defined <memberdef> kind {}".format(memberdef.attrib['kind']))
+
+                if list:
+                    group = Empty()
+                    group.name = compounddef_child.find('header').text
+                    group.id = slugify(group.name)
+                    group.description = parse_desc(state, compounddef_child.find('description'))
+                    group.members = list
+                    compound.groups += [group]
+
+            elif compounddef_child.attrib['kind'] not in ['private-type',
+                                                          'private-static-func',
+                                                          'private-static-attrib',
+                                                          'private-attrib',
+                                                          'friend']: # pragma: no cover
+                logging.warning("unknown <sectiondef> kind {}".format(compounddef_child.attrib['kind']))
+
+        elif compounddef_child.tag == 'templateparamlist':
+            compound.has_template_details, compound.templates = parse_template_params(state, compounddef_child, templates)
+
+        elif (compounddef_child.tag not in ['compoundname',
+                                            'briefdescription',
+                                            'detaileddescription',
+                                            'location',
+                                            'includes',
+                                            'includedby',
+                                            'incdepgraph',
+                                            'invincdepgraph',
+                                            'inheritancegraph',
+                                            'collaborationgraph',
+                                            'listofallmembers',
+                                            'tableofcontents'] and
+            not (compounddef.attrib['kind'] == 'page' and compounddef_child.tag == 'title')): # pragma: no cover
+            logging.warning("Ignoring <{}> in <compounddef>".format(compounddef_child.tag))
+
+    # Decide about the prefix (it may contain template parameters, so we
+    # had to wait until everything is parsed)
+    if compound.kind in ['namespace', 'struct', 'class', 'union']:
+        # The name itself can contain templates (e.g. a specialized template),
+        # so properly escape and fix spacing there as well
+        compound.prefix_wbr = add_wbr(fix_type_spacing(html.escape(compound.name)))
+
+        if compound.templates:
+            compound.prefix_wbr += '&lt;'
+            for index, t in enumerate(compound.templates):
+                if index != 0: compound.prefix_wbr += ', '
+                if t.name:
+                    compound.prefix_wbr += t.name
+                else:
+                    compound.prefix_wbr += '_{}'.format(index+1)
+            compound.prefix_wbr += '&gt;'
+
+        compound.prefix_wbr += '::<wbr/>'
+
+    parsed = Empty()
+    parsed.version = root.attrib['version']
+
+    # Decide about save as filename. Pages mess this up, because index page has
+    # "indexpage" as a name so we have to use the compound name instead
+    parsed.save_as = (compounddef.find('compoundname').text if compound.kind == 'page' else compound.id) + '.html'
+
+    parsed.compound = compound
+    return parsed
+
+def parse_index_xml(state: State, xml):
+    logging.info("Parsing {}".format(os.path.basename(xml)))
+
+    tree = ET.parse(xml)
+    root = tree.getroot()
+    assert root.tag == 'doxygenindex'
+
+    # Top-level symbols, files and pages. Separated to nestable (namespaces,
+    # dirs) and non-nestable so we have these listed first.
+    top_level_namespaces = []
+    top_level_classes = []
+    top_level_dirs = []
+    top_level_files = []
+    top_level_pages = []
+
+    # Non-top-level symbols, files and pages, assigned later
+    orphans_nestable = {}
+    orphan_pages = {}
+    orphans = {}
+
+    # Map of all entries
+    entries = {}
+
+    i: ET.Element
+    for i in root:
+        assert i.tag == 'compound'
+
+        entry = Empty()
+        entry.id = i.attrib['refid']
+
+        # Ignore unknown / undocumented compounds
+        if entry.id not in state.compounds or not state.compounds[entry.id].has_details:
+            continue
+
+        compound = state.compounds[entry.id]
+        entry.kind = compound.kind
+        entry.name = compound.leaf_name
+        entry.url = compound.url
+        entry.brief = compound.brief
+        entry.children = []
+        entry.has_nestable_children = False
+
+        # If a top-level thing, put it directly into the list
+        if not compound.parent:
+            if compound.kind == 'namespace':
+                top_level_namespaces += [entry]
+            elif compound.kind in ['class', 'struct', 'union']:
+                top_level_classes += [entry]
+            elif compound.kind == 'dir':
+                top_level_dirs += [entry]
+            elif compound.kind == 'file':
+                top_level_files += [entry]
+            else:
+                assert compound.kind == 'page'
+                # Ignore index page in page listing
+                if entry.id == 'indexpage': continue
+                top_level_pages += [entry]
+
+        # Otherwise put it into orphan map
+        else:
+            if compound.kind in ['namespace', 'dir']:
+                if not compound.parent in orphans_nestable:
+                    orphans_nestable[compound.parent] = []
+                orphans_nestable[compound.parent] += [entry]
+            elif compound.kind == 'page':
+                if not compound.parent in orphan_pages:
+                    orphan_pages[compound.parent] = {}
+                orphan_pages[compound.parent][entry.id] = entry
+            else:
+                assert compound.kind in ['class', 'struct', 'union', 'file']
+                if not compound.parent in orphans:
+                    orphans[compound.parent] = []
+                orphans[compound.parent] += [entry]
+
+        # Put it also in the global map so we can reference it later when
+        # getting rid of orphans
+        entries[entry.id] = entry
+
+    # Structure containing top-level symbols, files and pages, nestable items
+    # (namespaces, directories) first
+    parsed = Empty()
+    parsed.version = root.attrib['version']
+    parsed.index = Empty()
+    parsed.index.symbols = top_level_namespaces + top_level_classes
+    parsed.index.files = top_level_dirs + top_level_files
+    parsed.index.pages = top_level_pages
+
+    # Assign nestable children to their parents first, if the parents exist
+    for parent, children in orphans_nestable.items():
+        if not parent in entries: continue
+        entries[parent].has_nestable_children = True
+        entries[parent].children = children
+
+    # Add child pages to their parent pages. The user-defined order matters, so
+    # preserve it.
+    for parent, children in orphan_pages.items():
+        assert parent in entries
+        compound = state.compounds[parent]
+        for child in compound.children:
+            entries[parent].children += [children[child]]
+
+    # Add children to their parents, if the parents exist
+    for parent, children in orphans.items():
+        if parent in entries: entries[parent].children += children
+
+    return parsed
+
+def parse_doxyfile(state: State, doxyfile):
+    logging.info("Parsing configuration from {}".format(doxyfile))
+
+    comment_re = re.compile(r"""^\s*(#.*)?$""")
+    variable_re = re.compile(r"""^\s*(?P<key>[A-Z0-9_@]+)\s*=\s*(?P<quote>"?)(?P<value>.*)(?P=quote)\s*(?P<backslash>\\?)$""")
+    variable_continuation_re = re.compile(r"""^\s*(?P<key>[A-Z_]+)\s*\+=\s*(?P<quote>"?)(?P<value>.*)(?P=quote)\s*(?P<backslash>\\?)$""")
+    continuation_re = re.compile(r"""^\s*(?P<quote>['"]?)(?P<value>.*)(?P=quote)\s*(?P<backslash>\\?)$""")
+
+    # Defaults so we don't fail with minimal Doxyfiles and also that the
+    # user-provided Doxygen can append to them. They are later converted to
+    # string or kept as a list based on type, so all have to be a list of
+    # strings now.
+    config = {
+        'PROJECT_NAME': ['My Project'],
+        'OUTPUT_DIRECTORY': [''],
+        'XML_OUTPUT': ['xml'],
+        'HTML_OUTPUT': ['html'],
+        'IMAGE_PATH': [],
+        'HTML_EXTRA_STYLESHEET': [
+            'https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600',
+            '../css/m-dark+doxygen.compiled.css'],
+        'HTML_EXTRA_FILES': [],
+
+        'M_CLASS_TREE_EXPAND_LEVELS': ['1'],
+        'M_FILE_TREE_EXPAND_LEVELS': ['1'],
+        'M_EXPAND_INNER_TYPES': ['0'],
+        'M_THEME_COLOR': ['#22272e']
+    }
+
+    def parse_value(var):
+        if var.group('quote') == '"':
+            out = [var.group('value')]
+        else:
+            out = var.group('value').split()
+
+        if var.group('quote') and var.group('backslash') == '\\':
+            backslash = True
+        elif out and out[-1].endswith('\\'):
+            backslash = True
+            out[-1] = out[-1][:-1].rstrip()
+        else:
+            backslash = False
+
+        return [i.replace('\\"', '"') for i in out], backslash
+
+    with open(doxyfile) as f:
+        continued_line = None
+        for line in f:
+            line = line.strip()
+
+            # Ignore comments and empty lines. Comment also stops line
+            # continuation
+            if comment_re.match(line):
+                continued_line = None
+                continue
+
+            # Line continuation from before, append the line contents to it
+            if continued_line:
+                var = continuation_re.match(line)
+                value, backslash = parse_value(var)
+                config[continued_line] += value
+                if not backslash: continued_line = None
+                continue
+
+            # Variable
+            var = variable_re.match(line)
+            if var:
+                key = var.group('key')
+                value, backslash = parse_value(var)
+
+                # Another file included, parse it
+                if key == '@INCLUDE':
+                    parse_doxyfile(state, os.path.join(os.path.dirname(doxyfile), ' '.join(value)))
+                    assert not backslash
+                else:
+                    config[key] = value
+
+                if backslash: continued_line = key
+                continue
+
+            # Variable, adding to existing
+            var = variable_continuation_re.match(line)
+            if var:
+                key = var.group('key')
+                if not key in config: config[key] = []
+                value, backslash = parse_value(var)
+                config[key] += value
+                if backslash: continued_line = key
+
+                # only because coverage.py can't handle continue
+                continue # pragma: no cover
+
+            logging.warning("Umatchable line in Doxyfile: {}".format(line)) # pragma: no cover
+
+    # String values that we want
+    for i in ['PROJECT_NAME',
+              'PROJECT_BRIEF',
+              'OUTPUT_DIRECTORY',
+              'HTML_OUTPUT',
+              'XML_OUTPUT',
+              'M_PAGE_HEADER',
+              'M_THEME_COLOR']:
+        if i in config: state.doxyfile[i] = ' '.join(config[i])
+
+    # Int values that we want
+    for i in ['M_CLASS_TREE_EXPAND_LEVELS',
+              'M_FILE_TREE_EXPAND_LEVELS',
+              'M_EXPAND_INNER_TYPES']:
+        if i in config: state.doxyfile[i] = int(' '.join(config[i]))
+
+    # List values that we want. Drop empty lines.
+    for i in ['TAGFILES',
+              'IMAGE_PATH',
+              'HTML_EXTRA_STYLESHEET',
+              'HTML_EXTRA_FILES']:
+        if i in config:
+            state.doxyfile[i] = [line for line in config[i] if line]
+
+default_index_pages = ['pages', 'files', 'namespaces', 'annotated']
+default_wildcard = '*.xml'
+default_templates = 'templates/'
+
+def run(doxyfile, templates=default_templates, wildcard=default_wildcard, index_pages=default_index_pages):
+    state = State()
+    state.basedir = os.path.dirname(doxyfile)
+
+    parse_doxyfile(state, doxyfile)
+    xml_input = os.path.join(state.basedir, state.doxyfile['OUTPUT_DIRECTORY'], state.doxyfile['XML_OUTPUT'])
+    xml_files_metadata = [os.path.join(xml_input, f) for f in glob.glob(os.path.join(xml_input, "*.xml"))]
+    xml_files = [os.path.join(xml_input, f) for f in glob.glob(os.path.join(xml_input, wildcard))]
+    html_output = os.path.join(state.basedir, state.doxyfile['OUTPUT_DIRECTORY'], state.doxyfile['HTML_OUTPUT'])
+
+    if not os.path.exists(html_output):
+        os.makedirs(html_output)
+
+    env = Environment(loader=FileSystemLoader(templates),
+                      trim_blocks=True, lstrip_blocks=True, enable_async=True)
+
+    # Filter to return file basename or the full URL, if absolute
+    def basename_or_url(path):
+        if urllib.parse.urlparse(path).netloc: return path
+        return os.path.basename(path)
+    env.filters['basename_or_url'] = basename_or_url
+
+    # Do a pre-pass and gather:
+    # - brief descriptions of all classes, namespaces, dirs and files because
+    #   the brief desc is not part of the <inner*> tag
+    # - template specifications of all classes so we can include that in the
+    #   linking pages
+    # - get URLs of namespace, classe, file docs and pages so we can link to
+    #   them from breadcrumb navigation
+    logging.info("Parsing metadata from {} files".format(len(xml_files_metadata)))
+    file: str
+    for file in xml_files_metadata:
+        extract_metadata(state, file)
+
+    build_tree(state)
+
+    for file in xml_files:
+        if os.path.basename(file) == 'index.xml':
+            parsed = parse_index_xml(state, file)
+
+            for i in index_pages:
+                file = '{}.html'.format(i)
+
+                template = env.get_template(file)
+                rendered = template.render(index=parsed.index,
+                    DOXYGEN_VERSION=parsed.version,
+                    FILENAME=file,
+                    **state.doxyfile)
+
+                output = os.path.join(html_output, file)
+                with open(output, 'w') as f:
+                    f.write(rendered)
+        else:
+            parsed = parse_xml(state, file)
+            if not parsed: continue
+
+            template = env.get_template('{}.html'.format(parsed.compound.kind))
+            rendered = template.render(compound=parsed.compound,
+                DOXYGEN_VERSION=parsed.version,
+                FILENAME=parsed.save_as,
+                **state.doxyfile)
+
+            output = os.path.join(html_output, parsed.save_as)
+            with open(output, 'w') as f:
+                f.write(rendered)
+
+    # Copy all referenced files, skip absolute URLs
+    for i in state.images + state.doxyfile['HTML_EXTRA_STYLESHEET'] + state.doxyfile['HTML_EXTRA_FILES']:
+        if urllib.parse.urlparse(i).netloc: continue
+        logging.info("copying {} to output".format(i))
+        shutil.copy(i, os.path.join(html_output, os.path.basename(i)))
+
+if __name__ == '__main__': # pragma: no cover
+    parser = argparse.ArgumentParser()
+    parser.add_argument('doxyfile', help="where the Doxyfile is")
+    parser.add_argument('--templates', help="template directory", default=default_templates)
+    parser.add_argument('--wildcard', help="only process files matching the wildcard", default=default_wildcard)
+    parser.add_argument('--index-pages', nargs='+', help="index page templates", default=default_index_pages)
+    parser.add_argument('--no-doxygen', help="don't run Doxygen before", action='store_true')
+    parser.add_argument('--debug', help="verbose debug output", action='store_true')
+    args = parser.parse_args()
+
+    if args.debug:
+        logging.basicConfig(level=logging.DEBUG)
+    else:
+        logging.basicConfig(level=logging.INFO)
+
+    if not args.no_doxygen:
+        subprocess.run(["doxygen", args.doxyfile], cwd=os.path.dirname(args.doxyfile))
+
+    run(args.doxyfile, args.templates, args.wildcard, args.index_pages)
diff --git a/doxygen/templates/.kateconfig b/doxygen/templates/.kateconfig
new file mode 100644 (file)
index 0000000..b46a48b
--- /dev/null
@@ -0,0 +1 @@
+// kate: indent-width 2;
diff --git a/doxygen/templates/annotated.html b/doxygen/templates/annotated.html
new file mode 100644 (file)
index 0000000..6b2b9bd
--- /dev/null
@@ -0,0 +1,21 @@
+{% set navbar_current = 'annotated' %}
+{% extends 'base-index.html' %}
+
+{% block main %}
+        <h1>Classes</h2>
+        <ul class="m-dox">
+          {% for i in index.symbols recursive %}
+          {% if i.children %}
+          <li class="m-dox-collapsible{% if loop.depth > M_CLASS_TREE_EXPAND_LEVELS or (i.kind != 'namespace' and M_EXPAND_INNER_TYPES) %} collapsed{% endif %}">
+            <a href="#" onclick="return toggle(this)">{{ i.kind }}</a> <a href="{{ i.url }}" class="m-dox">{{ i.name }}</a> <span class="m-dox">{{ i.brief }}</span>
+            <ul class="m-dox">
+{{ loop(i.children)|indent(4, true) }}
+            </ul>
+          </li>
+          {% else %}
+          <li>{{ i.kind }} <a href="{{ i.url }}" class="m-dox">{{ i.name }}</a> <span class="m-dox">{{ i.brief }}</span></li>
+          {% endif %}
+          {% endfor %}
+        </ul>
+{{ super() -}}
+{% endblock %}
diff --git a/doxygen/templates/base-class-reference.html b/doxygen/templates/base-class-reference.html
new file mode 100644 (file)
index 0000000..7931e53
--- /dev/null
@@ -0,0 +1,436 @@
+{% set navbar_current = 'annotated' %}
+{% extends 'base.html' %}
+
+{% macro entry_class(class) %}{% include 'entry-class.html' %}{% endmacro %}
+{% macro entry_typedef(typedef, mark_nonpublic=False) %}{% include 'entry-typedef.html' %}{% endmacro %}
+{% macro entry_enum(enum, mark_nonpublic=False) %}{% include 'entry-enum.html' %}{% endmacro %}
+{% macro entry_func(func, mark_nonpublic=False) %}{% include 'entry-func.html' %}{% endmacro %}
+{% macro entry_var(var, mark_nonpublic=False) %}{% include 'entry-var.html' %}{% endmacro %}
+{% macro entry_define(define) %}{% include 'entry-define.html' %}{% endmacro %}
+
+{% macro details_typedef(typedef, prefix) %}{% include 'details-typedef.html' %}{% endmacro %}
+{% macro details_enum(enum, prefix) %}{% include 'details-enum.html' %}{% endmacro %}
+{% macro details_func(func, prefix) %}{% include 'details-func.html' %}{% endmacro %}
+{% macro details_var(var, prefix) %}{% include 'details-var.html' %}{% endmacro %}
+{% macro details_define(define) %}{% include 'details-define.html' %}{% endmacro %}
+
+{% block title %}{% set j = joiner('::') %}{% for name, _ in compound.breadcrumb %}{{ j() }}{{ name }}{% endfor %} {{ compound.kind }} | {{ super() }}{% endblock %}
+
+{% block main %}
+        <h1>
+          {% if compound.templates != None %}
+          {% set j = joiner(', ') %}
+          <div class="m-dox-template">template&lt;{% for t in compound.templates %}{{ j() }}{{ t.type }}{% if t.name %} {{ t.name }}{% endif %}{% if t.default %} = {{ t.default }}{% endif%}{% endfor %}&gt;</div>
+          {% endif %}
+          {%+ for name, target in compound.breadcrumb[:-1] %}<span class="m-breadcrumb"><a href="{{ target }}">{{ name }}</a>::</span>{% endfor %}{{ compound.breadcrumb[-1][0] }} <span class="m-thin">{{ compound.kind }}</span>
+        </h1>
+        {% if compound.brief %}
+        <p>{{ compound.brief }}</p>
+        {% endif %}
+        {% if compound.has_template_details %}
+        <table class="m-table m-fullwidth m-flat">
+          <thead>
+            <tr><th colspan="2">Template parameters</th></tr>
+          </thead>
+          <tbody>
+            {% for template in compound.templates|selectattr('name') %}
+            <tr>
+              <td{% if loop.index == 1 %} style="width: 1%"{% endif %}>{{ template.name }}</td>
+              <td>{{ template.description }}</td>
+            </tr>
+            {% endfor %}
+          </tbody>
+        </table>
+        {% endif %}
+        {% if compound.sections or compound.public_types or compound.public_static_funcs or compound.typeless_funcs or compound.public_funcs or compound.public_static_vars or compound.public_vars or compound.protected_types or compound.protected_static_funcs or compound.protected_funcs or compound.protected_static_vars or compound.protected_vars or compound.private_funcs or compound.groups or compound.relate %}
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            {% for id, name, children in compound.sections recursive %}
+            {% if children %}
+            <li>
+              <a href="#{{ id }}">{{ name }}</a>
+              <ul>
+{{ loop(children)|indent(4, true) }}
+              </ul>
+            </li>
+            {% else %}
+            <li><a href="#{{ id }}">{{ name }}</a></li>
+            {% endif %}
+            {% endfor %}
+            <li>
+              Reference
+              <ul>
+                {% if compound.public_types %}
+                <li><a href="#pub-types">Public types</a></li>
+                {% endif %}
+                {% if compound.public_static_vars %}
+                <li><a href="#pub-static-attribs">Public static variables</a></li>
+                {% endif %}
+                {% if compound.public_static_funcs %}
+                <li><a href="#pub-static-methods">Public static functions</a></li>
+                {% endif %}
+                {% if compound.typeless_funcs %}
+                <li><a href="#typeless-methods">Constructors, destructors, conversion operators</a></li>
+                {% endif %}
+                {% if compound.public_funcs %}
+                <li><a href="#pub-methods">Public functions</a></li>
+                {% endif %}
+                {% if compound.public_vars %}
+                <li><a href="#pub-attribs">Public variables</a></li>
+                {% endif %}
+                {% if compound.protected_types %}
+                <li><a href="#pro-types">Protected types</a></li>
+                {% endif %}
+                {% if compound.protected_static_funcs %}
+                <li><a href="#pro-static-methods">Protected static functions</a></li>
+                {% endif %}
+                {% if compound.protected_funcs %}
+                <li><a href="#pro-methods">Protected functions</a></li>
+                {% endif %}
+                {% if compound.protected_static_vars %}
+                <li><a href="#pro-static-attribs">Protected static variables</a></li>
+                {% endif %}
+                {% if compound.protected_vars %}
+                <li><a href="#pro-attribs">Protected variables</a></li>
+                {% endif %}
+                {% if compound.private_funcs %}
+                <li><a href="#pri-methods">Private functions</a></li>
+                {% endif %}
+                {% for group in compound.groups %}
+                <li><a href="#{{ group.id }}">{{ group.name }}</a></li>
+                {% endfor %}
+                {% if compound.related %}
+                <li><a href="#related">Related</a></li>
+                {% endif %}
+              </ul>
+            </li>
+          </ul>
+        </div>
+        {% endif %}
+        {% if compound.description %}
+{{ compound.description }}
+        {% endif %}
+        {% if compound.public_types %}
+        <section id="pub-types">
+          <h2><a href="#pub-types">Public types</a></h3>
+          <dl class="m-dox">
+            {% for kind, type in compound.public_types %}
+            {% if kind == 'class' %}
+{{ entry_class(type) }}
+            {% elif kind == 'enum' %}
+{{ entry_enum(type) }}
+            {% elif kind == 'typedef' %}
+{{ entry_typedef(type) }}
+            {% endif %}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.public_static_vars %}
+        <section id="pub-static-attribs">
+          <h2><a href="#pub-static-attribs">Public static variables</a></h3>
+          <dl class="m-dox">
+            {% for var in compound.public_static_vars %}
+{{ entry_var(var) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.public_static_funcs %}
+        <section id="pub-static-methods">
+          <h2><a href="#pub-static-methods">Public static functions</a></h3>
+          <dl class="m-dox">
+            {% for func in compound.public_static_funcs %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.typeless_funcs %}
+        <section id="typeless-methods">
+          <h2><a href="#typeless-methods">Constructors, destructors, conversion operators</a></h3>
+          <dl class="m-dox">
+            {% for func in compound.typeless_funcs %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.public_funcs %}
+        <section id="pub-methods">
+          <h2><a href="#pub-methods">Public functions</a></h3>
+          <dl class="m-dox">
+            {% for func in compound.public_funcs %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.public_vars %}
+        <section id="pub-attribs">
+          <h2><a href="#pub-attribs">Public variables</a></h3>
+          <dl class="m-dox">
+            {% for var in compound.public_vars %}
+{{ entry_var(var) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.protected_types %}
+        <section id="pro-types">
+          <h2><a href="#pro-types">Protected types</a></h3>
+          <dl class="m-dox">
+            {% for kind, type in compound.protected_types %}
+            {% if kind == 'class' %}
+{{ entry_class(type) }}
+            {% elif kind == 'enum' %}
+{{ entry_enum(type) }}
+            {% elif kind == 'typedef' %}
+{{ entry_typedef(type) }}
+            {% endif %}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.protected_static_funcs %}
+        <section id="pro-static-methods">
+          <h2><a href="#pro-static-methods">Protected static functions</a></h3>
+          <dl class="m-dox">
+            {% for func in compound.protected_static_funcs %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.protected_funcs %}
+        <section id="pro-methods">
+          <h2><a href="#pro-methods">Protected functions</a></h3>
+          <dl class="m-dox">
+            {% for func in compound.protected_funcs %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.protected_static_vars %}
+        <section id="pro-static-attribs">
+          <h2><a href="#pro-static-attribs">Protected static variables</a></h3>
+          <dl class="m-dox">
+            {% for var in compound.protected_static_vars %}
+{{ entry_var(var) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.protected_vars %}
+        <section id="pro-attribs">
+          <h2><a href="#pro-attribs">Protected variables</a></h3>
+          <dl class="m-dox">
+            {% for var in compound.protected_vars %}
+{{ entry_var(var) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.private_funcs %}
+        <section id="pri-methods">
+          <h2><a href="#pri-methods">Private functions</a></h3>
+          <dl class="m-dox">
+            {% for func in compound.private_funcs %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% for group in compound.groups %}
+        <section id="{{ group.id }}">
+          <h2><a href="#{{ group.id }}">{{ group.name }}</a></h2>
+          {% if group.description %}
+{{ group.description }}
+          {% endif %}
+          <dl class="m-dox">
+            {% for kind, member in group.members %}
+            {% if kind == 'typedef' %}
+{{ entry_typedef(member, mark_nonpublic=True) }}
+            {% elif kind == 'enum' %}
+{{ entry_enum(member, mark_nonpublic=True) }}
+            {% elif kind == 'func' %}
+{{ entry_func(member, mark_nonpublic=True) }}
+            {% elif kind == 'var' %}
+{{ entry_var(member, mark_nonpublic=True) }}
+            {% endif %}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endfor %}
+        {% if compound.related %}
+        <section id="related">
+          <h2><a href="#related">Related</a></h3>
+          <dl class="m-dox">
+            {% for kind, member in compound.related %}
+            {% if kind == 'typedef' %}
+{{ entry_typedef(member) }}
+            {% elif kind == 'enum' %}
+{{ entry_enum(member) }}
+            {% elif kind == 'func' %}
+{{ entry_func(member) }}
+            {% elif kind == 'var' %}
+{{ entry_var(member) }}
+            {% elif kind == 'define' %}
+{{ entry_define(member) }}
+            {% endif %}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.has_enum_details %}
+        <section>
+          <h2>Enum documentation</h2>
+          {% for kind, member in compound.public_types %}
+          {% if kind == 'enum' and member.has_details %}
+{{ details_enum(member, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for kind, member in compound.protected_types %}
+          {% if kind == 'enum' and member.has_details %}
+{{ details_enum(member, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for group in compound.groups %}
+          {% for kind, member in group.members %}
+          {% if kind == 'enum' and member.has_details %}
+{{ details_enum(member, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% endfor %}
+          {% for kind, member in compound.related %}
+          {% if kind == 'enum' and member.has_details %}
+{{ details_enum(member, '') }}
+          {% endif %}
+          {% endfor %}
+        </section>
+        {% endif %}
+        {% if compound.has_typedef_details %}
+        <section>
+          <h2>Typedef documentation</h2>
+          {% for kind, member in compound.public_types %}
+          {% if kind == 'typedef' and member.has_details %}
+{{ details_typedef(member, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for kind, member in compound.protected_types %}
+          {% if kind == 'typedef' and member.has_details %}
+{{ details_typedef(member, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for group in compound.groups %}
+          {% for kind, member in group.members %}
+          {% if kind == 'typedef' and member.has_details %}
+{{ details_typedef(member, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% endfor %}
+          {% for kind, member in compound.related %}
+          {% if kind == 'typedef' and member.has_details %}
+{{ details_typedef(member, '') }}
+          {% endif %}
+          {% endfor %}
+        </section>
+        {% endif %}
+        {% if compound.has_func_details %}
+        <section>
+          <h2>Function documentation</h2>
+          {% for func in compound.public_static_funcs %}
+          {% if func.has_details %}
+{{ details_func(func, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for func in compound.typeless_funcs %}
+          {% if func.has_details %}
+{{ details_func(func, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for func in compound.public_funcs %}
+          {% if func.has_details %}
+{{ details_func(func, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for func in compound.protected_static_funcs %}
+          {% if func.has_details %}
+{{ details_func(func, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for func in compound.protected_funcs %}
+          {% if func.has_details %}
+{{ details_func(func, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for func in compound.private_funcs %}
+          {% if func.has_details %}
+{{ details_func(func, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for group in compound.groups %}
+          {% for kind, member in group.members %}
+          {% if kind == 'func' and member.has_details %}
+{{ details_func(member, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% endfor %}
+          {% for kind, member in compound.related %}
+          {% if kind == 'func' and member.has_details %}
+{{ details_func(member, '') }}
+          {% endif %}
+          {% endfor %}
+        </section>
+        {% endif %}
+        {% if compound.has_var_details %}
+        <section>
+          <h2>Variable documentation</h2>
+          {% for var in compound.public_static_vars %}
+          {% if var.has_details %}
+{{ details_var(var, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for var in compound.public_vars %}
+          {% if var.has_details %}
+{{ details_var(var, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for var in compound.protected_static_vars %}
+          {% if var.has_details %}
+{{ details_var(var, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for var in compound.protected_vars %}
+          {% if var.has_details %}
+{{ details_var(var, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% for group in compound.groups %}
+          {% for kind, member in group.members %}
+          {% if kind == 'var' and member.has_details %}
+{{ details_var(member, compound.prefix_wbr) }}
+          {% endif %}
+          {% endfor %}
+          {% endfor %}
+          {% for kind, member in compound.related %}
+          {% if kind == 'var' and member.has_details %}
+{{ details_var(member, '') }}
+          {% endif %}
+          {% endfor %}
+        </section>
+        {% endif %}
+        {% if compound.has_define_details %}
+        <section>
+          <h2>Define documentation</h2>
+          {% for kind, member in compound.related %}
+          {% if kind == 'define' and member.has_details %}
+{{ details_define(member) }}
+          {% endif %}
+          {% endfor %}
+        </section>
+        {% endif %}
+{% endblock %}
+
diff --git a/doxygen/templates/base-index.html b/doxygen/templates/base-index.html
new file mode 100644 (file)
index 0000000..51f1a50
--- /dev/null
@@ -0,0 +1,19 @@
+{% extends 'base.html' %}
+
+{% block main %}
+        <script>
+        function toggle(e) {
+            e.parentElement.className = e.parentElement.className == 'm-dox-collapsible' ?
+                'm-dox-expansible' : 'm-dox-collapsible';
+            return false;
+        }
+        /* Collapse all nodes marked as such. Doing it via JS instead of directly in
+           markup so disabling it doesn't harm usability. The list is somehow
+           regenerated on every iteration and shrinks as I change the classes. It's not
+           documented anywhere and I'm not sure if this is the same across browsers, so
+           I am going backwards in that list to be sure.  */
+        var collapsed = document.getElementsByClassName("collapsed");
+        for(var i = collapsed.length - 1; i >= 0; --i)
+            collapsed[i].className = 'm-dox-expansible';
+        </script>
+{% endblock %}
diff --git a/doxygen/templates/base-reference.html b/doxygen/templates/base-reference.html
new file mode 100644 (file)
index 0000000..c3efe95
--- /dev/null
@@ -0,0 +1,286 @@
+{% extends 'base.html' %}
+
+{% set prefix = compound.prefix_wbr %}
+
+{% macro entry_dir(dir) %}{% include 'entry-dir.html' %}{% endmacro %}
+{% macro entry_file(file) %}{% include 'entry-file.html' %}{% endmacro %}
+{% macro entry_namespace(namespace) %}{% include 'entry-namespace.html' %}{% endmacro %}
+{% macro entry_class(class) %}{% include 'entry-class.html' %}{% endmacro %}
+{% macro entry_enum(enum) %}{% include 'entry-enum.html' %}{% endmacro %}
+{% macro entry_typedef(typedef) %}{% include 'entry-typedef.html' %}{% endmacro %}
+{% macro entry_func(func) %}{% include 'entry-func.html' %}{% endmacro %}
+{% macro entry_var(var) %}{% include 'entry-var.html' %}{% endmacro %}
+{% macro entry_define(define) %}{% include 'entry-define.html' %}{% endmacro %}
+
+{% macro details_enum(enum) %}{% include 'details-enum.html' %}{% endmacro %}
+{% macro details_typedef(typedef) %}{% include 'details-typedef.html' %}{% endmacro %}
+{% macro details_func(func) %}{% include 'details-func.html' %}{% endmacro %}
+{% macro details_var(var) %}{% include 'details-var.html' %}{% endmacro %}
+{% macro details_define(define) %}{% include 'details-define.html' %}{% endmacro %}
+
+{% block main %}
+{% block header %}
+{% endblock %}
+        {% if compound.brief %}
+        <p>{{ compound.brief }}</p>
+        {% endif %}
+        {% if compound.sections or compound.dirs or compound.files or compound.namespaces or compound.classes or compound.typedefs or compound.funcs or compound.vars or compound.defines or compound.groups %}
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            {% for id, name, children in compound.sections recursive %}
+            {% if children %}
+            <li>
+              <a href="#{{ id }}">{{ name }}</a>
+              <ul>
+{{ loop(children)|indent(4, true) }}
+              </ul>
+            </li>
+            {% else %}
+            <li><a href="#{{ id }}">{{ name }}</a></li>
+            {% endif %}
+            {% endfor %}
+            <li>
+              Reference
+              <ul>
+                {% if compound.dirs %}
+                <li><a href="#subdirs">Directories</a></li>
+                {% endif %}
+                {% if compound.files %}
+                <li><a href="#files">Files</a></li>
+                {% endif %}
+                {% if compound.namespaces %}
+                <li><a href="#namespaces">Namespaces</a></li>
+                {% endif %}
+                {% if compound.classes %}
+                <li><a href="#nested-classes">Classes</a></li>
+                {% endif %}
+                {% if compound.enums %}
+                <li><a href="#enum-members">Enums</a></li>
+                {% endif %}
+                {% if compound.typedefs %}
+                <li><a href="#typedef-members">Typedefs</a></li>
+                {% endif %}
+                {% if compound.funcs %}
+                <li><a href="#func-members">Functions</a></li>
+                {% endif %}
+                {% if compound.vars %}
+                <li><a href="#var-members">Variables</a></li>
+                {% endif %}
+                {% if compound.defines %}
+                <li><a href="#defines">Defines</a></li>
+                {% endif %}
+                {% for group in compound.groups %}
+                <li><a href="#{{ group.id }}">{{ group.name }}</a></li>
+                {% endfor %}
+              </ul>
+            </li>
+          </ul>
+        </div>
+        {% endif %}
+{% if compound.description %}
+{{ compound.description }}
+{% endif %}
+        {% if compound.dirs %}
+        <section id="subdirs">
+          <h2><a href="#subdirs">Directories</a></h3>
+          <dl class="m-dox">
+            {% for dir in compound.dirs %}
+{{ entry_dir(dir) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.files %}
+        <section id="files">
+          <h2><a href="#files">Files</a></h3>
+          <dl class="m-dox">
+            {% for file in compound.files %}
+{{ entry_file(file) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.namespaces %}
+        <section id="namespaces">
+          <h2><a href="#namespaces">Namespaces</a></h3>
+          <dl class="m-dox">
+            {% for namespace in compound.namespaces %}
+{{ entry_namespace(namespace) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.classes %}
+        <section id="nested-classes">
+          <h2><a href="#nested-classes">Classes</a></h3>
+          <dl class="m-dox">
+            {% for class in compound.classes %}
+{{ entry_class(class) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.enums %}
+        <section id="enum-members">
+          <h2><a href="#enum-members">Enums</a></h3>
+          <dl class="m-dox">
+            {% for enum in compound.enums %}
+{{ entry_enum(enum) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.typedefs %}
+        <section id="typedef-members">
+          <h2><a href="#typedef-members">Typedefs</a></h3>
+          <dl class="m-dox">
+            {% for typedef in compound.typedefs %}
+{{ entry_typedef(typedef) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.funcs %}
+        <section id="func-members">
+          <h2><a href="#func-members">Functions</a></h3>
+          <dl class="m-dox">
+            {% for func in compound.funcs %}
+{{ entry_func(func) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.vars %}
+        <section id="var-members">
+          <h2><a href="#var-members">Variables</a></h3>
+          <dl class="m-dox">
+            {% for var in compound.vars %}
+{{ entry_var(var) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% if compound.defines %}
+        <section id="define-members">
+          <h2><a href="#define-members">Defines</a></h3>
+          <dl class="m-dox">
+            {% for define in compound.defines %}
+{{ entry_define(define) }}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endif %}
+        {% for group in compound.groups %}
+        <section id="{{ group.id }}">
+          <h2><a href="#{{ group.id }}">{{ group.name }}</a></h2>
+          {% if group.description %}
+{{ group.description }}
+          {% endif %}
+          <dl class="m-dox">
+            {% for kind, member in group.members %}
+            {% if kind == 'namespace' %}
+{{ entry_namespace(member) }}
+            {% elif kind == 'class' %}
+{{ entry_class(member) }}
+            {% elif kind == 'enum' %}
+{{ entry_enum(member) }}
+            {% elif kind == 'typedef' %}
+{{ entry_typedef(member) }}
+            {% elif kind == 'func' %}
+{{ entry_func(member) }}
+            {% elif kind == 'var' %}
+{{ entry_var(member) }}
+            {% elif kind == 'define' %}
+{{ entry_define(member) }}
+            {% endif %}
+            {% endfor %}
+          </dl>
+        </section>
+        {% endfor %}
+        {% if compound.has_enum_details %}
+        <section>
+          <h2>Enum documentation</h2>
+          {% for enum in compound.enums %}
+          {% if enum.has_details %}
+{{ details_enum(enum) }}
+          {% endif %}
+          {% endfor %}
+          {% for group in compound.groups %}
+          {% for kind, member in group.members %}
+          {% if kind == 'enum' and member.has_details %}
+{{ details_enum(member) }}
+          {% endif %}
+          {% endfor %}
+          {% endfor %}
+        </section>
+        {% endif %}
+        {% if compound.has_typedef_details %}
+        <section>
+          <h2>Typedef documentation</h2>
+          {% for typedef in compound.typedefs %}
+          {% if typedef.has_details %}
+{{ details_typedef(typedef) }}
+          {% endif %}
+          {% endfor %}
+          {% for group in compound.groups %}
+          {% for kind, member in group.members %}
+          {% if kind == 'typedef' and member.has_details %}
+{{ details_typedef(member) }}
+          {% endif %}
+          {% endfor %}
+          {% endfor %}
+        </section>
+        {% endif %}
+        {% if compound.has_func_details %}
+        <section>
+          <h2>Function documentation</h2>
+          {% for func in compound.funcs %}
+          {% if func.has_details %}
+{{ details_func(func) }}
+          {% endif %}
+          {% endfor %}
+          {% for group in compound.groups %}
+          {% for kind, member in group.members %}
+          {% if kind == 'func' and member.has_details %}
+{{ details_func(member) }}
+          {% endif %}
+          {% endfor %}
+          {% endfor %}
+        </section>
+        {% endif %}
+        {% if compound.has_var_details %}
+        <section>
+          <h2>Variable documentation</h2>
+          {% for var in compound.vars %}
+          {% if var.has_details %}
+{{ details_var(var) }}
+          {% endif %}
+          {% endfor %}
+          {% for group in compound.groups %}
+          {% for kind, member in group.members %}
+          {% if kind == 'var' and member.has_details %}
+{{ details_var(member) }}
+          {% endif %}
+          {% endfor %}
+          {% endfor %}
+        </section>
+        {% endif %}
+        {% if compound.has_define_details %}
+        <section>
+          <h2>Define documentation</h2>
+          {% for define in compound.defines %}
+          {% if define.has_details %}
+{{ details_define(define) }}
+          {% endif %}
+          {% endfor %}
+          {% for group in compound.groups %}
+          {% for kind, member in group.members %}
+          {% if kind == 'define' and member.has_details %}
+{{ details_define(member) }}
+          {% endif %}
+          {% endfor %}
+          {% endfor %}
+        </section>
+        {% endif %}
+{% endblock %}
diff --git a/doxygen/templates/base.html b/doxygen/templates/base.html
new file mode 100644 (file)
index 0000000..1c5ea73
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>{% block title %}{{ PROJECT_NAME }}{% if PROJECT_BRIEF %} {{ PROJECT_BRIEF }}{% endif %}{% endblock %}</title>
+  {% for css in HTML_EXTRA_STYLESHEET %}
+  <link rel="stylesheet" href="{{ css|basename_or_url|e }}" />
+  {% endfor %}
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <meta name="theme-color" content="{{ M_THEME_COLOR }}" />
+</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">{{ PROJECT_NAME }}{% if PROJECT_BRIEF %} <span class="m-thin">{{ PROJECT_BRIEF }}</span>{% endif %}</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"{% if navbar_current == 'pages' %} id="m-navbar-current"{% endif %}>Pages</a></li>
+            <li><a href="namespaces.html"{% if navbar_current == 'namespaces' %} id="m-navbar-current"{% endif %}>Namespaces</a></li>
+          </ol>
+          <ol class="m-col-t-6 m-col-m-none" start="3">
+            <li><a href="annotated.html"{% if navbar_current == 'annotated' %} id="m-navbar-current"{% endif %}>Classes</a></li>
+            <li><a href="files.html"{% if navbar_current == 'files' %} id="m-navbar-current"{% endif %}>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">
+        {% if M_PAGE_HEADER %}
+        {{ M_PAGE_HEADER|replace('{filename}', FILENAME) }}
+        {% endif %}
+{% block main %}
+{% endblock %}
+      </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>{{ PROJECT_NAME }}{% if PROJECT_BRIEF %} {{ PROJECT_BRIEF }}{% endif %}. Created by <a href="http://doxygen.org/">Doxygen</a> {{ DOXYGEN_VERSION }} and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/templates/class.html b/doxygen/templates/class.html
new file mode 100644 (file)
index 0000000..a9ff5ac
--- /dev/null
@@ -0,0 +1 @@
+{% extends 'base-class-reference.html' %}
diff --git a/doxygen/templates/details-define.html b/doxygen/templates/details-define.html
new file mode 100644 (file)
index 0000000..1fee5ab
--- /dev/null
@@ -0,0 +1,35 @@
+          <section class="m-dox-details" id="{{ define.id }}"><div>
+            <h3>
+              {% set j = joiner(',\n              ') %}
+              <span class="m-dox-wrap-bumper">#define <a href="#{{ define.id }}" class="m-dox-self">{{ define.name }}</a>{% if define.params != None %}(</span><span class="m-dox-wrap">{% for param in define.params %}{{ j() }}{{ param[0] }}{% endfor %}){% endif %}</span>
+            </h3>
+            {% if define.brief %}
+            <p>{{ define.brief }}</p>
+            {% endif %}
+            {% if define.has_param_details or define.return_value %}
+            <table class="m-table m-fullwidth m-flat">
+              {% if define.has_param_details %}
+              <thead>
+                <tr><th colspan="2">Parameters</th></tr>
+              </thead>
+              <tbody>
+                {% for name, description in define.params %}
+                <tr>
+                  <td{% if loop.index == 1 %} style="width: 1%"{% endif %}>{{ name }}</td>
+                  <td>{{ description }}</td>
+                </tr>
+                {% endfor %}
+              </tbody>
+              {% endif %}
+              {% if define.return_value %}
+              <tfoot>
+                <tr>
+                  <th{% if not define.has_param_details %} style="width: 1%"{% endif %}>Returns</th>
+                  <td>{{ define.return_value }}</td>
+                </tr>
+              </tfoot>
+              {% endif %}
+            </table>
+            {% endif %}
+{{ define.description }}
+          </div></section>
diff --git a/doxygen/templates/details-enum.html b/doxygen/templates/details-enum.html
new file mode 100644 (file)
index 0000000..40c8d67
--- /dev/null
@@ -0,0 +1,34 @@
+          <section class="m-dox-details" id="{{ enum.id }}"><div>
+            <h3>
+              {% if compound.templates != None %}
+              <div class="m-dox-template">
+                {% set j = joiner(', ') %}
+                template&lt;{% for t in compound.templates %}{{ j() }}{{ t.type }} {% if t.name %}{{ t.name }}{% else %}_{{ loop.index }}{% endif %}{% endfor %}&gt;
+              </div>
+              {% endif %}
+              enum {% if enum.is_strong %}class {% endif %}{{ prefix }}<a href="#{{ enum.id }}" class="m-dox-self">{{ enum.name }}</a>{% if enum.type %}: {{ enum.type }}{% endif %}{% if enum.is_protected %} <span class="m-label m-warning">protected</span>{% endif %}
+              {# not sure why there needs to be this space #}
+
+            </h3>
+            {% if enum.brief %}{# brief can be omitted for anonymous enums #}
+            <p>{{ enum.brief }}</p>
+            {% endif %}
+            {% if enum.description %}
+{{ enum.description }}
+            {% endif %}
+            {% if enum.values %}
+            <table class="m-table m-fullwidth m-flat m-dox">
+              <thead><tr><th style="width: 1%">Enumerators</th><th></th></tr></thead>
+              <tbody>
+                {% for value in enum.values %}
+                <tr>
+                  <td><a href="#{{ value.id }}" class="m-dox-self" name="{{ value.id }}">{{ value.name }}</a></td>
+                  <td>
+{{ value.description }}
+                  </td>
+                </tr>
+                {% endfor %}
+              </tbody>
+            </table>
+            {% endif %}
+          </div></section>
diff --git a/doxygen/templates/details-func.html b/doxygen/templates/details-func.html
new file mode 100644 (file)
index 0000000..58b6396
--- /dev/null
@@ -0,0 +1,62 @@
+          <section class="m-dox-details" id="{{ func.id }}"><div>
+            <h3>
+              {% if compound.templates != None or func.templates != None %}
+              <div class="m-dox-template">
+                {% if compound.templates != None %}
+                {% set j = joiner(', ') %}
+                template&lt;{% for t in compound.templates %}{{ j() }}{{ t.type }} {% if t.name %}{{ t.name }}{% else %}_{{ loop.index }}{% endif %}{% endfor %}&gt;
+                {% endif %}
+                {% if func.templates != None %}
+                {% set j = joiner(', ') %}
+                template&lt;{% for t in func.templates %}{{ j() }}{{ t.type }}{% if t.name %} {{ t.name }}{% endif %}{% if t.default %} = {{ t.default }}{% endif %}{% endfor %}&gt;
+                {% endif %}
+              </div>
+              {% endif %}
+              {% set j = joiner(',\n              ') %}
+              <span class="m-dox-wrap-bumper">{{ func.prefix }}{{ func.type }} {{ prefix }}</span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#{{ func.id }}" class="m-dox-self">{{ func.name }}</a>(</span><span class="m-dox-wrap">{% for param in func.params %}{{ j() }}{{ param.type }}{% if param.default %} = {{ param.default }}{% endif %}{% endfor %}){{ func.suffix }}{% if func.is_explicit %} <span class="m-label m-info">explicit</span> {% endif %}{% if func.is_pure_virtual %} <span class="m-label m-warning">pure virtual</span>{% elif func.is_virtual %} <span class="m-label m-warning">virtual</span>{% endif %}{% if func.is_protected %} <span class="m-label m-warning">protected</span>{% elif func.is_private %} <span class="m-label m-danger">private</span>{% endif %}{% if func.is_defaulted %} <span class="m-label m-info">defaulted</span>{% endif %}{% if func.is_deleted %} <span class="m-label m-danger">deleted</span>{% endif %}{% if func.is_constexpr %} <span class="m-label m-primary">constexpr</span>{% endif %}{% if func.is_noexcept %} <span class="m-label m-success">noexcept</span>{% endif %}</span></span>
+            </h3>
+            {% if func.brief %}
+            <p>{{ func.brief }}</p>
+            {% endif %}
+            {% if func.has_template_details or func.has_param_details or func.return_value %}
+            <table class="m-table m-fullwidth m-flat">
+              {% if func.has_template_details %}
+              <thead>
+                <tr><th colspan="2">Template parameters</th></tr>
+              </thead>
+              <tbody>
+                {% for template in func.templates|selectattr('name') %}
+                <tr>
+                  <td{% if loop.index == 1 %} style="width: 1%"{% endif %}>{{ template.name }}</td>
+                  <td>{{ template.description }}</td>
+                </tr>
+                {% endfor %}
+              </tbody>
+              {% endif %}
+              {% if func.has_param_details %}
+              <thead>
+                <tr><th colspan="2">Parameters</th></tr>
+              </thead>
+              <tbody>
+                {% for param in func.params|selectattr('name') %}
+                <tr>
+                  <td{% if loop.index == 1 and not func.has_template_details %} style="width: 1%"{% endif %}>{{ param.name }}{% if param.direction == 'in' %}&nbsp;<span class="m-label m-flat m-info">in</span>{% elif param.direction == 'out' %}&nbsp;<span class="m-label m-flat m-warning">out</span>{% elif param.direction == 'inout' %}&nbsp;<span class="m-label m-flat m-danger">in/out</span>{% endif %}</td>
+                  <td>{{ param.description }}</td>
+                </tr>
+                {% endfor %}
+              </tbody>
+              {% endif %}
+              {% if func.return_value %}
+              <tfoot>
+                <tr>
+                  <th{% if not func.has_template_details and not func.has_param_details %} style="width: 1%"{% endif %}>Returns</th>
+                  <td>{{ func.return_value }}</td>
+                </tr>
+              </tfoot>
+              {% endif %}
+            </table>
+            {% endif %}
+            {% if func.description %}
+{{ func.description }}
+            {% endif %}
+          </div></section>
diff --git a/doxygen/templates/details-typedef.html b/doxygen/templates/details-typedef.html
new file mode 100644 (file)
index 0000000..bec5a0f
--- /dev/null
@@ -0,0 +1,44 @@
+          <section class="m-dox-details" id="{{ typedef.id }}"><div>
+            <h3>
+              {% if compound.templates != None or typedef.templates != None %}
+              <div class="m-dox-template">
+                {% if compound.templates != None %}
+                {% set j = joiner(', ') %}
+                template&lt;{% for t in compound.templates %}{{ j() }}{{ t.type }} {% if t.name %}{{ t.name }}{% else %}_{{ loop.index }}{% endif %}{% endfor %}&gt;
+                {% endif %}
+                {% if typedef.templates != None %}
+                {% set j = joiner(', ') %}
+                template&lt;{% for t in typedef.templates %}{{ j() }}{{ t.type }}{% if t.name %} {{ t.name }}{% endif %}{% if t.default %} = {{ t.default }}{% endif %}{% endfor %}&gt;
+                {% endif %}
+              </div>
+              {% endif %}
+              {% if typedef.is_using %}
+              using {{ prefix }}<a href="#{{ typedef.id }}" class="m-dox-self">{{ typedef.name }}</a> = {{ typedef.type }}{{ typedef.args }}{% if typedef.is_protected %} <span class="m-label m-warning">protected</span>{% endif %}
+              {% else %}
+              typedef {{ typedef.type }}{% if not typedef.args %} {% endif %}{{ prefix }}<a href="#{{ typedef.id }}" class="m-dox-self">{{ typedef.name }}</a>{{ typedef.args }}{% if typedef.is_protected %} <span class="m-label m-warning">protected</span>{% endif %}
+              {% endif %}
+              {# the empty line has to be here to prevent the lines from merging #}
+
+            </h3>
+            {% if typedef.brief %}
+            <p>{{ typedef.brief }}</p>
+            {% endif %}
+            {% if typedef.has_template_details %}
+            <table class="m-table m-fullwidth m-flat">
+              <thead>
+                <tr><th colspan="2">Template parameters</th></tr>
+              </thead>
+              <tbody>
+                {% for template in typedef.templates|selectattr('name') %}
+                <tr>
+                  <td{% if loop.index == 1 %} style="width: 1%"{% endif %}>{{ template.name }}</td>
+                  <td>{{ template.description }}</td>
+                </tr>
+                {% endfor %}
+              </tbody>
+            </table>
+            {% endif %}
+            {% if typedef.description %}
+{{ typedef.description }}
+            {% endif %}
+          </div></section>
diff --git a/doxygen/templates/details-var.html b/doxygen/templates/details-var.html
new file mode 100644 (file)
index 0000000..0eabc81
--- /dev/null
@@ -0,0 +1,17 @@
+          <section class="m-dox-details" id="{{ var.id }}"><div>
+            <h3>
+              {% if compound.templates != None %}
+              <div class="m-dox-template">
+                {% set j = joiner(', ') %}
+                template&lt;{% for t in compound.templates %}{{ j() }}{{ t.type }} {% if t.name %}{{ t.name }}{% else %}_{{ loop.index }}{% endif %}{% endfor %}&gt;
+              </div>
+              {% endif %}
+              {%+ if var.is_static %}static {% endif %}{{ var.type }} {{ prefix }}<a href="#{{ var.id }}" class="m-dox-self">{{ var.name }}</a>{% if var.is_protected %} <span class="m-label m-warning">protected</span>{% endif %}{% if var.is_constexpr %} <span class="m-label m-primary">constexpr</span>{% endif %}
+              {# the empty line needs to be here to prevent the lines from merging #}
+
+            </h3>
+            {% if var.brief %}
+            <p>{{ var.brief }}</p>
+            {% endif %}
+{{ var.description }}
+          </div></section>
diff --git a/doxygen/templates/dir.html b/doxygen/templates/dir.html
new file mode 100644 (file)
index 0000000..1d54c5e
--- /dev/null
@@ -0,0 +1,10 @@
+{% set navbar_current = 'files' %}
+{% extends 'base-reference.html' %}
+
+{% block title %}{% for name, _ in compound.breadcrumb %}{{ name }}/{% endfor %} directory | {{ super() }}{% endblock %}
+
+{% block header %}
+        <h1>
+          {%+ for name, target in compound.breadcrumb[:-1] %}<span class="m-breadcrumb"><a href="{{ target }}">{{ name }}</a>/</span>{% endfor %}{{ compound.breadcrumb[-1][0] }}<span class="m-breadcrumb">/</span> <span class="m-thin">directory</span>
+        </h1>
+{% endblock %}
diff --git a/doxygen/templates/entry-class.html b/doxygen/templates/entry-class.html
new file mode 100644 (file)
index 0000000..5ce0b74
--- /dev/null
@@ -0,0 +1,8 @@
+            <dt>
+              {% if class.templates != None %}
+              {% set j = joiner(', ') %}
+              <div class="m-dox-template">template&lt;{% for t in class.templates %}{{ j() }}{{ t.type }}{% if t.name %} {{ t.name }}{% endif %}{% if t.default %} = {{ t.default }}{% endif %}{% endfor %}&gt;</div>
+              {% endif %}
+              {{ class.kind }} <a href="{{ class.url }}" class="m-dox">{{ class.name }}</a>
+            </dt>
+            <dd>{{ class.brief }}</dd>
diff --git a/doxygen/templates/entry-define.html b/doxygen/templates/entry-define.html
new file mode 100644 (file)
index 0000000..6c3775e
--- /dev/null
@@ -0,0 +1,5 @@
+            <dt>
+              {% set j = joiner(',\n              ') %}
+              <span class="m-dox-wrap-bumper">#define <a href="#{{ define.id }}" {% if define.has_details %}class="m-dox"{% else %}class="m-dox-self" name="{{ define.id }}"{% endif %}>{{ define.name }}</a>{% if define.params != None %}(</span><span class="m-dox-wrap">{% for param in define.params %}{{ j() }}{{ param[0] }}{% endfor %}){% endif %}</span>
+            </dt>
+            <dd>{{ define.brief }}</dd>
diff --git a/doxygen/templates/entry-dir.html b/doxygen/templates/entry-dir.html
new file mode 100644 (file)
index 0000000..3232232
--- /dev/null
@@ -0,0 +1,2 @@
+            <dt>directory <a href="{{ dir.url }}" class="m-dox">{{ dir.name }}</a>/</dt>
+            <dd>{{ dir.brief }}</dd>
diff --git a/doxygen/templates/entry-enum.html b/doxygen/templates/entry-enum.html
new file mode 100644 (file)
index 0000000..60fa44b
--- /dev/null
@@ -0,0 +1,5 @@
+            <dt>
+              {% set j = joiner(',\n              ') %}
+              <span class="m-dox-wrap-bumper">enum {% if enum.is_strong %}class {% endif %}<a href="#{{ enum.id }}" {% if enum.has_details %}class="m-dox"{% else %}class="m-dox-self" name="{{ enum.id }}"{% endif %}>{{ enum.name }}</a>{% if enum.type %}: {{ enum.type }}{% endif %} { </span><span class="m-dox-wrap">{% for value in enum.values %}{{ j() }}<a href="#{{ value.id }}" class="m-dox">{{ value.name }}</a>{% if value.initializer %} {{ value.initializer }}{% endif %}{% endfor %} }{% if mark_nonpublic and enum.is_protected %} <span class="m-label m-flat m-warning">protected</span>{% endif %}</span>
+            </dt>
+            <dd>{{ enum.brief }}</dd>
diff --git a/doxygen/templates/entry-file.html b/doxygen/templates/entry-file.html
new file mode 100644 (file)
index 0000000..4dfdb91
--- /dev/null
@@ -0,0 +1,2 @@
+            <dt>file <a href="{{ file.url }}" class="m-dox">{{ file.name }}</a></dt>
+            <dd>{{ file.brief }}</dd>
diff --git a/doxygen/templates/entry-func.html b/doxygen/templates/entry-func.html
new file mode 100644 (file)
index 0000000..a7e0912
--- /dev/null
@@ -0,0 +1,9 @@
+            <dt>
+              {% if func.templates != None %}
+              {% set j = joiner(', ') %}
+              <div class="m-dox-template">template&lt;{% for t in func.templates %}{{ j() }}{{ t.type }}{% if t.name %} {{ t.name }}{% endif %}{% if t.default %} = {{ t.default }}{% endif%}{% endfor %}&gt;</div>
+              {% endif %}
+              {% set j = joiner(',\n              ') %}
+              <span class="m-dox-wrap-bumper">{{ func.prefix }}{% if func.type == 'void' %}void {% elif func.type %}auto {% endif %}<a href="#{{ func.id }}" {% if func.has_details %}class="m-dox"{% else %}class="m-dox-self" name="{{ func.id }}"{% endif %}>{{ func.name }}</a>(</span><span class="m-dox-wrap">{% for param in func.params %}{{ j() }}{{ param.type }}{% if param.default %} = {{ param.default }}{% endif %}{% endfor %}){{ func.suffix }}{% if func.type and func.type != 'void' %} -&gt; {{ func.type }}{% endif %}{% if not func.type or mark_nonpublic %}{% if func.is_protected %} <span class="m-label m-flat m-warning">protected</span>{% elif func.is_private %} <span class="m-label m-flat m-danger">private</span>{% endif %}{% endif %}{% if func.is_defaulted %} <span class="m-label m-flat m-info">defaulted</span>{% endif %}{% if func.is_deleted %} <span class="m-label m-flat m-danger">deleted</span>{% endif %}{% if func.is_explicit %} <span class="m-label m-flat m-info">explicit</span> {% endif %}{% if func.is_pure_virtual %} <span class="m-label m-flat m-warning">pure virtual</span>{% elif func.is_virtual %} <span class="m-label m-flat m-warning">virtual</span>{% endif %}{% if func.is_constexpr %} <span class="m-label m-flat m-primary">constexpr</span>{% endif %}{% if func.is_noexcept %} <span class="m-label m-flat m-success">noexcept</span>{% endif %}</span>
+            </dt>
+            <dd>{{ func.brief }}</dd>
diff --git a/doxygen/templates/entry-namespace.html b/doxygen/templates/entry-namespace.html
new file mode 100644 (file)
index 0000000..eaae64a
--- /dev/null
@@ -0,0 +1,2 @@
+            <dt>namespace <a href="{{ namespace.url }}" class="m-dox">{{ namespace.name }}</a></dt>
+            <dd>{{ namespace.brief }}</dd>
diff --git a/doxygen/templates/entry-typedef.html b/doxygen/templates/entry-typedef.html
new file mode 100644 (file)
index 0000000..03b99db
--- /dev/null
@@ -0,0 +1,10 @@
+            <dt>
+              {% if typedef.templates != None %}
+              {% set j = joiner(', ') %}
+              <div class="m-dox-template">template&lt;{% for t in typedef.templates %}{{ j() }}{{ t.type }}{% if t.name %} {{ t.name }}{% endif %}{% if t.default %} = {{ t.default }}{% endif%}{% endfor %}&gt;</div>
+              {% endif %}
+              using <a href="#{{ typedef.id }}" {% if typedef.has_details %}class="m-dox"{% else %}class="m-dox-self" name="{{ typedef.id }}"{% endif %}>{{ typedef.name }}</a> = {{ typedef.type }}{{ typedef.args }}{% if mark_nonpublic and typedef.is_protected %} <span class="m-label m-flat m-warning">protected</span>{% endif %}
+              {# This empty line needs to be there otherwise it's eaten #}
+
+            </dt>
+            <dd>{{ typedef.brief }}</dd>
diff --git a/doxygen/templates/entry-var.html b/doxygen/templates/entry-var.html
new file mode 100644 (file)
index 0000000..0cb5950
--- /dev/null
@@ -0,0 +1,2 @@
+            <dt>{% if var.is_static %}static {% endif %}{{ var.type }} <a href="#{{ var.id }}" {% if var.has_details %}class="m-dox"{% else %}class="m-dox-self" name="{{ var.id }}"{% endif %}>{{ var.name }}</a>{% if mark_nonpublic and var.is_protected %} <span class="m-label m-flat m-warning">protected</span>{% endif %}{% if var.is_constexpr %} <span class="m-label m-flat m-primary">constexpr</span>{% endif %}</dt>
+            <dd>{{ var.brief }}</dd>
diff --git a/doxygen/templates/example.html b/doxygen/templates/example.html
new file mode 100644 (file)
index 0000000..e594db2
--- /dev/null
@@ -0,0 +1,13 @@
+{% extends 'base.html' %}
+
+{% block title %}{{ compound.name }} example | {{ super() }}{% endblock %}
+
+{% block main %}
+          <h1>{{ compound.name }} <span class="m-thin">example</span></h1>
+          {% if compound.brief %}
+          <p>{{ compound.brief }}</p>
+          {% endif %}
+{% if compound.description %}
+{{ compound.description }}
+{% endif %}
+{% endblock %}
diff --git a/doxygen/templates/file.html b/doxygen/templates/file.html
new file mode 100644 (file)
index 0000000..8ded452
--- /dev/null
@@ -0,0 +1,10 @@
+{% set navbar_current = 'files' %}
+{% extends 'base-reference.html' %}
+
+{% block title %}{% set j = joiner('/') %}{% for name, _ in compound.breadcrumb %}{{ j() }}{{ name }}{% endfor %} file | {{ super() }}{% endblock %}
+
+{% block header %}
+        <h1>
+          {%+ for name, target in compound.breadcrumb[:-1] %}<span class="m-breadcrumb"><a href="{{ target }}">{{ name }}</a>/</span>{% endfor %}{{ compound.breadcrumb[-1][0] }} <span class="m-thin">file</span>
+        </h1>
+{% endblock %}
diff --git a/doxygen/templates/files.html b/doxygen/templates/files.html
new file mode 100644 (file)
index 0000000..0f1b98b
--- /dev/null
@@ -0,0 +1,21 @@
+{% set navbar_current = 'files' %}
+{% extends 'base-index.html' %}
+
+{% block main %}
+        <h1>Files</h2>
+        <ul class="m-dox">
+          {% for i in index.files recursive %}
+          {% if i.children %}
+          <li class="m-dox-collapsible{% if loop.depth > M_FILE_TREE_EXPAND_LEVELS %} collapsed{% endif %}">
+            <a href="#" onclick="return toggle(this)">{{ i.kind }}</a> <a href="{{ i.url }}" class="m-dox">{{ i.name }}</a> <span class="m-dox">{{ i.brief }}</span>
+            <ul class="m-dox">
+{{ loop(i.children)|indent(4, true) }}
+            </ul>
+          </li>
+          {% else %}
+          <li>{{ i.kind }} <a href="{{ i.url }}" class="m-dox">{{ i.name }}</a> <span class="m-dox">{{ i.brief }}</span></li>
+          {% endif %}
+          {% endfor %}
+        </ul>
+{{ super() -}}
+{% endblock %}
diff --git a/doxygen/templates/namespace.html b/doxygen/templates/namespace.html
new file mode 100644 (file)
index 0000000..e829c15
--- /dev/null
@@ -0,0 +1,8 @@
+{% set navbar_current = 'namespaces' %}
+{% extends 'base-reference.html' %}
+
+{% block title %}{% set j = joiner('::') %}{% for name, _ in compound.breadcrumb %}{{ j() }}{{ name }}{% endfor %} namespace | {{ super() }}{% endblock %}
+
+{% block header %}
+        <h1>{% for name, target in compound.breadcrumb[:-1] %}<span class="m-breadcrumb"><a href="{{ target }}">{{ name }}</a>::</span>{% endfor %}{{ compound.breadcrumb[-1][0] }} <span class="m-thin">namespace</span></h1>
+{% endblock %}
diff --git a/doxygen/templates/namespaces.html b/doxygen/templates/namespaces.html
new file mode 100644 (file)
index 0000000..2f1af35
--- /dev/null
@@ -0,0 +1,21 @@
+{% set navbar_current = 'namespaces' %}
+{% extends 'base-index.html' %}
+
+{% block main %}
+        <h1>Namespaces</h2>
+        <ul class="m-dox">
+          {% for i in index.symbols|selectattr('kind', 'equalto', 'namespace') recursive %}
+          {% if i.has_nestable_children %}
+          <li class="m-dox-collapsible">
+            <a href="#" onclick="return toggle(this)">{{ i.kind }}</a> <a href="{{ i.url }}" class="m-dox">{{ i.name }}</a> <span class="m-dox">{{ i.brief }}</span>
+            <ul class="m-dox">
+{{ loop(i.children|selectattr('kind', 'equalto', 'namespace'))|indent(4, true) }}
+            </ul>
+          </li>
+          {% else %}
+          <li>{{ i.kind }} <a href="{{ i.url }}" class="m-dox">{{ i.name }}</a> <span class="m-dox">{{ i.brief }}</span></li>
+          {% endif %}
+          {% endfor %}
+        </ul>
+{{ super() -}}
+{% endblock %}
diff --git a/doxygen/templates/page.html b/doxygen/templates/page.html
new file mode 100644 (file)
index 0000000..1a1883f
--- /dev/null
@@ -0,0 +1,38 @@
+{% set navbar_current = 'pages' %}
+{% extends 'base.html' %}
+
+{% block title %}{% set j = joiner(' &raquo; ') %}{% for name, _ in compound.breadcrumb %}{{ j() }}{{ name }}{% endfor %} | {{ super() }}{% endblock %}
+
+{% block main %}
+        <h1>
+          {% for name, target in compound.breadcrumb[:-1] %}
+          <span class="m-breadcrumb"><a href="{{ target }}">{{ name }}</a> &raquo;</span>
+          {% endfor %}
+          {{ compound.breadcrumb[-1][0] }}
+        </h1>
+        {% if compound.brief %}
+        <p>{{ compound.brief }}</p>
+        {% endif %}
+        {% if compound.sections %}
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            {% for id, name, children in compound.sections recursive %}
+            {% if children %}
+            <li>
+              <a href="#{{ id }}">{{ name }}</a>
+              <ul>
+{{ loop(children)|indent(4, true) }}
+              </ul>
+            </li>
+            {% else %}
+            <li><a href="#{{ id }}">{{ name }}</a></li>
+            {% endif %}
+            {% endfor %}
+          </ul>
+        </div>
+        {% endif %}
+{% if compound.description %}
+{{ compound.description }}
+{% endif %}
+{% endblock %}
diff --git a/doxygen/templates/pages.html b/doxygen/templates/pages.html
new file mode 100644 (file)
index 0000000..fe4b7ce
--- /dev/null
@@ -0,0 +1,21 @@
+{% set navbar_current = 'pages' %}
+{% extends 'base-index.html' %}
+
+{% block main %}
+        <h1>Pages</h2>
+        <ul class="m-dox">
+          {% for i in index.pages recursive %}
+          {% if i.children %}
+          <li class="m-dox-collapsible">
+            <a href="#" onclick="return toggle(this)"></a><a href="{{ i.url }}" class="m-dox">{{ i.name }}</a> <span class="m-dox">{{ i.brief }}</span>
+            <ul class="m-dox">
+{{ loop(i.children)|indent(4, true) }}
+            </ul>
+          </li>
+          {% else %}
+          <li><a href="{{ i.url }}" class="m-dox">{{ i.name }}</a> <span class="m-dox">{{ i.brief }}</span></li>
+          {% endif %}
+          {% endfor %}
+        </ul>
+{{ super() -}}
+{% endblock %}
diff --git a/doxygen/templates/struct.html b/doxygen/templates/struct.html
new file mode 100644 (file)
index 0000000..a9ff5ac
--- /dev/null
@@ -0,0 +1 @@
+{% extends 'base-class-reference.html' %}
diff --git a/doxygen/templates/union.html b/doxygen/templates/union.html
new file mode 100644 (file)
index 0000000..a9ff5ac
--- /dev/null
@@ -0,0 +1 @@
+{% extends 'base-class-reference.html' %}
diff --git a/doxygen/test/README.rst b/doxygen/test/README.rst
new file mode 100644 (file)
index 0000000..afdd8c3
--- /dev/null
@@ -0,0 +1,22 @@
+Doxygen generator testing and code coverage
+###########################################
+
+Run tests:
+
+.. code:: sh
+
+    cd doxygen
+    python -m unittest
+
+Code coverage needs `coverage.py <https://coverage.readthedocs.io/>`_:
+
+.. code:: sh
+
+    cd doxygen
+    coverage run -m unittest -v ; coverage html
+    # open htmlcov/index.html in your browser
+
+Files named ``test_something.py`` take their input from  ``something[_name]``
+directories, ``name`` corresponds to given test class. Comment-out the line
+that removes the ``html`` directory in ``__init__.py`` to see all test output
+files.
diff --git a/doxygen/test/__init__.py b/doxygen/test/__init__.py
new file mode 100644 (file)
index 0000000..6179f29
--- /dev/null
@@ -0,0 +1,32 @@
+import os
+import shutil
+import subprocess
+import unittest
+import xml.etree.ElementTree as ET
+
+from dox2html5 import run, default_templates, default_wildcard, default_index_pages
+
+class IntegrationTestCase(unittest.TestCase):
+    def __init__(self, path, dir, *args, **kwargs):
+        unittest.TestCase.__init__(self, *args, **kwargs)
+        # Source files for test_something.py are in something_{dir}/ subdirectory
+        self.path = os.path.join(os.path.dirname(os.path.realpath(path)), os.path.splitext(os.path.basename(path))[0][5:] + ('_' + dir if dir else ''))
+
+        # Display ALL THE DIFFS
+        self.maxDiff = None
+
+    def setUp(self):
+        if os.path.exists(os.path.join(self.path, 'xml')): shutil.rmtree(os.path.join(self.path, 'xml'))
+        subprocess.run(["doxygen"], cwd=self.path)
+
+        if os.path.exists(os.path.join(self.path, 'html')): shutil.rmtree(os.path.join(self.path, 'html'))
+
+    def run_dox2html5(self, templates=default_templates, wildcard=default_wildcard, index_pages=default_index_pages):
+        run(os.path.join(self.path, 'Doxyfile'), templates=templates, wildcard=wildcard, index_pages=index_pages)
+
+    def expected_actual_contents(self, file):
+        with open(os.path.join(self.path, file)) as f:
+            expected = f.read().strip()
+        with open(os.path.join(self.path, 'html', file)) as f:
+            actual = f.read().strip()
+        return expected, actual
diff --git a/doxygen/test/compound_detailed/Doxyfile b/doxygen/test/compound_detailed/Doxyfile
new file mode 100644 (file)
index 0000000..beb4a79
--- /dev/null
@@ -0,0 +1,6 @@
+INPUT                   = File.h
+AUTOLINK_SUPPORT        = NO
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
diff --git a/doxygen/test/compound_detailed/File.h b/doxygen/test/compound_detailed/File.h
new file mode 100644 (file)
index 0000000..f624977
--- /dev/null
@@ -0,0 +1,210 @@
+/** @file
+ * @brief A file
+ */
+
+/**
+@brief Class with template parameters
+@tparam T Template parameter T
+@tparam U Template parameter U
+
+Should have it displayed on top.
+*/
+template<class T, class U = void, class = int> struct Template {
+    /**
+     * @brief Another
+     *
+     * Should have just one template with _3 for unnamed parameter.
+     */
+    void bar();
+
+    protected:
+        /**
+        * @brief Variable
+        *
+        * Should have just one template with _3 for unnamed parameter. Should
+        * also have the `protected` label in the details.
+        */
+        int a;
+
+        /**
+        * @brief Enum
+        *
+        * Should have just one template with _3 for unnamed parameter. Should
+        * also have the `protected` label in the details.
+        */
+        enum class Bar {};
+
+        /**
+         * @brief Typedef
+         *
+         * Should have just one template with _3 for unnamed parameter. Should
+         * also have the `protected` label in the details.
+         */
+        typedef A B;
+
+        /**
+         * @brief Template alias
+         * @tparam V Well, this is V as well
+         *
+         * Should include both template lists, with _3 for unnamed parameter.
+         * Should also have the `protected` label in the details.
+         */
+        template<class V, bool = false> using Foo = Buuu<V, false>;
+
+        /**
+        * @brief Function
+        * @tparam V Well, this is V
+        *
+        * Should not repeat default parameter from class, should include both U
+        * and V in the docs. Should also have the `protected` label in the
+        * details.
+        */
+        template<class V, int = 3> void foo();
+};
+
+/**
+@brief Specialized class template
+
+Should have `template<>` displayed on top.
+*/
+template<> struct Template<void> {
+    /**
+     * @brief Function
+     *
+     * Should still have both templates repeated.
+     */
+    template<int b> void baz();
+};
+
+/**
+@brief Class with wrong template parameter description
+@param T Documented wrongly as parameter
+@tparam WTF And this one does not exist
+*/
+template<class T> struct TemplateWarning {};
+
+/**
+@brief Namespace docs
+
+And we have some detailed docs as well.
+*/
+namespace Namee {}
+
+namespace Foo {
+
+/**
+@brief Function with *everything*
+@tparam T A template, innit
+@param a        That's a for you
+@param b        Well, a string
+@param things   And an array!
+@return It returns!
+
+Ooooh, more text!
+*/
+template<class T> int foo(int a, std::string b, char(&things)[5], bool, char(&)[42]);
+
+/**
+@brief Input and output
+@param[in]      in      Input
+@param[out]     out     Output
+@param[in,out]  shit    Well, that's messy
+*/
+constexpr void bar(int in, int& out, void* shit) noexcept;
+
+/**
+@brief Function
+@return With just return value docs should still have detailed section
+*/
+int justReturn();
+
+}
+
+namespace Eno {
+
+/** @brief Boolean */
+enum Boolean {
+    True = 7,           /**< True. */
+    False,              /**< False? */
+    FileNotFound = -1   /**< Haha. */
+};
+
+enum {
+    /** Value of an anonymous enum */
+    Value = 34
+};
+
+}
+
+namespace Type {
+
+/**
+@brief A templated type with just template details
+@tparam T Template param
+*/
+template<class T, typename = void> using Foo = Bar<T, int>;
+
+/**
+@brief Another typedef
+
+Details.
+*/
+typedef Me Ugly;
+
+/**
+@brief Function pointer typedef
+
+Huh.
+*/
+typedef void(*Func)(int, std::string&);
+
+}
+
+namespace Var {
+
+/**
+@brief A value
+
+Details.
+*/
+constexpr const int a = 25;
+
+}
+
+namespace Warning {
+
+/** @brief Use the brief! */
+enum Enum {
+    /** @brief Don't use the brief! */
+    Warn
+};
+
+/**
+@brief Wrong
+@param wrong This parameter is not here
+*/
+void bar();
+
+}
+
+/**
+@brief A define
+
+Details.
+*/
+#define A_DEFINE
+
+/**
+@brief A macro
+@return Hahah. Nothing.
+*/
+#define A_MACRO()
+
+/**
+@brief Macro with parameters
+@param foo Foo to bar
+@param bar Bar to foo
+
+Details? No.
+*/
+#define MACRO(foo, bar)
diff --git a/doxygen/test/compound_detailed/File_8h.html b/doxygen/test/compound_detailed/File_8h.html
new file mode 100644 (file)
index 0000000..5870b7d
--- /dev/null
@@ -0,0 +1,161 @@
+<!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="#namespaces">Namespaces</a></li>
+                <li><a href="#nested-classes">Classes</a></li>
+                <li><a href="#defines">Defines</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="namespaces">
+          <h2><a href="#namespaces">Namespaces</a></h3>
+          <dl class="m-dox">
+            <dt>namespace <a href="namespaceNamee.html" class="m-dox">Namee</a></dt>
+            <dd>Namespace docs.</dd>
+          </dl>
+        </section>
+        <section id="nested-classes">
+          <h2><a href="#nested-classes">Classes</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <div class="m-dox-template">template&lt;class T, class U = void, class = int&gt;</div>
+              struct <a href="structTemplate.html" class="m-dox">Template</a>
+            </dt>
+            <dd>Class with template parameters.</dd>
+            <dt>
+              <div class="m-dox-template">template&lt;&gt;</div>
+              struct <a href="structTemplate_3_01void_01_4.html" class="m-dox">Template&lt;void&gt;</a>
+            </dt>
+            <dd>Specialized class template.</dd>
+            <dt>
+              <div class="m-dox-template">template&lt;class T&gt;</div>
+              struct <a href="structTemplateWarning.html" class="m-dox">TemplateWarning</a>
+            </dt>
+            <dd>Class with wrong template parameter description.</dd>
+          </dl>
+        </section>
+        <section id="define-members">
+          <h2><a href="#define-members">Defines</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">#define <a href="#a144a2a84c08d05de76f6a4a245584810" class="m-dox">A_DEFINE</a></span>
+            </dt>
+            <dd>A define.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">#define <a href="#ac93121ddaf1925d97ab2673f6151b062" class="m-dox">A_MACRO</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>A macro.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">#define <a href="#acf406f8979f9a2831e9efebfd8606833" class="m-dox">MACRO</a>(</span><span class="m-dox-wrap">foo,
+              bar)</span>
+            </dt>
+            <dd>Macro with parameters.</dd>
+          </dl>
+        </section>
+        <section>
+          <h2>Define documentation</h2>
+          <section class="m-dox-details" id="a144a2a84c08d05de76f6a4a245584810"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">#define <a href="#a144a2a84c08d05de76f6a4a245584810" class="m-dox-self">A_DEFINE</a></span>
+            </h3>
+            <p>A define.</p>
+<p>Details.</p>
+          </div></section>
+          <section class="m-dox-details" id="ac93121ddaf1925d97ab2673f6151b062"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">#define <a href="#ac93121ddaf1925d97ab2673f6151b062" class="m-dox-self">A_MACRO</a>(</span><span class="m-dox-wrap">)</span>
+            </h3>
+            <p>A macro.</p>
+            <table class="m-table m-fullwidth m-flat">
+              <tfoot>
+                <tr>
+                  <th style="width: 1%">Returns</th>
+                  <td>Hahah. Nothing.</td>
+                </tr>
+              </tfoot>
+            </table>
+
+          </div></section>
+          <section class="m-dox-details" id="acf406f8979f9a2831e9efebfd8606833"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">#define <a href="#acf406f8979f9a2831e9efebfd8606833" class="m-dox-self">MACRO</a>(</span><span class="m-dox-wrap">foo,
+              bar)</span>
+            </h3>
+            <p>Macro with parameters.</p>
+            <table class="m-table m-fullwidth m-flat">
+              <thead>
+                <tr><th colspan="2">Parameters</th></tr>
+              </thead>
+              <tbody>
+                <tr>
+                  <td style="width: 1%">foo</td>
+                  <td>Foo to bar</td>
+                </tr>
+                <tr>
+                  <td>bar</td>
+                  <td>Bar to foo</td>
+                </tr>
+              </tbody>
+            </table>
+<p>Details? No.</p>
+          </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_detailed/namespaceEno.html b/doxygen/test/compound_detailed/namespaceEno.html
new file mode 100644 (file)
index 0000000..fa5cfa7
--- /dev/null
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Eno namespace | 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" id="m-navbar-current">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>Eno <span class="m-thin">namespace</span></h1>
+        <section id="enum-members">
+          <h2><a href="#enum-members">Enums</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">enum <a href="#a4c1723bb8d7d27b0cbbdaba791556cf4" class="m-dox">Boolean</a> { </span><span class="m-dox-wrap"><a href="#a4c1723bb8d7d27b0cbbdaba791556cf4a0af19db6c4f528b65608a4f7e1e20f60" class="m-dox">True</a> = 7,
+              <a href="#a4c1723bb8d7d27b0cbbdaba791556cf4a1de42a0ec8f62f2b3f9382569e5c596e" class="m-dox">False</a>,
+              <a href="#a4c1723bb8d7d27b0cbbdaba791556cf4aa715872c5cfc5f1d4b1f1c2d68ceaccd" class="m-dox">FileNotFound</a> = -1 }</span>
+            </dt>
+            <dd>Boolean.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">enum <a href="#a007babfcd4198ed69f112505ae96f065" class="m-dox">(anonymous)</a> { </span><span class="m-dox-wrap"><a href="#a007babfcd4198ed69f112505ae96f065afaa3d046ec30de86846ea5bf0c875cb8" class="m-dox">Value</a> = 34 }</span>
+            </dt>
+            <dd></dd>
+          </dl>
+        </section>
+        <section>
+          <h2>Enum documentation</h2>
+          <section class="m-dox-details" id="a4c1723bb8d7d27b0cbbdaba791556cf4"><div>
+            <h3>
+              enum Eno::<wbr/><a href="#a4c1723bb8d7d27b0cbbdaba791556cf4" class="m-dox-self">Boolean</a>
+            </h3>
+            <p>Boolean.</p>
+            <table class="m-table m-fullwidth m-flat m-dox">
+              <thead><tr><th style="width: 1%">Enumerators</th><th></th></tr></thead>
+              <tbody>
+                <tr>
+                  <td><a href="#a4c1723bb8d7d27b0cbbdaba791556cf4a0af19db6c4f528b65608a4f7e1e20f60" class="m-dox-self" name="a4c1723bb8d7d27b0cbbdaba791556cf4a0af19db6c4f528b65608a4f7e1e20f60">True</a></td>
+                  <td>
+<p>True.</p>
+                  </td>
+                </tr>
+                <tr>
+                  <td><a href="#a4c1723bb8d7d27b0cbbdaba791556cf4a1de42a0ec8f62f2b3f9382569e5c596e" class="m-dox-self" name="a4c1723bb8d7d27b0cbbdaba791556cf4a1de42a0ec8f62f2b3f9382569e5c596e">False</a></td>
+                  <td>
+<p>False?</p>
+                  </td>
+                </tr>
+                <tr>
+                  <td><a href="#a4c1723bb8d7d27b0cbbdaba791556cf4aa715872c5cfc5f1d4b1f1c2d68ceaccd" class="m-dox-self" name="a4c1723bb8d7d27b0cbbdaba791556cf4aa715872c5cfc5f1d4b1f1c2d68ceaccd">FileNotFound</a></td>
+                  <td>
+<p>Haha.</p>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+          </div></section>
+          <section class="m-dox-details" id="a007babfcd4198ed69f112505ae96f065"><div>
+            <h3>
+              enum Eno::<wbr/><a href="#a007babfcd4198ed69f112505ae96f065" class="m-dox-self">(anonymous)</a>
+            </h3>
+            <table class="m-table m-fullwidth m-flat m-dox">
+              <thead><tr><th style="width: 1%">Enumerators</th><th></th></tr></thead>
+              <tbody>
+                <tr>
+                  <td><a href="#a007babfcd4198ed69f112505ae96f065afaa3d046ec30de86846ea5bf0c875cb8" class="m-dox-self" name="a007babfcd4198ed69f112505ae96f065afaa3d046ec30de86846ea5bf0c875cb8">Value</a></td>
+                  <td>
+<p>Value of an anonymous enum</p>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+          </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_detailed/namespaceFoo.html b/doxygen/test/compound_detailed/namespaceFoo.html
new file mode 100644 (file)
index 0000000..dae3234
--- /dev/null
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Foo namespace | 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" id="m-navbar-current">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>Foo <span class="m-thin">namespace</span></h1>
+        <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>
+              <div class="m-dox-template">template&lt;class T&gt;</div>
+              <span class="m-dox-wrap-bumper">auto <a href="#ae88691fe7f08f83578b05daa67e78887" class="m-dox">foo</a>(</span><span class="m-dox-wrap">int a,
+              std::string b,
+              char(&amp;things)[5],
+              bool,
+              char(&amp;)[42]) -&gt; int</span>
+            </dt>
+            <dd>Function with <em>everything</em></dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a256688820e6f5564e3210874bbda84c3" class="m-dox">bar</a>(</span><span class="m-dox-wrap">int in,
+              int&amp; out,
+              void* shit) <span class="m-label m-flat m-primary">constexpr</span> <span class="m-label m-flat m-success">noexcept</span></span>
+            </dt>
+            <dd>Input and output.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">auto <a href="#ada6488b07291f349307778cc7bb3547d" class="m-dox">justReturn</a>(</span><span class="m-dox-wrap">) -&gt; int</span>
+            </dt>
+            <dd>Function.</dd>
+          </dl>
+        </section>
+        <section>
+          <h2>Function documentation</h2>
+          <section class="m-dox-details" id="ae88691fe7f08f83578b05daa67e78887"><div>
+            <h3>
+              <div class="m-dox-template">
+                template&lt;class T&gt;
+              </div>
+              <span class="m-dox-wrap-bumper">int Foo::<wbr/></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#ae88691fe7f08f83578b05daa67e78887" class="m-dox-self">foo</a>(</span><span class="m-dox-wrap">int a,
+              std::string b,
+              char(&amp;things)[5],
+              bool,
+              char(&amp;)[42])</span></span>
+            </h3>
+            <p>Function with <em>everything</em></p>
+            <table class="m-table m-fullwidth m-flat">
+              <thead>
+                <tr><th colspan="2">Template parameters</th></tr>
+              </thead>
+              <tbody>
+                <tr>
+                  <td style="width: 1%">T</td>
+                  <td>A template, innit</td>
+                </tr>
+              </tbody>
+              <thead>
+                <tr><th colspan="2">Parameters</th></tr>
+              </thead>
+              <tbody>
+                <tr>
+                  <td>a</td>
+                  <td>That&#x27;s a for you</td>
+                </tr>
+                <tr>
+                  <td>b</td>
+                  <td>Well, a string</td>
+                </tr>
+                <tr>
+                  <td>things</td>
+                  <td>And an array!</td>
+                </tr>
+              </tbody>
+              <tfoot>
+                <tr>
+                  <th>Returns</th>
+                  <td>It returns!</td>
+                </tr>
+              </tfoot>
+            </table>
+<p>Ooooh, more text!</p>
+          </div></section>
+          <section class="m-dox-details" id="a256688820e6f5564e3210874bbda84c3"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">void Foo::<wbr/></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#a256688820e6f5564e3210874bbda84c3" class="m-dox-self">bar</a>(</span><span class="m-dox-wrap">int in,
+              int&amp; out,
+              void* shit) <span class="m-label m-primary">constexpr</span> <span class="m-label m-success">noexcept</span></span></span>
+            </h3>
+            <p>Input and output.</p>
+            <table class="m-table m-fullwidth m-flat">
+              <thead>
+                <tr><th colspan="2">Parameters</th></tr>
+              </thead>
+              <tbody>
+                <tr>
+                  <td style="width: 1%">in&nbsp;<span class="m-label m-flat m-info">in</span></td>
+                  <td>Input</td>
+                </tr>
+                <tr>
+                  <td>out&nbsp;<span class="m-label m-flat m-warning">out</span></td>
+                  <td>Output</td>
+                </tr>
+                <tr>
+                  <td>shit&nbsp;<span class="m-label m-flat m-danger">in/out</span></td>
+                  <td>Well, that&#x27;s messy</td>
+                </tr>
+              </tbody>
+            </table>
+          </div></section>
+          <section class="m-dox-details" id="ada6488b07291f349307778cc7bb3547d"><div>
+            <h3>
+              <span class="m-dox-wrap-bumper">int Foo::<wbr/></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#ada6488b07291f349307778cc7bb3547d" class="m-dox-self">justReturn</a>(</span><span class="m-dox-wrap">)</span></span>
+            </h3>
+            <p>Function.</p>
+            <table class="m-table m-fullwidth m-flat">
+              <tfoot>
+                <tr>
+                  <th style="width: 1%">Returns</th>
+                  <td>With just return value docs should still have detailed section</td>
+                </tr>
+              </tfoot>
+            </table>
+          </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_detailed/namespaceNamee.html b/doxygen/test/compound_detailed/namespaceNamee.html
new file mode 100644 (file)
index 0000000..02125b7
--- /dev/null
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Namee namespace | 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" id="m-navbar-current">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>Namee <span class="m-thin">namespace</span></h1>
+        <p>Namespace docs.</p>
+<p>And we have some detailed docs as well.</p>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_detailed/namespaceType.html b/doxygen/test/compound_detailed/namespaceType.html
new file mode 100644 (file)
index 0000000..6a61e4e
--- /dev/null
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Type namespace | 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" id="m-navbar-current">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>Type <span class="m-thin">namespace</span></h1>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#typedef-members">Typedefs</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="typedef-members">
+          <h2><a href="#typedef-members">Typedefs</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <div class="m-dox-template">template&lt;class T, typename = void&gt;</div>
+              using <a href="#a9d12414d1c73eed4c413440b95cca46b" class="m-dox">Foo</a> = Bar&lt;T, int&gt;
+            </dt>
+            <dd>A templated type with just template details.</dd>
+            <dt>
+              using <a href="#a60126d739e81aaae3b1222f38582b9fe" class="m-dox">Ugly</a> = Me
+            </dt>
+            <dd>Another typedef.</dd>
+            <dt>
+              using <a href="#ac861cffee5a0381b9404bf23a3d788de" class="m-dox">Func</a> = void(*)(int, std::string&amp;)
+            </dt>
+            <dd>Function pointer typedef.</dd>
+          </dl>
+        </section>
+        <section>
+          <h2>Typedef documentation</h2>
+          <section class="m-dox-details" id="a9d12414d1c73eed4c413440b95cca46b"><div>
+            <h3>
+              <div class="m-dox-template">
+                template&lt;class T, typename = void&gt;
+              </div>
+              using Type::<wbr/><a href="#a9d12414d1c73eed4c413440b95cca46b" class="m-dox-self">Foo</a> = Bar&lt;T, int&gt;
+            </h3>
+            <p>A templated type with just template details.</p>
+            <table class="m-table m-fullwidth m-flat">
+              <thead>
+                <tr><th colspan="2">Template parameters</th></tr>
+              </thead>
+              <tbody>
+                <tr>
+                  <td style="width: 1%">T</td>
+                  <td>Template param</td>
+                </tr>
+              </tbody>
+            </table>
+          </div></section>
+          <section class="m-dox-details" id="a60126d739e81aaae3b1222f38582b9fe"><div>
+            <h3>
+              typedef Me Type::<wbr/><a href="#a60126d739e81aaae3b1222f38582b9fe" class="m-dox-self">Ugly</a>
+            </h3>
+            <p>Another typedef.</p>
+<p>Details.</p>
+          </div></section>
+          <section class="m-dox-details" id="ac861cffee5a0381b9404bf23a3d788de"><div>
+            <h3>
+              typedef void(*Type::<wbr/><a href="#ac861cffee5a0381b9404bf23a3d788de" class="m-dox-self">Func</a>)(int, std::string&amp;)
+            </h3>
+            <p>Function pointer typedef.</p>
+<p>Huh.</p>
+          </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_detailed/namespaceVar.html b/doxygen/test/compound_detailed/namespaceVar.html
new file mode 100644 (file)
index 0000000..e2afe5a
--- /dev/null
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Var namespace | 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" id="m-navbar-current">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>Var <span class="m-thin">namespace</span></h1>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#var-members">Variables</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="var-members">
+          <h2><a href="#var-members">Variables</a></h3>
+          <dl class="m-dox">
+            <dt>const int <a href="#a4f9fd9cff960aeecffcab6a5d2ffcd81" class="m-dox">a</a> <span class="m-label m-flat m-primary">constexpr</span></dt>
+            <dd>A value.</dd>
+          </dl>
+        </section>
+        <section>
+          <h2>Variable documentation</h2>
+          <section class="m-dox-details" id="a4f9fd9cff960aeecffcab6a5d2ffcd81"><div>
+            <h3>
+              const int Var::<wbr/><a href="#a4f9fd9cff960aeecffcab6a5d2ffcd81" class="m-dox-self">a</a> <span class="m-label m-primary">constexpr</span>
+            </h3>
+            <p>A value.</p>
+<p>Details.</p>
+          </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_detailed/namespaceWarning.html b/doxygen/test/compound_detailed/namespaceWarning.html
new file mode 100644 (file)
index 0000000..93b73cc
--- /dev/null
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Warning namespace | 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" id="m-navbar-current">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>Warning <span class="m-thin">namespace</span></h1>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#enum-members">Enums</a></li>
+                <li><a href="#func-members">Functions</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="enum-members">
+          <h2><a href="#enum-members">Enums</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">enum <a href="#a6e48c63bc575702198dfcc3501fc8bb8" class="m-dox-self" name="a6e48c63bc575702198dfcc3501fc8bb8">Enum</a> { </span><span class="m-dox-wrap"><a href="#a6e48c63bc575702198dfcc3501fc8bb8a63997f6aebd31d3b13d6bbb51c87c4f0" class="m-dox">Warn</a> }</span>
+            </dt>
+            <dd>Use the brief!</dd>
+          </dl>
+        </section>
+        <section id="func-members">
+          <h2><a href="#func-members">Functions</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a084dfc535219dee446df1c710e215839" class="m-dox-self" name="a084dfc535219dee446df1c710e215839">bar</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>Wrong.</dd>
+          </dl>
+        </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_detailed/structTemplate.html b/doxygen/test/compound_detailed/structTemplate.html
new file mode 100644 (file)
index 0000000..397501e
--- /dev/null
@@ -0,0 +1,226 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Template struct | 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" id="m-navbar-current">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>
+          <div class="m-dox-template">template&lt;class T, class U = void, class = int&gt;</div>
+          Template <span class="m-thin">struct</span>
+        </h1>
+        <p>Class with template parameters.</p>
+        <table class="m-table m-fullwidth m-flat">
+          <thead>
+            <tr><th colspan="2">Template parameters</th></tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td style="width: 1%">T</td>
+              <td>Template parameter T</td>
+            </tr>
+            <tr>
+              <td>U</td>
+              <td>Template parameter U</td>
+            </tr>
+          </tbody>
+        </table>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#pub-methods">Public functions</a></li>
+                <li><a href="#pro-types">Protected types</a></li>
+                <li><a href="#pro-methods">Protected functions</a></li>
+                <li><a href="#pro-attribs">Protected variables</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+<p>Should have it displayed on top.</p>
+        <section id="pub-methods">
+          <h2><a href="#pub-methods">Public functions</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#af51f2282e44f51eea57a198c123f8b16" class="m-dox">bar</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>Another.</dd>
+          </dl>
+        </section>
+        <section id="pro-types">
+          <h2><a href="#pro-types">Protected types</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">enum class <a href="#a78bd618022079b3efbf1db104e058c8a" class="m-dox">Bar</a> { </span><span class="m-dox-wrap"> }</span>
+            </dt>
+            <dd>Enum.</dd>
+            <dt>
+              using <a href="#a661cbea16b59544c9907189d8ccf6da5" class="m-dox">B</a> = A
+            </dt>
+            <dd>Typedef.</dd>
+            <dt>
+              <div class="m-dox-template">template&lt;class V, bool = false&gt;</div>
+              using <a href="#a6b37f78f11b281740b9daf07f695c0fa" class="m-dox">Foo</a> = Buuu&lt;V, false&gt;
+            </dt>
+            <dd>Template alias.</dd>
+          </dl>
+        </section>
+        <section id="pro-methods">
+          <h2><a href="#pro-methods">Protected functions</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <div class="m-dox-template">template&lt;class V, int = 3&gt;</div>
+              <span class="m-dox-wrap-bumper">void <a href="#aab8b2a12ab389309990a2f3d7ae0289e" class="m-dox">foo</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>Function.</dd>
+          </dl>
+        </section>
+        <section id="pro-attribs">
+          <h2><a href="#pro-attribs">Protected variables</a></h3>
+          <dl class="m-dox">
+            <dt>int <a href="#aaf7ee941db121bdf57653fe4bd8f3f53" class="m-dox">a</a></dt>
+            <dd>Variable.</dd>
+          </dl>
+        </section>
+        <section>
+          <h2>Enum documentation</h2>
+          <section class="m-dox-details" id="a78bd618022079b3efbf1db104e058c8a"><div>
+            <h3>
+              <div class="m-dox-template">
+                template&lt;class T, class U, class _3&gt;
+              </div>
+              enum class Template&lt;T, U, _3&gt;::<wbr/><a href="#a78bd618022079b3efbf1db104e058c8a" class="m-dox-self">Bar</a> <span class="m-label m-warning">protected</span>
+            </h3>
+            <p>Enum.</p>
+<p>Should have just one template with _3 for unnamed parameter. Should also have the <code>protected</code> label in the details.</p>
+          </div></section>
+        </section>
+        <section>
+          <h2>Typedef documentation</h2>
+          <section class="m-dox-details" id="a661cbea16b59544c9907189d8ccf6da5"><div>
+            <h3>
+              <div class="m-dox-template">
+                template&lt;class T, class U, class _3&gt;
+              </div>
+              typedef A Template&lt;T, U, _3&gt;::<wbr/><a href="#a661cbea16b59544c9907189d8ccf6da5" class="m-dox-self">B</a> <span class="m-label m-warning">protected</span>
+            </h3>
+            <p>Typedef.</p>
+<p>Should have just one template with _3 for unnamed parameter. Should also have the <code>protected</code> label in the details.</p>
+          </div></section>
+          <section class="m-dox-details" id="a6b37f78f11b281740b9daf07f695c0fa"><div>
+            <h3>
+              <div class="m-dox-template">
+                template&lt;class T, class U, class _3&gt;
+                template&lt;class V, bool = false&gt;
+              </div>
+              using Template&lt;T, U, _3&gt;::<wbr/><a href="#a6b37f78f11b281740b9daf07f695c0fa" class="m-dox-self">Foo</a> = Buuu&lt;V, false&gt; <span class="m-label m-warning">protected</span>
+            </h3>
+            <p>Template alias.</p>
+            <table class="m-table m-fullwidth m-flat">
+              <thead>
+                <tr><th colspan="2">Template parameters</th></tr>
+              </thead>
+              <tbody>
+                <tr>
+                  <td style="width: 1%">V</td>
+                  <td>Well, this is V as well</td>
+                </tr>
+              </tbody>
+            </table>
+<p>Should include both template lists, with _3 for unnamed parameter. Should also have the <code>protected</code> label in the details.</p>
+          </div></section>
+        </section>
+        <section>
+          <h2>Function documentation</h2>
+          <section class="m-dox-details" id="af51f2282e44f51eea57a198c123f8b16"><div>
+            <h3>
+              <div class="m-dox-template">
+                template&lt;class T, class U, class _3&gt;
+              </div>
+              <span class="m-dox-wrap-bumper">void Template&lt;T, U, _3&gt;::<wbr/></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#af51f2282e44f51eea57a198c123f8b16" class="m-dox-self">bar</a>(</span><span class="m-dox-wrap">)</span></span>
+            </h3>
+            <p>Another.</p>
+<p>Should have just one template with _3 for unnamed parameter.</p>
+          </div></section>
+          <section class="m-dox-details" id="aab8b2a12ab389309990a2f3d7ae0289e"><div>
+            <h3>
+              <div class="m-dox-template">
+                template&lt;class T, class U, class _3&gt;
+                template&lt;class V, int = 3&gt;
+              </div>
+              <span class="m-dox-wrap-bumper">void Template&lt;T, U, _3&gt;::<wbr/></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#aab8b2a12ab389309990a2f3d7ae0289e" class="m-dox-self">foo</a>(</span><span class="m-dox-wrap">) <span class="m-label m-warning">protected</span></span></span>
+            </h3>
+            <p>Function.</p>
+            <table class="m-table m-fullwidth m-flat">
+              <thead>
+                <tr><th colspan="2">Template parameters</th></tr>
+              </thead>
+              <tbody>
+                <tr>
+                  <td style="width: 1%">V</td>
+                  <td>Well, this is V</td>
+                </tr>
+              </tbody>
+            </table>
+<p>Should not repeat default parameter from class, should include both U and V in the docs. Should also have the <code>protected</code> label in the details.</p>
+          </div></section>
+        </section>
+        <section>
+          <h2>Variable documentation</h2>
+          <section class="m-dox-details" id="aaf7ee941db121bdf57653fe4bd8f3f53"><div>
+            <h3>
+              <div class="m-dox-template">
+                template&lt;class T, class U, class _3&gt;
+              </div>
+              int Template&lt;T, U, _3&gt;::<wbr/><a href="#aaf7ee941db121bdf57653fe4bd8f3f53" class="m-dox-self">a</a> <span class="m-label m-warning">protected</span>
+            </h3>
+            <p>Variable.</p>
+<p>Should have just one template with _3 for unnamed parameter. Should also have the <code>protected</code> label in the details.</p>
+          </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_detailed/structTemplateWarning.html b/doxygen/test/compound_detailed/structTemplateWarning.html
new file mode 100644 (file)
index 0000000..6194a1c
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>TemplateWarning struct | 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" id="m-navbar-current">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>
+          <div class="m-dox-template">template&lt;class T&gt;</div>
+          TemplateWarning <span class="m-thin">struct</span>
+        </h1>
+        <p>Class with wrong template parameter description.</p>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_detailed/structTemplate_3_01void_01_4.html b/doxygen/test/compound_detailed/structTemplate_3_01void_01_4.html
new file mode 100644 (file)
index 0000000..4d3f799
--- /dev/null
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Template&lt;void&gt; struct | 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" id="m-navbar-current">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>
+          <div class="m-dox-template">template&lt;&gt;</div>
+          Template&lt;void&gt; <span class="m-thin">struct</span>
+        </h1>
+        <p>Specialized class template.</p>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#pub-methods">Public functions</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+<p>Should have <code>template&lt;&gt;</code> displayed on top.</p>
+        <section id="pub-methods">
+          <h2><a href="#pub-methods">Public functions</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <div class="m-dox-template">template&lt;int b&gt;</div>
+              <span class="m-dox-wrap-bumper">void <a href="#a655f7a260f538edc42775e74c6a3d2d3" class="m-dox">baz</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>Function.</dd>
+          </dl>
+        </section>
+        <section>
+          <h2>Function documentation</h2>
+          <section class="m-dox-details" id="a655f7a260f538edc42775e74c6a3d2d3"><div>
+            <h3>
+              <div class="m-dox-template">
+                template&lt;&gt;
+                template&lt;int b&gt;
+              </div>
+              <span class="m-dox-wrap-bumper">void Template&lt;void&gt;::<wbr/></span><span class="m-dox-wrap"><span class="m-dox-wrap-bumper"><a href="#a655f7a260f538edc42775e74c6a3d2d3" class="m-dox-self">baz</a>(</span><span class="m-dox-wrap">)</span></span>
+            </h3>
+            <p>Function.</p>
+<p>Should still have both templates repeated.</p>
+          </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/Another/Some.h b/doxygen/test/compound_listing/Another/Some.h
new file mode 100644 (file)
index 0000000..c0ccb9a
--- /dev/null
@@ -0,0 +1,5 @@
+/** @file
+ * @brief Some file
+ */
+
+namespace Some {}
diff --git a/doxygen/test/compound_listing/Class_8h.html b/doxygen/test/compound_listing/Class_8h.html
new file mode 100644 (file)
index 0000000..b81e1cd
--- /dev/null
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Directory/Sub/Class.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>
+          <span class="m-breadcrumb"><a href="dir_4b0d5f8864bf89936129251a2d32609b.html">Directory</a>/</span><span class="m-breadcrumb"><a href="dir_bbe5918fe090eee9db2d9952314b6754.html">Sub</a>/</span>Class.h <span class="m-thin">file</span>
+        </h1>
+        <p>File in a subdirectory.</p>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#namespaces">Namespaces</a></li>
+                <li><a href="#nested-classes">Classes</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="namespaces">
+          <h2><a href="#namespaces">Namespaces</a></h3>
+          <dl class="m-dox">
+            <dt>namespace <a href="namespaceRoot.html" class="m-dox">Root</a></dt>
+            <dd>Root namespace.</dd>
+            <dt>namespace <a href="namespaceRoot_1_1Directory.html" class="m-dox">Root::Directory</a></dt>
+            <dd>Namespace in directory.</dd>
+            <dt>namespace <a href="namespaceRoot_1_1Directory_1_1Sub.html" class="m-dox">Root::Directory::Sub</a></dt>
+            <dd>Namespace in subdirectory.</dd>
+          </dl>
+        </section>
+        <section id="nested-classes">
+          <h2><a href="#nested-classes">Classes</a></h3>
+          <dl class="m-dox">
+            <dt>
+              class <a href="classRoot_1_1Directory_1_1Sub_1_1Class.html" class="m-dox">Root::Directory::Sub::Class</a>
+            </dt>
+            <dd>A class.</dd>
+            <dt>
+              struct <a href="structRoot_1_1Directory_1_1Sub_1_1Class_1_1Foo.html" class="m-dox">Root::Directory::Sub::Class::Foo</a>
+            </dt>
+            <dd>A public subclass.</dd>
+            <dt>
+              <div class="m-dox-template">template&lt;class T, class U = void&gt;</div>
+              union <a href="unionRoot_1_1Directory_1_1Sub_1_1Class_1_1Bar.html" class="m-dox">Root::Directory::Sub::Class::Bar</a>
+            </dt>
+            <dd>A protected subclass.</dd>
+          </dl>
+        </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/Directory/File.h b/doxygen/test/compound_listing/Directory/File.h
new file mode 100644 (file)
index 0000000..bdbbadb
--- /dev/null
@@ -0,0 +1,53 @@
+/** @file
+ * @brief File in directory
+ */
+
+namespace Root { namespace Directory {
+
+/** @brief A class */
+class Class {};
+
+/** @brief A structure */
+struct Struct {};
+
+/** @brief An union */
+union Union {};
+
+/** @brief An enum */
+enum class Enum: int {};
+
+/** @brief A typedef */
+typedef int Int;
+
+/** @brief An using declaration */
+using Float = float;
+
+/** @brief A variable */
+constexpr const int Var = 3;
+
+/** @brief A function */
+void foo();
+
+/** @{ @name A group */
+
+/** @brief Flag in a group */
+enum class Flag {};
+
+/** @brief Alias in a group */
+using Main = void;
+
+/** @brief Function in a group */
+void bar();
+
+/** @brief Variable in a group */
+constexpr void* variable = nullptr;
+
+/** @brief A define in a group */
+#define A_DEFINE_IN_A_GROUP
+
+/*@}*/
+
+}}
+
+/** @brief A define */
+#define A_DEFINE
diff --git a/doxygen/test/compound_listing/Directory/Sub/Class.h b/doxygen/test/compound_listing/Directory/Sub/Class.h
new file mode 100644 (file)
index 0000000..e91c2ed
--- /dev/null
@@ -0,0 +1,151 @@
+/** @file
+ * @brief File in a subdirectory
+ */
+
+namespace Root { namespace Directory { namespace Sub {
+
+/**
+@brief A class
+
+@section Class-section A section
+
+Text.
+
+@subsection Class-sub-section Subsection
+
+@subsection Class-sub-section2 Subsection 2
+
+@subsubsection Class-sub-section3 Subsection 3
+
+@section Class-section2 Section 2
+
+*/
+class Class {
+    public:
+        /** @brief A public subclass */
+        struct Foo {};
+
+        /** @brief A public typedef */
+        typedef void(*Deleter)(int, void*);
+
+        /** @brief A enum value */
+        enum E: int { FooBar = 3 };
+
+        /** @brief A public static var */
+        constexpr static int Size = 0;
+
+        /** @brief A public static function */
+        static void damage();
+
+        /** @brief A constructor without parameter names */
+        constexpr explicit Class(int, void*) noexcept;
+
+        /** @brief Deleted copy */
+        Class(Class&) = delete;
+
+        /** @brief Defaulted move */
+        Class& operator=(Class&&) = default;
+
+        /** @brief A conversion operator that works only on && */
+        explicit operator bool() const &&;
+
+        /** @brief A public variable */
+        std::string debug;
+
+        /** @{ @name Group with only undocumented functions should not appear in the docs */
+
+        void undocumented();
+
+        /*@}*/
+
+    protected:
+        /** @brief A protected subclass */
+        template<class T, class U = void> union Bar {};
+
+        /** @brief A protected alias */
+        using Type = double;
+
+        /** @brief Protected enum */
+        enum class Boolean {
+            True, False, FileNotFound
+        };
+
+        /** @brief A protected static var */
+        static bool False;
+
+        /** @brief A protected static function */
+        static void repair();
+
+        /** @brief A protected pure virtual destructor */
+        virtual ~Class() = 0;
+
+        /** @brief Protected function */
+        constexpr int fetchMeSomeIntegers() const;
+
+        /** @brief A protected variable */
+        std::string logger;
+
+        /** @{ @name Group full of non-public stuff which should be marked as such */
+
+        /** @brief Protected flag in a group */
+        enum class Flag {};
+
+        /** @brief Protected alias in a group */
+        using Main = void;
+
+        /** @brief Protected function in a group */
+        void foo() const &;
+
+        /** @brief Protected variable in a group */
+        void* variable;
+
+    private:
+        /** @brief Private virtual function in a group */
+        virtual int doStuff() = 0;
+
+        /*@}*/
+
+        /** @brief This shouldn't appear in the docs */
+        class Private {};
+
+        /** @brief A documented private virtual function */
+        virtual int doSomething() const;
+
+        /* Undocumented private virtual function shouldn't appear in the docs */
+        virtual int boom() = 0;
+
+        /** @brief This shouldn't appear in the docs */
+        void foobar();
+};
+
+/** @relatedalso Class
+ * @brief An enum
+ */
+enum class Enum: int {};
+
+/** @relatedalso Class
+ * @brief A typedef
+ */
+typedef int Int;
+
+/** @relatedalso Class
+ * @brief An using declaration
+ */
+using Float = float;
+
+/** @relatedalso Class
+ * @brief A variable
+ */
+constexpr const int Var = 3;
+
+/** @relatedalso Class
+ * @brief A function
+ */
+void foo();
+
+}}}
+
+/** @relatesalso Root::Directory::Sub::Class
+ * @brief A macro
+ */
+#define A_MACRO(foo) bar
diff --git a/doxygen/test/compound_listing/Doxyfile b/doxygen/test/compound_listing/Doxyfile
new file mode 100644 (file)
index 0000000..09aa151
--- /dev/null
@@ -0,0 +1,10 @@
+INPUT                   =
+FILE_PATTERNS           = *.h *.dox
+RECURSIVE               = YES
+AUTOLINK_SUPPORT        = NO
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
+
+M_FILE_TREE_EXPAND_LEVELS = 2
diff --git a/doxygen/test/compound_listing/File_8h.html b/doxygen/test/compound_listing/File_8h.html
new file mode 100644 (file)
index 0000000..bd32e51
--- /dev/null
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Directory/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>
+          <span class="m-breadcrumb"><a href="dir_4b0d5f8864bf89936129251a2d32609b.html">Directory</a>/</span>File.h <span class="m-thin">file</span>
+        </h1>
+        <p>File in directory.</p>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#namespaces">Namespaces</a></li>
+                <li><a href="#nested-classes">Classes</a></li>
+                <li><a href="#defines">Defines</a></li>
+                <li><a href="#a-group">A group</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="namespaces">
+          <h2><a href="#namespaces">Namespaces</a></h3>
+          <dl class="m-dox">
+            <dt>namespace <a href="namespaceRoot.html" class="m-dox">Root</a></dt>
+            <dd>Root namespace.</dd>
+            <dt>namespace <a href="namespaceRoot_1_1Directory.html" class="m-dox">Root::Directory</a></dt>
+            <dd>Namespace in directory.</dd>
+          </dl>
+        </section>
+        <section id="nested-classes">
+          <h2><a href="#nested-classes">Classes</a></h3>
+          <dl class="m-dox">
+            <dt>
+              class <a href="classRoot_1_1Directory_1_1Class.html" class="m-dox">Root::Directory::Class</a>
+            </dt>
+            <dd>A class.</dd>
+            <dt>
+              struct <a href="structRoot_1_1Directory_1_1Struct.html" class="m-dox">Root::Directory::Struct</a>
+            </dt>
+            <dd>A structure.</dd>
+            <dt>
+              union <a href="unionRoot_1_1Directory_1_1Union.html" class="m-dox">Root::Directory::Union</a>
+            </dt>
+            <dd>An union.</dd>
+          </dl>
+        </section>
+        <section id="define-members">
+          <h2><a href="#define-members">Defines</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">#define <a href="#a144a2a84c08d05de76f6a4a245584810" class="m-dox-self" name="a144a2a84c08d05de76f6a4a245584810">A_DEFINE</a></span>
+            </dt>
+            <dd>A define.</dd>
+          </dl>
+        </section>
+        <section id="a-group">
+          <h2><a href="#a-group">A group</a></h2>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">#define <a href="#ac8ab78e5a895bc0dfceb61c9b7707dbe" class="m-dox-self" name="ac8ab78e5a895bc0dfceb61c9b7707dbe">A_DEFINE_IN_A_GROUP</a></span>
+            </dt>
+            <dd>A define in a group.</dd>
+          </dl>
+        </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/Root.h b/doxygen/test/compound_listing/Root.h
new file mode 100644 (file)
index 0000000..cc70357
--- /dev/null
@@ -0,0 +1,3 @@
+/* Intentionally not documented */
+
+namespace Root {}
diff --git a/doxygen/test/compound_listing/TopLevelFile.h b/doxygen/test/compound_listing/TopLevelFile.h
new file mode 100644 (file)
index 0000000..7c1a2ca
--- /dev/null
@@ -0,0 +1,6 @@
+/** @file
+ * @brief Top-level file
+ */
+
+/** @brief Top-level class */
+class TopLevelClass {};
diff --git a/doxygen/test/compound_listing/annotated.html b/doxygen/test/compound_listing/annotated.html
new file mode 100644 (file)
index 0000000..7cd146a
--- /dev/null
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>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" id="m-navbar-current">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>Classes</h2>
+        <ul class="m-dox">
+          <li>namespace <a href="namespaceAnother.html" class="m-dox">Another</a> <span class="m-dox">Another namespace.</span></li>
+          <li class="m-dox-collapsible">
+            <a href="#" onclick="return toggle(this)">namespace</a> <a href="namespaceRoot.html" class="m-dox">Root</a> <span class="m-dox">Root namespace.</span>
+            <ul class="m-dox">
+              <li class="m-dox-collapsible collapsed">
+                <a href="#" onclick="return toggle(this)">namespace</a> <a href="namespaceRoot_1_1Directory.html" class="m-dox">Directory</a> <span class="m-dox">Namespace in directory.</span>
+                <ul class="m-dox">
+                  <li class="m-dox-collapsible collapsed">
+                    <a href="#" onclick="return toggle(this)">namespace</a> <a href="namespaceRoot_1_1Directory_1_1Sub.html" class="m-dox">Sub</a> <span class="m-dox">Namespace in subdirectory.</span>
+                    <ul class="m-dox">
+                      <li class="m-dox-collapsible collapsed">
+                        <a href="#" onclick="return toggle(this)">class</a> <a href="classRoot_1_1Directory_1_1Sub_1_1Class.html" class="m-dox">Class</a> <span class="m-dox">A class.</span>
+                        <ul class="m-dox">
+                          <li>union <a href="unionRoot_1_1Directory_1_1Sub_1_1Class_1_1Bar.html" class="m-dox">Bar</a> <span class="m-dox">A protected subclass.</span></li>
+                          <li>struct <a href="structRoot_1_1Directory_1_1Sub_1_1Class_1_1Foo.html" class="m-dox">Foo</a> <span class="m-dox">A public subclass.</span></li>
+                          <li>class <a href="classRoot_1_1Directory_1_1Sub_1_1Class_1_1Private.html" class="m-dox">Private</a> <span class="m-dox">This shouldn&#x27;t appear in the docs.</span></li>
+                        </ul>
+                      </li>
+                    </ul>
+                  </li>
+                  <li>class <a href="classRoot_1_1Directory_1_1Class.html" class="m-dox">Class</a> <span class="m-dox">A class.</span></li>
+                  <li>struct <a href="structRoot_1_1Directory_1_1Struct.html" class="m-dox">Struct</a> <span class="m-dox">A structure.</span></li>
+                  <li>union <a href="unionRoot_1_1Directory_1_1Union.html" class="m-dox">Union</a> <span class="m-dox">An union.</span></li>
+                </ul>
+              </li>
+            </ul>
+          </li>
+          <li>class <a href="classTopLevelClass.html" class="m-dox">TopLevelClass</a> <span class="m-dox">Top-level class.</span></li>
+        </ul>
+        <script>
+        function toggle(e) {
+            e.parentElement.className = e.parentElement.className == 'm-dox-collapsible' ?
+                'm-dox-expansible' : 'm-dox-collapsible';
+            return false;
+        }
+        /* Collapse all nodes marked as such. Doing it via JS instead of directly in
+           markup so disabling it doesn't harm usability. The list is somehow
+           regenerated on every iteration and shrinks as I change the classes. It's not
+           documented anywhere and I'm not sure if this is the same across browsers, so
+           I am going backwards in that list to be sure.  */
+        var collapsed = document.getElementsByClassName("collapsed");
+        for(var i = collapsed.length - 1; i >= 0; --i)
+            collapsed[i].className = 'm-dox-expansible';
+        </script>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/classRoot_1_1Directory_1_1Sub_1_1Class.html b/doxygen/test/compound_listing/classRoot_1_1Directory_1_1Sub_1_1Class.html
new file mode 100644 (file)
index 0000000..2926758
--- /dev/null
@@ -0,0 +1,275 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Root::Directory::Sub::Class class | 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" id="m-navbar-current">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>
+          <span class="m-breadcrumb"><a href="namespaceRoot.html">Root</a>::</span><span class="m-breadcrumb"><a href="namespaceRoot_1_1Directory.html">Directory</a>::</span><span class="m-breadcrumb"><a href="namespaceRoot_1_1Directory_1_1Sub.html">Sub</a>::</span>Class <span class="m-thin">class</span>
+        </h1>
+        <p>A class.</p>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              <a href="#Class-section">A section</a>
+              <ul>
+                <li><a href="#Class-sub-section">Subsection</a></li>
+                <li>
+                  <a href="#Class-sub-section2">Subsection 2</a>
+                  <ul>
+                    <li><a href="#Class-sub-section3">Subsection 3</a></li>
+                  </ul>
+                </li>
+              </ul>
+            </li>
+            <li><a href="#Class-section2">Section 2</a></li>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#pub-types">Public types</a></li>
+                <li><a href="#pub-static-attribs">Public static variables</a></li>
+                <li><a href="#pub-static-methods">Public static functions</a></li>
+                <li><a href="#typeless-methods">Constructors, destructors, conversion operators</a></li>
+                <li><a href="#pub-methods">Public functions</a></li>
+                <li><a href="#pub-attribs">Public variables</a></li>
+                <li><a href="#pro-types">Protected types</a></li>
+                <li><a href="#pro-static-methods">Protected static functions</a></li>
+                <li><a href="#pro-methods">Protected functions</a></li>
+                <li><a href="#pro-static-attribs">Protected static variables</a></li>
+                <li><a href="#pro-attribs">Protected variables</a></li>
+                <li><a href="#pri-methods">Private functions</a></li>
+                <li><a href="#group-full-of-non-public-stuff-which-should-be-marked-as-such">Group full of non-public stuff which should be marked as such</a></li>
+                <li><a href="#related">Related</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+<section id="Class-section"><h2><a href="#Class-section">A section</a></h2><p>Text.</p><section id="Class-sub-section"><h3><a href="#Class-sub-section">Subsection</a></h3></section><section id="Class-sub-section2"><h3><a href="#Class-sub-section2">Subsection 2</a></h3><section id="Class-sub-section3"><h4><a href="#Class-sub-section3">Subsection 3</a></h4></section></section></section><section id="Class-section2"><h2><a href="#Class-section2">Section 2</a></h2></section>
+        <section id="pub-types">
+          <h2><a href="#pub-types">Public types</a></h3>
+          <dl class="m-dox">
+            <dt>
+              struct <a href="structRoot_1_1Directory_1_1Sub_1_1Class_1_1Foo.html" class="m-dox">Foo</a>
+            </dt>
+            <dd>A public subclass.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">enum <a href="#a691ffcb6faf21c021ded037101d5414f" class="m-dox-self" name="a691ffcb6faf21c021ded037101d5414f">E</a>: int { </span><span class="m-dox-wrap"><a href="#a691ffcb6faf21c021ded037101d5414fab40890227c995cba62c5ba928fa05797" class="m-dox">FooBar</a> = 3 }</span>
+            </dt>
+            <dd>A enum value.</dd>
+            <dt>
+              using <a href="#af68c16757e5d0c83765cff3837952b8b" class="m-dox-self" name="af68c16757e5d0c83765cff3837952b8b">Deleter</a> = void(*)(int, void*)
+            </dt>
+            <dd>A public typedef.</dd>
+          </dl>
+        </section>
+        <section id="pub-static-attribs">
+          <h2><a href="#pub-static-attribs">Public static variables</a></h3>
+          <dl class="m-dox">
+            <dt>static int <a href="#a37f97d663491ff54fda7f9cfc3080006" class="m-dox-self" name="a37f97d663491ff54fda7f9cfc3080006">Size</a> <span class="m-label m-flat m-primary">constexpr</span></dt>
+            <dd>A public static var.</dd>
+          </dl>
+        </section>
+        <section id="pub-static-methods">
+          <h2><a href="#pub-static-methods">Public static functions</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">static void <a href="#abc9f4f532d25aa0d957a183098f2291d" class="m-dox-self" name="abc9f4f532d25aa0d957a183098f2291d">damage</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>A public static function.</dd>
+          </dl>
+        </section>
+        <section id="typeless-methods">
+          <h2><a href="#typeless-methods">Constructors, destructors, conversion operators</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper"><a href="#a01c99be667ab8ee934e9f94da744ea83" class="m-dox-self" name="a01c99be667ab8ee934e9f94da744ea83">Class</a>(</span><span class="m-dox-wrap">int,
+              void*) <span class="m-label m-flat m-info">explicit</span>  <span class="m-label m-flat m-primary">constexpr</span> <span class="m-label m-flat m-success">noexcept</span></span>
+            </dt>
+            <dd>A constructor without parameter names.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper"><a href="#a55a51bc352524f6da634bb257d69a784" class="m-dox-self" name="a55a51bc352524f6da634bb257d69a784">Class</a>(</span><span class="m-dox-wrap"><a href="classRoot_1_1Directory_1_1Sub_1_1Class.html" class="m-dox">Class</a>&amp;) <span class="m-label m-flat m-danger">deleted</span></span>
+            </dt>
+            <dd>Deleted copy.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper"><a href="#ae8ec516d48f6045f9fd7c08ba724bf6e" class="m-dox-self" name="ae8ec516d48f6045f9fd7c08ba724bf6e">operator bool</a>(</span><span class="m-dox-wrap">) const &amp;&amp; <span class="m-label m-flat m-info">explicit</span> </span>
+            </dt>
+            <dd>A conversion operator that works only on &amp;&amp;.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper"><a href="#a7f5debd40ecca62a7ee98cd83858c013" class="m-dox-self" name="a7f5debd40ecca62a7ee98cd83858c013">~Class</a>(</span><span class="m-dox-wrap">) <span class="m-label m-flat m-warning">protected</span> <span class="m-label m-flat m-warning">pure virtual</span></span>
+            </dt>
+            <dd>A protected pure virtual destructor.</dd>
+          </dl>
+        </section>
+        <section id="pub-methods">
+          <h2><a href="#pub-methods">Public functions</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">auto <a href="#ad749cc571894bad6cb3b23b1f4527233" class="m-dox-self" name="ad749cc571894bad6cb3b23b1f4527233">operator=</a>(</span><span class="m-dox-wrap"><a href="classRoot_1_1Directory_1_1Sub_1_1Class.html" class="m-dox">Class</a>&amp;&amp;) -&gt; <a href="classRoot_1_1Directory_1_1Sub_1_1Class.html" class="m-dox">Class</a>&amp; <span class="m-label m-flat m-info">defaulted</span></span>
+            </dt>
+            <dd>Defaulted move.</dd>
+          </dl>
+        </section>
+        <section id="pub-attribs">
+          <h2><a href="#pub-attribs">Public variables</a></h3>
+          <dl class="m-dox">
+            <dt>std::string <a href="#ad877084846b47e5504224c72aa49d399" class="m-dox-self" name="ad877084846b47e5504224c72aa49d399">debug</a></dt>
+            <dd>A public variable.</dd>
+          </dl>
+        </section>
+        <section id="pro-types">
+          <h2><a href="#pro-types">Protected types</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <div class="m-dox-template">template&lt;class T, class U = void&gt;</div>
+              union <a href="unionRoot_1_1Directory_1_1Sub_1_1Class_1_1Bar.html" class="m-dox">Bar</a>
+            </dt>
+            <dd>A protected subclass.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">enum class <a href="#a0d7a4c92456263a36bd0819d9f26c996" class="m-dox-self" name="a0d7a4c92456263a36bd0819d9f26c996">Boolean</a> { </span><span class="m-dox-wrap"><a href="#a0d7a4c92456263a36bd0819d9f26c996af827cf462f62848df37c5e1e94a4da74" class="m-dox">True</a>,
+              <a href="#a0d7a4c92456263a36bd0819d9f26c996af8320b26d30ab433c5a54546d21f414c" class="m-dox">False</a>,
+              <a href="#a0d7a4c92456263a36bd0819d9f26c996a2767828026039e8ba7b38973cbb701f2" class="m-dox">FileNotFound</a> }</span>
+            </dt>
+            <dd>Protected enum.</dd>
+            <dt>
+              using <a href="#ad4571bbf02497aa3e998918dcee071fc" class="m-dox-self" name="ad4571bbf02497aa3e998918dcee071fc">Type</a> = double
+            </dt>
+            <dd>A protected alias.</dd>
+          </dl>
+        </section>
+        <section id="pro-static-methods">
+          <h2><a href="#pro-static-methods">Protected static functions</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">static void <a href="#a493c315509b0c10158bdc5dd229ea1bf" class="m-dox-self" name="a493c315509b0c10158bdc5dd229ea1bf">repair</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>A protected static function.</dd>
+          </dl>
+        </section>
+        <section id="pro-methods">
+          <h2><a href="#pro-methods">Protected functions</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">auto <a href="#a5ae387679a842b33720c0ceadb2583a0" class="m-dox-self" name="a5ae387679a842b33720c0ceadb2583a0">fetchMeSomeIntegers</a>(</span><span class="m-dox-wrap">) const -&gt; int <span class="m-label m-flat m-primary">constexpr</span></span>
+            </dt>
+            <dd>Protected function.</dd>
+          </dl>
+        </section>
+        <section id="pro-static-attribs">
+          <h2><a href="#pro-static-attribs">Protected static variables</a></h3>
+          <dl class="m-dox">
+            <dt>static bool <a href="#a74e37b7c91fdbbfb8b077f96ae5e6b2f" class="m-dox-self" name="a74e37b7c91fdbbfb8b077f96ae5e6b2f">False</a></dt>
+            <dd>A protected static var.</dd>
+          </dl>
+        </section>
+        <section id="pro-attribs">
+          <h2><a href="#pro-attribs">Protected variables</a></h3>
+          <dl class="m-dox">
+            <dt>std::string <a href="#a7646ff8bc6f40c535eb3c281d969f8cd" class="m-dox-self" name="a7646ff8bc6f40c535eb3c281d969f8cd">logger</a></dt>
+            <dd>A protected variable.</dd>
+          </dl>
+        </section>
+        <section id="pri-methods">
+          <h2><a href="#pri-methods">Private functions</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">auto <a href="#a28551ce6aa7f9f41c1360ed17737b65d" class="m-dox-self" name="a28551ce6aa7f9f41c1360ed17737b65d">doSomething</a>(</span><span class="m-dox-wrap">) const -&gt; int <span class="m-label m-flat m-warning">virtual</span></span>
+            </dt>
+            <dd>A documented private virtual function.</dd>
+          </dl>
+        </section>
+        <section id="group-full-of-non-public-stuff-which-should-be-marked-as-such">
+          <h2><a href="#group-full-of-non-public-stuff-which-should-be-marked-as-such">Group full of non-public stuff which should be marked as such</a></h2>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">enum class <a href="#a82511584183fc6aa5505e0e4ce811580" class="m-dox-self" name="a82511584183fc6aa5505e0e4ce811580">Flag</a> { </span><span class="m-dox-wrap"> } <span class="m-label m-flat m-warning">protected</span></span>
+            </dt>
+            <dd>Protected flag in a group.</dd>
+            <dt>
+              using <a href="#a4a7ac6e39fedaf79a0ceb0f8d2a3cb64" class="m-dox-self" name="a4a7ac6e39fedaf79a0ceb0f8d2a3cb64">Main</a> = void <span class="m-label m-flat m-warning">protected</span>
+            </dt>
+            <dd>Protected alias in a group.</dd>
+            <dt>void* <a href="#a347f08e1aec78ec16125bac4c2577962" class="m-dox-self" name="a347f08e1aec78ec16125bac4c2577962">variable</a> <span class="m-label m-flat m-warning">protected</span></dt>
+            <dd>Protected variable in a group.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a829faa7cd38054a51a303027eaee3b31" class="m-dox-self" name="a829faa7cd38054a51a303027eaee3b31">foo</a>(</span><span class="m-dox-wrap">) const &amp; <span class="m-label m-flat m-warning">protected</span></span>
+            </dt>
+            <dd>Protected function in a group.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">auto <a href="#af5c2ec17b691bd71f7445c9ee886b82e" class="m-dox-self" name="af5c2ec17b691bd71f7445c9ee886b82e">doStuff</a>(</span><span class="m-dox-wrap">) -&gt; int <span class="m-label m-flat m-danger">private</span> <span class="m-label m-flat m-warning">pure virtual</span></span>
+            </dt>
+            <dd>Private virtual function in a group.</dd>
+          </dl>
+        </section>
+        <section id="related">
+          <h2><a href="#related">Related</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">enum class <a href="#af7cffe8dae198e7cb01579ec6417a637" class="m-dox-self" name="af7cffe8dae198e7cb01579ec6417a637">Enum</a>: int { </span><span class="m-dox-wrap"> }</span>
+            </dt>
+            <dd>An enum.</dd>
+            <dt>
+              using <a href="#a7cc214a236ad3bb6ad435bdcf5262a3f" class="m-dox-self" name="a7cc214a236ad3bb6ad435bdcf5262a3f">Int</a> = int
+            </dt>
+            <dd>A typedef.</dd>
+            <dt>
+              using <a href="#a3ffd74e95952eacd75f04a2b85d61845" class="m-dox-self" name="a3ffd74e95952eacd75f04a2b85d61845">Float</a> = float
+            </dt>
+            <dd>An using declaration.</dd>
+            <dt>const int <a href="#a7708bd7aaec399e771a2b30db52e4d22" class="m-dox-self" name="a7708bd7aaec399e771a2b30db52e4d22">Var</a> <span class="m-label m-flat m-primary">constexpr</span></dt>
+            <dd>A variable.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#ac07863d69ae41a4e395b31f73b35fbcd" class="m-dox-self" name="ac07863d69ae41a4e395b31f73b35fbcd">foo</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>A function.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">#define <a href="#af370f27ec90a92ed7656537eacb476e9" class="m-dox-self" name="af370f27ec90a92ed7656537eacb476e9">A_MACRO</a>(</span><span class="m-dox-wrap">foo)</span>
+            </dt>
+            <dd>A macro.</dd>
+          </dl>
+        </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/dir_4b0d5f8864bf89936129251a2d32609b.html b/doxygen/test/compound_listing/dir_4b0d5f8864bf89936129251a2d32609b.html
new file mode 100644 (file)
index 0000000..f49a520
--- /dev/null
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Directory/ directory | 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>
+          Directory<span class="m-breadcrumb">/</span> <span class="m-thin">directory</span>
+        </h1>
+        <p>Directory.</p>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#subdirs">Directories</a></li>
+                <li><a href="#files">Files</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="subdirs">
+          <h2><a href="#subdirs">Directories</a></h3>
+          <dl class="m-dox">
+            <dt>directory <a href="dir_bbe5918fe090eee9db2d9952314b6754.html" class="m-dox">Sub</a>/</dt>
+            <dd>Subdirectory.</dd>
+          </dl>
+        </section>
+        <section id="files">
+          <h2><a href="#files">Files</a></h3>
+          <dl class="m-dox">
+            <dt>file <a href="File_8h.html" class="m-dox">File.h</a></dt>
+            <dd>File in directory.</dd>
+          </dl>
+        </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/dir_bbe5918fe090eee9db2d9952314b6754.html b/doxygen/test/compound_listing/dir_bbe5918fe090eee9db2d9952314b6754.html
new file mode 100644 (file)
index 0000000..476d8a4
--- /dev/null
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Directory/Sub/ directory | 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>
+          <span class="m-breadcrumb"><a href="dir_4b0d5f8864bf89936129251a2d32609b.html">Directory</a>/</span>Sub<span class="m-breadcrumb">/</span> <span class="m-thin">directory</span>
+        </h1>
+        <p>Subdirectory.</p>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#files">Files</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="files">
+          <h2><a href="#files">Files</a></h3>
+          <dl class="m-dox">
+            <dt>file <a href="Class_8h.html" class="m-dox">Class.h</a></dt>
+            <dd>File in a subdirectory.</dd>
+          </dl>
+        </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/files.html b/doxygen/test/compound_listing/files.html
new file mode 100644 (file)
index 0000000..38971cc
--- /dev/null
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>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>Files</h2>
+        <ul class="m-dox">
+          <li class="m-dox-collapsible">
+            <a href="#" onclick="return toggle(this)">dir</a> <a href="dir_56e20ab71e0974449b1654dd79ea6687.html" class="m-dox">Another</a> <span class="m-dox">Another directory.</span>
+            <ul class="m-dox">
+              <li>file <a href="Some_8h.html" class="m-dox">Some.h</a> <span class="m-dox">Some file.</span></li>
+            </ul>
+          </li>
+          <li class="m-dox-collapsible">
+            <a href="#" onclick="return toggle(this)">dir</a> <a href="dir_4b0d5f8864bf89936129251a2d32609b.html" class="m-dox">Directory</a> <span class="m-dox">Directory.</span>
+            <ul class="m-dox">
+              <li class="m-dox-collapsible">
+                <a href="#" onclick="return toggle(this)">dir</a> <a href="dir_bbe5918fe090eee9db2d9952314b6754.html" class="m-dox">Sub</a> <span class="m-dox">Subdirectory.</span>
+                <ul class="m-dox">
+                  <li>file <a href="Class_8h.html" class="m-dox">Class.h</a> <span class="m-dox">File in a subdirectory.</span></li>
+                </ul>
+              </li>
+              <li>file <a href="File_8h.html" class="m-dox">File.h</a> <span class="m-dox">File in directory.</span></li>
+            </ul>
+          </li>
+          <li>file <a href="TopLevelFile_8h.html" class="m-dox">TopLevelFile.h</a> <span class="m-dox">Top-level file.</span></li>
+        </ul>
+        <script>
+        function toggle(e) {
+            e.parentElement.className = e.parentElement.className == 'm-dox-collapsible' ?
+                'm-dox-expansible' : 'm-dox-collapsible';
+            return false;
+        }
+        /* Collapse all nodes marked as such. Doing it via JS instead of directly in
+           markup so disabling it doesn't harm usability. The list is somehow
+           regenerated on every iteration and shrinks as I change the classes. It's not
+           documented anywhere and I'm not sure if this is the same across browsers, so
+           I am going backwards in that list to be sure.  */
+        var collapsed = document.getElementsByClassName("collapsed");
+        for(var i = collapsed.length - 1; i >= 0; --i)
+            collapsed[i].className = 'm-dox-expansible';
+        </script>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/input.dox b/doxygen/test/compound_listing/input.dox
new file mode 100644 (file)
index 0000000..8aeef79
--- /dev/null
@@ -0,0 +1,48 @@
+/** @namespace Root
+ * @brief Root namespace
+ */
+
+/** @dir Directory
+ * @brief Directory
+ */
+/** @namespace Root::Directory
+ * @brief Namespace in directory
+ */
+
+/** @dir Directory/Sub
+ * @brief Subdirectory
+ */
+/** @namespace Root::Directory::Sub
+ * @brief Namespace in subdirectory
+ */
+
+/** @dir Another
+ * @brief Another directory
+ */
+/** @namespace Another
+ * @brief Another namespace
+ */
+
+/** @page page-toc Page with TOC
+
+@tableofcontents
+
+@section section A section
+
+Text.
+
+@subsection sub-section Subsection
+
+@subsection sub-section2 Subsection 2
+
+@subsubsection sub-section3 Subsection 3
+
+@section section2 Section 2
+
+*/
+
+/** @page page-no-toc Page without TOC
+
+@section section-notoc A section that doesn't go into TOC
+
+*/
diff --git a/doxygen/test/compound_listing/namespaceAnother.html b/doxygen/test/compound_listing/namespaceAnother.html
new file mode 100644 (file)
index 0000000..84cd77c
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Another namespace | 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" id="m-navbar-current">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>Another <span class="m-thin">namespace</span></h1>
+        <p>Another namespace.</p>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/namespaceRoot_1_1Directory.html b/doxygen/test/compound_listing/namespaceRoot_1_1Directory.html
new file mode 100644 (file)
index 0000000..6e8792d
--- /dev/null
@@ -0,0 +1,151 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Root::Directory namespace | 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" id="m-navbar-current">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><span class="m-breadcrumb"><a href="namespaceRoot.html">Root</a>::</span>Directory <span class="m-thin">namespace</span></h1>
+        <p>Namespace in directory.</p>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              Reference
+              <ul>
+                <li><a href="#namespaces">Namespaces</a></li>
+                <li><a href="#nested-classes">Classes</a></li>
+                <li><a href="#enum-members">Enums</a></li>
+                <li><a href="#typedef-members">Typedefs</a></li>
+                <li><a href="#func-members">Functions</a></li>
+                <li><a href="#var-members">Variables</a></li>
+                <li><a href="#a-group">A group</a></li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+        <section id="namespaces">
+          <h2><a href="#namespaces">Namespaces</a></h3>
+          <dl class="m-dox">
+            <dt>namespace <a href="namespaceRoot_1_1Directory_1_1Sub.html" class="m-dox">Sub</a></dt>
+            <dd>Namespace in subdirectory.</dd>
+          </dl>
+        </section>
+        <section id="nested-classes">
+          <h2><a href="#nested-classes">Classes</a></h3>
+          <dl class="m-dox">
+            <dt>
+              class <a href="classRoot_1_1Directory_1_1Class.html" class="m-dox">Class</a>
+            </dt>
+            <dd>A class.</dd>
+            <dt>
+              struct <a href="structRoot_1_1Directory_1_1Struct.html" class="m-dox">Struct</a>
+            </dt>
+            <dd>A structure.</dd>
+            <dt>
+              union <a href="unionRoot_1_1Directory_1_1Union.html" class="m-dox">Union</a>
+            </dt>
+            <dd>An union.</dd>
+          </dl>
+        </section>
+        <section id="enum-members">
+          <h2><a href="#enum-members">Enums</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">enum class <a href="#a5927d5ad68391bd75c1f43b1ccb957b1" class="m-dox-self" name="a5927d5ad68391bd75c1f43b1ccb957b1">Enum</a>: int { </span><span class="m-dox-wrap"> }</span>
+            </dt>
+            <dd>An enum.</dd>
+          </dl>
+        </section>
+        <section id="typedef-members">
+          <h2><a href="#typedef-members">Typedefs</a></h3>
+          <dl class="m-dox">
+            <dt>
+              using <a href="#ac5f7e56298e7c5f4744da826f519b41c" class="m-dox-self" name="ac5f7e56298e7c5f4744da826f519b41c">Int</a> = int
+            </dt>
+            <dd>A typedef.</dd>
+            <dt>
+              using <a href="#a61d6355f361b4a422e0dc65fc6ab9703" class="m-dox-self" name="a61d6355f361b4a422e0dc65fc6ab9703">Float</a> = float
+            </dt>
+            <dd>An using declaration.</dd>
+          </dl>
+        </section>
+        <section id="func-members">
+          <h2><a href="#func-members">Functions</a></h3>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a1e483a02e625a420e6b3541677ab4fbd" class="m-dox-self" name="a1e483a02e625a420e6b3541677ab4fbd">foo</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>A function.</dd>
+          </dl>
+        </section>
+        <section id="var-members">
+          <h2><a href="#var-members">Variables</a></h3>
+          <dl class="m-dox">
+            <dt>const int <a href="#acdc29819d61c01eed9c74242010a7601" class="m-dox-self" name="acdc29819d61c01eed9c74242010a7601">Var</a> <span class="m-label m-flat m-primary">constexpr</span></dt>
+            <dd>A variable.</dd>
+          </dl>
+        </section>
+        <section id="a-group">
+          <h2><a href="#a-group">A group</a></h2>
+          <dl class="m-dox">
+            <dt>
+              <span class="m-dox-wrap-bumper">enum class <a href="#ad48cec404dd0ac98a7cb35cde9b80ef7" class="m-dox-self" name="ad48cec404dd0ac98a7cb35cde9b80ef7">Flag</a> { </span><span class="m-dox-wrap"> }</span>
+            </dt>
+            <dd>Flag in a group.</dd>
+            <dt>
+              using <a href="#ad647ff34e255fa1b8adea19bfc55d631" class="m-dox-self" name="ad647ff34e255fa1b8adea19bfc55d631">Main</a> = void
+            </dt>
+            <dd>Alias in a group.</dd>
+            <dt>void* <a href="#ac4c2505beb086a985a4154d00d41de70" class="m-dox-self" name="ac4c2505beb086a985a4154d00d41de70">variable</a> <span class="m-label m-flat m-primary">constexpr</span></dt>
+            <dd>Variable in a group.</dd>
+            <dt>
+              <span class="m-dox-wrap-bumper">void <a href="#a0daa434b0cb806e7613bcc06ed6baaf6" class="m-dox-self" name="a0daa434b0cb806e7613bcc06ed6baaf6">bar</a>(</span><span class="m-dox-wrap">)</span>
+            </dt>
+            <dd>Function in a group.</dd>
+          </dl>
+        </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/namespaces.html b/doxygen/test/compound_listing/namespaces.html
new file mode 100644 (file)
index 0000000..ac512a2
--- /dev/null
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>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" id="m-navbar-current">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>Namespaces</h2>
+        <ul class="m-dox">
+          <li>namespace <a href="namespaceAnother.html" class="m-dox">Another</a> <span class="m-dox">Another namespace.</span></li>
+          <li class="m-dox-collapsible">
+            <a href="#" onclick="return toggle(this)">namespace</a> <a href="namespaceRoot.html" class="m-dox">Root</a> <span class="m-dox">Root namespace.</span>
+            <ul class="m-dox">
+              <li class="m-dox-collapsible">
+                <a href="#" onclick="return toggle(this)">namespace</a> <a href="namespaceRoot_1_1Directory.html" class="m-dox">Directory</a> <span class="m-dox">Namespace in directory.</span>
+                <ul class="m-dox">
+                  <li>namespace <a href="namespaceRoot_1_1Directory_1_1Sub.html" class="m-dox">Sub</a> <span class="m-dox">Namespace in subdirectory.</span></li>
+                </ul>
+              </li>
+            </ul>
+          </li>
+        </ul>
+        <script>
+        function toggle(e) {
+            e.parentElement.className = e.parentElement.className == 'm-dox-collapsible' ?
+                'm-dox-expansible' : 'm-dox-collapsible';
+            return false;
+        }
+        /* Collapse all nodes marked as such. Doing it via JS instead of directly in
+           markup so disabling it doesn't harm usability. The list is somehow
+           regenerated on every iteration and shrinks as I change the classes. It's not
+           documented anywhere and I'm not sure if this is the same across browsers, so
+           I am going backwards in that list to be sure.  */
+        var collapsed = document.getElementsByClassName("collapsed");
+        for(var i = collapsed.length - 1; i >= 0; --i)
+            collapsed[i].className = 'm-dox-expansible';
+        </script>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/page-no-toc.html b/doxygen/test/compound_listing/page-no-toc.html
new file mode 100644 (file)
index 0000000..ce38c09
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Page without TOC | 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>
+          Page without TOC
+        </h1>
+<section id="section-notoc"><h2><a href="#section-notoc">A section that doesn&#x27;t go into TOC</a></h2></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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/compound_listing/page-toc.html b/doxygen/test/compound_listing/page-toc.html
new file mode 100644 (file)
index 0000000..016da4b
--- /dev/null
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Page with TOC | 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>
+          Page with TOC
+        </h1>
+        <div class="m-block m-default">
+          <h3>Contents</h3>
+          <ul>
+            <li>
+              <a href="#section">A section</a>
+              <ul>
+                <li><a href="#sub-section">Subsection</a></li>
+                <li>
+                  <a href="#sub-section2">Subsection 2</a>
+                  <ul>
+                    <li><a href="#sub-section3">Subsection 3</a></li>
+                  </ul>
+                </li>
+              </ul>
+            </li>
+            <li><a href="#section2">Section 2</a></li>
+          </ul>
+        </div>
+<section id="section"><h2><a href="#section">A section</a></h2><p>Text.</p><section id="sub-section"><h3><a href="#sub-section">Subsection</a></h3></section><section id="sub-section2"><h3><a href="#sub-section2">Subsection 2</a></h3><section id="sub-section3"><h4><a href="#sub-section3">Subsection 3</a></h4></section></section></section><section id="section2"><h2><a href="#section2">Section 2</a></h2></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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/contents_blocks/Doxyfile b/doxygen/test/contents_blocks/Doxyfile
new file mode 100644 (file)
index 0000000..d8d89a9
--- /dev/null
@@ -0,0 +1,5 @@
+INPUT                   = input.dox
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
diff --git a/doxygen/test/contents_blocks/index.html b/doxygen/test/contents_blocks/index.html
new file mode 100644 (file)
index 0000000..f104237
--- /dev/null
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>My Project | 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>
+          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>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/contents_blocks/input.dox b/doxygen/test/contents_blocks/input.dox
new file mode 100644 (file)
index 0000000..167cfd9
--- /dev/null
@@ -0,0 +1,25 @@
+/** @mainpage
+
+First paragraph containing some content.
+@attention An attention section.
+@see Other section.
+
+Paragraph following the sections.
+
+@note A note.
+
+@bug This is a bug.
+
+@todo Or a TODO.
+
+@deprecated Which is deprecated.
+
+@xrefitem old "Old stuff" "Just old" This is old.
+
+*/
+
+/** @page other Other page
+
+@todo Diffferent TODO
+
+*/
diff --git a/doxygen/test/contents_blocks/todo.html b/doxygen/test/contents_blocks/todo.html
new file mode 100644 (file)
index 0000000..a31416a
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Todo List | 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>
+          Todo List
+        </h1>
+<dl class="m-dox"><dt><a name="_todo000001"></a>page <a href="index.html" class="m-dox">Main Page</a></dt><dd>Or a TODO.</dd><dt><a name="_todo000002"></a>Page <a href="other.html" class="m-dox">Other page</a></dt><dd>Diffferent TODO</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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/contents_code/Doxyfile b/doxygen/test/contents_code/Doxyfile
new file mode 100644 (file)
index 0000000..d8d89a9
--- /dev/null
@@ -0,0 +1,5 @@
+INPUT                   = input.dox
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
diff --git a/doxygen/test/contents_code/index.html b/doxygen/test/contents_code/index.html
new file mode 100644 (file)
index 0000000..9aec367
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>My Project | 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>
+          My Project
+        </h1>
+<pre class="m-code"><span class="c1">// A code block.</span>
+<span class="c1">// Spanning multiple lines.</span></pre><pre class="m-code"><span class="c1">// Special handling of some extensions</span></pre><p><code class="m-code"><span class="na">Inline</span><span class="o">=</span><span class="s">code</span></code> at the start of a line. Then a code that is inside of <code class="m-code"><span class="nb">cd</span> dir</code> a text, should be delimited by spaces. But not when it is in (<code class="m-code"><span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;www&#39;</span><span class="p">);</span></code>) parentheses.</p><pre class="m-console">!<span class="g g-AnsiBlue">[</span><span class="g g-AnsiBrightWhite">mosra@don-perverzo </span><span class="g g-AnsiWhite">m.css</span><span class="g g-AnsiBlue">]</span><span class="g g-AnsiBrightCyan">$ </span></pre><pre class="m-code"><span class="p">{</span>
+    <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>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/contents_code/input.dox b/doxygen/test/contents_code/input.dox
new file mode 100644 (file)
index 0000000..cb1a9d8
--- /dev/null
@@ -0,0 +1,49 @@
+/** @mainpage
+
+@code{.cpp}
+// A code block.
+// Spanning multiple lines.
+@endcode
+
+@code{.glsl}
+// Special handling of some extensions
+@endcode
+
+@code{.ini} Inline=code @endcode at the start of a line. Then a code that
+is inside of @code{.sh} cd dir @endcode a text, should be delimited by spaces.
+But not when it is in (@code{.js} alert('www'); @endcode) parentheses.
+
+@code{.ansi}
+!\e[0;34m[\e[1;37mmosra@don-perverzo \e[0;37mm.css\e[0;34m]\e[1;36m$ \e[0m
+@endcode
+
+@code{.cpp}
+    {
+        // a block
+            // that is indented
+        // but has a lot of trailing whitespace which should be removed
+    }
+
+
+
+
+@endcode
+*/
+
+/** @page warnings Code that produces warnings
+
+@code
+// Code without language
+// description
+@endcode
+
+A paragraph.
+@code{.ini}
+Multi=line
+code=that is a part of a paragraph.
+@endcode
+
+@code{.whatthehell}
+Code that has unrecognizable format.
+@endcode
+*/
diff --git a/doxygen/test/contents_code/warnings.html b/doxygen/test/contents_code/warnings.html
new file mode 100644 (file)
index 0000000..c94a2b1
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Code that produces warnings | 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>
+          Code that produces warnings
+        </h1>
+<pre class="m-code"><span class="c1">// Code without language</span>
+<span class="c1">// description</span></pre><p>A paragraph.</p><pre class="m-code"><span class="na">Multi</span><span class="o">=</span><span class="s">line</span>
+<span class="na">code</span><span class="o">=</span><span class="s">that is a part of a paragraph.</span></pre><pre class="m-code">Code that has unrecognizable format.</pre>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/contents_image/Doxyfile b/doxygen/test/contents_image/Doxyfile
new file mode 100644 (file)
index 0000000..0cd61da
--- /dev/null
@@ -0,0 +1,6 @@
+INPUT                   = input.dox
+IMAGE_PATH              = .
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
diff --git a/doxygen/test/contents_image/index.html b/doxygen/test/contents_image/index.html
new file mode 100644 (file)
index 0000000..795bc18
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>My Project | 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>
+          My Project
+        </h1>
+<p><img class="m-image" src="tiny.png" alt="Alt text" /></p>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/contents_image/input.dox b/doxygen/test/contents_image/input.dox
new file mode 100644 (file)
index 0000000..0c5c157
--- /dev/null
@@ -0,0 +1,15 @@
+/** @mainpage
+
+@image html tiny.png Alt text
+
+*/
+
+/** @page warnings Images that produce warnings
+
+@image html nonexistent.png Image that doesn't exist.
+
+Image without alt text:
+
+@image html tiny.png
+
+*/
diff --git a/doxygen/test/contents_image/tiny.png b/doxygen/test/contents_image/tiny.png
new file mode 100644 (file)
index 0000000..cacab70
Binary files /dev/null and b/doxygen/test/contents_image/tiny.png differ
diff --git a/doxygen/test/contents_image/warnings.html b/doxygen/test/contents_image/warnings.html
new file mode 100644 (file)
index 0000000..66925e2
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Images that produce warnings | 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>
+          Images that produce warnings
+        </h1>
+<p><img class="m-image" src="nonexistent.png" alt="Image that doesn&#x27;t exist." /></p><p>Image without alt text:</p><p><img class="m-image" src="tiny.png" alt="Image" /></p>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/contents_math/Doxyfile b/doxygen/test/contents_math/Doxyfile
new file mode 100644 (file)
index 0000000..d8d89a9
--- /dev/null
@@ -0,0 +1,5 @@
+INPUT                   = input.dox
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
diff --git a/doxygen/test/contents_math/index.html b/doxygen/test/contents_math/index.html
new file mode 100644 (file)
index 0000000..da6c805
--- /dev/null
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>My Project | 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>
+          My Project
+        </h1>
+<p>Here&#x27;s a block formula:</p><div class="m-math"><svg height='27.0023pt' version='1.1' viewBox='148.249 -21.6018 92.0442 21.6018' width='115.055pt'>
+<title>LaTeX Math</title>
+<desc>
+\[ \hat q = [\boldsymbol 0, 1] + \epsilon [\frac{\boldsymbol v}{2}, 0] \]
+</desc>
+<defs>
+<path d='M6.46775 -4.32777C6.46775 -5.41569 5.66675 -5.41569 5.65479 -5.41569C5.17659 -5.41569 4.7462 -4.91357 4.7462 -4.5071C4.7462 -4.17235 4.99726 -4.02889 5.10486 -3.96912C5.60697 -3.67024 5.70262 -3.45504 5.70262 -3.21594C5.70262 -2.95293 5.00922 -0.334745 3.61046 -0.334745C2.74969 -0.334745 2.74969 -1.05205 2.74969 -1.26725C2.74969 -1.96065 3.08443 -2.83337 3.467 -3.78979C3.56264 -4.02889 3.59851 -4.13649 3.59851 -4.32777C3.59851 -5.02117 2.90511 -5.40374 2.24757 -5.40374C0.980324 -5.40374 0.382565 -3.77783 0.382565 -3.53873C0.382565 -3.37136 0.561893 -3.37136 0.669489 -3.37136C0.812951 -3.37136 0.896638 -3.37136 0.944458 -3.52677C1.32702 -4.81793 1.96065 -4.97335 2.17584 -4.97335C2.25953 -4.97335 2.37908 -4.97335 2.37908 -4.72229C2.37908 -4.44732 2.23562 -4.10062 2.19975 -4.00498C1.64981 -2.61818 1.47049 -2.0802 1.47049 -1.50635C1.47049 -0.239103 2.49863 0.0956413 3.53873 0.0956413C5.59502 0.0956413 6.46775 -3.29963 6.46775 -4.32777Z' id='eq1-g0-118'/>
+<path d='M4.77011 -2.76164H8.06974C8.23711 -2.76164 8.4523 -2.76164 8.4523 -2.97684C8.4523 -3.20399 8.24907 -3.20399 8.06974 -3.20399H4.77011V-6.50361C4.77011 -6.67098 4.77011 -6.88618 4.55492 -6.88618C4.32777 -6.88618 4.32777 -6.68294 4.32777 -6.50361V-3.20399H1.02814C0.860772 -3.20399 0.645579 -3.20399 0.645579 -2.98879C0.645579 -2.76164 0.848817 -2.76164 1.02814 -2.76164H4.32777V0.537983C4.32777 0.705355 4.32777 0.920548 4.54296 0.920548C4.77011 0.920548 4.77011 0.71731 4.77011 0.537983V-2.76164Z' id='eq1-g3-43'/>
+<path d='M5.35592 -3.82565C5.35592 -4.81793 5.29614 -5.7863 4.86575 -6.69489C4.37559 -7.68717 3.51482 -7.95019 2.92902 -7.95019C2.23562 -7.95019 1.3868 -7.60349 0.944458 -6.61121C0.609714 -5.85803 0.490162 -5.11681 0.490162 -3.82565C0.490162 -2.666 0.573848 -1.79328 1.00423 -0.944458C1.47049 -0.0358655 2.29539 0.251059 2.91706 0.251059C3.95716 0.251059 4.55492 -0.37061 4.90162 -1.06401C5.332 -1.96065 5.35592 -3.13225 5.35592 -3.82565ZM2.91706 0.0119552C2.5345 0.0119552 1.75741 -0.203238 1.53026 -1.50635C1.39875 -2.22366 1.39875 -3.13225 1.39875 -3.96912C1.39875 -4.94944 1.39875 -5.83412 1.59004 -6.53948C1.79328 -7.34047 2.40299 -7.71108 2.91706 -7.71108C3.37136 -7.71108 4.06476 -7.43611 4.29191 -6.40797C4.44732 -5.72653 4.44732 -4.78207 4.44732 -3.96912C4.44732 -3.16812 4.44732 -2.25953 4.31582 -1.53026C4.08867 -0.215193 3.33549 0.0119552 2.91706 0.0119552Z' id='eq1-g3-48'/>
+<path d='M3.44309 -7.66326C3.44309 -7.93823 3.44309 -7.95019 3.20399 -7.95019C2.91706 -7.6274 2.3193 -7.18506 1.08792 -7.18506V-6.83836C1.36289 -6.83836 1.96065 -6.83836 2.61818 -7.14919V-0.920548C2.61818 -0.490162 2.58232 -0.3467 1.53026 -0.3467H1.15965V0C1.48244 -0.0239103 2.64209 -0.0239103 3.03661 -0.0239103S4.57883 -0.0239103 4.90162 0V-0.3467H4.53101C3.47895 -0.3467 3.44309 -0.490162 3.44309 -0.920548V-7.66326Z' id='eq1-g3-49'/>
+<path d='M5.26027 -2.00847H4.99726C4.96139 -1.80523 4.86575 -1.1477 4.7462 -0.956413C4.66252 -0.848817 3.98107 -0.848817 3.62242 -0.848817H1.41071C1.7335 -1.12379 2.46276 -1.88892 2.7736 -2.17584C4.59078 -3.84956 5.26027 -4.47123 5.26027 -5.65479C5.26027 -7.02964 4.17235 -7.95019 2.78555 -7.95019S0.585803 -6.76663 0.585803 -5.73848C0.585803 -5.12877 1.11183 -5.12877 1.1477 -5.12877C1.39875 -5.12877 1.70959 -5.30809 1.70959 -5.69066C1.70959 -6.0254 1.48244 -6.25255 1.1477 -6.25255C1.0401 -6.25255 1.01619 -6.25255 0.980324 -6.2406C1.20747 -7.05355 1.85305 -7.60349 2.63014 -7.60349C3.64633 -7.60349 4.268 -6.75467 4.268 -5.65479C4.268 -4.63861 3.68219 -3.75392 3.00075 -2.98879L0.585803 -0.286924V0H4.94944L5.26027 -2.00847Z' id='eq1-g3-50'/>
+<path d='M8.06974 -3.87347C8.23711 -3.87347 8.4523 -3.87347 8.4523 -4.08867C8.4523 -4.31582 8.24907 -4.31582 8.06974 -4.31582H1.02814C0.860772 -4.31582 0.645579 -4.31582 0.645579 -4.10062C0.645579 -3.87347 0.848817 -3.87347 1.02814 -3.87347H8.06974ZM8.06974 -1.64981C8.23711 -1.64981 8.4523 -1.64981 8.4523 -1.86501C8.4523 -2.09215 8.24907 -2.09215 8.06974 -2.09215H1.02814C0.860772 -2.09215 0.645579 -2.09215 0.645579 -1.87696C0.645579 -1.64981 0.848817 -1.64981 1.02814 -1.64981H8.06974Z' id='eq1-g3-61'/>
+<path d='M2.98879 2.98879V2.54645H1.82914V-8.52403H2.98879V-8.96638H1.3868V2.98879H2.98879Z' id='eq1-g3-91'/>
+<path d='M1.85305 -8.96638H0.251059V-8.52403H1.41071V2.54645H0.251059V2.98879H1.85305V-8.96638Z' id='eq1-g3-93'/>
+<path d='M2.92902 -8.29689L1.36289 -6.67098L1.55417 -6.49166L2.91706 -7.72304L4.29191 -6.49166L4.48319 -6.67098L2.92902 -8.29689Z' id='eq1-g3-94'/>
+<path d='M3.47895 -2.71382C3.65828 -2.71382 3.86152 -2.71382 3.86152 -2.90511C3.86152 -3.06052 3.74197 -3.06052 3.52677 -3.06052H1.59004C1.88892 -4.14844 2.59427 -4.80598 3.65828 -4.80598H4.00498C4.20822 -4.80598 4.38755 -4.80598 4.38755 -4.99726C4.38755 -5.15268 4.25604 -5.15268 4.04085 -5.15268H3.63437C2.16389 -5.15268 0.549938 -3.98107 0.549938 -2.10411C0.549938 -0.777086 1.44658 0.119552 2.63014 0.119552C3.39527 0.119552 4.14844 -0.358655 4.14844 -0.478207C4.14844 -0.549938 4.11258 -0.621669 4.04085 -0.621669C4.00498 -0.621669 3.98107 -0.609714 3.9213 -0.561893C3.467 -0.263014 3.02466 -0.119552 2.666 -0.119552C2.03238 -0.119552 1.36289 -0.537983 1.36289 -1.69763C1.36289 -1.92478 1.3868 -2.23562 1.4944 -2.71382H3.47895Z' id='eq1-g2-15'/>
+<path d='M2.33126 0.0478207C2.33126 -0.645579 2.10411 -1.15965 1.61395 -1.15965C1.23138 -1.15965 1.0401 -0.848817 1.0401 -0.585803S1.21943 0 1.6259 0C1.78132 0 1.91283 -0.0478207 2.02042 -0.155417C2.04433 -0.179328 2.05629 -0.179328 2.06824 -0.179328C2.09215 -0.179328 2.09215 -0.0119552 2.09215 0.0478207C2.09215 0.442341 2.02042 1.21943 1.32702 1.99651C1.19552 2.13998 1.19552 2.16389 1.19552 2.1878C1.19552 2.24757 1.25529 2.30735 1.31507 2.30735C1.41071 2.30735 2.33126 1.42267 2.33126 0.0478207Z' id='eq1-g2-59'/>
+<path d='M5.27223 -5.15268C5.27223 -5.21245 5.22441 -5.26027 5.16463 -5.26027C5.06899 -5.26027 4.60274 -4.82989 4.37559 -4.41146C4.1604 -4.94944 3.78979 -5.27223 3.27572 -5.27223C1.92478 -5.27223 0.466252 -3.52677 0.466252 -1.75741C0.466252 -0.573848 1.15965 0.119552 1.9726 0.119552C2.60623 0.119552 3.13225 -0.358655 3.38331 -0.633624L3.39527 -0.621669L2.94097 1.17161L2.83337 1.60199C2.72578 1.96065 2.54645 1.96065 1.98456 1.9726C1.85305 1.9726 1.7335 1.9726 1.7335 2.19975C1.7335 2.28344 1.80523 2.3193 1.88892 2.3193C2.05629 2.3193 2.27148 2.29539 2.43885 2.29539H3.65828C3.83761 2.29539 4.04085 2.3193 4.22017 2.3193C4.29191 2.3193 4.43537 2.3193 4.43537 2.09215C4.43537 1.9726 4.33973 1.9726 4.1604 1.9726C3.59851 1.9726 3.56264 1.88892 3.56264 1.79328C3.56264 1.7335 3.5746 1.72154 3.61046 1.56613L5.27223 -5.15268ZM3.58655 -1.42267C3.52677 -1.21943 3.52677 -1.19552 3.3594 -0.968369C3.09639 -0.633624 2.57036 -0.119552 2.00847 -0.119552C1.51831 -0.119552 1.24334 -0.561893 1.24334 -1.26725C1.24334 -1.92478 1.61395 -3.26376 1.8411 -3.76588C2.24757 -4.60274 2.80946 -5.03313 3.27572 -5.03313C4.06476 -5.03313 4.22017 -4.0528 4.22017 -3.95716C4.22017 -3.94521 4.18431 -3.78979 4.17235 -3.76588L3.58655 -1.42267Z' id='eq1-g2-113'/>
+<path d='M6.18082 -3.8137C6.18082 -4.96139 6.18082 -7.84259 3.3594 -7.84259C0.526027 -7.84259 0.526027 -4.97335 0.526027 -3.8137C0.526027 -2.666 0.526027 0.143462 3.34745 0.143462S6.18082 -2.63014 6.18082 -3.8137ZM3.3594 -0.251059C2.97684 -0.251059 2.68991 -0.406476 2.45081 -0.657534C2.15193 -0.956413 1.96065 -1.1477 1.96065 -3.95716C1.96065 -4.79402 1.96065 -5.55915 2.05629 -6.18082C2.22366 -7.36438 3.08443 -7.44807 3.34745 -7.44807C3.73001 -7.44807 4.47123 -7.26874 4.63861 -6.26451C4.7462 -5.65479 4.7462 -4.68643 4.7462 -3.95716C4.7462 -1.13574 4.56687 -0.968369 4.20822 -0.609714C3.96912 -0.37061 3.64633 -0.251059 3.3594 -0.251059Z' id='eq1-g1-48'/>
+</defs>
+<g id='eq1-page1'>
+<use x='149.108' xlink:href='#eq1-g3-94' y='-8.20066'/>
+<use x='148.249' xlink:href='#eq1-g2-113' y='-8.20066'/>
+<use x='157.189' xlink:href='#eq1-g3-61' y='-8.20066'/>
+<use x='169.615' xlink:href='#eq1-g3-91' y='-8.20066'/>
+<use x='172.867' xlink:href='#eq1-g1-48' y='-8.20066'/>
+<use x='179.591' xlink:href='#eq1-g2-59' y='-8.20066'/>
+<use x='184.835' xlink:href='#eq1-g3-49' y='-8.20066'/>
+<use x='190.688' xlink:href='#eq1-g3-93' y='-8.20066'/>
+<use x='196.597' xlink:href='#eq1-g3-43' y='-8.20066'/>
+<use x='208.358' xlink:href='#eq1-g2-15' y='-8.20066'/>
+<use x='213.085' xlink:href='#eq1-g3-91' y='-8.20066'/>
+<use x='217.532' xlink:href='#eq1-g0-118' y='-16.2884'/>
+<rect height='0.478187' width='7.21734' x='217.532' y='-11.4285'/>
+<use x='218.214' xlink:href='#eq1-g3-50' y='0'/>
+<use x='225.945' xlink:href='#eq1-g2-59' y='-8.20066'/>
+<use x='231.189' xlink:href='#eq1-g3-48' y='-8.20066'/>
+<use x='237.042' xlink:href='#eq1-g3-93' y='-8.20066'/>
+</g>
+</svg></div><p>And <svg class="m-math" style="vertical-align: -2.9pt;" height='13.2835pt' version='1.1' viewBox='0 -8.30219 6.71157 10.6268' width='8.38946pt'>
+<title>LaTeX Math</title>
+<desc>
+$ \hat q $
+</desc>
+<defs>
+<path d='M5.27223 -5.15268C5.27223 -5.21245 5.22441 -5.26027 5.16463 -5.26027C5.06899 -5.26027 4.60274 -4.82989 4.37559 -4.41146C4.1604 -4.94944 3.78979 -5.27223 3.27572 -5.27223C1.92478 -5.27223 0.466252 -3.52677 0.466252 -1.75741C0.466252 -0.573848 1.15965 0.119552 1.9726 0.119552C2.60623 0.119552 3.13225 -0.358655 3.38331 -0.633624L3.39527 -0.621669L2.94097 1.17161L2.83337 1.60199C2.72578 1.96065 2.54645 1.96065 1.98456 1.9726C1.85305 1.9726 1.7335 1.9726 1.7335 2.19975C1.7335 2.28344 1.80523 2.3193 1.88892 2.3193C2.05629 2.3193 2.27148 2.29539 2.43885 2.29539H3.65828C3.83761 2.29539 4.04085 2.3193 4.22017 2.3193C4.29191 2.3193 4.43537 2.3193 4.43537 2.09215C4.43537 1.9726 4.33973 1.9726 4.1604 1.9726C3.59851 1.9726 3.56264 1.88892 3.56264 1.79328C3.56264 1.7335 3.5746 1.72154 3.61046 1.56613L5.27223 -5.15268ZM3.58655 -1.42267C3.52677 -1.21943 3.52677 -1.19552 3.3594 -0.968369C3.09639 -0.633624 2.57036 -0.119552 2.00847 -0.119552C1.51831 -0.119552 1.24334 -0.561893 1.24334 -1.26725C1.24334 -1.92478 1.61395 -3.26376 1.8411 -3.76588C2.24757 -4.60274 2.80946 -5.03313 3.27572 -5.03313C4.06476 -5.03313 4.22017 -4.0528 4.22017 -3.95716C4.22017 -3.94521 4.18431 -3.78979 4.17235 -3.76588L3.58655 -1.42267Z' id='eq2-g0-113'/>
+<path d='M2.92902 -8.29689L1.36289 -6.67098L1.55417 -6.49166L2.91706 -7.72304L4.29191 -6.49166L4.48319 -6.67098L2.92902 -8.29689Z' id='eq2-g1-94'/>
+</defs>
+<g id='eq2-page1'>
+<use x='0.858581' xlink:href='#eq2-g1-94' y='0'/>
+<use x='0' xlink:href='#eq2-g0-113' y='0'/>
+</g>
+</svg> is how quaternion is denoted.</p>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/contents_math/input.dox b/doxygen/test/contents_math/input.dox
new file mode 100644 (file)
index 0000000..8f72d86
--- /dev/null
@@ -0,0 +1,11 @@
+/** @mainpage
+
+Here's a block formula:
+
+@f[
+    \hat q = [\boldsymbol 0, 1] + \epsilon [\frac{\boldsymbol v}{2}, 0]
+@f]
+
+And @f$ \hat q @f$ is how quaternion is denoted.
+
+*/
diff --git a/doxygen/test/contents_tagfile/Doxyfile b/doxygen/test/contents_tagfile/Doxyfile
new file mode 100644 (file)
index 0000000..e361ae2
--- /dev/null
@@ -0,0 +1,6 @@
+INPUT                   = input.dox
+TAGFILES                = ../../../doc/doxygen/corrade.tag=http://doc.magnum.graphics/corrade/
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
diff --git a/doxygen/test/contents_tagfile/index.html b/doxygen/test/contents_tagfile/index.html
new file mode 100644 (file)
index 0000000..63cdf1c
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>My Project | 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>
+          My Project
+        </h1>
+<p>See <a href="http://doc.magnum.graphics/corrade/Assert_8h.html#a1114c0fdae83004b9a0f8d2ed4afae96" class="m-dox-external">CORRADE_<wbr/>INTERNAL_<wbr/>ASSERT()</a> for more information.</p><pre class="m-code"><span class="n">Corrade</span><span class="o">::</span><span class="n">Utility</span><span class="o">::</span><span class="n">Resource</span> <span class="n">rx</span><span class="p">;</span></pre>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/contents_tagfile/input.dox b/doxygen/test/contents_tagfile/input.dox
new file mode 100644 (file)
index 0000000..e7c385d
--- /dev/null
@@ -0,0 +1,9 @@
+/** @mainpage
+
+See @ref CORRADE_INTERNAL_ASSERT() for more information.
+
+@code{.cpp}
+Corrade::Utility::Resource rx;
+@endcode
+
+*/
diff --git a/doxygen/test/contents_typography/Doxyfile b/doxygen/test/contents_typography/Doxyfile
new file mode 100644 (file)
index 0000000..d8d89a9
--- /dev/null
@@ -0,0 +1,5 @@
+INPUT                   = input.dox
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
diff --git a/doxygen/test/contents_typography/index.html b/doxygen/test/contents_typography/index.html
new file mode 100644 (file)
index 0000000..cc90fdf
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>My Project | 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>
+          My Project
+        </h1>
+<section id="section"><h2><a href="#section">Page section</a></h2><blockquote><p>A blockquote.</p></blockquote><pre class="m-code">Preformatted text.
+</pre><section id="subsection"><h3><a href="#subsection">Page subsection</a></h3><p><ul><li>Unordered</li><li>list</li><li>of<ul><li>nested</li><li>items</li></ul></li><li>and back</li></ul></p><section id="subsubsection"><h4><a href="#subsubsection">Sub-sub section</a></h4><p><ol><li>Ordered</li><li>list</li><li>of<ol><li>nested</li><li>items</li></ol></li><li>and back</li></ol></p><p><a name="an-anchor"></a> This is a <code>typewriter text</code>, <em>emphasis</em> and <strong>bold</strong>. <a href="http://google.com">http:/<wbr/>/<wbr/>google.com</a> and <a href="http://google.com">URL</a>. En-dash &ndash; and em-dash &mdash;. Reference to a <a href="index.html#subsection" class="m-dox">Page subsection</a>.</p></section></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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/contents_typography/input.dox b/doxygen/test/contents_typography/input.dox
new file mode 100644 (file)
index 0000000..b362bb6
--- /dev/null
@@ -0,0 +1,43 @@
+/** @mainpage
+
+@section section Page section
+
+> A blockquote.
+
+    Preformatted text.
+
+@subsection subsection Page subsection
+
+-   Unordered
+-   list
+-   of
+    -   nested
+    -   items
+-   and back
+
+@subsubsection subsubsection Sub-sub section
+
+1.  Ordered
+2.  list
+3.  of
+    1.  nested
+    2.  items
+4.  and back
+
+@anchor an-anchor
+
+This is a `typewriter text`, *emphasis* and **bold**. http://google.com and
+[URL](http://google.com). En-dash -- and em-dash ---. Reference to a
+@ref subsection.
+
+*/
+
+/** @page warnings Content that produces warnings
+
+# Markdown heading 1
+
+## Markdown heading 2
+
+### Markdown heading 3
+
+*/
diff --git a/doxygen/test/contents_typography/warnings.html b/doxygen/test/contents_typography/warnings.html
new file mode 100644 (file)
index 0000000..454f87e
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Content that produces warnings | 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>
+          Content that produces warnings
+        </h1>
+<p><h2>Markdown heading 1</h2></p><p><h3>Markdown heading 2</h3></p><p><h4>Markdown heading 3</h4></p>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/doxyfile/Doxyfile b/doxygen/test/doxyfile/Doxyfile
new file mode 100644 (file)
index 0000000..3f059d8
--- /dev/null
@@ -0,0 +1,16 @@
+# Includes
+@INCLUDE = Doxyfile-another
+
+# Quotes
+PROJECT_BRIEF = "is cool"
+
+# Multiple lines
+HTML_EXTRA_FILES = \
+    css \
+    "another.png" \
+    \
+    "hello"
+
+# Adding
+HTML_EXTRA_STYLESHEET = a.css
+HTML_EXTRA_STYLESHEET += b.css
diff --git a/doxygen/test/doxyfile/Doxyfile-another b/doxygen/test/doxyfile/Doxyfile-another
new file mode 100644 (file)
index 0000000..c030d17
--- /dev/null
@@ -0,0 +1 @@
+PROJECT_NAME = "My Project"
diff --git a/doxygen/test/page_duplicated_brief/Doxyfile b/doxygen/test/page_duplicated_brief/Doxyfile
new file mode 100644 (file)
index 0000000..d8d89a9
--- /dev/null
@@ -0,0 +1,5 @@
+INPUT                   = input.dox
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
diff --git a/doxygen/test/page_duplicated_brief/input.dox b/doxygen/test/page_duplicated_brief/input.dox
new file mode 100644 (file)
index 0000000..99b222a
--- /dev/null
@@ -0,0 +1,11 @@
+/** @page page-a A page
+@brief Brief docs for a page
+
+Detailed docs for a page.
+*/
+
+/** @page page-b Page B
+@brief Brief with a period.
+
+Detailed docs for page B.
+*/
diff --git a/doxygen/test/page_duplicated_brief/page-a.html b/doxygen/test/page_duplicated_brief/page-a.html
new file mode 100644 (file)
index 0000000..fbba052
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>A page | 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>
+          A page
+        </h1>
+        <p>Brief docs for a page.</p>
+<p>Detailed docs for a page.</p>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/page_duplicated_brief/page-b.html b/doxygen/test/page_duplicated_brief/page-b.html
new file mode 100644 (file)
index 0000000..19faf69
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Page B | 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>
+          Page B
+        </h1>
+        <p>Brief with a period.</p>
+<p>Detailed docs for page B.</p>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/page_order/00-page-order.dox b/doxygen/test/page_order/00-page-order.dox
new file mode 100644 (file)
index 0000000..b57e053
--- /dev/null
@@ -0,0 +1,7 @@
+/**
+
+@page 03-first First
+@page 01-second Second
+@page 02-last Last
+
+*/
diff --git a/doxygen/test/page_order/01-second.dox b/doxygen/test/page_order/01-second.dox
new file mode 100644 (file)
index 0000000..d9f2805
--- /dev/null
@@ -0,0 +1,4 @@
+/** @page 01-second Second
+
+Contents of second page.
+*/
diff --git a/doxygen/test/page_order/02-last.dox b/doxygen/test/page_order/02-last.dox
new file mode 100644 (file)
index 0000000..ff52f61
--- /dev/null
@@ -0,0 +1,4 @@
+/** @page 02-last Last
+
+Contents of last page.
+*/
diff --git a/doxygen/test/page_order/03-first.dox b/doxygen/test/page_order/03-first.dox
new file mode 100644 (file)
index 0000000..541b6f7
--- /dev/null
@@ -0,0 +1,9 @@
+/** @page 03-first First
+
+Contents of first page, with subpages.
+
+- @subpage other-page
+- @subpage yet-another-subpage
+- @subpage a-subpage
+
+*/
diff --git a/doxygen/test/page_order/Doxyfile b/doxygen/test/page_order/Doxyfile
new file mode 100644 (file)
index 0000000..b928f4c
--- /dev/null
@@ -0,0 +1,6 @@
+INPUT                   =
+FILE_PATTERNS           = *.dox
+QUIET                   = YES
+GENERATE_HTML           = NO
+GENERATE_LATEX          = NO
+GENERATE_XML            = YES
diff --git a/doxygen/test/page_order/a-subpage.dox b/doxygen/test/page_order/a-subpage.dox
new file mode 100644 (file)
index 0000000..eaf8f4c
--- /dev/null
@@ -0,0 +1,4 @@
+/** @page a-subpage A subpage
+
+Contents of a subpage.
+*/
diff --git a/doxygen/test/page_order/other-page.dox b/doxygen/test/page_order/other-page.dox
new file mode 100644 (file)
index 0000000..16bccd8
--- /dev/null
@@ -0,0 +1,4 @@
+/** @page other-page Other page
+
+Contents of other subpage.
+*/
diff --git a/doxygen/test/page_order/pages.html b/doxygen/test/page_order/pages.html
new file mode 100644 (file)
index 0000000..7e20e86
--- /dev/null
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>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>Pages</h2>
+        <ul class="m-dox">
+          <li class="m-dox-collapsible">
+            <a href="#" onclick="return toggle(this)"></a><a href="03-first.html" class="m-dox">First</a> <span class="m-dox"></span>
+            <ul class="m-dox">
+              <li><a href="other-page.html" class="m-dox">Other page</a> <span class="m-dox"></span></li>
+              <li><a href="yet-another-subpage.html" class="m-dox">Yet another subpage</a> <span class="m-dox"></span></li>
+              <li><a href="a-subpage.html" class="m-dox">A subpage</a> <span class="m-dox"></span></li>
+            </ul>
+          </li>
+          <li><a href="01-second.html" class="m-dox">Second</a> <span class="m-dox"></span></li>
+          <li><a href="02-last.html" class="m-dox">Last</a> <span class="m-dox"></span></li>
+        </ul>
+        <script>
+        function toggle(e) {
+            e.parentElement.className = e.parentElement.className == 'm-dox-collapsible' ?
+                'm-dox-expansible' : 'm-dox-collapsible';
+            return false;
+        }
+        /* Collapse all nodes marked as such. Doing it via JS instead of directly in
+           markup so disabling it doesn't harm usability. The list is somehow
+           regenerated on every iteration and shrinks as I change the classes. It's not
+           documented anywhere and I'm not sure if this is the same across browsers, so
+           I am going backwards in that list to be sure.  */
+        var collapsed = document.getElementsByClassName("collapsed");
+        for(var i = collapsed.length - 1; i >= 0; --i)
+            collapsed[i].className = 'm-dox-expansible';
+        </script>
+      </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> 1.8.14 and <a href="http://mcss.mosra.cz/">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/doxygen/test/page_order/yet-another-subpage.dox b/doxygen/test/page_order/yet-another-subpage.dox
new file mode 100644 (file)
index 0000000..0fc036a
--- /dev/null
@@ -0,0 +1,4 @@
+/** @page yet-another-subpage Yet another subpage
+
+Contents of yet another subpage.
+*/
diff --git a/doxygen/test/test_compound.py b/doxygen/test/test_compound.py
new file mode 100644 (file)
index 0000000..de5490b
--- /dev/null
@@ -0,0 +1,101 @@
+import os
+import unittest
+
+from test import IntegrationTestCase
+
+class Listing(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'listing', *args, **kwargs)
+
+    def test_index_pages(self):
+        self.run_dox2html5(wildcard='index.xml', index_pages=['annotated', 'namespaces'])
+        self.assertEqual(*self.expected_actual_contents('annotated.html'))
+        self.assertEqual(*self.expected_actual_contents('namespaces.html'))
+
+    def test_index_pages_custom_expand_level(self):
+        self.run_dox2html5(wildcard='index.xml', index_pages=['files'])
+        self.assertEqual(*self.expected_actual_contents('files.html'))
+
+    def test_dir(self):
+        self.run_dox2html5(wildcard='dir_*.xml')
+        self.assertEqual(*self.expected_actual_contents('dir_4b0d5f8864bf89936129251a2d32609b.html'))
+        self.assertEqual(*self.expected_actual_contents('dir_bbe5918fe090eee9db2d9952314b6754.html'))
+
+    def test_file(self):
+        self.run_dox2html5(wildcard='*_8h.xml')
+        self.assertEqual(*self.expected_actual_contents('File_8h.html'))
+        self.assertEqual(*self.expected_actual_contents('Class_8h.html'))
+
+    @unittest.expectedFailure
+    def test_empty_file_doc_not_generated(self):
+        self.run_dox2html5(wildcard='Root_8h.xml')
+        self.assertFalse(os.path.exists(os.path.join(self.path, 'html', 'Root_8h.html')))
+
+    def test_namespace(self):
+        self.run_dox2html5(wildcard='namespaceRoot_1_1Directory.xml')
+        self.assertEqual(*self.expected_actual_contents('namespaceRoot_1_1Directory.html'))
+
+    def test_namespace_empty(self):
+        self.run_dox2html5(wildcard='namespaceAnother.xml')
+        self.assertEqual(*self.expected_actual_contents('namespaceAnother.html'))
+
+    def test_class(self):
+        self.run_dox2html5(wildcard='classRoot_1_1Directory_1_1Sub_1_1Class.xml')
+        self.assertEqual(*self.expected_actual_contents('classRoot_1_1Directory_1_1Sub_1_1Class.html'))
+
+    @unittest.expectedFailure
+    def test_empty_class_doc_not_generated(self):
+        self.run_dox2html5(wildcard='union*Bar*.xml')
+        self.assertFalse(os.path.exists(os.path.join(self.path, 'html', 'unionRoot_1_1Directory_1_1Sub_1_1Class_1_1Bar.html')))
+
+    def test_page_toc(self):
+        self.run_dox2html5(wildcard='page-toc.xml')
+        self.assertEqual(*self.expected_actual_contents('page-toc.html'))
+
+    def test_page_no_toc(self):
+        self.run_dox2html5(wildcard='page-no-toc.xml')
+        self.assertEqual(*self.expected_actual_contents('page-no-toc.html'))
+
+class Detailed(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'detailed', *args, **kwargs)
+
+    def test_namespace(self):
+        self.run_dox2html5(wildcard='namespaceNamee.xml')
+        self.assertEqual(*self.expected_actual_contents('namespaceNamee.html'))
+
+    def test_class_template(self):
+        self.run_dox2html5(wildcard='structTemplate.xml')
+        self.assertEqual(*self.expected_actual_contents('structTemplate.html'))
+
+    def test_class_template_specialized(self):
+        self.run_dox2html5(wildcard='structTemplate_3_01void_01_4.xml')
+        self.assertEqual(*self.expected_actual_contents('structTemplate_3_01void_01_4.html'))
+
+    def test_class_template_warnings(self):
+        self.run_dox2html5(wildcard='structTemplateWarning.xml')
+        self.assertEqual(*self.expected_actual_contents('structTemplateWarning.html'))
+
+    def test_function(self):
+        self.run_dox2html5(wildcard='namespaceFoo.xml')
+        self.assertEqual(*self.expected_actual_contents('namespaceFoo.html'))
+
+    def test_enum(self):
+        self.run_dox2html5(wildcard='namespaceEno.xml')
+        self.assertEqual(*self.expected_actual_contents('namespaceEno.html'))
+
+    def test_function_enum_warnings(self):
+        self.run_dox2html5(wildcard='namespaceWarning.xml')
+        self.assertEqual(*self.expected_actual_contents('namespaceWarning.html'))
+
+    def test_typedef(self):
+        self.run_dox2html5(wildcard='namespaceType.xml')
+        self.assertEqual(*self.expected_actual_contents('namespaceType.html'))
+
+    def test_var(self):
+        self.run_dox2html5(wildcard='namespaceVar.xml')
+        self.assertEqual(*self.expected_actual_contents('namespaceVar.html'))
+
+    def test_define(self):
+        self.run_dox2html5(wildcard='File_8h.xml')
+        self.assertEqual(*self.expected_actual_contents('File_8h.html'))
diff --git a/doxygen/test/test_contents.py b/doxygen/test/test_contents.py
new file mode 100644 (file)
index 0000000..ad1410a
--- /dev/null
@@ -0,0 +1,68 @@
+import os
+
+from test import IntegrationTestCase
+
+class Typography(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'typography', *args, **kwargs)
+
+    def test(self):
+        self.run_dox2html5(wildcard='indexpage.xml')
+        self.assertEqual(*self.expected_actual_contents('index.html'))
+
+    def test_warnings(self):
+        self.run_dox2html5(wildcard='warnings.xml')
+        self.assertEqual(*self.expected_actual_contents('warnings.html'))
+
+class Blocks(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'blocks', *args, **kwargs)
+
+    def test(self):
+        self.run_dox2html5(wildcard='indexpage.xml')
+        self.assertEqual(*self.expected_actual_contents('index.html'))
+
+    def test_xrefpages(self):
+        self.run_dox2html5(wildcard='todo.xml')
+        self.assertEqual(*self.expected_actual_contents('todo.html'))
+
+class Code(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'code', *args, **kwargs)
+
+    def test(self):
+        self.run_dox2html5(wildcard='indexpage.xml')
+        self.assertEqual(*self.expected_actual_contents('index.html'))
+
+    def test_warnings(self):
+        self.run_dox2html5(wildcard='warnings.xml')
+        self.assertEqual(*self.expected_actual_contents('warnings.html'))
+
+class Image(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'image', *args, **kwargs)
+
+    def test(self):
+        self.run_dox2html5(wildcard='indexpage.xml')
+        self.assertEqual(*self.expected_actual_contents('index.html'))
+        self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'tiny.png')))
+
+    def test_warnings(self):
+        self.run_dox2html5(wildcard='warnings.xml')
+        self.assertEqual(*self.expected_actual_contents('warnings.html'))
+
+class Math(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'math', *args, **kwargs)
+
+    def test(self):
+        self.run_dox2html5(wildcard='indexpage.xml')
+        self.assertEqual(*self.expected_actual_contents('index.html'))
+
+class Tagfile(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'tagfile', *args, **kwargs)
+
+    def test(self):
+        self.run_dox2html5(wildcard='indexpage.xml')
+        self.assertEqual(*self.expected_actual_contents('index.html'))
diff --git a/doxygen/test/test_doxyfile.py b/doxygen/test/test_doxyfile.py
new file mode 100644 (file)
index 0000000..e33a6ff
--- /dev/null
@@ -0,0 +1,22 @@
+import unittest
+
+from dox2html5 import parse_doxyfile, State
+
+class Doxyfile(unittest.TestCase):
+    def test(self):
+        state = State()
+        parse_doxyfile(state, 'test/doxyfile/Doxyfile')
+        self.assertEqual(state.doxyfile, {
+            'HTML_EXTRA_FILES': ['css', 'another.png', 'hello'],
+            'HTML_EXTRA_STYLESHEET': ['a.css', 'b.css'],
+            'HTML_OUTPUT': 'html',
+            'IMAGE_PATH': [],
+            'M_CLASS_TREE_EXPAND_LEVELS': 1,
+            'M_EXPAND_INNER_TYPES': 0,
+            'M_FILE_TREE_EXPAND_LEVELS': 1,
+            'M_THEME_COLOR': '#22272e',
+            'OUTPUT_DIRECTORY': '',
+            'PROJECT_BRIEF': 'is cool',
+            'PROJECT_NAME': 'My Project',
+            'XML_OUTPUT': 'xml'
+        })
diff --git a/doxygen/test/test_page.py b/doxygen/test/test_page.py
new file mode 100644 (file)
index 0000000..37273b2
--- /dev/null
@@ -0,0 +1,18 @@
+from test import IntegrationTestCase
+
+class Order(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'order', *args, **kwargs)
+
+    def test(self):
+        self.run_dox2html5(index_pages=['pages'], wildcard='index.xml')
+        self.assertEqual(*self.expected_actual_contents('pages.html'))
+
+class DuplicatedBrief(IntegrationTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'duplicated_brief', *args, **kwargs)
+
+    def test(self):
+        self.run_dox2html5(wildcard='page-*.xml')
+        self.assertEqual(*self.expected_actual_contents('page-a.html'))
+        self.assertEqual(*self.expected_actual_contents('page-b.html'))
index 350ea335434ecdecc877af3a2041fcfe02b0c017..2376e8325919cc9e7744693c2f0529c2814bc746 100644 (file)
@@ -5,7 +5,7 @@
   <meta charset="UTF-8" />
   <title>{% block title %}{{ SITENAME }}{% endblock title %}</title>
   {% for href in M_CSS_FILES %}
-  <link rel="stylesheet" href="{{ href|format_siteurl }}" />
+  <link rel="stylesheet" href="{{ href|format_siteurl|e }}" />
   {% endfor %}
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   {% if M_THEME_COLOR %}
index b8385aa768da7001997c5ff17ae8037f465a58c8..85efd76305b86ceaf143404580112cfdafe30cec 100644 (file)
@@ -68,6 +68,7 @@ M_LINKS_NAVBAR2 = [('Pelican plugins', 'plugins/', 'plugins', [
                         ('Images', 'plugins/images/', 'plugins/images'),
                         ('Math and code', 'plugins/math-and-code/', 'plugins/math-and-code'),
                         ('Links', 'plugins/links/', 'plugins/links')]),
+                   ('Doxygen theme', 'doxygen/', 'doxygen', []),
                    ('GitHub', 'https://github.com/mosra/m.css', '', [])]
 
 M_LINKS_FOOTER1 = [('m.css', '/'),
@@ -86,7 +87,9 @@ M_LINKS_FOOTER2 = [('CSS', 'css/'),
 
 M_LINKS_FOOTER3 = [('Pelican', 'pelican/'),
                    ('Writing content', 'pelican/writing-content/'),
-                   ('Theme', 'pelican/theme/')]
+                   ('Theme', 'pelican/theme/'),
+                   ('', ''),
+                   ('Doxygen theme', 'doxygen/')]
 
 M_LINKS_FOOTER4 = [('Pelican plugins', 'plugins/'),
                    ('HTML sanity', 'plugins/htmlsanity/'),
@@ -122,7 +125,7 @@ PLUGINS = ['m.abbr',
 THEME = '../pelican-theme'
 THEME_STATIC_DIR = 'static'
 M_THEME_COLOR = '#22272e'
-M_CSS_FILES = ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i&amp;subset=latin-ext',
+M_CSS_FILES = ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i&subset=latin-ext',
                '/static/m-dark.css',
               #'/static/m-debug.css'
               ]