Compact Web Language (COWEL)

Contents

1

Introduction

2

Getting started

3

Motivation

4

Syntax in a nutshell

4.1

Whitespace

4.2

Paragraph splitting

5

Directives

5.1

Directive names

5.2

Directive arguments

5.3

Directive content

6

Contexts and output

7

Themes

8

List of directives

8.1

Comments

8.1.1

\comment — Comments

8.2

Text formatting

8.3

Code and syntax highlighting

8.3.1

\code — Inline code

8.3.2

\codeblock — Code blocks

8.3.3

\hl — Syntax highlight override

8.3.4

\pre — Preformatted blocks

8.4

Math

8.4.1

\math — Inline math

8.4.2

\mathblock — Math blocks

8.5

Separators and word breaking

8.5.1

\br — Break line

8.5.2

\hr — Horizontal rule

8.5.3

\wbr — Word break opportunity

8.5.4

\word — Unbroken words

8.6

Special characters

8.6.1

\U — Code point literal

8.6.2

\c — Character references

8.7

Special blocks

8.7.1

\abstract — Abstract blocks

8.7.2

\blockquote — Quote blocks

8.7.3

\bug — Bug blocks

8.7.4

\decision — Decision blocks

8.7.5

\delblock — Deletion blocks

8.7.6

\details — Details blocks aka spoilers

8.7.7

\diff — Difference blocks

8.7.8

\example — Example blocks

8.7.9

\insblock — Insertion blocks

8.7.10

\important — Important blocks

8.7.11

\note — Note blocks

8.7.12

\tip — Tip blocks

8.7.13

\todo — TODO blocks

8.7.14

\warning — Warning blocks

8.8

Lists

8.8.1

\ul — Unordered lists

8.8.2

\ol — Ordered lists

8.8.3

\dl — Definition lists

8.9

Tables

8.10

Headings

8.11

References

8.11.1

\ref — References

8.11.2

\mail — E-Mail addresses

8.11.3

\tel — Telephone numbers

8.12

Foreign languages

8.12.1

\html — Inline HTML

8.12.2

\htmlblock — HTML blocks

8.12.3

\html-* — HTML element literals

8.12.4

\script — JavaScript blocks

8.12.5

\noscript — No-JavaScript content

8.12.6

\style — CSS blocks

8.13

Paragraph control

8.13.1

\p — Paragraphs

8.13.2

\paragraphs — Enable paragraph splitting

8.13.3

\block — Display as block content

8.13.4

\inline — Display as inline content

8.14

Sections

8.14.1

\there — Append content to section

8.14.2

\here — Copy section content

8.14.3

\hereblock — Copy section content in block

8.15

Macros

8.15.1

\def — Define a macro

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.

The following COWEL code ...

Hello, \strong{strong} world!

... generates the HTML ...

Hello, <strong>strong</strong> world!

... which renders as:

Hello, strong world!

2. Getting started

COWEL is still early in development, and not available in any package manager yet. To install it and run COWEL:

git clone https://github.com/Eisenwave/cowel.git --recursive cd cowel cmake -B build cmake --build build ./build/cowel-cli INPUT.cowel OUTPUT.html

3. 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.

4. Syntax in a nutshell

COWEL has a minimalistic but powerful syntax, built on top of only three syntactical constructs:

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.

At a top level, whitespace is merged and line breaks are rendered like spaces:

This displays on one line because line breaks render like spaces.

Generated HTML:

<p>This displays on one line because line breaks render like spaces.</p>

Rendered output:

This displays on one line because line breaks render like spaces.

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. \comment) that don't generate anything rendered are meta content.

The process of paragraph splitting works as follows:

COWEL markup:

First paragraph. Second paragraph. \blockquote{This is a block directive.}

Generated HTML:

<p>First paragraph.</p> <p>Second paragraph.</p> <blockquote>This is a block directive.</blockquote>

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:

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, '-', '.', '_', and various Unicode characters.

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.

Often, arguments are converted to HTML attributes.

\b[id = abc]{Bold text.}

Generated HTML:

<b id=abc>Bold text.</b>

