105 lines
3.2 KiB
Julia
105 lines
3.2 KiB
Julia
#=
|
|
Functions to manage the library
|
|
=#
|
|
using JSON, StringDistances
|
|
|
|
"""
|
|
Add `entry` to `bibliography` on key `id`
|
|
|
|
Defines `pre_add_to_bib` and `after_add_to_bib`.
|
|
"""
|
|
function addtobibliography!(bibliography::Bibliography, id::String, entry::Citation)
|
|
@hook :pre_add_to_bib
|
|
info("Here")
|
|
exists = id in keys(bibliography)
|
|
info("The id you are adding $(id) does " * (exists ? "" : "not ") * "exists")
|
|
if exists
|
|
oldentry = bibliography[id]
|
|
# TODO: run a Levenshtein distance on the two entry and decide
|
|
# what to do Options should be to merge/replace or keep both.
|
|
# In the latter the id must be modified (like id-$counter)
|
|
|
|
old = lowercase(get(oldentry,"title",""))
|
|
new = lowercase(get(entry,"title","-"))
|
|
differencepercent = compare(TokenMax(RatcliffObershelp()), old, new)
|
|
if differencepercent > 0.8
|
|
@hook :duplicated_paper
|
|
warn("The old and the new seems to be the same paper\n
|
|
(similarity is $(differencepercent))")
|
|
@show json(oldentry)
|
|
@show json(entry)
|
|
else
|
|
@hook :similar_paper
|
|
info("keeping both")
|
|
id = nextidnumber(bibliography,id)
|
|
end
|
|
end
|
|
bibliography[id] = entry
|
|
|
|
@hook :after_add_to_bib
|
|
end
|
|
|
|
""" Set `newbib` as a the bibliography, replacing `bibliography`.
|
|
"""
|
|
function setbibliography!(bibliography::Bibliography, newbib::Bibliography)
|
|
empty!(bibliography)
|
|
merge!(bibliography, newbib)
|
|
end
|
|
|
|
import Base.pop!
|
|
function pop!(bibliography::Bibliography, key::String)
|
|
copy = Dict(bibliography)
|
|
p = Base.pop!(copy, key) # FIXME: remove this Base.
|
|
empty!(bibliography)
|
|
foreach(k -> bibliography[k] = copy[k], keys(copy))
|
|
# Behaves like a real `pop`, returning the popped key value
|
|
p
|
|
end
|
|
|
|
# FIXME: find files?
|
|
"""Add all entries in a bibtex string to the current bibliography"""
|
|
function addbibtex!(bibliography, bibstring)
|
|
bibs = Bibliography(bibstring)
|
|
foreach(bib -> addtobibliography!(bibliography, createcitekey(bibs[bib]), bibs[bib]),
|
|
keys(bibs))
|
|
"ok"
|
|
end
|
|
|
|
function splitauthors(bib::Citation)
|
|
authors = split(bib["author"], " and ")
|
|
map(a -> (split(strip(a, ['}', '{']), ", ")),
|
|
authors)
|
|
end
|
|
|
|
"""Create the cite key given a bibtex object"""
|
|
function createcitekey(bib::Citation)
|
|
authors = splitauthors(bib)
|
|
firstauthor = length(authors) > 0 ? authors[1][1] : "Unnamed"
|
|
title = split(get(bib, "title", "Untitled"), " ")[1]
|
|
year = match(r"([0-9]{4})", get(bib, "year", get(bib, "date", "0000")))[1]
|
|
|
|
string(firstauthor, "_", title, "_", year) |> lowercase
|
|
end
|
|
|
|
"""Generates a new id, with the same key, but with a number at the end
|
|
(id-\$number) so that it is unique in the library. Fallback for
|
|
duplicates. """
|
|
function nextidnumber(bibliography::Bibliography,id::String)
|
|
num = 0
|
|
while true
|
|
nid = string(id, "-", num)
|
|
nid in keys(bibliography) || break
|
|
num += 1
|
|
end
|
|
nid
|
|
end
|
|
|
|
# """
|
|
# Apply some cleaning to the bibtex citation, namely fixing the key id.
|
|
|
|
# Useful when adding a bibtex directly to verify that it conforms to our "standard"
|
|
# """
|
|
# function cleancitation(cit)
|
|
|
|
# end
|