67 lines
2.0 KiB
Scheme
67 lines
2.0 KiB
Scheme
|
(define-module (skribe-utils)
|
||
|
#:use-module (ice-9 match) ; match-lambda
|
||
|
#:use-module (srfi srfi-1) ; list stuff
|
||
|
#:export (email
|
||
|
~
|
||
|
---
|
||
|
page
|
||
|
div
|
||
|
table
|
||
|
figure
|
||
|
wide-img))
|
||
|
|
||
|
(define (div class . contents)
|
||
|
`(div (@ (class ,class)) ,@contents))
|
||
|
|
||
|
(define (page . contents)
|
||
|
`(div (@ (class "page")) ,@contents))
|
||
|
|
||
|
(define (email address)
|
||
|
"Obfuscate a given email ADDRESS."
|
||
|
`(span (@ (class "obfuscated"))
|
||
|
,(string-map (lambda (c) (integer->char (+ 1 (char->integer c))))
|
||
|
address)))
|
||
|
|
||
|
(define (~)
|
||
|
"Non-breaking space."
|
||
|
(string #\240))
|
||
|
|
||
|
(define (---)
|
||
|
"Em dash." "—")
|
||
|
|
||
|
(define* (table #:key (align '()) headers rows)
|
||
|
"Build HTML tables more easily."
|
||
|
(let ((alignment (append align
|
||
|
(make-list (- (length headers)
|
||
|
(length align))
|
||
|
"left"))))
|
||
|
(define (make-row fields)
|
||
|
`(tr ,(map (match-lambda
|
||
|
((field alignment)
|
||
|
`(td (@ (align ,alignment)) ,field)))
|
||
|
(zip fields alignment))))
|
||
|
(define (make-header fields)
|
||
|
`(tr (@ (class "header"))
|
||
|
,(map (match-lambda
|
||
|
((field alignment)
|
||
|
`(th (@ (align ,alignment)) ,field)))
|
||
|
(zip fields alignment))))
|
||
|
`(table
|
||
|
(thead ,(make-header headers))
|
||
|
(tbody ,(map make-row rows)))))
|
||
|
|
||
|
(define (figure file caption)
|
||
|
`(div (@ (class "figure"))
|
||
|
(img (@ (src ,(if (string-prefix? "/" file)
|
||
|
file
|
||
|
(string-append "/images/posts/" file)))
|
||
|
(alt ,caption)))
|
||
|
(p (@ (class "caption")) ,caption)))
|
||
|
|
||
|
(define (wide-img file alt)
|
||
|
`(img (@ (class "full stretch")
|
||
|
(src ,(if (string-prefix? "/" file)
|
||
|
file
|
||
|
(string-append "/images/posts/" file)))
|
||
|
(alt ,alt))))
|