import xml.etree.ElementTree as ET
import argparse
import base64
+import copy
import sys
import re
import html
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.
- if not config: config = {
+ default_config = {
'PROJECT_NAME': ['My Project'],
'OUTPUT_DIRECTORY': [''],
'XML_OUTPUT': ['xml'],
'M_SEARCH_EXTERNAL_URL': ['']
}
+ # 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.
+ if not config: config = copy.deepcopy(default_config)
+
def parse_value(var):
if var.group('quote') == '"':
out = [var.group('value')]
logging.warning("{}: unmatchable line {}".format(doxyfile, line)) # pragma: no cover
+ # Some values are set to empty in the default-generated Doxyfile but they
+ # shouldn't be empty. Revert them to our defaults.
+ # TODO: this may behave strange in corner cases where multiple @INCLUDEd
+ # files set or append to the same thing
+ for i in ['HTML_EXTRA_STYLESHEET']:
+ if i in config and not config[i]:
+ config[i] = default_config[i]
+
# String values that we want
for i in ['PROJECT_NAME',
'PROJECT_BRIEF',
--- /dev/null
+<!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-8 m-col-m-none m-left-m">My Project</a>
+ <div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
+ <a href="#search" class="m-dox-search-icon" title="Search" onclick="return showSearch()"><svg viewBox="0 0 16 16">
+ <path d="m6 0c-3.3144 0-6 2.6856-6 6 0 3.3144 2.6856 6 6 6 1.4858 0 2.8463-0.54083 3.8945-1.4355-0.0164 0.33797 0.14734 0.75854 0.5 1.1504l3.2227 3.7891c0.55185 0.6139 1.4517 0.66544 2.002 0.11524 0.55022-0.55022 0.49866-1.4501-0.11524-2.002l-3.7891-3.2246c-0.39184-0.35266-0.81242-0.51469-1.1504-0.5 0.89472-1.0482 1.4355-2.4088 1.4355-3.8945 0-3.3128-2.6856-5.998-6-5.998zm0 1.5625a4.4375 4.4375 0 0 1 4.4375 4.4375 4.4375 4.4375 0 0 1-4.4375 4.4375 4.4375 4.4375 0 0 1-4.4375-4.4375 4.4375 4.4375 0 0 1 4.4375-4.4375z"/>
+ </svg></a>
+ <a id="m-navbar-show" href="#navigation" title="Show navigation"></a>
+ <a id="m-navbar-hide" href="#" title="Hide navigation"></a>
+ </div>
+ <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">Files</a></li>
+ <li class="m-show-m"><a href="#search" class="m-dox-search-icon" title="Search" onclick="return showSearch()"><svg viewBox="0 0 16 16">
+ <path d="m6 0c-3.3144 0-6 2.6856-6 6 0 3.3144 2.6856 6 6 6 1.4858 0 2.8463-0.54083 3.8945-1.4355-0.0164 0.33797 0.14734 0.75854 0.5 1.1504l3.2227 3.7891c0.55185 0.6139 1.4517 0.66544 2.002 0.11524 0.55022-0.55022 0.49866-1.4501-0.11524-2.002l-3.7891-3.2246c-0.39184-0.35266-0.81242-0.51469-1.1504-0.5 0.89472-1.0482 1.4355-2.4088 1.4355-3.8945 0-3.3128-2.6856-5.998-6-5.998zm0 1.5625a4.4375 4.4375 0 0 1 4.4375 4.4375 4.4375 4.4375 0 0 1-4.4375 4.4375 4.4375 4.4375 0 0 1-4.4375-4.4375 4.4375 4.4375 0 0 1 4.4375-4.4375z"/>
+ </svg></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>
+ </div>
+ </div>
+ </div>
+</article></main>
+<div class="m-dox-search" id="search">
+ <a href="#!" onclick="return hideSearch()"></a>
+ <div class="m-container">
+ <div class="m-row">
+ <div class="m-col-m-8 m-push-m-2">
+ <div class="m-dox-search-header m-text m-small">
+ <div><span class="m-label m-default">Tab</span> / <span class="m-label m-default">T</span> to search, <span class="m-label m-default">Esc</span> to close</div>
+ <div id="search-symbolcount">…</div>
+ </div>
+ <div class="m-dox-search-content">
+ <input type="search" id="search-input" placeholder="Loading …" disabled="disabled" autofocus="autofocus" />
+ <noscript class="m-text m-danger m-text-center">Unlike everything else in the docs, the search functionality <em>requires</em> JavaScript.</noscript>
+ <div id="search-help" class="m-text m-dim m-text-center">
+ Search for symbols, directories, files, pages or modules. You can omit any
+ prefix from the symbol or file path; adding a <code>:</code> or <code>/</code>
+ suffix lists all members of given symbol or directory. Navigate through the
+ list using <span class="m-label m-dim">↓</span> and
+ <span class="m-label m-dim">↑</span>, press
+ <span class="m-label m-dim">Enter</span> to go.
+ </div>
+ <div id="search-notfound" class="m-text m-warning m-text-center">Sorry, nothing was found.</div>
+ <ul id="search-results"></ul>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+<script src="search.js"></script>
+<script src="searchdata.js" async="async"></script>
+<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>
#
import os
+import subprocess
from test import BaseTestCase
self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'search.js')))
self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'searchdata.js')))
+class LayoutGeneratedDoxyfile(BaseTestCase):
+ def __init__(self, *args, **kwargs):
+ super().__init__(__file__, 'generated_doxyfile', *args, **kwargs)
+
+ def test(self):
+ if os.path.exists(os.path.join(self.path, 'Doxyfile')):
+ os.remove(os.path.join(self.path, 'Doxyfile'))
+
+ subprocess.run(['doxygen', '-g'], cwd=self.path)
+ self.run_dox2html5(wildcard='indexpage.xml')
+ self.assertEqual(*self.actual_expected_contents('index.html'))
+
class LayoutMinimal(BaseTestCase):
def __init__(self, *args, **kwargs):
super().__init__(__file__, 'minimal', *args, **kwargs)