Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 175 additions & 0 deletions docs/reference/restructuredtext/term-index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
.. include:: /include.rst.txt

.. _term-index:

==========
Term index
==========

.. contents::

.. index:: reST directives; seealso

The ``index`` directive marks terms for a project-wide index, the way a
printed book's index points readers from a term to every page that discusses
it. Collected entries can then be rendered as a ``genindex`` page, either
project-wide or scoped to part of the project (e.g. one changelog version).

.. _index-directive:

The ``index`` directive
=======================

Collects one or more entries, project-wide, to be aggregated into a
``genindex`` page later. The directive itself is invisible in the rendered
page -- it produces no visible output where it's written.

Entry types
-----------

Each line of an ``index`` directive declares one entry. The prefix before the
first colon selects the entry type; without a recognized prefix, the whole
line is treated as a plain ``single`` term:

``single``
A top-level term, optionally with a subterm:

.. code-block::

.. index:: single: installation
.. index:: single: installation; troubleshooting

``pair``
Shorthand for two reciprocal ``single`` entries, so the term is findable
either way round:

.. code-block::

.. index:: pair: configuration; file

This is equivalent to writing both
``single: configuration; file`` and ``single: file; configuration``.

``triple``
Shorthand for three reciprocal entries covering every rotation of the
given terms:

.. code-block::

.. index:: triple: access; token; refresh

``module``
Nests the given name under a literal top-level "module" term:

.. code-block::

.. index:: module: Acme\Bundle\FooBundle

``see`` / ``seealso``
A cross-reference from one term to another, rendered without its own
link -- only as a pointer to the target term:

.. code-block::

.. index:: see: token; access token
.. index:: seealso: OAuth; access token

Prefixing an entry with ``!`` marks it as the "main" definition of that term,
which themes can render distinctly (e.g. bold) from its other occurrences:

.. code-block::

.. index:: ! access token

Several entries can also be declared at once, one per line, under a single
directive:

.. code-block::

.. index::
single: configuration
pair: configuration; file
see: token; access token

Comma-separated, type-less form
-------------------------------

A line may also hold several comma-separated terms at once, each becoming
its own ``single`` entry -- the convention used by e.g. TYPO3 Core's
Changelog files:

.. code-block::

.. index:: Backend, PHP-API, ext:core

.. _genindex-template:

The ``genindex`` template
=========================

The full, project-wide index is rendered by giving a document the
``template`` field, set to ``genindex``:

.. code-block::
:caption: genindex.rst

:orphan:
:template: genindex

Index
=====

.. _genindex-directive:

The ``genindex`` directive
==========================

The ``.. genindex::`` directive renders the same kind of listing inline,
anywhere a document chooses to place it. Unlike the ``template`` field,
which produces at most one page for the *whole* project, ``genindex`` can
be placed anywhere and used more than once -- e.g. one listing per version
directory in a changelog:

.. code-block::

Index for 12.4
--------------

.. genindex::
:scope: Changelog/12.4/

Full index
----------

.. genindex::

``:scope:`` accepts a comma-separated list of path prefixes; entries from
documents whose path doesn't start with one of them are left out of that
particular listing. Omitting ``:scope:`` includes every entry in the
project.

Both the ``genindex`` template and the ``.. genindex::`` directive group
terms under an A-Z jumpbox with one heading per letter by default. For a
small listing -- e.g. a single changelog version -- that grouping can add
more noise than it saves navigation, so it can be turned off:

.. code-block::

.. genindex::
:scope: Changelog/12.4/
:no-letter-index:

Index terms on sections
=======================

Independently of any ``genindex`` page, every term from an ``index`` entry
is also recorded on the section it resolves to (the next heading following
the directive, or the document's own top-level section if none follows).
A theme's section template can expose these as a search-key data attribute,
e.g. ``data-guides-index-terms="configuration,file"``.

This makes the terms available to external tooling that crawls the
rendered HTML rather than the reST source -- for example, a custom search
engine such as TYPO3's Elasticsearch integration can pick up the attribute
and index a section under the same terms an author tagged it with via
``index``, without needing its own copy of the genindex logic.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use phpDocumentor\Guides\RestructuredText\Directives\ErrorDirective;
use phpDocumentor\Guides\RestructuredText\Directives\FigureDirective;
use phpDocumentor\Guides\RestructuredText\Directives\GeneralDirective;
use phpDocumentor\Guides\RestructuredText\Directives\GenIndexDirective;
use phpDocumentor\Guides\RestructuredText\Directives\HighlightDirective;
use phpDocumentor\Guides\RestructuredText\Directives\HighlightsDirective;
use phpDocumentor\Guides\RestructuredText\Directives\HintDirective;
Expand Down Expand Up @@ -89,6 +90,7 @@
use phpDocumentor\Guides\RestructuredText\Parser\Productions\FieldList\OrphanFieldListItemRule;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\FieldList\ProjectFieldListItemRule;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\FieldList\RevisionFieldListItemRule;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\FieldList\TemplateFieldListItemRule;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\FieldList\TocDepthFieldListItemRule;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\FieldList\VersionFieldListItemRule;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\FieldListRule;
Expand Down Expand Up @@ -212,6 +214,7 @@
->set(IncludeDirective::class)
->arg('$startingRule', service(DocumentRule::class))
->set(IndexDirective::class)
->set(GenIndexDirective::class)
->set(LaTeXMain::class)
->set(ListTableDirective::class)
->set(LiteralincludeDirective::class)
Expand Down Expand Up @@ -354,6 +357,9 @@
->set(TocDepthFieldListItemRule::class)
->tag('phpdoc.guides.parser.rst.fieldlist')

->set(TemplateFieldListItemRule::class)
->tag('phpdoc.guides.parser.rst.fieldlist')

->set(VersionFieldListItemRule::class)
->args([
'$logger' => service(LoggerInterface::class),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\RestructuredText\Directives;

use phpDocumentor\Guides\Nodes\Index\GenIndexNode;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
use phpDocumentor\Guides\RestructuredText\Parser\Directive;

use function array_filter;
use function array_map;
use function array_values;
use function explode;
use function trim;

/**
* Renders a genindex term listing wherever it's placed, optionally scoped to
* documents under one or more path prefixes -- unlike the project-wide
* `:template: genindex` page, this can be dropped inline anywhere and used
* more than once, e.g. one per version directory in a changelog:
*
* .. genindex::
*
* .. genindex::
* :scope: Changelog/12.4/
*
* .. genindex::
* :scope: Changelog/12.4/, Changelog/12.4-security/
*
* The A-Z letter index (jumpbox + one heading per letter) can be turned off
* for small, e.g. per-version, listings where it adds more noise than it
* saves navigation -- terms are then listed flat, in one table:
*
* .. genindex::
* :scope: Changelog/12.4/
* :no-letter-index:
*
* The node is populated later by IndexCollectorPass, once entries from every
* document have been collected; at parse time it's an empty placeholder.
*/
final class GenIndexDirective extends BaseDirective
{
public function getName(): string
{
return 'genindex';
}

/** {@inheritDoc} */
public function process(
BlockContext $blockContext,
Directive $directive,
): Node|null {
$prefixes = explode(',', $directive->getOptionString('scope'));
$prefixes = array_values(array_filter(array_map(trim(...), $prefixes), static fn (string $prefix): bool => $prefix !== ''));

return new GenIndexNode([], $prefixes, !$directive->hasOption('no-letter-index'));
}
}
Loading
Loading