top-level *Namespaces* item and links to two subdirectories as sub-items of the
*Files* item.
+For custom links in the navbar it's possible to use HTML code directly, both
+for a top-level item or in a submenu. The item is taken as everything from the
+initial :html:`<a` to the first closing :html:`</a>`. In the following snippet,
+there are two top-level items, first linking to the page index and having a
+submenu linking to an e-mail address and a ``fine-print`` page and the second
+linking to a GitHub project page:
+
+.. code:: ini
+
+ M_LINKS_NAVBAR2 = \
+ "pages <a href=\"mailto:mosra@centrum.cz\">Contact</a> fine-print" \
+ "<a href=\"https://github.com/mosra/m.css\">GitHub</a>"
+
`Search options`_
-----------------
type, so either strings, booleans, or lists of strings. The exceptions are:
- The :py:`M_LINKS_NAVBAR1` and :py:`M_LINKS_NAVBAR2` are processed to tuples
- in a form :py:`(title, url, id, sub)` where :py:`title` is link title,
- :py:`url` is link URL, :py:`id` is compound ID (to use for highlighting
- active menu item) and :py:`sub` is a list optionally containing sub-menu
- items. The sub-menu items are in a similarly formed tuple,
- :py:`(title, url, id)`.
+ in a form :py:`(html, title, url, id, sub)` where either :py:`html` is a
+ full HTML code for the link and :py:`title`, :py:`url` :py:`id` is empty;
+ or :py:`html` is :py:`None`, :py:`title` and :py:`url` is a link title and
+ URL and :py:`id` is compound ID (to use for highlighting active menu item).
+ The last item, :py:`sub` is a list optionally containing sub-menu items.
+ The sub-menu items are in a similarly formed tuple,
+ :py:`(html, title, url, id)`.
- The :py:`M_FAVICON` is converted to a tuple of :py:`(url, type)` where
:py:`url` is the favicon URL and :py:`type` is favicon MIME type to
populate the ``type`` attribute of :html:`<link rel="favicon" />`.
# Other compounds are not in any index pages or breadcrumb, so leaf
# name not needed
- # Assign names and URLs to menu items
+ # Assign names and URLs to menu items. The link can be either a predefined
+ # keyword from the below list, a Doxygen symbol, or a HTML code. The
+ # template then gets a tuple of (HTML code, title, URL) and either puts
+ # in the HTML code verbatim (if it's not empty) or creates a link from the
+ # title and URL.
predefined = {
- 'pages': ("Pages", 'pages.html'),
- 'namespaces': ("Namespaces", 'namespaces.html'),
- 'modules': ("Modules", 'modules.html'),
- 'annotated': ("Classes", 'annotated.html'),
- 'files': ("Files", 'files.html')
+ 'pages': (None, "Pages", 'pages.html'),
+ 'namespaces': (None, "Namespaces", 'namespaces.html'),
+ 'modules': (None, "Modules", 'modules.html'),
+ 'annotated': (None, "Classes", 'annotated.html'),
+ 'files': (None, "Files", 'files.html')
}
+ def extract_link(link):
+ # If this is a HTML code, return it verbatim
+ if link.startswith('<a'):
+ return link, None, None
- def find(id):
# If predefined, return those
- if id in predefined:
- return predefined[id]
+ if link in predefined:
+ return predefined[link]
# Otherwise search in symbols
- found = state.compounds[id]
- return found.name, found.url
-
+ found = state.compounds[link]
+ return None, found.name, found.url
i: str
for var in 'M_LINKS_NAVBAR1', 'M_LINKS_NAVBAR2':
navbar_links = []
for i in state.doxyfile[var]:
- links = i.split()
- assert len(links)
+ # Split the line into links. It's either single-word keywords or
+ # HTML <a> elements. If it looks like a HTML, take everything until
+ # the closing </a>, otherwise take everything until the next
+ # whitespace.
+ links = []
+ while i:
+ if i.startswith('<a'):
+ end = i.index('</a>') + 4
+ links += [i[0:end]]
+ i = i[end:]
+ else:
+ firstAndRest = i.split(None, 1)
+ if len(firstAndRest):
+ links += [firstAndRest[0]]
+ if len(firstAndRest) == 1:
+ break;
+ i = firstAndRest[1]
+
sublinks = []
for sublink in links[1:]:
- title, url = find(sublink)
- sublinks += [(title, url, sublink)]
- title, url = find(links[0])
- navbar_links += [(title, url, links[0], sublinks)]
+ html, title, url = extract_link(sublink)
+ sublinks += [(html, title, url, sublink)]
+ html, title, url = extract_link(links[0])
+ navbar_links += [(html, title, url, links[0], sublinks)]
state.doxyfile[var] = navbar_links
<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="{% if M_LINKS_NAVBAR2 %}m-col-t-6{% else %}m-col-t-12{% endif %} m-col-m-none">
- {% for title, link, id, sub in M_LINKS_NAVBAR1 %}
+ {% for html, title, link, id, sub in M_LINKS_NAVBAR1 %}
{% if not sub %}
- <li><a href="{{ link }}"{% if (compound and compound.id == id) or navbar_current == id %} id="m-navbar-current"{% endif %}>{{ title }}</a></li>
+ <li>{% if html %}{{ html }}{% else %}<a href="{{ link }}"{% if (compound and compound.id == id) or navbar_current == id %} id="m-navbar-current"{% endif %}>{{ title }}</a>{% endif %}</li>
{% else %}
<li>
+ {% if html %}
+ {{ html }}
+ {% else %}
<a href="{{ link }}"{% if (compound and compound.id == id) or navbar_current == id %} id="m-navbar-current"{% endif %}>{{ title }}</a>
+ {% endif %}
<ol>
- {% for title, link, id in sub %}
- <li><a href="{{ link }}"{% if (compound and compound.id == id) or navbar_current == id %} id="m-navbar-current"{% endif %}>{{ title }}</a></li>
+ {% for html, title, link, id in sub %}
+ <li>{% if html %}{{ html }}{% else %}<a href="{{ link }}"{% if (compound and compound.id == id) or navbar_current == id %} id="m-navbar-current"{% endif %}>{{ title }}</a>{% endif %}</li>
{% endfor %}
</ol>
</li>
{% if M_LINKS_NAVBAR2 or not M_SEARCH_DISABLED %}
{% set start = M_LINKS_NAVBAR1|length + 1 %}
<ol class="m-col-t-6 m-col-m-none" start="{{ start }}">
- {% for title, link, id, sub in M_LINKS_NAVBAR2 %}
+ {% for html, title, link, id, sub in M_LINKS_NAVBAR2 %}
{% if not sub %}
- <li><a href="{{ link }}"{% if (compound and compound.id == id) or navbar_current == id %} id="m-navbar-current"{% endif %}>{{ title }}</a></li>
+ <li>{% if html %}{{ html }}{% else %}<a href="{{ link }}"{% if (compound and compound.id == id) or navbar_current == id %} id="m-navbar-current"{% endif %}>{{ title }}</a>{% endif %}</li>
{% else %}
<li>
+ {% if html %}
+ {{ html }}
+ {% else %}
<a href="{{ link }}"{% if (compound and compound.id == id) or navbar_current == id %} id="m-navbar-current"{% endif %}>{{ title }}</a>
+ {% endif %}
<ol>
- {% for title, link, id in sub %}
- <li><a href="{{ link }}"{% if (compound and compound.id == id) or navbar_current == id %} id="m-navbar-current"{% endif %}>{{ title }}</a></li>
+ {% for html, title, link, id in sub %}
+ <li>{% if html %}{{ html }}{% else %}<a href="{{ link }}"{% if (compound and compound.id == id) or navbar_current == id %} id="m-navbar-current"{% endif %}>{{ title }}</a>{% endif %}</li>
{% endfor %}
</ol>
</li>
--- /dev/null
+XML_OUTPUT =
+
+##! M_LINKS_NAVBAR1 = \
+##! "<a href=\"javascript:alert('hello!');\">Say hello</a> annotated" \
+##! "files"
+##! M_LINKS_NAVBAR2 = \
+##! "pages <a href=\"mailto:mosra@centrum.cz\">This is an e-mail</a> namespaces" \
+##! "<a href=\"https://github.com/mosra/m.css\">GitHub</a>"
+##! M_PAGE_FINE_PRINT =
+##! M_THEME_COLOR =
+##! M_FAVICON =
+##! M_SEARCH_DISABLED = YES
--- /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" />
+</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="javascript:alert('hello!');">Say hello</a>
+ <ol>
+ <li><a href="annotated.html">Classes</a></li>
+ </ol>
+ </li>
+ <li><a href="files.html">Files</a></li>
+ </ol>
+ <ol class="m-col-t-6 m-col-m-none" start="3">
+ <li>
+ <a href="pages.html">Pages</a>
+ <ol>
+ <li><a href="mailto:mosra@centrum.cz">This is an e-mail</a></li>
+ <li><a href="namespaces.html">Namespaces</a></li>
+ </ol>
+ </li>
+ <li><a href="https://github.com/mosra/m.css">GitHub</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>
+</body>
+</html>
\ 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.14">
+ <compounddef id="indexpage" kind="page">
+ <compoundname>index</compoundname>
+ <title>My Project</title>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ </compounddef>
+</doxygen>
self.run_dox2html5(wildcard='indexpage.xml')
self.assertEqual(*self.actual_expected_contents('index.html'))
+class NavbarHtml(BaseTestCase):
+ def __init__(self, *args, **kwargs):
+ super().__init__(__file__, 'navbar_html', *args, **kwargs)
+
+ def test(self):
+ self.run_dox2html5(wildcard='indexpage.xml')
+ self.assertEqual(*self.actual_expected_contents('index.html'))
+
class SearchBinary(BaseTestCase):
def __init__(self, *args, **kwargs):
super().__init__(__file__, 'search_binary', *args, **kwargs)