5 Module Reference
5.1 Core
| (require punct/core) | package: punct-lib |
parameter
(current-metas) → (or/c hash-eq? #f)
(current-metas metas) → void? metas : (or/c hash-eq? #f)
The only key automatically defined in every metadata table is 'here-path, which holds the absolute path to the source file.
If no Punct file is currently being compiled, this parameter will hold #f by default. In particular, this parameter is not automatically set to a Punct file’s metas during the rendering phase (e.g., doc->html).
procedure
key : symbol? val : (not/c procedure?)
syntax
(? key val-expr ...)
#lang punct •?[title "Example Title" author "Me"] ...
5.1.1 Elements
| (require punct/element) | package: punct-lib |
The bindings provided by this module are also provided by punct/core.
procedure
(default-element-function tag default-attr-kw default-attr-val ...) → (->* () #:rest any/c xexpr?) tag : symbol? default-attr-kw : keyword? default-attr-val : string?
You can also give keyword/value arguments to default-element-function itself; these will be set as default attributes/values in the custom element returned by the resulting function.
> (define aside (default-element-function 'aside)) > (aside "Hello") '(aside "Hello")
> (define kbd (default-element-function 'kbd #:alt "foo")) > (kbd "CTRL") '(kbd ((alt "foo")) "CTRL")
> (kbd "CTRL" #:data-code "1") '(kbd ((alt "foo") (data-code "1")) "CTRL")
On Mac OS, type ALT+6 to produce § and ALT+7 to produce ¶.
If tag ends in either § or ¶, the resulting function will add a default block attribute of "root" or "single" respectively:
> (define info (default-element-function 'info§)) > (info "Note!") '(info ((block "root")) "Note!")
> (define mypar (default-element-function 'mypar¶)) > (mypar "Walnuts") '(mypar ((block "single")) "Walnuts")
If tag has a suffix of the form .foo, the resulting function will add a default 'class attribute whose value is set to "foo". Multiple such suffixes will add additional values to the 'class attribute.
> (define carton (default-element-function 'carton.xyz.abc)) > (carton "Cashews") '(carton ((class "xyz abc")) "Cashews")
> (define crate (default-element-function 'crate¶.foo)) > (crate "Pecans") '(crate ((block "single") (class "foo")) "Pecans")
Added in version 1.3 of package punct-lib.
syntax
(define-element id [default-attr-kw default-attr-val ...])
(define-element id tag [default-attr-kw default-attr-val ...])
default-attr-kw : keyword?
default-attr-val : string?
If tag is supplied, it is used as the tag for the X-expressions generated by the resulting function:
> (define-element bowl container.bowl) > (bowl "Corn nuts") '(container ((class "bowl")) "Corn nuts")
> (define-element jar vessel¶ #:type "Glass") > (jar "Chestnuts") '(vessel ((type "Glass") (block "single")) "Chestnuts")
If tag is not supplied, the first argument is used both as the identifier for the function and for the tag in generated X-expressions:
> (define-element bag.xyz.abc) > (bag "Sunflower seeds") '(bag ((class "xyz abc")) "Sunflower seeds")
> (define-element packet¶.foo) > (packet "Raisins") '(packet ((block "single") (class "foo")) "Raisins")
Added in version 1.3 of package punct-lib.
5.2 Fetch
| (require punct/fetch) | package: punct-lib |
procedure
src : path-string?
procedure
doc : document? key : symbol?
default : failure-result/c = (lambda () (raise (make-exn:fail ....)))
Changed in version 1.1 of package punct-lib: Removed get-doc-ref and replaced with get-meta
5.3 Parse
| (require punct/parse) | package: punct-lib |
procedure
(parse-markup-elements metas elements #:extract-inline? extract? #:parse-footnotes? parse-fn?) → (or/c document? (listof xexpr?)) metas : hash-eq? elements : list extract? : #t parse-fn? : #f
If #:extract-inline? is #true, and if the parsed document contains only a single paragraph element at the root level, then the elements inside the paragraph are returned as a list (the paragraph is "shucked"). Otherwise, the entire result is returned as a document.
The #:parse-footnotes? argument determines whether the commonmark parser will parse Markdown-style footnote references and definitions in elements.
> (define elems '("# Title\n\nA paragraph with *italic* text, and " 1 (custom "custom element"))) > (parse-markup-elements (hasheq) elems)
(document
'#hasheq()
'((heading ((level "1")) "Title")
(paragraph
"A paragraph with "
(italic "italic")
" text, and 1"
(custom "custom element")))
'())
5.4 Rendering
Punct currently includes renderers for HTML, Typst, and plain-text. These are based on a "base" renderer class that you can extend to customize the rendering process or to target new output formats.
5.4.1 Rendering custom elements
When rendering your document to a specific output format (such as HTML) Punct has to decide how to render any custom elements introduced by your code. When Punct encounters a custom element, it passes it to a fallback function: the fallback function receives three arguments: the custom element’s tag, its attributes, and a list of sub-elements found inside the element. The sub-elements will already have been fully processed by Punct.
A separate fallback function is needed for each output format you want to target. Punct provides default fallback functions the target output format it supports natively. For example, when targeting HTML, Punct defaults to default-html-tag, which simply converts custom elements to HTML elements. If you want more customized behavior, you’ll need to provide your own fallback procedure to the renderer.
Here’s an example pair of functions for rendering documents containing the custom abbreviation element (from the examples above) into HTML:
(define (custom-html tag attrs elems) (match (list tag attrs) [`(abbreviation [[term ,term]]) `(abbr [[title ,term]] ,@elems)])) (define (my-html-renderer source-path) (doc->html (get-doc source-path) custom-html))
5.4.2 HTML
| (require punct/render/html) | package: punct-lib |
procedure
pdoc : document?
fallback :
(-> symbol? (listof (list/c symbol? string?)) (listof xexpr?) xexpr?) = default-html-tag
This function uses xexpr->string to generate the HTML string. This function will blindly escape characters inside <script> and <style> tags, which may introduce errors. For HTML output that is friendlier and more correct, consider using the html-printer package in concert with doc->html-xexpr.
For more information on using the fallback argument to render custom elements, see Rendering custom elements.
procedure
(doc->html-xexpr pdoc [fallback]) → xexpr?
pdoc : document?
fallback :
(-> symbol? (listof (list/c symbol? string?)) (listof xexpr?) xexpr?) = default-html-tag
For more information on using the fallback argument to render custom elements, see Rendering custom elements.
procedure
(default-html-tag tag attributes elements) → xexpr?
tag : symbol? attributes : (listof (list/c symbol? string?)) elements : (listof xexpr?)
> (require punct/render/html) > (default-html-tag 'kbd '() '("Enter")) '(kbd "Enter")
> (default-html-tag 'a '((href "http://example.com")) '("Link")) '(a ((href "http://example.com")) "Link")
|
superclass: punct-abstract-render% |
5.4.3 Typst
| (require punct/render/typst) | package: punct-lib |
Typst is a modern typesetting system designed as an alternative to LaTeX. This renderer produces Typst markup from Punct documents.
procedure
(doc->typst pdoc [fallback]) → string?
pdoc : document?
fallback : (symbol? (listof (listof symbol? string?)) list? . -> . string?) = default-typst-tag
Markdown/Punct elements are mapped to Typst syntax as follows:
Punct element | Typst output |
Headings | = Heading (with levels as = count) |
Bold | *text* |
Italic | _text_ |
Inline code | `code` |
Code blocks | ```lang ... ``` |
Links | #link("url")[text] |
Images | #image("path") |
Bullet lists | - item |
Numbered lists | + item |
Block quotes | #quote(block: true)[...] |
Footnotes | #footnote[...] (inline) |
Typst special characters (*, _, `, #, @, $, [, ]) in text content are automatically escaped, allowing the same Punct source to target both HTML and Typst without manual escaping. Content inside code blocks and inline code is not escaped, as Typst renders these literally.
For more information on using the fallback argument to render custom elements, see Rendering custom elements.
Added in version 1.4 of package punct-lib.
procedure
(default-typst-tag tag attributes elements) → string?
tag : symbol? attributes : (listof (listof symbol? string?)) elements : list?
The output format is #tag(attr: "val", ...)[content], where attributes become named arguments with string values, and elements become a trailing content block. When there are no attributes, the parentheses are omitted: #tag[content]. When there are no elements, the content block is omitted: #tag(attr: "val").
Hyphens in tag and attribute names are converted to underscores to produce valid Typst identifiers (e.g., 'my-element becomes my_element).
Note that elements are already escaped when passed to the fallback. Attribute values are automatically escaped and quoted as Typst strings.
> (require punct/render/typst) > (default-typst-tag 'note '() '("Important!")) "#note[Important!]"
> (default-typst-tag 'note '((class "info")) '("Important!")) "#note(class: \"info\")[Important!]"
> (default-typst-tag 'my-spacer '((line-height "2em")) '()) "#my_spacer(line_height: \"2em\")"
Added in version 1.4 of package punct-lib.
procedure
(escape-typst-text str) → string?
str : string?
Added in version 1.4 of package punct-lib.
procedure
(escape-typst-string str) → string?
str : string?
Added in version 1.4 of package punct-lib.
|
superclass: punct-abstract-render% |
Added in version 1.4 of package punct-lib.
5.4.4 Plain text
| (require punct/render/plaintext) | package: punct-lib |
Sometimes you want to convert a document into a text format that is even plainer than Markdown, such as when generating the plaintext version of an email newsletter.
procedure
(doc->plaintext pdoc line-width [fallback]) → string?
pdoc : document? line-width : exact-nonnegative-integer?
fallback :
(-> symbol? (listof (list/c symbol? string?)) (listof xexpr?) xexpr?) = (make-plaintext-fallback line-width)
The function applies very rudimentary text formatting which usually looks as you would expect, but which often discards information.
Level 1 headings are underlined with =, and all other headings are underlined with -.
Link destination URLs are given inside parentheses directly following the link text.
Code blocks are indented with four spaces, and the language name, if any, is discarded.
Images are replaced with their "alt" text, prefixed by "Image: " and wrapped in parentheses; the source URL and title are discarded.
For more information on using the fallback argument to render custom elements, see Rendering custom elements.
> (require punct/render/plaintext) > (define email (parse-markup-elements (hasheq) '("# Issue No. 1\n\nHowdy!"))) > (display (doc->plaintext email 72))
Issue No. 1
===========
Howdy!
procedure
(make-plaintext-fallback width)
→ (symbol? (listof (listof symbol? string?)) list? . -> . string?) width : exact-nonnegative-integer?
> (define foo (make-plaintext-fallback 72)) > (foo 'kbd '() '("Enter")) "[kbd] Enter\n\n"
> (foo 'a '((href "http://example.com")) '("Link")) "[a] Link\n\n"
5.4.5 Base renderer
| (require punct/render/base) | package: punct-lib |
|
superclass: object% |
constructor
(new punct-abstract-render% [doc doc] [render-fallback render-fallback]) → (is-a?/c punct-abstract-render%) doc : document?
render-fallback :
(-> symbol? (listof (list/c symbol? string?)) list? any/c) Creates a new renderer instance. The doc argument is the Punct document to render. The render-fallback procedure is called for any custom elements encountered during rendering.
method
(send a-punct-abstract-render render-document) → any/c
The main entry point for rendering. Calls the appropriate rendering methods for each element in the document body and footnotes.The default implementation returns two values: a list of rendered body elements and a list of rendered footnotes. Subclasses typically override this to combine these into a single output value (e.g., a string or X-expression).
method
(send a-punct-abstract-render render-string s) → any/c
s : string? Called for every string in the document. Override this to transform raw text (e.g., for escaping special characters in the target format). The default implementation returns the string unchanged.AAdded in version 1.4 of package punct-lib.
To create a custom renderer, extend this class and implement all of the abstract methods below.
See Extending the Renderer for examples of extending the base renderer.
method
(send a-punct-abstract-render render-thematic-break) → any/c
method
(send a-punct-abstract-render render-heading level rendered-elems) → any/c level : string? rendered-elems : list?
method
(send a-punct-abstract-render render-code-block info-string raw-elems) → any/c info-string : string? raw-elems : list?
method
(send a-punct-abstract-render render-html-block raw-content)
→ any/c raw-content : any/c
method
(send a-punct-abstract-render render-paragraph rendered-elems)
→ any/c rendered-elems : list?
method
(send a-punct-abstract-render render-blockquote rendered-elems)
→ any/c rendered-elems : list?
method
(send a-punct-abstract-render render-itemization style start rendered-items) → any/c style : string? start : string? rendered-items : list?
method
(send a-punct-abstract-render render-item rendered-elems)
→ any/c rendered-elems : list?
method
(send a-punct-abstract-render render-line-break) → any/c
method
(send a-punct-abstract-render render-bold rendered-elems)
→ any/c rendered-elems : list?
method
(send a-punct-abstract-render render-italic rendered-elems)
→ any/c rendered-elems : list?
method
(send a-punct-abstract-render render-code raw-elems) → any/c
raw-elems : list?
method
(send a-punct-abstract-render render-link dest title rendered-elems) → any/c dest : string? title : string? rendered-elems : list?
method
(send a-punct-abstract-render render-image src title desc raw-elems) → any/c src : string? title : string? desc : string? raw-elems : list?
method
(send a-punct-abstract-render render-html raw-content) → any/c
raw-content : any/c