#lang racket/base
; SPDX-License-Identifier: BlueOak-1.0.0
; This file is licensed under the Blue Oak Model License 1.0.0.
;; Pollen “tag functions” that return elements of a Yarn AST. This AST can be
;; rendered into HTML or other formats (using, e.g., the yarn/render/html module).
(require pollen/decode
pollen/tag
"index.rkt"
"string.rkt"
"tools.rkt")
(provide (all-defined-out))
;; Yarn AST:
;; (document Block-Contents)
;; Footnote definitions, index entry keys are stored in the metas
;; Block-Content :=
;; (heading #:level Inline-Contents)
;; | (paragraph Inline-Contents)
;; | (thematic-break style)
;; | (codeblock info Inline-Contents)
;; | (blockquote items := (item Block-Contents))
;; | (poetry title style Block-Contents)
;; | (itemization style start Block-Contents)
;; | (dialogue speeches := (speech interlocutor Block-Contents))
;; | (figure source caption)
;; | (margin-note Block-Contents)
;; Inline-Content :=
;; string?
;; | (italic Inline-Contents)
;; | (bold Inline-Contents)
;; | (link destination Inline-Contents)
;; | (monospace Inline-Contents)
;; | (strikethrough Inline-Contents)
;; | (caps Inline-Contents)
;; | (image description source)
;; | (xref type dest-key Inline-Contents)
;; | (footnote-ref label)
;; | line-break
(define blocks-elements
'(heading
paragraph
thematic-break
codeblock
blockquote
poetry
itemization
dialogue
figure
margin-note))
(define inline-elements
'(italic
bold
link
image
xref
footnote-ref
line-break))
(define (title . t) (set-meta 'title t) (set-meta 'title-supplied? #t) "")
(define (section . s) `(heading [[level "2"]] ,@s))
(define (subsection . s) `(heading [[level "3"]] ,@s))
(define (excerpt . e) (set-meta 'excerpt e))
(define (excerpt* . e) (apply excerpt e) `(@ ,@e))
(define (pause [type 'blank]) `(thematic-break ,type)) ; type = blank | mark
(define codeblock (default-tag-function 'codeblock #:info ""))
(define blockquote (default-tag-function 'blockquote)) ; #:caption
(define figure (default-tag-function 'figure))
(define (i . inline) `(italic ,@inline))
(define em i)
(define (b . inline) `(bold ,@inline))
(define (mono . inline) `(monospace ,@inline))
(define (caps . inline) `(caps ,@inline))
(define (strike . inline) `(strikethrough ,@inline))
(define br 'line-break)
(define (link ref . elems) `(link ,ref ,@elems))
(define (url ref URL) (update-metas-subhash 'urls ref URL) "")
(define (xref type elems k)
(define key (or k (normalize-key (->text elems))))
(cons-to-metas-list 'xref-keys key)
`(xref ,type ,key ,@elems))
(define (pin #:key [key #f] . elems) (xref 'idx elems key))
(define (def #:key [key #f] . elems) (xref 'def elems key))
(define (ref #:key [key #f] . elems) (xref 'ref elems key))
(define (fn ref) `(footnote-ref ,ref))
(define (fndef ref . elems) (update-metas-subhash 'footnote-defs ref elems) "")
(define (ol . elems) `(itemization [[start "1"]] ,@elems)) ; #:style
(define (ul . elems) `(itemization ,@elems)) ; #:style
(define (item . blocks) `(item ,@blocks))
(define (dialogue . speeches) `(dialogue ,@speeches))
(define (say interlocutor elems) `(speech ,interlocutor ,@elems))
(define (saylines interlocutor elems)
`(speech ,interlocutor ,@(decode-linebreaks elems 'line-break)))
(define verse (default-tag-function 'poetry)) ; #:title, #:style