Compact Web Language (COWEL)
Contents
Introduction
Motivation
Getting started
Syntax in a nutshell
Whitespace
Paragraph splitting
Directives
Directive names
Directive arguments
Named arguments
Positional arguments
Directive content
Directive processing
Contexts and output
Themes
List of directives
Comments
\comment
— Comments
Text formatting
Code and syntax highlighting
\code
— Inline code
Manual nested highlighting
Highlighting prefix and suffix
Further advice on highlighting
\codeblock
— Code blocks
\hl
— Syntax highlight override
\pre
— Preformatted blocks
\literally
— Treat input literally as text
\unprocessed
— Suppress directive processing
Math
\math
— Inline math
\mathblock
— Math blocks
Separators and word breaking
\br
— Break line
\hr
— Horizontal rule
\wbr
— Word break opportunity
\nobr
— Unbroken words
\word
— Deprecated alias for \nobr
Special characters
\U
— Code point literal
\N
— Code point by name
\Udigits
— Digits of code point
\c
— Character references
Special blocks
\Babstract
— Abstract blocks
\Bquote
— Quote blocks
\blockquote
— Alias for \Bquote
\Bug
— Bug blocks
\Bdecision
— Decision blocks
\Bdel
— Deletion blocks
\Bdetails
— Details blocks aka spoilers
\details
— Alias for \Bdetails
\Bdiff
— Difference blocks
\Bex
— Example blocks
\Bins
— Insertion blocks
\Bimp
— Important blocks
\Bnote
— Note blocks
\Btip
— Tip blocks
\Btodo
— TODO blocks
\Bwarn
— Warning blocks
Deprecated aliases
\bug
— Deprecated alias for \Bug
\decision
— Deprecated alias for \Bdecision
\delblock
— Deprecated alias for \Bdel
\diff
— Deprecated alias for \Bdiff
\example
— Deprecated alias for \Bex
\insblock
— Deprecated alias for \Bins
\important
— Deprecated alias for \Bimp
\note
— Deprecated alias for \Bnote
\tip
— Deprecated alias for \Btip
\todo
— Deprecated alias for \Btodo
\warning
— Deprecated alias for \Bwarn
Lists
\ul
— Unordered lists
\ol
— Ordered lists
\li
— List items
\item
— List item pseudo-directive
\dl
— Definition lists
Tables
Headings
\make-contents
— Make table of contents
Bibliography
\bib
— Add bibliography entry
\make-bib
— Generate bibliography
References
\ref
— References
\mail
— E-Mail addresses
\tel
— Telephone numbers
Foreign languages
\html
— Inline HTML
\htmlblock
— HTML blocks
\html-*
— HTML element literals
\script
— JavaScript blocks
\noscript
— No-JavaScript content
\style
— CSS blocks
Paragraph control
\p
— Paragraphs
\paragraphs
— Enable paragraph splitting
\block
— Display as block content
\inline
— Display as inline content
Sections
\there
— Append content to section
\here
— Copy section content
\hereblock
— Copy section content in block
File management
\include
— Include text from a file
\import
— Import a sub-document
Macros
\macro
— Define a macro
\ put { }
— Replaced with provided content
\ put { 0}
, \ put { 1}
, … — Replaced with argument
\ put { ...}
— Forwarding provided arguments
Avoiding name collisions
Miscellaneous
\div
— Content division
\trim
— Trim input
\text
— Plaintext context
Variables and calculations
\Vset
— Set a variable
\Vget
— Get a variable
\Cadd
— Perform addition
\Csub
— Perform subtraction
\Cmul
— Perform multiplication
\Cdiv
— Perform division
1. Introduction
COWEL is a markup language with TeX-like syntax, intended to generate HTML documents, mainly for proposals and technical text. Many of its features are purpose-built for use in WG21, such as for writing C++ proposals.
... generates the HTML ...
... which renders as:
2. Motivation
Many similar tools (mpark/wg21, bikeshed, etc.) are based on Markdown. This makes them beginner-friendly, but advanced formatting requires heavy use of Markdown extensions or mixed use of Markdown and HTML tags. Metadata such as bibliographies, document information, etc. also rely on yet another format (e.g. JSON, YAML).
This makes these tools difficult to master and makes the design incoherent. Why do we need three languages glued together just to format our documents?
COWEL is the missing middle, the missing link. It makes producing HTML a natural part of the language, lets you specify metadata, and more, all in one, simple syntax.
3. Getting started
COWEL is still early in development, and not available in any package manager yet. To install it and run COWEL:
Many text editors support associating such file extensions with TeX or LaTeX syntax highlighting, whose syntax is similar enough to get some basic highlighting.
A VSCode plugin for proper highlighting is planned, among other features.
4. Syntax in a nutshell
COWEL has a minimalistic but powerful syntax, built on top of only three syntactical constructs:
\ various-directives [ positional args, named-args = 0] { and content} Text.
- Escape sequences, such as
,\ {
,\ }
, etc.\ \
There is no special syntax besides that,
meaning that as long as some bit of code doesn't contain a \
,
it's all interpreted as plaintext.
This makes COWEL exceptionally suited to nest other languages inside of it in code blocks etc.
4.1. Whitespace
COWEL translates very directly into HTML. Any whitespace in text is preserved exactly as is. The way that whitespace is processed then depends on the produced HTML and how it is CSS-styled.
Generated HTML:
Rendered output:
4.2. Paragraph splitting
At the top-level in the document and within the content of certain directives,
paragraph splitting takes place.
All content in COWEL is either inline content, block content, or meta content.
Text and escape sequences are inline content,
and directives are sometimes inline and sometimes block content.
Certain directives (e.g.
) that don't generate anything rendered are meta content.
The process of paragraph splitting works as follows:
-
Blank-line-separated blocks of inline content is wrapped in in
tags. Meta content is not counted as a blank line, so it "continues" inline content, but no effort is made to wrap it in< p > ...</ p >
.< p > ...</ p > -
Block content stays untouched, i.e. it is not wrapped in
. However, it also terminates prior inline content, like a blank line.< p > ...</ p >
Generated HTML:
5. Directives
A directive is a way of generating plaintext, HTML, both, or neither. You can think of it as a "command" or "function call".
Every directive has three parts:
- The
selects a specific directive to be processed.\ directive-name -
An optional
[comma-separated, positional arguments, named-arguments = ...]
provides additional inputs to the directive. -
An optional
{block of content}
provides a "main input" to a directive.
5.1. Directive names
A directive name selects a specific directive to be processed.
The name begins with a \
character,
followed by
any character that is valid in an HTML (custom) tag name.
This includes any alphanumeric ASCII characters,
U+002D (
Doing so is equivalent to writing
and longword
immediately following one another.
would get parsed as a directive name,
but this behavior will be removed in the future.
This will result in
being parsed as a directive name,
followed by plaintext
5.2. Directive arguments
Directive arguments can be positional arguments or named arguments. Arguments are separated by commas. Unlike anywhere else, whitespace surrounding directive arguments is ignored.
Arguments provide additional information to a directive.
Generated HTML:
5.2.1. Named arguments
Named arguments are of the form
name = value
, where spaces anywhere around name
and value
are ignored.
Named arguments are matched to directive parameters before any positional arguments,
meaning that positional arguments fill the remaining unmatched arguments.
Argument names can consist of any character, except
ASCII control characters,
U+0020 SPACE,
U+0022 (
name = value
instead,
you can do so by writing:
Only the literal =
character can be used for named arguments,
not its escaped variant
.
5.2.2. Positional arguments
Positional arguments are content just like any other content,
except that an unbalanced closing U+005D (
5.3. Directive content
The directive content is the primary input to a directive.
It is delimited by a '
Generated HTML:
Escape sequences don't participate in this "brace matching", so they can be used to literally produce a brace character.
Generated HTML:
Unlike in the directive arguments, whitespace is not trimmed.
Generated HTML:
5.4. Directive processing
Unlike in typical programming languages, where the input to a function is processed at the call site and the resulting values are passed into the function, COWEL directives have absolute control over their inputs and how they are processed.
Say you have a JavaScript function:
has no idea that its input was originally
.
It only sees the value
and prints it, "oblivious to the outside".
COWEL follows a different model:
No
tag is ever generated because
is never processed.
is not magical feature;
it simply has control over all of its contents and arguments,
and it can choose not to process them.
You can even make a
directive that works
just like
yourself:
6. Contexts and output
There are two types of contexts: plaintext contexts and HTML contexts. These control what directives (and other content) will generate.
&
will be converted to
in an HTML context.
Any directive is capable of generating either plaintext or HTML, and the output may be substantially different depending on the context.
directive is used to generate HTML character references, aka "HTML entities".
It converts its input to plaintext to determine the chosen character.
Within such a plaintext context,
directives like
will simply output their content as plaintext:
Generated HTML:
Also,
will only emit an HTML entity in an HTML context.
In a plaintext context (such as in the input to
), it outputs the character directly.
For example, if we write:
The generated (malformed) HTML is:
7. Themes
COWEL outputs documents that can be viewed in light mode and dark mode.
When the document is opened with support for JavaScript, there is an button in the top-right that can be used to switch between three modes:
- Sync the theme with the OS (default)
- Light mode (ignoring system preference)
- Dark mode (ignoring system preference)
Forced light/dark mode works by adding a
element in the DOM.
For reference, you can look at the CSS in the COWEL source code to see how it's done properly.
8. List of directives
8.1. Comments
Unlike many other markup languages,
COWEL has no dedicated syntax for comments.
However, there exists a
directive which you can use to put comments into code.
8.1.1. \comment
— Comments
The
directive does not process its arguments or content.
It outputs no plaintext or HTML.
Generated HTML:
8.2. Text formatting
COWEL allows for basic text formatting using various directives. Many of the formatting directives are some direct equivalent of an HTML element. For these, there is a fixed HTML element that will always be used. You can rely on this when adding custom CSS.
Directive | HTML | Renders as |
---|---|---|
|
|
Bold text |
|
|
Name of cited work |
|
|
|
|
|
Definition |
|
|
Emphasized text |
|
unspecified | |
|
|
Italic text |
|
|
Inserted text |
|
|
Ctrl + Keyboard key |
|
|
Marked/highlighted |
|
unspecified | Oblique text |
|
|
Quoted text |
|
|
|
|
|
Sample output |
|
unspecified | |
|
unspecified | |
|
|
Small text |
|
|
(No change in formatting) |
|
|
Subscript |
|
|
Superscript |
|
|
Strong text |
|
unspecified | |
|
|
Variable name |
|
|
Underlined text |
All such formatting directives convert all named arguments directly into HTML attributes.
,
,
and
are all italic.
Both
and
are bold.
Both
and
use teletype font.
However, you can customize the style; see §8.13.6.
— CSS blocks.
) and italic (
) text
is that oblique text is merely slanted,
while italic text is fundamentally a different font with different characters.
8.3. Code and syntax highlighting
COWEL uses µlight for syntax highlighting. While the set of supported language is relatively small, the highlighter is ultra-light, extremely fast, and deals with modern C++ features correctly.
8.3.1. \code
— Inline code
The
directive produced syntax-highlighted text in code font.
- Arguments
-
(plaintext) — the syntax highlighting language.lang (yes/no) — whether whether to omitnested
tags.< code > (plaintext) — code before the input from the view of the highlighter.prefix (plaintext) — code after input from the view of the highlighter.suffix
- Input content
-
The input to a
directive is a plaintext context. However, there are special rules for formatting directives and pure plaintext directives (see below).\code - HTML output
-
In an HTML context, the
takes the input source code, applies syntax highlighting, and outputs the result surrounded by\code
.< code > ...</ code > - Plaintext output
-
In a plaintext context,
simply outputs the input source code.\code - Display style
- Inline
This applies C++ syntax highlighting, and generates HTML.
The
tags are an implementation detail and may be subject to change.
8.3.1.1. Manual nested highlighting
The
tags are omitted,
which makes it suitable for nesting languages within other
or
directives.
This renders as follows:
out . write_json ( " { "x" : 123 , "y" : true , "z" : null } " )
Note that by default,
you may often not even notice a visual difference between using the
elements
to have borders, background color, padding, and other such styling features.
8.3.1.2. Highlighting prefix and suffix
The
This renders as:
"keys"
and " values "
.
Notice that the color of
is different because it is interpreted
as if it was positioned like:
8.3.1.3. Further advice on highlighting
directives directly is often too tedious,
so you'll likely want to define a macro to make this easier:
8.3.2. \codeblock
— Code blocks
The
directive works exactly like
,
but it is a block directive, not an inline directive.
Additionally, code blocks render using borders and a dark background by default.
This can be controlled using the
This renders as:
8.3.3. \hl
— Syntax highlight override
The
directive forces certain syntax highlighting to be applied to some text;
it is a manual override for when automatic syntax highlighting is insufficient or broken.
It displays as inline content and wraps its content (which is an HTML context)
in the appropriate syntax highlighting tags.
It has a single
.
The long name is the enumerator name without the
This generates the HTML (subject to change):
It renders as
.
,
the "short names" (kw_type
) are not stable, i.e. they are more likely to change.
Only µlight long names should be used directly.
8.3.4. \pre
— Preformatted blocks
The
directive contains pre-formatted content.
It can be used to contain code, however, there is no syntax highlighting in a
block.
This renders as:
Hello, world! ============= a b c
,
currently does not support the
8.3.5. \literally
— Treat input literally as text
The
directive treats its input source code as plain text,
even if it contains directives or escape sequences.
It outputs the given input source code as text.
Its content is an unprocessed context, and it takes no arguments.
This renders as:
This \comment{comment} \{ is taken literally \}!
pseudo-directives in macros are still processed,
even inside
blocks
because
replaces any appearances of
with the given content,
disregarding the semantics of any directives nested within.
8.3.6. \unprocessed
— Suppress directive processing
The
directive works just like
,
except that escape sequences are processed into their escaped characters.
This renders as:
This \comment{comment} { is unprocessed }!
and (to a lesser extent)
are very useful for nesting
code inside COWEL that already contains underscores.
For example,
is an escape sequence for newline characters in many languages,
and it may be annoying if it gets interpreted as an
directive:
This renders as:
Notice that COWEL technically parses a
directive instead of just
,
which is the part that turns into a newline escape sequence in the C++ code block.
However, that is ultimately irrelevant for syntax highlighting
because the source characters of
are taken as text,
and then split up according to C++ syntax.
pseudo-directives in macros are still processed,
even inside
blocks
because
replaces any appearances of
with the given content,
disregarding the semantics of any directives nested within.
8.4. Math
In recent years, browser support for MathML within HTML has become widespread. COWEL relies entirely on the browser for properly rendering math as MathML, which is very simple and lightweight, but not as portable as "baking" the math into an SVG.
or
:
This renders as:
You can also keep the MathML separate within an XML document and
it:
However, hand-writing MathML would be extremely tedious and verbose, so COWEL offers some convenience directives, listed below.
8.4.1. \math
— Inline math
A
directive surrounds its content with
tags,
and displays as inline content.
Its content is an HTML context,
and within it, additional pseudo-directives like
or
corresponding to MathML elements can be used.
Essentially, this allows you to build MathML using COWEL syntax.
See Mozilla's MathML elements reference for a list of supported elements/directives.
This renders as:
8.4.2. \mathblock
— Math blocks
The
directive functions almost exactly as the
directive,
but it displays as block content instead of inline content,
and it produces an opening
tag.
8.5. Separators and word breaking
8.5.1. \br
— Break line
The
directive produces a line break,
and corresponds to the HTML element
.
It displays as inline content, and its input content is ignored.
is particularly useful when line breaks are treated same as spaces,
which is the case in most HTML content.
8.5.2. \hr
— Horizontal rule
The
directive produces a horizontal rule,
and corresponds to the HTML element
.
It displays as block content, and its input content is ignored.
Here is an example:
8.5.3. \wbr
— Word break opportunity
The
directive produces a word break opportunity,
and corresponds to the HTML element
.
It displays as inline content, and its input content is ignored.
elements can be inserted into the middle of long words,
which, if they don't fit on one line,
will be broken at the point of the
element
(without a hyphen at the end of the line).
Since µlight only supports UTF-8 output,
is equivalent to
,
which outputs a U+200B ZERO-WIDTH SPACE code point.
or
to output a U+00AD SOFT HYPHEN.
8.5.4. \nobr
— Unbroken words
The
directive is a formatting directive
which prevents word breaks within its content.
Its content is an HTML context.
This is done by applying a
style its content.
Combined
,\ c { nbsp} WordCombined
, or\ N { NO-BREAK SPACE} WordCombined
.\ U { A0} Word
8.5.5. \word
— Deprecated alias for \nobr
The
directive has the same effect as
.
8.6. Special characters
It is quite common that a text document should include special characters. While COWEL is built on UTF-8, and in theory one could just write the character directly into the source code, not every text editor handles special characters well.
To increase portability,
COWEL has the
and
directives.
8.6.1. \U
— Code point literal
The input to a
directive is a plaintext context,
which should be a sequence of hexadecimal numbers
specifying a Unicode scalar value;
that is, a code point which UTF-8 permits to be encoded.
generates '
are allowed.
8.6.2. \N
— Code point by name
The
directive behaves almost identically to
,
except that its input has to be a
Unicode name
rather than a hex digits.
That is, the name of a code point,
or one of its "control", "alternate", or "correction" aliases.
generates '
can lead to much more descriptive, human-friendly code, compared to
.
The main issue with
is that it is very non-descriptive in source code.
It simply contains a handful of digits,
and unless the reader is a Unicode expert who happens to know that sequence,
they cannot easily tell what the purpose of the character is.
8.6.3. \Udigits
— Digits of code point
The
directive is essentially the inverse of the
directive.
Its input is also a plaintext context;
rather than producing a code point from a digit sequence,
it produces a digit sequence from its input code point.
This can be fine-tuned with the following parameters:
This renders as:
Note that U+0078 is the usual way in which Unicode code points are represented.
That is,
can also be combined with
to produce human-readable descriptions of code points,
while also keeping our source code readable:
This renders as:
uses only the first code point within the input text,
even though the entire input text is processed into plaintext.
This renders as
... which corresponds to a
, whereas b
and c
are discarded.
8.6.4. \c
— Character references
The input to a
directive is a plaintext context,
where the same content is permitted as for HTML character references, aka. HTML entities,
between '
and
, the '
- Literally '
& ' in text
(code point literal for U+0026)\ U { 26}
(like\ c { amp}
, named character reference)&
(like\ c { #38}
, decimal character reference)&38;
(like\ c { #x26}
, hexadecimal character reference)&x26;
In an HTML context,
is literally translated into
.
In a plaintext context, the character reference is mapped onto its corresponding code point(s),
and those code points are output directly.
are allowed.
8.7. Special blocks
Often, the content we write falls into some special category like "example", "note", etc. COWEL supports a large number of special block directives, which wrap their content in a block, with background color, borders, etc.
The input to all special block directives is an HTML context, they all convert their arguments to HTML attributes, and they all display as block content.
8.7.1. \Babstract
— Abstract blocks
8.7.2. \Bquote
— Quote blocks
The
directive directly corresponds to the
element.
Quotes blocks or "block quotes" display quoted text.
8.7.3. \blockquote
— Alias for \Bquote
The
directive is equivalent to the
directive.
8.7.4. \Bug
— Bug blocks
8.7.5. \Bdecision
— Decision blocks
8.7.6. \Bdel
— Deletion blocks
A deletion block acts as a wrapper for a large amount of deleted content.
It is typically used when individual
directives would be too tedious to use.
8.7.7. \Bdetails
— Details blocks aka spoilers
The
directive directly corresponds to the
element.
Within
,
the
directive can be used to specify summary text.
This is a summary. Click to open!
A details block contains details which need to be revealed by the user. This is also referred to as "spoiler".8.7.8. \details
— Alias for \Bdetails
The
directive is equivalent to the
directive.
8.7.9. \Bdiff
— Difference blocks
A difference block contains changes,
where some content within is typically deleted or inserted.
8.7.10. \Bex
— Example blocks
8.7.11. \Bins
— Insertion blocks
A deletion block acts as a wrapper for a large amount of inserted content.
It is typically used when individual
directives would be too tedious to use.
8.7.12. \Bimp
— Important blocks
8.7.13. \Bnote
— Note blocks
8.7.14. \Btip
— Tip blocks
8.7.15. \Btodo
— TODO blocks
8.7.16. \Bwarn
— Warning blocks
8.7.17. Deprecated aliases
Some of the special blocks also have alternative spellings
which only exist for compatibility with past versions.
The new naming scheme is for all special blocks to have a
name.
8.7.17.1. \bug
— Deprecated alias for \Bug
8.7.17.2. \decision
— Deprecated alias for \Bdecision
8.7.17.3. \delblock
— Deprecated alias for \Bdel
8.7.17.4. \diff
— Deprecated alias for \Bdiff
8.7.17.5. \example
— Deprecated alias for \Bex
8.7.17.6. \insblock
— Deprecated alias for \Bins
8.7.17.7. \important
— Deprecated alias for \Bimp
8.7.17.8. \note
— Deprecated alias for \Bnote
8.7.17.9. \tip
— Deprecated alias for \Btip
8.7.17.10. \todo
— Deprecated alias for \Btodo
8.7.17.11. \warning
— Deprecated alias for \Bwarn
8.8. Lists
8.8.1. \ul
— Unordered lists
The
directive corresponds to the
element,
and produces an unordered list.
8.8.2. \ol
— Ordered lists
The
directive corresponds to the
element,
and produces an ordered list.
8.8.3. \li
— List items
The
directive corresponds to the
element,
and produces a list item with
or
.
This renders as:
- first bullet
- second bullet
- first bullet
- second bullet
8.8.4. \item
— List item pseudo-directive
Within
and
,
the
pseudo-directive can also be used instead of
.
8.8.5. \dl
— Definition lists
The
directive corresponds to the
element,
and produces a definition list.
Within that list, you can use
for definition terms, and\dt
for definition descriptions.\dd
8.9. Tables
Tables are simply produced by using the
,
,
,
,
,
,
,
,
,
and
directives to
produce the corresponding HTML tags with the same name.
directive.
8.10. Headings
Headings can be produced using the
,
,
,
,
, and
directives to
produce the corresponding HTML tags with the same name.
Headings take a
— Make table of contents) automatically.
Headings also take a
Other arguments to these headings are converted into attributes of the corresponding HTML element.
An
If none is provided, an
directive:
8.10.1. \make-contents
— Make table of contents
The
directive generates the table of contents,
which is comprised of all the headings within the document.
It takes no arguments and its content is ignored.
It displays as a block.
The table of contents is is populated by headings (§8.10. Headings) as the document is processed.
A similar effect can be achieved using
(§8.13.3.
— HTML element literals).
However, using
will also not emit a link icon in the gutter,
and it will not synthesize an
.
additionally wraps those contents in HTML elements to
chang their visual appearance.
8.11. Bibliography
In technical writing it is common for documents to reference other papers, and it is expected that references are properly cited. To support this,
COWEL provides directives for adding bibliography entries, and for generating a bibliography automatically.
8.11.1. \bib
— Add bibliography entry
The
directive adds a single entry to the bibliography.
Its content is ignored, and it displays as a meta directive.
It has a number of parameters, each of which is a plaintext context:
id -
The identifier of the bibliography entry.
This can later be referenced using
.\ ref [ id] author - The name of the author(s). This is in no particular format, and if you want to provide multiple authors, you can do so via a comma-separated list here.
title - The title of the cited work.
date - The date of publication. No particular format is enforced; this is simply a string, so you can choose some local format.
publisher - The name of the publisher.
link -
The primary link to the document.
This should typically be a short link because it is copied into each
to the bibliography entry.\ref long-link -
A "long link" to the document.
If present, this will be rendered within the bibliography,
and it is typically meant to be a semantic or more stable link than the
. You can also think of it as a "link for pretty printing".link issue-link - A link to issue tracking for the document. For example, in WG21 circles, this may be a link to the GitHub issue where a paper is tracked.
Every argument except the
8.11.2. \make-bib
— Generate bibliography
The
directive generates a bibliography.
This is typically done towards the bottom of the document, but can be done anywhere.
It takes no arguments, its content is ignored, and it displays as a block.
The
directive is populated by uses of
directives in order of use.
That is, the bibliography is not automatically sorted for you;
the order in which
directives are used is also the order in which the bibliography
entries are generated.
,
it is a wrapper for the underlying
8.12. References
8.12.1. \ref
— References
The
directive takes a single
tag with some content inside.
The content is an HTML context, and is what actually gets displayed. If no content is provided, it can be synthesized from the following types of references:
mailto URLs (e-mail addresses)tel URLs (telephone numbers)http andhttps URLs- Anchors (
#id ) for some heading in the document - Anything defined in the bibliography using
\bib
HTML output (
tag may have additional attributes):
This renders as:
8.12.2. \mail
— E-Mail addresses
A
directive behaves the same
directive that is given a
8.12.3. \tel
— Telephone numbers
A
directive behaves the same
directive that is given a
8.13. Foreign languages
8.13.1. \html
— Inline HTML
The
directive can be used to output HTML literally.
Its content is a plaintext context,
and it displays as inline content.
Generated HTML:
directive can produce malformed HTML content if you're not careful.
See, §8.13.3.
— HTML element literals for a safer option.
8.13.2. \htmlblock
— HTML blocks
The
directive works exactly like the
directive,
but displays as block content instead of inline content.
directive can produce malformed HTML content if you're not careful.
See, §8.13.3.
— HTML element literals for a safer option.
8.13.3. \html-*
— HTML element literals
Any directive beginning with
can be used to produce an HTML element
directly.
Its content is a plaintext context,
and it displays as inline content.
Arguments are converted to HTML attributes of the produced tag.
Generated HTML:
8.13.4. \script
— JavaScript blocks
The content of a
directive is a plaintext context,
where the input is treated as JavaScript code
and surrounded in
tags.
displays as meta content (like
).
Generated HTML:
8.13.5. \noscript
— No-JavaScript content
The
directive corresponds to the
element.
Its content is an HTML context,
and will only be shown by the browser when JavaScript is disabled.
8.13.6. \style
— CSS blocks
The content of a
directive is a plaintext context,
where the input is treated as JavaScript code and surrounded in
tags.
displays as meta content (like
).
Generated HTML:
8.14. Paragraph control
In some cases, the automatic §4.2. Paragraph splitting process is not enough. To get more fine-tuned control, we have a number of directives.
8.14.1. \p
— Paragraphs
The
directive surrounds its content in
tags.
8.14.2. \paragraphs
— Enable paragraph splitting
The
directive activates paragraph splitting.
This may be useful in places where it is not active by default.
Generated HTML:
8.14.3. \block
— Display as block content
The
directive doesn't add any HTML itself,
but causes its contents to be considered block content.
can be used to suppress automatic paragraph splitting:
8.14.4. \inline
— Display as inline content
The
directive works like the
directive,
but causes its contents to display as inline content, not as block content.
8.15. Sections
Often, you want to produce content in one place,
but have it display in another place within the document.
A classic example is collecting headings automatically in a table of contents,
or copying the content of a heading into a preview when referenced by
.
8.15.1. \there
— Append content to section
The
directive displays as meta content.
Basically, it stashes away its input content (which is an HTML context) somewhere else.
It takes a single
By default, all document content is placed within a
element,
inside
, inside html
.
allows you to write outside of the
element:
-
will write\ there [ std.head] { text} text
inside of the
element (following auto-generated content).< head > -
will write\ there [ std.body] { text} text
inside of the
element (following< body >
and other automatically inserted elements).< main >
8.15.2. \here
— Copy section content
The
directive inserts the content from another section at its location.
It displays as inline content.
It takes a single
All references produced by
are resolved in a post-processing step,
which allows forward-references.
Generated HTML:
8.15.3. \hereblock
— Copy section content in block
The
directive functions exactly like the
directive,
but displays as block content instead of inline content.
8.16. File management
Once projects get larger, it often becomes difficult to manage everything in a single file. Also, tooling may benefit from having separate files. For example, keeping separate SVG files or CSS files may have better IDE support than writing these out directly inside of COWEL.
COWEL provides directives to load content from other files.
8.16.1. \include
— Include text from a file
The
directive produces plaintext by loading the text contents of another file,
relative to the directory of the document.
It has no arguments, and its content is a plaintext context in which the path is specified.
block to use it as a script,
or we can include it into a
to display its contents.
Assuming that
simply takes the text content of the file and generates plaintext from it.
However, when the directive is used in an HTML context
(like if we simply use
in the middle of the document),
it is subject to escaping (
, etc.) just like any other text.
In other words, you are also safe from HTML tags inside of included text breaking the document,
barring a few directives, like
or
;
no such escaping takes place inside of
.
8.16.2. \import
— Import a sub-document
The
directive loads the content from another COWEL document,
substitutes the
directive for those contents,
and processes them.
It has no arguments, and its content is a plaintext context in which the path is specified.
While
and
are similar,
there are some stark differences:
-
is used for COWEL documents, while\import
is used for anything else.\include -
doesn't just load the text from another file, but parses it and ensures that the contents are a valid COWEL document.\import -
is a plaintext directive, and interops nicely with syntax highlighting. It is also possible to\include
COWEL files into code blocks without any regards as to their contents. On the contrary, content expanded from\include
is subject to the same rules as the surrounding document.\import
When using
,
the contents of the other file are substituted where we have written
,
which means that imported content also plays nicely with paragraph splitting:
Generated HTML:
them when needed.
This can help you avoid copying boilerplate between multiple documents.
It is also common to split documents into multiple files that are combined using a sequence
of
s.
8.17. Macros
8.17.1. \macro
— Define a macro
The
directive defines a macro,
which is basically a user-defined directive.
It has a single
Within macros, uses of the
pseudo-directive are replaced with the inputs to
the macro.
There are multiple forms of the
which expand different parts of the macro input.
The content of a
directive is a plaintext context,
and specifies which part of the provided content or arguments should be used.
8.17.2. \ put { }
— Replaced with provided content
A
directive with no given content (or empty/blank content)
is replaced with the content provided to the macro upon use.
8.17.3. \ put { 0}
, \ put { 1}
, … — Replaced with argument
When the content provided to
is an integer,
the corresponding argument is selected,
where
Additionally,
such a
directive has an
directive if not enough positional arguments were provided
to the macro.
If there is no
After macro substitution, this markup is equivalent to:
Notice that xyz
is ignored in either case
because there is no
that would make use of it.
The second macro invocation
would result in an error if no
8.17.4. \ put { ...}
— Forwarding provided arguments
(where the given content is three periods)
expands to all provided macro arguments.
It shall only appear as a positional argument to a directive, with no surrounding content.
That is:
is OK,\ x [ \ put { ...} ] -
is OK because spaces around\ x [ a, \ put { ...} , b]
are ignored and do not constitute text, but\ put { ...} -
is an error because\ x [ a\ put { ...} b]
is being mixed with other (text) content,\ put { ...} -
is an error because\ x [ n = \ put { ...} ]
is used as a named argument, and\ put { ...} -
is an error because\ x { \ put { ...} }
does not appear as a directive argument.\ put { ...}
is especially useful when creating "wrapper macros" for other directives:
After macro substitution, this markup is equivalent to:
8.17.5. Avoiding name collisions
Since COWEL continuously adds more directives in the future,
you should try to avoid names that may collide with those when defining your own macros.
COWEL builtin directive names only use alphanumeric characters and '
8.18. Miscellaneous
8.18.1. \div
— Content division
The
directive surrounds its contents in
tags.
It displays as a block, and its content is an HTML context.
's named arguments are turned into HTML attributes.
8.18.2. \trim
— Trim input
The content of a
directive is an HTML context
(§6. Contexts and output).
Its arguments are ignored.
is a formatting directive.
The process of trimming eliminates leading and trailing whitespace in the input, at the COWEL source level.
This renders as:
is primarily useful inside of macros.
We might not want to space-separate content if some of it is empty.
For example, we could define a
macro
where the user can optionally provide a number for that note:
This renders as:
Note: Something something.
Note 1: Something else.
Notice that because
expands to no content,
the trailing space after Note
is eliminated.
If it wasn't eliminated, we would end up with
,
but there should never be a space before the colon.
8.18.3. \text
— Plaintext context
The content of a
directive is a plaintext context
(§6. Contexts and output).
Its arguments are ignored.
It simply outputs the input that it was given as text.
Therefore, it acts as a sort of wrapper for plaintext.
Notably, this forces the generation of plaintext even when
is within an HTML context.
8.19. Variables and calculations
While COWEL is not intended to be general purpose programming language, and more advanced interactive features are better suited for JavaScript, it does provide a few ways to perform calculations.
8.19.1. \Vset
— Set a variable
sets the value of a variable to some provided plaintext.
It displays as a meta directive.
It takes a single
This renders as:
8.19.2. \Vget
— Get a variable
obtains the value of a variable,
and displays as inline.
Its content is ignored.
It takes a single
If the variable denoted by the
expands to nothing.
8.19.3. \Cadd
— Perform addition
The
directive performs an integer addition between its (nameless) arguments.
Its content is ignored, and it displays as inline.
Each of its arguments is a plaintext context, where the argument is interpreted as an integer, and then summed.
This renders as:
with
and
to store the results
of your calculations:
This renders as:
Paragraph 1
Paragraph 2
and other calculation directives are mainly intended
for incrementing paragraph numbers and other basic tasks.
8.19.4. \Csub
— Perform subtraction
The
directive behaves like the
directive,
except that it performs subtraction instead of addition.
8.19.5. \Cmul
— Perform multiplication
The
directive behaves like the
directive,
except that it performs multiplication instead of addition.
8.19.6. \Cdiv
— Perform division
The
directive behaves like the
directive,
except that it performs division instead of addition.