allow keyword arguments to have quotes (closes #39)

main
Matthew Butterick 5 years ago
parent 2e622ce368
commit 10cbb47950

@ -1,11 +1,11 @@
#lang quadwriter/markdown #lang quadwriter/markdown
#:page-size A3 #:page-size "A3"
#:page-orientation wide #:page-orientation "wide"
#:column-count 3 #:column-count 3
#:column-gap 24 #:column-gap 24
#:line-align justify #:line-align "justify"
#:line-wrap best #:line-wrap "best"
#:page-margin-left 200 #:page-margin-left 200
#:page-margin-right 100 #:page-margin-right 100

@ -292,16 +292,16 @@ Even if you're using a @racketmodname[quadwriter] dialect, you can still set top
@codeblock|{ @codeblock|{
#lang quadwriter/markdown #lang quadwriter/markdown
#:page-size tabloid #:page-size "tabloid"
#:page-orientation wide #:page-orientation "wide"
#:font-size 18 #:font-size 18
#:font-color red #:font-color "red"
Brennan and Dale like fancy sauce. Brennan and Dale like fancy sauce.
}| }|
] ]
Any of the @secref{Markup} attributes documented below can be used as keyword arguments. The syntax follows the pattern above: one attribute + value pair per line, with the attribute prefixed with @litchar{#:} to make it a keyword, and the value unquoted. Any of the @secref{Markup} attributes documented below can be used as keyword arguments. The syntax follows the pattern above: one attribute + value pair per line, with the attribute prefixed with @litchar{#:} to make it a keyword, followed by the value.
This keyword syntax works in the @racketmodname[quadwriter], @racketmodname[quadwriter/markdown], and @racketmodname[quadwriter/markup] languages. The idea is to make it easy to adjust the default layout behavior without going outside the source file. This keyword syntax works in the @racketmodname[quadwriter], @racketmodname[quadwriter/markdown], and @racketmodname[quadwriter/markup] languages. The idea is to make it easy to adjust the default layout behavior without going outside the source file.

@ -1,6 +1,7 @@
#lang debug racket/base #lang debug racket/base
(require (for-syntax racket/base) (require (for-syntax racket/base)
racket/match racket/match
racket/dict
pollen/tag pollen/tag
racket/system racket/system
racket/class racket/class
@ -19,20 +20,20 @@
(define ((make-read-syntax expander-mod pt-proc) path-string p) (define ((make-read-syntax expander-mod pt-proc) path-string p)
;; peel off any lines of format #:keyword val (bounded by newline) ;; peel off any lines of format #:keyword val (bounded by newline)
;; and turn them into qexpr attrs ;; and turn them into qexpr attrs
(define kw-val-pat #px"^(#:\\S+)\\s+([\\w ]*)\n")
(define kw-attrs (define kw-attrs
(let loop ([acc null]) (let loop ([kw-val-pairs null])
(cond (cond
[(regexp-try-match #px"^\\s+" p) (loop acc)] [(regexp-try-match #px"^\\s+" p) (loop kw-val-pairs)]
[(regexp-try-match kw-val-pat p) [(equal? (peek-bytes 2 0 p) #"#:") ; discovered a keyword
=> (parameterize ([current-input-port (open-input-string (read-line p))])
(λ (m) (match (list (read) (read))
(match m [(list (? keyword? kw) val) #:when (not (eof-object? val))
[(list _ kw val) (loop (cons (list kw val) acc))]))] (loop (cons (cons kw val) kw-val-pairs))]
[_ (loop kw-val-pairs)]))]
;; reverse in case of multiple values with same keyword, latest takes precedence (by becoming first) ;; reverse in case of multiple values with same keyword, latest takes precedence (by becoming first)
[else (reverse (for/list ([item (in-list acc)]) [else (reverse (for/list ([(kw val) (in-dict kw-val-pairs)])
(match-define (list kw val) (map bytes->string/utf-8 item)) (list (string->symbol (string-trim (keyword->string kw) "#:"))
(list (string->symbol (string-trim kw "#:")) val)))]))) (format "~a" val))))])))
(strip-context (strip-context
(with-syntax ([PATH-STRING path-string] (with-syntax ([PATH-STRING path-string]
[((ATTR-NAME ATTR-VAL) ...) kw-attrs] [((ATTR-NAME ATTR-VAL) ...) kw-attrs]

Loading…
Cancel
Save