""" 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::Citation` supports `b[key]` access to retrieve the data and in general acts like a dictionary from `String` to `String`. """ struct Citation{S} <: Associative{String,String} data::Dict{String,String} end Citation{S}() where {S} = Citation{S}(Dict{String,String}()) function Citation!(data::Dict{String,String}) S = Symbol(pop!(data, "__type__")) return Citation{S}(data) end 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::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::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::Citation{S}) print(io, "Citation{:$S}(", length(b), " entries)") end # TODO: add Base.show text/plain and text/markdown for formatted citation