;; Insert a bibliography into a Markdown file. ;; ;; This version does _not_ use the built-in support for citations ;; (RMarkdown-style), but instead illustrates how one would grub about ;; in the parse-tree and support citations formatted as `[[ref]]()` ;; (not a very sensible choice of syntax, but chosen as one ;; which the Markdown parser here doesn't recognise as special). ;; ;; Usage: ;; ;; beastie make-bib.scm foo.md bibfile.bib ;; ;; The citations are indicated by links [[ref]](). ;; ;; This works with beastie v0.14. The functions it uses may change ;; with later versions. ;; ;; Limitations: ;; ;; * It currently support only a subset of types explicitly. ;; * There's no discrimination between colliding author-year pairs ;; (ie, no 1905a/b/c) ;; * No distinction between (the equivalents of) \cite, \citep, \citeyear ;; ;; Respects BIBINPUTS. ;; ;; This file is part of Beastie ;; SPDX-FileCopyrightText: 2023 Norman Gray ;; SPDX-License-Identifier: BSD-2-Clause (module 'markdown 'xexpr 'bibtex) (unless (= (length *command-line*) 3) (eprintf "Insert a bibliography into a Markdown file.~%The citations are identified by [[ref]]().~%~%") (eprintf "Usage:~% beastie ~a foo.md database.bib~%" (car *command-line*)) (eprintf "~%Respects the value of $BIBINPUTS~%") (exit 1)) (define *input-markdown* (cadr *command-line*)) (define *bibtex-database* ;; resolve-file throws an error if it can't find a file (resolve-file (caddr *command-line*) ".bib")) (module "plain.scm") ;; Given a xexpr TREE with the document content (parsed from Markdown), ;; and a hash REFS (symbol? -> string?) which maps citation keys to reference text, ;; produces a copy of the input tree with (a ((href "")) "ref") elements ;; filled in. (define (insert-refs tree refs) (define (edit-tree el) (if (list? el) (receive (gi atts content) (xexpr-disassemble el) (if (and (eqv? gi 'a) (equal? (assv 'href atts) '(href ""))) ;; content is ("[" ref "]") (let* ((key (string->symbol (cadr content))) (citation (refs key))) (if citation `(a ((href ,(sprintf "#~a" key))) "(" ,citation ")") `(a ((href ,(sprintf "#~a" key))) "[" key "]"))) `(,gi ,atts . ,(map edit-tree content)))) el)) (edit-tree tree)) ;; The text contains references formatted as [[ref]](), which appear ;; in the parse-tree as (a ((href "")) "[" ref "]") (define text (parse-markdown-file *input-markdown*)) (define refs (map (lambda (e) ; argument is (a ((...)) "[" ref "]") (list-ref e 3)) (xexpr-path-search (list 'a (lambda (e) (string=? (xexpr-get-attribute e 'href) ""))) text))) ;; look at what we've got so far ;(eprintf "text=~s~%refs=~s~%" text refs) (let ((bib ;produces a list of citation? objects -- see bibtex.scm (assemble-bibliography (map string->symbol refs) (list *bibtex-database*)))) (xexpr-write/xhtml! `(body ,@(cdr (insert-refs text (apply hash-table (apply append (map (lambda (b) (list (citation-key b) (citation-reference b))) bib))))) (h2 "Bibliography") ,@(map citation-html bib)))) ;; (printf "refs=~s bib=~s~%" refs (list (resolve-file "science" ".bib"))) ;; (process-citations (map string->symbol refs) ;; (list (resolve-file "science" ".bib")) ;; #f) ;(call-with-aux-file "herbert-ives.aux" process-citations)