CEsc plugin for Take Command / TCC / TCC/LE

beta version 0.60.0.5     2024-04-03

Charles Dye

Purpose:

This plugin provides functions to expand C-style character escape sequences, and to replace troublesome characters with escape sequences.

Installation:

To use this plugin, copy CEsc.dll and CEsc.chm to some known location on your hard drive. (If you are using the 32-bit version of Take Command, take CEsc-x86.dll instead of CEsc.dll.) Load the .DLL file with a PLUGIN /L command, for example:

plugin /l c:\bin\tcmd\test\cesc.dll

If you copy these files to a subdirectory named PlugIns within your Take Command program directory, the plugin will be loaded automatically when TCC starts.

Plugin Features:

New Command:
EXPECHO
New Functions:
@ESCAPIFY@ESCENV@ESCLINE@ESCREAD@EXP
@EXPCMP@EXPFIND@EXPREPLACE@EXPWRITE
New Variable:
_CESCVER

Syntax Note:

The syntax definitions in the following text use these conventions for clarity:

BOLD CODEindicates text which must be typed exactly as shown.
CODEindicates optional text, which may be typed as shown or omitted.
Bold italicnames a required argument; a value must be supplied.
Regular italicnames an optional argument.
ellipsis…after an argument means that more than one may be given.

New Command:

EXPECHO — Expand escapes and display text.

Syntax:
EXPECHO text

textthe text to be displayed

Escape sequences will be expanded, and the resulting text sent to stdout. EXPECHO does not automatically append an end-of-line. If you want one, append \r\n to the text.

expecho Test:\t\U1f431\r\n



New Functions:

@ESCAPIFY — Returns the string, with troublesome characters escaped.

Syntax:
%@ESCAPIFY[string]

stringstring to be escapified

This function returns the input string, with troublesome characters replaced by C-style character escape sequences. See Escapification for more details.

You can use the CESC_CHARS and CESC_FLAGS environment variables to tweak the way text is escapified.

echo %@escapify[<p>This is a test.</p>]

See also: @EXP, which performs the reverse operation, expanding escape sequences in a string.



@ESCENV — Returns the value of an environment variable, escapified.

Syntax:
%@ESCENV[varname]

varnamethe name of an environment variable

This function is useful with commands such as INPUT or DO var IN @file, which stash text directly in an environment variable without first passing it through the command parser. Do not type a percent sign before the variable name. If you do, TCC’s parser will expand the variable before @ESCENV sees it.

You can use the CESC_CHARS and CESC_FLAGS environment variables to tweak the way text is escapified.

input Type some text: %%text
set text=%@escenv[text]
expecho You typed \u201c%text\u201d.\r\n

Note: If you want to use this function in conjunction with the FOR command, be aware that FOR only stores its control variable in the environment if the variable name is more than one character long.



@ESCLINE — Returns a line from a file, escapified.

Syntax:
%@ESCLINE[filename,n]

filenamethe file to read from
nthe line to read; 0-based

Return line n from the file, with special characters escapified. Line numbers begin at 0. Returns **EOF** for lines past the end of the file.

You can use the CESC_CHARS and CESC_FLAGS environment variables to tweak the way text is escapified.

This function calls @LINE internally.

for /l %i in ( 0, 1, 20 ) echo %i: %@escline[cesc.html,%i]



@ESCREAD — Returns text from a file, escapified.

Syntax:
%@ESCREAD[handle,len]

handlemust be a handle returned by @FILEOPEN
lenthe number of bytes to read

Reads text from the file opened as handle, with special characters escapified. Returns **EOF** if you try to read past the end of the file.

If len is not specified, @ESCREAD will read until the next end-of-line. If len is specified, @ESCREAD will read len bytes regardless of any end-of-line characters.

You can use the CESC_CHARS and CESC_FLAGS environment variables to tweak the way text is escapified.

This function calls @FILEREAD internally.

@echo off
rem   Batch file to test @ESCREAD:
setlocal

