#lang racket/base (require racket/contract racket/list racket/match racket/port racket/string markdown markdown/display-xexpr markdown/toc "compiler.rkt" (prefix-in sass: sass) (prefix-in mathml: "ext-mathml/main.rkt") (prefix-in syntax: "ext-syntax/main.rkt") (prefix-in article: "templates/article.html.rkt")) (define metadata? (listof (or/c (list/c 'date integer? integer? integer?) (list/c 'title string?) (list/c 'slug string?) (list/c 'summary string?) (cons/c 'authors (listof string?))))) (define (metadata-ref md key [default (λ () (error "no such key"))]) (match (assoc key md) [#f (if (procedure? default) (default) default)] [(cons _ rst) rst])) (define (metadata-ref+ md key [default (λ () (error "no such key"))]) (first (metadata-ref md key default))) (struct input-document [metadata text] #:transparent) (define (read-doc [port (current-input-port)]) (define metadata (read port)) (unless (metadata? metadata) (error "post front matter is not valid metadata!")) (define text (port->string port)) (input-document metadata text)) (define (markdown->html input) (match-define (input-document md text) input) (define output-raw (parse-markdown text)) (define output-cooked (mathml:transform-xexprs (syntax:transform-xexprs output-raw))) (define output-toc (toc output-cooked)) (define scss-files (append mathml:scss-files syntax:scss-files)) (define top-level-style (string-join (map (λ (x) (format "@import \"~a\";" (path->string x))) scss-files) "\n")) (define styles (sass:compile/string top-level-style #t)) (define document (article:execute (hash 'metadata-ref metadata-ref 'metadata-ref+ metadata-ref+ 'metadata md 'page-styles styles 'content-toc output-toc 'content output-cooked))) (with-output-to-string (λ () (display "") (display-xexpr document)))) (module+ main (require racket/cmdline) (command-line #:program "meow" #:args (infile outfile) (define-rule (render [out outfile] [in infile]) (write-string (markdown->html (read-doc in)) out)) (generate/execute (list render))))