Highlight
Usage:
[rexx] highlight [options] file
The utility can run in one of three modes, namely, ANSI mode, HTML mode, and LaTeX 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.
Options:
-a, --ansi |
Select ANSI SGR terminal highlighting |
--css |
Include links to css files (HTML only) |
--continue |
Continue when a fenced code block is in error (HTML only) |
--doccomments detailed|block |
Select highlighting level for doc-comments |
-xtr,
--executor |
Enable support for Executor |
-e, -exp,
--experimental |
Enable Experimental features |
-h |
Display help (when used alone) o select HTML highlighting |
--html |
Select HTML highlighting |
--help |
Display this help |
-it,
--itrace |
Print internal traceback on error |
-l, --latex |
Select LaTeX highlighting |
--noprolog |
Don't print a prolog |
-n,
--numberlines |
Print line numbers |
--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: Several of the options below
(-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.
-a, --ansi
Selects ANSI highlighting using ANSI SGR (Select Graphic Rendition) codes.
--continue
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.
--css
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.
--doccomments [detailed|block]
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.
--default attributes
Specifies the default attributes to be applied to all the highlighted code blocks.
--executor
Enables support for JLF's Executor extensions.
-e, -exp, --experimental
Enables Experimental Rexx features so that they are recognized by the Parser.
-h, --html
Selects HTML highlighting.
See also --css (#css).
-l, --latex
Selects LaTeX highlighting.
--noprolog
Don't print a prolog (LaTeX only).
See also --prolog.
-n, --numberlines
Print line numbers.
See also --startFrom.
--patch "patches"
Apply the semicolon-separated list of patches.
See also --patchFile.
--patchFile file
Apply the patches contained in file.
See also --patch.
--prolog
Print a prolog (LaTeX driver only).
See also --latex and --noprolog.
--startFrom n
Start numbering lines at line n.
See also --numberlines
-s, --style style
Use the rexx-style.css style sheet. The default
is rexx-dark.css.
--tutor
Enable TUTOR-flavored Unicode.
See also --unicode.
--u, --unicode
Enable TUTOR-flavored Unicode.
See also --tutor.
-w, --width n
Ensure that lines have a minimum width of n characters (ANSI highlighting only).
See also --ansi.
-xtr
Enables support for JLF's Executor extensions.
Example:
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 places in the
directory where the highlight utility was run.
Program source:
#!/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 */
/* */
/******************************************************************************/
Signal On Syntax
package = .context~package
myName = package~name
Parse Caseless Value FileSpec( "Name", myName ) With myName".rex"
myHelp = ChangeStr( -
"myName", -
"https://rexx.epbcn.com/rexx-parser/doc/utilities/myName/", -
myName)
Parse Source . how .
If how == "COMMAND", .SysCArgs \== .Nil
Then args = .SysCArgs
Else args = ArgArray(Arg(1))
-- We will store our processed options in a stem
options. = 0
-- Set default mode to ANSI if called from the command line...
If how == "COMMAND"
Then options.mode = ANSI
-- ...otherwise, assume HTML.
Else options.mode = HTML
options.default = ""
myPath = FileSpec("Location",myself)
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 = CharIn( file, 1, Chars(file) )~makeArray
Call Stream file, "C", "Close"
patch = .StylePatch~of( value )
args~delete(1)
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 "-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 "--tutor" Then options.unicode = 1
When "-u", "--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 = CharIn(fullPath,1,Chars(fullPath))~makeArray
Call Stream fullPath,"c","close"
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 "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)
--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
