Software: beastie

Norman Gray gray at nxg.name
Wed May 22 19:59:24 CEST 2024


Karl, hello.

Karl Berry wrote:

> I don't know that it's relevant, but what came to mind is one of the
> wishlist items that's been in my head for a long time: a bst or other
> file that can do the usual bib processing, but outputs a reasonably
> machine-readable marked-up file like:

I've quickly adapted/extended the extract-bib.scm program in the distribution's examples/ directory (the modified version is attached), and now...

$ beastie extract-bib.scm -O crossref test.aux
<citation_list><citation key="kaplan05"><article_title>The {IAU} Resolutions on Astronomical Reference Systems, Time Scales, and Earth Rotation Models: Explanation and Implementation</article_title>George H Kaplan<issue>179</issue><cYear>2005</cYear></citation><citation key="kennefick09"><journal_title>Physics Today</journal_title><article_title>Testing Relativity from the 1919 Eclipse---a Question of Bias</article_title>Daniel Kennefick<volume>62</volume><issue>3</issue><first_page>37-42</first_page><cYear>2009</cYear><doi>10.1063/1.3099578</doi></citation><citation key="kennefick12"><article_title>Not Only Because of Theory: {Dyson}, {Eddington}, and the Competing Myths of the 1919 Eclipse Expedition</article_title>Daniel Kennefick<first_page>201--232</first_page><cYear>2012</cYear><doi>10.1007/978-0-8176-4940-1_9</doi><isbn>978-0-8176-4940-1</isbn></citation><citation key="lorentz52"><article_title>The Principle of Relativity</article_title>H A Lorentz<cYear>1952</cYear><isbn>9780486600819</isbn></citation></citation_list>

(hmm: it would do no harm for me to chuck in a few line-breaks there...)

That would count as _preliminary_, since it doesn't split page ranges so that it produces <first_page> correctly,  and it should be type-sensitive enough to detect when a BibTeX 'title' is a crossref article_title or book_title, but it's a sketch.  But was that the sort of thing you were meaning?

Also, now:

$ beastie extract-bib.scm -O yaml test.aux
- key: kaplan05
  type: techreport
  title: The {IAU} Resolutions on Astronomical Reference Systems, Time Scales, and Earth Rotation Models: Explanation and Implementation
  url: https://www.usno.navy.mil/USNO/astronomical-applications/publications/Circular_179.pdf
  institution: United States Naval Observatory
  type: Circular
  number: 179
  year: 2005
  author:
    - George H Kaplan
- key: kennefick09
  type: article
  title: Testing Relativity from the 1919 Eclipse---a Question of Bias
  pages: 37-42
  number: 3
  volume: 62
  year: 2009
  journal: Physics Today
  author:
    - Daniel Kennefick
  doi: 10.1063/1.3099578
- key: kennefick12
  type: inbook
  url: https://doi.org/10.1007/978-0-8176-4940-1_9
  isbn: 978-0-8176-4940-1
  doi: 10.1007/978-0-8176-4940-1_9
  title: Not Only Because of Theory: {Dyson}, {Eddington}, and the Competing Myths of the 1919 Eclipse Expedition
  booktitle: Einstein and the Changing Worldviews of Physics
  address: Boston
  publisher: Birkh\"auser Boston
  abstract: One of the most celebrated physics experiments of the twentieth century, a century of many great breakthroughs in physics, took place on May 29th, 1919, in two remote equatorial locations. One was the town of Sobral in northern Brazil, the other the island of Principe off the west coast of Africa. The experiment in question concerned the problem of whether light rays are deflected by gravitational forces, and took the form of astrometric observations of the positions of stars near the Sun during a total solar eclipse. The expedition to observe the eclipse proved to be one of those infrequent, but recurring, moments when astronomical observations have overthrown the foundations of physics. In this case it helped replace Newton's Law of Gravity with Einstein's theory of General Relativity as the generally accepted fundamental theory of gravity. It also became, almost immediately, one of those uncommon occasions when a scientific endeavor captures and holds the attention of the public throughout the world.
  editor:
    - Christoph Lehner
    - Jürgen Renn
    - Matthias Schemmel
  note: See also arXiv:0709.0685
  pages: 201--232
  year: 2012
  author:
    - Daniel Kennefick
- key: lorentz52
  type: book
  title: The Principle of Relativity
  isbn10: 0-486-60081-5
  translator:
    - W Perrett
    - G B Jeffery
  publisher: Dover
  year: 1952
  author:
    - H A Lorentz
    - A Einstein
    - H Minkowski
    - H Weyl
  isbn: 9780486600819

(I'm not 100% positive that's valid YAML, but it looks right-ish).


>     I didn't aim to be 100% compatible with bibtex-the-program
>
> The main issue that comes to mind for me is sorting compatibility. For
> accented last names and other such, BibTeX effectively requires
> something like:
>   author = "{\noopsort{SortKey}{LastName}}, First"
>
> Does that still work in beastie?

It does, yes.

Indeed {\noopsort{SortKey}{Ol{\'e}}, Chlo\"e} turns into author "Chloë \noopsort{SortKey}{Olé}"

I should make a note to myself that that is the sort of thing one might reasonably find here.  It isn't disrupted by beastie's actions in expanding {\'e}, etc, since that step passes unchanged, and quietly, everything it doesn't recognise.

Best wishes,

Norman


-- 
Norman Gray  :  https://nxg.me.uk
-------------- next part --------------
;; Given a .aux file, create a .bib file which contains the references
;; it requires, as extracted from the one or more .bib files it
;; references.
;;
;; With options -Ocrossref and -Oyaml, produce the output in
;; (rough) crossref format (see
;; <https://www.crossref.org/documentation/schema-library/markup-guide-metadata-segments/references/>),
;; or YAML, respectively.
;;
;; Usage:
;;
;;      beastie extract-bib.scm foo.aux
;;
;; Just to show how (and to support \cite{*}) we also output the
;; result sorted in order of increasing date+authorname.
;;
;; This works with beastie v0.8.
;; The functions it uses may change with later versions.

(module 'aux 'bibtex 'authors 'xexpr)

;; Pick a format
;(define *name-format* '((von "~") (last) (", " junior) (", " first)))
(define *name-format* '((first " ") (von "~") (last) (", " junior)))

(define (print/bibtex! l)
  (for-each entry-print l))

(define (print/crossref! entry-list)
  (define (entry->crossref-citation e)
    ;; given an entry?, produce a <citation> as xexpr?
    (with-fields-from-entry e
        ()
        (journal title year volume number pages author doi isbn)
      ;; The following should do different things for different entry types:
      ;; eg, the 'title' is a <article_title> for articles, and a <volume_title> for books.
      ;; Other crossref subtleties?
      `(citation ((key ,(symbol->string (entry-key e))))
                 . ,(filter values
                            (list
                             (and journal `(journal_title ,journal))
                             (and title `(article_title ,title))
                             (and author
                                  (let ((authors (parse-author-list author)))
                                    (format-name *name-format* (car authors))))
                             (and volume `(volume ,volume))
                             (and number `(issue ,number))
                             (and pages `(first_page ,pages)) ;XXX should be just first page!
                             (and year `(cYear ,year))
                             (and doi `(doi ,doi))
                             (and isbn `(isbn ,isbn)))))))
  (xexpr-write/xml!
   `(citation_list . ,(map entry->crossref-citation entry-list))))

(define (print/yaml! entry-list)
  (define (print-field/yaml! kv)
    (let ((field (car kv))
          (value (cdr kv)))
      (case field
        ((author editor translator)
         (let ((authors (parse-author-list value)))
           (printf "  ~a:~%" field)
           (for-each (λ (a)
                       (printf "    - ~a~%"
                               (format-name *name-format* a)))
                     authors)))
        (else (printf "  ~a: ~a~%" field value)))))
  (define (print-entry/yaml! e)
    (printf "- key: ~a~%  type: ~a~%" (entry-key e) (entry-type e))
    (for-each print-field/yaml!
              (entry-fields e)))
  (for-each print-entry/yaml! entry-list))

(define (exit/usage)
  (eprintf "Usage:~%    beastie [-O fmt] extract-bib.scm foo.aux~%~%Respects the value of $BIBINPUTS~%")
  (exit 1))

;; Parse the argument list
(define-values (*aux-file* print-entries!)
  (receive (cmd opts args)
      (getopt '((#\O format
                 "Output format: bibtex | crossref | yaml (default bibtex)"
                 (string->symbol format))))
    ;(eprintf "cmd=~s  opts=~s  args=~s~%" cmd opts args)
    (values
     (case (length args)
       ((0) (exit/usage))
       ((1) (car args))
       (else
        (eprintf "Too many arguments.~%")
        (exit/usage)))
     (cond ((assq #\O opts)
            => (λ (format-option)
                 (case (cdr format-option)
                   ((bibtex) print/bibtex!)
                   ((crossref) print/crossref!)
                   ((yaml) print/yaml!)
                   (else (eprintf "Unexpected -O option: ~a~%" (cdr format-option))
                         (exit/usage)))))
           (else                        ;default: output .bib
            print/bibtex!)))))

;; Extract the requested citations (may be 'all) from the one or more bibfiles
;; (bibstyle is ignored).
;; Returns a sorted list of entry?
(define (extract-aux citations bibfiles bibstyle)
  (unless (and (or (eqv? citations 'all)
                   (list? citations))
               (list? bibfiles))
    (define (list/printing l)
      (cond ((not l) "#f")
            ((null? l) "()")
            (else (sprintf "(~s...)" (car l)))))
    (eprintf "extract-aux: citation list = ~a, and bibfiles list = ~a must both be lists~%"
             (list/printing citations) (list/printing bibfiles))
    (exit 1))

  (let ((citations/set            ;the list of citations as a set/hash
         (if (eqv? citations 'all)
             (λ (key) #t)    ;dummy: include all entries in the output
             (make-set/eqv citations)))
        (allbib                 ;parse all of the mentioned .bib files
         (apply append (map parse-bibtex-file bibfiles))))
    (sort! (fold (lambda (e knil)
                   ;; include only those entries whose key appears in citations/set
                   (if (citations/set (entry-key e))
                       (cons e knil)
                       knil))
                 '()
                 allbib)
           entry<?)))

;; Wrap parse-aux-file:
;; discard any .bst file found in the aux file
;; (we don't need it, and so get an error we don't care about, if it's not findable).
(define (parse-aux-file/nobst fn)
  (cond ((parse-aux-file fn)
         => (lambda (result)
              (list (car result) (cadr result) #f)))
        (else #f)))

(print-entries!
 (call-with-aux-file *aux-file*
                     extract-aux
                     :parse-aux-file parse-aux-file/nobst))


More information about the texhax mailing list.