# The alt text can apparently be specified only with the HTML
# <img> tag, not with @image. It's also present only since
# 1.9.1(?).
+ # TODO Doxygen seems to be double-escaping this, which
+ # ultimately means we cannot escape this ourselves as it'd be
+ # wrong. See test_contents.HtmlEscape for a repro case.
alt = i.attrib.get('alt', 'Image')
caption = i.text
# Fill breadcrumb with leaf names and URLs
include = []
for i in reversed(path_reverse):
- include += [state.compounds[i].leaf_name]
+ # TODO the escaping / unescaping is a mess, fix that
+ include += [html.unescape(state.compounds[i].leaf_name)]
state.includes['/'.join(include)] = compound.id
# Resolve navbar links that are just an ID
- def resolve_link(html, title, url, id):
- if not html and not title and not url:
+ def resolve_link(html_, title, url, id):
+ if not html_ and not title and not url:
assert id in state.compounds, "Navbar references {} which wasn't found".format(id)
found = state.compounds[id]
title, url = found.name, found.url
- return html, title, url, id
+ return html_, title, url, id
for var in 'LINKS_NAVBAR1', 'LINKS_NAVBAR2':
links = []
- for html, title, url, id, sub in state.config[var]:
- html, title, url, id = resolve_link(html, title, url, id)
+ for html_, title, url, id, sub in state.config[var]:
+ html_, title, url, id = resolve_link(html_, title, url, id)
sublinks = []
for i in sub:
sublinks += [resolve_link(*i)]
- links += [(html, title, url, id, sublinks)]
+ links += [(html_, title, url, id, sublinks)]
state.config[var] = links
def build_search_data(state: State, merge_subtrees=True, add_lookahead_barriers=True, merge_prefixes=True) -> bytearray:
# chars which should fit the full function name in the list in most
# cases, yet be still long enough to be able to distinguish
# particular overloads.
- # TODO: the suffix_length has to be calculated on UTF-8 and I
- # am (un)escaping a lot back and forth here -- needs to be
- # cleaned up
+ # TODO: the suffix_length has to be calculated on UTF-8
params = ', '.join(result.params)
+ assert is_html_safe(params) # this is not C++, so no <>&
if len(params) > 49:
params = params[:48] + '…'
name_with_args += '(' + params + ')'
suffix_length += len(params.encode('utf-8')) + 2
complete_name = joiner.join(result.prefix + [name_with_args])
+ # TODO needs escaping once page names are exposed to search
assert is_html_safe(complete_name) # this is not C++, so no <>&
index = map.add(complete_name, result.url, suffix_length=suffix_length, flags=result.flags)
if name:
lookahead_barriers += [len(name)]
name += joiner
- name += html.unescape(j)
+ # TODO needs escaping once page names are exposed to search
+ assert is_html_safe(j) # this is not C++, so no <>&
+ name += j
trie.insert(name.lower(), index, lookahead_barriers=lookahead_barriers if add_lookahead_barriers else [])
# Add functions the second time with () appended, referencing
if os.path.exists(os.path.join(self.path, 'html')): shutil.rmtree(os.path.join(self.path, 'html'))
def run_doxygen(self, templates=default_templates, wildcard=default_wildcard, index_pages=default_index_pages, config={}):
- state = State({**copy.deepcopy(default_config), **config})
+ state = State(copy.deepcopy(default_config))
parse_doxyfile(state, os.path.join(self.path, self.doxyfile))
+ # Make the supplied config values overwrite what's in the Doxyfile
+ state.config = {**state.config, **config}
run(state, templates=templates, wildcard=wildcard, index_pages=index_pages, sort_globbed_files=True)
def actual_expected_contents(self, actual, expected = None):
--- /dev/null
+INPUT = page.dox Fi&le.h
+IMAGE_PATH = .
+QUIET = YES
+GENERATE_HTML = NO
+GENERATE_LATEX = NO
+GENERATE_XML = YES
+XML_PROGRAMLISTING = NO
+CASE_SENSE_NAMES = YES
+
+# Needed to make the @struct <file> <name> recognized by m.css, otherwise it's
+# ignored as the directory structure gets lost with empty STRIP_FROM_INC_PATH
+STRIP_FROM_INC_PATH = .
+
+##! M_PAGE_FINE_PRINT =
+##! M_THEME_COLOR =
+##! M_FAVICON =
+##! M_LINKS_NAVBAR1 = files
+##! M_LINKS_NAVBAR2 = pages annotated
+##! M_SEARCH_DISABLED = YES
--- /dev/null
+/** @file
+ * @brief The file path should be escaped, in the file list also
+ */
+
+/**
+@brief The class include name as well as derived class reference should be escaped
+*/
+template<class T> struct Class {
+ /** @brief Function */
+ void suffixShouldBeEscaped(const Type<char>::ShouldBeEscaped& = "default value <&> should be escaped") &&;
+
+ /** @brief Enum */
+ enum Enum {
+ Value = Initializer<char&>::ShouldBeEscaped
+ };
+};
+
+template<class, class> struct Sub;
+
+template<class T> struct Sub<char, T>: Class<T> {
+ /** @brief The outer class name should be escaped, in the class list as well */
+ struct Nested {};
+};
+
+/** @struct Sub<char, T> Fi&le.h FakeFi&le.h
+ * @brief The class name as well as base class reference should be escaped, in the class list as well; the faked include should be escaped here too */
+
+/** @brief Function specialization */
+template<> void functionShouldHaveSpecializedNameEscaped<char&>();
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Fi&le.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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 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="files.html">Files</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="2">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="annotated.html">Classes</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>
+ Fi&le.h <span class="m-thin">file</span>
+ </h1>
+ <p>The file path should be escaped, in the file list also.</p>
+ <nav class="m-block m-default">
+ <h3>Contents</h3>
+ <ul>
+ <li>
+ Reference
+ <ul>
+ <li><a href="#nested-classes">Classes</a></li>
+ <li><a href="#func-members">Functions</a></li>
+ </ul>
+ </li>
+ </ul>
+ </nav>
+ <section id="nested-classes">
+ <h2><a href="#nested-classes">Classes</a></h2>
+ <dl class="m-doc">
+ <dt>
+ <div class="m-doc-template">template<class T></div>
+ struct <a href="structClass.html" class="m-doc">Class</a>
+ </dt>
+ <dd>The class include name as well as derived class reference should be escaped.</dd>
+ <dt>
+ <div class="m-doc-template">template<class T></div>
+ struct <a href="structSub_3_01char_00_01T_01_4.html" class="m-doc">Sub<char, T></a>
+ </dt>
+ <dd>The class name as well as base class reference should be escaped, in the class list as well; the faked include should be escaped here too.</dd>
+ <dt>
+ struct <a href="structSub_3_01char_00_01T_01_4_1_1Nested.html" class="m-doc">Sub<char, T>::Nested</a>
+ </dt>
+ <dd>The outer class name should be escaped, in the class list as well.</dd>
+ </dl>
+ </section>
+ <section id="func-members">
+ <h2><a href="#func-members">Functions</a></h2>
+ <dl class="m-doc">
+ <dt id="a3b5d61927252197070e8d998f643a2b2">
+ <div class="m-doc-template">template<></div>
+ <span class="m-doc-wrap-bumper">void <a href="#a3b5d61927252197070e8d998f643a2b2" class="m-doc-self">functionShouldHaveSpecializedNameEscaped<char&></a>(</span><span class="m-doc-wrap">)</span>
+ </dt>
+ <dd>Function specialization.</dd>
+ </dl>
+ </section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 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="files.html">Files</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="2">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="annotated.html" id="m-navbar-current">Classes</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</h1>
+ <ul class="m-doc">
+ <li>struct <a href="structClass.html" class="m-doc">Class</a> <span class="m-doc">The class include name as well as derived class reference should be escaped.</span></li>
+ <li class="m-doc-collapsible collapsed">
+ <a href="#" onclick="return toggle(this)">struct</a> <a href="structSub_3_01char_00_01T_01_4.html" class="m-doc">Sub<char, T></a> <span class="m-doc">The class name as well as base class reference should be escaped, in the class list as well; the faked include should be escaped here too.</span>
+ <ul class="m-doc">
+ <li>struct <a href="structSub_3_01char_00_01T_01_4_1_1Nested.html" class="m-doc">Nested</a> <span class="m-doc">The outer class name should be escaped, in the class list as well.</span></li>
+ </ul>
+ </li>
+ </ul>
+ <script>
+ function toggle(e) {
+ e.parentElement.className = e.parentElement.className == 'm-doc-collapsible' ?
+ 'm-doc-expansible' : 'm-doc-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-doc-expansible';
+ </script>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 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="files.html" id="m-navbar-current">Files</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="2">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="annotated.html">Classes</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</h1>
+ <ul class="m-doc">
+ <li>file <a href="Fi_6le_8h.html" class="m-doc">Fi&le.h</a> <span class="m-doc">The file path should be escaped, in the file list also.</span></li>
+ </ul>
+ <script>
+ function toggle(e) {
+ e.parentElement.className = e.parentElement.className == 'm-doc-collapsible' ?
+ 'm-doc-expansible' : 'm-doc-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-doc-expansible';
+ </script>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Page <&> title <&> should be escaped, in the page list also | 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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 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="files.html">Files</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="2">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="annotated.html">Classes</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 <&> title <&> should be escaped, in the page list also
+ </h1>
+<section id="section"><h2><a href="#section">Section <&> name should be escaped</a></h2><p>The <&> first text before any markup should be escaped. <strong>Yes</strong> The <&> last text after any markup should be escaped.</p><section id="autotoc_md0"><h3><a href="#autotoc_md0">Section level 2 <&> should be escaped</a></h3><section id="autotoc_md1"><h4><a href="#autotoc_md1">Section level 3 <&> should be escaped</a></h4><section id="autotoc_md2"><h5><a href="#autotoc_md2">Section level 4 <&> should be escaped</a></h5></section><section id="autotoc_md3"><h5><a href="#autotoc_md3">5 Section level 5 <&> should be escaped</a></h5><pre>Stuff in a code <&> block <&> should be escaped
+</pre><aside class="m-note m-default"><h4>Paragraph <&> title should be escaped</h4><p>Yes</p></aside><aside class="m-note m-info"><h4>Note</h4><p>Yes</p></aside><p>Text right after a note <&> should be escaped</p><blockquote><p>Text in a blockquote <&> should be escaped</p></blockquote><aside class="m-note m-default"><h4>Id</h4><p>some strange RCS <&> content should be escaped</p></aside><figure class="m-figure"><img src="tiny.png" alt="Image" /><figcaption>Image <&> title should be escaped</figcaption></figure><img class="m-image" src="tiny.png" alt="Image" /><p><a href="https://mcss.mosra.cz/?url<&>should-be-escaped">Yes</a></p></section></section></section></section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /dev/null
+/**
+@page page Page <&> title <&> should be escaped, in the page list also
+
+@section section Section <&> name should be escaped
+
+The <&> first text before any markup should be escaped. <b>Yes</b>
+The <&> last text after any markup should be escaped.
+
+## Section level 2 <&> should be escaped
+
+### Section level 3 <&> should be escaped
+
+#### Section level 4 <&> should be escaped
+
+####5 Section level 5 <&> should be escaped
+
+ Stuff in a code <&> block <&> should be escaped
+
+@par Paragraph <&> title should be escaped
+ Yes
+
+@note Yes
+
+Text right after a note <&> should be escaped
+
+> Text in a blockquote <&> should be escaped
+
+$Id: some strange RCS <&> content should be escaped $
+
+@image html tiny.png "Image <&> title should be escaped"
+
+<img src="tiny.png" alt="Image <&> alt should be escaped, but only because Doxygen forgets to unescape when parsing and so m.css doesn't escape again"/>
+
+<a href="https://mcss.mosra.cz/?url<&>should-be-escaped">Yes</a>
+*/
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Page <&> title <&> should be escaped, in the page list also | 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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 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="files.html">Files</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="2">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="annotated.html">Classes</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 <&> title <&> should be escaped, in the page list also
+ </h1>
+<section id="section"><h2><a href="#section">Section <&> name should be escaped</a></h2><p>The <&> first text before any markup should be escaped. <strong>Yes</strong> The <&> last text after any markup should be escaped.</p><section id="autotoc_md0"><h3><a href="#autotoc_md0">Section level 2 <&> should be escaped</a></h3><section id="autotoc_md1"><h4><a href="#autotoc_md1">Section level 3 <&> should be escaped</a></h4><section id="autotoc_md2"><h5><a href="#autotoc_md2">Section level 4 <&> should be escaped</a></h5></section><section id="autotoc_md3"><h5><a href="#autotoc_md3">5 Section level 5 <&> should be escaped</a></h5><pre>Stuff in a code <&> block <&> should be escaped
+</pre><aside class="m-note m-default"><h4>Paragraph <&> title should be escaped</h4><p>Yes</p></aside><aside class="m-note m-info"><h4>Note</h4><p>Yes</p></aside><p>Text right after a note <&> should be escaped</p><blockquote><p>Text in a blockquote <&> should be escaped</p></blockquote><aside class="m-note m-default"><h4>Id</h4><p>some strange RCS <&> content should be escaped</p></aside><figure class="m-figure"><img src="tiny.png" alt="Image" /><figcaption>Image <&> title should be escaped</figcaption></figure><img class="m-image" src="tiny.png" alt="Image <&> alt should be escaped, but only because Doxygen forgets to unescape when parsing and so m.css doesn't escape again" /><p><a href="https://mcss.mosra.cz/?url<&>should-be-escaped">Yes</a></p></section></section></section></section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 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="files.html">Files</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="2">
+ <li><a href="pages.html" id="m-navbar-current">Pages</a></li>
+ <li><a href="annotated.html">Classes</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</h1>
+ <ul class="m-doc">
+ <li><a href="page.html" class="m-doc">Page <&> title <&> should be escaped, in the page list also</a> <span class="m-doc"></span></li>
+ </ul>
+ <script>
+ function toggle(e) {
+ e.parentElement.className = e.parentElement.className == 'm-doc-collapsible' ?
+ 'm-doc-expansible' : 'm-doc-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-doc-expansible';
+ </script>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Class 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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 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="files.html">Files</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="2">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="annotated.html">Classes</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-doc-include m-code m-inverted m-right-m m-text-right"><span class="cp">#include</span> <a class="cpf" href="Fi_6le_8h.html"><Fi&le.h></a></div>
+ <div class="m-doc-template">template<class T></div>
+ Class <span class="m-thin">struct</span>
+ </h1>
+ <p>The class include name as well as derived class reference should be escaped.</p>
+ <nav class="m-block m-default">
+ <h3>Contents</h3>
+ <ul>
+ <li>
+ Reference
+ <ul>
+ <li><a href="#derived-classes">Derived classes</a></li>
+ <li><a href="#pub-types">Public types</a></li>
+ <li><a href="#pub-methods">Public functions</a></li>
+ </ul>
+ </li>
+ </ul>
+ </nav>
+ <section id="derived-classes">
+ <h2><a href="#derived-classes">Derived classes</a></h2>
+ <dl class="m-doc">
+ <dt>
+ <div class="m-doc-template">template<class T></div>
+ struct <a href="structSub_3_01char_00_01T_01_4.html" class="m-doc">Sub<char, T></a>
+ </dt>
+ <dd>The class name as well as base class reference should be escaped, in the class list as well; the faked include should be escaped here too.</dd>
+ </dl>
+ </section>
+ <section id="pub-types">
+ <h2><a href="#pub-types">Public types</a></h2>
+ <dl class="m-doc">
+ <dt id="abc566500394204b1aff6106bb4559e18">
+ <span class="m-doc-wrap-bumper">enum <a href="#abc566500394204b1aff6106bb4559e18" class="m-doc-self">Enum</a> { </span><span class="m-doc-wrap"><a href="#abc566500394204b1aff6106bb4559e18a1f46b75c9c2abcdd838e6ff824a60db9" class="m-doc">Value</a> = Initializer<char&>::ShouldBeEscaped }</span>
+ </dt>
+ <dd>Enum.</dd>
+ </dl>
+ </section>
+ <section id="pub-methods">
+ <h2><a href="#pub-methods">Public functions</a></h2>
+ <dl class="m-doc">
+ <dt id="a0dbbef222ebfc3607c4ad7283ec260c3">
+ <span class="m-doc-wrap-bumper">void <a href="#a0dbbef222ebfc3607c4ad7283ec260c3" class="m-doc-self">suffixShouldBeEscaped</a>(</span><span class="m-doc-wrap">const Type<char>::ShouldBeEscaped& = "default value <&> should be escaped") &&</span>
+ </dt>
+ <dd>Function.</dd>
+ </dl>
+ </section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Sub<char, T> 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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 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="files.html">Files</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="2">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="annotated.html">Classes</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-doc-include m-code m-inverted m-right-m m-text-right"><span class="cp">#include</span> <a class="cpf" href="Fi_6le_8h.html"><FakeFi&le.h></a></div>
+ <div class="m-doc-template">template<class T></div>
+ Sub<char, T> <span class="m-thin">struct</span>
+ </h1>
+ <p>The class name as well as base class reference should be escaped, in the class list as well; the faked include should be escaped here too.</p>
+ <nav class="m-block m-default">
+ <h3>Contents</h3>
+ <ul>
+ <li>
+ Reference
+ <ul>
+ <li><a href="#base-classes">Base classes</a></li>
+ <li><a href="#pub-types">Public types</a></li>
+ </ul>
+ </li>
+ </ul>
+ </nav>
+ <section id="base-classes">
+ <h2><a href="#base-classes">Base classes</a></h2>
+ <dl class="m-doc">
+ <dt>
+ <div class="m-doc-template">template<class T></div>
+ struct <a href="structClass.html" class="m-doc">Class<T></a>
+ </dt>
+ <dd>The class include name as well as derived class reference should be escaped.</dd>
+ </dl>
+ </section>
+ <section id="pub-types">
+ <h2><a href="#pub-types">Public types</a></h2>
+ <dl class="m-doc">
+ <dt>
+ struct <a href="structSub_3_01char_00_01T_01_4_1_1Nested.html" class="m-doc">Nested</a>
+ </dt>
+ <dd>The outer class name should be escaped, in the class list as well.</dd>
+ </dl>
+ </section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Sub<char, T>::Nested 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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 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="files.html">Files</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="2">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="annotated.html">Classes</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="structSub_3_01char_00_01T_01_4.html">Sub<char, T></a>::<wbr/></span>Nested <span class="m-thin">struct</span>
+ <div class="m-doc-include m-code m-inverted m-text-right"><span class="cp">#include</span> <a class="cpf" href="Fi_6le_8h.html"><Fi&le.h></a></div>
+ </h1>
+ <p>The outer class name should be escaped, in the class list as well.</p>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /dev/null
+../../../plugins/m/test/images/tiny.png
\ No newline at end of file
--- /dev/null
+<?xml version='1.0' encoding='UTF-8' standalone='no'?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.8.18">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+<para><blockquote><para>A blockquote. </para>
+</blockquote><verbatim>Preformatted text.
+</verbatim></para>
+<para>Paragraph <linebreak/>
+ with <linebreak/>
+ explicit <linebreak/>
+ line <linebreak/>
+ breaks.</para>
+<sect1 id="index_1section">
+<title>Page section</title>
+<para><preformatted>Differently
+ preformatted
+text.</preformatted></para>
+<para><itemizedlist>
+<listitem><para>Unordered</para>
+</listitem><listitem><para>list</para>
+</listitem><listitem><para>of<itemizedlist>
+<listitem><para>nested</para>
+</listitem><listitem><para>items</para>
+</listitem></itemizedlist>
+</para>
+</listitem><listitem><para>and back</para>
+</listitem></itemizedlist>
+<orderedlist>
+<listitem><para>Ordered</para>
+</listitem><listitem><para>list</para>
+</listitem><listitem><para>of<orderedlist>
+<listitem><para>nested</para>
+</listitem><listitem><para>items</para>
+</listitem></orderedlist>
+</para>
+</listitem><listitem><para>and back</para>
+</listitem></orderedlist>
+</para>
+<para><anchor id="index_1an-anchor"/> This is a <computeroutput>typewriter text</computeroutput>, <emphasis>emphasis</emphasis>, <bold>bold</bold>. <emphasis>Emphasis with <computeroutput>typewriter</computeroutput> and <bold>bold</bold> nested.</emphasis> <ulink url="http://google.com">http://google.com</ulink> and <ulink url="http://google.com">URL</ulink>. <small>Small <emphasis>text</emphasis>.</small> En-dash <ndash/> and em-dash <mdash/>. Reference to a <ref refid="index_1section" kindref="member">Page section</ref>. Named reference with special characters in title: <ref refid="index_1section" kindref="member"><raquo/> Warnings <laquo/></ref>. Reference with escaped characters in<nonbreakablespace/>title: <ref refid="index_1an-anchor" kindref="member"><anchor></ref>.</para>
+<para>2<superscript>nd</superscript> is L<subscript><infin/></subscript> <forall/> <nabla/> <pi/> <real/> <imaginary/> This costs no $, <euro/>, <pound/>, <yen/> or <curren/>.</para>
+<para>Empty elements: <emphasis></emphasis> <computeroutput></computeroutput> <bold></bold> <preformatted></preformatted> <small></small></para>
+<para><hruler/>
+</para>
+<para>Above is a horizontal line. </para>
+</sect1>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
from hashlib import sha1
+from doxygen import EntryType
+from _search import pretty_print, searchdata_filename
+
from . import BaseTestCase, IntegrationTestCase, doxygen_version, parse_version
def dot_version():
self.assertEqual(*self.actual_expected_contents('index.html'))
else:
self.assertEqual(*self.actual_expected_contents('index.html', 'index-pygments29.html'))
+
+class HtmlEscape(IntegrationTestCase):
+ def setUp(self):
+ IntegrationTestCase.setUp(self)
+
+ # Doxygen does *almost* a good job of escaping everything, except the
+ # bit in <includes>. Patch that up.
+ for i in [
+ 'structClass.xml',
+ 'structSub_3_01char_00_01T_01_4.xml',
+ 'structSub_3_01char_00_01T_01_4_1_1Nested.xml',
+ # These two are broken only in 1.8.16 and older, the second one
+ # isn't actually used for anything but still produces an error log
+ # if not patched.
+ 'Fi_6le_8h.xml',
+ 'structSub.xml'
+ ]:
+ with open(os.path.join(self.path, 'xml', i), 'r+') as f:
+ contents = f.read()
+ f.seek(0)
+ f.truncate(0)
+ f.write(contents.replace('Fi&le.h', 'Fi&le.h'))
+
+ def test(self):
+ self.run_doxygen(wildcard='*.xml')
+
+ # Page title escaping, content escaping
+ self.assertEqual(*self.actual_expected_contents('pages.html'))
+
+ # Versions before 1.9.1(?) don't have the alt attribute preserved for
+ # <img>
+ if parse_version(doxygen_version()) >= parse_version("1.9.1"):
+ self.assertEqual(*self.actual_expected_contents('page.html'))
+ else:
+ self.assertEqual(*self.actual_expected_contents('page.html', 'page-1820.html'))
+
+ # Filename escaping
+ self.assertEqual(*self.actual_expected_contents('files.html'))
+ self.assertEqual(*self.actual_expected_contents('Fi_6le_8h.html'))
+
+ # Class name escaping; include, symbol and value escaping
+ self.assertEqual(*self.actual_expected_contents('annotated.html'))
+ self.assertEqual(*self.actual_expected_contents('structClass.html'))
+ self.assertEqual(*self.actual_expected_contents('structSub_3_01char_00_01T_01_4.html'))
+ self.assertEqual(*self.actual_expected_contents('structSub_3_01char_00_01T_01_4_1_1Nested.html'))
+
+ def test_search(self):
+ # Re-run everything with search enabled, the search data shouldn't be
+ # escaped. Not done as part of above as it'd unnecessarily inflate the
+ # size of compared files with the search icon and popup.
+ self.run_doxygen(index_pages=[], wildcard='*.xml', config={
+ 'SEARCH_DISABLED': False,
+ 'SEARCH_DOWNLOAD_BINARY': True
+ })
+
+ with open(os.path.join(self.path, 'html', searchdata_filename.format(search_filename_prefix='searchdata')), 'rb') as f:
+ serialized = f.read()
+ search_data_pretty = pretty_print(serialized, entryTypeClass=EntryType)[0]
+ # print(search_data_pretty)
+ self.assertEqual(search_data_pretty, """
+8 symbols
+fi&le.h [2]
+|| :$
+|| :functionshouldhavespecializednameescaped<char&> [0]
+|| ($
+|| ) [1]
+|unctionshouldhavespecializednameescaped<char&> [0]
+|| ($
+|| ) [1]
+page <&> title <&> should be escaped, in the page list also [3]
+class [7]
+| :$
+| :enum [4]
+| suffixshouldbeescaped [5]
+| | ($
+| | ) [6]
+enum [4]
+suffixshouldbeescaped [5]
+| | ($
+| | ) [6]
+| b<char, t> [8]
+| | :$
+| | :nested [9]
+nested [9]
+0: ::functionShouldHaveSpecializedNameEscaped<char&>() [prefix=2[:14], suffix_length=2, type=FUNC] -> #a3b5d61927252197070e8d998f643a2b2
+1: [prefix=0[:48], type=FUNC] ->
+2: Fi&le.h [type=FILE] -> Fi_6le_8h.html
+3: Page <&> title <&> should be escaped, in the page list also [type=PAGE] -> page.html
+4: ::Enum [prefix=7[:16], type=ENUM] -> #abc566500394204b1aff6106bb4559e18
+5: ::suffixShouldBeEscaped(const Type<char>::ShouldBeEscaped&) && [prefix=7[:16], suffix_length=39, type=FUNC] -> #a0dbbef222ebfc3607c4ad7283ec260c3
+6: [prefix=5[:50], suffix_length=37, type=FUNC] ->
+7: Class [type=STRUCT] -> structClass.html
+8: Sub<char, T> [type=STRUCT] -> structSub_3_01char_00_01T_01_4.html
+9: ::Nested [prefix=8[:30], type=STRUCT] -> _1_1Nested.html
+(EntryType.PAGE, CssClass.SUCCESS, 'page'),
+(EntryType.NAMESPACE, CssClass.PRIMARY, 'namespace'),
+(EntryType.GROUP, CssClass.SUCCESS, 'group'),
+(EntryType.CLASS, CssClass.PRIMARY, 'class'),
+(EntryType.STRUCT, CssClass.PRIMARY, 'struct'),
+(EntryType.UNION, CssClass.PRIMARY, 'union'),
+(EntryType.TYPEDEF, CssClass.PRIMARY, 'typedef'),
+(EntryType.DIR, CssClass.WARNING, 'dir'),
+(EntryType.FILE, CssClass.WARNING, 'file'),
+(EntryType.FUNC, CssClass.INFO, 'func'),
+(EntryType.DEFINE, CssClass.INFO, 'define'),
+(EntryType.ENUM, CssClass.PRIMARY, 'enum'),
+(EntryType.ENUM_VALUE, CssClass.DEFAULT, 'enum val'),
+(EntryType.VAR, CssClass.DEFAULT, 'var')
+""".strip())
set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${target})
endforeach()
+# Need a special location for this one
+pybind11_add_module(pybind_content_html_escape content_html_escape/content_html_escape/pybind.cpp)
+set_target_properties(pybind_content_html_escape PROPERTIES
+ OUTPUT_NAME pybind
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/content_html_escape/content_html_escape)
+
# Need a special location for this one
pybind11_add_module(pybind_inspect_create_intersphinx inspect_create_intersphinx/inspect_create_intersphinx/pybind.cpp)
set_target_properties(pybind_inspect_create_intersphinx PROPERTIES
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>content_html_escape.Class | My Python 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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 Python Project</a>
+ <div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
+ <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-12 m-col-m-none">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="modules.html">Modules</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="content_html_escape.html">content_html_escape</a>.<wbr/></span>Class <span class="m-thin">class</span>
+ </h1>
+ <nav class="m-block m-default">
+ <h3>Contents</h3>
+ <ul>
+ <li>
+ Reference
+ <ul>
+ <li><a href="#enums">Enums</a></li>
+ <li><a href="#classmethods">Class methods</a></li>
+ <li><a href="#staticmethods">Static methods</a></li>
+ <li><a href="#methods">Methods</a></li>
+ <li><a href="#dunder-methods">Special methods</a></li>
+ <li><a href="#data">Data</a></li>
+ </ul>
+ </li>
+ </ul>
+ </nav>
+ <section id="enums">
+ <h2><a href="#enums">Enums</a></h2>
+ <dl class="m-doc">
+ <dt id="ClassEnum">
+ <span class="m-doc-wrap-bumper">class <a href="#ClassEnum" class="m-doc-self">ClassEnum</a>(enum.Enum): </span><span class="m-doc-wrap"><a href="#ClassEnum-VALUE_THAT_SHOULD_BE_ESCAPED" class="m-doc-self" id="ClassEnum-VALUE_THAT_SHOULD_BE_ESCAPED">VALUE_THAT_SHOULD_BE_ESCAPED</a> = '<&>'</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ <section id="classmethods">
+ <h2><a href="#classmethods">Class methods</a></h2>
+ <dl class="m-doc">
+ <dt id="classmethod">
+ <span class="m-doc-wrap-bumper">def <a href="#classmethod" class="m-doc-self">classmethod</a>(</span><span class="m-doc-wrap">default_string_that_should_be_escaped = '<&>')</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ <section id="staticmethods">
+ <h2><a href="#staticmethods">Static methods</a></h2>
+ <dl class="m-doc">
+ <dt id="staticmethod">
+ <span class="m-doc-wrap-bumper">def <a href="#staticmethod" class="m-doc-self">staticmethod</a>(</span><span class="m-doc-wrap">default_string_that_should_be_escaped = '<&>')</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ <section id="methods">
+ <h2><a href="#methods">Methods</a></h2>
+ <dl class="m-doc">
+ <dt id="method">
+ <span class="m-doc-wrap-bumper">def <a href="#method" class="m-doc-self">method</a>(</span><span class="m-doc-wrap">self,
+ default_string_that_should_be_escaped = '<&>')</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ <section id="dunder-methods">
+ <h2><a href="#dunder-methods">Special methods</a></h2>
+ <dl class="m-doc">
+ <dt id="__dunder_method__">
+ <span class="m-doc-wrap-bumper">def <a href="#__dunder_method__" class="m-doc-self">__dunder_method__</a>(</span><span class="m-doc-wrap">self,
+ default_string_that_should_be_escaped = '<&>')</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ <section id="data">
+ <h2><a href="#data">Data</a></h2>
+ <dl class="m-doc">
+ <dt id="DATA_THAT_SHOULD_BE_ESCAPED">
+ <a href="#DATA_THAT_SHOULD_BE_ESCAPED" class="m-doc-self">DATA_THAT_SHOULD_BE_ESCAPED</a> = '<&>'
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>content_html_escape | My Python 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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 Python Project</a>
+ <div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
+ <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-12 m-col-m-none">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="modules.html">Modules</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_html_escape <span class="m-thin">module</span>
+ </h1>
+ <p>Summary that should be <&> escaped <&></p>
+ <nav class="m-block m-default">
+ <h3>Contents</h3>
+ <ul>
+ <li>
+ Reference
+ <ul>
+ <li><a href="#packages">Modules</a></li>
+ <li><a href="#classes">Classes</a></li>
+ <li><a href="#enums">Enums</a></li>
+ <li><a href="#functions">Functions</a></li>
+ <li><a href="#data">Data</a></li>
+ </ul>
+ </li>
+ </ul>
+ </nav>
+<p>Details that *aren't* rST-processed and thus should only be <&> escaped <&>.</p>
+ <section id="namespaces">
+ <h2><a href="#namespaces">Modules</a></h2>
+ <dl class="m-doc">
+ <dt>module <a href="content_html_escape.pybind.html" class="m-doc">pybind</a></dt>
+ <dd>pybind11 html escaping</dd>
+ </dl>
+ </section>
+ <section id="classes">
+ <h2><a href="#classes">Classes</a></h2>
+ <dl class="m-doc">
+ <dt>class <a href="content_html_escape.Class.html" class="m-doc">Class</a></dt>
+ <dd></dd>
+ </dl>
+ </section>
+ <section id="enums">
+ <h2><a href="#enums">Enums</a></h2>
+ <dl class="m-doc">
+ <dt id="Enum">
+ <span class="m-doc-wrap-bumper">class <a href="#Enum" class="m-doc-self">Enum</a>(enum.Enum): </span><span class="m-doc-wrap"><a href="#Enum-VALUE_THAT_SHOULD_BE_ESCAPED" class="m-doc-self" id="Enum-VALUE_THAT_SHOULD_BE_ESCAPED">VALUE_THAT_SHOULD_BE_ESCAPED</a> = '<&>'</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ <section id="functions">
+ <h2><a href="#functions">Functions</a></h2>
+ <dl class="m-doc">
+ <dt id="function">
+ <span class="m-doc-wrap-bumper">def <a href="#function" class="m-doc-self">function</a>(</span><span class="m-doc-wrap">default_string_that_should_be_escaped = '<&>',
+ default_function_that_should_be_escaped = <function <lambda>>)</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ <section id="data">
+ <h2><a href="#data">Data</a></h2>
+ <dl class="m-doc">
+ <dt id="DATA_THAT_SHOULD_BE_ESCAPED">
+ <a href="#DATA_THAT_SHOULD_BE_ESCAPED" class="m-doc-self">DATA_THAT_SHOULD_BE_ESCAPED</a> = '<&>'
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>content_html_escape.pybind | My Python 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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 Python Project</a>
+ <div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
+ <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-12 m-col-m-none">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="modules.html">Modules</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="content_html_escape.html">content_html_escape</a>.<wbr/></span>pybind <span class="m-thin">module</span>
+ </h1>
+ <p>pybind11 html escaping</p>
+ <nav class="m-block m-default">
+ <h3>Contents</h3>
+ <ul>
+ <li>
+ Reference
+ <ul>
+ <li><a href="#functions">Functions</a></li>
+ </ul>
+ </li>
+ </ul>
+ </nav>
+ <section id="functions">
+ <h2><a href="#functions">Functions</a></h2>
+ <dl class="m-doc">
+ <dt id="default_value_should_be_escaped">
+ <span class="m-doc-wrap-bumper">def <a href="#default_value_should_be_escaped" class="m-doc-self">default_value_should_be_escaped</a>(</span><span class="m-doc-wrap">string: str = '<&>') -> int</span>
+ </dt>
+ <dd></dd>
+ </dl>
+ </section>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /dev/null
+"""
+Summary that should be <&> escaped <&>
+
+Details that *aren't* rST-processed and thus should only be <&> escaped <&>.
+"""
+
+import enum
+
+from . import pybind
+
+# TODO page names can be escaped!
+
+class Class:
+ class ClassEnum(enum.Enum):
+ VALUE_THAT_SHOULD_BE_ESCAPED = "<&>"
+
+ @staticmethod
+ def staticmethod(default_string_that_should_be_escaped = "<&>"):
+ pass
+
+ @classmethod
+ def classmethod(cls, default_string_that_should_be_escaped = "<&>"):
+ pass
+
+ def __dunder_method__(self, default_string_that_should_be_escaped = "<&>"):
+ pass
+
+ def method(self, default_string_that_should_be_escaped = "<&>"):
+ pass
+
+ DATA_THAT_SHOULD_BE_ESCAPED = "<&>"
+
+class Enum(enum.Enum):
+ VALUE_THAT_SHOULD_BE_ESCAPED = "<&>"
+
+def function(default_string_that_should_be_escaped = "<&>", default_function_that_should_be_escaped = lambda a: a):
+ pass
+
+DATA_THAT_SHOULD_BE_ESCAPED = "<&>"
--- /dev/null
+#include <pybind11/pybind11.h>
+
+namespace py = pybind11;
+
+int defaultValueShouldBeEscaped(const char*) { return 0; }
+
+PYBIND11_MODULE(pybind, m) {
+ m.doc() = "pybind11 html escaping";
+
+ m.def("default_value_should_be_escaped", defaultValueShouldBeEscaped, py::arg("string") = "<&>");
+}
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>Page title that should be <&> escaped <&>, and also in the page tree | My Python 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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 Python Project</a>
+ <div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
+ <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-12 m-col-m-none">
+ <li><a href="pages.html">Pages</a></li>
+ <li><a href="modules.html">Modules</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 title that should be <&> escaped <&>, and also in the page tree
+ </h1>
+<p>Page content that <&> <em>is</em> rST-processed <&> and thus gets escaped by docutils.</p>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
--- /dev/null
+Page title that should be <&> escaped <&>, and also in the page tree
+####################################################################
+
+Page content that <&> *is* rST-processed <&> and thus gets escaped by docutils.
--- /dev/null
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <title>My Python 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+documentation.compiled.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</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 Python Project</a>
+ <div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
+ <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-12 m-col-m-none">
+ <li><a href="pages.html" id="m-navbar-current">Pages</a></li>
+ <li><a href="modules.html">Modules</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</h1>
+ <ul class="m-doc">
+ <li><a href="page.html" class="m-doc">Page title that should be <&> escaped <&>, and also in the page tree</a> <span class="m-doc"></span></li>
+ </ul>
+ <script>
+ function toggle(e) {
+ e.parentElement.className = e.parentElement.className == 'm-doc-collapsible' ?
+ 'm-doc-expansible' : 'm-doc-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-doc-expansible';
+ </script>
+ </div>
+ </div>
+ </div>
+</article></main>
+</body>
+</html>
#
import os
+import unittest
from . import BaseInspectTestCase
+from _search import pretty_print, searchdata_filename
+from python import EntryType
+
class Content(BaseInspectTestCase):
def test(self):
self.run_python({
})
self.assertEqual(*self.actual_expected_contents('content_parse_docstrings.html'))
self.assertEqual(*self.actual_expected_contents('content_parse_docstrings.Class.html'))
+
+class HtmlEscape(BaseInspectTestCase):
+ def test(self):
+ self.run_python({
+ 'INPUT_PAGES': ['page.rst'],
+ 'PYBIND11_COMPATIBILITY': True,
+ 'LINKS_NAVBAR1': [
+ ('Pages', 'pages', []),
+ ('Modules', 'modules', [])],
+ })
+
+ # Page title escaping
+ self.assertEqual(*self.actual_expected_contents('page.html'))
+ self.assertEqual(*self.actual_expected_contents('pages.html'))
+
+ # Value escaping
+ self.assertEqual(*self.actual_expected_contents('content_html_escape.html'))
+ self.assertEqual(*self.actual_expected_contents('content_html_escape.Class.html'))
+ self.assertEqual(*self.actual_expected_contents('content_html_escape.pybind.html'))
+
+ @unittest.skip("Page names are currently not exposed to search and there's nothing else that would require escaping, nothing to test")
+ def test_search(self):
+ # Re-run everything with search enabled, the search data shouldn't be
+ # escaped. Not done as part of above as it'd unnecessarily inflate the
+ # size of compared files with the search icon and popup.
+ self.run_python({
+ 'INPUT_PAGES': ['page.rst'],
+ 'PYBIND11_COMPATIBILITY': True,
+ 'SEARCH_DISABLED': False,
+ 'SEARCH_DOWNLOAD_BINARY': True
+ })
+
+ with open(os.path.join(self.path, 'output', searchdata_filename.format(search_filename_prefix='searchdata')), 'rb') as f:
+ serialized = f.read()
+ search_data_pretty = pretty_print(serialized, entryTypeClass=EntryType)[0]
+ # print(search_data_pretty)
+ self.assertEqual(search_data_pretty, """
+TODO
+""".strip())