A Sphinx Site

With sphinx-source, the site is built from your Sphinx project, and the NED reference (and the C++ API) become pages of it:

- uses: omnetpp/doc-builder@v1
  with:
    sphinx-source: doc
    doxygen: true

The action generates the NED reference as reStructuredText into <sphinx-source>/ned (ned-dir) and the C++ API into <sphinx-source>/api (api-dir), then runs sphinx-build in the Sphinx project. Your project refers to them from a toctree:

.. toctree::

   guide
   NED Reference <ned/index>
   C++ Reference <api/index>

and ignores them in git, since they are generated (doc/.gitignore):

/ned/
/api/

The configuration

The action does not change conf.py; it is yours. The image provides Sphinx, sphinx_immaterial and the OMNeT++ extensions (see The Theme and The Extensions). A conf.py that gives the site the look of the OMNeT++ sites:

project = 'My Model'

extensions = [
    'sphinx_immaterial',
    'omnetpp_immaterial',   # the look of the OMNeT++ sites
    'omnetpp_neddoc',       # the :ned: and :msg: roles, NED/MSG highlighting
    'omnetpp_doxylink',     # the :cppref: role (with doxygen: true)
]
html_theme = 'sphinx_immaterial'

doxylink = {'cppref': ('api/tagfile.xml', 'api/')}

omnetpp_neddoc finds the NED reference in ned (its neddoc_dir setting; change it together with ned-dir).

The NED reference and the C++ API have a page per type, too many for the navigation that Sphinx puts into every page. omnetpp_immaterial shows them in the sidebar as trees that the browser loads when the reader opens them: the NED reference by packages, kinds of types and files, the C++ API by namespaces and classes. The trees appear under the entries of ned/index and api/index in your toctree; open the NED Reference of this site to see them.

The pages of the site refer to NED and MSG types and to C++ classes with roles, and highlight NED, MSG and ini code (see Writing Pages).

This site as an example

The site/doc directory of the repository is the Sphinx project of this site. Its conf.py:

import os

project = 'doc-builder'
author = 'OMNeT++ developers'
copyright = '2026, OpenSim Ltd.'

extensions = [
    'sphinx_immaterial',
    'omnetpp_immaterial',   # the look of the OMNeT++ sites
    'omnetpp_neddoc',       # the :ned: and :msg: roles, linking to the NED reference in ned/
    'omnetpp_doxylink',     # the :cppref: role, linking to the C++ API
]

html_theme = 'sphinx_immaterial'
html_title = 'OMNeT++ doc-builder'
html_baseurl = 'https://omnetpp.org/doc-builder/'
html_theme_options = {
    'site_url': html_baseurl,
    'repo_url': 'https://github.com/omnetpp/doc-builder',
    'repo_name': 'omnetpp/doc-builder',
    'icon': {
        'repo': 'fontawesome/brands/github',
        'logo': 'material/book-open-page-variant-outline',
    },
    'globaltoc_collapse': False,
    'toc_title_is_page_title': True,
    'features': [
        'navigation.expand',
        'navigation.instant',
        'navigation.sections',
        'navigation.tabs',
        'navigation.top',
        'search.highlight',
        'toc.follow',
        'toc.sticky',
    ],
    'palette': [
        {
            'media': '(prefers-color-scheme: light)',
            'scheme': 'default',
            'primary': 'indigo',
            'accent': 'deep-orange',
            'toggle': {'icon': 'material/lightbulb-outline', 'name': 'Switch to dark mode'},
        },
        {
            'media': '(prefers-color-scheme: dark)',
            'scheme': 'slate',
            'primary': 'indigo',
            'accent': 'amber',
            'toggle': {'icon': 'material/lightbulb', 'name': 'Switch to light mode'},
        },
    ],
}

# Each tab shows one of the ways the tabs can be navigated (see config/navigation.rst)
omnetpp_nav_no_menu = ['Home']
omnetpp_nav_dropdown = ['Configuration']
omnetpp_nav_nowrap = ['/ned/', '/api/']
# The sample API is too small to reach omnetpp_nav_json_threshold; the tree is what a large API would get
omnetpp_nav_json = ['api/index']

# Untracked files are not counted: the build's own output is among them.
omnetpp_commit = os.popen('git rev-parse --short=10 HEAD').read().strip()
if omnetpp_commit and os.popen('git status --porcelain --untracked-files=no').read():
    omnetpp_commit += '+'
omnetpp_commit = omnetpp_commit or None

# The doc-builder action generates the C++ API into api/, with its doxygen tag file
doxylink = {'cppref': ('api/tagfile.xml', 'api/')}

# The PDF is the guide alone: the NED reference and the C++ API are pages for the web.
latex_documents = [('guide/index', 'doc-builder.tex', 'OMNeT++ doc-builder', author, 'manual')]

To build the site locally while writing it, see Running Locally.