Fixing PR12779
original commit: 8b035f3c736d92c5e8ae896b3044eb2e32f44c8a
This commit is contained in:
parent
b5f09c0d39
commit
e690d99f57
|
@ -17,7 +17,7 @@
|
||||||
(list->string
|
(list->string
|
||||||
(let loop ()
|
(let loop ()
|
||||||
(match (peek-char ip)
|
(match (peek-char ip)
|
||||||
[(? pred)
|
[(and (? char?) (? pred))
|
||||||
(cons (read-char ip)
|
(cons (read-char ip)
|
||||||
(loop))]
|
(loop))]
|
||||||
[_
|
[_
|
||||||
|
@ -41,10 +41,13 @@
|
||||||
[(? eof-object?)
|
[(? eof-object?)
|
||||||
(void)]
|
(void)]
|
||||||
[c
|
[c
|
||||||
(perror ip 'read-entries "Expected % or @, got ~v" c)]))
|
;; All other characters are comments.
|
||||||
|
(read-entries ip)]))
|
||||||
|
|
||||||
(define (read-entry ip)
|
(define (read-entry ip)
|
||||||
(match (read-until (λ (c) (char=? c #\{)) ip)
|
(match (read-until (λ (c) (or (char=? c #\{)
|
||||||
|
(char=? c #\()))
|
||||||
|
ip)
|
||||||
[(app string-downcase "string")
|
[(app string-downcase "string")
|
||||||
(slurp-whitespace ip)
|
(slurp-whitespace ip)
|
||||||
(match (read-char ip)
|
(match (read-char ip)
|
||||||
|
@ -84,11 +87,17 @@
|
||||||
(let loop ()
|
(let loop ()
|
||||||
(slurp-whitespace ip)
|
(slurp-whitespace ip)
|
||||||
(define atag (read-tag ip))
|
(define atag (read-tag ip))
|
||||||
|
(cond
|
||||||
|
[(string=? "" atag)
|
||||||
|
(read-char ip)
|
||||||
|
(hash)]
|
||||||
|
[else
|
||||||
(slurp-whitespace ip)
|
(slurp-whitespace ip)
|
||||||
(match (read-char ip)
|
(match (read-char ip)
|
||||||
[#\=
|
[#\=
|
||||||
(slurp-whitespace ip)
|
(slurp-whitespace ip)
|
||||||
(define aval (read-value ip))
|
(define aval (read-value ip))
|
||||||
|
(slurp-whitespace ip)
|
||||||
(match (read-char ip)
|
(match (read-char ip)
|
||||||
[#\,
|
[#\,
|
||||||
(hash-set (loop) atag aval)]
|
(hash-set (loop) atag aval)]
|
||||||
|
@ -97,7 +106,7 @@
|
||||||
[c
|
[c
|
||||||
(perror ip 'read-entry "Parsing entry, expected , or }, got ~v; label is ~v; atag is ~v; aval is ~v" c label atag aval)])]
|
(perror ip 'read-entry "Parsing entry, expected , or }, got ~v; label is ~v; atag is ~v; aval is ~v" c label atag aval)])]
|
||||||
[c
|
[c
|
||||||
(perror ip 'read-entry "Parsing entry tag, expected =, got ~v; label is ~v; atag is ~v" c label atag)])))
|
(perror ip 'read-entry "Parsing entry tag, expected =, got ~v; label is ~v; atag is ~v" c label atag)])])))
|
||||||
(hash-set! ENTRY-DB label
|
(hash-set! ENTRY-DB label
|
||||||
(hash-set alist 'type typ))]))
|
(hash-set alist 'type typ))]))
|
||||||
|
|
||||||
|
@ -106,13 +115,12 @@
|
||||||
(string-downcase
|
(string-downcase
|
||||||
(read-until
|
(read-until
|
||||||
(λ (c) (or (char-whitespace? c)
|
(λ (c) (or (char-whitespace? c)
|
||||||
(char=? c #\=)))
|
(char=? c #\=)
|
||||||
|
(char=? c #\{)
|
||||||
|
(char=? c #\})))
|
||||||
ip)))
|
ip)))
|
||||||
|
|
||||||
(define (read-value ip)
|
(define (read-braced-value ip)
|
||||||
(slurp-whitespace ip)
|
|
||||||
(match (peek-char ip)
|
|
||||||
[#\{
|
|
||||||
(read-char ip)
|
(read-char ip)
|
||||||
(let loop ()
|
(let loop ()
|
||||||
(define first-part (read-until (λ (c) (or (char=? c #\{) (char=? c #\})))
|
(define first-part (read-until (λ (c) (or (char=? c #\{) (char=? c #\})))
|
||||||
|
@ -121,12 +129,42 @@
|
||||||
[#\{
|
[#\{
|
||||||
(string-append first-part (read-value ip) (loop))]
|
(string-append first-part (read-value ip) (loop))]
|
||||||
[#\}
|
[#\}
|
||||||
|
(read-char ip)
|
||||||
|
first-part])))
|
||||||
|
|
||||||
|
(define (read-value ip)
|
||||||
|
(slurp-whitespace ip)
|
||||||
|
(define first-part (read-value-single ip))
|
||||||
|
(slurp-whitespace ip)
|
||||||
|
(match (peek-char ip)
|
||||||
|
[#\#
|
||||||
|
(read-char ip)
|
||||||
|
(string-append first-part (read-value ip))]
|
||||||
|
[_
|
||||||
|
first-part]))
|
||||||
|
|
||||||
|
(define (read-value-single ip)
|
||||||
|
(slurp-whitespace ip)
|
||||||
|
(match (peek-char ip)
|
||||||
|
[#\{
|
||||||
|
(read-braced-value ip)]
|
||||||
|
[#\"
|
||||||
|
(read-char ip)
|
||||||
|
(let loop ()
|
||||||
|
(define first-part (read-until (λ (c) (or (char=? c #\{) (char=? c #\")))
|
||||||
|
ip))
|
||||||
|
(match (peek-char ip)
|
||||||
|
[#\{
|
||||||
|
(string-append first-part (read-braced-value ip) (loop))]
|
||||||
|
[#\"
|
||||||
(read-char ip)
|
(read-char ip)
|
||||||
first-part]))]
|
first-part]))]
|
||||||
[(? char-numeric?)
|
[(? char-numeric?)
|
||||||
(read-while char-numeric? ip)]
|
(read-while char-numeric? ip)]
|
||||||
[(? char-alphabetic?)
|
[(? char-alphabetic?)
|
||||||
(define string-tag (read-until (λ (c) (char=? c #\,)) ip))
|
(define string-tag (read-until (λ (c) (or (char-whitespace? c)
|
||||||
|
(char=? c #\,)))
|
||||||
|
ip))
|
||||||
(hash-ref STRING-DB string-tag
|
(hash-ref STRING-DB string-tag
|
||||||
(λ () string-tag))]
|
(λ () string-tag))]
|
||||||
[c
|
[c
|
||||||
|
@ -238,4 +276,7 @@
|
||||||
[_
|
[_
|
||||||
(make-bib #:title (format "~v" the-raw))]))))
|
(make-bib #:title (format "~v" the-raw))]))))
|
||||||
|
|
||||||
(provide define-bibtex-cite)
|
(provide (struct-out bibdb)
|
||||||
|
path->bibdb
|
||||||
|
bibtex-parse
|
||||||
|
define-bibtex-cite)
|
||||||
|
|
|
@ -18,3 +18,18 @@ Uses @racket[define-cite] from @racketmodname[scriblib/autobib], but augments th
|
||||||
Each string is broken along spaces into citations keys that are looked up in the BibTeX database and turned into @racket[bib?] structures.
|
Each string is broken along spaces into citations keys that are looked up in the BibTeX database and turned into @racket[bib?] structures.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@defstruct*[bibdb ([raw (hash/c string? (hash/c string? string?))]
|
||||||
|
[bibs (hash/c string? bib?)])]{
|
||||||
|
Represents a BibTeX database. The @racket[_raw] hash table maps the labels in the file to hash tables of the attributes and their values. The @racket[_bibs] hash table maps the same labels to Scribble data-structures representing the same information.
|
||||||
|
}
|
||||||
|
|
||||||
|
@defproc[(path->bibdb [path path-string?])
|
||||||
|
bibdb?]{
|
||||||
|
Parses a path into a BibTeX database.
|
||||||
|
}
|
||||||
|
|
||||||
|
@defproc[(bibtex-parse [ip input-port?])
|
||||||
|
bibdb?]{
|
||||||
|
Parses an input port into a BibTeX database.
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,15 @@
|
||||||
(define-runtime-path example.bib "example.bib")
|
(define-runtime-path example.bib "example.bib")
|
||||||
|
|
||||||
(test
|
(test
|
||||||
|
(let ()
|
||||||
|
(define example (path->bibdb example.bib))
|
||||||
|
(define raw (bibdb-raw example))
|
||||||
|
|
||||||
|
(test
|
||||||
|
(hash-ref (hash-ref raw "sweig42") "month") => "march"
|
||||||
|
(hash-ref (hash-ref raw "sweig42a") "month") => "1~mar"
|
||||||
|
(hash-ref (hash-ref raw "sweig42b") "month") => "1~march"
|
||||||
|
(hash-ref (hash-ref raw "sweig42c") "month") => "1~marcha"))
|
||||||
(let ()
|
(let ()
|
||||||
(define-bibtex-cite example.bib
|
(define-bibtex-cite example.bib
|
||||||
~cite-id citet-id generate-bibliography-id)
|
~cite-id citet-id generate-bibliography-id)
|
||||||
|
|
|
@ -309,3 +309,91 @@
|
||||||
Year = {1987},
|
Year = {1987},
|
||||||
Bdsk-Url-1 = {http://doi.acm.org/10.1145/41625.41654}}
|
Bdsk-Url-1 = {http://doi.acm.org/10.1145/41625.41654}}
|
||||||
|
|
||||||
|
@article{hochreiter_long_1997,
|
||||||
|
author = {Hochreiter, S. and Schmidhuber, J.},
|
||||||
|
title = {Long {Short-Term} Memory},
|
||||||
|
volume = {9},
|
||||||
|
number = {8},
|
||||||
|
journal = {Neural Computation},
|
||||||
|
year = {1997},
|
||||||
|
pages = {1735--1780}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Article{py03,
|
||||||
|
author = {Xavier D\'ecoret},
|
||||||
|
title = "PyBiTex",
|
||||||
|
year = 2003
|
||||||
|
}
|
||||||
|
|
||||||
|
@Article{key03,
|
||||||
|
title = "A {bunch {of} braces {in}} title"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Article{key01,
|
||||||
|
author = "Simon {"}the {saint"} Templar",
|
||||||
|
}
|
||||||
|
|
||||||
|
@Article{key01,
|
||||||
|
title = "The history of @ sign"
|
||||||
|
}
|
||||||
|
|
||||||
|
Some {{comments} with unbalanced braces
|
||||||
|
....and a "commented" entry...
|
||||||
|
|
||||||
|
Book{landru21,
|
||||||
|
author = {Landru, Henri D\'esir\'e},
|
||||||
|
title = {A hundred recipes for you wife},
|
||||||
|
publisher = {Culinary Expert Series},
|
||||||
|
year = 1921
|
||||||
|
}
|
||||||
|
|
||||||
|
..some other comments..before a valid entry...
|
||||||
|
|
||||||
|
@Book{steward03,
|
||||||
|
author = { Martha Steward },
|
||||||
|
title = {Cooking behind bars},
|
||||||
|
publisher = {Culinary Expert Series},
|
||||||
|
year = 2003
|
||||||
|
}
|
||||||
|
|
||||||
|
...and finally an entry commented by the use of the special @Comment entry type.
|
||||||
|
|
||||||
|
@Comment{steward03,
|
||||||
|
author = {Martha Steward},
|
||||||
|
title = {Cooking behind bars},
|
||||||
|
publisher = {Culinary Expert Series},
|
||||||
|
year = 2003
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment{
|
||||||
|
@Book{steward03,
|
||||||
|
author = {Martha Steward},
|
||||||
|
title = {Cooking behind bars},
|
||||||
|
publisher = {Culinary Expert Series},
|
||||||
|
year = 2003
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@String{mar = "march"}
|
||||||
|
|
||||||
|
@Book{sweig42,
|
||||||
|
Author = { Stefan Sweig },
|
||||||
|
title = { The impossible book },
|
||||||
|
publisher = { Dead Poet Society},
|
||||||
|
year = 1942,
|
||||||
|
month = mar
|
||||||
|
}
|
||||||
|
|
||||||
|
@Book{sweig42a,
|
||||||
|
month = "1~mar"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Book{sweig42b,
|
||||||
|
month = "1~" # mar
|
||||||
|
}
|
||||||
|
|
||||||
|
@Book{sweig42c,
|
||||||
|
month = "1~" # mar # "a"
|
||||||
|
}
|
||||||
|
|
||||||
|
@preamble{"This bibliography was generated on \today"}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user