Roles¶
Roles are inline markers that give a fragment of text a special meaning —
formatting it, or turning it into a link.
In the Rendered preview ubCode styles the text-formatting roles,
turns :pep: / :rfc: and the cross-reference roles into links,
and shows any role it does not recognise as a readable placeholder chip
carrying the role name and its content.
This is :strong:`important` and :literal:`inline code`.
Roles work the same way in Markdown (MyST),
written with the curly-brace form ({strong} instead of :strong:);
the role set and its rendering are identical on both surfaces.
This reference describes the Rendered preview mode;
in Structural mode every directive and role renders as a uniform placeholder
(see Authoring).
Where the preview differs from a full sphinx-build,
see Differences from a Sphinx build.
Text styling roles¶
These roles format their content. Role names are matched case-insensitively, and several carry short aliases.
Role (and aliases) |
Rendered as |
|---|---|
|
Italic text |
|
Bold text |
|
Inline code (monospace) |
|
Inline code (monospace);
derive a role from it with |
|
Subscript |
|
Superscript |
|
A citation-style reference, like a cited work title; also the default role for text in bare single backticks (see below) |
|
An abbreviation (no tooltip) |
|
An acronym, styled like an abbreviation |
Text inside a role is shown as-is:
inline markup written within it is not re-parsed,
so *stars* inside :emphasis: appear literally rather than as emphasis.
Math¶
The :math: role typesets an inline LaTeX formula (KaTeX),
in both the preview and a built site:
Euler's identity: :math:`e^{i\pi} + 1 = 0`.
The role text is the LaTeX source, taken verbatim
(backslashes need no doubling inside the backticks).
A formula KaTeX cannot parse is left as its raw source,
with the parse error shown in the tooltip.
Equation numbering and the :eq: cross-reference role are not yet
supported — see Differences from a Sphinx build.
UI and file roles¶
These Sphinx roles describe user-interface elements, files, and other technical text.
Role |
Rendered as |
|---|---|
|
Keystrokes as keycaps; a multi-key sequence
(split on |
|
A user-interface label; an |
|
A menu path; a |
|
A file path in monospace; a |
|
Literal text in monospace; a |
|
A command name (bold) |
|
A program name (bold) |
|
A make variable (bold) |
|
A term being defined (italic) |
|
A MIME type (italic) |
|
A regular expression (monospace) |
|
An abbreviation; a trailing |
Press :kbd:`Ctrl+C` to copy.
Open :menuselection:`File --> Save As...`.
Edit :file:`~/.config/{project}/settings.toml`.
The :abbr:`LIFO (last in, first out)` order applies.
PEP and RFC links¶
:pep: and :rfc: become real external links,
even before the project has been indexed.
:pep:links to the numbered PEP onpeps.python.organd is shown asPEP <number>.:rfc:links to the numbered RFC on the IETF site and is shown asRFC <number>. An#anchorsuffix is appended to the link target, so you can point at a section within the RFC.
See :pep:`8` for style, and :rfc:`2822` for the message format.
Link straight into a section with :rfc:`2822#section-3`.
If the number is not valid — non-numeric, or out of range — the role is shown as a placeholder chip and a diagnostic is reported.
Project link shorthands (extlinks)¶
An extlink role turns a repetitive URL pattern into a short role of your own —
:issue:`42` instead of the full issue-tracker URL every time.
Unlike every role above, the role names are defined by your project.
This comes from Sphinx’s own
sphinx.ext.extlinks
extension, which ubCode implements natively:
enable it and declare one role per [parse.extlinks] entry
in your parsing configuration:
[parse]
extensions = ["sphinx.ext.extlinks"]
[parse.extlinks.issue]
url = "https://github.com/useblocks/ubcode/issues/%s"
caption = "issue %s"
The url is a template in which %s is replaced by the role’s text;
the optional caption templates the link text the same way.
See :issue:`42` for the bug, or :issue:`the tracker <100>` for the epic.
The same roles in Markdown (MyST):
See {issue}`42` for the bug, or {issue}`the tracker <100>` for the epic.
With the caption above,
:issue:`42`renders as issue 42, linking to…/issues/42.Without a
caption, the link text is the fully expanded URL itself.The explicit-title form —
:issue:`the tracker <100>`— uses your title as the link text (the caption is not applied), and the target100fills the%s.The text is substituted into the URL verbatim — it is not URL-encoded — so a target containing spaces produces a URL containing spaces.
An extlink is a direct external link, like :pep: and :rfc: above:
it renders immediately, without waiting for the project index,
and it is styled as a standard external reference.
(A full sphinx-build additionally tags each link
with a CSS class named after the role, extlink-issue;
ubCode does not.)
While the extension is not enabled the configured names are simply unknown roles —
each shows as a placeholder chip — and a [parse.extlinks] table
on its own changes nothing.
A template with more than one %s (write a literal percent as %%),
or a role name that would shadow a built-in role such as ref or pep,
is reported as a configuration warning and that role is skipped;
see Parsing for the details.
Cross-references and hydration¶
Several roles are cross-references: they point at something elsewhere in your project — a labelled location, a document, a glossary term, or a need.
Before the project has been indexed in the background — and for any target that cannot be resolved — a cross-reference shows as a placeholder chip carrying the role name and the target text. Once the background index is ready, the preview is hydrated: each resolved cross-reference becomes a clickable link that opens the target file at the right line. An open preview re-hydrates as indexing progresses, so chips upgrade to links on their own. (For how hydration works across the preview as a whole, see RST preview.)
These roles hydrate into links:
Role |
Links to |
|---|---|
|
A labelled location (a section, or an explicit target) |
|
Another document |
|
A glossary term |
|
A need, by its ID |
|
A need, following an incoming or outgoing link |
See :ref:`installation` for setup.
:ref:`Custom link text <installation>`
:ref:`!installation`
:need:`REQ_001`
:need:`REQ_001.part_a`
Custom link text. The titled form (second line above) uses your text as the link label instead of the target’s own title.
Opting out of a link. Prefixing the target with
!(third line above) keeps the reference as a chip and never turns it into a link, even when the target resolves.Need parts.
:need:also accepts a dotted part reference (last line above); it links to the base need.
With the sphinx.ext.autosectionlabel port enabled
in your parsing configuration,
every section title is a :ref: target of its own,
with no explicit .. _label: written above the section —
:ref:`guide/intro:Overview` with autosectionlabel_prefix_document on —
and the resolved link jumps to the section itself.
See Parsing for the port’s options
and how duplicate titles are resolved.
Not every reference-style role is linked.
:numref: and :any: are not recognised
and render as placeholder chips,
and :need_part: (with its alias :np:) shows its chip
but does not yet become a link.
:download: is the one reference-style role that links to a file
rather than to a target in your project:
write :download:`assets/report.pdf` and ubCode publishes that file
alongside your site and links it as a download.
A target containing :// is linked as an external URL and never copied.
See Downloads for how it names the published file
and how it behaves when the file is not there.
For everything specific to needs — need IDs, link types, and the need cards the preview builds — see Needs.
Finding what you can reference¶
Rather than guessing a target name, ask the project what it can cross-reference:
ubc query search installation # ranked hits, each with the role to paste
ubc query search --kind label # no query: list every label, by name
ubc query search --kind term glossary # search glossary terms only
ubc query search --scope python array # search one intersphinx project only
ubc query search -f json installation # machine-readable
The command (re)indexes the project,
then searches both its own :ref: labels, glossary terms, documents and filed index entries
and every entry of every loaded intersphinx inventory.
Each hit carries the object type, the scope it comes from,
its location, and — the point of the exercise — the exact role to paste,
project-absolute where that matters (:doc:`/guide/install`).
A few things worth knowing:
It searches reference targets and filed index entries, not document content.
--kindaccepts adomain:objtypeglob (py:*,*:label) or one of the shorthandslabel,term,doc,index; a kind that matches nothing is an empty result rather than an error, since any inventory may introduce an object type.--scopeacceptslocal,external, or one configured project name, and anything else is an error listing what would have worked.An
index:entryhit carries no snippet: no role resolves to an index entry, so what it answers is the neighbouring question — is this phrase already indexed, and where?Matching is keyword-based and ANDed, so pass a few specific words or the exact name; an exact name ranks first, and a partial name completes by prefix.
Exit codes suit a script:
0when something was found,1when nothing was,2for a usage, configuration or license error.Need references are deliberately absent: they are graph edges, so
ubc query cypher(see Writing a filter) is their tool.
The same search backs the search_references tool
the MCP server exposes to AI agents.
The default role and custom roles¶
Text written in single backticks with no explicit role uses the default
role, which is :title-reference: unless you change it.
Two things can change it:
The
.. default-role::directive changes the default role from that point in the document onward; a bare.. default-role::resets it to:title-reference:.The
default_rolekey in Parsing seeds the default role for every document in the project.
The .. role:: directive defines a custom role.
A plain custom role renders as a span carrying a CSS class named after the role;
a derived role, written .. role:: name(base),
inherits the behaviour of the existing base role.
The directives themselves are covered on Directives.
Highlighted inline code¶
A role derived from :code: can carry a :language: option,
and its uses render as syntax-highlighted inline code —
the inline twin of the code-block directive,
in both the preview and a built site:
.. role:: python(code)
:language: python
In Python, :python:`1 + 2` is equal to :python:`3`.
The language names are the same Sphinx/Pygments names code blocks accept,
and the value is used exactly as written
(:language: Python and :language: python both resolve,
but the class on the element keeps your spelling).
A language that is not recognised
is shown as plain inline code — never mangled.
A chain of derived roles inherits the language
from the nearest definition that sets one.
The plain :code: role, with no language, renders like :literal:.
A derived role with no :language: does too —
the role’s name is never used as the language,
so .. role:: python(code) on its own does not highlight as Python.
See Differences from a Sphinx build for how highlighted inline code differs from a Sphinx build.
The variant role¶
:variant: resolves a dotted path into your configured variant data
and shows the resolved value as plain text.
Because it belongs with the other variant-authoring constructs,
its full entry lives on its own page:
see Variants.
See also
Directives — the directive reference, including
.. default-role::and.. role::.Needs — needs, need IDs, and need cards.
Differences from a Sphinx build — how the preview differs from a full
sphinx-build.Parsing — the
[parse]configuration, includingdefault_role,extend_rolesfor custom roles from your extensions, and the[parse.extlinks]link-shorthand table.Linting — how diagnostics are surfaced and configured.