set handle=%@fileopen[%_batchname,r]

do
   set line=%@escread[%handle]
   if "%line" == "**EOF**" leave
   echo %line``
enddo

set rv=%@fileclose[%handle]
endlocal

See also: @EXPWRITE, which does the reverse.



@EXP — Expands C escape sequences in a string.

Syntax:
%@EXP[string]

stringthe string to be expanded

This function returns the input string after expanding escape sequences.

echo %@exp[Hello:\t\U1f601]

See also: @ESCAPIFY, which performs the reverse operation, escaping troublesome characters in a string.



@EXPCMP — Compares two strings after expanding escapes.

Syntax: %@EXPCMP[string1,string2,flags]

string1the first string to compare
string2the second string to compare
flags1: case insensitive

Use commas to separate arguments. If you need a comma in either string, either enclose the string in double quotes, or else use \c or \x002c to represent the comma.

If you need a double quote in either string, use \q or \x0022 to represent it.

This function returns 0 if the two strings match, or nonzero if they don’t.

rem   Case sensitive:
echo %@expcmp[Cr\ue8me br\ufbl\u00e9e \u20ac3.50,CR\uc8ME BR\udbL\u00c9E \u20ac3.50]

rem   Case insensitive:
echo %@expcmp[Cr\ue8me br\ufbl\u00e9e \u20ac3.50,CR\uc8ME BR\udbL\u00c9E \u20ac3.50,1]



@EXPFIND — Searches for one string within another after expanding escapes.

Syntax: %@EXPFIND[string,substring,n,flags]

stringthe string to search within
substringthe string to search for
nnth match in string
flags1: case sensitive
8: return offset and length

Use commas to separate arguments. If you need a comma in either string, either enclose the string double quotes, or else use \c or \x002c to represent the comma.

If you need a double quote in either string, use \q or \x0022 to represent it.

This function returns -1 if the substring was not found in the string, or a different value if it was. If either string or substring is empty, there is no match and the function returns -1.

The n argument can be used to look for multiple occurences of the substring in the string. If n is positive, @EXPFIND will return the nth instance of substring. If n is negative, @EXPFIND will return the last, next-to-last, etc. instance. If n is zero, @EXPFIND will return the number of matches. If n is not specified, it defaults to 1 — the first instance.

When a match is found, the return value is the zero-based offset in the original string — i.e. before any expansion of escapes. If bit 4 of flags is set, @EXPFIND returns both the offset and the length of substring, separated by a + sign. Again, these refer to the original string before any expansion of escapes.

rem   Case insensitive:
echo %@expfind[\x41\x42\x43\x44\x45\x46\x47\x48,cde]

rem   Case sensitive:
echo %@expfind[\x41\x42\x43\x44\x45\x46\x47\x48,cde,,1]

There may be multiple matches in one string. You can use the n argument to select each:

for /l %i in ( 0, 1, 5 ) echo %i - %@expfind["B\x61n\x61n\x61 b\x61n\x61n\x61r\x61m\x61!",ana,%i]



@EXPREPLACE   Replaces text in an escaped string.

Syntax:
%@EXPREPLACE[from,to,flags,string]

fromthe substring to find and replace
tothe text which will replace from
flags1: case insensitive
2: replace only the first match
4: do not escapify the resulting string
stringthe string in which to find and replace text

Use commas to separate arguments. If you need a comma in any string, either enclose it in double quotes, or else use \c or \x002c to represent the comma. If you need a double quote, use \q or \x0022 to represent it.

All three string arguments — from, to, and string — may contain character escapes; they will be expanded before the search.

You can use the CESC_CHARS and CESC_FLAGS environment variables to tweak the way text is escapified.

echo %@expreplace[:),\U1f600,4,:):) Have a nice day! :):)]



@EXPWRITE — Writes a line to a file, with escapes expanded.

Syntax:
%@EXPWRITE[handle,text]

handlea handle returned by @FILEOPEN
textthe text to write to the file

A carriage return and line feed will be appended to the text automatically.

@echo off
rem   Batch file to test @ESCWRITE:
setlocal
option //unicodeoutput=no

set h1=%@fileopen[%_batchname,r]
set h2=%@fileopen[testfile.out,w]

do
   set line=%@escread[%h1]
   if "%line" == "**EOF**" leave
   set rv=%@expwrite[%h2,%line]
enddo

set rv=%@fileclose[%h1] %@fileclose[%h2]
endlocal

See also: @ESCREAD, which does the reverse.



New Variable:

_CESCVER — Returns the version of ExpandEscapes.cpp used to build this plugin.

Syntax:
%_CESCVER

This variable returns the version number of ExpandEscapes.cpp in this plugin. Note that this is not the same thing as the plugin version; use %@PLUGINVER[CESC] to get that.



Escape Sequences:

This plugin recognizes these escape sequences:

Code:Expands to:Example:
\nnnoctal value, up to 777\101 → A
\\backslash (0x5c)
\aASCII BEL character (0x07)
\bbackspace
\ccomma
\eASCII ESC character (0x1b)
\fform feed (0x0c)
\kgrave accent (0x60)
\nline feed (0x0a)
\qdouble quotes (0x22)
\rcarriage return (0x0d)
\sspace (0x20)
\ttab (0x09)
\unnnnUnicode character, up to U+FFFF\u03a3 → Σ
\UnnnnnnnnUnicode character, up to U+10FFFF\U0001f63a → 😺
\vvertical tab (0x0b)
\xnnnnhexadecimal value, up to FFFF\x0041 → A
\#nnnnndecimal value, up to 65535\#65 → A

Note that case is significant for the letter after the backslash. All must be lowercase, except for \Uxxxxxxxx.

Case is not significant in hexadecimal values. \uxxxx and \xxxxx read up to four hexadecimal digits; \Uxxxxxxxx reads up to eight. You may use fewer than four (or eight) digits if the following character is not a valid hex digit.

Similarly, octal character escapes read up to three octal digits. You may use fewer than three if the following character is not an octal digit. Decimal escapes read up to five decimal digits; you may use fewer than five if the following character is not a digit.

Escapification:

These characters will be replaced with escape sequences:

Value:Characters:
0x01 - 0x1fASCII control characters
0x22"  double quotes
0x25%  percent sign
0x26&  ampersand
0x3c<  less-than sign
0x3e>  greater-than sign
0xb5[  open bracket
0x5c\  backslash
0x5d]  close bracket
0x5e^  caret
0x60`  grave accent
0x7c|  vertical bar
0x7fASCII DEL character
0x80 - 0x9fC1 control characters
0xa0non-breaking space
0x10000 - 0x10ffffany Unicode character not in the BMP
TCC’s current command separator character
TCC’s current escape character
anything in the CESC_CHARS environment variable

Two environment variables affect the escapification process:

CESC_CHARS contains a list of characters to be escaped. This list is in addition to the characters in the table above, which will always be escaped regardless of CESC_CHARS. For example, if you need the dollar sign to be replaced with an escape sequence, you could:

set cesc_chars=$

CESC_FLAGS is a bitmapped numeric value:

1escape all non-ASCII characters, i.e. everything above 0x7F DEL
4use the nonstandard \e \q \c \k for ESC, double quote, comma, grave accent
8allow short form of numeric escapes at the end of the string

Startup Message:

This plugin displays an informational line when it initializes. The message will be suppressed in transient or pipe shells. You can disable it for all shells by defining an environment variable named NOLOADMSG, for example:

set /e /u noloadmsg=1

Status and Licensing:

Consider this beta software. It may well have issues. Try it at your own risk. If you find a problem, you can report it in the JP Software support forum.

CEsc is currently licensed only for testing purposes. I may make binaries and source code available under some free license once I consider it ready for use.

Download:

You can download the current version of the plugin from http://charlesdye.net/dl/cesc.zip.