Element categories to HTML class mappings
Every element category, and, in the case of elements which are "taken constants" (that is, strings or symbols taken as a constant), every element subcategory, is eventually associated with a HTML class. The form of this association is determined by the values specified in the argument stem. The following package contains the routine implementing the default HTML class mapping.
/******************************************************************************/
/* */
/* HTMLClasses.cls - element category/subcategory to html class translation */
/* ======================================================================== */
/* */
/* This program is part of the Rexx Parser package */
/* [See https://rexx.epbcn.com/rexx.parser/] */
/* */
/* Copyright (c) 2024-2025 Josep Maria Blasco <josep.maria.blasco@epbcn.com> */
/* */
/* License: Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0) */
/* */
/* Version history: */
/* */
/* Date Version Details */
/* -------- ------- --------------------------------------------------------- */
/* 20241206 0.1 First public release */
/* 20241208 0.1a c/CLASSIC_COMMENT/STANDARD_COMMENT/ */
/* 20241209 0.1b Add shebang support */
/* New call system */
/* 20241225 0.1d Add doc-comment support */
/* 20250103 0.1e Add TUTOR-flavored Unicode classes */
/* 20250116 0.1f Add support for EL.SUBKEYWORD */
/* */
/******************************************************************************/
::Routine HTMLClasses Public
--
-- ARGUMENT
-- --------
--
-- "Options.", a stem.
--
Use Strict Arg Options.
--
-- The following tails are examined:
--
-- * Options.assignment,
-- for (extended) assignment operator characters and character sequences.
-- * Options.constant,
-- for strings or symbols taken as a constant.
-- * Options.operator,
-- for operator characters and operator character sequences.
-- * Options.special,
-- for special characters and special character sequences.
-- * Options.classprefix,
-- a prefix prepended to every HTML class. Default is "".
--
-- The code assigns one or two HTML classes to every element category, and,
-- in the case of symbols taken as a constant, to every element subcategory.
--
-- When two classes are assigned, the first one is generic (for instance,
-- "spe" for special characters), and the second one identifies the
-- corresponding element (for example, "comma", or "colon").
--
-- The value of the corresponding compound variables determine the class
-- associated with every element category and subcategory,
-- in the following way:
--
-- * When the value is "group", only the generic class is assigned.
-- * When the value is "detail", only the detailed class is assigned.
-- * When the value is "full", two classes are assigned, the generic
-- one and the detailed one (in this order).
--
-- RETURNS
-- -------
--
-- A stem ("HTMLClass") mapping element categories and subcategories to html
-- classes. The default HTML class is "rexx".
--
prefix = options.classprefix
HTMLClass = .Stem~new --
HTMLClass[] = "rexx" -- The default HTML class is 'rexx'
--
-- We will assign HTML classes to a number of element categories
-- using the "Assign" internal routine.
--
-- We include it here and skip over its code for readability.
--
--------------------------------------------------------------------------------
Signal SkipOverAssign
Assign:
value = "" -- An accumulator
classes = Arg(2)~makeArray(" ")
Do Counter c class Over classes
If c > 1 Then value ||= " "
value ||= prefix || class -- Prepend the prefix to each class
End
HTMLClass[ Arg(1) ] = value
Return
SkipOverAssign:
/******************************************************************************/
/* SHEBANGS */
/******************************************************************************/
Call Assign .EL.SHEBANG, "shb"
/******************************************************************************/
/* SYMBOLS */
/******************************************************************************/
--------------------------------------------------------------------------------
-- Keywords --
--------------------------------------------------------------------------------
--
-- Directive keywords have a special element category, different from
-- instruction keywords, and, correspondingly, they can be assigned a different
-- HTML class, if so desired.
--
Call Assign .EL.KEYWORD, "kw"
Call Assign .EL.SUBKEYWORD, "skw"
Call Assign .EL.DIRECTIVE_KEYWORD, "dkw"
--------------------------------------------------------------------------------
-- Variables --
--------------------------------------------------------------------------------
--
-- The parser is able to differentiate exposed (instance) variables from
-- local variables.
--
Call Assign .EL.SIMPLE_VARIABLE, "var"
Call Assign .EL.COMPOUND_VARIABLE, "cmp"
Call Assign .EL.STEM_VARIABLE, "stem"
Call Assign .EL.EXPOSED_SIMPLE_VARIABLE, "xvar"
Call Assign .EL.EXPOSED_COMPOUND_VARIABLE, "xcmp"
Call Assign .EL.EXPOSED_STEM_VARIABLE, "xstem"
--------------------------------------------------------------------------------
-- Environment symbols --
--------------------------------------------------------------------------------
Call Assign .EL.ENVIRONMENT_SYMBOL, "env"
--------------------------------------------------------------------------------
-- Pure constant symbols --
--------------------------------------------------------------------------------
--
-- That is, constant symbols that are not environment symbols or numbers
--
-- .EL.PERIOD is used when parsing PARSE templates. By default, its
-- highlighting is the same as other symbol literals.
--
Call Assign .EL.SYMBOL_LITERAL, "lit"
Call Assign .EL.PERIOD, "lit"
--------------------------------------------------------------------------------
-- Numbers --
--------------------------------------------------------------------------------
Call Assign .EL.EXPONENTIAL_NUMBER, "exp"
Call Assign .EL.FRACTIONAL_NUMBER, "frac"
Call Assign .EL.INTEGER_NUMBER, "int"
/******************************************************************************/
/* STRINGS */
/******************************************************************************/
Call Assign .EL.BINARY_STRING, "bstr"
Call Assign .EL.STRING, "str"
Call Assign .EL.HEX_STRING, "xstr"
Call Assign .EL.BYTES_STRING, "ystr"
Call Assign .EL.CODEPOINTS_STRING, "pstr"
Call Assign .EL.GRAPHEMES_STRING, "gstr"
Call Assign .EL.TEXT_STRING, "tstr"
Call Assign .EL.UNICODE_STRING, "ustr"
/******************************************************************************/
/* COMMENTS */
/******************************************************************************/
-- We style doc-comments the same as non-doc comments by default
Call Assign .EL.LINE_COMMENT, "lncm"
Call Assign .EL.DOC_COMMENT_MARKDOWN, "doc-lncm"
Call Assign .EL.STANDARD_COMMENT, "cm"
Call Assign .EL.DOC_COMMENT, "doc-cm"
/******************************************************************************/
/* RESOURCES */
/******************************************************************************/
--
-- See also the .RESOURCE.NAME and .RESOURCE.DELIMITER.NAME
-- subcategories below.
--
Call Assign .EL.RESOURCE_DATA, "res-data"
Call Assign .EL.RESOURCE_IGNORED_DATA, "res-ignore"
/******************************************************************************/
/* WHITESPACE */
/******************************************************************************/
--
-- Note that elements with the .EL.WHITESPACE class include
-- continuation characters "-" and ","
--
Call Assign .EL.WHITESPACE, "ws"
/******************************************************************************/
/* OPERATORS */
/******************************************************************************/
Signal SkipOverOperator
Operator:
Select Case Options.operator
When "group" Then Call Assign Arg(1), "op"
When "full" Then Call Assign Arg(1), "op" Arg(2)
When "detail" Then Call Assign Arg(1), Arg(2)
End
Return
SkipOverOperator:
--------------------------------------------------------------------------------
-- Single-character operators --
--------------------------------------------------------------------------------
Call Operator .EL.OP.AND, "and"
Call Operator .EL.OP.DIVISION, "div"
Call Operator .EL.OP.EQUAL, "eq"
Call Operator .EL.OP.GREATER_THAN, "gt"
Call Operator .EL.OP.INTEGER_DIVISION, "idiv"
Call Operator .EL.OP.LOWER_THAN, "lt"
Call Operator .EL.OP.MINUS, "sub"
Call Operator .EL.OP.MESSAGE, "msg"
Call Operator .EL.OP.MULTIPLICATION, "mul"
Call Operator .EL.OP.NEGATION, "not"
Call Operator .EL.OP.OR, "or"
Call Operator .EL.OP.PLUS, "add"
Call Operator .EL.OP.REFERENCE.LOWER_THAN, "ref-lt"
Call Operator .EL.OP.REFERENCE.GREATER_THAN, "ref-gt"
--------------------------------------------------------------------------------
-- Prefix operators --
--------------------------------------------------------------------------------
--
-- "\" is always a prefix operator
--
Call Operator .EL.OP.PREFIX.MINUS, "prf-sub"
Call Operator .EL.OP.PREFIX.PLUS, "prf-add"
--------------------------------------------------------------------------------
-- Multi-character operator sequences --
--------------------------------------------------------------------------------
--
-- There may be some whitespace, comments and continuations inside
-- the sequence; only the relevant characters will be tagged.
--
Call Operator .EL.OP.CASCADING_MESSAGE, "cmsg"
Call Operator .EL.OP.CONCATENATION, "cat"
Call Operator .EL.OP.GREATER_OR_EQUAL, "ge"
Call Operator .EL.OP.GREATER_OR_LOWER_THAN, "glt"
Call Operator .EL.OP.LOWER_OR_EQUAL, "le"
Call Operator .EL.OP.LOWER_OR_GREATER_THAN, "lgt"
Call Operator .EL.OP.NOT_GREATER_THAN, "ngt"
Call Operator .EL.OP.NOT_LOWER_THAN, "nlt"
Call Operator .EL.OP.NOT_EQUAL, "ne"
Call Operator .EL.OP.POWER, "pow"
Call Operator .EL.OP.REMAINDER, "rem"
Call Operator .EL.OP.XOR, "xor"
--------------------------------------------------------------------------------
-- Strict comparison operator sequences --
--------------------------------------------------------------------------------
--
-- All are multi-character
--
Call Operator .EL.OP.STRICT.LOWER_THAN, "st-lt"
Call Operator .EL.OP.STRICT.GREATER_OR_EQUAL, "st-ge"
Call Operator .EL.OP.STRICT.GREATER_THAN, "st-gt"
Call Operator .EL.OP.STRICT.NOT_EQUAL, "st-ne"
Call Operator .EL.OP.STRICT.NOT_LOWER_THAN, "st-nlt"
Call Operator .EL.OP.STRICT.NOT_GREATER_THAN, "st-ngt"
Call Operator .EL.OP.STRICT.LOWER_OR_EQUAL, "st-le"
Call Operator .EL.OP.STRICT.EQUAL, "st-eq"
--------------------------------------------------------------------------------
-- Blank concatenation --
--------------------------------------------------------------------------------
--
-- The abuttal operator is zero-length, but blank concatenation is not.
--
Call Operator .EL.OP.BLANK, "blank"
/******************************************************************************/
/* ASSIGNMENTS */
/******************************************************************************/
Signal SkipOverAssignment
Assignment:
Select Case Options.assignment
When "group" Then Call Assign Arg(1), "asg"
When "full" Then Call Assign Arg(1), "asg" Arg(2)
When "detail" Then Call Assign Arg(1), Arg(2)
End
Return
SkipOverAssignment:
--------------------------------------------------------------------------------
Call Assignment .EL.ASG.EQUAL, "asg-equal"
Call Assignment .EL.ASG.PLUS, "asg-add"
Call Assignment .EL.ASG.MINUS, "asg-sub"
Call Assignment .EL.ASG.MULTIPLY, "asg-mul"
Call Assignment .EL.ASG.DIVIDE, "asg-div"
Call Assignment .EL.ASG.INTEGER_DIVISION, "asg-idiv"
Call Assignment .EL.ASG.AND, "asg-and"
Call Assignment .EL.ASG.OR, "asg-or"
Call Assignment .EL.ASG.REMAINDER, "asg-rem"
Call Assignment .EL.ASG.CONCATENATION, "asg-cat"
Call Assignment .EL.ASG.XOR, "asg-xor"
Call Assignment .EL.ASG.POWER, "asg-pow"
/******************************************************************************/
/* SPECIAL CHARACTERS */
/******************************************************************************/
Signal SkipOverSpecial
Special:
Select Case Options.special
When "group" Then Call Assign Arg(1), "spe"
When "full" Then Call Assign Arg(1), "spe" Arg(2)
When "detail" Then Call Assign Arg(1), Arg(2)
End
Return
SkipOverSpecial:
--------------------------------------------------------------------------------
Call Special .EL.COMMA, "comma"
Call Special .EL.COLON, "colon"
Call Special .EL.LEFT_PARENTHESIS, "paren"
Call Special .EL.RIGHT_PARENTHESIS, "paren"
Call Special .EL.LEFT_BRACKET, "bracket"
Call Special .EL.RIGHT_BRACKET, "bracket"
--
-- Directive start. Although technically this is a sequence of special
-- characters, we assign a new class using "Assign" instead of "Special",
-- since we will probably want to highlight "::" differently from other
-- specials and special .
--
Call Assign .EL.DIRECTIVE_START, "dir"
-- The period as a compound variable tail separator is a pseudo-special, ...
Call Special .EL.TAIL_SEPARATOR, "period"
-- ... as is the "..." construct at the end of an argument list.
Call Special .EL.ELLIPSIS, "ellipsis"
/******************************************************************************/
/* STRINGS OR SYMBOLS TAKEN AS A CONSTANT */
/******************************************************************************/
Signal SkipOverConstant
Constant:
Select Case Options.["CONSTANT"]
When "group" Then value = prefix"const"
When "full" Then value = prefix"const" prefix||Arg(2)
When "detail" Then value = prefix||Arg(2)
End
HTMLClass[ constant, Arg(1) ] = value
Return
SkipOverConstant:
--------------------------------------------------------------------------------
constant = .EL.TAKEN_CONSTANT
-- Function and subroutine call constants
Call Constant .INTERNAL.FUNCTION.NAME, "int-func"
Call Constant .INTERNAL.SUBROUTINE.NAME, "int-proc"
Call Constant .BUILTIN.FUNCTION.NAME, "bif-func"
Call Constant .BUILTIN.SUBROUTINE.NAME, "bif-proc"
Call Constant .PACKAGE.FUNCTION.NAME, "pkg-func"
Call Constant .PACKAGE.SUBROUTINE.NAME, "pkg-proc"
Call Constant .EXTERNAL.PACKAGE.FUNCTION.NAME, "ext-pkg-func"
Call Constant .EXTERNAL.PACKAGE.SUBROUTINE.NAME, "ext-pkg-func"
Call Constant .EXTERNAL.FUNCTION.NAME, "ext-func"
Call Constant .EXTERNAL.SUBROUTINE.NAME, "ext-proc"
-- Other constants
Call Constant .ANNOTATION.NAME, "annotation"
Call Constant .BLOCK.INSTRUCTION.NAME, "block"
Call Constant .CLASS.NAME, "class"
Call Constant .ENVIRONMENT.NAME, "environment"
Call Constant .LABEL.NAME, "label"
Call Constant .METHOD.NAME, "method"
Call Constant .NAMESPACE.NAME, "namespace"
Call Constant .ROUTINE.NAME, "routine"
Call Constant .REQUIRES.PROGRAM.NAME, "requires"
Call Constant .RESOURCE.NAME, "resource"
Call Constant .RESOURCE.DELIMITER.NAME, "res-delimiter"
Call Constant .USER.CONDITION.NAME, "user-condition"
Call Constant .ANNOTATION.VALUE, "annotation-value"
Call Constant .CONSTANT.VALUE, "constant-value"
--------------------------------------------------------------------------------
Return HTMLClass