changeset 125:3629bf09b30d

Much more documentation including most details of the AlgPseudocodeLexer
author Franz Glasner <fzglas.hg@dom66.de>
date Wed, 06 May 2026 16:59:44 +0200
parents f916251d5647
children e91c9dcbeb77
files docs/details.rst docs/index.rst
diffstat 2 files changed, 298 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/docs/details.rst	Wed May 06 16:12:17 2026 +0200
+++ b/docs/details.rst	Wed May 06 16:59:44 2026 +0200
@@ -5,6 +5,203 @@
  Details
 *********
 
+.. role:: algpseudocode(code)
+   :language: algpseudocode
+
+
+Lexer Options
+=============
+
+`no_end`
+
+  Default: ``False``
+
+  If ``True`` all the ``ENDxxx`` commands will be skipped and yield nothing.
+
+`gets`
+
+  Default: ``←``
+
+  The operator symbol to be printed by the command ``\GETS``.
+
+  Often used alternative: ``:=``.
+
+`remark`
+
+  Default: ``▷``
+
+  The symbol to be printed as when starting comments with ``\REMARK`` or ``\REM``
+
+
+Comments
+========
+
+- with the ``\REMARK`` or ``\REM`` keywords
+- multi-line comments with ``/* ... */``; they can be **nested**
+- multi-line comments with ``(* ... *)``; they can be **nested**
+- single-line comments with ``//`` or ``#`` (until the end of the line)
+
+
+Literals
+========
+
+Strings and numbers as in `Python <https://www.python.org>`_.
+
+To yield non-string-delimiting single- and double-quotes you have to escape them
+using ``\'`` or ``\"``. This must be used to typeset something as
+:algpseudocode:`f\\'(x) = 0`.
+
+
+Keywords
+========
+
+Explicit Keywords
+-----------------
+
+- Start with a backslash character ``\``
+- Case-insensitive
+- Translated if a translation is found
+
+Parameter handling is as follows:
+
+- Parameters are enclosed in curly braces ``{`` and ``}``
+- Escaping within the braces is possible using the backslash ``\``
+- Parameters are separated from the keyword/command by a (possibly empty) run
+  of space or TAB characters.
+  This is true for required and optional parameters.
+
+
+With Required Parameters
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: algpseudocode
+
+   \TEXT{\PROGRAM {A Program\}  or  \PROG {A Program\}}                                    \PROGRAM {A Program}
+   \TEXT{\ALGORITHM{An Algorithm\}  or  \ALGO{An Algorithm\}}                              \ALGORITHM{An Algorithm}
+   \TEXT{\PROCEDURE{A Procedure\}  or  \PROC{A Procedure\}}                                \PROCEDURE{A Procedure}
+   \TEXT{\FUNCTION{A Function\}  or  \FUNC{A Function\}  or  \FN{A Function\}}              \FUNCTION{A Function}
+   \TEXT{\CLASS{A Class\}}                                                                \CLASS{A Class}
+
+   \TEXT{\STATEMENT{the expression\}  \STATE{the expression\}  \BLOCK{the expression\}}     \STATEMENT{the expression}
+
+   \TEXT{expr1: \\EXPRESSION{expression a in b\}   expr2: \\EXPR{expression b in a\}}        \TEXT{expr1: \EXPRESSION{expression a in b}   expr2: \EXPR{expression b in a}}
+
+   \TEXT{\TEXTSTATEMENT{the text\}  \TEXTSTATE{the text\}  \TSTATEMENT{the text\}  \TSTATE{the text\}  \TEXTBLOCK{the text\}  \TBLOCK{the text\}}             \TEXTSTATEMENT{the text}
+
+   \TEXT{\INPUT{Input 1\}}                            \INPUT{Input 1}
+   \TEXT{\INPUTS{Input 2\}}                           \INPUTS{Input 2}
+
+   \TEXT{\OUTPUT{Output 1\}}                          \OUTPUT{Output 1}
+   \TEXT{\OUTPUTS{Output 2\}}                         \OUTPUTS{Output 2}
+
+   \TEXT{\ENSURE{Whatever should be ensured!\}}       \ENSURE{Whatever should be ensured!}
+
+   \TEXT{\REQUIRE{Whatever should be required.\}}     \REQUIRE{Whatever should be required.}   
+
+   \TEXT{\RETURNS{Return 2\}}                         \RETURNS{Return 2}
+
+   \TEXT{\CALL{a function\}(p1, p2)}                  \CALL{a function}(p1, p2)
+
+
+With Optional Parameters
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some ``END``-keywords have optional parameters:
+
+.. code-block:: algpseudocode
+
+   \TEXT{\ENDPROGRAM  \ENDPROG}              \ENDPROGRAM
+   \TEXT{\ENDALGORITHM  \ENDALGO}            \ENDALGORITHM
+   \TEXT{\ENDPROCEDURE  \ENDPROC}            \ENDPROCEDURE
+   \TEXT{\ENDFUNCTION  \ENDFUNC  \ENDFN}     \ENDFUNCTION
+   \TEXT{\ENDCLASS}                          \ENDCLASS
+
+They are used like this:
+
+.. code-block:: algpseudocode
+
+   \TEXT{\CLASS{Foo Bar Class\} ... \END CLASS {Foo Bar Class\}}   \TEXT{yields}   \CLASS{Foo Bar Class} ... \END CLASS {Foo Bar Class}
+
+.. seealso:: Syntax variants: `END-Keywords`_
+
+
+Without Parameters
+~~~~~~~~~~~~~~~~~~
+
+"Normal" Keywords
+'''''''''''''''''
+
+.. code-block:: algpseudocode
+
+   \TEXT{\IF}                                \IF
+   \TEXT{\THEN}                              \THEN
+   \TEXT{\ELSE}                              \ELSE
+   \TEXT{\ELSEIF or \ELSIF  or  \ELIF}       \ELSEIF \text{or} \ELSIF \text{or} \ELIF
+   \TEXT{\DO}                                \DO
+   \TEXT{\WHILE}                             \WHILE
+   \TEXT{\FORALL}                            \FORALL
+   \TEXT{\FOR}                               \FOR
+   \TEXT{\FROM}                              \FROM
+   \TEXT{\TO}                                \TO
+   \TEXT{\STEP}                              \STEP
+   \TEXT{\IN}                                \IN
+   \TEXT{\LOOP}                              \LOOP
+   \TEXT{\REPEAT}                            \REPEAT
+   \TEXT{\UNTIL}                             \UNTIL
+
+   \TEXT{\RETURN}                            \RETURN
+
+   \TEXT{\BEGIN}                             \BEGIN
+   \TEXT{\END}                               \END
+
+   \TEXT{\IS}                                \IS
+   \TEXT{\WITH}                              \WITH
+
+   \TEXT{\\REMARK   or   \\REM}                \REMARK A comment with a sigil
+
+``\REMARK`` or ``\REM`` is special: all characters to the end of the
+line are taken as comment; curly braces are not needed -- in fact:
+they are interpreted as part of the comment.
+
+
+END-Keywords
+''''''''''''
+
+The separator character can be empty, a run of ASCII spaces, a run of TAB characters,
+a single underscore ``_`` or a single hyphen ``-`` like:
+
+  ``\ENDIF``, ``\END IF``, ``\END-IF``, ``\END_IF`` or ``\END IF``
+
+
+.. code-block:: algpseudocode
+
+   \text{\ENDIF}             \ENDIF     \rem empty
+
+   \text{\END IF}            \END IF     \rem a single space
+
+   \text{\END  IF}           \END  IF     \rem two spaces
+
+   \text{\END-IF}            \END-IF     \rem a single hyphen
+
+   \text{\END_IF}            \END_IF     \rem a single underscore
+
+   \text{\END   IF}          \END       IF     \rem a single TAB character
+
+The list of END-keywords (here always just with ``-`` as separator):
+
+.. code-block:: algpseudocode
+
+   \text{\END-PROGRAM  \END-PROG}              \END-PROGRAM
+   \text{\END-ALGORITHM  \END-ALGO}            \END-ALGORITHM
+   \text{\END-PROCEDURE  \END-PROC}            \END-PROCEDURE
+   \text{\END-FUNCTION  \END-FUNC  \END-FN}    \END-FUNCTION
+   \text{\END-CLASS}                           \END-CLASS
+   \text{\END-IF}                              \END-IF
+   \text{\END-WHILE}                           \END-WHILE
+   \text{\END-FOR}                             \END-FOR
+   \text{\END-FORALL}                          \END-FORALL
+   \text{\END-LOOP}                            \END-LOOP
+
 
 Explicit Token Types
 ====================
@@ -40,7 +237,7 @@
 
 Examples:
 
-.. code-block:: AlgPseudocode
+.. code-block:: algpseudocode
 
    \text{• \\tt-kc/C}      \tt-kc/C            \rem C as Keyword.Constant
    \text{• \\tt-ow/∈}      \tt-ow/∈            \rem ∈ as Operator.Word
@@ -63,3 +260,34 @@
       * with a Generic.Error token and no expansion.
       */
    \text{• \\ttx-NON-EXISTING[∈_∌](p1, p2)}      \ttx-NON_EXISTING[∈_∌](p1, p2)
+
+.. note:: Explicit token types are **case-sensitive**.
+
+
+Customized Lexers in Sphinx
+===========================
+
+Defining lexers with non-default options in Sphinx can be done in its
+configuration file :file:`conf.py`:
+
+.. code-block:: python
+
+   from functools import partial
+   from pygments_lexer_pseudocode2.algpseudocode import AlgPseudocodeLexer
+
+   def setup(app):
+
+       #
+       # Add a custom lexer: AlgPseudocodeLexer with custom init
+       # option "no_end".
+       #
+       # In modern Sphinx versions given lexer must be callable and may
+       # not be a lexer instance. So use an indirection with "partial"
+       # here.
+       #
+       app.add_lexer("noend-algpseudocode",
+                     partial(AlgPseudocodeLexer, no_end=True))
+
+Similarily it works for custom styles and filters.
+
+For older Sphinx versions your mileage may vary.
--- a/docs/index.rst	Wed May 06 16:12:17 2026 +0200
+++ b/docs/index.rst	Wed May 06 16:59:44 2026 +0200
@@ -8,9 +8,70 @@
    :maxdepth: 2
    :caption: Contents:
 
+   readme	     
    details
 
 
+.. list-table::
+   :align: left
+   :header-rows: 1
+
+   * - Language Name
+     - Description
+     - Extension(s)
+     - Aliases / Short Name(s)
+     - Lexer Class
+
+   * - AlgPseudocode
+     - Pseudocode with inspirations from CTAN's "Algpseudocodex"
+     - \*.algpseudocode, \*.algpseudo
+     - algpseudocode, algpseudo
+     - AlgPseudocodeLexer
+
+   * - AlgPseudocodeFR
+     - AlgPseudocode with french keyword expansion
+     - \*.algpseudo-fr, \*.algpseudocode-fr
+     - algpseudocode-fr, algpseudo-fr
+     - AlgPseudocodeLexer_FR
+
+   * - AlgPseudocodeDE
+     - AlgPseudocode with german keyword expansion
+     - \*.algpseudo-de, \*.algpseudocode-de
+     - algpseudocode-de, algpseudo-de
+     - AlgPseudocodeLexer_DE
+
+   * - FrPseudocode
+     - The original lexer (slightly changed) from `pygments-lexer-pseudocode`
+     - \*.fr-algo, \*.fr-pseudocode
+     - fr-pseudocode, fr-pseudo, fr-algorithm, fr-algo
+     - FrPseudocodeLexer
+
+To be used in Sphinx like this:
+
+.. code-block:: none
+
+   .. code-block:: algpseudocode
+
+      \PROGRAM {The Pseudoprogram} \IS
+
+      \END PROGRAM {The Pseudoprogram}
+
+would be rendered as:
+
+.. code-block:: algpseudocode
+
+   \PROGRAM {The Pseudoprogram} \IS
+
+   \END PROGRAM {The Pseudoprogram}
+
+And the same with the german variant:
+
+.. code-block:: algpseudocode-de
+
+   \PROGRAM {The Pseudoprogram} \IS
+
+   \END PROGRAM {The Pseudoprogram}
+
 Expressions:
 
 - Strings (single-quote, double-quote, triple-single-quote, triple-double-quote)
@@ -22,7 +83,7 @@
 - Names (`Name.Entity`)
 
 .. literalinclude:: example-1.pseudocode
-   :language: AlgPseudocode
+   :language: algpseudocode
    :lines: 2-
 
 With a customized `AlgPseudocodeLexer` and its `no_end`
@@ -48,14 +109,14 @@
 (see https://en.wikipedia.org/wiki/Dinic%27s_algorithm):
 
 .. literalinclude:: algorithm-dinic.description
-   :language: AlgPseudocode
+   :language: algpseudocode
    :lines: 2-
 
 This is Wikipedia's pseudocode of the *Ford–Fulkerson Algorithm*
 (see https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm):
 
 .. literalinclude:: algorithm-ford-fulkerson.pseudocode
-   :language: AlgPseudocode
+   :language: algpseudocode
    :lines: 2-
 
 This is Wikipedia's pseudocode of the *Edmonds–Karp Algorithm*
@@ -63,20 +124,13 @@
 
 .. literalinclude:: algorithm-edmonds-karp.pseudocode
    :language: NoEndAlgPseudocode
-   :lines: 2-	   
+   :lines: 2-
 
-.. todo::
+And now the *Edmonds–Karp Algorithm* with french keywords:
 
-   Note how
-   https://stackoverflow.com/questions/11413203/sphinx-pygments-lexer-filter-extension
-   documents dynamic lexer and style creation for Pygments within Sphinx.
-
-   Examples:
-
-   - Load lexers with some custom (init) options
-   - Dynamically create new lexers, styles, formatters or filters
-
-.. todolist::
+.. literalinclude:: algorithm-edmonds-karp.pseudocode
+   :language: algpseudocode-fr
+   :lines: 2-
 
 
 Indices and tables