Skip to content

Instantly share code, notes, and snippets.

@cite-reader
Created November 19, 2015 00:51
Show Gist options
  • Save cite-reader/f24f624e223909a72a88 to your computer and use it in GitHub Desktop.
Save cite-reader/f24f624e223909a72a88 to your computer and use it in GitHub Desktop.
I was going to write something, but wrote a tool to render what I'd written instead.
#lang racket/base
(require (for-syntax racket/base)
pollen/world pollen/decode racket/function hyphenate)
(provide (except-out (all-defined-out)
default-postprocessor define-tag-handler
define-trivial-html-handler))
(module config racket/base
(provide poly-targets)
(define poly-targets '(html)))
;;; Do basic post-processing over the entire source document.
;;;
;;; This function wraps `decode-elements` from `pollen/decode`, to provide
;;; paragraph detection and hyphenation.
;;;
;;; The behavior on X-expressions differs from the default in that we
;;; specifically leave linebreaks alone, rather than detecting them and
;;; inserting explicit `br` elements. One source line per sentence interacts
;;; nicely with historical diffs, but it would be unacceptable in an output
;;; format.
(define (default-postprocessor content)
(decode-elements
content
#:txexpr-elements-proc (lambda (el)
(detect-paragraphs
el
#:linebreak-proc identity))
#:string-proc hyphenate))
;;; Create a tag handler with error checking.
;;;
;;; The body forms are copied verbatim to a `case` form; if the current output
;;; format is not explicitly handled, the resulting function complains through
;;; `error` defined in `racket/base`.
(define-syntax define-tag-handler
(syntax-rules ()
((_ (name arg ... content) ((symbols ...) then-body ...) ...)
(define (name arg ... . content)
(let ((target (world:current-poly-target)))
(case target
((symbols ...) then-body ...)
...
(else (error 'name "I don’t know how to make ~A" target))))))))
;;; Rename tags
;;;
;;; Trivial html handlers are tag handlers, as `define-tag-handler`, which:
;;;
;;; 1. Only understand the `'html` target
;;; 2. Do nothing other than replace the semantic `name` tag in the Pollen
;;; source with the HTML tag `tag`.
(define-syntax define-trivial-html-handler
(syntax-rules ()
((_ name tag)
(define-tag-handler (name content)
((html) (cons 'tag content))))))
(define-tag-handler (root content)
((html) (cons 'root (default-postprocessor content))))
(define-trivial-html-handler title h1)
(define-tag-handler (byline name)
((html) `(span ((class "byline")) ,@name)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment