NAME

Podlite - Use Podlite markup language in Perl programs

VERSION

This document describes Podlite version 1.00

SYNOPSIS

use Podlite;

=comment
This is a Podlite comment block

=head1 Head title
=para
Some text of paragraph

Delimited style, paragraph style, or abbreviated style of blocks:

=begin para :nested
Podlite is a lightweight markup language with a simple,
consistent underlying document object model.
=end para

=for para :nested
Podlite is a lightweight markup language.

=para
Podlite is a lightweight markup language.

Unordered lists:

=item FreeBSD
=item Linux
=item Windows
=item MacOS

Definition lists:

=defn XML
Extensible Markup Language
=defn HTML
Hyper Text Markup Language

Task lists with checkboxes:

=item [x] Completed task
=item [ ] Pending task

Tables with captions:

=begin table :caption<System Requirements>
Component    Minimum     Recommended
CPU          2 GHz       4 GHz
RAM          4 GB        16 GB
=end table

Notification blocks (callouts):

=begin nested :notify<warning> :caption<Important>
This feature is experimental and may change.
=end nested

Markdown blocks:

=begin markdown
# Documentation

Mix **markdown** formatting with Podlite!

- Bullet points
- **Bold** and *italic*
- Code blocks with ```perl syntax```
=end markdown

DESCRIPTION

Podlite is a lightweight markup language with a simple, consistent underlying document object model. It is designed to be a pure descriptive markup language with no presentational components, focusing on simplicity and consistency.

This module preprocesses your Perl code from the point at which the module is first used, stripping out any Podlite documentation while preserving line numbering for accurate error reporting.

This means that, so long as your program starts with:

use Podlite;

you can document it using the Podlite markup notation and it will still run correctly under the Perl interpreter.

In addition, the module detects any =data sections in the stripped documentation and makes them available to your program in three ways:

  • As a single concatenated string, in the $DATA package variable

  • As a sequence of strings (one per =data block) in the @DATA package variable

  • As a single concatenated input stream in the *DATA filehandle.

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 with an equals sign (=) in the first column.

The content of a document is specified within one or more blocks. Every Podlite block may be declared in any of three equivalent forms: delimited style, paragraph style, or abbreviated style.

Delimited blocks

The general syntax is:

=begin BLOCK_TYPE  OPTIONAL CONFIG INFO
=                  OPTIONAL EXTRA CONFIG INFO
BLOCK CONTENTS
=end 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

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 BLOCK_TYPE  OPTIONAL CONFIG INFO
=                OPTIONAL EXTRA CONFIG INFO
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:

=BLOCK_TYPE  BLOCK DATA
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 three block specifications (delimited, paragraph, and abbreviated) are treated identically by the underlying documentation model, so you can use whichever form is most convenient for a particular documentation task.

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 built-in block types. These include:

:caption

Assigns a title to the given block, typically used for creating a table of contents.

=for table :caption<Performance Benchmarks>

:id

Enables explicit definition of identifiers for blocks, used for linking purposes.

=for head1 :id<introduction>
Introduction

:nested

Specifies that the block is to be nested within its current context. Can take integer values for multiple nesting levels.

=begin para :nested(3)
"We're going deep, deep, deep undercover!"
=end para

Use :nested(0) or :!nested to defeat implicit nesting.

:numbered

Specifies that the block is to be numbered. The most common use is to create numbered headings and ordered lists, but it can be applied to any block.

=for head1 :numbered
The Problem

Shorthand: If first word is a single #, it's removed and treated as :numbered:

=head1 # The Problem

:checked

Adds checkbox to block (for task lists). Use :!checked for unchecked.

=for item :checked
Buy groceries

Shorthand: [x] for checked, [ ] for unchecked:

=item [x] Buy groceries
=item [ ] Clean garage

:folded

Specifies if block is foldable and default state (collapsed/expanded).

=for table :folded :caption<Data>

:!folded or :folded(0) = expanded by default. :folded or :folded(1) = collapsed by default.

:lang

Specifies programming language for code blocks (for syntax highlighting).

=begin code :lang<raku>
sub demo { say 'Hello'; }
=end code

Common values: cpp, css, html, java, javascript, python, raku, perl

:allow

Lists markup codes recognized within V<> codes (typically in code blocks).

=begin code :allow<B R E>
sub demo {
    B<say> 'Hello R<name>';
}
=end code

Block types

Podlite supports many block types including:

Headings (=head1, =head2, etc.) - Unlimited nesting levels
Paragraphs (=para) - Formatted text with whitespace squeezed
Code blocks (=code) - Pre-formatted source code
Lists (=item, =item1, =item2, etc.) - Multi-level lists
Definition lists (=defn) - Term and definition pairs
Tables (=table, =row, =cell) - Simple and advanced formats
Nesting blocks (=nested) - For blockquotes and indented content
Comments (=comment) - Documentation that won't be rendered
Data blocks (=data) - Binary or text data sections
Include blocks (=include) - Content reuse from other files
Table of contents (=toc) - Auto-generated TOC
Pictures (=picture) - Image insertion
Formulas (=formula) - Mathematical formulas
Markdown blocks (=markdown) - Embedded Markdown
Notification blocks (=nested :notify) - Callouts/admonitions
Semantic blocks (=SYNOPSIS, =AUTHOR, etc.) - Uppercase names

Markup codes

Podlite supports inline formatting codes:

B<> - Bold/basis/important text
I<> - Italic/important text
U<> - Underlined text
C<> - Code/verbatim inline text
E<> - Entities and emoji
N<> - Footnotes and annotations
D<> - Definitions (for inline glossary)
V<> - Verbatim text (no processing)
K<> - Keyboard input
T<> - Terminal output
R<> - Replaceable text/metasyntax
H<> - Superscript (High text)
J<> - Subscript (Junior text)
O<> - Overstrike/strikethrough
P<> - Pictures (inline images)
F<> - Formulas (inline math)
M<> - Custom markup codes

Version 1.0 Features

Podlite 1.0 includes many advanced features:

Notification blocks - Callouts/admonitions with :notify attribute
Table of contents - =toc block with selectors
Include blocks - =include for content reuse
Picture insertion - =picture and P<> code
Mathematical formulas - =formula and F<> code
Markdown support - =markdown blocks for embedding GitHub-flavored Markdown syntax within Podlite documents
Task lists - :checked attribute and [x]/[ ] syntax
Advanced tables - =row/=cell with colspan/rowspan
Custom blocks - Named semantic blocks
Embedded data - =data blocks with MIME types and encoding
Folding support - :folded attribute for collapsible content
Selectors - Pattern-based block filtering from multiple sources

INTERFACE

None. You use the module and it takes care of everything.

EXAMPLES

Basic Documentation

use Podlite;

sub calculate {
    my ($x, $y) = @_;
    return $x + $y;
}

=head1 FUNCTIONS

=head2 calculate

=para
Adds two numbers together.

=begin code :lang<perl>
my $result = calculate(5, 3);  # Returns 8
=end code

Task List

=head1 TODO

=item [x] Implement basic functionality
=item [x] Write documentation
=item [ ] Add test suite
=item [ ] Publish to CPAN

Table with Caption

=begin table :caption<Performance Benchmarks>
Operation      Time (ms)   Memory (MB)
Parse          45          12
Render         23          8
Export         67          15
=end table

Notification Block

=begin nested :notify<warning> :caption<Important Note>
This feature is experimental and may change in future releases.
=end nested

Markdown Block

use Podlite;

my $config = {
    title => "My Project",
    version => "1.0"
};

=begin markdown
# Documentation

You can mix **markdown** and *Podlite* markup!

## Features

- Easy to read
- Easy to write
- Works seamlessly with Perl code

Code example:
```perl
my $x = 1 + 1;
```
=end markdown

print "Config: $config->{title} v$config->{version}\n";

DIAGNOSTICS

Can't set up *DATA handle (%s)

The filter found at least one =data block, but was unable to create a *DATA filehandle in the caller's namespace (for the reason specified in the parens).

CONFIGURATION AND ENVIRONMENT

Podlite requires no configuration files or environment variables.

DEPENDENCIES

Requires the standard module Filter::Simple.

LIMITATIONS

Unlike full Podlite parsers:

  • This module does not make every Podlite block available to the surrounding program, only the =data blocks. This is to avoid unacceptably slow compilation speed that would result from attempting to fully parse the entire embedded Podlite markup.

  • The contents of =data blocks appear in the global variables $DATA and @DATA, and the global *DATA filehandle, rather than in a special $?DATA object. These variables and filehandle are accessible from main and in every other package that is explicitly declared in the file.

  • Parser modes (pod mode for .podlite files, markdown mode for .md files) are not implemented in this source filter. You must explicitly use =begin blocks or other directives.

BUGS

Please report any bugs https://github.com/zag/p5-Podlite/issues

SEE ALSO

Podlite Specification - Official specification in HTML
Podlite Specification Source - Specification source code
Podlite Implementation - Main Podlite implementation
Podlite Desktop - Desktop viewer/editor
Podlite Web - Publishing system
podlite.org - Official website
Filter::Simple - The module used for source filtering

AUTHOR

Aliaksandr Zahatski, <zag at cpan.org>

CREDITS

Damian Conway - for inspiration and source filter techniques

LICENCE AND COPYRIGHT

Copyright (C) 2025 by Aliaksandr Zahatski

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl you may have available.

DISCLAIMER OF STABILITY

This module will attempt to track any future changes to the Podlite specification. Hence its features and the Podlite syntax it recognizes may change in future releases.

DISCLAIMER OF WARRANTY

BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.