RakuDoc is a markup language with simple instructions for simple tasks and more complex structures to suit larger projects. There is a clear distinction between documenting intended to help maintain and develop the software, and the visually presentations needed by a newcomer to understand how to use software.
SYNOPSIS§
Consider the two ways in which documentation is used.
Case 1: You are writing internal documentation to aid software design§
unit ;#| a variable to hold number of peoplehas ;#| data that is initially provided by default, but will be overwrittenhas = ;... # code=finishdefault data string for a new participant
A RakuDoc compliant editor or Integrated Design Environment will pick up the text following #|
and put it into a pop-up menu whenever you select (e.g. by hovering over) a use of $.participants
.
The =finish
statement is the last piece of code. Everything after it is treated as a string and placed in the $=finish
variable.
There are other possibilities described below.
Case2: You are writing external documentation to accompany some software§
Consider the following short description:
=begin rakudoc =TITLE Tutorial about Flavorizing =SUBTITLE A short tutorial on Flavorizing your quarks =head1 Starting out In the section you will learn about how to add flavors to quarks produced by the I<Imagiton>. It goes without saying that these techniques should B<NOT> be carried out without a precocious child nearby; they will strain the imagination of an ossified adult. =head2 What is a flavour It is well-known (see the L<Wikipedia article|https://en.wikipedia.org/wiki/Flavour_(particle_physics)> that quarks N<a quark is a constituent of a hadron> come in six flavors, for example: =item Up =item Bottom =item Charm Z< Lots more text > =end rakudoc
To indicate that all of the markup above is not Raku code, it is enclosed in a block labelled rakudoc. This is an example of the delimited form of the rakudoc block (so named because it is specified between =begin
and =end
directives).
The =TITLE
, =SUBTITLE
, and =SYNOPSIS
are semantic blocks containing standard information that can be searched by other tools. For all other purposes, they can be considered to the same as =head1
blocks.
A =head1
block begins a top-level heading. The =head2
is a second level heading. These are examples of the abbreviated form of RakuDoc blocks. Any non-empty text lines following a heading specifier are collectively treated as the text of the heading.
The =item
components are abbreviated blocks with text entries for a list. There is no need to start or stop a list explicitly; the renderer will place each consecutive =item
in a list. The first non-=item
paragraph or block will end the list.
Within the text there are several examples of inline markup instructions, which have the form Upper Unicode character < > . In the example above, we used: I B N L Z
. These are for Important, Basis, Note (a footnote), Link, and Zero (a comment) markup.
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.
A file with mainly RakuDoc source has a file extension .rakudoc.
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 a running 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 recognise along with some expected rendering behaviors for text-oriented renderers. "Expected behaviors" means that a renderer should approximate the behavior 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.
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 B<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 B<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.
=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 ends ambient code and is followed by text
=alias 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
=config 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 ÿÿ<var>ÿÿBLOCK_TYPEÿÿ</var>ÿÿ ÿÿ<var>ÿÿCONFIG OPTIONSÿÿ</var>ÿÿ = ÿÿ<var>ÿÿOPTIONAL EXTRA CONFIG OPTIONSÿÿ</var>ÿÿ
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>This configures the
C<>
markup instruction to recognize nestedB<>
andI<>
markup instructions (both of which would otherwise be treated as verbatim within aC<>
instruction).To avoid ambiguities Naming rules are applied to blocks and markup instructions.
=place specifies a source of information that is to be placed in the current block. The general syntax of =place is
=place=
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" 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
The general syntax is:
=begin ÿÿ<var>ÿÿBLOCK_TYPEÿÿ</var>ÿÿ ÿÿ<var>ÿÿOPTIONAL CONFIG INFOÿÿ</var>ÿÿ = ÿÿ<var>ÿÿOPTIONAL EXTRA CONFIG INFOÿÿ</var>ÿÿ ÿÿ<var>ÿÿBLOCK CONTENTSÿÿ</var>ÿÿ =end ÿÿ<var>ÿÿBLOCK_TYPEÿÿ</var>ÿÿ
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. For example, to specify apara
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.
The general syntax is:
=for ÿÿ<var>ÿÿBLOCK_TYPEÿÿ</var>ÿÿ ÿÿ<var>ÿÿOPTIONAL CONFIG INFOÿÿ</var>ÿÿ = ÿÿ<var>ÿÿOPTIONAL EXTRA CONFIG INFOÿÿ</var>ÿÿ ÿÿ<var>ÿÿBLOCK DATAÿÿ</var>ÿÿ
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 directive line) is considered the content of the block. For example, to specify apara
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.
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 (eg, Verbatim blocks).
Markup instruction syntax§
The general syntax of a markup instruction is
<Instruction><opening marker><content>|<meta list><closing marker>
<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 entityE<0x00AB>
)<content>
This is a string that does not contain the
|
character (i.e. Unicode entityE<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 entityE<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>.
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 Raku option pairs. The following are 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.
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 header block
Directives§
Directives are similar in form to 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.
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>
This would produce:
The use of Earl Irradiatem Evermore is subject to the terms andconditions laid out by 4D Kingdoms Inc, as specified at:=item=item=item
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>
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<ÿÿ<strong>ÿÿthis program |ÿÿ</strong>ÿÿ PROGNAME> is subject to the terms and conditions laid out by A<ÿÿ<strong>ÿÿour company |ÿÿ</strong>ÿÿ VENDOR>, as specified at: A<ÿÿ<strong>ÿÿ(Please visit our website) |ÿÿ</strong>ÿÿ TERMS_URLS>
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.
Config§
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 labeled 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:
ÿÿ<strong>ÿÿ=config code :delta(v2.3.2+, 'oFun enhancements') ÿÿ</strong>ÿÿ =code method droll { say 'what a cool operator' } =code method drool { say 'what a slob' } =code method drill { say 'keep up' }
Within the same block scope, eg., 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 code :allow< B C I > # The default metadata for any code block is now: :allow< B C I > =begin code # In this paragraph B<this phrase will be shown as basis (possibly in bold font)> # and I<this will be shown as important (possibly italics)>. # But other markup such as R<placeholder> and K<input> will be shown verbatim. # # Because no :lang<> option was configured, the language for the block # is the universal default: :lang<Raku> =end code =config code :lang<RakuDoc> # The default metadata for any code block is now: :allow< B C I > :lang<RakuDoc> =begin code :allow< R K > # Here the explicit :allow on the block overrides the default :allow from the =config # so B<markup> and I<markup> are shown verbatim, while R<this will be shown as a replacement text>. # # There is no explicit :lang on the code block, # so the language for the block is the configured default: :lang<RakuDoc. =end code =code # Now we're back to B<basic> and I<important>, but not R<placeholder> or K<input> =begin section =config code :allow< R K > # The default metadata for any code block is now: :allow< R K > :lang<RakuDoc> =begin code :lang<JavaScript> // The format codes R and K are activated by default, // but B<> C<> I<> markup will be shown verbatim // // The language has been explicitly set to Javascript // (important if syntax highlighting is turned on), // so the configured default language (RakuDoc) is overridden =end code =end section
There is more discussion of =config
in the context of Formatting codes.
Document termination§
The =finish
directive indicates the end of 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 = from-json( $=finish );say .raku;# more lines of code=finish
This will generate the following output:
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 external sources§
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:
Schema | Where to look for the resource |
---|---|
C<http(s):> | Look on the web |
C<file:> | Look on the local filesystem |
C<rakudoc:> | Look in the usual places for Raku documentation |
C<man:> | Look via a local man(1) |
C<defn:> | Look in the current document |
Meanwhile, the kind of content being placed is inferred from the final extension of the URL. For example:
Extension | How to treat the contents |
---|---|
C<.txt> | Render the contents as plaintext |
C<.rakudoc> | Render the contents as RakuDoc |
C<.html> | Render the contents as XHTML |
C<.md> | Render the contents as Markdown |
C<.json> | Render the contents as JSON |
C<.jpg> | Render the contents as an image |
C<.mp4> | Render 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
...then the type of content (and hence rendering) may be inferred from the schema:
Schema | Inferred content type if no final extension |
---|---|
C<http(s):> | XHTML |
C<file:> | plaintext |
C<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/camelia-logo.png :caption<Raku's mascot> :alt<A multicoloured butterfly>
Code-oriented RakuDoc§
The following RakuDoc components are primarily intended for use when editing 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 character, 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:
sub duel( #= Magicians only, no mortals.Magician , #= first magicianMagician , #= second magician)say Magician.WHY; # OUTPUT: «Base class for magicians»say .WHY.leading; # OUTPUT: «Fight mechanics»say .WHY.trailing; # OUTPUT: «Magicians only, no mortals.»say .signature.params[0].WHY; # OUTPUT: «first magician»say .signature.params[1].WHY; # OUTPUT: «second magician»
These declarations can extend to several lines. For example:
* Numbers turn into strings* Regexes operate on said strings* C<with> topicalizes and places result into)sub search-in-seq* topic* decont operator»( Int , Int )
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 , #= the first CLI parameterInt :, #= an integer to indicate output, 0 = no output)
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>;
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: ', [1];=data Industry=data Patience=data Humility
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 header #this line is now ambient code and so must be specified as a comment
A rakudoc
block reverses this assumption.
#start of file my $text; # ambient code =begin rakudoc =head this is some text this line continues the header this line is not ambient code and so it will be treated as an ordinary paragraph =end rakudoc # this line is now ambient code
Files that are intended to contain text-oriented documentation alone should be entirely 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.
Headings§
Headings can be defined using =headN
, where N is greater than zero (e.g. =head1
, =head2
, etc.). =head
is an alias for =head1
.
=head1 A top level heading =head2 A second level heading =head3 A third level heading
Numbered headings§
You can specify that a heading is numbered using the =numhead
block. For example:
=numhead1 The Problem =numhead1 The Solution =numhead2 Analysis =head3 Overview =head3 Details =numhead2 Design =numhead1 The Implementation
which would produce:
1. The Problem 2. The Solution 2.1. Analysis Overview Details 2.2. Design 3. The Implementation
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
should produce something like:
2.3.8.6.1.9. The Rescue of the Kobayashi Maru
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.
For example, suppose the following RakuDoc text was included in a source file
=begin section :delta(v2.3.2-, 'removed due to conflict with chancellors') =head2 role fool This role is especially important in authoritarian kingdoms to remind kings of their humanity. =end section
If a user indicates to a renderer that they wish to view documentation valid today, which corresponds (for example) to v3.1.1
then, because v3.1.1
is after v2.3.2
, the section above – including the nested =head2
block and the following plain paragraph – would not be rendered.
If however, a user indicates they wish to view documentation for v2
, the renderer would render the section above, including an indication the section will be removed in v2.3.2
.
Document scope§
A =begin rakudoc
declaration (or equivalently a =begin pod
) also defines a new scope, and also has the effect that code following it is not considered Raku code.
An =end rakudoc
will return scope to the ambient code. This also means that rakudoc
blocks cannot be nested, while section
blocks may be nested.
The first =begin rakudoc
declaration in a document starts the RakuDoc scope of the document. Metadata following the first such declaration are made available to all blocks in the document.
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 mark-up 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:
=head1 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
Ordinary paragraphs do not require an explicit marker or delimiters (within a rakudoc
block).
Alternatively, there is also an explicit =para
marker 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.
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
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 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
...which would produce:
We are all of us in the gutter,
but some of us are looking at the stars!
-- Oscar Wilde
Nesting blocks can contain any other kind of block, including implicit paragraph and code blocks. Note that the relative physical indentation of the nested blocks plays no role in determining their ultimate indentation in the final rendering. The preceding example could equally have been specified:
=begin nested 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
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, mark-up, 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:= 1 * code('block');.is_specified(:by<indenting>);
Implicit code blocks may be used elsewhere with some caveats.
There is also an explicit =code
block (which can be specified within any block type, not just =rakudoc
, =item
, etc.):
The C<loud_update()> subroutine adds feedback:=begin codesub loud_update ($who, $status) {say "$who -> $status";silent_update($who, $status);}=end 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 should offer the option to use syntax highlighting to render code in a code block, perhaps by specifying a :syntax-highlighting
metadata option for code blocks. By default, a renderer will not change the contents of a code block, but see the caveat when :allow
is used.
The :lang< ... >
metadata option may be used to specify that the contents of a given =code
block are in a given language. If the specified language is unknown to a renderer, it may choose either to default to Raku syntax highlighting, or may apply some other heuristic.
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 mark-up 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
In this example, the two embedded K<...>
sequences would be recognized as inline mark-up 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 markup instructions 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 {'Hello ';'The I format is not recognised';}=end code
This would be rendered:
sub demo
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
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
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, lower-level items should not be specified inside higher-level 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
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.
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 =item
N 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 =item
N, for example
The project originally consisted of five phases, of which two are already complete and two have been abandoned: =for item ÿÿ<strong>ÿÿ:bullet< E<BALLOT BOX WITH CHECK> >ÿÿ</strong>ÿÿ Investigate existing solutions =for item ÿÿ<strong>ÿÿ:bullet< E<BALLOT BOX WITH CHECK> >ÿÿ</strong>ÿÿ Define a minimal initial feature set =for item ÿÿ<strong>ÿÿ:bullet< E<BALLOT BOX> >ÿÿ</strong>ÿÿ Implement this minimal set of features =for item ÿÿ<strong>ÿÿ:bullet< E<BALLOT BOX WITH X> >ÿÿ</strong>ÿÿ Secure 100 million in venture capital =for item ÿÿ<strong>ÿÿ:bullet< E<BALLOT BOX WITH X> >ÿÿ</strong>ÿÿ Abscond to the Bahamas with the cash
... would produce something like a list with checkboxes, thus:
The project originally consisted of five phases, of whichtwo 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 ÿÿ<strong>ÿÿ:bullet< E<Heavy Check Mark> >ÿÿ</strong>ÿÿ Investigate existing solutions =for item ÿÿ<strong>ÿÿ:bullet< E<Heavy Check Mark> >ÿÿ</strong>ÿÿ Define a minimal initial feature set =for item ÿÿ<strong>ÿÿ:bullet< E<Anticlockwise Downwards And Upwards Open Circle Arrows> >ÿÿ</strong>ÿÿ Implement this minimal set of features =for item ÿÿ<strong>ÿÿ:bullet< E<prohibited sign> >ÿÿ</strong>ÿÿ Secure 100 million in venture capital =for item ÿÿ<strong>ÿÿ:bullet< E<prohibited sign; palm tree> >ÿÿ</strong>ÿÿ Abscond to the Bahamas with the cash
... 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 ÿÿ<strong>ÿÿ=config item1 :bullet< E<Earth Globe Europe-Africa> > ÿÿ</strong>ÿÿ ÿÿ<strong>ÿÿ=config item2 :bullet< E<Hand with Index and Middle Fingers Crossed> > ÿÿ</strong>ÿÿ The major sources of sustainable energy are: =item1 wind =item1 hydroelectric =item1 solar =item1 geothermal =item1 fusion =item2 (eventually) =end section
...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 unrecognised 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
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 `:html-ordered` that leverages 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
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.) only resets to 1 when a higher-level item's numbering either resets or increments.
To prevent a =numitemN
from resetting after a non-item block, you can specify the :continued
option:
=numitem1 Retreat to remote Himalayan monastery =numitem1 Learn the hidden mysteries of space and time I<????> =for numitem1 :continued Prophet!
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 second =numitemN
block is specified with a :continued
option the numbering of that second block does not reset, but increments instead (i.e. as if there had been no intervening non-numbered block).
The :continued
option has no effect on any higher- or lower-numbered =numitem
blocks that are currently active in the same scope. That is: a =for numitemN :continued
causes the numbering of every active =numitemZ
block (where Z > N) to reset to 1, and the numbering 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: =itemN
and/or =numitemN
instructions) has 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 :continued
on 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 in HTML.
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 Happy When you're not blue. =defn Blue When you're not happy.
...will be rendered as:
- Happy
- When you're not blue.
- Blue
- When you're not happy.
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 a =numdefn
instruction is associated with a :continued
metadata option, then the preceding definition list's inherent numeration is preserved and continued.
For example:
=numdefn AAA first letters =numdefn BBB second letters A normal para =numdefn XXX ending letters =numdefn YYY finals
will yield something like:
1. ÿÿ<strong>ÿÿAAAÿÿ</strong>ÿÿ first letters 2. ÿÿ<strong>ÿÿBBBÿÿ</strong>ÿÿ second letters A normal paragraph 1. ÿÿ<strong>ÿÿXXXÿÿ</strong>ÿÿ ending letters 2. ÿÿ<strong>ÿÿYYYÿÿ</strong>ÿÿ finals
In order to continue a list, an explicit :continued
is needed, such as:
=numdefn AAA first letters =numdefn BBB second letters A normal para =for numdefn ÿÿ<strong>ÿÿ:continuedÿÿ</strong>ÿÿ XXX ending letters =numdefn YYY finals
will yield something like
1. ÿÿ<strong>ÿÿAAAÿÿ</strong>ÿÿ first letters 2. ÿÿ<strong>ÿÿBBBÿÿ</strong>ÿÿ second letters A normal paragraph 3. ÿÿ<strong>ÿÿXXXÿÿ</strong>ÿÿ ending letters 4. ÿÿ<strong>ÿÿYYYÿÿ</strong>ÿÿ finals
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 require every =numdefn
to be specified with a :continued
option. Or the writer could simply pre-configure every =numdefn
within the scope, as follows:
=config numdefn :continued
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 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 column separator type is allowed in a single line, but different lines are allowed to use different visible column separator types (though that style is not recommended). Using a mixture of visible and non-visible column separator types in a 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
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
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
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.
Valid tables§
Following are examples of valid tables.
=begin 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 =end table
=table Constants 1 Variables 10 Subroutines 33 Everything else 57
=for table mouse | mice horse | horses elephant | elephants
=table Animal | Legs | Eats ======================= Zebra + 4 + Cookies Human + 2 + Pizza Shark + 0 + Fish
=table Superhero | Secret | | Identity | Superpower ==============|=================|================================ The Shoveller | Eddie Stevens | King Arthur's singing shovel
=begin table 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
=table X | O | ---+---+--- | X | O ---+---+--- | | X
=table X O =========== X O =========== X
=begin table foo bar =end table
Invalid tables§
Following are examples of invalid tables, and they should trigger an unhandled exception during parsing.
Mixed column separator types in the same row are not allowed:
=begin table r0c0 + r0c1 | r0c3 =end table
Mixed visual and whitespace column separator types in the same table are not allowed:
=begin table r0c0 + r0c1 | r0c3 r1c0 r0c1 r0c3 =end table
Two consecutive interior row separators are not allowed:
=begin table r0c0 | r0c1 ============ ============ r1c0 | r1c1 =end table
Unexpected tables§
Following are examples of valid tables that are probably intended to be two columns. However, the columns in these examples are not aligned well, so each will parse as a single-column table.
Unaligned columns with WS column separators:
Notice the second row has the two words separated by only one WS character, while it takes at least two adjacent WS characters to define a column separation. This is a valid table but will be parsed as a single-column table.
=begin table r0c0 r0c1 r1c0 r0c1 =end table
Unaligned columns with visual column separators:
Notice the second row has the two words separated by a visible character ('|') but the character is not recognized as a column separator because it doesn't have an adjacent WS character on both sides of it. Although this is a legal table, the result will not be what the user intended because the first row has two columns while the second row has only one column, and it will thus have an empty second column.
=begin table r0c0 | r0c1 r1c0 |r0c1 =end table
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).
Subsequent =cell
blocks start filling that grid in, 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)
, :col-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)
Let’s see how it works...
The following RakuDoc specification:
=begin table =row :header =for cell :row-span(2) Date =for cell :column-span(3) Samples =for cell :row-span(2) Mean =row :header =cell I<Sample 1> =cell I<Sample 2> =cell I<Sample 3> =row =column =cell 2023-03-08 =cell 2023-04-14 =cell 2023-06-23 =column =cell 0.4 =cell 0.8 =cell 0.2 =column =cell 0.1 =cell 0.6 =cell 0.9 =column =cell 0.3 =cell 0.5 =cell 0.0 =column =cell 0.26667 =cell 0.63333 =cell 0.36667 =row =for cell :label Mean: =cell 0.46667 =cell 0.53333 =cell 0.26667 =cell 0.42222 =end table
... produces the following table:
Date | Samples | Mean | ||
---|---|---|---|---|
Sample 1 | Sample 2 | Sample 3 | ||
2023-03-08 | 0.4 | 0.1 | 0.3 | 0.26667 |
2023-04-14 | 0.8 | 0.6 | 0.5 | 0.63333 |
2023-06-23 | 0.2 | 0.9 | 0.0 | 0.36667 |
Mean: | 0.46667 | 0.53333 | 0.26667 | 0.42222 |
Let’s examine how that specification creates that layout, step by step. Note that, in the following diagram, the various symbols have these meanings:
┌───┐│ │ : An empty table cell└───┘┌───┐│ → │ : The empty cell at ; is currently "across"└───┘┌───┐│ ↓ │ : The empty cell at ; is currently "down"└───┘┌───┐│+++│ : The most recently filled cell└───┘┌───┐│###│ : A previously filled cell└───┘
And now the step-by-step explanation:
=begin table ┌───┬───┬───┬───┬───┬───┬┈┈│ → │ │ │ │ │ │(Create a new table grid ├───┼───┼───┼───┼───┼───┼┈┈Default $POS is [0,0] │ │ │ │ │ │ │Default $DIR is across) ├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=row :header ┌───┬───┬───┬───┬───┬───┬┈┈│ → │ │ │ │ │ │(Previous action was not =cell ├───┼───┼───┼───┼───┼───┼┈┈So set $DIR to "across" │ │ │ │ │ │ │and don't change $POS) ├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=for cell :row-span(2) ┌───┬───┬───┬───┬───┬───┬┈┈Date │+++│ → │ │ │ │ ││+++│───┼───┼───┼───┼───┼┈┈(Fill in 1x2 cells │+++│ │ │ │ │ │starting from $POS ├───┼───┼───┼───┼───┼───┼┈┈Then move $POS to │ │ │ │ │ │ │first empty cell ├───┼───┼───┼───┼───┼───┼┈┈in $DIR direction) │ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=for cell :column-span(3) ┌───┬───────────┬───┬───┬┈┈Samples │###│+++++++++++│ → │ ││###├───┬───┬───┼───┼───┼┈┈(Fill in 3x1 cells │###│ │ │ │ │ │starting from $POS ├───┼───┼───┼───┼───┼───┼┈┈Then move $POS to │ │ │ │ │ │ │first empty cell ├───┼───┼───┼───┼───┼───┼┈┈in $DIR direction) │ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=for cell :row-span(2) ┌───┬───────────┬───┬───┬┈┈Mean │###│###########│+++│ → ││###├───┬───┬───┤+++│───┼┈┈(Fill in 1x2 cells │###│ │ │ │+++│ │starting from $POS ├───┼───┼───┼───┼───┼───┼┈┈Then move $POS to │ │ │ │ │ │ │first empty cell ├───┼───┼───┼───┼───┼───┼┈┈in $DIR direction) │ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=row :header ┌───┬───────────┬───┬───┬┈┈│###│###########│###│ │(Find the next row at or │###├───┬───┬───┤###│───┼┈┈below the current $POS │###│ → │ │ │###│ │that has an empty cell ├───┼───┼───┼───┼───┼───┼┈┈to the left of $POS, then │ │ │ │ │ │ │move $POS to the leftmost ├───┼───┼───┼───┼───┼───┼┈┈cell on that row, and set │ │ │ │ │ │ │$DIR to "across") ├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=cell Sample 1 ┌───┬───────────┬───┬───┬┈┈│###│###########│###│ │(Fill in 1x1 cell at $POS │###├───┬───┬───┤###│───┼┈┈then move $POS to │###│+++│ → │ │###│ │the first empty cell ├───┼───┼───┼───┼───┼───┼┈┈in $DIR direction) │ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=cell Sample 2 ┌───┬───────────┬───┬───┬┈┈│###│###########│###│ │(Fill in 1x1 cell at $POS │###├───┬───┬───┤###│───┼┈┈then move $POS to │###│###│+++│ → │###│ │the first empty cell ├───┼───┼───┼───┼───┼───┼┈┈in $DIR direction) │ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=cell Sample 3 ┌───┬───────────┬───┬───┬┈┈│###│###########│###│ │(Fill in 1x1 cell at $POS │###├───┬───┬───┤###│───┼┈┈then move $POS to │###│###│###│+++│###│ → │the first empty cell ├───┼───┼───┼───┼───┼───┼┈┈in $DIR direction) │ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=row ┌───┬───────────┬───┬───┬┈┈│###│###########│###│ │(Move $POS down to the │###├───┬───┬───┤###│───┼┈┈next row with an empty cell │###│###│###│###│###│ │that's to the left of $POS ├───┼───┼───┼───┼───┼───┼┈┈and to left-most empty cell │ → │ │ │ │ │ │on that row) ├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=column ┌───┬───────────┬───┬───┬┈┈│###│###########│###│ │(Previous action was not a │###├───┬───┬───┤###│───┼┈┈=cell so set $DIR to "down", │###│###│###│###│###│ │with no other effect) ├───┼───┼───┼───┼───┼───┼┈┈│ ↓ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=cell 2023-03-08 ┌───┬───────────┬───┬───┬┈┈=cell 2023-04-14 │###│###########│###│ │=cell 2023-06-23 │###├───┬───┬───┤###│───┼┈┈│###│###│###│###│###│ │(Each =cell block ├───┼───┼───┼───┼───┼───┼┈┈fills in a 1x1 cell │+++│ │ │ │ │ │at $POS, then moves ├───┼───┼───┼───┼───┼───┼┈┈$POS to the first empty │+++│ │ │ │ │ │cell in $DIR direction) ├───┼───┼───┼───┼───┼───┼┈┈│+++│ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ ↓ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=column ┌───┬───────────┬───┬───┬┈┈│###│###########│###│ │(Previous action was │###├───┬───┬───┤###│───┼┈┈a =cell, so move $POS │###│###│###│###│###│ │to the uppermost empty ├───┼───┼───┼───┼───┼───┼┈┈cell in the first non-full │###│ ↓ │ │ │ │ │column to the right, ├───┼───┼───┼───┼───┼───┼┈┈and set $DIR to "down") │###│ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│###│ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=cell 0.4 ┌───┬───────────┬───┬───┬┈┈=cell 0.8 │###│###########│###│ │=cell 0.2 │###├───┬───┬───┤###│───┼┈┈│###│###│###│###│###│ │(Each =cell block ├───┼───┼───┼───┼───┼───┼┈┈fills in a 1x1 cell │###│+++│ │ │ │ │at $POS, then moves ├───┼───┼───┼───┼───┼───┼┈┈$POS to the first empty │###│+++│ │ │ │ │cell in $DIR direction) ├───┼───┼───┼───┼───┼───┼┈┈│###│+++│ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈│ │ ↓ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=column ┌───┬───────────┬───┬───┬┈┈=cell 0.1 │###│###########│###│ │=cell 0.6 │###├───┬───┬───┤###│───┼┈┈=cell 0.9 │###│###│###│###│###│ │=column ├───┼───┼───┼───┼───┼───┼┈┈=cell 0.3 │###│###│+++│+++│+++│ │=cell 0.5 ├───┼───┼───┼───┼───┼───┼┈┈=cell 0.0 │###│###│+++│+++│+++│ │=column ├───┼───┼───┼───┼───┼───┼┈┈=cell 0.26667 │###│###│+++│+++│+++│ │=cell 0.63333 ├───┼───┼───┼───┼───┼───┼┈┈=cell 0.36667 │ │ │ │ │ ↓ │ │├───┼───┼───┼───┼───┼───┼┈┈(Rinse and repeat) ┊ ┊ ┊ ┊ ┊ ┊ ┊=row ┌───┬───────────┬───┬───┬┈┈│###│###########│###│ │($POS row is entirely empty │###├───┬───┬───┤###│───┼┈┈so it's the first row with │###│###│###│###│###│ │an empty cell to the left ├───┼───┼───┼───┼───┼───┼┈┈of $POS, so stay on current │###│###│###│###│###│ │row and move $POS to the ├───┼───┼───┼───┼───┼───┼┈┈left-most empty cell in row; │###│###│###│###│###│ │change $DIR to "across") ├───┼───┼───┼───┼───┼───┼┈┈│###│###│###│###│###│ │├───┼───┼───┼───┼───┼───┼┈┈│ → │ │ │ │ │ │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=for cell :label ┌───┬───────────┬───┬───┬┈┈Mean: │###│###########│###│ │=cell 0.46667 │###├───┬───┬───┤###│───┼┈┈=cell 0.53333 │###│###│###│###│###│ │=cell 0.26667 ├───┼───┼───┼───┼───┼───┼┈┈=cell 0.42222 │###│###│###│###│###│ │├───┼───┼───┼───┼───┼───┼┈┈(Fill in 1x1 cells, │###│###│###│###│###│ │moving $POS each time ├───┼───┼───┼───┼───┼───┼┈┈in the direction │###│###│###│###│###│ │specified by $DIR) ├───┼───┼───┼───┼───┼───┼┈┈│+++│+++│+++│+++│+++│ → │├───┼───┼───┼───┼───┼───┼┈┈┊ ┊ ┊ ┊ ┊ ┊ ┊=end table ┌───┬───────────┬───┐│###│###########│###│(Terminate grid-filling │###├───┬───┬───┤###│then trim the table to │###│###│###│###│###│the bounding box around ├───┼───┼───┼───┼───┤all filled cells) │###│###│###│###│###│├───┼───┼───┼───┼───┤│###│###│###│###│###│├───┼───┼───┼───┼───┤│###│###│###│###│###│├───┼───┼───┼───┼───┤│###│###│###│###│###│└───┴───┴───┴───┴───┘
Formulae§
RakuDoc v.2 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 v.2 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, eg., 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.
For example, the following two formulae:
We will use the identity: F<\sum \frac{1}{n^{2}} = \frac{\pi^{2}}{6}>...where the value of pi can be inferred from Euler’s Identity:=formula e^{i\pi}+1=0
...may either be rendered “accurately”:
We will use the identity: F<\sum \frac{1}{n^{2}} = \frac{\pi^{2}}{6}>...where the value of pi can be inferred from Euler’s Identity:=formula e^{i\pi}+1=0
... or may be converted to a suitable Unicode approximation:
We will use the identity: ∑ 1/n² = 𝜋²/6
...where the value of pi can be inferred from Euler’s Identity:
eⁱᐢ + 1 = 0
... or may even left as raw LaTeX (perhaps with some kind of visual marker indicating that it is unprocessed):
We will use the identity: \sum \frac{1}{n^{2}} = \frac{\pi^{2}}{6}
... where the value of pi can be inferred from Euler’s Identity:
e^{i\pi}+1=0
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< e + 1 = 0 >e^{i\pi}+1=0 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
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 > |
It is also possible to stack the fallback options. For example, they 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>| file:EulerID.jpg>| e^+1=0>
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.
RakuDoc comments§
RakuDoc comments are components that both RakuDoc renderers and ambient-code compilers ignore.
Comments are useful for meta-documentation (documenting the documentation). Single-line comments use the =comment
marker:
=comment Add more here about the algorithm
For multi-line comments, use a delimited comment
block:
=begin comment This comment is multi-line. =end comment
Semantic blocks§
All uppercase block typenames are reserved for specifying standard documentation, publishing components, source constructs, or meta-information. The following must be recognised:
=NAME =AUTHOR =VERSION =TITLE =SUBTITLE =LICENSE =LICENCE =SYNOPSIS
The block name of a semantic block is to be rendered as if it were =head1 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 metadata option with the extended or abbreviated forms) then the renderer will not render the semantic block at the position it is placed in the RakuDoc document. It will be placed in a data structure by the renderer and the contents can 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
, :headlevel
, 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.
User-defined blocks§
When a block name contains both an upper case and a lower case character, as specified in the naming rules below, it is interpreted as a developer-defined block. The naming rules are to ensure that built-in blocks, semantic blocks, and custom blocks are never mixed up.
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.
The DOC phaser in Raku is the way an author can define which renderer to use, e.g.:
DOC use My::Special::Renderer;DOC use My::Other::Special::Renderer;=begin rakudoc...=end rakudoc
Non-Raku environments might specify their own mechanisms for loading custom renderers. For example, they might require a RakuDoc comment at the start of the document:
=begin rakudoc =comment load MySpecialRenderer, MyOtherSpecialRenderer ... =end rakudoc
Or they might require that any special handlers be specified as metadata on the rakudoc
block itself:
=begin rakudoc :Load< MySpecialRenderer MyOtherSpecialRenderer > ... =end rakudoc
If a renderer does not recognise a custom block, then the renderer should treat the block name as the contents of a =head1
block, which can be overridden as described in Table of Contents. The contents of the unrecognised custom block should be rendered verbatim, like a =code
block.
Consequently, 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:
Builtin blocks (e.g.
head
,item
,table
)names must be all lowercase and at least two characters long
renderers may choose how to render builtin 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 namethe 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
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
Which means that:
=begin rakudoc =for Podcast this is not code this is code =end rakudoc
...because the final line is indented from the virtual margin of its containing =begin rakudoc
/=end rakudoc
block, so it must be code.
Whereas:
=begin rakudoc =for Podcast this is not code this is not code either =end rakudoc
...because the final content line starts at the virtual margin of its containing =begin rakudoc
/=end rakudoc
block.
Care must be taken with abbreviated and extended blocks where the block ends at the next blank line.
=begin rakudoc This is an ordinary paragraph While this is not an ordinary paragraph; it is a code block. =head1 Mumble mumble Surprisingly, this is a code block (with fancy indentation too) This is just an ordinary paragraph. =end rakudoc
The Surprisingly ... paragraph is a code block because a block only sets the virtual margin within that block, and the =head1
block terminates at the blank line immediately after the =head1
line, and before the apparent code block begins. At which point, the virtual margin reverts to the previous virtual margin set by the surrounding =begin rakudoc...=end rakudoc
block.
The current virtual margin terminates at the end of the block whose opener set it, and not at the start of the next block that sets a virtual margin. In other words, the virtual margin is a local feature of each individual block, not a collective feature of the entire document, and therefore a block's virtual margin always ends at the end of the block itself (and reverts at that point to the virtual margin of the surrounding block, if any).
Which means:
=begin rakudoc This is an ordinary paragraph While this is not This is a code block =head1 Mumble mumble This IS also a code block because the preceding =head's virtual margin ended at the end of the preceding =head block, which was at the preceding blank line. So the virtual margin for this implicit block is the virtual margin of the surrounding C<=begin rakudoc ... =end rakudoc> block. This block is indented relative to that C<=rakudoc block>'s virtual margin, so it's a code block. This is a para block (with fancy indentation too, because the indentation of first line alone determines whether an implicit block is a C<=para> or a C<=code> block, and all subsequent lines, regardless of their indentation, become part of that block ... until the end of the implicit block, which occurs at the next blank line or the next explicit RakuDoc block or directive.) =end rakudoc
And if, instead, you wanted the block straight after the =head
to be an implicit paragraph block (i.e. not an implicit code block), you'd write it:
=begin rakudoc This is an ordinary paragraph While this is not This is a code block =begin section =head1 Mumble mumble This is a para block, NOT a code block because the virtual margin for this implicit block is the virtual margin of the surrounding =begin section ... =end section block. The first line of this implicit block is NOT indented relative to that =section block's virtual margin, so it's a para block. =end section This is a para block too...because its first line is not indented relative to the virtual margin of the current =begin rakudoc ... =end rakudoc block. =end rakudoc
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=code
and on-margin=para
shortcuts: =defn
, =item
, =itemN
, =nested
, =rakudoc
, =section
, =pod
, =cell
.
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 of them 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.
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.
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 tabs that it will recognise.
Anchors§
Whenever a =head
block such as:
=head Table of Contents and Index
...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 and Index>
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 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.
The :id<name of a link>
metadata option can be attached to any block. For example:
=for head :id<ToCaI> Table of Contents and Index ...and later we can add: L<link to an internal heading|#ToCaI>
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>
, orthe exact contents of the corresponding
=header
block, orthe exact contents of a block’s explicit
:caption<TEXT>
.
Internal links cannot be specified by a #
followed by
a
=header
block's implicit autogenerated-from-content ID, ora block’s implicit autogenerated-from-caption ID.
That is, the in-document link target cannot be the mangled contents of a =header
block or a :caption<...>
metatag; it can only be the original contents.
For example:
=for header :id<h123>A sample header=for table :id<t456> :caption<Example table>A B C1 2 3This 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 header >This is a L<valid link (to a caption) | #Example table >This is L<NOT a valid link | #A_sample_header >This is L<NOT a valid link | #Example_table >
Table of Contents and Index§
When a renderer parses a file containing RakuDoc, heading and X<>
markup information is collected. This information can be rendered using a P<>
markup instruction, or may be used in another way by the renderer (e.g. to create a sidebar with the Table of Contents).
Named blocks are considered by default to be equivalent to =head
for the purposes of a Table of Contents. The exceptions are para
, nested
, code
, input
and output
blocks.
This default can be changed with the :toc
and :headlevel
meta tabs.
Setting :toc
on a block will include the contents of the block in the Table of Contents. Including the entire block contents is usually not desirable, so the :caption<...>
meta tab can be used to provide a text for the Table of Contents.
Setting :!toc
will prevent a block's information from being included in the Table of Contents.
Setting :headlevel(N)
, where N is an integer greater than 0, will cause the block information to be treated in the same way as a headN
heading is treated. Setting N to less than 1 has the same effect as :!toc
. If it is not explicitly set, :toc
will set the headlevel to 1.
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 tab, or specified inline with the Δ< ... >
markup instruction. Both the metadata tab 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 summarised as follows:
Syntax | Meaning |
---|---|
'*' | Any version |
v1.2.3 | specific version |
v1.2.3+ | specific version or later |
v1.2.3- | specific version or earlier |
v1.2.3..v2.3.4 | inclusive range of versions |
v1.2.3^..^v2.3.4 | exclusive range of versions |
v1.2.3..^v2.3.4 and v1.2.3^..v2.3.4 | semi-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, a renderer should only show blocks that correspond to the version information. A block that does not have a :delta
is treated as if it has :delta<*>
.
An example is given in the description of the section
block
Markup instructions§
Markup instructions provide a way to add inline mark-up 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 characterises formatting codes semantically, allowing a renderer to choose any appropriate visual representation. Thus B<>
is for the Basis of a sentence, although a visual equivalent might involve a bold font.
The following should be made available in all renderers.
Inline markup | Instruction | Mnemonic | HTML equivalent | Markdown equivalent |
---|---|---|---|---|
Basis | B<text> | "B for Basis" | <b>text</b> | **text** |
Important | I<text> | "I for Important" | <i>text</i> | *text* |
Unusual | U<text> | "U for Unusual" | <u>text</u> | __text__ |
Strikethrough | O<text> | "O for Overstrike" | <s>text</s> | ~~text~~ |
Superscript | H<text> | "H for High text" | <sup>text</sup> | ^text^ |
Subscript | J<text> | "J for Junior text" | <sub>text</sub> | ~text~ |
Code | C<text> | "C for Code" | <code>text</code> | `text` |
The table contains suggested HTML and Markdown equivalents; a renderer may 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:
This mechanism is explained further in the syntax section.
Instructions with side effects§
Markup instructions, including all customisable instructions, will typically have associated metadata.
Links§
To create a link, enclose it 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 schema 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.
Several schemas are possible:
https://
orhttp://
The renderer may style the label and cause a jump in a networked environment, as is normal for HTML documents.rakudoc:
A reference to a RakuDoc source, which might be in a Raku module or a RakuDoc file.mailto:
An email address. Typically, activating this type of link invokes a mailer.man:
A link to the system manpages.isbn:
andissn:
The International Standard Book Number or International Standard Serial Number for a publication.defn:
A link to a block-form definition or an inline definition of the specified term within the current document.
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.
A renderer is expected to render a link with a schema as follows:
At a minimum, a link like rakudoc:ModuleName is simply rendered as text, to something like: “the ModuleName documentation”, and 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
orman 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 tohttps://raku.land/
orman:
links tohttps://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 the standard Unix L<man:find(1)> facilities.Please forward bug reports to L<mailto:abyss@example.org>This 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 lexiphaniaAn unfortunate proclivity foremploying grandiloquisms (for example, words such as "proclivity", "grandiloquism", and indeed "lexiphania").=defn glossoligationRestraint 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.
Placement links§
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 spaces 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>
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<ÿÿ<strong>ÿÿThe document is copyright. |ÿÿ</strong>ÿÿ file:/shared/docs/std_copyright.rakudoc> =DISCLAIMER P<ÿÿ<strong>ÿÿNO WARRANTY. NONE. NIL. NADA. |ÿÿ</strong>ÿÿ http://www.MegaGigaTeraPetaCorp.com/std/disclaimer.txt>
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:
andhttps:
file:
toc:
index:
semantic:
The toc:
form is a special pseudo-scheme that inserts a table of contents in place of the P<>
code. After the colon, list the block types that you wish to include in the table of contents. For example, to place a table of contents listing only top- and second-level headings:
See: toc:1,2
To place a table of contents that lists the top four levels of headings:
See: toc:1..4
In order to include the whole table of contents, use toc:*
. The *
is needed to make this term a valid URI.
A document may have as many P<toc:...>
placements as necessary.
The index:*
form is a special pseudo-scheme that inserts an index table in place of the P<>
code.
The semantic:XXX
form places the XXX 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>.
Any Raku object 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
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 briefsuspension of the effects of gravity, accompanied by a suddento-the-camera realization of imminent downwards acceleration.
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 ÿÿ<strong>ÿÿ<dfn id="term being defined">term being defined</dfn>ÿÿ</strong>ÿÿ would be...
And a L<defn:term being defined>
link would be translated to something like:
...a ÿÿ<strong>ÿÿ<a href="#term being defined">term being defined</a>ÿÿ</strong>ÿÿ link would be...
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 wayto add inline mark-up to a piece of text.
Space-preserving text§
Any text enclosed in an unknown format-code 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>.
would be formatted like so:
The emergency signal is: dot dot dot dash dash dash dot dot dot.
rather than:
The emergency signal is: dot dot dot dash dash dash dot dot dot.
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!>
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>
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>
Which is rendered like so:
Enter your name: K<John Doe>
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>
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
Which would be rendered:
T<Enter your name:> John Doe
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 using 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.
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> UkraineE<RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK>
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
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.
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.
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<ÿÿ<strong>ÿÿleft- |ÿÿ</strong>ÿÿlaquo> and E<ÿÿ<strong>ÿÿright-double-angle |ÿÿ</strong>ÿÿraquo> characters. Raku code often contains the E<ÿÿ<strong>ÿÿleft- and right-corner |ÿÿ</strong>ÿÿ0xff62;0xff63> bracketing characters to avoid using quotes.
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<> >.
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<>
'colors' the contents to show that it is code, whilst V<>
uses the default text presentation.
The default behaviors of both V<>
and C<>
can be changed using a =config
directive, e.g.,
=config C :allow< B I U > =config V :allow< N L X >
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 ÿÿ<strong>ÿÿX<array>ÿÿ</strong>ÿÿ is an ordered list of scalars indexed by number, starting with 0. A ÿÿ<strong>ÿÿX<hash>ÿÿ</strong>ÿÿ is an unordered collection of scalar values indexed by their associated string key.
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 ÿÿ<strong>ÿÿX<array|arrays>ÿÿ</strong>ÿÿ is an ordered list of scalars indexed by number, starting with 0. A ÿÿ<strong>ÿÿX<hash|hashes>ÿÿ</strong>ÿÿ is an unordered collection of scalar values indexed by their associated string key.
In the two-part form, the 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|ÿÿ<strong>ÿÿarrays, definition ofÿÿ</strong>ÿÿ> is an ordered list of scalars indexed by number, starting with 0. A X<hash|ÿÿ<strong>ÿÿhashes, definition ofÿÿ</strong>ÿÿ> is an unordered collection of scalar values indexed by their associated string key.
You can specify two or more entries for a single indexed text, by separating the entries with semicolons:
A X<hash|ÿÿ<strong>ÿÿhashes, definition of; associative arraysÿÿ</strong>ÿÿ> is an unordered collection of scalar values indexed by their associated string key.
The indexed text can be empty, creating a "zero-width" index entry:
ÿÿ<strong>ÿÿX<|puns, deliberate>ÿÿ</strong>ÿÿThis is called the "Orcish Maneuver" because you "OR" the "cache".
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 recognise 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 highlight color), 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 marvelous libation M<order now by PayMeApp|PayMeApp; vendor-id; $0.99>
An HTML renderer would the convert this to, for example,
<p>To sample this marvelous libation
<button class="PayMeApp" data-token="vendor-id" data-price="$0.99">
order now by PayMeApp
</button>
</p>
Display and metadata§
In the descriptions above, it will be seen that markup codes may only contain display text or a mix of display and meta information. This section clarifies these groups.
If a markup code may contain both display text and meta information, the character |
is used to delimit the two components. In order to use |
inside a display text, it must be escaped (\|
) or specified as an entity (E<VERTICAL LINE>
).
Display only codes§
The following codes may only contain display text:
B< DISPLAY-TEXT >C< DISPLAY-TEXT >H< DISPLAY-TEXT >I< DISPLAY-TEXT >J< DISPLAY-TEXT >K< DISPLAY-TEXT >R< DISPLAY-TEXT >S< DISPLAY-TEXT >T< DISPLAY-TEXT >U< DISPLAY-TEXT >V< DISPLAY-TEXT >N< DISPLAY-TEXT >O< DISPLAY-TEXT >
Metadata and (optional) display text§
The following codes may (and, in some cases, must) contain both a display text and some kind of metadata.
A< DISPLAY-TEXT | METADATA=ALIAS-NAME >D< DISPLAY-TEXT | METADATA=SYNONYMS >Δ< DISPLAY-TEXT | METADATA=VERSION-ETC >E< DISPLAY-TEXT | METADATA=HTML/UNICODE-ENTITIES >F< DISPLAY-TEXT | METADATA=LATEX-FORM >L< DISPLAY-TEXT | METADATA=TARGET-URI >M< DISPLAY-TEXT | METADATA=WHATEVER >P< DISPLAY-TEXT | METADATA=REPLACEMENT-URI >X< DISPLAY-TEXT | METADATA=INDEX-ENTRY >
The markup codes A
, E
, F
, L
, and P
may be specified without a display text, in which case, the renderer (as elsewhere provided in this specification) may provide an automatic rendering if the metadata component fails to produce a renderable result. If an explicit display text is provided (i.e. to the left of a |
), that text overrides the default alternate rendering.
Metadata only§
Z< METADATA=COMMENT >
The comment code Z<>
is intended not to have a display text so the contents of a comment can be considered as pure metadata.
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
recognise 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
AUTHORS§
Damian Conway (@thoughtstream)
Richard Hainsworth (@finanalyst)
Elizabeth Mattijen (@lizmat)
Aliaksandr Zahatski (@zag)
Summary§
Directives§
Directive | Specifies |
---|---|
=alias | Define a RakuDoc macro |
=begin | Start of an explicitly terminated block |
=column | Start a new column in a procedural table |
=config | Block scope modifications to a block or markup instruction |
=end | Explicit termination of a begin block |
=finish | No ambient blocks after this point |
=for | Start of an implicitly (blank-line) terminated block |
=row | Start a new row in a procedural table |
Blocks§
Block typename | Specifies |
=cell | Contents of a table cell, only valid in a procedural table context |
=code | Verbatim pre-formatted sample source code |
=input | Pre-formatted sample input |
=output | Pre-formatted sample output |
=comment | Content to be ignored by all renderers |
=head | First-level heading |
=headN | Nth-level heading |
=numhead | First-level numbered heading |
=numheadN | Nth-level numbered heading |
=defn | Definition of a term |
=item | First-level list item |
=itemN | Nth-level list item |
=numitem | First-level numbered list item |
=numitemN | Nth-level numbered list item |
=nested | Nest block contents within the current context |
=para | Ordinary paragraph |
=rakudoc | No "ambient" blocks inside |
=section | Defines a section |
=pod | Legacy version of RakuDoc |
=table | Visual or procedural table |
=formula | Render content as LaTex formula |
=data | Raku data section |
RESERVED | Semantic blocks (SYNOPSIS, TITLE, etc.) |
CustomName | User-defined block |
Metadata options§
Metadata option | Blocks applied to | Description |
---|---|---|
|
| Change default of verbatim blocks |
| ||
| ||
| ||
| all blocks | Specify the anchor for a block |
|
| Continue numbering from the previous numbered list |
| ||
|
| Include content or caption in Table of contents |
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| SEMANTIC block | Do not include content or caption in Table of contents |
Custom block | ||
| ||
| ||
| SEMANTIC block | Define the head level at which the caption is included in the Table of contents |
Custom block | ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| Semantic block | Caption to be associated with a block in the Table of Contents |
Custom block | ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| Semantic block | Remove block from rendered text and ToC (use |
|
| Specify rows, columns, or cells to be rendered as headers |
| ||
| ||
| ||
|
| Specify rows, columns, or cells to be rendered as labels |
| ||
| ||
| ||
|
| Specify how cell contents are to be vertically and/or horizontally aligned |
| ||
| ||
| ||
|
| Specify how many rows a single cell should span in a procedural table |
|
| Specify how many columns a single cell should span in a procedural table |
|
| A shortcut for |
|
| Developer information associated with a block |
| ||
| ||
| ||
| ||
| ||
| ||
| ||
Semantic block | ||
Custom block | ||
|
| Replace the default bullet with one or more characters, or entities specified with |
Markup instructions§
Markup instruction | Specifies |
A<...|...> | Alias to be replaced by contents of specified =alias directive |
B<...> | Basis/focus of sentence (typically rendered bold) |
C<...> | Code (typically rendered fixed-width) |
D<...> | Definition inline (D<term being defined|synonym1; synonym2>) |
Δ<...|...;...> | Delta note (Δ<visible text|version; Notification text>) |
E<...|...;...> | Entity (HTML or Unicode) description (E<entity1;entity2; multi,glyph;...>) |
F<...|...> | Inline content for a formula (F<ALT|LaTex notation>) |
G<...> | (This markup code is not yet defined, but is reserved for future use) |
H<...> | High text (typically rendered superscript) |
I<...> | Important (typically rendered in italics) |
J<...> | Junior text (typically rendered subscript) |
K<...> | Keyboard input (typically rendered fixed-width) |
L<...|...> | Link (L<display text|destination URI>) |
M<...|..,..;...> | Markup extra (M<display text|functionality;param,sub-type;...>) |
N<...> | Note (not rendered inline, but visible in some way: footnote, sidenote, pop-up, etc.)) |
O<...> | Overstrike or strikethrough |
P<...|...> | Placement link |
Q<...> | (This markup code is not yet defined, but is reserved for future use) |
R<...> | Replaceable component or metasyntax |
S<...> | Space characters to be preserved |
T<...> | Terminal output (typically rendered fixed-width) |
U<...> | Unusual (typically rendered with underlining) |
V<...> | Verbatim (internal markup instructions ignored) |
W<...> | (This markup code is not yet defined, but is reserved for future use) |
X<...|..,..;...> | Index entry (X<display text|entry,subentry;...>) |
Y<...> | (This markup code is not yet defined, but is reserved for future use) |
Z<...> | Zero-width comment (contents never rendered) |
LICENSE§
Artistic-2.0