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:
Libraries for TypeScript
A web editor - pod6.in
A free desktop editor - Podlite-desktop
A package for creating modern web applications: Podlite for Web
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
andhead2
blocks from thearticle.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:
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:
=formula :caption<Quadratic Formula>
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
It may be rendered as:
=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:
Contextual backlinks
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:
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. 😄