BrowserREPL-button-tip-on BrowserREPL-button-tip-off

EditButtonTip 2026-08-10

RakuDoc

Raku markup for documenting Raku software to aid development and use.

VERSION    2.21.0§

Introduction§

RakuDoc has a variety of components that allow for rich structured documents, provide markup hints to renderers without assuming an output format, extract information from compiled programs, provide information to programs, and enable custom developer extensions.

This document describes a revision of RakuDoc modifying the original speculation S26 that was implemented as Raku was developed. RakuDoc is intended to be backwards compatible with the POD6 markup language based on S26.

RakuDoc is extensible and renderers are free to provide extra functionality beyond the minimum set of instructions described here.

The markup language is called RakuDoc with the CamelCase spelling in order to highlight both the Raku and Doc parts for a newcomer. Some authors may prefer Rakudoc with Titlecase spelling, which is considered a possible but non-canonical variant.

The file extension for a file containing RakuDoc source is .rakudoc.

A note about indentation§

As it will become apparent, whitespace and indentation plays an important role in RakuDoc. There are quite a few horizontal whitespace characters; no equivalence is made between them by Rakudo. For example, tabs and spaces are treated as two separate horizontal whitespace characters, with no assumption that a single tab is equivalent to four (or two or eight) spaces.

Consequently, mixing spaces and tabs may appear to create the same visual margin in some editor, but they may be treated as different margins when parsing RakuDoc.

It is recommended that RakuDoc authors choose a single whitespace character (e.g. only tabs or only spaces) for margin alignment.

Two use cases for RakuDoc§

RakuDoc can be thought of as having components that are closely connected to a program or module that is being documented (code-oriented RakuDoc), and components that can be used for text-oriented documents, such as the source for a webpage or a book (text-oriented RakuDoc).

Code-oriented RakuDoc is expected to be "consumed" by users in an editor or Integrated Design Environment (IDE), while text-oriented RakuDoc is consumed in some rendered version, such as an HTML web page, a command-line manpage, or a chapter in an e-book.

When RakuDoc components are viewed in an editor or IDE to provide information about variables, methods, roles, classes and the like, the information could be made available in a pop-up whenever a documented term is selected in some way (e.g. hovering a mouse over it). In the editor context, RakuDoc blocks and markup should then be treated as a comment to the code. Editors are not expected to render the RakuDoc other than to show the RakuDoc components verbatim, but may do so if it seems expedient.

When RakuDoc components are viewed in a rendered version (for example, as HTML), components related to the executable aspects of the program should be ignored.

Within the body of a program there may be several sections of code, which is called the ambient context, interleaved between sections of RakuDoc.

Sections of code that are intended to be examples within the documentation (i.e. code that is not actual interleaved executable code) can be specified in =code blocks, which are treated as integral parts of the RakuDoc, not as source code in ambient context.

Consider a source file containing the definition of a class. When the file is edited in an IDE (e.g. the class is being developed or maintained) the code-oriented RakuDoc is useful to help the developer understand the internal structure and function of specific elements within the code.

Furthermore, when the class is imported into another Raku program the IDE will be able to access the information in declarator blocks attached to specific terms, without needing the source code to be available.

However, by including text-oriented RakuDoc in the same file, end-user documentation can be provided for the class within the same source file. By passing the source through a renderer, a documentation file (e.g. a README.md file for a github repo) can be generated.

This document describes the minimum version of RakuDoc that a renderer or editor must recognize, along with some expected rendering behaviours for text-oriented renderers. “Expected behaviours” means that a renderer should approximate the behaviour as far as possible given the limitations of the output format, and that the approximation should be a reasonable interpretation of the standard described here.

The RakuDoc design assumes certain types of customisability, such as the ability to define new blocks or markup instructions. In order to access blocks or functionality not described in this document, the file containing such RakuDoc instructions should contain a use statement that loads a module that provides the information needed to render the extensions. The information provided by this module may be renderer-specific.

Further exposition on this topic is available.

Components§

RakuDoc has four main types of components, which are distinguished by their scope and by effect they have on other components.

Directives

Directives define how blocks work. Directives have a similar syntax to regular blocks, but they actually operate on other blocks. New directives cannot be defined. Directives specify behaviours rather than content.

Blocks

Blocks define complete text components, such as a new paragraph or a code sample or a table. New kinds of blocks can be defined. Blocks contain actual content which is to be directly rendered in some way.

Markup instructions
Markup instructions typically define inline items embedded within a block. Some markup instructions only affect the visual rendering of their contents. Others may have side-effects (such as including items into an index or glossary). New markup instructions can be defined.
Metadata options
Options provide information to a block. They may produce side-effects or alter the way a block should be rendered. A document writer can associate any metadata option with any block or directive. A renderer is only required to comply with those listed in this document.

Directive syntax§

These are the syntax forms for each directive. The = of each directive must be the first non-whitespace character on a given line.

Block and document delimiters§

  • =begin specifies the start of a delimited block
  • =end specifies the end of a delimited block
  • =for specifies the start of an extended block
  • =finish specifies the end of all RakuDoc and all ambient code; everything thereafter is a string

Procedural table constructors§

  • =column specifies the start of a column, but only inside a table block
  • =row specifies the start of a row, but only inside a table block

Alias declaration§

The =alias directive specifies a text substitution available in subsequent A<...> markup instructions. The general syntax for an alias directive is:

=alias ALIAS_NAME Text for substitution
=                 Optional extra text
Code

Lexical block and markup configuration§

The =config directive specifies default options to be applied to specific types of blocks or markup instructions within the remainder of the current block-scope. These default options apply from immediately after the =config directive up to the end of the innermost surrounding block.

The general syntax for configuration directives is:

=config BLOCK_TYPE  :CONFIG
=                   :OPTIONAL<EXTRA CONFIG OPTIONS>
Code

If the block-type is single uppercase character X, the =config directive applies the specified configuration options to the X markup instruction. For example:

=config C :allow<B I>
Code

This configures the C<> markup instruction to recognize nested B<> and I<> markup instructions (both of which would otherwise be treated as verbatim within a C<> instruction).

To avoid ambiguities Naming rules are applied to blocks and markup instructions.

Note that since the =config directive applies to block types, =config item ... and =config numitem ... are equivalent. More information about block types can be found in the section on Block type, level and enumeration.

Global document configuration§

The =document directive specifies new default values for options applicable to the whole document. These values are applied when the final rendering is completed.

The syntax is:

=document :DOCUMENT
=         :OPTIONAL<EXTRA DOCUMENT OPTIONS>
Code

A renderer may provide custom options not specified here. These should have mixed-case names, see Naming rules.

Content insertion§

The =place directive specifies a source of information that is to be placed in the current block. The general syntax of =place is

=place URL :OPTIONS
=          :MORE :IF<NECESSARY>
Code

Lexical counter configuration§

The =counter directive reconfigures a named counter within the current lexical scope. The general syntax of =counter is

=counter COUNTER_NAME :OPTIONS
=                     :MORE :IF<NECESSARY>
Code

Block syntax§

Even though visually similar in some contexts, a block is not a directive...nor vice versa.

Blocks may be specified in three ways...

Delimited form§

