more tests and fixes, renamed to Bibliography and Citation
This commit is contained in:
parent
75809edb6b
commit
457f4104d4
|
@ -1,5 +1,5 @@
|
|||
module BibTeX
|
||||
export Bib, BibItem
|
||||
export Bibliography, Citation
|
||||
|
||||
include("parser.jl")
|
||||
include("bibitem.jl")
|
||||
|
|
44
src/bib.jl
44
src/bib.jl
|
@ -1,39 +1,39 @@
|
|||
struct Bib <: Associative{String,BibItem}
|
||||
struct Bibliography <: Associative{String,Citation}
|
||||
preamble::String
|
||||
data::Dict{String,BibItem}
|
||||
data::Dict{String,Citation}
|
||||
end
|
||||
|
||||
"""
|
||||
Bib(bibtex::String)
|
||||
Bib(io::IO)
|
||||
Bibliography(bibtex::String)
|
||||
Bibliography(io::IO)
|
||||
|
||||
Given a string (or IO stream) of bibtex-format bibliography data,
|
||||
parses the data and returns a `Dict`-like object `b::Bib` that
|
||||
parses the data and returns a `Dict`-like object `b::Bibliography` that
|
||||
behaves as a dictionary mapping strings to bibliography items
|
||||
[`BibItem`](@ref).
|
||||
[`Citation`](@ref).
|
||||
"""
|
||||
function Bib(bibtex::String)
|
||||
function Bibliography(bibtex::String)
|
||||
preamble, data = parse_bibtex(bibtex)
|
||||
return Bib(preamble, Dict(k=>BibItem!(v) for (k,v) in data))
|
||||
return Bibliography(preamble, Dict(k=>Citation!(v) for (k,v) in data))
|
||||
end
|
||||
Bib(io::IO) = Bib(readstring(io))
|
||||
Base.open(::Type{Bib}, args...) = open(io -> Bib(io), args...)
|
||||
Bibliography(io::IO) = Bibliography(readstring(io))
|
||||
Base.open(::Type{Bibliography}, args...) = open(io -> Bibliography(io), args...)
|
||||
|
||||
Base.similar(b::Bib) = Bib("", Dict{String,BibItem}())
|
||||
Base.rehash!(b::Bib, n=length(b.data)) = begin rehash!(b.data, n); b; end
|
||||
Base.sizehint!(b::Bib, n) = begin sizehint!(b.data, n); b; end
|
||||
Base.empty!(b::Bib) = begin empty!(b.data); b; end
|
||||
Base.copy(b::Bib) = Bib(b.preamble, copy(b.data))
|
||||
Base.similar(b::Bibliography) = Bibliography("", Dict{String,Citation}())
|
||||
Base.rehash!(b::Bibliography, n=length(b.data)) = begin Base.rehash!(b.data, n); b; end
|
||||
Base.sizehint!(b::Bibliography, n) = begin sizehint!(b.data, n); b; end
|
||||
Base.empty!(b::Bibliography) = begin empty!(b.data); b; end
|
||||
Base.copy(b::Bibliography) = Bibliography(b.preamble, copy(b.data))
|
||||
|
||||
function Base.setindex!(b::Bib, v::BibItem, k::AbstractString)
|
||||
setindex!(b.data[String(k)], v)
|
||||
function Base.setindex!(b::Bibliography, v::Citation, k::AbstractString)
|
||||
b.data[String(k)] = v
|
||||
return b
|
||||
end
|
||||
Base.get(b::Bib, k::AbstractString, default) = get(b.data, String(k), default)
|
||||
Base.get(b::Bibliography, k::AbstractString, default) = get(b.data, String(k), default)
|
||||
|
||||
Base.start(b::Bib) = start(b.data)
|
||||
Base.done(b::Bib, i) = done(b.data, i)
|
||||
Base.next(b::Bib, i) = next(b.data, i)
|
||||
Base.length(b::Bib) = length(b.data)
|
||||
Base.start(b::Bibliography) = start(b.data)
|
||||
Base.done(b::Bibliography, i) = done(b.data, i)
|
||||
Base.next(b::Bibliography, i) = next(b.data, i)
|
||||
Base.length(b::Bibliography) = length(b.data)
|
||||
|
||||
# todo: add specialized Base.show methods for MIME"text/bibtex" etc.
|
||||
|
|
|
@ -1,41 +1,42 @@
|
|||
"""
|
||||
BibItem{S}(data::Dict{String,String})
|
||||
Citation{S}(data::Dict{String,String})
|
||||
|
||||
A bibliography item in a bibTeX database, based on a dictionary of
|
||||
strings to values. It is parameterized by a symbol `S` giving the
|
||||
type of the item (`:article` etcetera). A `b::BibItem` supports
|
||||
type of the item (`:article` etcetera). A `b::Citation` supports
|
||||
`b[key]` access to retrieve the data and in general acts like
|
||||
a dictionary from `String` to `String`.
|
||||
"""
|
||||
struct BibItem{S} <: Associative{String,String}
|
||||
struct Citation{S} <: Associative{String,String}
|
||||
data::Dict{String,String}
|
||||
end
|
||||
Citation{S}() where {S} = Citation{S}(Dict{String,String}())
|
||||
|
||||
function BibItem!(data::Dict{String,String})
|
||||
function Citation!(data::Dict{String,String})
|
||||
S = Symbol(pop!(data, "__type__"))
|
||||
return BibItem{S}(data)
|
||||
return Citation{S}(data)
|
||||
end
|
||||
|
||||
Base.similar(b::BibItem{S}) where {S} = BibItem{S}(Dict{String,String}())
|
||||
Base.rehash!(b::BibItem, n=length(b.data)) = begin rehash!(b.data, n); b; end
|
||||
Base.sizehint!(b::BibItem, n) = begin sizehint!(b.data, n); b; end
|
||||
Base.empty!(b::BibItem) = begin empty!(b.data); b; end
|
||||
Base.copy(b::BibItem{S}) where {S} = BibItem{S}(copy(b.data))
|
||||
Base.similar(b::Citation{S}) where {S} = Citation{S}(Dict{String,String}())
|
||||
Base.rehash!(b::Citation, n=length(b.data)) = begin rehash!(b.data, n); b; end
|
||||
Base.sizehint!(b::Citation, n) = begin sizehint!(b.data, n); b; end
|
||||
Base.empty!(b::Citation) = begin empty!(b.data); b; end
|
||||
Base.copy(b::Citation{S}) where {S} = Citation{S}(copy(b.data))
|
||||
|
||||
Base.get(b::BibItem, k::AbstractString, default) = get(b.data, String(k), default)
|
||||
Base.getindex(b::BibItem, k::AbstractString) = getindex(b.data, String(k))
|
||||
function Base.setindex!(b::BibItem, v::AbstractString, k::AbstractString)
|
||||
Base.get(b::Citation, k::AbstractString, default) = get(b.data, String(k), default)
|
||||
Base.getindex(b::Citation, k::AbstractString) = getindex(b.data, String(k))
|
||||
function Base.setindex!(b::Citation, v::AbstractString, k::AbstractString)
|
||||
b.data[String(k)] = String(v)
|
||||
return b
|
||||
end
|
||||
|
||||
Base.start(b::BibItem) = start(b.data)
|
||||
Base.done(b::BibItem, i) = done(b.data, i)
|
||||
Base.next(b::BibItem, i) = next(b.data, i)
|
||||
Base.length(b::BibItem) = length(b.data)
|
||||
Base.start(b::Citation) = start(b.data)
|
||||
Base.done(b::Citation, i) = done(b.data, i)
|
||||
Base.next(b::Citation, i) = next(b.data, i)
|
||||
Base.length(b::Citation) = length(b.data)
|
||||
|
||||
function Base.show{S}(io::IO, b::BibItem{S})
|
||||
print(io, "BibItem{:$S}(", length(b), " entries)")
|
||||
function Base.show{S}(io::IO, b::Citation{S})
|
||||
print(io, "Citation{:$S}(", length(b), " entries)")
|
||||
end
|
||||
|
||||
# TODO: add Base.show text/plain and text/markdown for formatted citation
|
||||
|
|
|
@ -14,7 +14,29 @@ Documenter.makedocs(
|
|||
)
|
||||
|
||||
@testset "examples.bib" begin
|
||||
b = open(Bib, joinpath("..", "example", "examples.bib"), "r")
|
||||
b = open(Bibliography, joinpath("..", "example", "examples.bib"), "r")
|
||||
@test length(b) == 92
|
||||
@test (b["angenendt"]::BibItem{:article})["date"] == "2002"
|
||||
@test (b["angenendt"]::Citation{:article})["date"] == "2002"
|
||||
end
|
||||
|
||||
@testset "small bib" begin
|
||||
b = Bibliography("""
|
||||
@article{foo, bar=baz}
|
||||
@book{bar, foobar=1}
|
||||
""")
|
||||
@test get(b, "foobar", nothing) === nothing
|
||||
@test get(b["foo"], "blah", nothing) === nothing
|
||||
|
||||
@test string(b["foo"]) == "Citation{:article}(1 entries)"
|
||||
|
||||
Base.rehash!(b)
|
||||
b2 = copy(b)
|
||||
@test isempty(sizehint!(empty!(b2),10))
|
||||
@test isempty(similar(b))
|
||||
b2["x"] = Citation{:foo}()
|
||||
b2["x"]["bar"] = "blah"
|
||||
@test length(b2) == length(b2["x"]) == 1
|
||||
@test b2["x"]["bar"] == "blah"
|
||||
@test collect(b2)[1][2] == b2["x"]
|
||||
@test collect(b2["x"])[1] == ("bar"=>"blah")
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue