HTMX Lang
HTMX Lang
expandfile
Tom Van Vleck
x.htmx x.htmx
y.htmi templates expandfile output
x.html
conf.htmi
config
§HTMX is an extension language for HTML
§expandfile can run offline or online
§Can produce any format of output, not just HTML
HTMX Benefits
• Simplify features of HTML.
• Avoid errors.
• Edit one file instead of many:
– Standard headers, footers, values.
– One file can depend on another’s content.
– One file can depend on another’s attributes.
• Fill in values automatically.
• Can still use any HTML feature.
1. Set variable humordate to the date a file was modified. (External program
filemodshort returns the date modified of a file as mm/dd/yy.)
2. Set humorK to the size of a file, by calling external program filesizek .
3. Set humoru to contents of updatedflag if file is less than 9 days old.
4. Insert a line beginning with <dt>.
5. Insert a <dd> block with the file's size and date last modified.
HTMX example 3a
1 %[*include,=htmxlib.htmi]%
....
2 %[*callv,myfileinfo,="multics-humor"]%
<dt><a href="multics-humor.html">
3 <span class="topic">Humor</span></a>%[humoru]%</dt>
4 <dd>Jokes about Multics. %[fileattrib]%</dd>
<div class="pic">
<a href="p2.gif"><img src="sp2.gif" width="300" height="317"
alt="horse" title="click for larger view."></a>
</div>
• %[block]%
• Inserts the contents of a variable or block,
expanding any %[..]% references inside.
Variables
• Variables have names
• Letters, digits, spaces, ()-+_. are allowed.
• All-numeric names cause a warning.
%[year]% 2004
%[prevyear]% 2003
%[day]% 07
%[month]% Oct
%[prevmonth]% Sep
%[monthx]% 10
%[hour]% 09
%[min]% 31
%[date]% 07 Oct 2004
%[timestamp]% 2004-10-07 09:31
%[pct]% %
%[lbkt]% [
%[rbkt]% ]
%[quote]% "
%[_xf_currentfilename]% xyz.htmx
37 HTMX built-in functions
Begin with *. Won’t cause blank lines in the output if they are
the only thing on a line.
• %[*include,=filename]%
– insert the contents of filename, expanding variables in it.
– (use the *fread2 builtin to read files without expanding values.)
• %[*set,&varname,value]%
– set varname to "value", for later expansion.
– value can be
• =string Literal string value, e.g. ="2 cats", =Fred
• name Value of variable name, from a previous set
• envvar Value of shell environment variable envvar
• %[** a remark]%
– Is a comment.
HTMX Blocks
• %[*block,&blockname,end-re]%
– Reads following lines until a line matching regular expression
end-re and puts the lines in variable blockname.
– For end-re, use something like ^EOB.
– Variables and builtins in the block are not expanded at
definition time, but instead when the block is expanded later.
– Specifying the same blockname more than once appends
content to the block definition.
– Must be alone on a line. Blocks do not nest.
• Examples:
– %[*if,=,moddate,="",*set,&moddate,date]%
– Sets moddate to the current date if it is blank.
– %[*if,eq,d,="0",*if,ne,sm,="",*fwrite,=%[m]%,sm]%
– If d is zero and sm is nonblank, write sm into file m.
– %[*if,gt,x0,=999,*subst,&w0,="^.*(...)$",=",$1"]%
– Drops all but the last 3 characters of w0 and prefixes them with a comma.
More HTMX built-ins
• %[*expand,varname]%
– Expand constructs in varname, output the result.
• %[*expandv,&var,varname]%
– Expand constructs in varname, put result in var, output
nothing.
• %[*concat,&varname,value]%
– Concatenate value onto the value in varname, output nothing.
• %[*ncopies,&varname,value,n]%
– Put n copies of value into varname, output nothing.
• %[*subst,&varname,left,right]%
– Apply Perl substitution s/left/right/ig to the contents of
varname, replacing its contents, output nothing.
• left can be a regular expression.
• left can contain parenthesized strings, used in right as $1 $2 etc.
• Backslashes in the expression need to be doubled.
• Slashes in left or right need to be prefixed by \\
HTMX Arithmetic
• %[*increment,&varname,value]%
– Increment varname's contents by contents of value, output
nothing.
• %[*decrement,&varname,value]%
– Decrement varname's contents by contents of value, output
nothing.
• %[*product,&varname,value1,value2]%
– Multiply value1 by value2 and store in varname, output
nothing.
• %[*quotient,&varname,value1,value2]%
– Divide value1 by value2 and store integer in varname,
output nothing.
• %[*quotientrounded,&varname,value1,value2]%
– Divide value1 by value2, round, store integer in varname,
output nothing.
• %[*scale,&varname,value1,value2,value3]%
– Store int(.5+(value1*value3)/value2) in varname,
output nothing.
External files
• %[*fwrite,=file,varname]%
– Write contents of varname to file, output nothing.
• %[*fappend,=file,varname]%
– Append contents of varname to file, output nothing.
• %[*fread,&varname,=file]%
– Read contents of file into varname, output nothing.
– If input is not found, sets varname to empty string.
– Does not expand values or blocks.
External Values
– %[*shell,&x,abc]%
• Executes the shell command in variable abc, sets x to
result, output nothing. If multiple lines are returned, change
newline to the value of _xf_ssvsep (default is space).
• Example:
%[*shell,&xdate,=filemodiso %[inputfile]%]%
might set xdate to "2016-07-04"
– %[*urlfetch,&varname,=url]%
• Read contents of url into varname, output nothing.
• (Think carefully about security if you do something like
this.)
External Shell Scripts
• Useful external shell commands
– supplied with expandfile, written in Perl
– Import values into expandfile
– write your own as needed, in any language
• %[*htmlescape,varname]%
– Output a HTML-escaped version of varname.
– <fred> => <fred>
• %[*warn,message]%
– Write a line to STDERR.
• %[*dump]%
• Output the entire symbol table for debugging.
• %[*exit]%
– Stop expanding.
Special Files
• config.htmi
– Defines values you use in many files.
– Sequence of %[*set,&var,=value]% commands.
– Specify on command line.
Formatted output:
%[outvar]% expansion of variable set by CSV loop
XML loops
• A similar loop operates on each item in an XML file.
(The file may be gzipped.)
– %[*xmlloop,&resultvar,tpt,=filename]%
– XML file has
• outermost <list> ... </list>
• containing a sequence of <item> ... </item>
– Each item contains multiple fields
• <item>
• <name>John Smith</name>
• <addr>1234 Any Street</addr>
• </item>
– For each item, binds fields to names like item.name, expands
tpt, appends result to resultvar, outputs nothing.
– Binds _xf_nxml to number of items read, after loop finishes.
– Binds _xf_xmlfields to space separated list of field names.
– Instead of <cite> use !!cite!!whatever!!/cite!!
– Instead of á use &aacute;
XML loops cont.
• An alternate form of the loop allows an XPath
– %[*xmlloop,&resultvar,tpt,=filename,xpath]%
– for cases where the XML structure is more complex.
– if xpath is not specified, the default is "/*/*"
– for each item found by the XPath arg,
• bind the values of sub-items "./*"
• bind the values of attributes of items "./@*"
– example JAMF file, access items with "*/computers/computer"
<?xml version="1.0" encoding="UTF-8"?>
<computer_group>
<name>All Managed Clients</name>
<computers>
<size>119</size>
<computer>
<name>QA2 MacBook</name>
<serial_number>54321</serial_number>
</computer>
<computer>
<name>Rocky</name>
<serial_number>12345</serial_number>
</computer>
...
File System Loops
• A similar loop iterates over a directory.
• %[*dirloop,&outvar,iter,dirpath,starrex]%
• Lists directory dirpath and expands block iter for each file
matching regular expression starrex; output is appended to
variable outvar, outputs nothing.
• e.g. %[*dirloop,&out,it2,="/home/jack/xx",="*.html"]%
• Binds variables to the values of status() info on each file:
– file_name, file_type, file_dev, file_ino, file_mode,
file_nlink, file_uid, file_gid, file_rdev, file_size,
file_atime, file_mtime, file_ctime, file_blksize,
file_blocks, file_sec, file_min, file_hour, file_mday,
file_mon, file_year, file_wday, file_yday, file_isdst,
file_datemod, file_modshort, file_sizek, file_age
• Variable file_type is set to 'f' for file, 'd' for dir, 'l' for link
SSV Loops over variables
• A similar loop iterates over a list of items in a string value.
("ssv" stands for "space separated values")
• %[*ssvloop,&outvar,iterblock,ssv]%
– Breaks ssv into tokens and expands iterblock for each,
binding _xf_ssvitem to the token (skips null tokens).
– Binds _xf_nssv to the number of tokens processed.
– Token separator is the value of _ssvsep, default is space.
– Result is stored in outvar.
– Outputs nothing. Does not modify ssv.
• %[*popssv,&var,&ssv]%
– Takes first value from ssv, puts it in var, rewrites ssv to
remove value, outputs nothing.
External Programs
• Invoke any shell program or script and capture its output.
• Example:
– %[*shell,&result,=filemodshort myfile.htmx]%
• Called from Perl, output has NL changed to space
• Useful programs (can be written in any language):
– filemodshort file => 03/27/07
– filesizek file => 33
– nargs a bb c dd e f g => 7
– gifsize pic.jpg => "pic.jpg" width="75" height="75"
– lowercase ABcdE => abcde
– nrandomlines x.htmx n (n lines from x.htmx separated by |)
– firstletter applecart => a
– filedaysold filename => 12
– fmtnum 123456 num => 123,456
– grep, sed, date, cut, awk => (Unix command output)
• Write your own as needed
Bind values from a CSV file
• Read a file in CSV format and bind variables in the memory.
– %[*bindcsv,=file]%
– The file can specify a local disk file or a URL.
– First line of the file provides the column names.
– Second line of the file provides the column values.
– Will not bind variables beginning with _ or . for security.
• For example, each server listed in an SSV could prepare a
two-line .csv file, and a simple loop over the SSV could
create an HTML table with a row for each server showing
status.
• Binds _xf_colnames to the column names set.
• A warning is printed if the file is not found.
Macro Example
Call: %[*callv,imgtag,="abc.jpg",="AAA",="Bbb"]%
Generates: <img src="abc.jpg" width="75" height="75" border="0" alt="AAA" title="Bbb">
Use: generates IMG tag and fills in size in pixels, ALT and TITLE