diff docs/details.rst @ 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 03e9031b5eca
children
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.