Podlite - a lightweight markup language
- v1.0
- Podlite
- General syntactic structure
- Podlite blocks
- Delimited blocks
- Paragraph blocks
- Abbreviated blocks
- Block equivalence
- Standard configuration options
- Selectors
- Block types
- Headings
- Ordinary paragraph blocks
- Code blocks
- I/O blocks
- Lists
- Nesting blocks
- Tables
- Named or modular custom blocks
- Podlite comments
- Data blocks
- Semantic blocks
- Table of contents
- Include block
- Inserting pictures
- Mathematical formulas
- Markdown support
- Markup codes
- Significance indicators
- Mistake marking
- Text positioning
- Definitions
- Example specifiers
- Verbatim text
- Inline comments
- Links
- Contextual backlinks
- Alias placements
- Space-preserving text
- Entities
- Indexing terms
- Annotations
- Module-defined handler for extends markup features
- Block pre-configuration
- Aliases
- Notification blocks
- Directives
- Blocks
- Inline markup codes
AUTHORS
Damian Conway <damian@conway.org>
Aliaksandr Zahatski <zag@cpan.org>
VERSION
1.0
CHANGES
v1.0
New:
Notification blocks,
:notify
attribute for=nested
blocks,:folded
attribute,:folded-levels
for=toc
block,Refactor Named custom blocks and markup custom codes,
M<>
,embedding binary data into documents,
=data
,:filename
,:encoding
,:mime-type
attribute for=include
and=data
blocks,introduce
data:
schema for use in=picture
and=table
,render tables from CSV files,
=table
,new markdown mode for parser,
M<>
- extends inline markup features,add
:id
,:caption
,:lang
attributes,task lists,
=item
and:checked
attribute,intro Selectors,
table of contents,
=toc
,include block,
=include
,inserting pictures,
=picture
,P<>
,mathematical formulas,
=formula
,F<>
,Markdown support,
=markdown
,mistake marking,
O<>
,text positioning,
J<>
,H<>
,Emoji,
E<>
,contextual backlinks,
W<>
,advanced table format,
=row
,=cell
blocks,:header
,:rowspan
,:colspan
attributes.
Deprecated/removed:
Contextual aliases,
=finish
,markers in comments,
:margin
attribute,=encoding
directive,P<toc:>
due to=toc
block,P<man:>
,P<doc:>
due to=include
block,P<>
- placement links,Declarator block,
:formatted
attribute,:like
attribute.
Podlite
Podlite is an easy-to-use markup language with a simple, consistent underlying document object model. Podlite can be used for writing language documentation, for documenting programs and modules, as well as for other types of document composition.
The Podlite is a purely descriptive mark-up notation, with no presentational components.
General syntactic structure
Podlite documents are specified using directives, which are used to declare configuration information and to delimit blocks of textual content.
Every directive starts either with an equals sign (=
) followed
immediately by an identifier.
An identifier composed of an alphabetical character followed by any combination of alphanumeric characters. Alphabetic and numeric definitions encompass relevant Unicode characters. The underscore is consistently treated as alphabetic. Additionally, an identifier can include isolated apostrophes or hyphens, given that the subsequent character is alphabetic.
Directives that start with =
can be indented like the code they
interleave, but their initial =
must still be the first non-whitespace
character on their line.
An indented Podlite block is considered to have a virtual left margin, determined by the indentation of its opening delimiter.
In other words, if a directive is indented from the left margin, the column at which the first character of its opening delimiter appears is thereafter considered the first column of the entire block's contents.
The virtual margin treats leading tabs as aligning to tabstops spaced
every ($?TABSTOP // 8)
characters.
Podlite blocks
The content of a document is specified within one or more blocks. Every Podlite block may be declared in any of three forms: delimited style, paragraph style, or abbreviated style. All of these forms are equivalent.
Anything in a document that is neither a Podlite directive nor contained within a Podlite block is treated as "ambient" material. Typically this would be the source code of the program that the Podlite is documenting. Podlite parsers still parse this text into the internal representation of the file, representing it as a "ambient" block. Renderers will usually ignore such blocks. This is the default mode of the parser.
All directives have a defined terminator and the Podlite parser always reverts to "ambient" at the end of each Podlite directive or block.
The =pod
block puts the parser in "pod" mode,
treating all text between blocks as implicit paragraph Podlite, even if
it's not inside an explicit block.
To keep the parser in "pod" mode, enclose the desired Podlite region
in a =pod
block:
=begin pod
=head1 A heading
This is Podlite too. Specifically, this is a simple C<para> block
$this = pod('also'); # Specifically, a code block
=end pod
The contents of files with the extensions .podlite
and .pod6
are
implicitly wrapped in a =pod
directive.
For .md
and .markdown
files, the parser operates in "Markdown"
mode for the entire file, treating all
text as markdown even if it is not inside an =markdown
block.
Any other file extension puts the parser in default mode. The =include
block has a mechanism to override this behavior by using
the :mime-type
attribute for the included files.
Delimited blocks
Delimited blocks are bounded by =begin
and =end
markers, both of
which are followed by a valid Podlite identifier, which is the
typename of the block. Typenames that are entirely lowercase (for
example: =begin head1
) or entirely uppercase (for example: =begin
SYNOPSIS
) are reserved.
After the typename, the rest of the =begin
marker line is treated as
configuration information for the block. This information is used in
different ways by different types of blocks, but is always specified using
any of:
Value is... | Specify with... | Or with... | Or with... |
---|---|---|---|
Boolean (true) | :key | :key(1) | key => 1 |
Boolean (false) | :!key | :key(0) | key => 0 |
String | :key<str> | :key('str') | key => 'str' |
List | :key<1 2 3> | :key[1,2,3] | key => [1,2,3] |
Hash | :key{a=>1, b=>2} | key => {a=>1, b=>2} |
All option keys and values must, of course, be constants since Podlite is a specification language, not a programming language. Specifically, option values cannot be closures.
The configuration section may be extended over subsequent lines by
starting those lines with an =
in the first (virtual) column followed
by a whitespace character.
The lines following the opening delimiter and configuration are the
data or contents of the block, which continue until the block's matching
=end
marker line. For most block types, these contents may be
indented if you wish, without them being treated as code blocks. Indented text is only treated as code within
=pod
, =nested, =item, =code
,
and semantic blocks.
The general syntax is:
=begin R<BLOCK_TYPE> R<OPTIONAL CONFIG INFO>
= R<OPTIONAL EXTRA CONFIG INFO>
R<BLOCK CONTENTS>
=end R<BLOCK_TYPE>
For example:
=begin table :caption<Table of Contents>
Constants 1
Variables 10
Subroutines 33
Everything else 57
=end table
=begin Name :required
= :width(50)
The applicant's full name
=end Name
=begin Contact :optional
The applicant's contact details
=end Contact
Note that no blank lines are required around the directives; blank lines within the contents are always treated as part of the contents. This is a universal feature of Podlite.
Note also that in the following specifications, a "blank line" is a line
that is either empty or that contains only whitespace characters. That
is, a blank line matches the following pattern: /^^ \h* $$/
. Podlite uses
blank lines as delimiters, rather than empty lines, to minimize unpleasant
surprises when stray spaces or tabs mysteriously turn up in hitherto
empty lines.
Paragraph blocks
Paragraph blocks are introduced by a =for
marker and terminated by
the next Podlite directive or the first blank line (which is not
considered to be part of the block's contents). The =for
marker is
followed by the name of the block and optional configuration
information. The general syntax is:
=for R<BLOCK_TYPE> R<OPTIONAL CONFIG INFO>
= R<OPTIONAL EXTRA CONFIG INFO>
R<BLOCK DATA>
For example:
=for table :caption<Table of Contents>
Constants 1
Variables 10
Subroutines 33
Everything else 57
=for Name :required
= :width(50)
The applicant's full name
=for Contact :optional
The applicant's contact details
Abbreviated blocks
Abbreviated blocks are introduced by an '='
sign in the
first column, which is followed immediately by the typename of the
block. The rest of the line is treated as block data, rather than as
configuration. The content terminates at the next Podlite directive or the
first blank line (which is not part of the block data). The general
syntax is:
=R<BLOCK_TYPE> R<BLOCK DATA>
R<MORE BLOCK DATA>
For example:
=table
Constants 1
Variables 10
Subroutines 33
Everything else 57
=Name The applicant's full name
=Contact The applicant's contact details
Note that abbreviated blocks cannot specify configuration information. If
configuration is required, use a =for
or =begin
/=end
instead.
Block equivalence
The underlying documentation model treats all block specifications (delimited, paragraph, and abbreviated) the same way. It is possible to choose the form is most convenient for a particular documentation task. In the descriptions that follow, the abbreviated form will generally be used, but should be read as standing for all three forms equally.
For example, although #Headings shows only:
=head1 Top Level Heading
this automatically implies that you could also write that block as:
=for head1
Top Level Heading
or:
=begin head1
Top Level Heading
=end head1
Standard configuration options
Podlite predefines a small number of standard configuration options that can be applied uniformly to any built-in block type. These include:
:caption
- This option assigns a title to the given block, which is typically used to create a table of contents.
:id
- This option enables the explicit definition of identifiers for blocks and use those IDs for linking purposes (see #Links).
:nested
- This option specifies that the block is to be nested within its current context. For example, nesting might be applied to block quotes, to textual examples, or to commentaries. In addition the =code, =item, =input, and =output blocks all have implicit nesting.
- Nesting of blocks is usually rendered by adding extra indentation to the block contents, but may also be indicated in other ways: by boxing the contents, by changing the font or size of the nested text, or even by folding the text (so long as a visible placeholder is provided).
- Occasionally it is desirable to nest content by more than one level:
- This can be simplified by giving the
:nested
option a positive integer value: - You can also give the option a value of zero, to defeat any implicit nesting that might normally be applied to a paragraph. For example, to specify a block of code that should appear without its usual nesting:
- Note that
:!nested
could also be used for this purpose:
=begin para :nested
=begin para :nested
=begin para :nested
"We're going deep, deep, deep undercover!"
=end para
=end para
=end para
=begin para :nested(3)
"We're going deep, deep, deep undercover!"
=end para
=comment Don't nest this code block in the usual way...
=begin code :nested(0)
1 2 3 4 5 6
123456789012345678901234567890123456789012345678901234567890
|------|-----------------------|---------------------------|
line instruction comments
number code
=end code
=Z<>begin code :!nested
:numbered
- This option specifies that the block is to be numbered. The most common use of this option is to create numbered headings and ordered lists, but it can be applied to any block.
- The numbering conventions for headings and lists are specified in those sections, but it is up to individual renderers to decide how to display any numbering associated with other types of blocks.
- Note that numbering is never explicit; it is always implied by context.
:checked
- This attribute indicates that a checkbox should be added to that block.
It is possible to apply a
:checked
attributes to any block. The most common use of this option is to create task lists. - For an unchecked checkbox the
:!checked
is used. - The task list item marker (checkbox) is added to the output.
In HTML output, this would be represented as an
<input type="checkbox">
element. - The specification does not define how these checkboxes are interacted with. Implementors are free to choose whether they render them as disabled, unchangeable elements, or handle dynamic interactions like checking and unchecking in the final rendered document.
:folded
- This option specifies whether the block is foldable and, if specified, whether it should be collapsed or expanded by default. This feature is useful in managing the length of documents and focusing the reader's attention on certain sections as needed.
- A
:!folded
or:folded(0)
expands the callout by default, and a:folded
or:folded(1)
collapses it instead. - When applied to a block element, such as a heading, the attribute typically affects all headings with lower-level content, creating a hierarchical folding effect.
- For example:
=for table :folded :caption('Culinary Techniques for Sustainability')
Sous-vide Low energy consumption
---------- -------------------------
Steaming Preserves nutrients
Baking Efficient for batch cooking
=for head2 :folded
Green Energy Overview
:lang
- This option is used to provide information about the programming language used in a specific code block. This helps ensure that the code is displayed and interpreted correctly by rendering engines or syntax highlighters.
- Here's a table that lists a few programming languages along with their possible
values for the
:lang
attribute: - If the language is not specified, the default language is used based on the file extension or mime type of the current document.
Programming language | Possible :lang values |
---|---|
C++ | cpp |
CSS | css |
HTML | html |
Java | java |
JavaScript | javascript |
Python | python |
Raku | raku |
:allow
- This option expects a list of markup codes that are to be recognized
within any
V<>
codes that appear in (or are implicitly applied to) the current block. The option is most often used on=code
blocks to allow mark-up within those otherwise verbatim blocks, though it can be used in any block that contains verbatim text. See #Formatting within code blocks.
Selectors
Selectors consist of patterns that help identify and filter specific blocks within documents. Each pattern contains optional source of blocks and block names.
The general syntax is:
R<EXTERNAL_SOURCE>
or
[ R<EXTERNAL_SOURCE> | ] R<BLOCKS_SELECTOR>
...where
EXTERNAL_SOURCE - optional source of blocks for filtering, default current document,
BLOCK_SELECTOR - list of block names, filter for
For example:
Selector | Description |
---|---|
head1, head2, item1 | all head1, head2 and item1 blocks from document |
file:article.pod6 | head1, head2 | all head1 and head2 blocks from article.pod6 file |
file:./includes/*.pod6 | head1, head2 | all head1 and head2 blocks from pod6 files placed in includes directory |
doc:Data::Dumper | code | all code blocks from a module documentation |
file:/docs/**/*.md | head1 | search headers with first level for all ".md" files |
within the "docs" directory and its subdirectories. |
Please note that while the Selector blocks provide a way to query and filter specific elements within Markdown files, Markdown itself doesn't have formal named blocks like the Podlite syntax. Instead, Markdown uses a lightweight markup to structure content. The above table provides a mapping between Podlite block names and their corresponding Markdown elements.
Podlite | Markdown | Describtion |
---|---|---|
=head1 , =head2 , ... | #, ##, ... | Heading level 1,2... |
=nested | ">" | blockquote |
=para | block of text | paragraph |
N<> | [^1]: footnote. | footnote |
=Html | <span>text<span> | HTML block |
O<text> | ~~text~~ | Strikethrough, "O for Overstrike" |
H<text> | ^text^ | Superscript, "H for High text" |
J<text> | ~text~ | Subscript, "J for Junior text" |
F<> , =formula | $,$$, ```math | Mathematical formulas |
The most common use of Selectors is to create table of contents and in include block.
Block types
Podlite offers notations for specifying a wide range of standard block types...
Headings
Podlite provides an unlimited number of levels of heading, specified by the
=head
N block marker. For example:
=head1 A Top Level Heading
=head2 A Second Level Heading
=head3 A third level heading
=head86 A "Missed it by I<that> much!" heading
While Podlite parsers are required to recognize and distinguish all levels of heading, Podlite renderers are only required to provide distinct renderings of the first four levels of heading (though they may, of course, provide more than that). Headings at levels without distinct renderings would typically be rendered like the lowest distinctly rendered level.
Numbered headings
You can specify that a heading is numbered using the :numbered
option. For
example:
=for head1 :numbered
The Problem
=for head1 :numbered
The Solution
=for head2 :numbered
Analysis
=for head3
Overview
=for head3
Details
=for head2 :numbered
Design
=for head1 :numbered
The Implementation
which would produce:
1. The Problem
2. The Solution
2.1. Analysis
Overview
Details
2.2: Design
3. The Implementation
It is usually better to preset a numbering scheme for each heading level, in a series of configuration blocks:
=config head1 :numbered
=config head2 :numbered
=config head3 :!numbered
=head1 The Problem
=head1 The Solution
=head2 Analysis
=head3 Overview
=head3 Details
=head2 Design
=head1 The Implementation
Alternatively, as a short-hand, if the first whitespace-delimited word
in a heading consists of a single literal #
character, the #
is
removed and the heading is treated as if it had a :numbered
option:
=head1 # The Problem
=head1 # The Solution
=head2 # Analysis
=head3 Overview
=head3 Details
=head2 # Design
=head1 # The Implementation
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:
=head6 # The Rescue of the Kobayashi Maru
should produce something like:
2.3.8.6.1.9. The Rescue of the Kobayashi Maru
Ordinary paragraph blocks
Ordinary paragraph blocks consist 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 at (virtual) column 1. The paragraph is terminated by the first blank line or block 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
Within a =pod
, =item
, =defn
, =nested
, or
semantic block, ordinary paragraphs do not require
an explicit marker or delimiters, but there is also an explicit para
marker (which may be used anywhere):
=para
This is an ordinary paragraph.
Its text will be squeezed and
short lines filled.
and likewise the longer =for
and =begin
/=end
forms. For example:
=begin para
This is an ordinary paragraph.
Its text will be squeezed and
short lines filled.
This is I<still> part of the same paragraph,
which continues until an...
=end para
As the previous example implies, when any form of explicit =para
block
is used, any whitespace at the start of each line is removed during rendering.
In addition, within a delimited =begin para
/=end para
block, any
blank lines are preserved.
Code blocks
Code blocks are used to specify pre-formatted text (typically source code), which should be rendered without rejustification, without whitespace-squeezing, and without recognizing any inline markup codes. Code blocks also have an implicit nesting associated with them. Typically these blocks are used to show examples of code, mark-up, or other textual specifications, and are 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. For example:
This ordinary paragraph introduces a code block:
$this = 1 * code('block');
$which.is_specified(:by<indenting>);
Implicit code blocks may only be used within =pod
, =item
, =defn
,
=nested
, or semantic blocks.
There is also an explicit =code
block (which can be specified within
any other block type, not just =pod
, =item
, etc.):
The C<loud_update()> subroutine adds feedback:
=begin code
sub loud_update ($who, $status) {
say "$who -> $status";
silent_update($who, $status);
}
=end code
As the previous example demonstrates, within an explicit =code
block
the code 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.
Formatting within code blocks
Although =code
blocks automatically disregard all markup
codes, occasionally you may still need to specify
some formatting 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 codes 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 codes. Those codes will then remain active inside the
code block. For example:
=begin code :allow<B R>
sub demo {
B<say> 'Hello R<name>';
}
=end code
would be rendered:
sub demo {
say 'Hello name';
}
Note that the use of the :allow
option also makes it possible
for verbatim markup codes (such as C<>
and V<>
) to contain other codes as well.
Assign programming language to code blocks
The :lang
attribute will be used to provide information about the
programming language used in a particular block of code. This helps
in ensuring that the code is correctly rendered and interpreted by the
renderers or syntax highlighting tools.
For example:
=begin code :lang<raku>
sub demo {
say 'Hello R<name>';
}
=end code
I/O blocks
Podlite also provides blocks for specifying the input and output of programs.
The =input
block is used to specify pre-formatted keyboard input,
which should be rendered without rejustification or squeezing of whitespace.
The =output
block is used to specify pre-formatted terminal or file
output which should also be rendered without rejustification or
whitespace-squeezing.
Note that, like =code
blocks, both =input
and =output
blocks have an
implicit level of nesting. They are also like =code
blocks in that they
are typically rendered in a fixed-width font, though ideally all three blocks
would be rendered in distinct font/weight combinations (for example: regular
serifed for code, bold sans-serif for input, and regular sans-serif for
output).
Unlike =code
blocks, both =input
and =output
blocks honour any
nested markup codes. This is particularly useful since a sample of
input will often include prompts (which are, of course, output).
Likewise a sample of output may contain the occasional interactive
component. Podlite provides special markup codes
(K<>
and T<>
) to indicate embedded input or output, so you can use
the block type that indicates the overall purpose of the sample (i.e. is
it demonstrating an input operation or an output sequence?) and then use
the "contrasting" markup code within the block.
For example, to include a small amount of input in a sample of output
you could use the K<>
markup code:
=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
Lists
Lists in Podlite are specified as a series of contiguous =item
blocks. No
special "container" directives or other delimiters are required to
enclose the entire list. For example:
The seven suspects are:
=item Happy
=item Dopey
=item Sleepy
=item Bashful
=item Sneezy
=item Grumpy
=item Keyser Soze
List items have one implicit level of nesting:
The seven suspects are:
Happy
Dopey
Sleepy
Bashful
Sneezy
Grumpy
Keyser Soze
Lists may be multi-level, with items at each level specified using the
=item1
, =item2
, =item3
, etc. blocks. Note that =item
is just
an abbreviation for =item1
. For example:
=item1 Animal
=item2 Vertebrate
=item2 Invertebrate
=item1 Phase
=item2 Solid
=item2 Liquid
=item2 Gas
=item2 Chocolate
which would be rendered something like:
• Animal
– Vertebrate
– Invertebrate
• Phase
– Solid
– Liquid
– Gas
– Chocolate
Podlite parsers must issue a warning if a "level-N+1" =item
block
(e.g. an =item2
, =item3
, etc.) appears anywhere except where there
is a preceding "level-N" =item
in the same surrounding block. That
is, an =item3
should only be specified if an =item2
appears
somewhere before it, and that =item2
should itself only appear if
there is a preceding =item1
.
Note 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 WRONG...
=begin item1 --------------
The choices are: |
=item2 Liberty ==< Level 2 |==< Level 1
=item2 Death ==< Level 2 |
=item2 Beer ==< Level 2 |
=end item1 --------------
=comment CORRECT...
=begin item1 ---------------
The choices are: |==< Level 1
=end item1 ---------------
=item2 Liberty ==================< Level 2
=item2 Death ==================< Level 2
=item2 Beer ==================< Level 2
Ordered lists
An item is part of an ordered list if the item has a :numbered
configuration option:
=for item1 :numbered
Visito
=for item2 :numbered
Veni
=for item2 :numbered
Vidi
=for item2 :numbered
Vici
This would produce something like:
1. Visito
1.1. Veni
1.2. Vidi
1.3. Vici
although the numbering scheme is entirely at the discretion of the renderer, so it might equally well be rendered:
1. Visito
1a. Veni
1b. Vidi
1c. Vici
or even:
A: Visito
(i) Veni
(ii) Vidi
(iii) Vici
Alternatively, if the first word of the item consists of a single #
character, the item is treated as having a :numbered
option:
=item1 # Visito
=item2 # Veni
=item2 # Vidi
=item2 # Vici
To specify an unnumbered list item that starts with a literal #
, either
make the octothorpe verbatim:
=item V<#> introduces a comment
or explicitly mark the item itself as being unnumbered:
=for item :!numbered
# introduces a comment
The numbering of successive =item1
list items increments
automatically, but is reset to 1 whenever any other kind of non-ambient
Podlite block appears between two =item1
blocks. For example:
The options are:
=item1 # Liberty
=item1 # Death
=item1 # Beer
The tools are:
=item1 # Revolution
=item1 # Deep-fried peanut butter sandwich
=item1 # Keg
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 (=item2
, =item3
, etc.) only resets
(to 1) when the higher-level item's numbering either resets or increments.
To prevent a numbered =item1
from resetting after a non-item block,
you can specify the :continued
option:
=for item1
# Retreat to remote Himalayan monastery
=for item1
# Learn the hidden mysteries of space and time
I<????>
=for item1 :continued
# Prophet!
which produces:
1. Retreat to remote Himalayan monastery
2. Learn the hidden mysteries of space and time
????
3. Prophet!
Task lists
In addition to the ordered list Podlite also supports task lists, which are commonly known as checklists or to-do lists.
To create a task list item just apply a :checked
attribute to =item
block.
=for item :checked
Buy groceries
=for item :!checked
Clean the garage
The rendered output looks like this:
[X] Buy groceries
[ ] Clean the garage
Alternatively, if item content starts with brackets with space ([ ]
)
the item is treated as having a :!checked
attribute.
To select a checkbox, add an x
in between the brackets ([x]
). it eqvivalent
of :checked
attribute.
For example:
=item [x] Buy groceries
=itme [ ] Clean the garage
It possiible to create multilevel to-do lists, which permits the inclusion of various task levels or sub-tasks. Here's an example:
=item1 [ ] Work
=item2 [ ] Prepare the presentation
=item2 [x] Send emails
=item1 [ ] Home
=item2 [ ] Vacuum the living room
=item2 [ ] Water the plants
Unordered lists
List items that are not :numbered
or :checked
are treated as defining unordered
lists. Typically, such lists are rendered with bullets. For example:
=item1 Reading
=item2 Writing
=item3 'Rithmetic
might be rendered:
• Reading
— Writing
¤ 'Rithmetic
As with numbering styles, the bulletting strategy used for different levels within a nested list is entirely up to the renderer.
Multi-paragraph list items
Use the delimited form of the =item
block to specify items that
contain multiple paragraphs. For example:
Let's consider two common proverbs:
=begin item :numbered
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 :numbered
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.
which produces:
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.
Definition lists
To create term/definition lists, use a =defn
block. This is
similar in effect to an =item
block, in that a series of =defn
blocks implicitly defines a list (but which might then be rendered into
HTML using <DL>...</DL>
tags, rather than <UL>...</UL>
tags)
The first non-blank line of content is treated as a term being defined, and the remaining content is treated as the definition for the term. For example:
=defn MAD
Affected with a high degree of intellectual independence.
=defn MEEKNESS
Uncommon patience in planning a revenge that is worth while.
=defn
MORAL
Conforming to a local and mutable standard of right.
Having the quality of general expediency.
Like other kinds of list items, definitions can be numbered, using either an
option or a leading #
:
=for defn :numbered
SELFISH
Devoid of consideration for the selfishness of others.
=defn # SUCCESS
The one unpardonable sin against one's fellows.
Nesting blocks
Any block can be nested by specifying a :nested
option on it:
=begin para :nested
We are all of us in the gutter,E<NL>
but some of us are looking at the stars!
=end para
However, qualifying each nested paragraph individually quickly becomes tedious if there are many in a sequence, or if multiple levels of nesting are required:
=begin para :nested
We are all of us in the gutter,E<NL>
but some of us are looking at the stars!
=end para
=begin para :nested(2)
-- Oscar Wilde
=end para
So Podlite provides a =nested
block that marks all its contents as being
nested:
=begin nested
We are all of us in the gutter,E<NL>
but some of us are looking at the stars!
=begin nested
-- Oscar Wilde
=end nested
=end nested
Nesting blocks can contain any other kind of block, including implicit paragraph and code blocks. Note that the relative physical indentation of the blocks plays no role in determining their ultimate nesting. The preceding example could equally have been specified:
=begin nested
We are all of us in the gutter,E<NL>
but some of us are looking at the stars!
=begin nested
-- Oscar Wilde
=end nested
=end nested
Tables
Simple tables can be specified in Podlite using a =table
block.
The table may be given an associated description or title using the
:caption
option.
Columns are separated by two or more consecutive whitespace characters
(double-space),
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
(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 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
With header:
=begin table
Directive Specifies
_________ ____________________________________________________
C<=begin> Start of an explicitly terminated block
C<=config> Lexical modifications to a block or markup code
=end table
Or:
=begin table
Energy Source Benefit
Solar power Reduces electricity bills
Wind energy Clean power source
Hydroelectric power Highly efficient
Geothermal energy Low emissions
Biomass Reduces waste
=end table
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
Advanced Table Format
Tables may construct using =row
and =cell
blocks.
The =row
blocks represent individual rows within the table.
The =cell
blocks exist within rows and contain the actual content of the table.
These cells can contain text, data, or other blocks.
=begin table
=begin row
=cell Fruits
=cell Bananas
=cell Yellow and ripe
=end row
=begin row
=cell Vegetables
=cell Carrots
=begin cell
=para Crunchy and orange
=end cell
=end row
=end table
Each =row
block may have an optional :header
attribute, designating
it as a header row. Header rows typically contain labels or titles
for columns and are visually distinct.
=begin table
=begin row :header
=cell Category
=cell Product
=cell Description
=end row
=begin row
=cell Fruits
=cell Bananas
=cell Yellow and ripe
=end row
=begin row
=cell Vegetables
=cell Carrots
=cell Crunchy and orange
=end row
=end table
The =cell
blocks can also have two important attributes:
:colspan
- This attribute specifies the number of columns a cell should span horizontally. It allows cells to merge and occupy multiple adjacent columns, creating a visually unified cell.
:rowspan
- This attribute determines how many rows a cell should span vertically.
Cells with
:rowspan
can cover multiple rows in a table, creating a vertical merge effect.
These example demonstrate how :colspan
and :rowspan
attributes can be used
to create tables with merged cells, which is especially useful for complex
data structures.
=begin table
=begin row :header
=for cell :colspan(2)
Item and Quantity
=cell Description
=end row
=begin row
=cell Apples
=cell 5
=for cell :rowspan(2)
Fruit for snacking
=end row
=begin row
=cell Bananas
=cell 3
=end row
=end table
It draw somethink like this:
---------------------------------------------------------------
| Item and Quantity | Description |
|----------------------------------|--------------------------|
| Apples | 5 | |
|--------------|-------------------| Fruit for snacking |
| Bananas | 3 | |
---------------------------------------------------------------
Each =row
block may only contain =cell
blocks or blank lines as delimiters.
All other types of blocks within the =row
are implicitly wrapped
by =cell
blocks.
For example:
=begin table
=begin row :header
=cell Diagram or Picture
=cell Description
=end row
=begin row
=picture spacecraft_in_orbit.jpg
=para
A vehicle designed for space travel
=end row
=begin row
=Mermaid
graph TD;
A[Space Station] --> B[Mars Base]
A space station connected to a Mars base
=end row
=end table
Table from CSV files or data blocks
It is possible to create tables from files or data blocks.
To do this, use the file:
or data:
schema in the first non-blank line
to specify the source of the table data.
For example:
=table file:recipe_ingredients.csv
=for table :caption('Basic cake recipe ingredients')
data:recipe_ingredients
=begin data :key<recipe_ingredients> :mime-type<text/csv>
ingredient,quantity,unit
flour,2,cups
sugar,1,cups
eggs,2,items
butter,0.5,cups
baking powder,2,teaspoons
=end data
Named or modular custom blocks
Blocks whose names contain at least one uppercase and one lowercase letter are assumed to be destined for specialized renderers or parser plug-ins. For example:
=begin Xhtml
<object type="video/quicktime" data="onion.mov">
=end Xhtml
or:
=Image http://www.perlfoundation.org/images/perl_logo_32x104.png
Ideally, each named block should have a corresponding handler responsible for its rendering and processing.
In the absence of a handler for named block, the implementation should allow the content to degrade gracefully, ensuring that the core message or functionality remains accessible even if some advanced features cannot be rendered. As result, that blocks my be displayed as verbatim or placeholder content or even not rendered at all.
Alongside the verbatim or placeholder content, the renderer could provide an unobtrusive yet informative error message, explaining that the named block could not be processed.
Note that all block names consisting entirely of lowercase or entirely of uppercase letters are reserved. See #Semantic blocks.
To check custom markup codes, refer to #Custom markup codes.
Podlite comments
Podlite comments refers to Podlite blocks that should not be displayed by any renderer. However, they are still may be part of the internal Podlite representation. However, they can still be part of internal Podlite representation.
Comments are useful for meta-documentation (documenting the documentation):
=comment Add more here about the algorithm
and for temporarily removing parts of a document:
=item # Retreat to remote Himalayan monastery
=item # Learn the hidden mysteries of space and time
=item # Achieve enlightenment
=begin comment
=item # Prophet!
=end comment
Data blocks
The =data
block is used to embed various types of data directly into a document.
For example, to include a CSV file in a document, it is possible to use the following syntax:
=begin data :key<sales_data> :mime-type<text/csv>
name,month,amount
John Doe,January,1000
Jane Doe,February,1500
=end data
Each =data
block can be given a :key
option, to name it. The contents
of any =data
block with a key are addressable via
the data:
schema. For example:
=begin data :key<employee_data> :mime-type<text/csv>
id,name,position,department
1,John Doe,Manager,Marketing
2,Jane Smith,Developer,Engineering
3,Bob Brown,Designer,Product
=end data
=table data:employee_data
Each =data
block can include several attributes to provide additional information
about the contained data:
:filename
- This option specifies the original file name of the embedded data, which
can be used to hint at the type of data contained if the
:mime-type
is not explicitly provided.
:mime-type
- This option indicates the MIME type of the data, such as
image/png
for PNG images, which helps determine how the data should be interpreted and processed. - Here is a list of common MIME types and their corresponding file extensions:
MIME Type | File Extension |
---|---|
text/plain | .txt |
text/markdown | .md, .markdown |
text/podlite | .podlite, .pod6 |
application/json | .json |
application/xml | .xml |
image/jpeg | .jpg, .jpeg |
image/png | .png |
application/pdf | |
application/zip | .zip |
audio/mpeg | .mp3 |
video/mp4 | .mp4 |
application/msword | .doc, .docx |
text/csv | .csv |
text/tab-separated-values | .tsv, .tab |
:access-time
and:modify-time
- These attributes record the times when the data was last accessed or edited.
:encoding
- This option specifies the encoding method used to store the data.
For non-text data, such as images in PNG format,
the encoding method
base64
is used.
Example of storing images in =data
blocks:
=begin data :key<Logo> :filename<Logo.png> :mime-type<image/png>
= :access-time<2022-01-01T00:00:00Z> :modify-time<2022-01-02T10:00:00Z>
= :encoding<base64>
iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAS0lEQVR4AWPOPfjpvWZSW4db
ZLk+kwTHP24HUQYGfi4WTiZVAcYfDtIMDCJc/38xK6TWth37wcrw7cufF8yeeWUGrL8Z33Ey
/t0HAMBnF2nt5sNRAAAAAElFTkSuQmCC
=end data
=picture data:Logo
In the example above, we have a =data
block with :id
Logo
that stores
the base64-encoded image data. We also specify the filename, mime type,
access time, and edit time as attributes of the =data
block.
The image can then be referenced using the `=picture` block with the scheme
data:
and the block name Logo
.
The =data
blocks are just regular Podlite blocks and may appear anywhere
within a source file, and as many times as required.
Note that in Podlite, it is possible to specify =data
blocks
after the point in the source where their contents will be used.
=data
blocks are never rendered by the standard Podlite renderers.
Semantic blocks
All uppercase block typenames are reserved for specifying standard documentation, publishing, or source components.
Standard semantic blocks include:
=NAME
=AUTHOR
=VERSION
=SYNOPSIS
=DESCRIPTION
=USAGE
=INTERFACE
=METHOD
=SUBROUTINE
=OPTION
=DIAGNOSTIC
=ERROR
=WARNING
=DEPENDENCY
=BUG
=SEE-ALSO
=ACKNOWLEDGEMENT
=COPYRIGHT
=DISCLAIMER
=LICENCE
=LICENSE
=TITLE
=SECTION
=CHAPTER
=APPENDIX
=TOC
=INDEX
=FOREWORD
=SUMMARY
The plural forms of each of these keywords are also reserved, and are aliases for the singular forms.
Most of these blocks are typically used in their full delimited forms:
=begin SYNOPSIS
use Magic::Parser;
my Magic::Parser $parser .= new();
my $tree = $parser.parse($fh);
=end SYNOPSIS
Semantic blocks can be considered to be variants of the =head1
block
in most respects (and most renderers will treat them as such). The main
difference is that, in a =head1
block, the heading is the contents of
the block; whereas, in a semantic block, the heading is derived from the
typename of the block itself and the block contents are instead treated as
the =para
or =code
block(s) belonging to the heading.
The use of these special blocks is not required; you can still just write:
=head1 SYNOPSIS
=begin code :lang<raku>
use Magic::Parser
my Magic::Parser $parser .= new();
my $tree = $parser.parse($fh);
=end code
However, using the keywords adds semantic information to the
documentation, which may assist various renderers, summarizers, coverage
tools, document refactorers, and other utilities. This is because a
semantic block encloses the text it controls (unlike a =head1
,
which merely precedes its corresponding text), so using semantic blocks
produces a more explicitly structured document.
Note that there is no requirement that semantic blocks be rendered in
a particular way (or at all). Specifically, it is not necessary to
preserve the capitalization of the keyword. For example, the
=SYNOPSIS
block of the preceding example might be rendered like so:
3. Synopsis
use Raku::Magic::Parser; my $rep = Raku::Magic::Parser.parse($fh, :all_pod);
Table of contents
The =toc
block creates an autogenerated table of contents (TOC)
in a document. The TOC is an index of section titles within the document,
and its structure is determined by the document's organization.
The first non-blank line of =toc
content is treated as a selector.
For example:
=toc head1, head2, head3, item1, item2, table
or:
=toc head1, head2, head3
The TOC displays without a caption by default.
However, a caption can be specified using the :caption
attribute of the =toc
block.
For example:
=for toc :caption('Table of contents')
head1, head2, head3
The TOC entries are built using the :caption
attribute content
within the block. If this attribute is not present, the text
presentation of the block's content serves as the TOC entry.
The depth of the generated TOC is determined by the "Selector" argument. The selector is processed, and headers or filtered blocks that allow levels are used to build the TOC levels. If a block lacks an associated level, it is rendered at a level one higher than the previous block with a level in the TOC.
Note that all semantic blocks are treated as equivalent
to head1
headings, and the =item1
/=item
equivalence is preserved.
The :folded-levels
attribute indicates which levels of the TOC should
be folded.
=for toc :folded-levels[2,3] :caption('Table of contents')
head1, head2, item1
If the :folded-levels
attribute is provided with a set
of key-value pairs, it indicates the folding state of each
specified level.
For example:
=for toc :folded-levels< 2=>1, 4 => 1, 3=>0 >
head1, head2, head3, item1, item2
The value 0
for level 3
indicates that this level should
remain unfolded. Levels 2
and 4
are folded.
This configuration enables customized folding within the TOC.
The TOC is inserted at the location of the =toc
block.
To enable the autogenerated TOC controlled by the renderer, set the :toc
document attribute for the =pod
block. In this case, the specific configuration
and outcome of the TOC are determined by the renderer implementation.
Include block
The =include
block enables reuse of specific parts of documents within
project sources. This feature is particularly useful for complex documents
that require including sections from different files while maintaining the
overall context and structure.
The =include
block is followed by a "Selector" that specifies the
content to be included.
In this example, the content of the file chapter01.pod6
located in the
./includes
directory is included:
=include file:./includes/chapter01.pod6
A wildcard "Selector" enables inclusion of content from all the Markdown files:
=include file:./includes/*.md
It is possible to include blocks from the same document. This feature proves valuable when reusing parts of existing content.
For instance, a semantic block =VERSION
can be included as demonstrated:
=include VERSION
=VERSION 1.0.0
or, equivalently:
=VERSION 1.0.0
=VERSION 1.0.0
Podlite detects the type of the included file by its extension.
For example, if the included file has a .md
extension,
it is treated as a Markdown file.
To override the type of the included file, use the :mime-type
attribute. This attribute specifies the MIME type of the included file.
For example:
=for include :mime-type('text/podlite')
file:./includes/text.txt
The :mime-type
attribute is particularly useful when including files with
extensions that do not match their actual MIME type.
Security considerations are crucial, as adding content from external sources could potentially create vulnerabilities such as injecting harmful code or malicious material. Tools responsible for displaying and handling the content should provide warnings in such situations.
Inserting pictures
Podlite allows to include images using a =picture
block with an inline version
represented as P<alternative text|source of the image>
:
=picture astronaut.png
=para In the vast expanse of the cosmos, an intrepid P<astronaut|astronaut.png>
floats weightlessly above the Earth.
The first non-blank line of content within the =picture
block specifies the
source of the image, and the remaining content is treated as caption.
This source can be either local or remote, and it can be
specified using different schemas: https:
for remote images, file:
for
local ones, or data:
for embedded images in the document.
If no schema is provided, file:
is used as default.
=picture https://example.com/image.jpg
=picture file:/local/image.png
=picture /local/image.png
=picture ../image.png
=picture data:Logo
Following the source line, it possible to include an image caption.
=picture astronaut.png
In the vast expanse of the cosmos, an intrepid B<astronaut>
floats weightlessly above the Earth.
In the delimited form of =picture
, multiple text blocks can be included:
=begin picture
astronaut.png
In the vast expanse of the cosmos, an intrepid B<astronaut>
floats weightlessly above the Earth.
This astronaut explores the vastness of space.
=end picture
All inline markup codes supported by ordinary paragraph blocks can be used within picture captions.
A caption can also be defined using the :caption
attribute:
=for picture :caption<diagram>
diag01.png
Mathematical formulas
To include mathematical formulas, use a =formula
block with an inline version
represented as F<>
.
To insert mathematical expressions, use LaTeX-style syntax, which is a commonly used format for writing mathematical equations.
=formula
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
In a right triangle, the length of the hypotenuse can be calculated
using the Pythagorean theorem: F<a^2 + b^2 = c^2>.
Euler's identity, F<e^{i\pi} + 1 = 0>, is a fundamental equation in
complex analysis.
The formula caption can be defined using the :caption
attribute:
=formula :caption<Quadratic Formula>
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
Markdown support
Podlite includes built-in support for Markdown, making it easy to include Markdown
content within Podlite documents. This is achieved using the =markdown
block.
=begin markdown
## Markdown Example
You can use all the standard Markdown syntax within this block. For example:
- *Italic text* using asterisks or underscores: *italic* or _italic_.
- **Bold text** using double asterisks or underscores: **bold** or __bold__.
- [Links](https://example.com) with the `[text](url)` syntax.
- Unordered lists using `-`, `*`, or `+`:
- Item 1
- Item 2
- Ordered lists using numbers:
1. First item
2. Second item
- Code blocks with backticks:
```python
def hello_world():
print("Hello, World!")
```
- Blockquotes with the `>` symbol:
> This is a blockquote.
=end markdown
This block allows to seamlessly combine Podlite's structured blocks with the flexibility of Markdown.
Markup codes
Markup codes enable inline markup within the text of (most) Podlite block types. They are a form of block that can contain only other markup codes. Specifically, markup codes can nest:
B<I shall say this loudly
Z<and repeatedly>
and with emphasis.>
All Podlite markup codes consist of a single capital letter followed
immediately by a set of angle brackets. The brackets contain the text or
data to which the markup code applies. A set of single
angles (<...>
), a set of double angles («...»
), or multiple
single-angles (<<<...>>>
) can be used.
Within angle delimiters, you cannot use sequences of the same angle characters that are longer than the delimiters:
=comment
These are errors...
C< $foo<<bar>> >
The Perl 5 heredoc syntax was: C< <<END_MARKER >
Sequences of angles that are the same length as the delimiters can be used, but they must be balanced. For example:
C< $foo<bar> >
C<< $foo<<bar>> >>
If an unbalanced angle is needed, either use different delimiters:
C«$foo < $bar»
The Perl 5 heredoc syntax was: C« <<END_MARKER »
or delimiters with more consecutive angles than the text contains:
C<<$foo < $bar>>
The Perl 5 heredoc syntax was: C<<< <<END_MARKER >>>
A markup code ends at the matching closing angle bracket(s), or at the end of the enclosing block or markup code in which the opening angle bracket was specified, whichever comes first (this includes paragraph and abbreviated blocks, ending with blank a line). Podlite parsers are required to issue a warning whenever a markup code is terminated by the end of an outer block rather than by its own delimiter (unless the user explicitly disables the warning).
Significance indicators
Podlite provides three markup codes that flag their contents with increasing levels of significance:
The
U<>
markup code specifies that the contained text is unusual or distinctive; that it is of minor significance. Typically such content would be rendered in an underlined style.The
I<>
markup code specifies that the contained text is important; that it is of major significance. Such content would typically be rendered in italics or in<em>...</em>
tagsThe
B<>
markup code specifies that the contained text is the basis or focus of the surrounding text; that it is of fundamental significance. Such content would typically be rendered in a bold style or in<strong>...</strong>
tags.
Mistake marking
The code O<>
can be used for strikethrough text, where 'O' stands
for "Overstrike." This indicates that certain words are a
mistake and should not be included in the document.
O<The sky is green.> Our planet's sky is usually blue.
Text positioning
Podlite provides two markup codes for positioning characters or words.
To create subscript text, use the
J<>
markup code, where 'J' represents "Junior text." Subscript positions one or more characters slightly below the normal line of type.HJ<2>O
This code renders as
H<sub>2</sub>O
, which signifies that the '2' is positioned slightly below the baseline, as is often seen in chemical formulas likeH₂O
(water).To create superscript text, it possible to use the
H<>
markup code, where 'H' stands for "High text." Superscript positions one or more characters slightly above the normal line of typeXH<2>
This code renders as
X<sup>2</sup>
, indicating that the'2'
is positioned slightly above the baseline. This is commonly used for mathematical exponents, as inX²
.
Definitions
The D<>
markup code indicates that the contained text is a
definition, introducing a term that the adjacent text
elucidates. It is the inline equivalent of a =defn
block.
For example:
There ensued a terrible moment of D<coyotus interruptus>: a brief
suspension of the effects of gravity, accompanied by a sudden
to-the-camera realization of imminent downwards acceleration.
A definition may be given synonyms, which are specified after a vertical bar and separated by semicolons:
A D<markup code|markup codes;formatters> provides a way
to add inline mark-up to a piece of text.
A definition would typically be rendered in italics or <dfn>...</dfn>
tags and will often be used as a link target for subsequent instances of the
term (or any of its specified synonyms) within a hypertext.
Example specifiers
Podlite provides markup codes for specifying inline examples of input, output, code, and metasyntax:
The
T<>
markup code specifies that the contained text is terminal output; that is: something that a program might print out. Such content would typically be rendered in a fixed-width font or with<samp>...</samp>
tags. The contents of aT<>
code are always space-preserved (as if they had an implicitS<...>
around them). TheT<>
code is the inline equivalent of the=output
block.The
K<>
markup code specifies that the contained text is keyboard input; that is: something that a user might type in. Such content would typically be rendered in a fixed-width font (preferably a different font from that used for theT<>
markup code) or with<kbd>...</kbd>
tags. The contents of aK<>
code are always space-preserved. TheK<>
code is the inline equivalent of the=input
block.The
C<>
markup code specifies that the contained text is code; that is, something that might appear in a program or specification. Such content would typically be rendered in afixed-width font
(preferably a different font from that used for theT<>
orK<>
markup codes) or with<code>...</code>
tags. The contents of aC<>
code are space-preserved and verbatim. TheC<>
code is the inline equivalent of the=code
block.To include other markup codes in a
C<>
code, the code can be lexically reconfigured:=begin para =config C< :allow<E I>> Raku makes extensive use of the C<E<laquo>> and C<E<raquo>> characters, for example, in a hash look-up: C<%hashI<E<laquo>>keyI<E<raquo>>> =end para
To enable entities in every
C<...>
, place a=config C<> :allow<E>
at the top of the document.The
R<>
markup code specifies that the contained text is a replaceable item, placeholder, or 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>
or:
Then enter your details at the prompt: =for input Name: R<your surname> ID: R<your employee number> Pass: R<your 36-letter password>
Typically replaceables would be rendered in fixed-width italics or with
<var>...</var>
tags. The font used should be the same as that used for theC<>
code, unless theR<>
is inside aK<>
orT<>
code (or the equivalent=input
or=output
blocks), in which case their respective fonts should be used.
Verbatim text
The V<>
markup code treats its entire contents as being verbatim,
disregarding every apparent markup code within it. For example:
The B<V< V<> >> markup code disarms other codes
such as V< I<>, C<>, B<>, and M<> >.
Note 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 codes surrounding the V<>
code
are still applied to its contents. For example, the previous example
is rendered:
The V<> markup code disarms other codes such as I<>, C<>, B<>, and M< >.
You can prespecify markup codes that remain active within
a V<>
code, using the :allow
option.
Inline comments
The Z<>
markup code indicates that its contents constitute a
zero-width comment, which should not be rendered by any renderer.
For example:
The "exeunt" command Z<Think about renaming this command?> is used
to quit all applications.
In certain scenarios, the Z<>
code is used to break up text that
would otherwise be considered mark-up:
In certain scenarios, the ZZ<><> code is used to break up text that
would otherwise be considered mark-up.
That technique still works, but it's now easier to accomplish the same goal using a verbatim markup code:
In certain scenarios, the V<V<Z<>>> code is used to break up text that
would otherwise be considered mark-up.
Moreover, the C<>
code automatically treats its contents as being
verbatim, which often eliminates the need for the V<>
as well:
In certain scenarios, the V<C<Z<>>> code was widely used to break up text
that would otherwise be considered mark-up.
The Z<>
markup code is the inline equivalent of a
=comment block.
Links
The L<>
code is used to specify all kinds of links, filenames, citations,
and cross-references (both internal and external).
A link specification consists of a scheme specifier terminated by a colon, followed by an external address (in the scheme's preferred syntax), followed by an internal address (again, in the scheme's syntax). All three components are optional, though at least one must be present in any link specification.
Usually, in schemes where an internal address makes sense, it will be
separated from the preceding external address by a #
, unless the
particular addressing scheme requires some other syntax. When new
addressing schemes are created specifically for Podlite, it is strongly
recommended that #
be used to mark the start of internal addresses.
Standard schemes include:
http:
andhttps:
- A standard web URL. For example:
- If the link does not start with
//
it is treated as being relative to the location of the current document:
This module needs the LAME library
(available from L<http://www.mp3dev.org/mp3/>)
See also: L<http:tutorial/faq.html> and
L<http:../examples/index.html>
file:
- A filename on the local system. For example:
- Filenames that don't begin with a
/
or a~
are relative to the current document's location:
Next, edit the global config file (that is, either
L<file:/usr/local/lib/.configrc> or L<file:~/.configrc>).
Then, edit the local config file (that is, either
L<file:.configrc> or L<file:CONFIG/.configrc>.
mailto:
- An email address. Typically, activating this type of link invokes a mailer. For example:
Please forward bug reports to L<mailto:devnull@rt.cpan.org>
man:
- A link to the system manpages. For example:
This module implements the standard
Unix L<man:find(1)> facilities.
doc:
- A link to other documents by utilizing semantic blocks
such as
=TITLE
or=NAME
as anchor points for these links. - For example:
- Moreover, the
doc:
scheme allows the use of an:id
attribute within the=TITLE
or=NAME
blocks to create unique identifiers for document linking. This ensures precision in navigation, as each identifier corresponds to a specific part of the document set. An example would be: - When Podlite processes a link, it can automatically use the document's title
from the
=TITLE
or=NAME
blocks as the display text for the hyperlink if no explicit text is provided. For example: - ... will be rendered as:
=NAME Dumper
You may wish to use L<doc:Dumper> to
view the results.
=for TITLE :id<Specification>
The Specification of Podlite
...
Read the L<spec|doc:Specification>.
...
=for TITLE :id<Specification>
The Specification of Podlite
=para
Please read "L<doc:Specification>".
Please read "The Specification of Podlite".
defn:
- A link to the block-form or inline definition of the specified term within the current document. For example:
- and later, to link back to the definition:
He was highly prone to D<lexiphania>: an unfortunate proclivity
for employing grandiloquisms (for example, words such as "proclivity",
"grandiloquism", and indeed "lexiphania").
=defn glossoligation
Restraint of the tongue (voluntary or otherwise)
To treat his chronic L<defn:lexiphania> the doctor prescribed an
immediate L<defn:glossoligation> or, if that proved ineffective,
a complete cephalectomy.
isbn:
andissn:
- The International Standard Book Number or International Standard Serial Number for a publication. For example:
The Perl Journal was a registered
serial publication (L<issn:1087-903X>)
To refer to a specific section within a webpage, manpage, or Podlite
document, add the name of that section after the main link, separated by
a #
. For example:
Also see: L<man:bash(1)#Compound Commands>,
L<doc:perlsyn#For Loops>, and
L<http://dev.perl.org/perl6/syn/S04.html#The_for_statement>
To refer to a section of the current document, omit the external address:
This mechanism is described under L<doc:#Special Features> below.
The scheme name may also be omitted in that case:
This mechanism is described under L<#Special Features> below.
Podlite includes the possibility of assigning a unique identifier to a block.
These identifiers can be explicitly assigned to any blocks using
the :id
attribute. Later, these identifiers are utilized for addressing blocks
and creating links.
=for head1 :id<intro>
Introduction
=for para :id<id1>
This is an introductory paragraph.
For more information, see L<here|#intro> and L<here|#id1>
In this example, the link reference to the header block identified by "intro" rather than the name "Introduction" and to the paragrapth block with identifier "id1".
Normally a link is presented as some rendered version of the link specification itself. However, you can specify an alternate presentation by prefixing the link with the desired text and a vertical bar. Whitespace is not significant on either side of the bar. For example:
This module needs the L<LAME library|http://www.mp3dev.org/mp3/>.
You could also write the code
L<in Latin | doc:Lingua::Romana::Perligata>
His L<lexiphanic|defn:lexiphania>> tendencies were, alas, incurable.
Contextual backlinks
Podlite introduces the concept of contextual backward links W<>
(or contextual backlinks),
enhancing the traditional linking mechanism by allowing to not
only reference another location but also provide specific
context around that reference. This context can take the form of opinions,
additional information, or any relevant commentary that enhances the understanding
of the referenced material.
For example:
This text can reveal the meaning of W<glossoligation|defn:glossoligation>
or:
We discuss here about W<doc:perldata>.
Contextual backlinks on the destination page can be displayed in various ways. They may appear with surrounding text chunks, providing context within the flow of the content. Alternatively, they can be placed at the end of the text, in the margin of the page, or highlighted in other visually distinctive ways.
Like traditional links, contextual backlinks allows the use of
all available link schemes, including https:
and doc:
, to link to external content.
Contextual backlinks might be visually distinguished from standard links through color coding.
Alias placements
The A<>
code 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>.
See #Aliases for further details of the aliasing macro mechanism.
Space-preserving text
Any text enclosed in an S<>
code is formatted normally, except that
every whitespace character in it—including any newline—is
preserved. These characters are also treated as being non-breaking
(except for the newlines, of course). For example:
The emergency signal is: S<
dot dot dot dash dash dash dot dot dot>.
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.
Entities
To include Unicode code points or HTML5 character references in a
Podlite document, specify the required entity using the E<>
code.
If the E<>
contains a number, that number is treated as the decimal
Unicode value for the desired code point. For example:
Podlite makes considerable use of E<171> and E<187>.
You can also use explicit binary, octal, decimal, or hexadecimal numbers:
Podlite makes considerable use of E<0b10101011> and E<0b10111011>.
Podlite makes considerable use of E<0o253> and E<0o273>.
Podlite makes considerable use of E<0d171> and E<0d187>.
Podlite makes considerable use of E<0xAB> and E<0xBB>.
If the E<>
contains anything that is not a number, the contents are
interpreted as a Unicode character name (which is always uppercase), or
else as an HTML5 named character reference. For example:
Podlite makes considerable use of E<LEFT DOUBLE ANGLE BRACKET>
and E<RIGHT DOUBLE ANGLE BRACKET>.
or, equivalently:
Podlite makes considerable use of E<laquo> and E<raquo>.
To include emoji codes, you can use the E<>
code along
with the colon-prefixed and postfix emoji shortname:
Podlite uses emoji codes to express emotions and actions,
such as E<:thumbsup:> for approval and E<:smile:> for happiness.
In this example, :smile:
and :thumbsup:
are emoji codes representing
the respective emojis. You can use any valid emoji code in this format
to include emojis in your Podlite document.
Note that the specific emoji codes and the emojis they represent may vary depending on the platform or system you are using.
Multiple consecutive entities (in any format) can be specified in a
single E<>
code, separated by semicolons:
Podlite makes considerable use of E<LEFT DOUBLE ANGLE BRACKET;hellip;0xBB;:smile:>.
Indexing terms
Anything enclosed in an X<>
code is an index entry. The contents
of the code are both formatted into the document and used as the
(case-insensitive) index entry:
An X<array> is an ordered list of scalars indexed by number,
starting with 0. A X<hash> is an unordered collection of scalar
values indexed by their associated string key.
An index entry where the indexed text and the index entry differ can be specified by separating the two with a vertical bar:
An X<array|arrays> is an ordered list of scalars indexed by number,
starting with 0. A X<hash|hashes> is an unordered collection of
scalar values indexed by their associated string key.
In the two-part form, the index entry comes after the bar and is case-sensitive.
Hierarchical index entries can be specified by separating indexing levels with commas:
An X<array|arrays, definition of> is an ordered list of scalars
indexed by number, starting with 0. A X<hash|hashes, definition of>
is an unordered collection of scalar values indexed by their
associated string key.
Multiple entries for a single indexed text can be specified by separating the entries with semicolons:
A X<hash|hashes, definition of; associative arrays>
is an unordered collection of scalar values indexed by their
associated string key.
The indexed text can be empty, creating a "zero-width" index entry:
X<|puns, deliberate>This is called the "Orcish Manoeuvre"
because you "OR" the "cache".
Annotations
Anything enclosed in an N<>
code is an inline note.
For example:
Space stations feature hydroponic gardens N<Plants grow without soil,
using mineral nutrient solutions.>, a necessity for long-term missions.
Renderers may present such annotations in various ways: as footnotes, endnotes, sidebars, pop-ups, tooltips, or expandable tags. They are never rendered as unmarked inline text. The previous example might be rendered as:
Space stations feature hydroponic gardens †, a necessity for long-term missions. and later:
Footnotes
† Plants grow without soil, using mineral nutrient solutions.
Module-defined handler for extends markup features
The M<>
code in Podlite extends the language's capabilities by allowing users
to specify additional processing instructions within their documents.
This is achieved by combining content text with a custom plug-in specifier,
followed by optional configuration information that is passed to a handler function.
The structure of the M<>
markup code as follows:
M< CONTENT-TEXT| R<MODULE_NAME> R<OPTIONAL CONFIG INFO>>
This syntax includes CONTENT-TEXT
section, followed by a
name specifier MODULE_NAME
and then the OPTIONAL CONFIG INFO
(see "Configuration syntax options").
The name specifier should follow the same rules as for
named blocks.
The M<>
formatting code is the inline equivalent of a
named block.
An example of how this code might be used is :
M< This text is highlighted in yellow |Marker :color('yellow') >.
In this example, the text "This text is highlighted in yellow"
is subject
to special handling specified by the Marker
module and
:color('yellow')
, indicating that the text should be highlighted in yellow.
If the MODULE_NAME
is unrecognized, the content text CONTENT-TEXT
should be
rendered as ordinary text. This ensures that documents remain readable even
if specific processing instructions cannot be executed. The renderer could provide
an unobtrusive yet informative error message, explaining that the custom
markup block could not be processed.
Block pre-configuration
The =config
directive allows you to prespecify standard configuration
information that is applied to every block of a particular type.
=config code :lang<python> :allow<B>
=config head1 :numbered
=config head2 :folded
Here, two configurations are outlined. The first one sets
the language for code blocks to python
and allows bold markup.
The second establishes that all level 1 headings will be numbered.
The general syntax for configuration directives is:
=config R<BLOCK_TYPE> R<CONFIG OPTIONS>
= R<OPTIONAL EXTRA CONFIG OPTIONS>
A =config
is a directive, not a block. Hence,
there is no paragraph or delimited form of the =config
directive.
Each =config
specification is lexically scoped to the surrounding
block or file in which it is specified.
Note that, if a particular block later explicitly specifies a configuration option with the same key, that option overrides the pre-configured option. For example, given the code blocks configurations in the previous example, to specify another language for code block:
=for code :lang<javascript>
print(JSON.stringify([1,2]]));
Pre-configuring markup codes
You can also lexically preconfigure a markup code, by naming it with a pair of angles as a suffix. For example:
=comment Always allow E<> codes in any (implicit or explicit) V<> code...
=config V<> :allow<E>
=comment All inline code allows I<>
=config C<> :allow<I>
Note that, even though the markup code is named using single-angles, the preconfiguration applies regardless of the actual delimiters used on subsequent instances of the code.
Aliases
The =alias
directive provides a way to define lexically scoped
synonyms for longer Podlite sequences, (meta)object declarators from the
code, or even entire chunks of ambient source. These synonyms can then
be inserted into subsequent Podlite using the
A<> markup code.
Note that =alias
is a fundamental Podlite directive, like =begin
or
=for
; there are no equivalent paragraph or delimited forms.
Macro aliases are lexically scoped to the surrounding Podlite block.
The simplest form of alias takes two arguments. The first is an identifier (which is usually specified in uppercase, though this is certainly not mandatory). The second argument consists of one or more lines of replacement text.
This creates a lexically scoped Podlite macro that can be invoked during
document generation by placing the identifier (i.e. the first argument
of the alias) in an A<>
markup code. This markup code is then
replaced by the text returned by 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. The replacement text can extend over multiple
lines by starting each following line with an =
(at the same level
of indentation as the =alias
directive itself) followed by at least
one whitespace. Each additional line 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 and conditions laid out by 4D Kingdoms Inc, as specified at:
The advantage of using aliases is that the same alias can be reused in multiple places in the documentation. If the replacement text needs to be changed, it requires modification in only a single place:
=alias PROGNAME Count Krunchem Constantly
=alias VENDOR Last Chance Receivers Intl
=alias TERMS_URLS L<http://www.c11.com/generic_conditions>
Notification blocks
These blocks, often referred to as admonitions, callouts, or alerts, serve to draw attention to different types of content, such as tips, warnings, or important notes.
To create specially formatted blocks highlighting information in Podlite,
the =nested
block and :notice
attribute are used.
For example:
=begin nested :notify<tip>
Remember to always use oven mitts when handling hot bakeware
to prevent burns.
=end nested
Below is a table outlining the different types of notification blocks along with a brief description of each type.
Type | Description |
---|---|
note | Provides additional information and context without interrupting the flow of the main content |
tip | Offers advice for doing things better or more easily |
important | Signifies that the information is crucial for understanding or success |
warning | Indicates urgent information that requires immediate attention to avoid potential problems |
caution | Advises readers about potential negative outcomes or risks associated with certain actions |
By default, the title of the notification block is its type identifier in title case.
The title of the block and visibility of the information can be customized
using the :caption
and :folded
options.
=begin nested :caption<"Astronaut's Reminder"> :notify<important> :folded
Space missions require meticulous planning and adherence to safety protocols.
Neglecting these can lead to mission failure or, worse, endanger lives.
=end nested
Title-only callouts can be created by omitting the body.
=for nested :notify<important> :folded :caption<"Title-only callout">
Notification blocks are displayed with distinctive colors and icons that indicate the significance of the content.
SUMMARY
Directives
Directive | Specifies |
---|---|
=begin | Start of an explicitly terminated block |
=config | Lexical modifications to a block or markup code |
=end | Explicit termination of a =begin block |
=for | Start of an implicitly (blank-line) terminated block |
=alias | Define a Podlite macro |
Blocks
Block typename | Specifies |
---|---|
=code | Verbatim pre-formatted sample source code |
=comment | Content to be ignored by all renderers |
=defn | Definition of a term |
=head N | Nth-level heading |
=input | Pre-formatted sample input |
=item | First-level list item |
=item N | Nth-level list item |
=nested | Nested block contents within the current context |
=output | Pre-formatted sample output |
=para | Ordinary paragraph |
=pod | No "ambient" blocks inside |
=table | Simple rectangular table |
=data | Data section |
=toc | Autogenerated table of contents |
=include | Include other blocks or documents |
=picture | Insert pictures |
=formula | Mathematical formulas |
=markdown | Markdown support |
= RESERVED | Semantic blocks (=SYNOPSIS , =BUGS , etc.) |
= Typename | User-defined block |
Inline markup codes
Formatting code | Specifies |
---|---|
A<...> | Replaced by contents of specified macro/object |
B<...> | Basis/focus of sentence (typically rendered bold) |
C<...> | Code (typically rendered fixed-width) |
D<...|...;...> | Definition (D<R<defined term>|R<synonym>;R<synonym>;...> ) |
E<...;...> | Entity names or numeric codepoints (E<R<entity1>;R<entity2>;...> ), emoji |
F<...> | Mathematical formula |
G<...> | Reserved |
H<...> | Superscript |
I<...> | Important (typically rendered in italics) |
J<...> | Subscript |
K<...> | Keyboard input (typically rendered fixed-width) |
L<...|...> | Link (L<R<display text>|R<destination URI>> ) |
M<...:...> | Module-defined code (M<R<scheme>:R<contents>> ) |
N<...> | Note (not rendered inline) |
O<...> | Strikethrough |
P<...> | Inline eqivalent for =picture block |
Q<> | reserved |
C<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<V><...> | Verbatim (internal markup codes ignored) |
W<...|...> | Contextual backlinks |
X<...|..,..;...> | Index entry (X<R<display text>|R<entry>,R<subentry>;...> ) |
Y<> | Reserved |
Z<...> | Zero-width comment (contents never rendered) |
LICENSE
Artistic license 2.0