(module spod mzscheme
(provide spod
spod-extend
spod-join
spod-comma
spod-concat
spod-nlnl
spod-nl
spod-append
spod-empty
spod-enclose
spod-apply
spod-merge
spod-null?
spod-module-def
spod-module-add
spod-module-doc
%spod-module-add
spod-define
->spod
extract-spod
spod-install-provider
spod-provider
)
(define SPOD-PROVIDER #f)
(define (spod-install-provider provider)
(set! SPOD-PROVIDER provider))
(define (spod-provider)
SPOD-PROVIDER)
(define-syntax spod-define
(syntax-rules ()
((_ documentation
function-definition
body ...)
(begin
(spod-module-add (s=== (format "~a" 'function-definition))
documentation)
(define function-definition body ...))
)))
(define (spod-null? a)
(SPOD-PROVIDER 'null? a))
(define (spod-join sym list-of-stuff)
(define (value e)
e)
(define (i-cons L)
(if (null? L)
L
(if (null? (cdr L))
(list (value (car L)))
(cons (value (car L)) (cons sym (i-cons (cdr L)))))))
(let ((R
(if (not (list? list-of-stuff))
(spod-join sym (list list-of-stuff))
(if (eq? sym 'spod-empty)
list-of-stuff
(i-cons list-of-stuff)))))
R)
)
(define (spod-concat list-of-stuff)
(spod-join " " list-of-stuff))
(define (spod-comma list-of-stuff)
(spod-join ", " list-of-stuff))
(define (spod-nl list-of-stuff)
(spod-join "\n" list-of-stuff))
(define (spod-append list-of-stuff)
(spod-join 'spod-empty list-of-stuff))
(define (spod-nlnl sentence)
(if (not (list? sentence))
(spod-nlnl (list sentence))
(append sentence (list "\n\n"))))
(define (spod-enclose left middle right)
(if (not (list? middle))
(spod-enclose left (list middle) right)
(cons left (append middle (list right)))))
(define (spod-empty)
'spod-empty)
(define (spod-merge . args)
(lambda () (apply SPOD-PROVIDER 'spod-merge (extract-spod args))))
(define (spod-standard-provider)
(define (spod-merge first . rest)
(define (g x)
(if (not (list? x))
x
(if (null? x)
x
(if (list? (car x))
(append (g (car x)) (g (cdr x)))
(if (eq? (car x) 'spod-empty )
(g (cdr x))
(cons (car x) (g (cdr x))))))))
(if (null? rest)
first
(g (cons first rest))))
(define (spod-null? a)
(if (not (list? a))
(spod-null? (list a))
(if (null? a)
#t
(if (eq? (car a) 'spod-empty)
(spod-null? (cdr a))
#f))))
(define (head1 . args)
(spod-nlnl
(spod-concat (cons "=head1" args))))
(define (head2 . args)
(spod-nlnl
(spod-concat (cons "=head2" args))))
(define (head3 . args)
(spod-nlnl
(spod-concat (cons "=head3" args))))
(define (head4 . args)
(spod-nlnl
(spod-concat (cons "=head4" args))))
(define (bold . args)
(spod-enclose "B%=HOD%%" (spod-concat args) "%%HOD=%"))
(define (italics . args)
(spod-enclose "I%=HOD%%" (spod-concat args) "%%HOD=%"))
(define (code . args)
(spod-enclose "C%=HOD%%" (spod-concat args) "%%HOD=%"))
(define (scode . args)
(spod-enclose "S%=HOD%%" (apply code args) "%%HOD=%"))
(define (link where . text)
(spod-enclose "L%=HOD%%" (spod-merge (if (null? text)
where
(spod-concat text)) "|" where ) "%%HOD=%"))
(define (image description link position . size)
(define (find-ext pos)
(if (< pos 0)
""
(if (char=? (string-ref link pos) #\.)
(substring link (+ pos 1) (string-length link))
(find-ext (- pos 1)))))
(let ((type (find-ext (- (string-length link) 1))))
(spod-nlnl
(spod-concat (list "=image"
(spod-comma description link link type position (if (null? size)
(spod-empty)
(car size)))
)))))
(define (p . args)
(spod-nlnl
(spod-concat args)))
(define (lb . args)
(spod-append (list (spod-concat args) "E%=HOD%%lb%%HOD=%\n")))
(define (items . args)
(spod-enclose "=over 1\n\n" (spod-append args) "=back\n\n"))
(define (item . args)
(spod-nlnl
(spod-append (list (spod-nlnl "=item *") (spod-concat args)))))
(define (verbatim . args)
(map (lambda (s)
(if (string? s)
(regexp-replace* "[<]" (regexp-replace* "[>]" s "%%HOD=%") "%=HOD%%")
s))
(spod-nlnl
(spod-merge " " (spod-join "\n " args)))))
(define (syn language . tab)
(spod-nlnl
(string-append (format "=syn ~a,~a" language (if (null? tab) 8 (car tab))))))
(define (spodf . args)
(spod-append args))
(define (table sizes name caption border frame position size . args)
(spod-merge
(spod-nlnl (spod "=table " (spod-comma
(cons (spod-concat sizes)
(list caption
(if (eq? border 'border) 1 0)
(if (eq? frame 'frame) 1 0)
name
position
size)))))
args
(spod-nlnl (spod "=table"))))
(define (srow . args)
(spod-merge
(spod-nlnl "=row")
args))
(define (scell . args)
(spod-merge
(spod-nlnl "=cell")
args
(spod-nlnl "")))
(define (sccell . args)
(spod-merge
(spod-nlnl "=ccell")
args
(spod-nlnl "")))
(define (srcell . args)
(spod-merge
(spod-nlnl "=rcell")
args
(spod-nlnl "")))
(define (over . args)
(spod-merge
(spod-nlnl "=over 1")
(spod-nlnl args)
(spod-nlnl "=back")))
(define (->spod pod . name)
(define (g pod)
(apply spod-merge
(map (lambda (e)
(if (procedure? e)
(e)
e))
pod)))
(let ((fh (if (null? name)
(current-output-port)
(if (port? name)
name
(open-output-file (string-append (format "~a.pod" (car name))) 'text 'replace)))))
(let ((do-close (not (null? name))))
(let ((S (replace-escapes
(string-append "=pod\n\n"
(apply string-append (map (lambda (e) (format "~a" e))
(g pod)))
"=cut\n\n"))))
(display S fh)
(if do-close
(close-output-port fh))
S))))
(lambda (cmd . args)
(letrec ((f (lambda (cmds)
(if (null? cmds)
(error (format "spod-standard-provider: No such command '~a" cmd))
(if (eq? (caar cmds) cmd)
(apply (cadar cmds) args)
(f (cdr cmds)))))))
(f (list
(list 'null? spod-null?)
(list 'spod-merge spod-merge)
(list '->spod ->spod)
(list 'over over)
(list 'srcell srcell)
(list 'sccell sccell)
(list 'scell scell)
(list 'srow srow)
(list 'table table)
(list 'spodf spodf)
(list 'verbatim verbatim)
(list 'syn syn)
(list 'item item)
(list 'items items)
(list 'lb lb)
(list 'p p)
(list 'image image)
(list 'link link)
(list 'scode scode)
(list 'code code)
(list 'italics italics)
(list 'bold bold)
(list 'head1 head1)
(list 'head2 head2)
(list 'head3 head3)
(list 'head4 head4)))))
)
(spod-install-provider (spod-standard-provider))
(define extensions (list))
(define (spod-extension op . args)
(define (f E)
(if (null? E)
(eval (cons op args))
(let ((S (apply (car E) (cons op args))))
(if (eq? S #f)
(f (cdr E))
S))))
(f extensions))
(define (spod-extend function)
(set! extensions (cons function extensions)))
(define (_sinfo copyright authors license version . id)
(spod-nlnl
(spod (s== "Info")
(stable '(15 5 80) 'info "" 'no-border 'no-frame 'center ""
(sr (sc "Copyright") (scc ":") (sc copyright))
(sr (sc "Author(s)") (scc ":") (sc authors))
(sr (sc "License") (scc ":") (sc license))
(sr (sc "Version") (scc ":") (sc version))
(if (null? id)
(spod)
(spod (sr (sc "Id") (sc ":") (sc (car id)))))))))
(define (spod-work op . args)
(cond
((eq? op '=) (lambda () (apply (spod-provider) 'head1 args)))
((eq? op '==) (lambda () (apply (spod-provider) 'head2 args)))
((eq? op '===) (lambda () (apply (spod-provider) 'head3 args)))
((eq? op '====) (lambda () (apply (spod-provider) 'head4 args)))
((eq? op '*) (lambda () (apply (spod-provider) 'bold args)))
((eq? op '/) (lambda () (apply (spod-provider) 'italics args)))
((eq? op '%) (lambda () (apply (spod-provider) 'code args)))
((eq? op '%%) (lambda () (apply (spod-provider) 'scode args)))
((eq? op 'image) (lambda () (apply (spod-provider) 'image args)))
((eq? op 'table) (lambda () (apply (spod-provider) 'table args)))
((eq? op 'row) (lambda () (apply (spod-provider) 'srow args)))
((eq? op 'cell) (lambda () (apply (spod-provider) 'scell args)))
((eq? op 'ccell) (lambda () (apply (spod-provider) 'sccell args)))
((eq? op 'rcell) (lambda () (apply (spod-provider) 'srcell args)))
((eq? op 'link) (lambda () (apply (spod-provider) 'link args)))
((eq? op 'p) (lambda () (apply (spod-provider) 'p args)))
((eq? op '\\) (lambda () (apply (spod-provider) 'lb args)))
((eq? op 'items) (lambda () (apply (spod-provider) 'items args)))
((eq? op '-) (lambda () (apply (spod-provider) 'item args)))
((eq? op 'verbatim) (lambda () (apply (spod-provider) 'verbatim args)))
((eq? op 'syn) (lambda () (apply (spod-provider) 'syn args)))
((eq? op 'spod) (lambda () (apply (spod-provider) 'spodf args)))
((eq? op 'info) (lambda () (apply _sinfo args)))
((eq? op 'over) (lambda () (apply (spod-provider) 'over args)))
(else
(lambda () (apply spod-extension (cons op args))))))
(define-syntax spod-internal
(syntax-rules ()
((_ op)
(spod-work 'op))
((_ op a1)
(spod-work 'op a1))
((_ op a1 ...)
(spod-work 'op a1 ...))
))
(define-syntax spod1
(lambda (x)
(syntax-case x (s= s== s=== s==== sover
stable sr sc scc scr
sinfo
sp spp
s\\ s* s/ s% s%%
simage slink
sitems s-
sverb ssyn spod)
((_ (s= a1 ...))
(syntax (spod-internal = (spod a1) ...)))
((_ (s== a1 ...))
(syntax (spod-internal == (spod a1) ...)))
((_ (s=== a1 ...))
(syntax (spod-internal === (spod a1) ...)))
((_ (s==== a1 ...))
(syntax (spod-internal ==== (spod a1) ...)))
((_ (s* a1 ...))
(syntax (spod-internal * (spod a1) ...)))
((_ (s/ a1 ...))
(syntax (spod-internal / (spod a1) ...)))
((_ (s% a1 ...))
(syntax (spod-internal % (spod a1) ...)))
((_ (s%% a1 ...))
(syntax (spod-internal %% (spod a1) ...)))
((_ (simage a1 ...))
(syntax (spod-internal image (spod a1) ...)))
((_ (sitems a1 ...))
(syntax (spod-internal items (spod a1) ...)))
((_ (s- a1 ...))
(syntax (spod-internal - (spod a1) ...)))
((_ (sverb a1 ...))
(syntax (spod-internal verbatim (spod a1) ...)))
((_ (ssyn a1 ...))
(syntax (spod-internal syn (spod a1) ...)))
((_ (slink a1 ...))
(syntax (spod-internal link (spod a1) ...)))
((_ (sp a1 ...))
(syntax (spod-internal p (spod a1) ...)))
((_ (spp a1 ...))
(syntax (spod (sp 'a1 ...))))
((_ (s\\ a1 ...))
(syntax (spod-internal \\ (spod a1) ...)))
((_ (sinfo a1 ...))
(syntax (spod-internal info (spod a1) ...)))
((_ (stable a1 ...))
(syntax (spod-internal table (spod a1) ...)))
((_ (sr a1 ...))
(syntax (spod-internal row (spod a1) ...)))
((_ (sc a1 ...))
(syntax (spod-internal cell (spod a1) ...)))
((_ (scc a1 ...))
(syntax (spod-internal ccell (spod a1) ...)))
((_ (scr a1 ...))
(syntax (spod-internal rcell (spod a1) ...)))
((_ (spod a1 ...))
(syntax (spod-internal spod (spod a1) ...)))
((_ (sover a1 ...))
(syntax (spod-internal over (spod a1) ...)))
((_ (any ...))
(syntax (any ...)))
((_ a)
(syntax a)))))
(define-syntax spod
(lambda (x)
(syntax-case x (quote)
((_ (quote a))
(syntax 'a))
((_)
(syntax 'spod-empty))
((_ a1 ...)
(syntax (spod-merge (spod1 a1) ...)))
)))
(define-syntax spod-apply
(syntax-rules ()
((_ op list-of-args)
(apply spod-work (cons 'op list-of-args)))))
(define %spod-current-module-doc (spod))
(define (spod-module-def)
(set! %spod-current-module-doc (spod)))
(define (%spod-module-add doc)
(set! %spod-current-module-doc (spod-merge %spod-current-module-doc doc)))
(define-syntax spod-module-add
(syntax-rules ()
((_ d1 ...)
(%spod-module-add (spod d1 ...)))))
(define-syntax spod-module-doc
(syntax-rules ()
((_)
%spod-current-module-doc)
))
(define BHODRE (regexp "%=HOD%%"))
(define EHODRE (regexp "%%HOD=%"))
(define (replace-escapes S)
(regexp-replace* EHODRE
(regexp-replace* BHODRE
(let ((L (string->list S)))
(apply string-append
(map (lambda (c)
(cond
((char=? c #\<) "E<lt>")
((char=? c #\>) "E<gt>")
(else (string c))))
L))) "<")
">"))
(define (extract-spod pod)
(if (procedure? pod)
(extract-spod (pod))
(if (list? pod)
(map extract-spod pod)
pod)))
(define (->spod pod . name)
(apply SPOD-PROVIDER (cons '->spod (cons (extract-spod pod) name))))
)