5.3. Directive content

The directive content is the primary input to a directive. It is delimited by a '{' and ends with a matching closing '}'. This means that you can have opening and closing braces inside text, but they need to be balanced.

COWEL markup:

\b{Bold text { with braces }.}

Generated HTML:

<b>Bold text { with braces }.</b>

Escape sequences don't participate in this "brace matching", so they can be used to literally produce a brace character.

COWEL markup:

\b{Bold text \{ with brace.}

Generated HTML:

<b>Bold text { with brace.</b>

Unlike in the directive arguments, whitespace is not trimmed.

COWEL markup:

\b{bold} \i{ italic }

Generated HTML:

<b>bold</b> <i> italic </i>

Only one such block of content can be provided, unlike in TeX, which has a similar syntax, but permits multiple blocks. Each block is separated by a pair of braces.

6. Contexts and output

There are two types of contexts: plaintext contexts and HTML contexts. These control what directives (and other content) will generate.

The COWEL text & will be converted to & literally in a plaintext context, and to &amp; 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.

The \c 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 \b will simply output their content as plaintext:

\c{\b{Omega}} \c{Omega}

Generated HTML:

&Omega; &Omega;

Also, \c will only emit an HTML entity in an HTML context. In a plaintext context (such as in the input to \c), it outputs the character directly. For example, if we write:

\c{\c{Omega}}

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:

Forced light/dark mode works by adding a light or dark class to the <html> element in the DOM.

If you want to customize colors with CSS, remember to make them respond to theme and OS preference changes.

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 \comment directive which you can use to put comments into code.

8.1.1. \comment — Comments

The \comment directive does not process its arguments or content. It outputs no plaintext or HTML.

While comments don't output anything, §4.2. Paragraph splitting is based on blank lines in the source, so comments don't split paragraphs:

Text \comment{This is \directive{comment} content.} Text

Generated HTML:

<p>Text Text</p>

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
\b{...} <b>...</b> Bold text
\cite{...} <cite>...</cite> Name of cited work
\del{...} <del>...</del> Deleted text
\dfn{...} <dfn>...</dfn> Definition
\em{...} <em>...</em> Emphasized text
\gterm{...} unspecified grammar-term
\i{...} <i>...</i> Italic text
\ins{...} <ins>...</ins> Inserted text
\kbd{...} <kbd>...</kbd> Ctrl + Keyboard key
\mark{...} <mark>...</mark> Marked/highlighted
\o{...} unspecified Oblique text
\q{...} <q>...</q> Quoted text
\s{...} <s>...</s> Struck text
\samp{...} <samp>...</samp> Sample output
\sans{...} unspecified Sans-serif font
\serif{...} unspecified Serif font
\small{...} <small>...</small> Small text
\sub{...} <sub>...</sub> Subscript
\sup{...} <sup>...</sup> Superscript
\strong{...} <strong>...</strong> Strong text
\tt{...} unspecified Teletype/monospace font
\var{...} <var>...</var> Variable name
\u{...} <u>...</u> Underlined text

All such formatting directives convert all named arguments directly into HTML attributes.

By default, a substantial amount of directives are styled the same way. For example, \cite, \var, \i and \em are all italic. Both \strong and \b are bold. Both \tt and \samp use teletype font.

However, you can customize the style; see §8.12.6. \style — CSS blocks.

The difference between oblique (\o) and italic (\i) 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 \code directive produced syntax-highlighted text in code font.

Arguments
\code accepts a single lang argument which specifies the language used for syntax highlighting.
Input content
The input to a \code directive is a plaintext context. However, there are special rules for formatting directives and pure plaintext directives (see below).
HTML output
In an HTML context, the \code takes the input source code, applies syntax highlighting, and outputs the result surrounded by <code>...</code>.
Plaintext output
In a plaintext context, \code simply outputs the input source code.
Display style
Inline

COWEL markup:

\code[cpp]{123}

This applies C++ syntax highlighting, and generates HTML. The <h-> tags are an implementation detail and may be subject to change.

<code><h- data-h=num>123</h-></code>

Writing \code directives directly is often too tedious, so you'll likely want to define a macro to make this easier:

\comment{Defines a \js directive that can be used in place of \code[js] from now on:} \def[\js]{\code[js]{\put}} Let's highlight \js{var} in JavaScript.

8.3.2. \codeblock — Code blocks

The \codeblock directive works exactly like \code, 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 borders.

\codeblock[js]{ // Borders enabled let x = 0; } \codeblock[js,borders=no]{ // Borders disabled let x = 0; }

This renders as:

// Borders enabled let x = 0; // Borders disabled let x = 0;

8.3.3. \hl — Syntax highlight override

The \hl 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 name argument, which is the µlight long name for a highlight type. You can obtain a list of possible long names at ulight.h from the definition of enum ulight_highlight_type. The long name is the enumerator name without the ULIGHT_HL prefix, all lowercase, and with hyphens instead of underscores.

It is possible to mix automatic syntax highlighting with manual overrides:

\comment{_Int128 is manually highlighted as a type keyword, and x is automatically highlighted as an identifier} \code[c]{\hl[keyword-type]{_Int128} x}

This generates the HTML (subject to change):

<code><h- data=h=kw_type>_Int128</h-> <h- data-h=id>x</h-></code>

It renders as _Int128 x.

While it is also possible to produce the highlighting tags using \html-h-[data-h=kw_type]{_Int128}, 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 \pre directive contains pre-formatted content. It can be used to contain code, however, there is no syntax highlighting in a \pre block.

COWEL markup:

\pre{ Hello, world! ============= a b c }

This renders as:

Hello, world!
=============
    a b c

Unlike \codeblock, \pre currently does not support the borders=no option. This will be added in the future.

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.

If you have existing MathML, you can embed their content using \html or \htmlblock:

Math \html{ <math display=inline> <mfrac> <mi>x</mi> <mn>2</mn> </mfrac> </math> } in a sentence.

This renders as:

Math x 2 in a sentence.

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 \math directive surrounds its content with <math display=inline>...</math> tags, and displays as inline content.

Its content is an HTML context, and within it, additional pseudo-directives like \mi or \mn 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.

The previous example in §8.4. Math could also be written like:

Math \math{ \mfrac{\mi{x}\mn{2}} } in a sentence.

8.4.2. \mathblock — Math blocks

The \mathblock directive functions almost exactly as the \math directive, but it displays as block content instead of inline content, and it produces an opening <math display=block> tag.

8.5. Separators and word breaking

8.5.1. \br — Break line

The \br directive produces a line break, and corresponds to the HTML element <br/>. It displays as inline content, and its input content is ignored.

\br 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 \hr directive produces a horizontal rule, and corresponds to the HTML element <hr/>. It displays as block content, and its input content is ignored.

Here is an example:


8.5.3. \wbr — Word break opportunity

The \wbr directive produces a word break opportunity, and corresponds to the HTML element <wbr>. It displays as inline content, and its input content is ignored.

<wbr> 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 <wbr> element (without a hyphen at the end of the line).

Since µlight only supports UTF-8 output, \wbr is equivalent to \U{200B}, which outputs a U+200B ZERO-WIDTH SPACE code point.

If you want to provide a word break hint but have a hyphen at the end of the line, use \U{AD} or \c{shy} to output a U+00AD SOFT HYPHEN.

8.5.4. \word — Unbroken words

The \word directive is a formatting directive which prevents word breaks within its content. Its content is an HTML context. This is done by applying a white-space: nowrap; style its content.

Another way to prevent word-breaking is to use non-breaking spaces. You can insert these using Combined\c{nbsp}Word.

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 \U and \c directives.

8.6.1. \U — Code point literal

The input to a \U 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.

\U{30} generates '0' U+0030 DIGIT ZERO

Like anywhere else, directives inside of \U are allowed.

8.6.2. \c — Character references

The input to a \c directive is a plaintext context, where the same content is permitted as for HTML character references, aka. HTML entities, between '&' and ';'.

Using \U and \c, the '&' character can be produced in a number of ways:

In an HTML context, \c{xyz} is literally translated into &xyz;. In a plaintext context, the character reference is mapped onto its corresponding code point(s), and those code points are output directly.

Like anywhere else, directives inside of \c 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. \abstract — Abstract blocks

Abstracts provide a summary of the document.

8.7.2. \blockquote — Quote blocks

The \blockquote directive directly corresponds to the <blockquote> element.

Quotes blocks or "block quotes" display quoted text.

8.7.3. \bug — Bug blocks

A bug block contains the description of a bug. This often includes a code block which demonstrates how to reproduce the bug.

8.7.4. \decision — Decision blocks

A decision block indicates that a decision needs to be made.

8.7.5. \delblock — Deletion blocks

A deletion block acts as a wrapper for a large amount of deleted content. It is typically used when individual \del directives would be too tedious to use.

8.7.6. \details — Details blocks aka spoilers

The \details directive directly corresponds to the <details> element. Within \details, the \summary 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.7. \diff — Difference blocks

A difference block contains changes, where some content within is typically deleted or inserted.

8.7.8. \example — Example blocks

An example block contains examples.

8.7.9. \insblock — Insertion blocks

A deletion block acts as a wrapper for a large amount of inserted content. It is typically used when individual \ins directives would be too tedious to use.

8.7.10. \important — Important blocks

Important blocks contain especially important information.

8.7.11. \note — Note blocks

Note blocks contain less important information, which can often be skipped over by readers.

8.7.12. \tip — Tip blocks

Tip blocks contain useful advice.

8.7.13. \todo — TODO blocks

TODO blocks contain actions that remain to be done. They may indicate that a part of a project is incomplete.

8.7.14. \warning — Warning blocks

Warning blocks warn the reader of some hazard or potential mistake.

8.8. Lists

8.8.1. \ul — Unordered lists

The \ul directive corresponds to the <ul> element, and produces an unordered list. Within that list, you can use the pseudo-directive \item to produce list items.

8.8.2. \ol — Ordered lists

The \ol directive corresponds to the <ol> element, and produces an ordered list. Within that list, you can use the pseudo-directive \item to produce list items.

8.8.3. \dl — Definition lists

The \dl directive corresponds to the <dl> element, and produces a definition list. Within that list, you can use

8.9. Tables

Tables are simply produced by using the \table, \thead, \tbody, \tfoot, \tr, \th, \td, \colgroup, \col, and \caption directives to produce the corresponding HTML tags with the same name.

To perform advanced styling, like controlling alignment within columns, use a \style directive.

8.10. Headings

Headings can be produced using the \h1, \h2, \h3, \h4, \h5, and \h6 directives to produce the corresponding HTML tags with the same name.

Arguments to these headings are converted into attributes of the corresponding HTML element. An id argument can be provided explicitly.

If none is provided, an id is synthesized from the content within the heading.

Headings can be referenced using the \ref directive:

\h2{Heading with synthesized id} \h2[id=xyz]{Heading with manual id} \comment{These can be referenced as follows} \ref[#heading-with-synthesized-id] \ref[#xzy]

8.11. References

8.11.1. \ref — References

The \ref directive takes a single to argument, which can be a URL, anchor, or something else. It produces an <a> 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:

COWEL markup:

\ref[mail:john@us.gov]

HTML output (<a> tag may have additional attributes):

<a href=mail:john@us.gov>john@us.gov</a>

C++ standard draft links can be synthesized into human-readable descriptions.

\ref[https://eel.is/c++draft/expr#1]

This renders as:

8.11.2. \mail — E-Mail addresses

A \mail directive behaves the same \ref directive that is given a mailto URL. However, the input is provided as content instead of an argument, and the displayed text cannot be customized.

The following two lines produce the same output:

Please contact \mail{john@us.gov}. Please contact \ref[mailto:john@us.gov].

8.11.3. \tel — Telephone numbers

A \tel directive behaves the same \ref directive that is given a tel URL. However, the input is provided as content instead of an argument, and the displayed text cannot be customized.

The following two lines produce the same output:

Please contact \tel{+1234}. Please contact \ref[tel:+1234].

8.12. Foreign languages

8.12.1. \html — Inline HTML

The \html directive can be used to output HTML literally. Its content is a plaintext context, and it displays as inline content.

COWEL markup:

This is \html{<b>bold text</b>}.

Generated HTML:

This is <b>bold text</b>.

The \html directive can produce malformed HTML content if you're not careful. See, §8.12.3. \html-* — HTML element literals for a safer option.

8.12.2. \htmlblock — HTML blocks

The \htmlblock directive works exactly like the \html directive, but displays as block content instead of inline content.

The \htmlblock directive can produce malformed HTML content if you're not careful. See, §8.12.3. \html-* — HTML element literals for a safer option.

8.12.3. \html-* — HTML element literals

Any directive beginning with \html- 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.

COWEL markup:

This is \html-span[id=abc]{a span}.

Generated HTML:

This is <span id=abc>a span</span>.

8.12.4. \script — JavaScript blocks

The content of a \script directive is a plaintext context, where the input is treated as JavaScript code and surrounded in <script>/*...*/</script> tags.

\script displays as meta content (like \comment).

COWEL markup:

\script{ console.log("hello"); }

Generated HTML:

<script> console.log("hello"); </script>

8.12.5. \noscript — No-JavaScript content

The \noscript directive corresponds to the <noscript> element. Its content is an HTML context, and will only be shown by the browser when JavaScript is disabled.

8.12.6. \style — CSS blocks

The content of a \style directive is a plaintext context, where the input is treated as JavaScript code and surrounded in <style>/*...*/</style> tags.

\style displays as meta content (like \comment).

COWEL markup:

\style{ body { color: red; } }

Generated HTML:

<style> body { color: red; } </style>

8.13. 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.13.1. \p — Paragraphs

The \p directive surrounds its content in <p>...</p> tags.

8.13.2. \paragraphs — Enable paragraph splitting

The \paragraphs directive activates paragraph splitting. This may be useful in places where it is not active by default.

COWEL markup:

\ul{ \item{\paragraphs{ First paragraph in bullet. Second paragraph. }} }

Generated HTML:

<ul> <li> <p>First paragraph in bullet.</p> <p>Second paragraph in bullet.</p> </li> </ul>

8.13.3. \block — Display as block content

The \block directive doesn't add any HTML itself, but causes its contents to be considered block content.

\block can be used to suppress automatic paragraph splitting:

\comment{No <p> tags will be added here} \block{ First paragraph. Second paragraph. }

8.13.4. \inline — Display as inline content

The \inline directive works like the \block directive, but causes its contents to display as inline content, not as block content.

8.14. 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 \ref[#id].

8.14.1. \there — Append content to section

The \there directive displays as meta content. Basically, it stashes away its input content (which is an HTML context) somewhere else.

It takes a single section argument which specifies the name of the section. The section argument is a plaintext context.

8.14.2. \here — Copy section content

The \here directive inserts the content from another section at its location. It displays as inline content.

It takes a single section argument which specifies the name of the section. The section argument is a plaintext context.

All references produced by \here are resolved in a post-processing step, which allows forward-references.

COWEL markup:

\there[sec]{before/} (\here[sec]) \there[sec]{/after}

Generated HTML:

(before//after)

8.14.3. \hereblock — Copy section content in block

The \hereblock directive functions exactly like the \here directive, but displays as block content instead of inline content.

8.15. Macros

8.15.1. \def — Define a macro

The \def directive defines a macro, which is basically a user-defined directive. It has a single pattern argument, which shall be a single pattern directive which describes the defined directive.

The arguments and content of the pattern directive are not processed, but can be used to document how the directive is meant to be used.

\comment{The following two definitions are equivalent:} \def[\macro{...}]{xyz} \def[\macro]{xyz}

When a macro is used, the content within the \def directive is copied. Any uses of the \put pseud-directive inside the macro are replaced with copies of the input content.

\def[\bi]{\b{\i{\put}}} \comment{Now, the following are equivalent:} \b{\i{bold and italic}} \bi{bold and italic}

Currently, macros only support content as input. Arguments to macros are ignored entirely. This should be supported at some point.