11 File formats
11.1 Source formats
#lang pollen/pre | package: pollen |
#lang pollen/markdown | |
#lang pollen/markup | |
#lang pollen/ptree |
The Pollen language is divided into dialects that are tailored to suit each of the core source formats.
These dialects can be invoked one of two ways: either by invoking a specific dialect in the first line of the file (also known as the #lang line), or by using the generic #lang pollen as the first line, and then the correct dialect will be automatically selected based on the source file extension.
If the #lang line specifies a dialect different from the one implied by the file extension, the #lang line will take precedence.
For ease of use, the behavior of the Pollen language departs from the standard Racket language in several ways. The differences are noted below.
11.1.1 Command syntax using ◊
Commands must start with the special lozenge character ◊. Other material is interpreted as plain text. See Pollen command syntax for more.
You can change the command character for a project by overriding default-command-char.
How is this different from Racket? In Racket, everything is a command, and plain text must be quoted.
11.1.2 Any command is valid
There are no undefined commands in Pollen. If a command has not already been defined, it’s treated as a tag function. See Pollen command syntax and pollen/top for more.
How is this different from Racket? In Racket, if you try to treat an identifier as a function before defining it with define, you’ll get an error.
11.1.3 Standard exports
By default, every Pollen source file exports two identifiers:
As usual, you can use require, local-require, or dynamic-require to retrieve these values. But within a Pollen project, the faster way is to use get-doc and get-metas.
Pollen source files also make the metas hashtable available through a submodule, unsurprisingly called metas. So rather than importing a source file with (require "source.html.pm"), you can (require (submod "source.html.pm" metas)). Accessing the metas this way avoids fully compiling the source file, and thus will usually be faster.
The names doc and metas can be changed for a project by overriding default-main-export and default-meta-export.
The Pollen rendering system relies on these two exported identifiers, but otherwise doesn’t care how they’re generated. Thus, the code inside your Pollen source file could be written in #lang racket or #lang whatever. As long as you provide those two identifiers and follow Pollen’s file-naming conventions, your source file will be renderable.
How is this different from Racket? In Racket, you must explicitly define and then provide any values you want to export.
11.1.4 Custom exports
Any value or function that is defined within the source file using define is automatically exported.
How is this different from Racket? In Racket, you must explicitly provide any values you want to export. Unlike Racket, every Pollen source file impliedly uses (provide (all-defined-out)).
11.1.5 The "pollen.rkt" file
If a file called "pollen.rkt" exists in the same directory with a source file, or in a parent directory of that source file, it’s automatically imported when the source file is compiled.
How is this different from Racket? In Racket, you must explicitly import files using require.
11.1.6 Preprocessor (.pp extension)
Invoke the preprocessor dialect by using #lang pollen/pre as the first line of your source file, or by using #lang pollen with a file extension of .pp. These forms are equivalent:
"sample.css.pp"
#lang pollen ...source...
"sample.css"
#lang pollen/pre ...source...
When no dialect is explicitly specified by either the #lang line or the file extension, Pollen will default to using the preprocessor dialect. For instance, this file will be treated as preprocessor source:
"test.yyz"
#lang pollen ...source...
Of course, you’re better off specifying the preprocessor dialect explicitly rather than relying on this default behavior.
The output of the preprocessor dialect, provided by doc, is plain text. For this reason, the preprocessor will convert everything it finds to text in the least surprising way possible.
11.1.7 Markdown (.pmd extension)
Invoke the Markdown dialect by using #lang pollen/markdown as the first line of your source file, or by using #lang pollen with a file extension of .pmd. These forms are equivalent:
"sample.txt.pmd"
#lang pollen ...source...
"sample.txt"
#lang pollen/markdown ...source...
The output of the Markdown dialect, provided by doc, is a tagged X-expression.
11.1.8 Markup (.pm extension)
Invoke the Pollen markup dialect by using #lang pollen/markup as the first line of your source file, or by using #lang pollen with a file extension of .pm. These forms are equivalent:
"about.html.pm"
#lang pollen ...source...
"about.html"
#lang pollen/markup ...source...
The output of the Pollen markup dialect, provided by doc, is a tagged X-expression.
11.1.9 Pagetree (.ptree extension)
Invoke the pagetree dialect by using #lang pollen/ptree as the first line of your source file, or by using #lang pollen with a file extension of .ptree. These forms are equivalent:
"main.ptree"
#lang pollen ...source...
"main.rkt"
#lang pollen/ptree ...source...
The output of the pagetree dialect, provided by doc, is a pagetree? that is checked for correctness using validate-pagetree.
11.2 Utility formats
These aren’t source formats because they don’t contain a #lang pollen line. But for convenience, they get special handling by the Pollen project server.
11.2.1 Scribble (.scrbl extension)
Scribble files are recognized by the project server and can be compiled and previewed in single-page mode.
11.2.2 Null (.p extension)
Files with the null extension are simply rendered as a copy of the file without the extension, so "index.html.p" becomes "index.html".
This can be useful if you’re managing your project with Git. Most likely you’ll want to ignore "*.html" and other file types that are frequently regenerated by the project server. But if you have isolated static files — for instance, a "index.html" that doesn’t have source associated with it — they’ll be ignored too. You can cure this problem by appending the null extension to these static files, so they’ll be tracked in your source system without actually being source files.
The null extension is also useful for templates — "template.html" and "template.html.p" will work the same way.
11.3 Escaping output-file extensions within source-file names
Pollen relies extensively on the convention of naming source files by adding a source extension to an output-file name. So the Pollen markup source for "index.html" would be "index.html.pm".
This convention occasionally flummoxes other programs that assume a file can only have one extension. If you run into such a situation, you can escape the output-file extension with the underscore character _.
So instead of "index.html.pm", your source-file name would be "index_html.pm". When this source file is rendered, it will automatically be converted into "index.html" (meaning, the escaped extension will be converted into a normal file extension).
This alternative-naming scheme is automatically enabled in every project. You can also set the escape character on a per-project basis (by overriding defaul-extension-escape-char). Pollen will let you choose any character, but of course it would be unwise to pick one with special meaning in your filesystem (for instance, /).