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) |
--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 highlighting |
-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) |
-a, --ansi
Selects ANSI highlighting using ANSI SGR (Select Graphic Rendition) codes.
--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.
-e, -exp, --experimental
Enables Experimental Rexx features so that they are recognized by the Parser.
-h, --html
Selects HTML highlighting.
See also --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, --executor
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 */
/* */
/******************************************************************************/
Parse Arg fn
-- Remember how we were called
Parse Source . how myself
myPath = FileSpec("Location",myself)
sep = .File~separator
-- 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
-- Process user options, if any
patch = .Nil
Loop
Parse var fn op value rest
If op[1] \== "-" | fn == "-" Then Leave
If op~contains("=") Then Do
fn = Strip(value rest)
Parse Var op op"="value
Select Case Lower(op)
When "--startfrom" Then options.startFrom = Natural(value)
When "--style" Then options.style = value
When "--width" Then options.width = Natural(value)
When "--pad" Then options.pad = Natural(value)
When "--doccomments" Then Do
If WordPos(value,"detailed block") == 0 Then Do
Say "Invalid value '"value"'."
Exit 1
End
options.doccomments = value
End
When "--patch" Then Do
Call AllowQuotes
If value = "" Then patch = .Nil
Else patch = .StylePatch~of( value )
End
When "--patchfile" Then Do
Call AllowQuotes
If value = "" Then Do
Say "Invalid option '"op"'."
Exit 1
End
file = Stream(value,"C", "Q Exists")
If file == "" Then Do
Say "File '"value"' not found."
Exit 1
End
value = CharIn( file, 1, Chars(file) )~makeArray
Call Stream file, "C", "Close"
patch = .StylePatch~of( value )
End
Otherwise Do
Say "Invalid option '"op"'."
Exit 1
End
End
Iterate
End
gotAValue = 1
Select Case Lower(op)
When "-s" Then options.style = value
When "-w" Then options.width = Natural(value)
Otherwise gotAValue = 0
End
If gotAValue Then Do
fn = rest
Iterate
End
Select Case Lower(op)
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 "-e", "-exp", "--experimental" Then options.experimental = 1
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
Otherwise Do
Say "Invalid option '"op"'."
Exit 1
End
End
fn = Strip(value rest)
End
-- We need an argument
If fn = "" Then Do
Say .Resources[Help]
Exit 1
End
If fn == "-" Then source = .Input~ArrayIn
Else Do
-- Process filenames containing blanks
fn = Strip(fn)
c = fn[1]
If """'"~contains( c ) Then Do
Parse Var fn (c)fn2(c)extra
If extra \== "" Then Do
Say "Invalid filename '"fn"'."
Exit 1
End
fn = fn2
End
-- Check that the file exists
file = Stream(fn, 'c', 'q exists')
If file == "" Then Do
Say "File '"fn"' not found."
Exit 1
End
-- Load the whole file in the "source" array
source = CharIn(file,1,Chars(file))~makeArray
Call Stream file,"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 Return FencedCode( fn, source )
-- HTML? Process the fenced code blocks and display the result
If file~caselessEndsWith(".html") | file~caselessEndsWith(".htm") Then
Return FencedCode( fn, source )
-- Assume it's Rexx
hl = .Highlighter~new(fn, source, options.)
Return hl~parse( patch )
AllowQuotes:
q = value[1]
If """'"~contains( q ) Then Do
fn = value fn
Parse Var fn (q)value(q)fn
End
Return
Natural:
If DataType(Arg(1),"W"), Arg(1) >= 0 Then Return Arg(1)
Say "Invalid value" Arg(1)"."
Exit 1
--------------------------------------------------------------------------------
::Requires "Highlighter.cls"
::Requires "FencedCode.cls"
::Resource Help
Usage: highlight [OPTIONS] FILE
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
--css Include links to css files (HTML only)
--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
-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 'highlight' program is part of the Rexx Parser package, and is distributed
under the Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0).
Copyright (c) 2024, 2025 Josep Maria Blasco <josep.maria.blasco@epbcn.com>.
::END
::Resource HTML
<!doctype html>
<html lang='en'>
<head>
[*CSS*]
</head>
<body>
[*CONTENTS*]
</body>
</html>
::END
