Podlite - a lightweight markup language

This document is still being worked on!

It's not finished yet, but it's available for everyone to see and comment on. This way, it can get better with everyone's input.

If you have any ideas to make it better, or if you have any questions, you're welcome to suggest changes or start a conversation on our GitHub page.

AUTHORS

VERSION

1.0-beta2

CHANGES

1.0-beta2

New:

  • 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

Deprecated/removed:

  • =finish

  • markers in comments

1.0-beta1

New:

  • 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:

  • :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, but see #Aliases. 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) C«key => 1»
Boolean (false) :!key :key(0) C«key => 0»
String :key<str> :key('str') C«key => 'str'»
List :key<1 2 3> :key[1,2,3] C«key => [1,2,3]»
Hash C«:key{a=>1, b=>2}» C«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 specifies that the block may be given an associated description or title using the :caption option.
Usually, this description uses for build table of contents.
:id
This option allows to explicitly define identificator for blocks and use those IDs for linking, rather than relying on it content (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:
    =begin para :nested
    =begin para :nested
    =begin para :nested
    "We're going deep, deep, deep undercover!"
    =end para
    =end para
    =end para
This can be simplified by giving the :nested option a positive integer value:
    =begin para :nested(3)
    "We're going deep, deep, deep undercover!"
    =end para
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:
    =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
Note that :!nested could also be used for this purpose:
    =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 possible to apply a :checked attributes to any block. The most common use of this option is to create task lists.
For unchecked checkbox the :!checked is used.
The task list item marker (checkbox) is added to the output. In an 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.
:lang
This option used to provide information about the programming language used in a specific code block. This helps in ensuring 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:
Matching languages and lang attribute values
Programming Language Possible :lang Values
Python python
Raku raku
JavaScript javascript
Java java
C++ cpp
HTML html
CSS css
:allow
This option expects a list of formatting 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.

A table of correspondences for some Podlite blocks and markdown blocks
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 =headN 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 formatting 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 formatting 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 formatting 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 formatting 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 {
      B<say> 'Hello R<name>';
  }

Note that the use of the :allow option also makes it possible for verbatim formatting 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 formatting 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 formatting 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" formatting code within the block.

For example, to include a small amount of input in a sample of output you could use the K<> formatting 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 formatting 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 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

Note that all block names consisting entirely of lowercase or entirely of uppercase letters are reserved. See #Semantic blocks.

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 in determining how the data should be interpretered and processed.
Here is a list of few well-known 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 .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
This attributes record time for 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 the 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, source components, or meta-information of a compunit it needs to be able to be selected for loading.

Standard semantic blocks include:

    =NAME
    =AUTHOR
    =VERSION
    =CREATED
    =EMULATES
    =EXCLUDES
    =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 would typically be 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
        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 is used to make 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 is, by default, displayed without a caption. However, the value assigned to the :caption attribute of the =toc block is used to generate a caption for the TOC.

For example:

  =for toc :caption('Table of contents')
  head1, head2, head3 

To build the entries in the TOC, the content of the :caption attribute within the block is used. If this attribute does not exist, then the text presentation of the block's content is utilized as the TOC entry.

The depth of the generated TOC is determined by the "Selector" argument. The selector processed, and headers or filtered blocks that allow levels are used to build the TOC levels. If a block does not have an associated level, it is rendered at a level one higher than the previous block with a level in the TOC.

Note also that all semantic blocks are treated as equivalent to head1 headings, and the =item1/=item equivalence is preserved.

The TOC is inserted at the location of the =toc block.

To enable the autogenerated TOC, controlled and maintained by render, set the :toc document attribute for =pod block. In this case, the specific configuration and outcome of the TOC are influenced by the settings of the concrete render implementation.

Include block

The =include block is a powerful tool that allows to reuse specific parts of documents within project sources. This is particularly handy when dealing with complex documents that require to include certain sections from different files while keeping the overall context and structure intact.

The =include block is followed by an "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" serves this purpose, enabling inclusion of content from all the Markdown files:

=include file:./includes/*.md

It's possible to include blocks from the same document being worked on. 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 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 by extension, you can use the :mime-type attribute. This attribute allows you to specify 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.

It's crucial to think about security concerns, 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 be able to provide a warning 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 indicated using different schemas: https: for remote images, file: for local ones, or data for embedded images in to the document. If no schema is provided, it defaults to file:.

 =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 delimited form of =picture it possible to include as match texts as needed:

 =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

It possible to use all inline markup codes that are supported by ordinary paragraph blocks.

Alternatively, you can define the image caption 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.

It possible to define the formule caption 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.

Formatting codes

Formatting codes provide a way to add inline mark-up to a piece of text within the contents of (most types of) Podlite block. Formatting codes are themselves a type of block, and may nest other formatting codes. other type of block (most often, other formatting codes). In particular, you can nest comment blocks in the middle of a formatting code:

    B<I shall say this loudly
    Z<and repeatedly>
    and with emphasis.>

All Podlite formatting 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 formatting code applies. You can use a set of single angles (<...>), a set of double angles («...»), or multiple single-angles (<<<...>>>).

Within angle delimiters, you cannot use sequences of the same angle characters that are longer than the delimiters:

    =comment
        These are errors...

    C< $foo<<barB«>>» >
    The Perl 5 heredoc syntax was: C< <<END_MARKER >

You can use sequences of angles that are the same length as the delimiters, but they must be balanced. For example:

C<  $foo<bar>   >
    C<< $foo<<bar>> >>

If you need an unbalanced angle, either use different delimiters:

    C«$foo < $barB<»>
    The Perl 5 heredoc syntax was: C« <<END_MARKER B<»>

or delimiters with more consecutive angles than your text contains:

    C<<$foo < $barB«>>»
    The Perl 5 heredoc syntax was: C<<< <<END_MARKER B«>>>»

A formatting code ends at the matching closing angle bracket(s), or at the end of the enclosing block or formatting 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 formatting 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 formatting codes that flag their contents with increasing levels of significance:

  • The U<> formatting 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<> formatting 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> tags

  • The B<> formatting 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

It possible strikethrough words using the code C<O<>, where 'O' stands for "Overstrike." This is a way to indicate 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 formatting codes that allow positioning characters or words.

  • To create subscript text, you can use the J<> formatting 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 like H₂O (water).

  • To create superscript text, it possible to use the H<> formatting code, where 'H' stands for "High text." Superscript positions one or more characters slightly above the normal line of type

    XH<2>
    

    This code renders as "sup2</sup>," indicating that the '2' is positioned slightly above the baseline. This is commonly used for mathematical exponents, as in X².

Definitions

The D<> formatting 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<formatting code|formatting 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 formatting codes for specifying inline examples of input, output, code, and metasyntax:

  • The T<> formatting 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 a T<> code are always space-preserved (as if they had an implicit S<...> around them). The T<> code is the inline equivalent of the =output block.

  • The K<> formatting 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 the T<> formatting code) or with <kbd>...</kbd> tags. The contents of a K<> code are always space-preserved. The K<> code is the inline equivalent of the =input block.

  • The C<> formatting 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 a fixed-width font (preferably a different font from that used for the T<> or K<> formatting codes) or with <code>...</code> tags. The contents of a C<> code are space-preserved and verbatim. The C<> code is the inline equivalent of the =code block.

    To include other formatting codes in a C<> code, you can lexically reconfigure it:

      =begin para
      B<=config C<> :allow<E I>>
      Raku makes extensive use of the B<E<laquo>> and B<E<raquo>>
      characters, for example, in a hash look-up:
      %hashB<I<E<laquo>>>keyB<I<E<raquo>>>
      =end para
    

    To enable entities in every C<...> put a =config C<> :allow<E> at the top of the document

  • The R<> formatting code 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 ln command is: ln source_file target_file
    

    or:

      Then enter your details at the prompt:
      =for input
          Name: your surname
            ID: your employee number
          Pass: 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 the C<> code, unless the R<> is inside a K<> or T<> code (or the equivalent =input or =output blocks), in which case their respective fonts should be used.

Verbatim text

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

The B<V< V<> >> formatting code 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 formatting codes surrounding the V<> code are still applied to its contents. For example the previous example is rendered:

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

You can prespecify formatting codes that remain active within a V<> code, using the :allow option.

Inline comments

The Z<> formatting 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 formatting code:

  In certain scenarios, the B«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 Perl 5 POD, the B«V<C<Z<>>>» code was widely used to break up text
    that would otherwise be considered mark-up.

The Z<> formatting code is the inline equivalent of a =comment block.

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: and https:
A standard web URL. For example:
    This module needs the LAME library
    (available from L<http://www.mp3dev.org/mp3/>)
If the link does not start with // it is treated as being relative to the location of the current document:
    See also: http:tutorial/faq.html and
    http:../examples/index.html
file:
A filename on the local system. For example:
    Next, edit the global config file (that is, either
    undefined or undefined).
Filenames that don't begin with a / or a ~ are relative to the current document's location:
    Then, edit the local config file (that is, either
    undefined or undefined.
mailto:
An email address. Typically, activating this type of link invokes a mailer. For example:
    Please forward bug reports to mailto:devnull@rt.cpan.org
man:
A link to the system manpages. For example:
    This module implements the standard
    Unix man:find(1) facilities.
doc:
A link to some other documentation, typically a module or part of the core documentation. For example:
    You may wish to use doc:Data::Dumper to
    view the results. See also: doc:perldata.
defn:
A link to the block-form or inline definition of the specified term within the current document. For example:
    He was highly prone to 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)
and later, to link back to the definition
To treat his chronic defn:lexiphania the doctor prescribed an
immediate defn:glossoligation or, if that proved ineffective,
a complete cephalectomy.
isbn: and issn:
The International Standard Book Number or International Standard Serial Number for a publication. For example:
    The Perl Journal was a registered
    serial publication (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 include 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 adressing 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.

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 itincluding any newlineis 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:… dotdotdotdashdashdashdotdotdot.

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.

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

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

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

You can specify two or more entries for a single indexed text, by separating the entries with semicolons:

    A X<hash|hashes, definition of; associative arrays>
    is an unordered collection of scalar values indexed by their
    associated string key.

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 render such annotations in a variety of ways: as footnotes, as endnotes, as sidebars, as pop-ups, as tooltips, as expandable tags, etc. They are never, however, rendered as unmarked inline text. So 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 scheme specifier, followed by extra content that is passed verbatim to a handler function.

The structure of the M<> markup code as follows:

M< CONTENT-TEXT|SCHEME: VERBATIM_EXTRA_CONTENT>

This syntax includes an optional CONTENT-TEXT section, followed by a scheme specifier (SCHEME:) and then the VERBATIM_EXTRA_CONTENT. The scheme specifier should follow the same rules as for Named blocks. The scheme specifier allows the verbatim extra content (VERBATIM_EXTRA_CONTENT), which may include additional attributes or instructions for the markup code handler.

An example of how this code might be used is :

    M< This text is highlighted in yellow|Marker: yellow>.

In this example, the text s "This text is highlighted in yellow"> is subject to special handling specified by the Marker: scheme and yellow, indicating that the textshould be highlighted in yellow.

If the SCHEME: 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.

This feature enhances the flexibility and capability of Podlite documents, enabling custom formatting and behavior that goes beyond standard markup features.

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
    

Here, two configurations are outlined. The first one sets the language for code blocks to python and allows bold formatting 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 langiage for code block:

    =for code :lang<javascript>
    print(JSON.stringify([1,2]]));

Pre-configuring formatting codes

You can also lexically preconfigure a formatting 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 formatting 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<> formatting code.

Note that =alias is a fundamental Podlite directive, like =begin or =for; there are no equivalent paragraph or delimited forms.

There are two forms of =alias directive: macro aliases and contextual aliases. Both forms are lexically scoped to the surrounding Podlite block.

Macro aliases

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<> formatting code. This formatting 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. 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 addition 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>

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, 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>

Contextual aliases

If the =alias directive is specified with only a single argument (that is, with only its identifier), a contextual alias is created. In this form, the =alias directive must be followed immediately (on the next non-blank line) by ambient code.

The single argument is then used as the name of the alias being created, and some portion of the following code is used as the value returned by the alias macro.

Note that the code block following the =alias line is still treated as real code by the Podlite parser, but its contents are also used to create the replacement macro of the alias. This allows the developer to reproduce chunks of actual source code directly in the documentation, without having to copy it.

If the code following the one-argument =alias directive begins with a sequence of one or more repetitions of any opening bracket character, the replacement macro returns a string containing everything from the end of that opening sequence to just before the corresponding closing bracket sequence. For example:

    # This is actual code...

    sub hash_function ($key)
    =alias HASHCODE
    {
        my $hash = 0;
        for $key.split("") -> $char {
            $hash = $hash*33 + $char.ord;
        }
        return $hash;
    }

    =begin pod
    An ancient (but fast) hashing algorithm is used:

        =begin code :allow<A>
        A<HASHCODE>
        =end code

    =end pod

This would produce:

An ancient (but fast) hashing algorithm is used:

my $hash = 0;
    for $key.split("") -> $char {
        $hash *= 33;
        $hash += $char.ord;
    }
    return $hash;

Alternatively, if the =alias directive is not followed by an opening bracket, it must be followed by a declarator (such as my, class, sub, etc.) The declared object then becomes the (read-only) return value of the alias. For example:

 =alias CLASSNAME
 class Database::Handle {
     =alias ATTR
     has IO $!handle;
 
     =alias OPEN
     my Bool method open ($filename?) {...}
 
     =alias DEFNAME
     constant Str DEFAULT_FILENAME = 'db.log';
 
     =for para
         Note that the A<OPEN.name> method of class A<CLASSNAME>
         stores the resulting low-level database handle
         in its private A<ATTR.name> attribute. By default,
         handles are opened to the file "A<DEFNAME>".
 
 }

This would produce:

Note that the open method of class Database::Handle stores the resulting low-level database handle in its private $!handle attribute. By default, handles are opened to the file "db.log".

SUMMARY

Directives

Directive Specifies
=begin Start of an explicitly terminated block
=config Lexical modifications to a block or formatting 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
=headN Nth-level heading
=input Pre-formatted sample input
=item First-level list item
=itemN Nth-level list item
=nested Nest 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, documents
=picture Inserting pictures
=formula Mathematical formulas
=markdown Markdown support
=RESERVED Semantic blocks (=SYNOPSIS, =BUGS, etc.)
=Typename User-defined block

Formatting 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)
C<V><...> Verbatim (internal formatting codes ignored)
W<...|...> Contextual backlinks
Y<> reserved
X<...|..,..;...> Index entry (X<R<display text>|R<entry>,R<subentry>;...>)
Z<...> Zero-width comment (contents never rendered)

LICENSE

Artistic license 2.0