[rexx] highlight [options] file
The utility can run in one of four modes, namely, ANSI mode, HTML mode, LaTeX mode, and DocBook mode; every mode determines how the file will be highlighted.
When calling highlight as a command, the default mode is
ANSI; otherwise, the default mode is HTML.
When file is a single dash ("-") which is the last option in
the command line argument, input is taken from the .input
monitor. In all other cases, file has to refer to a filesystem
file; when the extension of that file is .md,
.htm or .html, the utility processes all Rexx
fenced code blocks in file and highlights them. Otherwise, the
utility assumes that file is a Rexx file, it is highlighted
accordingly.
When called without arguments, display help information and exit.
-a, --ansi |
Select ANSI SGR terminal highlighting |
--continue |
Continue when a fenced code block is in error (HTML only) |
--css |
Include links to css files (HTML only) |
-d,
--docbook |
Select DocBook XML highlighting |
--default
attributes |
Select default attributes for code blocks |
--doccomments detailed|block |
Select highlighting level for doc-comments |
-e, -exp,
--experimental |
Enable Experimental features |
-xtr,
--executor |
Enable support for Executor |
-h, --html |
Select HTML highlighting (see note below) |
--help |
Display help and exit |
-it,
--itrace |
Print internal traceback on error |
-l, --latex |
Select LaTeX highlighting |
--noprolog |
Don't print a prolog |
-n,
--numberlines |
Print line numbers |
--pad=n |
Pad doc-comments and ::resources to n characters |
--patch=patches |
Apply the semicolon-separated list of patches. |
--patchfile
file |
Apply the patches contained in file. |
--prolog |
Print a prolog (LaTeX driver only) |
--startFrom
n |
Start line numbers at n. |
-s , --style
style |
Use the rexx-style.css style sheet |
--tutor |
Enable TUTOR-flavored Unicode |
-u ,
--unicode |
Enable TUTOR-flavored Unicode |
-w, --width
=n |
Ensure that lines have width n (ANSI only) |
Note on -h: The -h option
selects HTML mode. When it is the only option and no file is
specified, help is displayed instead (since processing options without a
file to process always displays help).
Note: Several of the options (-exp,
-s, -u, -xtr,
--executor, --experimental,
--unicode, --style or --tutor) do
not make sense when highlighting files containing fenced code blocks,
like Markdown or HTML files. In these cases, you should use either the --default option or the desired attributes in every
of the ```rexx or ```executor fences.
Selects ANSI highlighting using ANSI SGR (Select Graphic Rendition) codes.
When processing fenced code blocks, the default behaviour of
highlight.rex is to stop when an error is found or all the blocks have
been processed, whichever occurs first. You can change this behaviour by
specifying The --continue option; in that case, processing
continue even in the presence of an error: blocks in error cannot be
highlighted, but they will be substituted by a big warning box, with a
red background, displaying the line in error.
When generating HTML highlighting, the --css option adds
a skeleton HTML5 envelope to the generated code. This envelope includes,
in its head tag, up to three links to the style file
referenced in the -s or --style options: one
to a possible version stored in the https://rexx.epbcn.com/ site, another one to a path
relative to the highlight utility, and an optional third
one pointing to the style file, if such a file exists in the current
directory.
Note: The css option is a quick and
dirty hack intended to facilitate development in RAD scenarios, not a
way to generate distribution-ready or production files.
Specifies the default attributes to be applied to all the highlighted code blocks.
Selects DocBook XML highlighting. In this mode, each token is wrapped
in an XML element whose name is derived from its CSS classes:
rx-kw becomes <rexx_kw>,
rx-op rx-add becomes <rexx_op_add>, etc.
Whitespace is emitted as plain text (not wrapped in elements). All
content is XML-escaped.
The output is intended to be inserted into DocBook
<programlisting> blocks and rendered via XSL
templates generated by css2xsl.
See also css2xsl.
Select the highlighting level for doc-comments. When "detailed" is specified (the default), some sub-elements of doc-comments, like the summary statement, block tags or tag values, receive their own, separated styling; when "block" is specified, all the doc-comment as a whole gets a single style.
Enables support for JLF's Executor extensions.
Enables Experimental Rexx features so that they are recognized by the Parser.
Selects HTML highlighting.
See also --css (#css).
Selects LaTeX highlighting.
Don't print a prolog (LaTeX only).
See also --prolog.
Print line numbers.
See also --startFrom.
Pad doc-comments and ::resource blocks to n
characters.
Apply the semicolon-separated list of patches.
See also --patchFile.
Apply the patches contained in file.
See also --patch.
Print a prolog (LaTeX driver only).
See also --latex and --noprolog.
Start numbering lines at line n.
See also --numberlines
Use the rexx-style.css style sheet. The default
is rexx-dark.css.
Enable TUTOR-flavored Unicode.
See also --unicode.
Enable TUTOR-flavored Unicode.
See also --tutor.
Ensure that lines have a minimum width of n characters (ANSI highlighting only).
See also --ansi.
Enables support for JLF's Executor extensions.
The following command
highlight --css --style mystyle sample.html
could generate the following head section:
<head>
<link rel='stylesheet' href='https://rexx.epbcn.com/rexx-parser/css/rexx-mystyle.css'>
<link rel='stylesheet' href='file:///C:/path/rexx-parser/bin/../css/rexx-mystyle.css'>
<link rel='stylesheet' href='rexx-mystyle.css'>
</head>
where path is the path where the
rexx-parser resides, and the third link would only be
generated if the rexx-mystyle.css file was placed in the
directory where the highlight utility was run.
#!/usr/bin/env rexx
/******************************************************************************/
/* */
/* highlight.rex - Rexx highlighting example */
/* ========================================= */
/* */
/* This program is part of the Rexx Parser package */
/* [See https://rexx.epbcn.com/rexx-parser/] */
/* */
/* Copyright (c) 2024-2026 Josep Maria Blasco <josep.maria.blasco@epbcn.com> */
/* */
/* License: Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0) */
/* */
/* Date Version Details */
/* -------- ------- --------------------------------------------------------- */
/* 20241228 0.1d First public release */
/* 20241229 0.1e Add support for ANSI highlighing */
/* 20241231 Add support for LaTeX highlighing */
/* 20250102 0.1f Add --prolog and --noprolog options */
/* 20250103 Add -u --tutor and --unicode options */
/* 20250105 Add --patch="patch specs" and --patchfile=file */
/* 20250107 Change -t and --term for -a and --ansi */
/* 20250108 Add --pad= option */
/* 20250328 0.2 Main dir is now rexx-parser instead of rexx.parser */
/* 20250526 0.2b Add --css opt. & "-" to select .input (thanks, Rony!) */
/* 20250529 0.2c Add support for detailed string and number highlighting */
/* 20250706 0.2d Add support for detailed doc-comment highlighting */
/* 20251029 0.2e Change .stdin to .input (thanks, Rony!) */
/* 20251114 0.3a Add support for Experimental features */
/* 20251125 Add support for Executor */
/* 20251220 0.4a Disallow -xtr, etc when .md, .html, .htm */
/* 20251221 Add --itrace option, improve error messages */
/* 20251226 Send error messages to .error, not .output */
/* 20251226 Don't allow -s or --style for .md, improve error msgs */
/* 20251227 Use .SysCArgs when available */
/* 20251228 Add support for --default */
/* 20251230 Add support for --continue */
/* 20260102 Standardize help options to -h and --help */
/* 20260314 0.5 Use InitCLI() from CLISupport.cls */
/* */
/******************************************************************************/
Signal On Syntax
CLIhelper = InitCLI()
myName = CLIhelper~name
myHelp = CLIhelper~help
args = CLIhelper~args
-- We will store our processed options in a stem
options. = 0
-- Set default mode to ANSI if called from the command line...
Parse Source . how .
If how == "COMMAND"
Then options.mode = ANSI
-- ...otherwise, assume HTML.
Else options.mode = HTML
options.default = ""
myPath = FileSpec("Location",.context~package~name)
sep = .File~separator
patch = .Nil
styleSpecified = 0
Loop While args~size > 0, args[1][1] == "-"
option = args[1]
args~delete(1)
Select Case Lower(option)
When "--help" Then Signal Help
When "-s", "--style" Then Do
If args~size == 0 Then
Call Error "Missing style after '"option"' option."
options.style = args[1]
args~delete(1)
styleSpecified = 1
End
When "--default" Then Do
If args~size == 0 Then
Call Error "Missing attributes after '"option"' option."
options.default = args[1]
args~delete(1)
End
When "--doccomments" Then Do
If args~size == 0 Then
Call Error "Missing value after '"option"' option."
value = args[1]
args~delete(1)
If WordPos(value,"detailed block") == 0 Then
Call Error "Invalid value for --doccomments: '"value"'."
options.doccomments = value
End
When "--patch" Then Do
If args~size == 0 Then
Call Error "Missing value after '"option"' option."
patch = .StylePatch~of( args[1] )
args~delete(1)
End
When "--patchfile" Then Do
If args~size == 0 Then
Call Error "Missing value after '"option"' option."
value = args[1]
args~delete(1)
file = Stream(value,"C", "Q Exists")
If file == "" Then Call Error "File '"value"' not found."
value = File2Array( file )
patch = .StylePatch~of( value )
End
When "--startfrom" Then options.startFrom = Natural(value)
When "-w", "--width" Then options.width = Natural(value)
When "--pad" Then options.pad = Natural(value)
When "-it", "--itrace" Then options.itrace = 1
When "-h", "--html" Then options.mode = HTML
When "-l", "--latex" Then options.mode = LaTeX
When "-d", "--docbook" Then options.mode = DOCBOOK
When "-n", "--numberlines" Then options.numberlines = .True
When "-a", "--ansi" Then options.mode = ANSI
When "-xtr", "--executor" Then options.executor = 1
When "--css" Then options.css = 1
When "-u", "--tutor", -
"--unicode" Then options.unicode = 1
When "--noprolog" Then options.prolog = 0
When "--prolog" Then options.prolog = 1
When "--continue" Then options.continue = 1
When "-e", "-exp", "--experimental" Then
options.experimental = 1
Otherwise Call Error "Invalid option '"option"'."
End
End
If options.css, options.mode \== "HTML" Then
Call Error "The --css option cannot be used in" options.mode "mode."
-- This means that "highlight -h" will display help, which is good.
If args~items == 0 Then Signal Help
If args~items > 1 Then Call Error "Invalid argument '"args[2]"'."
file = args[1]
If file == "-" Then source = .Input~arrayIn
Else Do
fullPath = .context~package~findProgram(file)
If fullPath == .Nil Then Call Error "File '"file"' does not exist."
source = File2Array(fullPath)
End
If Options.css == 0 Then Do
Say ProcessSource()
Exit
End
-- Pick selected style
If Options.style == 0 Then mystyle = "dark"
Else mystyle = Options.style
-- A possible copy could reside in our rexx-parser installation
cssPath = ChangeStr("\",mypath".."sep"css"sep"rexx-"mystyle".css","/")
-- A possible copy could reside in the current directory
local = Stream(Directory()||sep"rexx-"mystyle".css","c","query exists")
Do line Over .Resources[HTML]
Select Case line
When "[*CSS*]" Then Do
Say " <link rel='stylesheet' href='https://rexx.epbcn.com/rexx-parser/css/rexx-"mystyle".css'></link>"
Say " <link rel='stylesheet' href='file:///"cssPath"'></link>"
If local \== "" Then Say " <link rel='stylesheet' href='rexx-"mystyle".css'></link>"
End
When "[*CONTENTS*]" Then Say ProcessSource()
Otherwise Say line
End
End
Exit
ProcessSource:
-- Markdown? Process the fenced code blocks and display the result
If file~caselessEndsWith(".md") Then Signal Fenced
-- HTML? Process the fenced code blocks and display the result
If file~caselessEndsWith(".html") | file~caselessEndsWith(".htm") Then
Signal Fenced
-- Assume it's Rexx
hl = .Highlighter~new(file, source, options.)
Return hl~parse( patch )
Fenced:
If styleSpecified | options.executor | options.experimental | options.unicode Then Do
.Error~Say( Copies("-",80) )
.Error~Say( "None of -exp, -s, -u, -xtr, --executor, --experimental, --unicode, --style" )
.Error~Say( "or --tutor can be specified for files with an extension of" FileSpec("E",file)"." )
.Error~Say( "Please use the --default option, or specific attributes in your" )
.Error~Say( "fenced code blocks instead." )
.Error~Say( "See https://rexx.epbcn.com/rexx-parser/doc/highlighter/fencedcode/ for details" )
Exit 1
End
Return FencedCode( file, source, , options. )
After:
If args~size == 0 Then
Call Error "Missing value after '"option"' option."
Return args~delete(1)
Natural:
If args~size == 0 Then
Call Error "Missing number after '"option"' option."
n = args[1]
args~delete(1)
If DataType(n,"W"), n > 0 Then Return n
Call Error "Positive whole number expected after '"option"', found '"n"'."
Syntax:
co = condition("O")
additional = Condition("A")
extra = additional~lastitem
line = extra~position
Parse Value co~code With major"."minor
.Error~Say( Right(line,6) "*-*" extra~sourceline )
-- Try to reconstruct the line number if we have enough information
name = extra~name
majorMessagePrinted = 0
If Right(name,1) == "]" Then Do
Parse Var name name1" [lines "start"-"end"]"
If name == name1" [lines "start"-"end"]" Then Do
majorMessagePrinted = 1
.Error~Say( "Error" major "in" name1", line" (start+line)": " ErrorText(major) )
End
End
If \majorMessagePrinted Then
.Error~Say( "Error" major "in" extra~name", line" line": " ErrorText(major) )
.Error~Say( "Error" co~code": " Ansi.ErrorText( co~code, additional ) )
If options.itrace Then Do
.Error~Say
.Error~Say( "Trace follows:" )
.Error~Say( Copies("-",80) )
.Error~Say( co~stackFrames~makeArray )
End
Exit -major
--------------------------------------------------------------------------------
Error:
.Error~Say(Arg(1))
Exit 1
--------------------------------------------------------------------------------
Help:
Say .Resources[Help]~makeString -
~caselessChangeStr("myName", myName) -
~caselessChangeStr("myHelp", myHelp)
Exit 1
--------------------------------------------------------------------------------
::Requires "Highlighter.cls"
::Requires "FencedCode.cls"
::Requires "CLISupport.cls"
::Requires "ANSI.ErrorText.cls"
::Resource Help
myname - Highlight a Rexx program, or a file containing Rexx programs
Usage: myname [OPTIONS] FILE
If the only option is -h or --help, or if no arguments are present,
then display this help and exit.
If FILE has a .md or .html extension, process all Rexx fenced code blocks
in FILE and highlight them. Otherwise, we assume that this is a Rexx file,
and we highlight it directly.
Options:
-a, --ansi Select ANSI mode
--continue Continue when a fenced code block is in error
--css Include links to css files (HTML only)
-d, --docbook Select DocBook mode
--default=attributes Select default attributes for code blocks
--doccomments=detailed|block Select highlighting level for doc-comments
-xtr,--executor Enable support for Executor
-e, -exp, --experimental Enable Experimental features
-h, --html Select HTML mode
-it, --itrace Printing internal traceback on error
-l, --latex Select LaTeX mode
--noprolog Do not print a prolog (LaTeX only)
-n, --numberlines Print line numbers
--patch="PATCHES" Apply semicolon-separated PATCHES
--patchfile=FILE Load patches from FILE
--pad=N Pad doc-comments and ::resources to N characters
--prolog Print a prolog (LaTeX only)
--startFrom=N Start line numbers at N
-s, --style=STYLE Use "rexx-STYLE.css" (default is "dark")
--tutor Enable TUTOR-flavored Unicode
-u, --unicode Enable TUTOR-flavored Unicode
-w, --width=N Ensure that all lines have width >= N (ANSI only)
The 'myname' program is part of the Rexx Parser package,
see https://rexx.epbcn.com/rexx-parser/. It is distributed under
the Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0).
Copyright (c) 2024-2026 Josep Maria Blasco <josep.maria.blasco@epbcn.com>.
See myhelp for details.
::END
::Resource HTML
<!doctype html>
<html lang='en'>
<head>
[*CSS*]
</head>
<body>
[*CONTENTS*]
</body>
</html>
::END