A delimited block starts with the directive =begin as the first non-whitespace on a line, followed by a valid Raku identifier indicating the name of the block, followed optionally by metadata (see #Metadata syntax below), followed by content lines. A delimited block is only terminated by an =end directive followed by the same block name. A delimited block that is not terminated by an =end same-block-name instruction throws an error.

For example, to specify a para block in delimited form:

=begin para :meta<data>
This text is the content of the block.

The preceding blank line is also a part of the block,
as are these two non-blank lines.
=end para
Code

The general syntax is:

=begin BLOCK_TYPE  :OPTIONAL<CONFIG INFO>
=                  :OPTIONAL<EXTRA CONFIG INFO>
BLOCK CONTENTS
=end BLOCK_TYPE
Code

Extended form§

An extended block begins with the directive =for as the first non-whitespace on a line, followed by the name of the block, followed by optional metadata. The next non-blank lines after the metadata specify the content of the block, which is terminated either by the first entirely blank line after the content or by the first line that begins with a RakuDoc directive or block. For example, to specify a para block in extended format:

=for para :meta<data>
This text is the content of the block.

This text is NOT content of the block.
After a blank line, a new block is started.
Code

The general syntax is:

=for BLOCK_TYPE  :OPTIONAL<CONFIG INFO>
=                :OPTIONAL<EXTRA CONFIG INFO>
BLOCK DATA
Code

Abbreviated form§

In an abbreviated block, the name of the block immediately follows an = sign, which must be the first non-whitespace character on the line. Everything after the block name (up to the first blank line or the start of the next directive or block) is considered the content of the block. For example, to specify a para block in abbreviated form:

=para This text is the content of the block.

This text is NOT content of the block.
After a blank line, a new block is started.
Code

Note that abbreviated blocks cannot be specified with metadata. Any apparent metadata elements placed after an abbreviated block name are instead considered to be part of the block contents.

Where an extended or abbreviated block uses a blank line as the block terminator, the blank line is not included as part of the content of the block. All subsequent whitespace, whether horizontal or vertical (spaces, tabs, new lines), is ignored. Note that horizontal and vertical whitespace can be included inside a delimited block, and may be significant (e.g. in #Verbatim blocks).

Naturally, the contents of blocks may contain embedded RakuDoc markup codes, but not all blocks may contain other blocks. These rules are:

  • Abbreviated- and extended-form blocks can never contain any other kind of block.
  • The delimited form of the following atomic blocks do not contain any other kind of block (i.e. they treat their contents as pure data, even if those contents happen to resemble a block definition): citation, code, comment, data, formula, head, input, output, table, custom blocks
  • The delimited form of the following paragraph-level blocks may contain only atomic blocks or implicit paragraphs: defn, item, para
  • The delimited form of the following container blocks may contain any other kind of block (including other container blocks): cell, nested, pod, rakudoc, section, SEMANTIC
  • The delimited form of the table block may directly contain only cell and/or comment blocks.
  • Note, however, that cell blocks may themselves contain any other kind of block, which means that table blocks may indirectly contain any other kind of block.
  • A table may also contain =row and =column directives, which are not blocks.

Markup instruction syntax§

The general syntax of a markup instruction is

  |  
Code
  • <instruction>

    This is a single uppercase letter, or a unicode entity with the UPPER property

  • <opening marker>

    This is either one-or-more < characters or a single « character (i.e. The Unicode entity E<0x00AB>)

  • <content>

    This is a string that does not contain the | character (i.e. Unicode entity E<0x007C>), unless that character is inside a nested markup instruction.

  • <meta list>

    Is a list of strings separated by , or ;, depending on the semantics imposed by the <Instruction>

  • <closing marker>

    Is one-or-more > or a single » (i.e. Unicode entity E<0x00BB>). The closing marker must be symmetrical with the markup instruction’s opening marker. That is, it must consist of the same number of > or » as there were < or « in the opening marker.

For example:

This is U<unusual> text, and this is I<important>.
And this is a L<link to the Raku Programming Language|https://raku.org>.
Code

Which would be rendered as:

For example: This is unusual text, and this is important. And this is a link to the Raku Programming Language.

Metadata syntax§

Metadata is specified using a Raku option pair, where the value portion is always parsed using Raku semantics. The following table contains some typical examples.

Value is...Specify with...
True:key
False:!key
Literal:key<answer>
List:key("foo", 42)
Hash:key{ :note('Rosebud, they said'), :emphasize }

Numerical values can be specified in any Raku-compatible format (42, 42.0, 42e0, 0x2a, 0d42, 0o52, 0b101010). Strings can either be specified using single or double quotes, or angle brackets ('foo', "bar", <baz>). Note that if a string with whitespace is specified in angle brackets, it is in fact a list of strings: <foo bar baz> is the same as ('foo','bar','baz').

Within the context of the parser of the Raku Programming Language, it is also possible to refer to any compile-time value inside the meta-data.

Requiring Raku semantics for the value component of a metadata option means that for compliance to this specification, RakuDoc markup is prohibited within a metadata option. For example, :bullet( E<BALLOT BOX WITH X> ) is prohibited. However, Raku has a syntax for Unicode characters, so :bullet«\c[BALLOT BOX WITH CHECK]» is possible. Note the use of «...» delimiters, which stringify their contents with interpolation, ensuring the \c[...] interpolator is correctly converted.

A renderer may provide a mechanism for allowing RakuDoc within a metadata option but the value part must still conform to Raku semantics, for example,

:caption('This is a heading with I<important markup> in it')
Code

The outer single quotes ensures that the parser passes a plain string to the renderer, which may then post-process the string.

The metadata of an extended block or abbreviated block may extend beyond the first line declaring the block. Each subsequent line must start with an = in the first virtual column, meaning that it must vertically align with the = of the RakuDoc block declaration, and it must be followed by at least one horizontal whitespace character.

For example:

=for head1 :a-first-line-key<firstvalue> :another-first-line-key<xyz>
=
:a-second-line-key(42)
=
:a-third-line-key<third>
Content for the heading block
Code

Directives§

Directives are similar in form to abbreviated block instructions, but they do not have the extended or delimited forms. If a directive name is preceded by a =begin, =for or =end, then an error will be thrown.

Directives cannot be enumerated. If a directive is prefixed by num, then a warning will be generated and the prefix ignored.

Aliases§

The =alias directive provides a way to define block-scoped synonyms for longer RakuDoc sequences, (meta)object declarators from the code, or even entire chunks of ambient source. These synonyms can then be inserted into subsequent RakuDoc using the A<> formatting code.

An =alias is scoped from immediately after its declaration up to the end of the innermost surrounding RakuDoc block.

The alias directive takes two arguments. The first is an identifier (which is usually specified in uppercase, though this is not mandatory). The second argument consists of one or more lines of replacement text.

Each =alias directive creates a block-scoped RakuDoc macro that can be invoked during document generation by placing the identifier (i.e. the first argument of the alias) in an A<> formatting code. This formatting code is then replaced by the text returned by the new macro.

The replacement text returned by the alias macro begins at the first non-whitespace character after the alias’s identifier, and continues to the end of the line. You can extend the replacement text over multiple lines by starting the following line(s) with an = (at the same level of indentation as the =alias directive itself) followed by at least one whitespace. Each additional line of replacement text uses the original line’s (virtual) left margin, as specified by the indentation of the replacement text on the =alias line.

For example:

=alias PROGNAME    Earl Irradiatem Evermore
=alias VENDOR 4D Kingdoms
=alias TERMS_URLS =item
L<http://www.4dk.com/eie>
= =item
L<http://www.4dk.co.uk/eie.io/>
= =item
L<http://www.fordecay.ch/canttouchthis>

The use of
A<PROGNAME> is subject to the terms and conditions
laid out by
A<VENDOR>, as specified at:

A<TERMS_URLS>
Code

This would produce:

The use of Earl Irradiatem Evermore is subject to the terms and conditions laid out by 4D Kingdoms, as specified at:

The advantage of using aliases is, obviously, that the same alias can be reused in multiple places in the documentation. Then, if the replacement text ever has to be changed, it need only be modified in a single place:

=alias PROGNAME    Count Krunchem Constantly
=alias VENDOR Last Chance Receivers Intl
=alias TERMS_URLS
L<http://www.c11.com/generic_conditions>
Code

Alias placement codes may also specify a default display text, before the alias name and separated from it by a |. When a display is specified, it will be used if the requested alias cannot be found (and an "unknown alias" warning will be issued in that case):

The use of A<this program | SOFTWARE> is subject to the terms and conditions
laid out by A<our company | COMPANY>, as specified at:

    A<(Please visit our website) | OURTERMS>
Code

produces ...

The use of this program is subject to the terms and conditions laid out by our company , as specified at: (Please visit our website)

Furthermore, since none of the aliases were specified in this document, error messages will be produced by the renderer (perhaps at the end of the rendered page).

Block specifiers§

The =begin, =end, and =for directives all specify types of blocks. They have already been illustrated in multiple examples and will not be described further here.

Block configuration§

All block forms can be associated with metadata options. Typically the metadata are specified for a block using the extended or delimited forms.

If the same option needs to be added to multiple blocks, this can be done using a config directive, and then the abbreviated block form can be used in the same block scope.

For example, suppose we want all =code blocks to be labelled with a :delta within some section of a document (More information on developer notes). Rather than add a :delta modifier to every individual =code, we could configure every =code block to be automatically given the same developer note, like so:

=config code :delta(v2.3.2+, 'oFun enhancements') 
=code method droll { say 'what a cool operator' }
=code method drool { say 'what a slob' }
=code method drill { say 'keep up' }
Code

Within the same block scope, e.g. between =begin section and =end section instructions, one or more =config directives can be specified to define the default behaviour of specific block types. Successive =config directives within the same scope are cumulative in effect. Because =config directives specify default behaviours, whenever a particular kind of metadata is explicitly specified for an instance of that block type, that option overrides the defaults set by any active =config blocks. For example:

=config item1 :bullet« \c[Earth Globe Europe-Africa] » 
=config item2 :bullet« \c[Hand with Index and Middle Fingers Crossed] » 
=comment  In the following list, =item1 and =item2 will now have non-standard bullets

The major sources of sustainable energy are:
    =item1 geothermal
    =item1 fusion
    =item2 (eventually)

=begin section
    =config item1 :toc :headlevel(2)
    =comment  The following items still have non-standard bullets but now they will
              also be added to the table of contents as if they were =head2 blocks

    Important items are:
        =item1 small scale fusion
        =item1 room temperature superconductors

=end section

=comment  The following list items will NOT be added to the Table of Contents
          because the section containing that particular =config has now ended.
          They will still have the non-standard Earth bullets though,
          because those two =config directives are still in scope.

    =item1 matter-antimatter annihilation
    =item1 zero-point energy
Code

There is more discussion of =config in the context of Formatting codes.

Document management§

The =document directive allows the author to override the values of document-level options. It is required that all document-level options have suitable default values, some of which are specified in this document. Any defaults that are not specified here are left to the discretion of the developer of each renderer.

Unlike the =config and other directives, the =document directive is not lexically scoped. Hence, one or more =document directives may be specified anywhere in a RakuDoc document and their effects are cumulative. That is, the options passed to each successive =document directive are accumulated and concatenated to determine the final set of options. Hence, the two directives:

=document :!auto-toc  :auto-index    :citation-style<acm>

=document :auto-toc :!auto-index :citation-locale<en-US>
Code

... are equivalent to the single directive:

=document :!auto-toc :auto-index :citation-locale<en-US> :auto-toc :!auto-index :citation-style<acm>
Code

... which is equivalent to:

=document  :citation-locale< en-US> :auto-toc  :!auto-index  :citation-style<acm>
Code

... because the :auto-toc and :auto-index options in later =document directives override those in earlier directives (which is the usual RakuDoc behaviour).

The following document level options are specified:

Option name

Default

Description

:error

True

If True, warnings for any error conditions are rendered at the end of the document.

:auto-tocFalse unless overridden by the presence of =head or semantic blocks.Whether to automatically generate a Table of Contents, or mandate no automatic rendering of a Table of Contents, more in Table of Contents, Index, and Citations.
:auto-indexFalse unless overridden by the presence of X< ... > markup.Whether to automatically generate an Index, or mandate no automatic rendering of an Index, more in Table of Contents, Index, and Citations.
:auto-citationsFalse unless overridden by the presence of Q< ... > markup.Whether to automatically generate a Citations list, or mandate no automatic rendering of a Citations list, more in Table of Contents, Index, and Citations.
:lang

en

The language of the content of the document.

:citation-style

ieee

The style used to format citations. More detail can be found in Citations.
:citation-locale

en-GB

The locale used to format citation dates and numbers. More detail can be found in Citations.
Document level options

Document termination§

The =finish directive indicates the end of all RakuDoc source and all ambient contexts within the document. This means that the parser will treat all the remaining text in the file as a string.

Any text after the =finish block can be accessed as a string within the program (i.e. the ambient code) via the $=finish variable. This can be used to provide data to a program, such as a test.

use JSON::Fast;
my %h = from-json( $=finish );
say %h.raku;
# more lines of code

=finish
{ "key1": "a string value", "key2": "another value" }
Code

This will generate the following output:

{:key1("a string value"), :key2("another value")}
Code

Note, however, that the =data block is the intended and preferred method of providing text data to ambient code, because it allows developers to specify multiple distinct text blocks, which can then be accessed either by name or by position.

Table constructors§

The =row and =column instructions are directives, not blocks, and they are described in more detail in the section on the procedural =table block.

Placement from another (external) source§

The =place instruction is a directive that tells the renderer to obtain text, information, or an object from another source.

The rendered version of the data placed in the text is considered to form its own block scope.

An in-line version of =place is P<...>, which is described in more detail in the section on markup codes.

The schema of the URL specified in a =place directive specifies where to look for the external content:

SchemaWhere to look for the resource
http(s):Look on the web
file:Look on the local filesystem
rakudoc:Look in the usual places for Raku documentation
man:Look via a local man(1)
defn:Look in the current document

Meanwhile, the kind of content being placed is inferred from the final extension of the URL. For example:

ExtensionHow to treat the contents
.txtRender the contents as plaintext
.rakudocRender the contents as RakuDoc
.htmlRender the contents as XHTML
.mdRender the contents as Markdown
.jsonRender the contents as JSON
.jpgRender the contents as an image
.mp4Render the contents as a video

Renderers are not required to render anything other than plaintext and RakuDoc, but may also support other formats if they wish.

In the case where a URL does not end in a recognized extension:

=place https://example.org/landingpage

=place rakudoc:App::Rak

=place file:/usr/share/legal/std_disclaimer
Code

...then the type of content (and hence rendering) may be inferred from the schema:

SchemaInferred content type if no final extension
http(s):XHTML
file:plaintext
rakudoc:RakuDoc

A =place directive may be accompanied by metadata options to ensure that a reference can be made in the Table of Contents, or to provide an ALT text. For example:

=place https://raku.org/img/camelia-logo.png  :!toc :caption<Raku’s mascot> :alt<A cheerful butterfly>
Code

will produce ...

Raku’s mascot§

A cheerful butterfly
Raku’s mascot

Use =place ... :toc :headlevel(3) to treat the :caption text as a =head3, and include it in the Table of Contents as a =head3 caption.

Note that when any of the toc:, index:, or citation: schemas is used, the automatic rendering of a full Tables of Contents, Index, or Citations list will be cancelled. See Table of Contents, Index, and Citations for more detail.

Enumeration management§

The =counter instruction is a directive that affects the behaviour of the counters used by numbered blocks.

Although each counter is named in the same way as a blocktype, the two are separate entities.

The directive is followed by the name of a counter (not the name of a block) and one or more of:

  • :restart
  • :!restart
  • :restart( INTEGER )
  • :restart-after< BLOCK LIST >
  • :restart-except-after< BLOCK LIST >
  • :prefix< BLOCK >

These options may not be used in a =config statement, nor may =config options appear in a =counter directive. In case of error, a warning message will be generated and the option will be ignored.

The directive is described in more detail in the section on enumerated blocks

Code-oriented RakuDoc§

The following RakuDoc components are primarily intended for use when editing Raku code within an editor. Standalone renderers may ignore them.

Declarator blocks§

Declarator blocks differ from other blocks in that they do not have a specific type. Instead, they are attached to a particular element of the ambient source code.

Declarator blocks are introduced by a special comment: either #| or #=, which must be immediately followed by either a space or an opening bracket character, such as a curly brace {, ( or «. If followed by a space, the block is terminated by the end of line; if followed by one or more opening bracket characters, the block may extend over multiple lines and is terminated by the matching sequence of closing bracket characters.

RakuDoc markup instructions may be used inside declarator blocks.

Blocks starting with #| are attached to the code after them, and blocks starting with #= are attached to the code before them.

Since declarator blocks are attached to source code, they can be used to document classes, roles, subroutines and in general any statement or block.

The WHY method can be used on these classes, roles, subroutines, etc. to return the attached RakuDoc value.

For example:

#| Base class for magicians
class Magician {
  has Int $.level;
  has Str @.spells;
}


#| Fight mechanics
sub duel(  #= Magicians only, no mortals.
  Magician $a,  #= first magician
  Magician $b,  #= second magician
) {
}

say Magician.WHY; # OUTPUT: «Base class for magicians␤»
say &duel.WHY.leading; # OUTPUT: «Fight mechanics␤»
say &duel.WHY.trailing; # OUTPUT: «Magicians only, no mortals.␤»
say &duel.signature.params[0].WHY;  # OUTPUT: «first magician␤»
say &duel.signature.params[1].WHY;  # OUTPUT: «second magician␤»
Code

These declarations can extend to several lines. For example:

#|( This is an example of stringification:
* Numbers turn into strings
* Regexes operate on said strings
*
C<with> topicalizes and places result into $_
)
sub search-in-seq
#=« Uses
* topic
* decont operator
»
  ( Int $end, Int $number ) {
    with (^$end).grep( /^$number/ ) {
        .say for $_<>;
    }
}
Code

A useful idiom is to place trailing declarator blocks on the parameters of the MAIN sub. These comments will be picked up automatically by USAGE.

sub MAIN(
    Str $prefix,   #= use this prefix on output lines
    Int :$verbose, #= how many lines of output per result (0 = no output)
)
Code

Data blocks§

=data blocks are used to specify named and/or ordered chunks of data for the ambient code. They may appear anywhere within a source file, and as many times as required.

The corresponding variable, $=data holds an object that does both the Associative and Positional roles.

Each =data block can be given a :key option, to name it. The contents of any =data block with a key are accessible (as a single string) via the Associative aspect of $=data object. For example:

=begin data :key<Virtues>
Laziness
Impatience
Hubris
=end data

say 'The three virtues are:';
say $=data<Virtues>;
Code

The contents of any =data block that does not have a :key are accessible (as a single string) via the Positional aspect of $=data. Unkeyed =data blocks are stored in the same order they appear in the file. For example:

say 'The second anti-virtue is: ', $=data[1];

=data Industry
=data Patience
=data Humility
Code

Note that, as the preceding example illustrates, because RakuDoc is a compile-time phenomenon, it is possible to specify =data blocks after the point in the source where their contents will be used (provided they’re not being used in a BEGIN, of course).

When $=data itself is stringified, it returns the concatenation of all the unkeyed =data blocks the parser has seen.

=data blocks are never rendered by the text-oriented RakuDoc renderers.

Text-oriented RakuDoc§

The RakuDoc instructions in this section are primarily intended for text-oriented rendering. However, text-oriented and code-oriented RakuDoc can be freely intermixed with Raku code in a single file; this may help to create code that is well-documented.

When a Raku compiler parses a file, line contents are expected to be Raku code (ambient text). When a RakuDoc block is finished, the next line is assumed to revert to ambient text.

#start of file
my $text; # ambient code

=head this is some text
this line continues the heading

#this line is now ambient code and so must be specified as a comment
Code

A rakudoc block reverses this assumption.

#start of file
my $text; # ambient code
=begin rakudoc

=head this is some text
this line continues the heading

this line is not ambient code and so
it will be treated as an ordinary paragraph
=end rakudoc
# this line is now ambient code
Code

Files that are intended to contain text-oriented documentation alone should be entirely enclosed in a rakudoc block.

However, files whose filename ends in a .rakudoc extension are always presumed to contain only text-oriented documentation, and any renderer must always treat the file’s contents as being enclosed in an implicit =begin rakudoc...=end rakudoc, unless those contents are already explicitly enclosed in a rakudoc block.

Historically the name pod was used for this functionality. For compatibility it will still be possible to use the name pod instead of rakudoc in the foreseeable future. Note however that the Raku Programming Language may assign slightly different semantics to rakudoc at some time in the future.

Block type, level and enumeration§

A block type consists of a block base name, such as head, and a block level, which is an integer starting from 1. (A block type consisting of a block base without an integer implies the block level is 1). The following are all valid block types: head, head2, formula3, table2, para.

Any block type can be associated with an enumeration by prefixing the block name with num, e.g. numhead, numtable, numitem, numcode, numformula.

The effects of enumeration and level on head, defn, and item are illustrated in the sections on those block types because they have some special properties by default, namely:

  • Sequences of =item and of =defn are grouped together into lists automatically.
  • The =head / =numhead blocks are automatically included into the main Table of Contents.
  • Semantic blocks are treated as =head blocks.

The block bases rakudoc, section, nested, citation, and pod are considered to be container blocks, which act on their contents but do not have any separate rendered contents. Consequently, even if the prefix num and a level are attached to these bases, they have no effect.

More detail about how enumerations can be customized for all block types can be found in Enumerated blocks.

Headings§

Headings can be defined using =headN, where N is greater than zero (e.g. =head1, =head2, =head3, etc.). =head is an alias for =head1.

=head A top-level heading

=head2 A second-level heading

=head3 A third-level heading
Code

Numbered headings§

You can specify that a heading is numbered using the =numhead block (more detail can be found in Enumerated blocks). For example:

=numhead1 The Problem

=numhead1 The Solution

=numhead2 Analysis

=head3 Overview

=head3 Details

=numhead2 Design

=numhead1 The Implementation
Code

which would produce:

1. The Problem

2. The Solution

2.1. Analysis

Overview

Details

2.2. Design

3. The Implementation
Code

A document has an inherent numbering for every heading, but only the =numheadN block makes the numeration visible in the heading and in the Table of Contents.

Note that, even though renderers are not required to distinctly render more than the first four levels of heading, they are required to correctly honour arbitrarily nested numberings. That is:

=numhead6 The Rescue of the Kobayashi Maru
Code

should produce something like:

2.3.8.6.1.9. The Rescue of the Kobayashi Maru
Code

Block scope§

A block scope is important for the =config and =alias directives. In addition, some renderers may generate secondary pages from primary source files, for example, gathering together the same method names in multiple classes. It is desirable for all the relevant blocks to be gathered together.

Sections§

The section block will typically only be used in the delimited form so that the document writer can define an explicit block scope. The =begin section declaration starts a new block scope, and the =end section returns the scope to the previous one. Unlike an =end rakudoc, an =end section does not always change the scope back to ambient code. It only does so when its corresponding =begin section changed the scope from ambient code. In contrast, an =end rakudoc always reverts to ambient code.

Sections may be embedded within other sections.

When a =begin section is not present, a renderer may apply the following heuristic to determine the block scope (assuming X, Y, and Z are digits such that 0 < X < Y < Z):

  • A =headY declaration starts a new block scope.
  • The next =headY declaration ends the block scope of the previous =headY
  • A =headZ declaration following a =headY is within the block scope of the preceding =headY declaration, and does not end it.
  • A =headX declaration ends the scope of any preceding =headY and =headZ declarations.

Note that a =begin section declaration overrides the heuristic, meaning that multiple =headX declarations can be placed within the same block scope.

A renderer is not expected to render blocks differently when they are embedded in a section block.

Providing metadata to a =begin section block definition is not the same as declaring metadata using a =config directive. Metadata in a config is provided to all matching blocks in the current block scope. Metadata in the =begin section declaration is only applied to the section itself, not to the blocks it contains.

Further exposition on this topic is available.

Document scope§

A RakuDoc document starts with the first RakuDoc block or directive supplied by the parser to the renderer from a file, either as an AST or $=pod structure, and ends with the last such directive or block. Once the document has ended, the document level options are evaluated and applied to render the document and create its output. Note that a RakuDoc document may be embedded within a Raku module or program using one or more rakudoc blocks.

A =begin rakudoc declaration (or equivalently a =begin pod) has the effect that the lines following it are consider RakuDoc text or blocks, and are not treated by the parser as Raku code.

An =end rakudoc (or =end pod) will signal a return to the ambient code.

A rakudoc block does not start a new block scope and continues the previous document scope.

rakudoc blocks may be nested, but do not create additional scopes. For example, if a RakuDoc source containing its own (possibly implied) =begin rakudoc statement is included in another RakuDoc source by means of a =place statement, then the embedded rakudoc block does not create a new block scope. This means that any =config statements in an embedded RakuDoc source will apply to the document or block scope in which the source is embedded.

Contrast this to a section block, which does create a new block scope.

The metadata that affect an entire document are tabulated in the syntax section. These options may changed at any point in a RakuDoc document with a =document directive. The option values are evaluated at the end of the document scope, so the last directives are the most significant.

Enumerated blocks§

RakuDoc allows for the customisable numbering of any block, not just headings and items. Moreover, the enumeration, which is generated automatically by the renderer, can be referred to later in the text using the A< ... > markup code. The automatic enumeration is controlled using a construct that is largely independent of blocks: counters.

The block level integer at the end of the name of a block type (e.g. head1, table2, formula3, etc.) is used to characterize numbering hierarchies, so that subordinate blocks are typically numbered with reference to their superordinate predecessors. For example, an instance of =numhead2 is subordinate to the last instance of =numhead (which is equivalent to =numhead1).

The block type may optionally be prefixed by the letters num, which signals that the block should be rendered with an enumeration. Every block has an enumeration, but only those blocks prefixed with num actually include that number in their rendering.

Note that directives (such as =for, =begin, =end, =config, =row, =column, =alias, etc.) are not blocks, and so cannot be prefixed by num.

The (possibly hierarchical) enumeration value for each block is provided by the counter to which the block is currently subscribed. By default, each block automatically subscribes to the counter with the same base name as itself. So, for example, enumeration values for head, head1, numhead and numhead1 blocks are supplied by the single counter named head1.

Every block, whether built-in or user-defined, automatically subscribes to a counter, even if the block is never explicitly specified in a document. Counters autovivify (with an initial individual value of 1) the first time they are referenced, either when a block subscribed to them is used in a document, or when the counter name itself is first used as the argument of some metaoption.

The counter to which a block is subscribed can be changed using the :counter metaoption, either applied to an single instance of a block:

=for head1 :counter<SomeOtherCounter>»
This Is A Specially Numbered Heading
Code

or configured for all subsequent blocks in the same scope:

=config head1 :counter<SomeOtherCounter>
Code

Two or more blocks may subscribe to the same counter, in which case every instance of any of those blocks causes the counter to increment (even instances without the num prefix). For example, to have every table and every formula use a single shared enumeration, you could either have the formula block subscribe to the table counter (as the table block already does by default):

=config formula1  :counter< table1 >
Code

...or else have both block types subscribe to the same user-defined counter (which would be autogenerated as soon as it is first used):

=config table1    :counter< TablesAndFormulae >
=config formula1 :counter< TablesAndFormulae >
Code

Note that the :counter option can also be used to create a unique numbering for only part of a document, by taking advantage of the lexical scoping of the =config directive. For example, to cause tables and formulae within a single subheading to be numbered separately (without affecting subsequent table/formula numbering later in the document):

=head3 Aside: Detailed derivation of the master equation
=begin section
=config table :counter< AsideNumbering >
=config formula :counter< AsideNumbering >
...
=end section

=head3 Table/formula numbering continues normally from here
Code

Enumeration aliases for blocks§

It is also possible to capture the specific number with which a given block was rendered, by specifying that block with the :numalias<TAG> metaoption. If this option is applied to a specific block then, when the block is rendered, a new alias is automatically created. If that alias is later referred to (using the A<TAG> notation), the enumeration value for the originating numbered block is substituted into the rendered document at that point. For example:

=for numtable :caption<Complete list of ingredients>  :numalias<IngredientsTable>

=comment And later...

First gather all the ingredients listed in
A<IngredientsTable>.
Code

This might be rendered something like...

Table 7. Complete list of ingredients

# And later...

=para  First gather all the ingredients listed in Table 7.
Code

By default, the format used for the substituted enumeration text will be %T %N (using the enumeration format string described elsewhere). However, the author may specify a different rendering for the alias, using an extended variant of the option: :numalias< FORMAT | TAG >, where FORMAT is a desired alternative format string. For example:

=for numitem  :numalias< Article %N | HQ >  :form<Article %N. %D>
Headquarters location.

=comment Text of document with many other numitems

=para The deadline is noon at the location of the main office, see
A<HQ>.
Code

This would be rendered as something like

Article 10. Headquarters location

# Lots of text

The deadline is noon at the location of the main office, see Article 10.
Code

Since all block options may be preconfigured using the =config directive, it is also possible to create a parameterized :numalias as follows:

=config numitem  :numalias< Article %N. | * >  :form<Article %N. %D>
Code

In this case, the * is replaced by the tag specified in each subsequent :numalias option applied to individual numitem blocks. For example, with the previous =config the following uses of :numalias:

=for numitem  :numalias< HQ  >
=for numitem :numalias< CCN >
=for numitem :numalias< WTF >
Code

...are equivalent to:

=for numitem :numalias< Article %N. | HQ  >
=for numitem :numalias< Article %N. | CCN >
=for numitem :numalias< Article %N. | WTF >
Code

The precedence rule for options is that options specified directly on a block take priority over preconfigured options specified by a =config directive. Consequently, a :numalias with an explicit format will replace any preconfigured :numalias supplied by a preceding =config directive. For example:

=config numitem  :numalias< Article %N. | * >  :form<Article %N. %D>

=for numitem :numalias< HQ  >
=for numitem :numalias< CCN >
=for numitem :numalias< The WTF Exception (%N) | WTF >
Code

...are equivalent to:

=for numitem :numalias< Article %N. | HQ  >
=for numitem :numalias< Article %N. | CCN >
=for numitem :numalias< The WTF Exception (%N) | WTF >
Code

Moreover, if the explicit format is empty (i.e. :numalias<|TAG>) then the default format (i.e. %T %N) will be reinstated for that one particular block. Hence:

=for numitem  :numalias< | WTF >
Code

...is equivalent to:

=for numitem :numalias< %T %N | WTF >
Code

Counts and counters§

The counters to which blocks can subscribe are independent constructs that are created and maintained for each RakuDoc document by every compliant renderer. Counters are entirely separate from the blocks they service, though the two constructs do interact in several ways that will be described hereafter.

Counters have a range of features useful for generating enumerations: an individual value, a hierarchical prefix, a restart status, and various possible restart triggers.

All these features have sensible defaults whenever a counter is auto-created. However, all of them may also be explicitly reconfigured within a given lexical scope using the =counter directive.

Each counter has an individual value§

A counter’s individual value (a.k.a. its count) is a global scalar integer variable that is external to the counter itself, and which tracks the counter’s current enumeration value. The individual value of every counter starts (and restarts) at 1, and is incremented every time some block requests the next value from the counter.

Because a counter’s individual value is not itself lexically scoped, it does not revert to its earlier value at the end of a section. It is the single value that a counter manages, not a lexical property of the counter itself. Diagrammatically:

    Block  (has lexically scoped properties: counter, form, allow, etc.)
      ┆
[subscribes to]
      ┆
      V
   Counter (has lexically scoped properties: prefix, restart status, restart trigger)
      ┆
  [manages]
      ┆
      V
    Count  (a single global integer variable)
Code

Each counter has a hierarchical prefix§

A counter’s hierarchical prefix is the name of some other counter which recursively supplies it with a hierarchical enumeration, such as is required by subordinate blocks such as head2, table3, etc.

Therefore, when a counter is asked to supply its current or next value to a block being rendered, the value returned is a list of integers consisting of the original counter’s own individual value, preceded by the current value of some other counter whose name is specified by the original counter’s hierarchical prefix.

By default, a given counter’s hierarchical prefix is its immediate superordinate counter. That is, the counter table3 has a default prefix of table2, and the table2 counter’s default prefix is table1. Top-level counters, such as table1 have no default hierarchical prefix.

So, for example, the complete hierarchical enumeration supplied by the table3 counter is: (t1, t2, t3), where tN is the current individual value of the tableN counter. Mathematically speaking:

hier-enum( CounterN )  →  hier-enum( Counter(N-1) ), indiv-count( CounterN )
hier-enum( Counter1 )  →                             indiv-count( Counter1 )
Code

You can change the hierarchical prefix value for a given counter using the =counter directive. For example, you might prefer that all top-level tables (which normally have no hierarchical prefix) should be prefixed by the current value of the head1 counter, to produce output like:

1. Concept
    Table 1.1. List of requirements
    Table 1.2. List of resources
    Table 1.3. List of constraints

2. Implementation
    Table 2.4. Implementation schedule
    Table 2.5. Resource suppliers
    Table 2.6. Costings vs actual expenditure
Code

To ensure that every numbered table uses the current head1 value as a prefix in this way, you would configure the table counter as follows:

=counter table1 :prefix<head1>
Code

(To have the individual counters of the tables automatically restart after each heading, see the :restart-after metaoption, which is described later.)

Note that the =counter directive is lexically scoped (i.e. it is effectively a =config for counters instead of blocks), so the preceding directive would need to be placed at the start of the document.

You can also explicitly remove any prefix from a counter, by specifying an “empty” prefix for it. For example, to change the usual t1.t2.t3. enumeration of the table3 counter to just t3., you could specify:

=counter table3 :prefix<>
Code

Note that this directive would also indirectly affect the table4, table5, etc. counters, by “cutting off” their default hierarchical prefixes at table3. This is considered a feature, as it ensures consistency of representation across counter hierarchies.

Each counter has a restart status§

A counter normally continues to increment its individual value every time any subscribing block requests the “next” value from the counter. However, this monotonic progression can be changed by altering the counter’s restart status.

Normally, a counter’s restart status has the value Nil, indicating no special restart behaviour. In that case the counter defaults to simply incrementing its individual value to obtain its next value.

But you can configure a counter’s restart status to ensure that its next value will be something other than a simple increment, using the =counter directive’s :restart option.

If the value passed in the :restart option is true: =counter head1 :restart then the counter’s restart status immediately becomes true and the counter will no longer increment its individual value when its next value is requested (i.e. when its next subscribing block is rendered). Instead the counter will restart its global count from 1 and return that as its next value.

If the value passed in the :restart option is false: =counter item1 :!restart then the counter’s restart status immediately becomes false and the counter will thereafter increment its individual value as usual when its next value is requested, even if an automatic restart trigger is subsequently encountered (see the following section).

If the value passed in the :restart option is an integer, such as: =counter head1 :restart(42) then the counter’s restart status becomes that integer and the counter will thereafter restart its individual value at the specified integer when a next value is requested, even if an automatic restart trigger is subsequently encountered.

Once a counter has used its restart status to determine what its next enumeration value should be, that restart status is always reset to Nil. In other words, the :restart option tells the counter how to calculate its next (and only its next) value.

Each counter has an automatic restart trigger§

By default, most counters are flagged for subsequent automatic restarting (from 1) whenever a block with the same base name but some superordinate level is encountered in the document. However, there is also a mechanism that permits other non-standard automatic restart triggers to be specified on a given counter.

Each custom trigger consists of a set of one or more basenames of specific trigger blocks that, when they are rendered, will automatically set the restart status of a counter to true, so that the counter will automatically restart whenever its next value is subsequently requested.

To specify that a particular counter should be automatically restarted after one or more blocks are rendered, configure that counter using the :restart-after metaoption, passing the names of the restart-triggering blocks as the metaoption’s argument. For example, to have the numbering of every table and formula restart after each head1, head2, or head3 block:

=counter table    :restart-after< head1 head2 head3 >
=counter formula :restart-after< head1 head2 head3 >
Code

Or to have the numbering of items restart only after each input block (i.e. instead of after any non-item block):

=counter item1   :restart-after< input >
=counter item2 :restart-after< input >
=counter item3 :restart-after< input >
=counter item4 :restart-after< input >
Code

Note that, as the first example above indicates, having to specify all the “superordinate” trigger blocks for each automatic counter restart is rather tedious, so we define that specifying a particular trigger blockname in a :restart-after< blocknameN > implies “...restart after blocknameN or any superordinate block of the same base name.”

In other words, the previous table-and-formula example (though still perfectly valid) could be simplified to:

=counter table    :restart-after< head3 >
=counter formula :restart-after< head3 >
Code

which means “Automatically restart the counter after any head3 or superordinate head block”.

It is also possible to specify automatic restart behaviours “negatively”. That is, to specify that a particular counter restarts after any block, except the one or more that are explicitly excluded from the trigger. For example, having previously changed the reset behaviours of the counters item1 through item4, we could reinstate their default “restart after any non-item” behaviours, like so:

=counter item1  :restart-except-after< item1 item2 item3 item4 >
=counter item2 :restart-except-after< item2 item3 item4 >
=counter item3 :restart-except-after< item3 item4 >
=counter item4 :restart-except-after< item4 >
Code

Or we coulld construct special counters for a set of user-defined item-like blocks, as follows:

=counter MyItem        :restart-except-after< MyItem MySubItem MySubSubItem >
=counter MySubItem :restart-except-after< MySubItem MySubSubItem >
=counter MySubSubItem :restart-except-after< MySubSubItem >
Code

In other words, the presence of an excluded blockname (such as BlockName) in a :restart-except-after implies that the counter being configured is to be automatically restarted after every block except BlockName. Multiple excluded blocknames can be specified in the same :restart-except-after, but specifying both a :restart-after and a :restart-except-after option on the same counter is redundant, because the :restart-except-after already implies “restart after everything else”, so any blocks explicitly listed in the :restart-after are already covered by that “...everything else”.

Therefore, where both :restart-after and :restart-except-after options are specified in a single =counter directive, the :restart-except-after trigger is installed and the :restart-after trigger is ignored (preferably with the renderer issuing a warning).

Note that having to specify hierarchical subordinate excluded subitems all the way down is also tedious, so we define that any excluded blockname in a :restart-except-after implies “...restart after any block except this block or any subordinate block of the same base name.”

Hence the previous example of reinstating normal item restarting behaviour could also be simplified to:

=counter item1  :restart-except-after< item1 >
=counter item2 :restart-except-after< item2 >
=counter item3 :restart-except-after< item3 >
=counter item4 :restart-except-after< item4 >
Code

Every counter’s automatic restart trigger is rechecked immediately after each block in a document is rendered, and if a match is found then the counter’s restart status is changed from Nil to True, which means that the counter will be restarted next time it is asked for a value. However, if the counter’s restart status is already non-Nil (because it has already had an explicit :restart option applied to it) then that pre-existing non-Nil restart status is left unchanged by the trigger.

The effect of this is that any explicit :restart always overrides the effect of any automatic trigger, regardless of whether the :restart precedes or follows the triggering.

Further exposition on this topic is available.

Formatting of blocks§

The :form metaoption allows the author to modify the way in which enumerated blocks are rendered. It can be used to alter the position where the enumeration value appears, and to add extra text around the various components of a block.

All para-ish blocks have a default format of :form<%N. %D> (e.g. 1. Block data here). All head-ish blocks have a default format of :form<%T %A. %C> (e.g. Table 1. Caption here), except for =numhead, which has a default of :form<%N. %D> (e.g. 1. Heading here).

The value associated with a :form option is similar in concept to a sprintf or strftime format string. That is, it specifies a template into which various values related to the block are inserted, to produce a final rendering of the block. The :form option differs from sprintf and strftime in that it uses a more verbose (but far more readable) specification syntax.

Placeholders for components to be formatted into the format template are known as “fields”, and are specified by a % followed by a single letter character (i.e. a single codepoint that matches /<:Letter>/. This may also be followed (immediately and without any intervening whitespace) by one or more options in the usual :OPTION or :OPTION<VALUE> format. Any other character sequences between fields are rendered verbatim.

Renderers are not required to implement the :form metaoption, but if they do then a conformant renderer must support at least the following field types:

Field

Insert next enumeration value as...

%Nthe corresponding Indo-Arabic numerals: 1, 2, 3, etc.
%Athe corresponding ASCII capital alpha: A, B, C ... Z, AA, AB, AC, etc.
%Tthe name of the block type in Titlecase without the leading num or trailing level number: Head, Item, Table, Formula, Defn, etc.
%C

the caption of the block (if any)

%Dthe data contained in the block (i.e. its contents)
%%a literal %
%:a literal :
Field types

So, for example, the following enumerated elements:

=numhead1 PHYSICS
=numhead2 Newtonian
=numhead2 Relativistic
=begin numformula :caption<Mass-Energy Equivalence>
E = MC²
=end numformula
Code

...would normally be rendered something like:

1. PHYSICS

1.1. Newtonian

1.2. Relativistic

            E = MC²

Formula 1. Mass-Energy Equivalence
Code

But the following pre-configurations:

=config numhead1   :form<TOPIC %A - %D>
=config numhead2 :form<%D [subtopic %A%N]>
=config numformula :form<Equation %N: %C>
Code

...would cause the document to be rendered differently:

TOPIC A - PHYSICS

Newtonian [subtopic A1]

Relativistic [subtopic A2]

            E = MC²

Equation 1: Mass-Energy Equivalence
Code

Formatting multi-level enumerations§

Notice that in the =config numhead2 example in the previous section the :form option specifies two enumeration fields: %A and %N. This is because enumerated headings are hierarchical in their numbering. For example, the sequence of numbered headings:

=numhead1 The Plan
=numhead2 Plan design criteria
=numhead2 Plan design constraints
=numhead3 Time
=numhead3 Space
=numhead3 Energy
=numhead4 Available energy
=numhead4 Energy costs
Code

...would be rendered something like:

1. The Plan
    1.1. Plan design criteria
    1.2. Plan design constraints
        1.2.1. Time
        1.2.2. Space
        1.2.3. Energy
            1.2.3.1. Available energy
            1.2.3.2. Energy costs
Code

So a :form for a second-level heading:

=config numhead2 :form<%D [subtopic %A%N]>
Code

...requires two fields, because it expects to interpolate two enumeration values: the enumeration value of the current first-level heading, plus its own second-level enumeration value.

In that example, the first field (%A) would be replaced by the current numhead1 enumeration value, and the second field (%N) would be replaced by the current numhead2 value.

In general, a :form applied to a numheadX block may specify up to X enumeration fields, X-1 of which would be replaced (left-to-right) by the X-1 current enumeration values of the X-1 superordinate headings. The X-th field would, of course, be replaced by the block’s own enumeration value. For example:

=config numhead4 :form<%N(%A) %N.%N: %D>
Code

...would be formatted by replacing the first %N with the current numhead1 enumeration value, then the single %A with the current numhead2 enumeration value, then the second %N with the current numhead3 enumeration value, then the third %N with the current numhead4 enumeration value.

If any of the superordinate headings is not enumerated (e.g. head3 instead of numhead3), then the corresponding enumeration field would be replaced by an empty string instead of a number.

If a :form option specifies fewer enumeration fields than the corresponding heading level:

=config numhead4 :form<%N.%N: %D>
Code

...then only the final X most-subordinate enumeration values are inserted into the corresponding format. That is, the previous example would be rendered:

1. The Plan
1.1. Plan design criteria
1.2. Plan design constraints
1.2.1. Time
1.2.2. Space
1.2.3. Energy
3.1. Available energy
3.2. Energy costs
Code

That is, because the :form for numhead4 specifies only two enumeration fields, only the two most-subordinate enumeration values (those for numhead3 and numhead4) are interpolated.

The same rules and behaviour apply to numitem1/numitem2/numitem3 blocks and to every other block that may be given a hierarchical enumeration.

Formatting options§

Field ordinality§

The %N field normally interpolates the current enumeration value as a cardinal number (1, 2, 3, etc.), but the :ord option requests the field to interpolate an ordinal number instead (1st, 2nd, 3rd, etc.th). For example:

=config numitem1  :form<%N:ord Activity: %D>
=config numitem2 :form<%N:ord step: %D>

=numitem1 Deploy
=numitem2 Plan
=numitem2 Prepare
=numitem2 Execute
=numitem1 Review
=numitem2 Observe
=numitem2 Discuss
Code

...would be rendered:

1st Activity: Deploy
    1st step: Plan
    2nd step: Prepare
    3rd step: Execute

2nd Activity: Review
    1st step: Observe
    2nd step: Discuss
Code

To change the underlying language of the ordinal system (e.g. 1er, 2e, 3e etc. or 第一, 第二, 第三, etc.) see the :lang option.

Field case§

Some enumeration formats (e.g. alphabetic characters or Roman numerals) have uppercase and lowercase variants or close analogies thereto (e.g. “Business” vs “ordinary” notation in Chinese and Japanese numbers). Other fields may benefit from other casing strategies (e.g. Sentencecase, or ProperCase).

To select which case-variant a field uses, append one of the following options:

Option

How the contents of the field are rendered

:ucEVERYTHING IN UPPERCASE OR AS “FORMAL/BUSINESS” NUMERALS
:lceverything in lowercase or as “ordinary/everyday” numerals
:tcFirst character in titlecase but NO other change of case
:tclcFirst character in titlecase, everything else in lowercase
:scSentencecase: First character of each sentence in Titlecase, ABBREVS entirely in uppercase, everything else in lowercase
:pcPropercase: First Character Of Every Word In Titlecase, ABBREVS Entirely In Uppercase, Everything Else In Lowercase
Form field case options

For example, to specify that particular case(s) should be used for %A alphabetic field:

=config numitem1  :form<%A:uc. %D>
=config numitem2 :form<%A:uc(%A:lc) %D>

=numitem1 Task sequence
=numitem2 Plan
=numitem2 Prepare
=numitem2 Execute
Code

...would be rendered:

A. Task sequence
    A(a) Plan
    A(b) Prepare
    A(c) Execute
Code

These options also specify how ordinal numbers are rendered:

=config numitem1  :form<%N:ord:uc ACTIVITY: %D>
=config numitem2 :form<%N:ord:lc step: %D>

=numitem1 DEPLOY
=numitem2 Plan
=numitem2 Prepare
=numitem2 Execute
=numitem1 REVIEW
=numitem2 Observe
=numitem2 Discuss
Code

...would be rendered:

1ST ACTIVITY: DEPLOY
    1st step: Plan
    2nd step: Prepare
    3rd step: Execute

2ND ACTIVITY: REVIEW
    1st step: Observe
    2nd step: Discuss
Code

As a convenient shortcut for common cases, every defined field of the form %X must also provide a corresponding field of the form %x, which is exactly equivalent to %X:lc.

Note, however, that the uppercase version (%X) is not automatically equivalent to %X:uc. That is, a renderer is free to specify, for each field type, whether the default rendering is uppercase or lowercase (if that is even relevant to the field). To override the renderer’s default casing and insist on an uppercase/formal rendering, the user must explicitly specify %X:uc

Note that the :uc, :lc, :tc, and :tclc options all behave exactly like their Raku counterparts, whereas :sc and :pc will attempt to behave in a somewhat more “literary” fashion. Specifically, these last two both understand that words originally in ALLCAPS usually need to stay capitalized. If you think that you need :tclc on a caption or data field, you probably want :sc instead, because it understands slightly more about natural language formatting. For example, the caption:

=for numtable :caption<list of allowed ASCII characters. Namely, those i like.> :form<%N. %C:tclc>
Code

...would be rendered:

Table 1. List of allowed ascii characters. Namely, those i like.
Code

...whereas:

=for numtable :caption<list of allowed ASCII characters. Namely, those i like.> :form<%N. %C:sc>
Code

...would be rendered:

Table 2. List of allowed ASCII characters. Namely, those I like.
Code

Note too that it is an error to specify two or more of :lc, :uc, :tc, :tclc, :sc, or :pc on the same field, either explicitly (e.g. %N:uc:lc) or implicitly (e.g. %n:tc). In such cases, the case of the field specifier itself determines which case is actually used (e.g. %N:uc:lc means %N:uc; %n:tc means %n:lc). Renderers should issue a warning when they encounter these kinds of self-contradictory field specifications.

Specific casing may also be applied to non-enumerator fields such as %T, %C, or %D. For example:

=config numhead1   :form<TOPIC %A - %D:uc>
=config numformula :form<[%T:lc %N: %C:sc]>

=numhead1 Physics

=begin numformula :caption<Mass-Energy Equivalence>
E = mc²
=end numformula
Code

This would override the intrinsic mixed-casing of the block data and captions to produce something like:

TOPIC A - PHYSICS

            E = mc²

[formula 1: Mass-energy equivalence]
Code

In order to avoid undue complexity and ambiguity, explicit embedded RakuDoc components in the data or caption associated with a block will disable any case handling.

For example:

=config numformula :form<[%T:lc %N: %C:sc]>

=begin numformula :caption<
B<Mass-Energy> Equivalence>
E = mc²
=end numformula
Code

This would override the sentence-casing of the caption (only) to produce something like:

            E = mc²
[formula 1: Mass-Energy Equivalence]
Code

Field language§

The :lang option specifies that a field should use the conventions of a specific language when inserting a numeric or ordinal value. The language to be used is specified using the language’s ISO 639-1 two-character language code.

For example to specify that, instead of using regular Indo-Arabic numerals, the items of a first-level enumerated list should use Roman (i.e. Latin) numerals:

=config numitem1 :form<%N:lang. %D>
Code

...or that second-level list items should use French ordinals (1er, 2e, 3e, etc.):

=config numitem2 :form<N:ord:lang. %D>
Code

Renderers are encouraged to support at least the following languages: English (:lang<en>, which is the default and represents the Indo-Arabic numeral system) Roman numerals (:lang<la>), Mandarin Chinese (:lang<zh>), Hindi (:lang<hi>), Bengali (:lang<bn>), and Japanese (:lang<ja>). Collectively these six languages cover the primary number systems used by a majority the world’s population.

Note, however, that renderers are not required to support any languages other than the default :lang<en>. If an unsupported language is requested, renderers may always fall back on :lang<en>.

If a renderer supports Roman numerals (I, II, III, IV, etc.) via %N:lang<la>, then it must also provide the equivalent field %R. If it also supports lowercase Roman numerals via %N:lang<la>:lc (i, ii, iii, iv, etc.), then it must also provide the equivalent field %r.

Likewise, if a renderer supports Mandarin Chinese numbers via %N:lang<zh> (which should generate formal/business 大寫 numerals), then it must also provide the equivalent fields %Z and %大. If it also supports %N:lang<zh>:lc (which should produce ordinary 小寫 numerals), then it must also provide the equivalent fields %z and %小.

Generated Chinese numbers should probably use traditional glyphs, rather than simplified glyphs, for maximum comprehensibility outside mainland China (though the expert opinions of native speakers regarding this choice should certainly be sought where possible).

If a renderer supports Japanese numerals, via %N:lang<ja>, then it must also provide the equivalent fields %J and %業 (formal/business numbers) as well as %j and %並 (everyday numbers). Note that %業 and %並 are still tentative, and perhaps not the most obvious choices. Unfortunately the most obvious choices – %大 and %小 – are already taken by %Z and %z (as Chinese arguably had the prior claim to them). Feedback on these names and suggestions for improvements – especially from native speakers of Japanese – would be greatly appreciated.

If a renderer supports Hindi numerals, via %N:lang<hi>, then it must also provide the equivalent fields %H and %ह. If a renderer supports Bengali numerals, via %N:lang<bn>, then it must also provide the equivalent fields %B and %ব.

Only these six languages (English, Mandarin Chinese, Hindi, Bengali, Japanese, and Latin) will ever have dedicated single-character field specifiers. If a renderer supports the number systems of any other languages (e.g. %N:lang<fr>, %N:lang<th>, or %N:lang<eo>), the renderer is not permitted to reserve any %X field for them.

Note that a renderer is permitted to support %N:lang<xx>, without supporting the corresponding %N:lang<xx>:ord, or vice versa (though implementers are strongly encouraged to implement both cardinal and ordinal modifiers – where relevant – for any language they support).

Formatting aliases§

A numBlockname may have an associated :numalias< TAG > option. Later, in accordance with the rules described above for the Alias directive , the enumeration can substituted into text using A<TAG>.

By default, the format used for the substituted enumeration text will be %T %N, using the enumeration format string described above.

The author may specify the rendering of the alias using the option :numalias< FORMAT | TAG >, where FORMAT is a format string. For example:

=for numitem :numalias
:form
Headquarters location. =comment Text of document with many numitems =para The deadline is noon at the location of the main office, see A<HQ>.
Code

This would be rendered as something like

Article 10. Headquarters location
# Lots of text
The deadline is noon at the location of the main office, see Article 10.
Code

Since all options may be set using the =config directive, it is possible to set :numalias as follows:

=config numitem :numalias< Article %N. | * > :form<Article %N. %D>
Code

In this case, the * is replaced by the actual TAG specified in the :numalias option for the block. For example:

=for numitem :numalias<HQ>
Code

The precedence rule for options is that options specified by a block take priority over options specified by a =config directive.

Consequently, :numalias<|TAG> will override any declaration given by a =config directive, and the default value of %T %N. will be used to render any A<TAG> reference.

Ordinary paragraphs§

An ordinary paragraph consists of text that is to be formatted into a document at the current level of nesting, with whitespace squeezed, lines filled, and any special inline markup applied.

Ordinary paragraphs consist of one or more consecutive lines of text, each of which starts with a non-whitespace character. The paragraph is terminated by the first blank line or directive.

For example:

=head This is a heading block

This is an ordinary paragraph.
Its text will be squeezed and
short lines filled. It is terminated by
the first blank line.

This is another ordinary paragraph.
Its text will also be squeezed and
short lines filled. It is terminated by
the trailing directive on the next line.

=head2 This is another heading block

This is yet another ordinary paragraph,
at the first virtual column set by the
previous directive
Code

Ordinary paragraphs do not require an explicit block specifier or delimiters (within a rakudoc block).

Alternatively, there is also an explicit =para block specifier that can be used to explicitly mark a paragraph, which would be necessary outside a rakudoc block.

=para
This is an ordinary paragraph.
Its text will be squeezed and
short lines filled.
Code

This is rendered as:

This is an ordinary paragraph. Its text will be squeezed and short lines filled.

In addition, the longer =begin para and =end para form can be used. For example:

=begin para
This is an ordinary paragraph.
Its text will be squeezed and
short lines filled.

This is still part of the same paragraph,
which continues until an...
=end para
Code

As demonstrated by the previous example, within a delimited =begin para and =end para block, any blank lines are preserved.

Nesting or indenting a block§

RakuDoc provides a =nested block that marks all its contents as being nested:

=begin nested
S<We are all of us in the gutter,
but some of us are looking at the stars!
>
=begin nested
– Oscar Wilde
=end nested
=end nested
Code

...which would produce:

We are all of us in the gutter,
but some of us are looking at the stars!

– Oscar Wilde

A nested block is like a section block in that it defines a scope and can contain any other kind of block, including implicit paragraph and code blocks. Note that the relative physical indentation of the nested blocks in the document plays no role in determining the ultimate indentation of their contents in the final rendering.

Verbatim blocks§

Normally a writer does not want to consider the way text flows on a page. They want the end of each line to be treated the same as a space, and for extra spaces to be eliminated. However, the exact placing of whitespace sometimes is important, especially for code.

Code blocks§

Code blocks are used to specify pre-formatted text (typically source code), which should be rendered without rejustification, without whitespace squeezing, and by default without recognizing any inline markup instructions. Code blocks also have an implicit nesting associated with them. Typically these blocks are used to show examples of code, markup, data formats, or other textual specifications. They are usually rendered using a fixed-width font.

A code block may be implicitly specified as one or more lines of text, each of which starts with a whitespace character at the block’s virtual left margin. The implicit code block is then terminated by a blank line or an explicit directive. For example:

This ordinary paragraph introduces a code block:

    $this = 1 * code('block');
    $which.is_specified(:by<indenting>);
Code

Implicit code blocks may be used elsewhere with some caveats.

There is also an explicit =code block (which can be specified within most other block types, not just =rakudoc, =item, etc.):

The C<loud_update()> subroutine adds feedback:

=begin code

sub loud_update ($who, $status) {
    say "$who -> $status";

    silent_update($who, $status);
}

=end code
Code

As the previous example demonstrates, within an explicit =code block the code does not have to be indented; it can start at the (virtual) left margin. Furthermore, lines that start with whitespace characters after that margin have subsequent whitespace preserved exactly (in addition to the implicit nesting of the code). Explicit =code blocks may also contain empty lines.

Preprocessing and postprocessing of code§

The code in a document is almost always related to a specific programming language, by default Raku. But examples of Ruby, C, RakuDoc, or other languages may also appear in the Raku documentation sources.

A renderer may apply language specific syntax highlighting to the contents of a code block according to the following rules:

  • =code blocks with no explicit or preconfigured :lang option default to :lang<raku>.
  • =code blocks can be marked as not being in any specific language by using :!lang.
  • Renderers must not syntax-highlight any code block whose :lang value is False, that is :!lang.
  • Renderers must not syntax-highlight any code block whose :syntax-highlighting value is False; by default :syntax-highlighting is True.
  • Renderers may syntax-highlight any other code block (including :lang<text>), but are not required to do so.

By default, a renderer will not change the contents of a code block, but see the caveat when :allow is used.

I/O blocks§

RakuDoc provides blocks for specifying the input and output of programs. These are similar to code blocks in that they preserve whitespace and are rendered distinctly from regular text paragraphs.

The =input block is used to specify pre-formatted keyboard input, which should be rendered without re-justification or squeezing of whitespace.

The =output block is used to specify pre-formatted terminal or file output, which should also be rendered without re-justification or whitespace-squeezing.

Although they are rendered with verbatim whitespace, like a code block, input and output blocks differ from code blocks in that they do recognize any inline markup instructions within their text.

For example:

=begin output
Name: Baracus, B.A.
Rank: Sgt
Serial: 1PTDF007

Do you want additional personnel details?
K<y>

Height: 180cm/5'11"
Weight: 104kg/230lb
Age: 49

Print?
K<n>
=end output
Code

In this example, the two embedded K<...> sequences would be recognized as inline markup and rendered appropriately (i.e. as keyboard input).

Markup within verbatim blocks§

Although =code blocks automatically disregard all markup instructions, occasionally you may still need to specify some markup within a code block. For example, you may wish to emphasize a particular keyword in an example (using a B<> code). Or you may want to indicate that part of the example is metasyntactic (using the R<> code). Or you might need to insert a non-ASCII character (using the E<> code).

You can specify a list of display only markup instructions (B, C, H, I, J, K, N, O, R, S, T, U, V) that should still be recognized within a code block using the :allow option. The value of the :allow option must be a list of the (single-letter) names of one or more markup instructions. Those codes will then remain active inside the code block. For example:

=begin code :allow< B R > :lang<RakuDoc>
sub demo {
    B<say> 'Hello R<name>';
    I<note> 'The I format is not recognized';
}
=end code
Code

This would be rendered:

sub demo {
    say 'Hello name';
    I<note> 'The I format is not recognized';
}
Code

It should be noted that both :allow and :lang (if :syntax-highlighting is True) will affect the rendering of the content of the block. This is likely to cause conflicts in some cases. The renderer is free to choose how to resolve such conflicts, e.g. by disregarding the :allow metadata.

Lists§

Lists in RakuDoc are specified as a series of contiguous =item blocks. No special "container" directives or other list delimiters are required to enclose the entire list.

Note that =item is just an abbreviation for =item1.

Unordered lists§

Lists in RakuDoc are by default unordered. For example:

The three suspects are:

=item Happy
=item Sleepy
=item Grumpy
Code

This produces:

The three suspects are:

  • Happy
  • Sleepy
  • Grumpy

By default, a compliant renderer will provide a bullet for each item. RakuDoc also allows for custom bullets as discussed below.

Multi-level lists§

Lists may be multi-level, with items at each level specified using the =item1, =item2, =item3, etc. blocks. (The indentation depends on the rendering engine and does not need to be included in the RakuDoc markup.) Up to four levels are normally differentiated.

For example:

=item1  Animal
=item2 Vertebrate
=item3 Mammals
=item4 Primates
=item2 Invertebrate

=item1 Phase
=item2 Solid
=item3 Crystalline
=item3 Amorphous
=item2 Liquid
=item2 Gas
Code

This would produce:

  • Animal
  • Vertebrate
  • Mammals
  • Primates
  • Invertebrate
  • Phase
  • Solid
  • Crystalline
  • Amorphous
  • Liquid
  • Gas

Note, however, that item blocks within the same list are not physically nested. That is, subordinate items should not be specified inside superordinate items:

=comment THE WRONG WAY...
=begin item1 ───────────────┐
The choices are: │
=item2 Liberty ─── Level 2 ├─── Level 1
=item2 Death ─── Level 2 │
=item2 Beer ─── Level 2 │
=end item1 ───────────────┘

=comment THE CORRECT WAY...
=begin item1 ───────────────┐
The choices are: ├─── Level 1
=end item1 ───────────────┘
=item2 Liberty ─────────────────── Level 2
=item2 Death ─────────────────── Level 2
=item2 Beer ─────────────────── Level 2
Code

Renderers are not required to parse nested list items, nor to produce a coherent rendering if they are able to parse them.

Multi-paragraph lists§

Using the delimited form of the =item block (=begin item and =end item), we can specify items that contain multiple paragraphs.

For example:

Let’s consider two common proverbs:

=begin item
I<The rain in Spain falls mainly on the plain.>

This is a common myth and an unconscionable slur on the Spanish people,
the majority of whom are extremely attractive.
=end item

=begin item
I<The early bird gets the worm.>

In deciding whether to become an early riser, it is worth considering
whether you would actually enjoy annelids for breakfast.
=end item

As you can see, folk wisdom is often of dubious value.
Code

This renders as:

Let’s consider two common proverbs:

  • The rain in Spain falls mainly on the plain.

    This is a common myth and an unconscionable slur on the Spanish people, the majority of whom are extremely attractive.

  • The early bird gets the worm.

    In deciding whether to become an early riser, it is worth considering whether you would actually enjoy annelids for breakfast.

As you can see, folk wisdom is often of dubious value.

Bullets and bullet strategy§

When rendered, each =itemN will be preceded by a bullet and each level may have a different bullet. A compliant renderer will define a default bullet for at least the first four levels within a nested list, with the bulleting strategy for other levels being up to the renderer.

The default bullet can be overridden with a custom bullet for any =itemN. For example:

The project originally consisted of five phases, of which
two are already complete and two have been abandoned:

=for item :bullet« \c[BALLOT BOX WITH CHECK] »
Investigate existing solutions

=for item :bullet« \c[BALLOT BOX WITH CHECK] »
Define a minimal initial feature set

=for item :bullet« \c[BALLOT BOX] »
Implement this minimal set of features

=for item :bullet« \c[BALLOT BOX WITH X] »
Secure 100 million in venture capital

=for item :bullet« \c[BALLOT BOX WITH X] »
Abscond to the Bahamas with the cash
Code

... would produce something like a list with checkboxes, thus:

The project originally consisted of five phases, of which two are already complete and two have been abandoned:

  • Investigate existing solutions
  • Define a minimal initial feature set
  • Implement this minimal set of features
  • Secure 100 million in venture capital
  • Abscond to the Bahamas with the cash

However, more interesting bullets are possible, including multiple characters. For example:

=for item :bullet« \c[Heavy Check Mark] »
Investigate existing solutions

=for item :bullet« \c[Heavy Check Mark] »
Define a minimal initial feature set

=for item :bullet« \c[Anticlockwise Downwards And Upwards Open Circle Arrows] »
Implement this minimal set of features

=for item :bullet« \c[no entry sign] »
Secure 100 million in venture capital

=for item :bullet« \c[no entry sign, palm tree] »
Abscond to the Bahamas with the cash
Code

... to produce

  • Investigate existing solutions
  • Define a minimal initial feature set
  • Implement this minimal set of features
  • Secure 100 million in venture capital
  • Abscond to the Bahamas with the cash

By using the =config directive, it is also possible to change the default bullets for the duration of a section. For example,

=begin section
=config item1 :bullet« \c[Earth Globe Europe-Africa] » 
=config item2 :bullet« \c[Hand with Index and Middle Fingers Crossed] » 

The major sources of sustainable energy are:
    =item1 wind
    =item1 hydroelectric
    =item1 solar
    =item1 geothermal
    =item1 fusion
    =item2 (eventually)
=end section
Code

...which would produce:

The major sources of sustainable energy are:

  • wind
  • hydroelectric
  • solar
  • geothermal
  • fusion
  • (eventually)

In the event that a custom bullet cannot be rendered (e.g. a specified Unicode glyph is unrecognized or unrenderable in the target format), a compliant renderer will fall back to its default bullet and generate an error message.

Ordered lists§

A =numitemN expresses the inherent numeration of a list:

=numitem1 Visito
=numitem2 Veni
=numitem2 Vidi
=numitem2 Vici
Code

This would produce something like:

1. Visito

1.1. Veni

1.2. Vidi

1.3. Vici

The numbering scheme is at the discretion of the renderer. A renderer might, for example, provide a scheme similar to the examples here, and also provide an enhancement, such as an :html-ordered metaoption that might leverage the <ul type="A"> markup.

The numbering of successive =numitem1 list items increments automatically, but is reset to 1 whenever any other kind of non-ambient RakuDoc block appears between two =numitem1 blocks. For example:

The options are:

=numitem1 Liberty
=numitem1 Death
=numitem1 Beer

The tools are:

=numitem1 Revolution
=numitem1 Deep-fried peanut butter sandwich
=numitem1 Keg
Code

This would produce:

The options are:

1. Liberty

2. Death

3. Beer

The tools are:

1. Revolution

2. Deep-fried peanut butter sandwich

3. Keg

The numbering of nested items (=numitem2, =numitem3, etc.) resets to 1 whenever the numbering of a superordinate item changes (either resets or increments).

To prevent a =numitemN from resetting after a non-item block, you can modify the block’s counter using the :!restart option:

=numitem1 Retreat to remote Himalayan monastery

=numitem1 Learn the hidden mysteries of space and time

I<????>

=counter numitem1 :!restart
=numitem1 Prophet!
Code

This produces:

1. Retreat to remote Himalayan monastery

2. Learn the hidden mysteries of space and time

????

3. Prophet!

Normally, if two =numitemN blocks are separated by some other kind of block (for example, a =para, =code, or =table block), then the numbering of the second =numitemN block resets to 1.

However, if the numitemN counter is modified with a :!restart option (either before or after the intervening block) the numbering of the second numitemN block does not reset, but increments instead (i.e. as if there had been no intervening non-numbered block).

The :!restart option has no effect on the counters of any superordinate or subordinate =numitem blocks that are currently active in the same scope. That is: a =counter numitemN :!restart causes the counter of every active =numitemZ block (where Z > N) to reset to 1, and the counter of every active =numitemA block (where A < N) stays the same.

A =numitem is the same as a =numitem1, by analogy with =item and =head.

The underlying paradigm is that every sequence of list instructions (that is: every sequence of =itemN and/or =numitemN blocks) has a default counter that provides an inherent numeration. The =numitemN instructions express the numeration when rendered, while the =itemN instructions do not.

When a sequence of list instructions is terminated by another sort of block then, by default, a new list is created with its own inherent numeration. By specifying :!restart before the next list instruction, the previous inherent numeration is preserved and continued.

Definition lists§

Lists that define terms or commands can be specified using the =defn block, which is equivalent to HTML <DL> lists.

A definition contains two parts: a term and a defining text. The term is the contents of the first line of the defn block (i.e. the text immediately after an abbreviated =defn, or the first line after a =for defn or =begin defn). The defining text is the remaining lines within the scope of the defn block. A renderer is expected to distinguish between the term and the defining text. For this reason, the term part is rendered verbatim, including any attempted markup codes.

For example:

=defn Admiration
Our polite recognition of another’s resemblance to ourselves.

=defn Misfortune
The kind of fortune that never misses.
Code

...will be rendered as:

Admiration
Our polite recognition of another’s resemblance to ourselves.
Misfortune
The kind of fortune that never misses.

A renderer is expected to retain the information generated by a definition list, and the defining text may be targeted by a link markup instruction.

Numbered definitions§

Definitions can be numbered in the same way as =item lists. That is a =numdefn instruction will express the inherent numeration of the definition list when it is rendered.

As with ordinary lists, if the counter of a =numdefn block is configured with a :!restart metadata option, then the preceding definition list’s inherent numeration is preserved and continued.

For example:

=numdefn Aardvark
A lexicographically pre-eminent animal

=numdefn Beaver
An architecturally pre-eminent animal

Et cetera, et cetera...

=numdefn Yak
A grammatically pre-eminent animal

=numdefn Zorilla
A lexicographically penultimate animal
Code

...will yield something like:

1.Aardvark
A lexicographically pre-eminent animal
2.Beaver
An architecturally pre-eminent animal

Et cetera, et cetera...

1.Yak
A grammatically pre-eminent animal
2.Zorilla
A lexicographically penultimate animal

In order to continue a list, an explicit :!restart must be specified for the block’s counter, such as:

=numdefn Aardvark
A lexicographically pre-eminent animal

=numdefn Beaver
An architecturally pre-eminent animal

Et cetera, et cetera...

=counter numdefn :!restart
=numdefn Yak
A grammatically pre-eminent animal

=numdefn Zorilla
A lexicographically penultimate animal
Code

...will yield something like:

1.Aardvark
A lexicographically pre-eminent animal
2.Beaver
An architecturally pre-eminent animal

Et cetera, et cetera...

3.Yak
A grammatically pre-eminent animal
4.Zorilla
A lexicographically penultimate animal

Suppose a writer needs every numbered definition to form a single monotonic sequence within some block scope (e.g. for every definition within a document section, or every definition throughout the entire document). This would seem to require that every =numdefn be preceded by a =counter numdefn :!restart option. Or the writer could simply pre-configure the auto-restart behaviour for every =numdefn within the scope so that the block’s counter never auto-restarts (i.e. restarts after no block whatsoever), as follows:

=counter numdefn :restart-after<>
Code

Tables§

Tables can be specified in RakuDoc using a =table block using either a visual definition, or a procedural definition. The visual semantics allow for a simple table to be quickly specified, but the simplicity imposes a number of constraints. The procedural semantics overcome those constraints by describing the contents of rows, columns, and cells.

A table may be given an associated description or title using the :caption option and may be included in the Table of Contents.

A procedural table may only be specified in the delimited form. As will become clear below, procedural semantics are assumed if the next RakuDoc instruction after a =begin table is one of =row, =column, or =cell.

Visual description of simple tables§

In a visual table specification, columns are separated by two or more consecutive whitespace characters (e.g. double-space or twin-tabs), or by a vertical line (|) or a border intersection (+), either of which must be separated from any content by at least one whitespace character. Note that only one kind of column separator (i.e. only spaced or only |/+) is allowed in a single line, but different lines are allowed to use different visible column separator types. Using a mixture of visible and non-visible column separator types in a single table is an error.

Rows can be specified in one of two ways: either one row per line, with no separators; or multiple lines per row with explicit horizontal separators – whitespace, intersections (+), or horizontal lines (-, =, _) – between every row. Either style can also have an explicitly separated header row at the top. If rows are using the two-whitespace-character separator, the row cells should be carefully aligned to ensure the table is interpreted as the user intended.

Each individual table cell is separately formatted, as if it were a nested =para. Note that table rows are expected to all have the same number of cells.

This means you can create tables compactly, line-by-line:

=table
The Shoveller Eddie Stevens King Arthur’s singing shovel
Blue Raja Geoffrey Smith Master of cutlery
Mr Furious Roy Orson Ticking time bomb of fury
The Bowler Carol Pinnsler Haunted bowling ball
Code

...or line-by-line with multi-line headers:

=table
Superhero | Secret |
| Identity | Superpower
==============|=================|================================
The Shoveller | Eddie Stevens | King Arthur’s singing shovel
Blue Raja | Geoffrey Smith | Master of cutlery
Mr Furious | Roy Orson | Ticking time bomb of fury
The Bowler | Carol Pinnsler | Haunted bowling ball
Code

...or with multi-line headers and multi-line data:

=begin table :caption('The Other Guys')

Secret
Superhero Identity Superpower
============= =============== ===================
The Shoveller Eddie Stevens King Arthur’s
singing shovel

Blue Raja Geoffrey Smith Master of cutlery

Mr Furious Roy Orson Ticking time bomb
of fury

The Bowler Carol Pinnsler Haunted bowling ball

=end table
Code

Visual-style tables can only have a single header row (namely: everything before the first ===== line). That single header may, however, span one or more initial lines of the visual table specification, as some of the preceding examples illustrate. However, regardless of how many lines a visual-style header spans, it is always treated as a single header row. Individual renderers are free to choose how they represent visual header contents that have line breaks in them: they may treat them as a single string to be reflowed and wrapped, or they may elect to preserve the original line breaks within each header cell. The only requirement is that the entire header of a visual-style table must be rendered as a single row of cells. If two or more header rows are required, use a procedural table instead.

Further exposition on this topic is available.

Procedural description of tables§

A visual table is useful for most purposes, but a procedural description is needed if one or more of the following are required:

  • row labels,
  • vertical or horizontal alignments of individual cells, of complete rows or columns, or of the entire table,
  • cells spanning multiple rows and/or columns,
  • cells that include other RakuDoc blocks, such as a nested sub-table or a code block.

Table semantics are procedural if the =table declarator is immediately followed by =cell, =row, or =column, otherwise visual semantics are assumed.

Only =cell, =row, =column, or =comment declarations are permitted within the immediate block scope of a procedural table. Note that both =cell and =comment introduce their own block scopes, so other RakuDoc blocks (including nested tables) may be included within their block scopes.

The fundamental idea is that a procedural =table sets up a semi-infinite 2D grid of cells, all of which are initially empty. The grid also tracks the fill position ($POS: the next empty cell to be filled), and the fill direction ($DIR: the direction to move $POS after filling; either across or down). Initially, $POS is set to the top left-most cell of the table, and $DIR is set to across.

Subsequent =cell blocks start filling in that grid, with any intervening =row and =column directives adjusting $POS and $DIR.

=cell blocks can be specified as spanning multiple rows and/or columns, using the :row-span(WIDTH), :column-span(HEIGHT), or :span(WIDTH, HEIGHT) annotations, in which case the block fills more than one grid cell (and merges them into a single logical cell), with the top-left corner of the fill starting at $POS.

A =cell block has the following effects:

  • The specified contents are considered to fill in the cell(s) at $POS (even if the contents are actually null/empty)
  • $POS is moved to the next unfilled cell in the direction specified by $DIR (i.e. either across or down)

A =row directive has the following effects:

  • $DIR is set to across
  • If the previous action was not a =cell (i.e. it was a =table , =row, or =column) then the =row directive has no other effects (i.e. the subsequent effect is skipped)
  • Otherwise, starting at the row specified by $POS, find the uppermost row R that is at-or-below the row specified by $POS, and where row R has at least one empty cell in a column strictly to the left of the column specified by $POS, then move $POS left-and-down, to the left-most empty cell in row R.

A =column directive has the following effects:

  • $DIR is set to down
  • If the previous action was not a =cell (i.e. it was a =table , =row, or =column) then the =column directive has no other effects (i.e. the subsequent effect is skipped)
  • Otherwise, starting at the column specified by $POS, find the left-most column C that is at-or-to-the-right-of the column specified by $POS, and where column C has at least one empty cell in a row strictly above the row specified by $POS, then move $POS up-and-right, to the upper-most empty cell in column C

In other words, =row searches the south-west quadrant from $POS to find the most north-westerly empty cell ... and moves $POS to that cell. And =column searches the north-east quadrant from $POS to find the most north-westerly empty cell ... and moves $POS to that cell.

In addition, =table and =cell blocks and =row and =column directives can be annotated with any of the following metadata, which subsequently act as defaults for any =cell in their scope:

  • :align< ALIGNMENTS > : changes how contents are aligned in a cell ALIGNMENTS may be any one of: left, centre, center, right, and/or any one of: top, middle, bottom.
  • :header : specifies that the cell(s) should be considered column headers
  • :label : specifies that the cell(s) should be considered row labels (i.e. horizontal headers)

For example:

=begin table :caption('The Other Guys')
=row :header
=cell Superhero
=cell Secret Identity
=cell Superpower
=row
=cell The Shoveller
=cell Eddie Stevens
=cell King Arthur’s singing shovel
=row
=cell Blue Raja
=cell Geoffrey Smith
=cell Master of cutlery
=row
=cell The Bowler
=cell Carol Pinnsler
=cell Haunted bowling ball
=end table
Code

Or, if you prefer to specify the data in columns:

=begin table :caption('The Other Guys')
=row :header
=cell Superhero
=cell Secret Identity
=cell Superpower
=row
=column
=cell The Shoveller
=cell Blue Raja
=cell The Bowler
=column
=cell Eddie Stevens
=cell Geoffrey Smith
=cell Carol Pinnsler
=column
=cell King Arthur’s singing shovel
=cell Master of cutlery
=cell Haunted bowling ball
=end table
Code

Either of which would produce:

Superhero

Secret Identity

Superpower

The Shoveller

Eddie Stevens

King Arthur’s singing shovel

Blue Raja

Geoffrey Smith

Master of cutlery

The Bowler

Carol Pinnsler

Haunted bowling ball

The Other Guys

Further exposition on this topic is available.

Formulae§

RakuDoc provides a built-in block =formula and an inline markup code F<> to contain text that will be rendered as formulae.

There are several markup languages for expressing mathematical expressions, so the RakuDoc specification recommends the currently most widespread markup syntax for =formula and F<>, namely the LaTeX mathematical notation, including the extensions specified in the AMSMath package

This does not preclude the development of custom blocks to support other mathematical markup languages, e.g. a =MathML custom block to support another syntax.

Implementors of renderers are not required to render the contents of these instructions; it is acceptable for a renderer to render the contents of a =formula or F<> in some other way than as a fully realized mathematical equation.

Both =formula and F<> may take explicit ALT texts, so that the author can decide how their formula should be rendered in cases where the renderer cannot handle the specification.

That is, the =formula block accepts an :alt metaoption, and the syntax for the F<> instruction is either F< FORMULA > or F< ALT | FORMULA >.

Using the ALT text options, the document author can supply a suitable explicit alternative rendering to renderers that cannot handle the full formula syntax:

We will use the identity: F<∑ 1/n² = 𝜋²/6 | \sum \frac{1}{n^{2}} = \frac{\pi^{2}}{6}>

...where the value of pi can be inferred from Euler’s Identity:

=for formula  :alt< eH<iπ> + 1 = 0 >
e^{i\pi}+1=0
Code

An ALT text allows an author to rely on getting an “accurate” representation under those renderers that fully support formulas, and to be able to fall back on a range of reasonable alternatives under those renderers that don’t:

Fall back on

Example

Plaintext

F<  Euler’s Identity | e^{i\pi}+1=0 >

RakuDoc

F<  eH<iπ> + 1 = 0 | e^{i\pi}+1=0 >

Unicode

F<  eⁱᐢ + 1 = 0 | e^{i\pi}+1=0 >

Image

F<  P<file:EulerID.jpg> | e^{i\pi}+1=0 >

Link

F<  L<https://en.wikipedia.org/wiki/Euler%27s_identity> | e^{i\pi}+1=0 >
Fallback options

It is also possible to stack the fallback options. For example, one could try for an “accurate” rendering of a formula, but fall back on the placement of a pre-rendered image, or (failing to find that) fall back again to a RakuDoc representation with an outgoing link:

We will use: F<
                 P<
                     L< eH<iπ> + 1 = 0
                      | https://en.wikipedia.org/wiki/Euler%27s_identity
                      >
                  >
              | e^{i\pi}+1=0
              >
Code

Implementors are free to delay – or reject – implementing LaTeX-based formulas, and implementations are considered compliant with the specification, so long as the ALT texts are rendered.

Further exposition on this topic is available.

RakuDoc comments§

RakuDoc comments are components that both RakuDoc renderers and ambient-code compilers ignore. Comments are useful for meta-documentation (documenting the documentation) and for communication between authors and readers of RakuDoc documents.

Single-line comments can use an abbreviated =comment block:

=comment Add more here about the algorithm
Code

For multi-line comments, use a delimited comment block:

=begin comment
This comment is
multi-line.
=end comment
Code

Note, however, that delimited comment blocks do not nest, so they are not a reliable method of “commenting out” sections of a RakuDoc (or Raku) source document. In particular, they will always produce an error if the section to be commented out already contains another delimited comment. To safely remove sections of RakuDoc source code from the renderer’s consideration see Ignoring RakuDoc source instead.

Where an output format, such as HTML, offers a comment syntax, a compliant renderer may render the comment contents as a native comment in the output.

Ignoring RakuDoc source§

During the development or maintenance of a document it is often necessary to temporarily exclude source from being rendered, while at the same time leaving the source in the file either for reference or to return to later.

The =ignore block does this. After a =begin ignore is encountered, everything thereafter is treated as not being rendererable RakuDoc, until the matching =end ignore line is encountered, where “matching” takes into account any number of (recursively) nested =begin ignore...=end ignore pairs.

Note: this implies that, whilst a delimited ignore block does not care about the correctness of the vast majority of any RakuDoc source contained within it, it does insist that any nested delimited ignore blocks within it must be properly balanced. That is, an unmatched inner =begin ignore or =end ignore within a balanced outer =begin ignore...=end ignore pair will produce an error when the document is rendered.

A renderer must never render the contents of an ignore block in any way.

Further exposition on this topic is available.

Semantic blocks§

All uppercase block typenames are reserved for specifying standard documentation, publishing components, source constructs, or meta-information. The following must be recognized:

=NAME
=AUTHOR
=VERSION
=TITLE
=SUBTITLE
=LICENSE
=LICENCE
=SYNOPSIS
Code

The block name of a semantic block is to be rendered as if it were =head BLOCKNAME, and the contents of the block are then to be rendered as one or more regular paragraphs. Consequently, if a semantic block has multiple lines, then its contents must be enclosed using the delimited form.

A semantic block may be defined, but omitted from the text in the place it is written. This is because sections about Authors, or Licensing, are sometimes required at the end, or at the beginning, or in the meta section of an HTML document.

A renderer is expected to gather the contents of a semantic block for it to be accessible by an external program.

If the metadata option :hidden is associated with a semantic block (by using a =config directive, or as a direct metadata option on the extended or delimited forms) then the renderer will not render the semantic block at the position it is located in the RakuDoc document. It will be placed in a data structure by the renderer and the contents can then be rendered at a place defined by a Placement instruction.

The block name of a rendered semantic block will be placed in the Table of Contents table in the position that it is rendered, unless the :!toc and or :caption options are set. A :hidden metadata option will also remove the block’s entry from the ToC. But if it is placed by a P<semantic:> instruction, the block entry will be placed at the appropriate point in the ToC.

Citations§

RakuDoc provides a mechanism for citing external reference sources in the usual way: with a compact marker in the text and the full information for the source material listed elsewhere. Citations in RakuDoc are marked and listed in an appearance-neutral syntax that allows them to be rendered consistently in any standard citation style (e.g. ACM, APA, Chicago, IEEE, Harvard, MLA, etc.).

Citation indicators§

Individual citations of reference sources in the text are indicated with a Q<> formatting code. The value contained within each such formatting code must be a unique citation identifier associated with some cited reference work within the document (see below). For example:

=para
We have now explored Q<rakudoc-evo-chapter> at some length
whether it would be better to use JSON or XML Q< JsonVsXMLMeta >
to specify citation data or whether it might be better to design
a bespoke DSL Q«10.1109/MODELS50736.2021.00031» instead.
Code

A single Q<> can contain multiple identifiers, which must be separated by semicolons. For example:

=para
The design of Raku commenced Q<Apocalypse1; P6&Parrot; ConwayKeynote2010> in late 2000...
Code

Depending on the chosen bibliographic style in which the document is eventually rendered, multi-identifier Q<> codes may be rendered separately:

The design of Raku commenced [7] [9] [10] in late 2000...

...or aggregated into a single bibliographic marker:

The design of Raku commenced [7,9-10] in late 2000...

Each identifier can also optionally be followed by comma and an annotation, which may be used to refine the context of a given citation by specifying particular sections, chapters, pages, figures, tables, timestamps, etc. within the work being cited. For example:

=para
We have now explored Q<rakudoc-evo-chapter, pp. 32-47> at some length
whether it would be better to use JSON or XML Qtable 8b>
to specify citation data or whether it might be better to design
a bespoke DSL Q<10.1109/MODELS50736.2021.00031, sect. III> instead.

=para
The design of Raku commenced Qch. 1; ConwayKeynote2010, ts=00:03:27>
in late 2000...
Code

Note that whether or not these annotations are included as part of the corresponding bibliographic markers, or are silently ignored, is determined entirely by the bibliographic style that is selected when the document is rendered.

Citation blocks§

The full citation dataset for each individual reference work is specified in a citation block, as structured textual data in any of the following notations: CSL-JSON, CSL-YAML, CSL-Raku, RIS, MODS, BiBLaTeX, BibTeX, BibTeXML, or Medline/PubMed (XML or NBIB). All of these formats are widely used citation-data-interchange standards, except for CSL-Raku, which is just CSL-JSON/CSL-YAML data transposed into the native Raku syntax for a list of hashes.

Each citation block may contain multiple entries (i.e. aggregated citation data for multiple reference works), but the data for every entry within a single block must be represented in the same data format (e.g. all in CSL-JSON, or all in BibTeX, etc.) A document may, however, contain multiple citation blocks, each of which may specify their contents in different data formats.

For example:

=comment  This citation data in in CSL-JSON format
=begin citation
[
{
"id": "mercurio2025",
"type": "book",
"title": "The Morphological Beauty of Raku Grammars",
"author": [ {"family": "Mercurio", "given": "Silvia"} ],
"issued": {"date-parts": [[2025, 3, 14]]},
"publisher": "Butterfly Press",
"ISBN": "978-1-2345-6789-0"
}
]
=end citation
Code
=comment  This citation is in BibLaTeX format
=citation @article{zenraku2024,
author = {Wall, Larry},
title = {The Zen of Raku},
journaltitle = {Journal of Camel Studies},
date = {2024-05-12},
volume = {42},
number = {3},
pages = {101-115},
url = {https://example.org/raku},
urldate = {2026-01-23}
}
Code
=comment  This in RIS data
=begin citation
TY - JOUR
ID - thorne2023
AU - Thorne, Alistair
TI - Optimization Strategies for MoarVM Bytecode
JO - Journal of Virtual Machine Design
PY - 2023/08/21/
VL - 9
IS - 2
SP - 210
EP - 235
SN - 1234-5678
ER -
=end citation
Code

Note that, for implementation (and perhaps source-highlighting) purposes, the actual species of notation for data contained in each citation block can be automatically inferred by examining just the first few non-blank characters in the block’s content (the “sniff” test), according to the following table:

First char(s)

Inferred format

Because character represents the start of a...

[

CSL-JSON

JSON array of objects

-

CSL-YAML

YAML list of mappings

(

CSL-Raku

Raku-native parenthesized list of hashes

{

CSL-Raku

Raku-native unparenthesized list of hashes

@

BibLaTeX

sequence of standard BibLaTeX or legacy BibTeX entries

<bibtex

BibTeXML

sequence of XML-encoded BibTeX entries.

<mods

MODS

sequence of XML-encoded MODS entries.

<PubmedArticleSet

PubMed/Medline XML

sequence of XML-encoded PubMed/Medline entries.

PMID-

PubMed/Medline NBIB

sequence of modern PubMed NBIB KEY-VALUE datasets

UI -

Medline NBIB

sequence of legacy Medline NBIB KEY-VALUE datasets

TY -

RIS

sequence of RIS-format KEY-VALUE datasets

Table

Citation data can also be loaded from external sources via a URL, by using the :load metaoption:

=for citation  :load< file:/users/jan/.citelists/working/citations.json >

=for citation :load< https:example.com/markup_design_references.bib >
Code

In this variant, the block must not contain any extra data (and renderers should report an error if it does).

The suffix of the file determines the inferred format of the imported data:

Suffix

Inferred format

.bib

BibLaTeX (including legacy BibTeX)

.json

CSL-JSON

.mods

MODS

.nbib

Medline/PubMed NBIB

.raku

CSL-Raku

.ris

RIS

.xml

MODS or PubMed XML or BibTeXML (distinguished via “sniff” test)

.yaml

CSL-YAML

Table

A document can include any number of citation blocks, in any order, located anywhere in the document. Some common approaches might be:

  • One block per citation, with each citation placed immediately before or after the point where the source is referred to via a Q<> code within the text.
  • One citation block at the end of each chapter, section, or heading, containing data for all citations made in that unit.
  • A single citation block at the end of the entire document, with all the citations aggregated together.

Citation identifiers§

Every dataset included in any citation block must contain a citation identifier: a text string consisting of any sequence of one or more Unicode characters. Each citation identifier must be unique across all citation datasets within the document.

This identifier may be specified in the id field (of any of the CSL notations), the ID attribute (of MODS), the mandatory initial ID string (of BibLaTeX, BibTeX, and BibTeXML), the PMID or UI value (of PubMed/Medline), or the ID tag (an unofficial extra tag commonly used with RIS data).

If a dataset cannot furnish a suitable identifier, but its citation data includes a ISO-26324 Digital Object Identifier, then the DOI may be used instead.

Each citation identifier is used to associate a Q<> marker with its corresponding citation data in some citation block. For example:

Most programming languages use everyday words for their keywords,
but some have taken that notion much further, basing their entire
syntax on (subsets) of natural languages Q<Perligata> or on conlangs
Q<tlhInganHol::yIghun>.

=begin citation
    [
      {
        "id":              "tlhInganHol::yIghun",
        "type":            "software",
        "title":           "Lingua::tlhInganHol::yIghun: Perl code in the original Klingon",
        "author":          [{ "family": "Conway", "given": "Damian" }],
        "issued":          { "date-parts": [[2009, 6, 1 ]] },
        "abstract":        "Perl module that allows programs to written Klingon syntax and vocabulary.",
        "publisher":       "MetaCPAN",
        "version":         "20090601",
        "URL":             "https://metacpan.org/pod/Lingua::tlhInganHol::yIghun",
        "accessed":        { "date-parts": [[2025, 1, 25 ]] }
      },
      {
        "id":              "Perligata",
        "type":            "paper-conference",
        "title":           "Lingua::Romana::Perligata -- Perl for the XXI-imum Century",
        "author":          [{ "family": "Conway", "given": "Damian" }],
        "event-title":     "Proceedings of the Perl Conference 4.0",
        "event-place":     "Monterey, CA, USA",
        "publisher":       "O’Reilly and Associates",
        "publisher-place": "CA, USA",
        "issued":          { "date-parts": [[2000, 7]] },
        "page":            "1-15",
        "ISBN":            "0-596-00013-8"
      }
    ]
=end citation
Code

When used within a Q<>, a citation identifier cannot contain the characters '|', ';', ',', or '\', unless they are escaped with a leading '\'. Likewise, it cannot contain the Q’s own delimiters, unless they are either balanced or escaped.

Further exposition on this topic is available.

Positioning bibliographic lists§

The eventual bibliographic list that a renderer generates from the data may be placed anywhere within a document, by using a =place directive with the citation: scheme. For example:

=head References
=place citation:*
Code

This places a custom list-of-citations that is specially produced by the renderer, using every dataset from all of the document’s =citation blocks, and applying a user-selected citation style – specified either within the document via a :citation-style option (see below), or a style externally selected for the renderer in some way (e.g. via a command-line argument or environment variable).

To have the renderer include only particular citations, you can specify something more limited than “whatever” (i.e. *) in the placement:

=head References
=comment Only list sources actually cited in at least one Q<>
=place citation:cited

=head Further Reading
=comment Only list sources not cited in any Q<>
=place citation:uncited
Code

If a RakuDoc document does not contain any =place citation: directives, but includes one or more Q<> codes, then the renderer should behave as if there had been a single =place citation:cited at the very end of the document.

Categorizing citation blocks and selecting bibliographic lists§

Individual citation blocks can also be declared to belong in one or more user-defined categories (whose names must – as usual for user-defined components – contain at least one uppercase and one lowercase letter).

These categories can then be used to select particular citation data for a given listing. Multiple citation blocks can be specified in the same category, and a given citation block can be specified as belonging to multiple categories. For example:

=for citation  :category<SyntaxResearch>

=for citation :category<OtherImpls>

=for citation :category<SyntaxResearch Semantics>

=for citation :category<Semantics ImplIssues>

=comment And then...

=head1 Bibliography

=numhead2 Syntactic design
=place citation:SyntaxResearch

=numhead2 Semantic constraints
=place citation:Semantics

=numhead2 Implementation
=place citation:ImplIssues,OtherImpls
Code

Rendering citations§

When a Q<> marker or =place citation: list is to be rendered, the renderer must determine the citation style in which the markers and the citations list are to be formatted (i.e. ACM, APA, Chicago, IEEE, Harvard, etc.)

The required styling information may be hard-coded directly into a document, by specifying the :citation-style option in the document scope. The :citation-style value may be specified either as a full URL for the corresponding CSL style file:

=document :citation-style< https://raw.githubusercontent.com/citation-style-language/styles/refs/heads/master/apa-numeric-superscript-brackets.csl >
Code

...or as just the standard name of the CSL style (without its filepath prefix or extension suffix):

=document :citation-style< chicago-author-date >
Code

In the absence of an explicit specification within a RakuDoc document, the default citation style is IEEE . That is, each document begins with an implicit =document :citation-style<ieee>.

A CSL locale is also required and may be hard-wired into a RakuDoc document, using the document level :citation-locale option, which takes an IETF BCP 47 language tag specifying the desired locale:

=document :citation-locale< de-CH >
Code

The default locale for a RakuDoc source is en-GB . That is, each document begins with an implicit =document :citation-locale< en-GB >.

Note: the en-US locale was not chosen as the default because it overpunctuates abbreviations and because it uses the month-day-year date sequence.

The specification order of the original citation data within a RakuDoc document is entirely unrelated to its final rendering; the order is always determined by the specified citation style and locale.

When rendering to output formats that support intradocument linkages (such as HTML), renderers may wish to link each rendered bibliographic marker to the corresponding bibliographic reference in the rendered bibliographic list, and perhaps back-link the reference to the marker as well. This approach is encouraged, but not required.

Missing citations§

If any Q<> contains a citation identifier that is not present anywhere in the document’s citation data, and if the author has explicitly requested a listing for that non-existent citation dataset (e.g. by specifying a =place citation:* or =place citation:cited), then the missing dataset must be listed in such a way that it is clearly marked as absent/unknown.

The missing listing must also still be associated with a suitable marker generated for the orphaned Q<> code when the citations are listed. For example, if a Q<Wall42> or Q<SapWho99> appears in the text, but there are no datasets in any citation block that contain those particular citation identifiers, then the markers must still be rendered appropriately in the text, as something like:

As discussed in Wall’s early treatise on language design[7,8], the apparent design tension between manipulexity and whipuptitude may only be an artefact of our fixation with linguistic minimalism.

...and the missing reference sources might be rendered like so (in IEEE style):

[7] R. Unknown, “NO SUCH CITATION ID: Wall42”, Did you misspell Wall42?, 0.

[8] R. Unknown, “NO SUCH CITATION ID: SapWho99”, Did you misspell SapWho99?, 1.

...or like so (MLA style):

Unknown, Reference. 0. "NO SUCH CITATION ID: Wall42." Did you misspell Wall42?

Unknown, Reference. 1. "NO SUCH CITATION ID: SapWho99." Did you misspell SapWho99?

That is, a RakuDoc renderer must autogenerate a pseudo-entry for each missing citation dataset, with the issue dates numbered sequentially from 1, as if the absent citation data had been:

=begin citation
[
{
"id": "Wall42",
"type": "article",
"title": "NO SUCH CITATION ID: Wall42",
"author": [{ "family": "Unknown", "given": "Reference" }],
"container-title": "Did you misspell Wall42?",
"issued": { "date-parts": [[0]] }
},
{
"id": "SapWho99",
"type": "article",
"title": "NO SUCH CITATION ID: SapWho99",
"author": [{ "family": "Unknown", "given": "Reference" }],
"container-title": "Did you misspell SapWho99?",
"issued": { "date-parts": [[1]] }
},
]
=end citation
Code

User-defined blocks§

When a block name contains both an uppercase and a lowercase character, as specified in the naming rules below, it is interpreted as a developer-defined block. The naming rules are to ensure that the names of built-in blocks, semantic blocks, and custom blocks never collide.

The way in which a renderer styles the contents of a custom block depends on the renderer, and each renderer may specify a procedure for using user-supplied templates or code.

If a renderer does not recognize a custom block, then the renderer should replace that block with the contents of the block’s :alt<...> option (if provided). If the document author did not include an :alt<...> option, then the renderer should treat the block name as the contents of a =head block, which can be overridden as described in Table of Contents and should render the contents of the unrecognized custom block verbatim, like a =code block. Any unrecognized custom block (with or without an :alt<...> option) should generate a warning message unless the custom block is passed the :!warn option.

Multi-paragraph contents should be enclosed using the delimited form of the block.

Naming rules§

In order to avoid conflicts between built-in blocks, semantic blocks, custom blocks, and markup instructions, the following rules must be followed:

  • Built-in blocks (e.g. head, item, table)
  • names must be all lowercase and at least two characters long
  • renderers may choose how to render built-in blocks, but must respect all the defined metadata options specified here, and may respect additional metadata options
  • Semantic blocks (e.g. AUTHOR, TITLE)
  • names must be all uppercase and at least two characters long
  • renderers should treat these as if they are head1 with a caption consisting of the semantic block name
  • the contents of the block should be treated as a paragraph.
  • Custom blocks (e.g. MyNewBlock)
  • names must contain at least one uppercase, and at least one lowercase character
  • renderers will define how users may specify metadata options and syntax
  • renderers will define how the contents of the block are interpreted and rendered
  • Custom markup codes (e.g. Æ, Ø, ß)
  • names must consist of exactly one uppercase Unicode character (i.e. with the Upper property)
  • names may not be a character in the ASCII range (these are reserved for current and future built-in markup codes)
  • the built-in markup instruction – M<> – is also provided for custom markup
  • Custom options
  • Renderers may provide additional options for all blocks and for the document, and it is strongly recommended that such option names consist of at least one uppercase and at least one lower case character to distinguish them from options specified in this document.

Implied code and indentation§

An example of implied code was given in the section on Code blocks. Implied code can be used in other blocks.

Each block creates a virtual margin (at the column before its leading =) and that virtual margin extends only to the end of the block (i.e. not to the start of the next named block). Thus:

┊=begin rakudoc
┊This is an implicit =para block
┊
┊   This is implicit =code block
┊
   ┊=begin nested
   ┊This is an implicit =para block
   ┊
   ┊   This is implicit =code block
   ┊
      ┊=begin nested
      ┊This is an implicit =para block
      ┊
      ┊   This is implicit =code block
      ┊
      ┊=end nested
   ┊
              ┊=for nested
              ┊This is an implicit =para block
              ┊over multiple lines
              ┊ending at this final non-blank line
   ┊
   ┊           This is implicit =code block (NOT a =para)
   ┊
   ┊=end nested
┊
┊This is an implicit =para block
┊
┊    This is implicit =code block
┊
┊=end rakudoc
Code

Which means that, in the following example:

=begin rakudoc
=for Podcast
this is not code

this is code
=end rakudoc
Code

...the final line is an implicit code block, because it is indented from the virtual margin of its containing =begin rakudoc/=end rakudoc block.

Whereas in:

=begin rakudoc
=for Podcast
this is not code

this is not code either
=end rakudoc
Code

...the final content is an implicit para block, because it starts at the virtual margin of its containing =begin rakudoc/=end rakudoc block.

Indentation from the current virtual margin only implies a para or code block in blocks that don’t already explicitly specify otherwise. Hence, all the following “container blocks” should honour the indented means code and on-margin means para shortcuts: =cell, =defn, =item, =itemN, =nested, =rakudoc, =section, =pod.

None of the following blocks should infer para or code from indentation: =para, =code, =input, =output, =comment, =table, =formula, =data, =head, =headN, =SEMANTIC.

That’s because each block in this second group specifies explicitly what type of information their contents are supposed to be, so there’s no need to infer anything. In particular, =para and =code are specifically provided to circumvent inference from indentation.

A =config code directive will also apply to any implicit code block in the block scope.

Finally, user-defined custom blocks should always pass their contents verbatim to whatever appropriate user-defined handler is in scope, and it’s up to that handler to infer the meaning of any indentation.

Further exposition on this topic is available.

Metadata§

A powerful feature of RakuDoc is the ability to associate metadata with a block. Metadata can be used to change the way a block is rendered, or to allow a renderer to access data in the cloud, or receive data from a microservice.

Some metadata options are defined for certain blocks and a renderer must produce the behaviour described in this section (or in the section for the relevant block), to the extent possible for a given output format.

A renderer may ignore metadata options not specified in this document, or define other metadata options that it will recognize.

Further exposition on this topic is available.

Anchors§

Whenever a =head block such as:

=head Table of Contents, Index, and Citations
Code

...is rendered, it is also associated with an anchor, so that when a link of the form L<link to an internal heading|#Table of Contents, Index, and Citations> is rendered, the renderer will place a link to the correct heading in the output format. The anchor will also be used in the Table of Contents.

Note that the text in the L<...> before the | is the display text, and the tag after the | is the content of the target =head block.

In order for a link to work correctly, the anchor must be unique. The renderer is free to chose the algorithm it uses for generating the internal anchor. This is because different outputs, such as Markdown and HTML, have different formats for anchors.

An author may want to shorten an internal link to a title, and also to place an anchor on every block. For this purpose, the :id<LABEL> metadata option can be attached to any block. For example:

=for head :id
Table of Contents, Index, and Citations

...and later we can add: L<link to an internal heading|#ToCIaC>
Code

The renderer is expected to create a link with that name to the start of the block. It is up to the author of the document to ensure that all :id links are unique.

A renderer may mangle the link name (e.g. the contents of a header) to create an anchor ID internally because different output formats may place restrictions on the characters that can be used in a link. However, a document author may not rely on a renderer’s ID generation algorithm.

Internal links (links to anchors within the same document) must be specified by a leading # followed by either:

  • the target block’s explicit :id<LABEL>, or
  • the exact contents of the corresponding =head block, or
  • the exact contents of a block’s explicit :caption<TEXT>.

Internal links cannot be specified by a # followed by:

  • a =head block’s implicit autogenerated-from-content ID, or
  • a block’s implicit autogenerated-from-caption ID.

That is, the in-document link target cannot be the mangled contents of a =head block or a :caption<...> metatag; it can only be the original contents.

For example:

=for head :id
A sample heading

=for table :id :caption
A  B  C
1  2  3

This is a L<valid link (to an explicit block ID) | #h123 >
This is a L<valid link (to an explicit block ID) | #t456 >

This is a L<valid link (to a heading) | #A sample heading >
This is a L<valid link (to a caption) | #Example table   >

This is L<NOT a valid link | #A_sample_heading >
This is L<NOT a valid link | #Example_table   >
Code

Table of Contents, Index, and Citations§

When a renderer parses a file containing RakuDoc, information is collected about headings (from =headN and semantic block statements), as well as X<> and Q<> markup codes.

This information, if it exists, is expected to be rendered in an automatic Table of Contents, an Index, or a Citations list, and placed in a manner determined by the renderer (e.g. as a sidebar Table of Contents, or as a separate Index or Bibliography at the end of the main text).

The information may also be filtered and placed by the author using a P<> markup instruction.

To avoid duplication, if an author uses a =place statement to filter information that would usually be automatically rendered, the automated rendering is cancelled. In this way, the author can circumvent the automated rendering of information and take explicit control of their positioning and content.

Additionally, some authors may not want any Table of Contents, Index, or Citations list. The automated generation of these structures can be prevented via the appropriate document-level meta option:

=document :!auto-toc :!auto-index
Code

Renderers will typically add default captions or titles for automatically generated content. These can also be changed using the various :auto-... meta options:

=document :auto-toc<Contents> :auto-index<Glossary> :auto-citations<List of References>
Code

Setting :toc on a block will cause the complete contents of that block to be included in the Table of Contents. Including the entire block contents is usually not desirable, so the :caption<...> meta option can be used to provide a more appropriate text for the Table of Contents.

Setting :!toc will prevent a block’s information from being included in the Table of Contents.

When a built-in block, such as table, needs to be entered into the Table of Contents and styled like a =head2, then use =table2 instead of table.

Custom Tables of Contents can be created to group together tables, formulas, code examples, etc.. This is described in Custom tables of contents. Note that placing information gathered for custom Tables of Content will not cancel the automated generation of the default head Table of Contents.

Custom tables of contents§

The implicit heading level of a block in the Table of Contents (TOC) is always equal to its block level. Hence =head1 is implicitly level-1, while =formula3 is implicitly level-3.

The default TOC is created from =head and semantic blocks (e.g. =SYNOPSIS), which are defined to have the :toc option set to True. The semantic blocks =TITLE and =SUBTITLE are not typically included in a Table of Contents, and so are defined to have the :!toc option.

Other blocks may be added to the default Table of Contents. To add a single block (or an entire block type) to the default TOC (a.k.a. the head TOC), configure it with an explicit :toc option. For example, if you want all first-level formulas to be listed in the TOC, preconfigure =formula1 with :toc:

=config formula1 :toc
Code

Then use =formula1 or =formula to specify each formula.

On the other hand, if you want only one particular table included as a third-level TOC entry, specify the :toc option on just that one block:

=for table3 :caption<XOR logic> :toc
    |   | 0 | 1 |
    | 0 | 0 | 1 |
    | 1 | 1 | 0 |
Code

You can also specify that a particular block or block type belongs to one or more other TOCs, by specifying the TOC name(s) as an optional argument to :toc. For example:

=comment All =formula3 and =Chart2 blocks are (only) included in “Diagrams” TOC...
=config formula3 :toc< Diagrams >
=config Chart2   :toc< Diagrams >

=comment This specific table is included in the default (head) TOC, as well as in the Diagrams and table TOCs...
=begin table :toc< head Diagrams table >
| NW | N | NE |
|  W | * | E  |
| SW | S | SE |
=end table
Code

To insert these other TOCs into a document, use a =place directive at the location where each custom table of contents is required. If you do not want your other TOCs to themselves be listed in the main TOC, add the :!toc option to the placements. For example:

=place toc:Diagrams :!toc :caption<List of Diagrams>
Code

More detail about constraining the TOC levels can be found in the section on placements.

Developer or delta notes§

When a set of source files is related to a project with versions (such as the Raku language), documentation may get out of date, or may only apply to features of a future release.

A delta note can be attached to a block using the :delta metadata option, or specified inline with the Δ< ... > markup instruction. Both the metadata option and the markup instruction have two arguments: the first is the version specification, and the second is an optional text note.

Note: This is an example of a built-in markup code that uses a Unicode Upper character. The mnemonic is Delta, which is commonly used to indicate an incremental component.

The version specification is summarized as follows:

SyntaxMeaning
'*'Any version
v1.2.3specific version
v1.2.3+specific version or later
v1.2.3-specific version or earlier
v1.2.3..v2.3.4inclusive range of versions
v1.2.3^..^v2.3.4exclusive range of versions
v1.2.3..^v2.3.4 or v1.2.3^..v2.3.4semi-inclusive range of versions

The version specification (e.g. v1.2.3) shown here follows the rules of semantic versioning, which is the preferred form for Raku documentation, but is not mandatory. Note that the .. and ^ characters create Raku ranges.

With no extra information about which version should be displayed, a renderer should have a way to include both the string and the version specification.

Alternatively, if there is information about the version to be shown (e.g. from a command-line argument), a renderer should only show blocks that correspond to the version information. A block that does not have an explicit :delta is treated as if it has :delta<*>.

An example is given in the description of the section block

Alternative rendering§

If the metadata option :alt associated with a block has a string value, and an error is encountered when rendering a block, then the value of :alt is rendered in place of the block.

Markup instructions§

Markup instructions provide a way to add inline markup to a piece of text.

All RakuDoc markup instructions consist of a single capital letter followed immediately by a set of single or double angle brackets; Unicode double angle brackets may be used.

Markup instructions may nest other markup instructions.

Some markup instructions only affect their contents and do not have any metadata associated with them. These are sometimes called formatting codes. Other markup instructions have side effects.

Formatting codes§

RakuDoc characterizes formatting codes semantically: markup tags indicate the purpose/function/status/meaning of the marked-up text and renderers may choose any appropriate visual representation to reflect the indicated significance. Thus the B<> formatting code does not indicate that the text must be Bold; it indicates that the text is highly significant: the Basis of a sentence. Although, when this highly significant basis text is rendered, it might very appropriately be rendered in a bold font.

The following markup codes should be made available in all renderers.

Inline markup

Instruction

Mnemonic

HTML equivalent

Markdown equivalent

Basis

B<text>“B for Basis”<strong>text</strong>**text**

Important

I<text>“I for Important”<em>text</em>*text*

Unusual

U<text>“U for Unusual”<ins>text</ins><ins>text</ins>

Weighty

W<text>“W for Weighty”<span style="font-variant: small-caps;">text</span><span style="font-variant: small-caps;">text</span>

Struck out

O<text>“O for Out”<del>text</del>~~text~~

Superscript

H<text>“H for High text”<sup>text</sup><sup>text</sup>

Subscript

J<text>“J for Junior text”<sub>text</sub><sub>text</sub>

Code

C<text>“C for Code”<code>text</code>`text`

The table contains suggested HTML and Markdown equivalents, however a renderer is free to choose other representations.

This syntax does not provide a mechanism to associate metadata options with formatting codes explicitly. It is, however, possible to do this via a =config directive. For example, C<> markup by default does not allow for embedded format codes to be rendered, but an author might want B<> to be allowed. This can be achieved with:

=config C :allow<B>
Code

This mechanism is explained further in the syntax section.

Instructions with side effects§

The following markup instructions, including all customisable instructions, will typically have associated metadata.

To create a link, enclose the target specification and any inline text in L< >. RakuDoc links are more general than the conventional HTML links.

The general syntax is L< LABEL | TARGET >

where the optional label is text that is rendered and the target may include a schema. If the label is omitted, then the target is used as the label. Whitespace on either side of the bar is not significant.

When the bar is present with whitespace as the label, then the renderer must supply a suitable text for the label. It is recommended that the renderer retrieves the description supplied by the URI target itself. Descriptions are common with modern internet protocols, such as HTTPS, but may not be available with older or poorly configured URIs. In such a case, the renderer may fallback to a text version of the URI itself. This can be summarised as follows:

Link specificiation

Displayed text

L< https://example.com >

The URI itself

L< some text | https://example.com>The text before the |
L< | https://example.com>The renderer is free to find a suitable display text, but must in all cases display something. The most "suitable display text" would be the title supplied by the URI target.
Table

When the schema in the URI is missing, then the https:// schema is implied, which means that if the website url is missing as well, the link is to the same host as the document.

The exact name of the resource to which a link is pointing must be used by the renderer. So L< For reference | README.md > or L< text reference | README >

must link to README.md and to README, with the renderer making no assumption about the file format.

However, a collection of RakuDoc source documents may be intended as the base for multiple output formats, such as .html, .md, or .pdf, and so links within the collection may not be able to provide fixed extensions within links. Instead, a group of interlinked RakuDoc documents may need to delegate the selection of an appropriate file format (and extension, if one is needed) to the renderer itself. This is accomplished explicitly using the .* pseudo extension. For example:

L< dealing with the filesystem | type/IO.Path.* >
Code

or for a heading within another resource:

L< getting a directory listing | type/IO.Path.*#routine_dir >
Code

When a .* (“whatever”) extension is encountered by the renderer, if the output format is Markdown, these links would be rendered with .md extensions replacing the .* pseudo-extensions:

[dealing with the filesystem](type/IO.Path.md)
[getting a directory listing](type/IO.Path.md#routine_dir)
Code

Or, if the output format is HTML, these links would be rendered with .html extensions instead:

<a href="type/IO.Path.html">             dealing with the filesystem 
.html#routine_dir"> getting a directory listing </a>
Code

Several schemas are possible:

To refer to a specific section within a webpage, manpage, or RakuDoc document, add the name of that section after the main link, separated by a #. To refer to a section of the current document, omit the external address (i.e. start the target specifier with a #).

A renderer is expected to render a link with a schema as follows:

  • At a minimum, a link like L<rakudoc:ModuleName> is simply rendered as text, to something like: “the ModuleName documentation”, and L<man:appname> to something like: “The appname manpage”. And neither of them attempt to add any kind of actual operational link.
  • At the next level of sophistication, a renderer encountering either link scheme may attempt to shell out a call to raku --doc ModuleName or man appname, and present the results in a pop-up.
  • If the renderer is in a networked environment, the renderer is expected to provide a set of user selectable options that provide links to such documentation, for example, a set of HTML links in a pop-down box. A renderer might also allow users to preconfigure their preferred website(s) for these schemes, perhaps offering rakudoc: links to https://raku.land/ or man: links to https://www.kernel.org/doc/man-pages/ as defaults.

Renderers are not expected to handle all schemas beyond the minimum above. Renderers offering more sophisticated styling or operational links should provide ways to configure schemas, whilst offering reasonable defaults.

Examples§

I<ACM Transactions on Programming Languages and Systems>
is a registered serial publication (L<issn:0164-0925>)

This module implements the standard Unix L<man:find(1)> facilities.

Please forward bug reports to L<mailto:abyss@example.org>

This module needs the L<LAME library|http://www.mp3dev.org/mp3/>.

You could also write the code L<in gibberish|RakuDoc:Acme::Anguish>

Also see: L<man:bash(1)#Compound Commands>,

=defn lexiphania
An unfortunate proclivity for employing grandiloquisms (for example,
words such as "proclivity", "grandiloquism", and indeed "lexiphania").

=defn glossoligation
Restraint of the tongue (voluntary or otherwise)

To treat his chronic L<defn:lexiphania> the doctor prescribed
an immediate L<defn:glossoligation> or, if that proved ineffective,
a complete cephalectomy.
Code

A second kind of link — the P<> or placement link — works in the opposite direction. Instead of directing focus out to another document, it allows you to assimilate the contents of another document into your own.

In other words, the P<> markup instruction takes a URI and (where possible) inserts the contents of the corresponding document inline in place of the code itself.

A URI meets the regex pattern \w+:\S+, where the word characters before : are called the schema. There may not be any explicit whitespace characters in a URI.

P<> markup is handy for breaking out standard elements of your documentation set into reusable components that can then be incorporated directly into multiple documents. For example:

=COPYRIGHT
P<file:/shared/docs/std_copyright.rakudoc>

=DISCLAIMER
P<http://www.MegaGigaTeraPetaCorp.com/std/disclaimer.txt>
Code

might produce:

Copyright

This document is copyright (c) MegaGigaTeraPetaCorp, 2006. All rights reserved.

Disclaimer

ABSOLUTELY NO WARRANTY IS IMPLIED. NOT EVEN OF ANY KIND. WE HAVE SOLD YOU THIS SOFTWARE WITH NO HINT OF A SUGGESTION THAT IT IS EITHER USEFUL OR USABLE. AS FOR GUARANTEES OF CORRECTNESS...DON’T MAKE US LAUGH! AT SOME TIME IN THE FUTURE WE MIGHT DEIGN TO SELL YOU UPGRADES THAT PURPORT TO ADDRESS SOME OF THE APPLICATION’S MANY DEFICIENCIES, BUT NO PROMISES THERE EITHER. WE HAVE MORE LAWYERS ON STAFF THAN YOU HAVE TOTAL EMPLOYEES, SO DON’T EVEN *THINK* ABOUT SUING US. HAVE A NICE DAY.

The P<> markup code can also be specified with an optional display text, which will be rendered if the renderer cannot find or access the external data source for the placement link. For example:

=COPYRIGHT
P<The document is copyright. | file:/shared/docs/std_copyright.rakudoc>

=DISCLAIMER
P<NO WARRANTY. NONE. NIL. NADA. | http://www.MegaGigaTeraPetaCorp.com/std/disclaimer.txt>
Code

If the filesystem or internet is inaccessible, this might produce:

Copyright

This document is copyright.

Disclaimer

NO WARRANTY. NONE. NIL. NADA.

If a renderer cannot find or access the external data source for a placement link, and the placement link does not have an alternative display text, it must issue a warning and render the URI directly in some form, possibly as an outwards link. For example:

Copyright

See: file:/shared/docs/std_copyright.rakudoc

Disclaimer

You can use any of the following URI forms (see #Links) in a placement link:

  • http: and https:
  • file:
  • toc:
  • index:
  • semantic:
  • citations:

TOC placements§

The toc: form is a special pseudo-scheme that inserts a table of contents (TOC) in place of the P<> code. After the colon, there must be a string of one or more non-blank characters, called the specification.

There is at least one set of TOC data collected by the renderer from the =head and semantic blocks, but as described above, custom TOC names can be created.

The specification is used to select the TOC data set and to constrain how much data is rendered. When the specification is a *, a digit, or a range, then the default or head TOC is implied. For example, to place a table of contents listing only first- and second-level headings:

P<toc:1..2 >
Code

To place a table of contents that lists the first four levels of headings:

P<toc:1..4 >
Code

In order to include the whole default (or head) table of contents, use toc:*.

When toc: is followed by the name of TOC and optionally a comma, then *, number, or range, the level restrictions are applied to the named TOC.

Valid specs would be:

  • * (all levels of the default ToC)
  • 1..4 (levels 1-4 of the default ToC)
  • Diagrams (meaning all levels of the Diagrams ToC)
  • Diagrams,* (all levels of the Diagrams ToC)
  • table,1..4 (levels 1..4 of the table ToC)

Invalid specs:

  • formula, (missing levels specifier)
  • ,* (missing TOC name)

A document may have as many P<toc:...> placements as necessary.

Index placements§

The index:* form is a special pseudo-scheme that inserts an index table in place of the P<> code.

Semantic block placements§

The semantic:NAME form places the NAME semantic block at the position of the P<> instruction.

Alias placement§

A variation on the placement instruction is the A<> instruction, which is replaced by the contents of the named alias or object specified within its delimiters. For example:

=alias PROGNAME    Earl Irradiatem Eventually
=alias VENDOR 4D Kingdoms
=alias TERMS_URL
L<http://www.4dk.com/eie>

The use of
A<PROGNAME> is subject to the terms and conditions
laid out by
A<VENDOR>, as specified at A<TERMS_URL>.
Code

Any Raku object available after the CHECK phase, such as an object that starts with a sigil, is available within an alias placement. Unless the object is already a string type, it is converted to a string during document-generation by implicitly calling .raku on it.

So, for example, a document can refer to its own filename (as A<$?FILE>), or to the subroutine inside which the specific RakuDoc is nested (as A<&?ROUTINE>), or to the current class (as A<$?CLASS>). Similarly, the value of any program constants defined with sigils can be easily reproduced in documentation:

# Actual code...
constant Num $GROWTH_RATE = 1.6;

=begin rakudoc
=head4 Standard Growth Rate

The standard growth rate is assumed to be
A<$GROWTH_RATE>.
=end rakudoc
Code

Non-mutating method calls on these objects are also allowed, so a document can reproduce the surrounding subroutine’s signature (A<&?ROUTINE.signature>) or the type of a constant (A<$GROWTH_RATE.WHAT>).

See Aliases for further details of the aliasing macro mechanism.

Inline definitions§

A D<> formatting code marks a piece of text as being the “inline definition” of a term. That is: it’s like a =defn block, but it’s not a list item; it’s just part of the regular text. Well-written documentation often includes sentences/paragraphs that introduce a new term, and define it. Typically we want to visually distinguish those newly defined terms, and to be able to link back to the paragraph where they’re defined.

For example:

There ensued a terrible moment of D<coyotus interruptus>: a brief
suspension of the effects of gravity, accompanied by a sudden
to-the-camera realization of imminent downwards acceleration.
Code

The contents of the D<> represent the term being defined, the location of the D<> implies a link target location, and the paragraph containing the D<> suggests a suitable pop-up definition of the term (if a renderer supports such).

The definition term in a D<> is rendered distinctly (typically in bold italics), and the D<> sets up a link target to that term, and possibly a pop-up for the corresponding L<> link to display the entire paragraph in which the D<> appeared. For this reason, the term is rendered verbatim, including any attempted markup codes.

In other words, when rendered to HTML, a D<term being defined> would be translated to something like:

...a term being defined would be...
Code

And a L<defn:term being defined> link would be translated to something like:

...a term being defined link would be...
Code

A definition may be given synonyms, which are specified after a vertical bar and separated by semicolons:

A D<formatting code|formatting codes;formatters> provides a way
to add inline markup to a piece of text.
Code

Space-preserving text§

Any text enclosed in an S<> code is formatted normally, except that every whitespace character in it — including any newline — is preserved. These characters are also treated as being non-breaking (except for the newlines, of course). For example:

The emergency signal is: S<
dot dot dot dash dash dash dot dot dot
>.
Code

would be formatted like so:

The emergency signal is:
dot dot dot dash dash dash dot dot dot.
Code

rather than:

The emergency signal is: dot dot dot dash dash dash dot dot dot.
Code

Comments§

A comment is text that is never rendered.

To create a comment enclose it in Z< >:

Raku is awesome Z<Of course it is!>
Code

This would be rendered as:

Raku is awesome

Notes§

Notes are ancillary information that may be rendered as footnotes or sidenotes or pop-up notes, depending on the renderer and environment.

To create a note, enclose it in N< >

Raku is multi-paradigmatic N<Supporting Procedural, Object Oriented, and Functional programming>
Code

Which produces:

Raku is multi-paradigmatic [ 1 ]

Keyboard input§

To flag text as keyboard input enclose it in K< >

=output Enter your name: K<John Doe>
Code

Which is rendered like so:

Enter your name: John Doe
Output

Replaceable§

The R<> markup instruction specifies that the contained text is a replaceable item, a placeholder, or a metasyntactic variable. It is used to indicate a component of a syntax or specification that should eventually be replaced by an actual value. For example:

The basic C<ln> command is: C<ln> R<source_file> R<target_file>
Code

This is rendered like so:

The basic ln command is: ln source_file target_file

Terminal output§

To flag text as terminal output enclose it in T< >

=input T<Enter your name:> John Doe
Code

Which would be rendered:

Enter your name: John Doe
Input

Unicode and HTML references§

Unicode codepoint names or numbers may be included in a RakuDoc document by enclosing them in E< >. When E< > encloses a number, it is treated as the Unicode value for the code point using binary, octal, decimal, or hexadecimal numbers specified in the Raku notations for explicitly based numbers. Numbers without an explicit base, as per Raku convention, are decimal.

For example, each of the following:

Raku makes considerable use of the E<171> and E<187> characters.

Raku makes considerable use of the
E<0b10101011> and E<0b10111011> characters.

Raku makes considerable use of the
E<0o253> and E<0o273> characters.

Raku makes considerable use of the
E<0d171> and E<0d187> characters.

Raku makes considerable use of the
E<0xAB> and E<0xBB> characters.
Code

will yield the same rendering:

Raku makes considerable use of the « and » characters.

It is also possible to specify Unicode codepoint names. Multiple codepoints separated by , will be considered as a single grapheme. So:

E<LEFT-POINTING DOUBLE ANGLE QUOTATION MARK>
E<REGIONAL INDICATOR SYMBOL LETTER U, REGIONAL INDICATOR SYMBOL LETTER A> Ukraine
E<RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK>
Code

will be rendered as:

« 🇺🇦 Ukraine »

Since emojis are graphemes that can be described by Unicode, E< > will also generate emojis. For example:

E<WHITE SMILING FACE> Smiling face
Code

will generate:

☺ Smiling face

Alternatively, HTML5 character references may be used. For example:

Raku makes considerable use of the E<laquo> and E<raquo> characters.
Code

also yields: Raku makes considerable use of the « and » characters.

The E<> markup may be used for a list of characters separated by ;

Raku code often contains the E<0xff62;0xff63> bracketing characters to avoid using quotes.
Code

This would yield: Raku code often contains the 「」 bracketing characters to avoid using quotes.

The E<> code can also be specified with an alternate display text (before the entity specification and separated from it by a |). When an alternate text is specified, it is used if the specified entity cannot be represented by the renderer (e.g. if the renderer only supports ASCII).

For example:

Raku makes considerable use of the E<left- |laquo> and E<right-double-angle |raquo> characters.

Raku code often contains the E<left- and right-corner |0xff62; 0xff63> bracketing characters
to avoid using quotes.
Code

An ASCII-only renderer would then render those like so:

Raku makes considerable use of the left- and right-double-angle characters.

Raku code often contains the left- and right-corner bracketing characters to avoid using quotes.

Verbatim text§

The V<> markup instruction treats its entire contents as being verbatim, disregarding every apparent markup instruction within it. For example:

The B<V< V<> >> markup instruction disarms other codes
such as
V< I<>, C<>, B<>, and M<> >.
Code

Note, however that the V<> code only changes the way its contents are parsed, not the way they are rendered. That is, the contents are still wrapped and formatted like plain text, and the effects of any markup instructions surrounding the V<> code are still applied to its contents. For example the previous example is rendered as:

The V<> markup instruction disarms other codes such as I<>, C<>, B<>, and M<>.

Note that C<> also by default keeps its contents verbatim; the difference between C<> and V<> is that C<> always renders its contents to show that they are code (e.g. in a fixed-width font or a distinctive style), whilst V<> uses the default text presentation for the current block.

The default behaviors of both V<> and C<> can be changed using a =config directive. For example:

=config C :allow< B I U >
=config V :allow< N L X >
Code

Indexing terms§

Anything enclosed in an X<> code is an index entry. The contents of the code are both formatted into the document and used as the (case-insensitive) index entry:

An X<array> is an ordered list of scalars indexed by number,
starting with 0. A X<hash> is an unordered collection of scalar
values indexed by their associated string key.
Code

You can specify an index entry in which the indexed text and the index entry are different, by separating the two with a vertical bar:

An X<array|arrays> is an ordered list of scalars indexed by number,
starting with 0. A X<hash|hashes> is an unordered collection of
scalar values indexed by their associated string key.
Code

In the two-part form, the presentation text comes before the bar, and the actual index entry comes after the bar and is case-sensitive.

You can specify hierarchical index entries by separating indexing levels with commas:

An X<array|arrays, definition of> is an ordered list of scalars
indexed by number, starting with 0. A X<hash|hashes, definition of>
is an unordered collection of scalar values indexed by their
associated string key.
Code

You can specify two or more entries for a single indexed text, by separating the entries with semicolons:

A X<hash|hashes, definition of; associative arrays>
is an unordered collection of scalar values indexed by their
associated string key.
Code

The indexed text can be empty, creating a "zero-width" index entry:

X<|puns, deliberate>This is called the "Orcish Maneuver"
because you "OR" the "cache".
Code

Markup extras§

In order to allow for renderers to add customisable markup code, whilst at the same time abiding by the naming rules, the markup instruction M< visible text | list-of-strings > is defined as a built-in markup instruction.

The visible text is shown in the text, and may be blank.

The list-of-strings is specified in the same way as the X<> markup instruction for indexing. The semantics of the string is defined by the renderer. If a renderer does not recognize the list of strings, it is expected that the visible text will be rendered and marked in some way (such as with a border, or highlighted), and at least the first string will be made available in the same way as the D<> markup instruction. It is also recommended that the first string is used by the renderer to identify the functionality being provided.

For example, suppose a RakuDoc document is used to create part of a website in which a button is to be styled that accesses the API of a payment service (e.g. 'PayMe'). A developer can then create some functionality according to the rules of a RakuDoc renderer, and present it to the service point. In an HTML document, this might be coded as a <button class="PayMeApp" data-token="vendor-id" data-price="$0.99"> with a specific class and structure. The RakuDoc instruction might then be:

To sample this marvellous libation M<order now by PayMeApp|PayMeApp; vendor-id; $0.99>
Code

An HTML renderer would the convert this to, for example,

<p>To sample this marvellous libation
    <button class="PayMeApp" data-token="vendor-id" data-price="$0.99">
    order now by PayMeApp
    </button>
</p>
Code

Implementor considerations§

RakuDoc is intended to be a markup language for text oriented documentation, which will be rendered into output formats such as HTML or epub. It is expected that there may be several modules that will render RakuDoc.

In order for a renderer to be compliant with the specification, it must:

  • render in some way all the built-in RakuDoc blocks and markup codes
  • where fallbacks have been specified, only the minimum fallback need be rendered
  • recognize and apply all the directives
  • provide some mechanism for a user to add custom blocks and markup codes
  • signal rendering errors in some way, unless such warnings have been explicitly silenced
  • rendering errors include unknown block/code types, as well as the use of unimplemented built-ins
  • the following signalling mechanisms are acceptable approaches to fulfil this requirement:
  • writing error messages to STDERR
  • writing error messages to a log file
  • appending error messages to the end of the rendered output in a distinctive style that indicates they are errors
  • rendering unhandled blocks or codes inline (in a distinctive style) and providing the associated error message in a pop-up that activates on hover or mouse-click

Licence§

Artistic-2.0

Credits§

  • Damian Conway (@thoughtstream)
  • Richard Hainsworth (@finanalyst)
  • Elizabeth Mattijen (@lizmat)
  • Aliaksandr Zahatski (@zag)

Footnotes

1 |^| Supporting Procedural, Object Oriented, and Functional programming