Podlite: Modernizing and Extending abandoned Raku Pod (ака pod6)

Podlite was born as a lightweight implementation of Raku Pod (also known as pod6), and over time, it has evolved into one of the most comprehensive implementations. It encompasses:

What's more, Podlite also supports Diagrams, auto-generated Table of Contents, and has built-in Markdown support.

I've been keeping daily journals in Raku Pod format for years and using Podlite to write blog articles.

At this point, I've accumulated a bunch of ideas that go beyond the standard Raku Pod (aka pod6) specification, along with some ideas I've been wanting to implement for a while. I've brought them all together, and I'd like to share the key ones in detail.

Selectors

Podlite selectors are, in essence, quite similar to CSS selectors. They help identify and filter specific blocks within documents. Each selector pattern can contain optional block sources and block names.

The general syntax is as follows:

<EXTERNAL_SOURCE>
or
[ <EXTERNAL_SOURCE> | ] <BLOCKS_SELECTOR>

For example:

  • head1, head2

    This selector defines all level 1 and level 2 header blocks.

  • para,code

    This selector defines all paragraph and code example blocks.

Selectors can be used not only to describe blocks within the current document but also in external documents:

  • file:article.rakudoc

    This selector points to all blocks in the article.rakudoc file.

  • file:article.rdoc | head1, head2

    All head1 and head2 blocks from the article.rdoc file.

Here are a few more examples:

Selector Description
head1, head2, item1 All head1, head2 and item1 blocks from document
file:article.rakudoc | head1, head2 All head1 and head2 blocks from article.rakudoc 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 for first-level headers in all ".md" files within the "docs" directory and its subdirectories.

Selectors are an essential part that will be used in other sections.

 =toc <SELECTOR>

The =toc block is used to create an autogenerated table of contents (TOC) in a document. The TOC serves as an index of section titles within the document, and its structure is determined by the organization of the document.

For example:

 =toc head1, head2, head3, item1, item2, table

In this block, a selector is used to describe the blocks used to build the TOC.

You can create lists of tables or even images:

=for toc :title('List of tables')
table

=for toc :title('List of media')
Image, Diagram

=include - Include block

	=include <SELECTOR>

The =include block is a powerful tool for reusing 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.

This block is perfect for creating books. Combined with Selectors, it allows you to include arbitrary blocks from other documents and files.

=picture, P< > - Inserting pictures

To insert pictures, you can use the =picture block:

=picture site-menu.png
This is the menu rendered by the React component

It may be rendered as follows:

and inline usage:

 =para In the vast expanse of the cosmos, an intrepid P<astronaut|astronaut.png>
 floats weightlessly above the Earth.

E<:hugging face:> - emoji 🤗

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.

it renders as:

Prototype of E<> inline code rendering

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.

For example:

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

may render as:

Prototype of formulas rendering

  =formula  :caption<Quadratic Formula> 
  x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}

It may be rendered as:

Prototype of formulas with the caption

=item, :checked - Task lists

In addition to the ordered list would be nice to support 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

or

 =item1 [ ] Work
   =item2 [ ] Prepare the presentation
   =item2 [x] Send emails
 =item1 [ ] Home
   =item2 [ ] Vacuum the living room
   =item2 [ ] Water the plants

Which might look something like this:

Prototype of checklist

Yeah, that's one of the ideas I've been thinking about lately.

Contextual backward links W<> (or contextual backlinks), enhance 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.

  • Integration with Markdown

Since last year, Podlite natively supports Markdown using the =Markdown block. This means that Markdown elements are translated into the Podlite AST, allowing features not available in Markdown, such as auto-generated TOCs.

For instance:

=Toc head1, head2, head3

=head1 This is header1
=head2 Another header

=begin Markdown

# this is markdown header
## and this!

=end Markdown

This document would look like this:

Autogenerated TOC for Markdown

You can play around with an example here.

The synergy between two markup languages is fascinating.

Here's another example that I'd like to make a reality:

=include article.md
=include file:./includes/*.md 

I like the idea of further integration.

Conclusion

These are some of the major improvements that Podlite brings. Many of these suggestions have already been implemented in Podlite and have proven their practical usefulness.

I took the current specification for Raku Pod (aka Synopsis 26), updated it, and incorporated all my ideas into it. I presented it as a specification for Rakudoc.

As a result, the Rakudoc proposal:

  • Is 100% compatible with already written documentation in Raku Pod (aka Pod6), guaranteed by using the current specification as a base (Synopsis 26).

  • Maintains simplicity and elegance.

  • Remains extensible.

  • Empowers users with new blocks and formatting codes.

I'm open to ideas and suggestions. Feel free to send it to zag(at)cpan.org. I'm looking forward to hearing from you!

In the meantime, I'll continue working on Podlite Editor and Podlite itself.

Thank you for your attention!

With best regards, Alex

PS. I recently noticed an intriguing event on the calendar – a POD birthday celebration marked with the comment '1994.10.18'. Although I couldn't find any confirmation of this event, it seemed like a good reason to dive into this topic and write this article. 😄