WML_INTRO(7)
π NAME π
WML Introduction β that's the name, and this is the WML_INTRO(7) page from the EN Tools crew β¨ It's literally just an introduction to WML's basic concepts. That's the assignment. Basics only. We're easing in, bestie π«Ά
β¨ DESCRIPTION β¨
WML is a free HTML generation toolkit for Unix, and ngl, internally it's made of 9 independent languages. Nine. Whole languages. It's giving overachiever and honestly? Obsessed π
The big main-character idea behind WML is a sequential filtering scheme β each of those 9 languages handles one of the 9 processing passes. So the frontend wml reads inputfile (or pulls from stdin if inputfile is a dash or is completely missing β no notes, she just handles it), applies passes 1β9 (or only the passes you specify with -p), and finally produces one or more outputfiles. Slay.
WML implements a total of three essential concepts, and they all interact with each other. Here's concept one π
π CONCEPT 1: SEQUENTIAL FILTERING SCHEME π
This concept is how WML gets all its various language features β by making use of maximum software leverage. Which is a fancy way of saying WML is built on top of 9 languages that the wml frontend runs in a very well-ordered fashion. Cute, organized, lowkey iconic.
π Pass 1: Source Reading and Include File Expansion π
- Processing: explicit
- Implementation: Include Pre-Processor (IPP)
- Author: Ralf S. Engelschall <rse@engelschall.com>
- See Also:
wml_p1_ipp(3)
Description:
This first pass reads inputfile and expands all the inlined include file directives by substituting them with the contents of the matching file β and yes, it can do that recursively, she's thorough π§ The file itself gets read from the current working directory or from a list of dedicated include directories (the compiled-in ones, plus whatever you hand over with option -I).
When you append name=value pairs to the include directive, $(name) expands to value in that particular include file and in all the files it recursively includes. On top of that, this pass gives you an End-Of-Line continuation feature and three special strings. __FILE__ and __LINE__ expand to the current include file and line number, while __END__ terminates the reading of the current include file. Periodt.
Summary Of Essential Features:
#include 'file.wml' [name[=value] ...]
#include "file.wml" [name[=value] ...]
#include <category/file.wml> [name[=value] ...]
#use wml::category::file [name[=value] ...]
some text which is \
continued at this line
$(name)
__FILE__, __LINE__
__END__
Example:
#use wml::std::tags
This FooBar, contained in file __FILE__, line __LINE__.
__END__
Documentation of FooBar...
π¦ Pass 2: High-Level Macro Construct Expansion π¦
- Processing: explicit
- Implementation: Macro Processor for HTML Documents (mp4h)
- Author: Denis Barbier <barbier@engelschall.com>
- See Also:
mp4h(1),http://www.engelschall.com/sw/mp4h/
Description:
This is the HTML-like macro definition and expansion pass π Here you define brand-new HTML tags with <define-tag foo>, and later they get expanded wherever you use them (<foo>). The goal of this pass is to create new HTML tags that encapsulate either raw text or even programmed functionality from Pass 3 (ePerl). Very demure, very powerful.
Summary Of Essential Features:
<define-tag foo>
...%attributes...
</define-tag>
<define-tag bar endtag=required>
...%attributes...%body...
</define-tag>
<foo ...>
<bar ...>...</bar>
Example:
<define-tag me>RSE</define-tag>
This is <me>.
π₯ Pass 3: Programming Construct Expansion π₯
- Processing: explicit
- Implementation: Embedded Perl 5 Language (ePerl)
- Author: Ralf S. Engelschall <rse@engelschall.com>
- See Also:
eperl(1),http://www.engelschall.com/sw/eperl/
Description:
This is where the real programming happens, bestie. The language in play is Larry Wall's Perl 5 scripting language π The language constructs get bristled into the HTML markup code using begin (<:) and end (:>) delimiters.
Plus this pass hands you some very nice shortcuts: first, a <#if..#elsif..#else..#endif> construct that expands into the corresponding Perl construct; second, a shorthand (<:= ...:>) for the construct (<: print ...:>) β which is the one you'll use most of the time, fr. And there's a container tag in wml::std::tags that gives you the more high-level container tag <perl>. Chef's kiss.
Summary Of Essential Features:
<perl> ...Perl 5 constructs... </perl>
<: ...Perl 5 constructs... :>
<:= ... :>
Example:
#use wml::std::tags
<perl>
sub isotime {
my ($time) = @_;
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
localtime($time);
my ($str) = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
$year+1900, $mon+1, $mday, $hour, $min, $sec);
return $str;
}
</perl>
The current date is <:= &isotime(time()) :>.
π Pass 4: Low-Level Macro Construct Expansion π
- Processing: explicit
- Implementation: GNU m4
- Author: Ren'e Seindal (FSF)
- See Also:
m4(1),http://www.gnu.mit.edu/
Description:
Another macro processor run takes place here. Where Pass 2 used a macro processor with an HTML-like syntax for high-level macro programming, this pass uses a macro processor for low-level programming. Mostly it's here to give you low-level symbol and function definitions (m4_define()). There's a definition in wml::std::tags that gives you a more high-level way to use it via the <symbol> tag.
Notice: this pass runs under a special environment, so listen up π 1. All m4 builtin macros have to be prefixed withm4_. 2. All variables defined by WML (both the internal ones and the ones from the-Doption) are directly accessible via symbols prefixed withm4_, i.e. variableNAMEis interpolated whenm4_NAMEoccurs. 3. The quoting characters are disabled per default, to prevent problems with the generated content. If you need quotes (for instance in include files) you have to enable them viam4_quotesand disable them later viam4_noquotes.
Summary Of Essential Features:
m4_quotes
m4_define(`name', `value')
m4_noquotes
<symbol name value>
Example:
#use wml::std::tags
<symbol bar BAZ>
foo bar quux
πΈ Pass 5: Diversion Filter πΈ
- Processing: explicit
- Implementation: Divert
- Author: Ralf S. Engelschall <rse@engelschall.com>
- See Also:
wml_p5_divert(3)
Description:
This pass applies a flexible and powerful diversion filter β the whole point is to give you a mechanism to change and intermix the order of data blocks. Do not intermix this with either the general macro mechanisms of Pass 2 and 4, or with the less powerful divert mechanism of GNU m4. (Not the same thing, don't do it π)
The idea: you define locations (via {#NAME#}) at any point, and fill those locations later by diverting the data flow to them (via {#NAME#: and :#NAME#}) at some other point. What makes this filter so powerful is that both the definition points and the diversion points can happen in any order, and they can even be nested. And again, WML provides high-level support tags in wml::std::tags for this functionality. Main character energy, honestly.
Summary Of Essential Features:
{#NAME#}
<dump NAME>
{#NAME#:
data for location `NAME'
:##}
<enter NAME>
data for location `NAME'
<leave>
<divert NAME>
data for location `NAME'
</divert>
Example:
<table>
<tr>
<td><dump LBORDER></td>
<td><dump BODY></td>
<td><dump RBORDER></td>
</tr>
</table>
<divert LBORDER>
Stuff for the left border
</divert>
<divert RBORDER>
Stuff for the right border
</divert>
<divert BODY>
The main data
</divert>
π Pass 6: Character and String Substitution π
- Processing: explicit
- Implementation: Area Subst (ASubst)
- Author: Ralf S. Engelschall <rse@engelschall.com>
- See Also:
wml_p6_asubst(3)
Description:
In this pass, single characters or substrings get substituted inside dedicated areas (delimited by {: ... :}). The intent is to support ISO-Latin-1 or other special characters that get entered as 8 Bit character codes and are substituted by their HTML entity-encoding string.
Do not intermix this with macro-expansion of Pass 2 or 4, okay? This is a generalized regular-expression-based substitution pass, where you can use Perl's s/../../ and tr/../../ commands to specify the substitutions. You can place these anywhere inside the substitution area and they just have to be marked by [[...]] delimiters β but the commands are always applied to the whole area. No exceptions, bestie.
Summary Of Essential Features:
{: ...text..[[s/../../flags]]..
...text..[[tr/../../flags]].. :}
Example:
{: [[s|X|ä|]] [[s|X|ü|]]
Foo Bar Baz Quux with Umlauts X and X
:}
β Pass 7: Markup Code Fixup β
- Processing: implicit
- Implementation: HTMLfix
- Author: Ralf S. Engelschall <rse@engelschall.com>
- See Also:
wml_p7_htmlfix(3)
Description:
Here's where some commonly known HTML markup code fixups get done, and it's genuinely so helpful π«Ά For instance: missing WIDTH and HEIGHT attributes for all IMG tags are calculated and added, ALT tags are added where they're missing, missing "#" characters in front of hextriple color attributes are added, numeric attribute values get surrounded by quotes, and obsolete HTML markup code like the proprietary <center> tag gets replaced by new standard HTML 3.2 tags (<div align=center>), etc. pp. Little glow-up pass. We love a fixup era.
π§ Pass 8: Markup Code Stripping π§
- Processing: implicit
- Implementation: HTMLstrip
- Author: Ralf S. Engelschall <rse@engelschall.com>
- See Also:
wml_p8_htmlfix(3)
Description:
β¦and that's exactly where part 1 leaves us, bestie π Pass 8's description is literally mid-sentence, so hold that thought β part 2 is right there and we are not done. Stay with me π
okay so here's the tea on why this whole pass even exists π
β because macro definitions add newlines to the output (or you'd have to always write stuff like ""..."<"/define-tag">";;;"", etc), extra shell-style comments would be genuinely useful, and whitespace can often be stripped from HTML markup code without changing the result. So this special HTML markup code reducement pass just... happens. β¨
The amount of stripping can be controlled by the WML option -O. Default is -O2, which does a really good job without destroying anything. π
And there's one special feature you simply have to know about, bestie: this pass recognizes pre-formatted areas ("<pre>..</pre>") and skips them. No touching. π
Also β when you want some area of your input file treated like it's pre-formatted, this pass supports its own container tag named "<nostrip>...</nostrip>". It does the same thing as "<pre>", except it's itself stripped, too. π
π Pass 9: Markup Code Splitting and Output Generation
- Processing: implicit/explicit
- Implementation: Slice
- Author: Ralf S. Engelschall
<rse@engelschall.com> - See Also:
slice(1)
Description:
The last and final pass is a really tricky one again, because one feature is still not implemented. π We need some way to conditionally create output to different output files. To pull this off, another source file construct ("[NAME:...:NAME]") gets recognized, and it defines what we call slices. Those slices are (possibly overlapped or nested) named areas of the input file, and you can use them via WML's -o option. This option can contain a slice-term in front of the filename, and that slice-term selects which slices get written to the output file. Such slice-terms are actually set theory terms, where slices with the same name define a set. π§
Summary Of Essential Features:
[NAME: ... :NAME]
[NAME: ... :]
Example:
[EN:Welcome to:][DE:Willkommen zu:] Foo Bar Baz Quux!
π« CONCEPT 2: WMLRC FILE HIERARCHY AND WMLOPTS VARIABLE
The second essential idea of WML is the use of .wmlrc files and a "WMLOPTS" environment variable for additionally command line options. π
On startup the frontend wml first processes all options found in "WMLOPTS", then it reads all options from $HOME/.wmlrc, followed by the options of all .wmlrc files found in all parent directories (i.e. ../.wmlrc, ../../.wmlrc, etc) of the directory containing the input file. And finally it processes all options given on the command line. So for instance, this feature provides you with the ability to setup defaults via -D options in the .wmlrc file at the top of your Webarea. π
And there is one more special case, bestie: the option form
-DNAME~VALUE
is always sticky to its location, i.e. it always gets evaluated for its local directory context instead of the current working directory where wml was started. Use this to easily introduce path or URL variables which adjust automatically to the current context of the generated webpage. π¦
π¦ CONCEPT 3: AUTO-ADJUSTED URL AND FILENAME VARIABLES
The third essential idea of WML is the above shortly described variable adjustment concept, which can be used via variable interpolation. The frontend wml provides a -D option for defining variables which get interpolated in each pass:
-DNAME=VALUE
-DNAME~VALUE
For both forms the value can be interpolated via <"get-var NAME"> inside Pass 2 and via "<:=$NAME:>" in Pass 3. The difference between the two forms is the tricky part of adjustment here:
-D NAME=VALUEβ here the variableNAMEgets statically set toVALUE. Each time you interpolate the variable the result is exactlyVALUE. Periodt. π-D NAME~VALUEβ here the variableNAMEgets initialized withVALUE, andVALUEwill be treated as either a (not fully qualified) URL or filename. When you interpolate the variable the result isVALUEif the current working directory is the same as where you used the-Doption (either where you run the frontendwmlor a.wmlrcfile). Else the result isVALUErelative path-adjusted for the current working directory. π§
On the first look this seems useless, but combined with CONCEPT 2 this provides a very essential feature. It gives you a powerful mechanism to automatically let URLs or pathnames get re-calculated for the local context. For instance when you define "-DROOT~." in your top-level .wmlrc file, then the variable "ROOT" will be interpolated to "." at the top-level, to ".." at the first subdir level, to "../.." at the second subdir level, etc. Use this for creating navigation bars or URL references across subtrees. π
π MORE INFORMATION
Now you've seen the various core languages of WML. π For a step-by-step introduction to this functionality and to see real examples, I recommend you read the WML tutorial in wml_tutorial(7) now.
Additionally you can step through the set of available standard include files WML ships with. Start with the top-level include file wml::all(3). π
β SEE ALSO
wml_tutorial(7),wml_tags(7).wml_p1_ipp(3),mp4h(1),eperl(1),m4(1),wml_p5_divert(3),wml_p6_asubst(3),wml_p7_htmlfix(3),wml_p8_htmlstrip(3),slice(1).wml::all(3)
and that's the whole page, bestie!! π it's from EN Tools, dated 2020-11-29, and it lives at WML_INTRO(7) β go forth and build cute websites, no cap π«Άβ¨
π¦ where this page comes from
- debian bookworm: wml 2.32.0~ds1-1 Β· GPL-2.0-or-later
- debian trixie: wml 2.32.0~ds1-1 Β· GPL-2.0-or-later
- ubuntu jammy: wml 2.32.0~ds1-1 Β· GPL-2.0-or-later
- ubuntu noble: wml 2.32.0~ds1-1 Β· GPL-2.0-or-later
- ubuntu questing: wml 2.32.0~ds1-1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms