179 lines
6.9 KiB
Scheme
179 lines
6.9 KiB
Scheme
(define (join-adjacent type? type-append list)
|
|
(let loop ((new-list '()) (list list))
|
|
(if (null? list) (reverse new-list)
|
|
(loop (if (and (not (null? new-list))
|
|
(type? (car new-list))
|
|
(type? (car list)))
|
|
(cons (type-append (car new-list)
|
|
(car list))
|
|
(cdr new-list))
|
|
(cons (car list) new-list))
|
|
(cdr list)))))
|
|
|
|
(define (join-adjacent-strings list)
|
|
(join-adjacent string? string-append list))
|
|
|
|
(define (vector-refs vec . indexes)
|
|
(let loop ((obj vec) (indexes indexes))
|
|
(if (null? indexes) obj
|
|
(loop (vector-ref obj (car indexes))
|
|
(cdr indexes)))))
|
|
|
|
(define (pandoc-json->sxml json)
|
|
|
|
(define (convert-block-or-inline element)
|
|
(if (string? element) element (convert-block element)))
|
|
|
|
(define (convert-block block)
|
|
(let ((type (cdr (assq 't block))))
|
|
(define (contents) (cdr (assq 'c block)))
|
|
(define (contents-list) (vector->list (contents)))
|
|
(cond ((equal? type "Space")
|
|
" ")
|
|
((equal? type "Str")
|
|
(contents))
|
|
((equal? type "BulletList")
|
|
`(ul
|
|
,@(map (lambda (list-element)
|
|
`(li ,@(convert-many (vector->list list-element))))
|
|
(contents-list))))
|
|
((equal? type "BlockQuote")
|
|
`(blockquote
|
|
,@(convert-many (contents-list))))
|
|
((equal? type "Code")
|
|
`(code ,@(convert-many (cdr (contents-list)))))
|
|
((equal? type "CodeBlock")
|
|
`(pre (@ (data-syntax ,@(join-adjacent-strings
|
|
(vector->list
|
|
(vector-refs (contents) 0 1)))))
|
|
,@(convert-many (cdr (contents-list)))))
|
|
((equal? type "Emph")
|
|
`(em ,@(convert-many (contents-list))))
|
|
((equal? type "Header")
|
|
(let* ((level (car (contents-list)))
|
|
(h-tag (string->symbol
|
|
(string-append
|
|
"h" (number->string (inexact->exact level))))))
|
|
`(,h-tag ,@(convert-many (vector->list
|
|
(list-ref (contents-list) 2))))))
|
|
((equal? type "Link")
|
|
`(a (@ (href ,(join-adjacent-strings
|
|
(vector->list (vector-ref (contents) 2)))))
|
|
,@(convert-many (vector->list (vector-ref (contents) 1)))))
|
|
((equal? type "Plain")
|
|
`(span ,@(convert-many (contents-list))))
|
|
((equal? type "Para")
|
|
`(p ,@(convert-many (contents-list))))
|
|
((equal? type "Quoted") ; TODO: What's this?
|
|
`(blockquote
|
|
,@(convert-many '())))
|
|
((equal? type "SingleQuote") ; TODO: What's this?
|
|
`(blockquote
|
|
,@(convert-many '())))
|
|
((equal? type "DoubleQuote") ; TODO: What's this?
|
|
`(blockquote
|
|
,@(convert-many '())))
|
|
((equal? type "OrderedList") ; TODO: What's this?
|
|
`(blockquote
|
|
,@(convert-many '())))
|
|
((equal? type "Superscript") ; TODO: What's this?
|
|
`(blockquote
|
|
,@(convert-many '())))
|
|
((equal? type "SoftBreak")
|
|
"\n")
|
|
((equal? type "Strong")
|
|
`(strong ,@(convert-many (contents-list))))
|
|
((equal? type "Table")
|
|
(let ((headings (vector-refs (contents) 3 1 0 1)))
|
|
`(table
|
|
(tr
|
|
,@(map (lambda (cell)
|
|
(let ((elements (vector->list
|
|
(vector-refs cell 4))))
|
|
`(th ,@(map convert-block-or-inline elements))))
|
|
(vector->list headings)))
|
|
,@(map (lambda (row)
|
|
`(tr ,@(map (lambda (cell)
|
|
(let ((elements
|
|
(vector->list
|
|
(vector-refs cell 4))))
|
|
`(td ,@(map convert-block-or-inline
|
|
elements))))
|
|
(vector->list (vector-refs row 1)))))
|
|
(vector->list (vector-refs (contents) 4 0 3))))))
|
|
(else
|
|
(error "Unknown type in pandoc JSON" type)))))
|
|
|
|
(define (convert-many elements)
|
|
(join-adjacent-strings (map convert-block-or-inline elements)))
|
|
|
|
(define (assert-supported-version)
|
|
(let* ((version (cdr (assq 'pandoc-api-version json)))
|
|
(major (vector-ref version 0)))
|
|
(unless (= major 1)
|
|
(error "Pandoc API version is not 1.x" version))))
|
|
|
|
(assert-supported-version)
|
|
(convert-many (vector->list (cdr (assq 'blocks json)))))
|
|
|
|
;;
|
|
|
|
(define (pandoc-bytevectors->json pandoc input-format bytevectors)
|
|
(pandoc input-format bytevectors))
|
|
|
|
(define (pandoc-strings->json pandoc input-format strings)
|
|
(pandoc-bytevectors->json
|
|
pandoc input-format
|
|
(map string->utf8 strings)))
|
|
|
|
(define (pandoc-files->json pandoc input-format filenames)
|
|
(pandoc-bytevectors->json
|
|
pandoc input-format
|
|
(map (lambda (filename)
|
|
(call-with-binary-input-file filename read-bytevector-all))
|
|
filenames)))
|
|
|
|
;;
|
|
|
|
(define (pandoc-bytevector->json pandoc input-format bytevector)
|
|
(car (pandoc-bytevectors->json pandoc input-format (list bytevector))))
|
|
|
|
(define (pandoc-string->json pandoc input-format string)
|
|
(car (pandoc-strings->json pandoc input-format (list string))))
|
|
|
|
(define (pandoc-file->json pandoc input-format filename)
|
|
(car (pandoc-files->json pandoc input-format (list filename))))
|
|
|
|
;;
|
|
|
|
(define (pandoc-bytevectors->sxml pandoc input-format bytevectors)
|
|
(map pandoc-json->sxml
|
|
(pandoc-bytevectors->json pandoc input-format bytevectors)))
|
|
|
|
(define (pandoc-strings->sxml pandoc input-format strings)
|
|
(map pandoc-json->sxml
|
|
(pandoc-strings->json pandoc input-format strings)))
|
|
|
|
(define (pandoc-files->sxml pandoc input-format filenames)
|
|
(map pandoc-json->sxml
|
|
(pandoc-files->json pandoc input-format filenames)))
|
|
|
|
;;
|
|
|
|
(define (pandoc-bytevector->sxml pandoc input-format bytevector)
|
|
(car (pandoc-bytevectors->sxml pandoc input-format (list bytevector))))
|
|
|
|
(define (pandoc-string->sxml pandoc input-format string)
|
|
(car (pandoc-strings->sxml pandoc input-format (list string))))
|
|
|
|
(define (pandoc-file->sxml pandoc input-format filename)
|
|
(car (pandoc-files->sxml pandoc input-format (list filename))))
|
|
|
|
;;
|
|
|
|
(define (pandoc-port->json pandoc input-format port)
|
|
(pandoc-bytevector->json pandoc input-format (read-bytevector-all port)))
|
|
|
|
(define (pandoc-port->sxml pandoc input-format port)
|
|
(pandoc-bytevector->sxml pandoc input-format (read-bytevector-all port)))
|