diff --git a/src/Bibliography.jl b/src/Bibliography.jl index 6a6d100..fcf4acd 100644 --- a/src/Bibliography.jl +++ b/src/Bibliography.jl @@ -23,12 +23,10 @@ include("csl.jl") include("staticweb.jl") """ - export_bibtex(e::Entry) - export_bibtex(bibliography::DataStructures.OrderedDict{String,Entry}) - export_bibtex(target::String, bibliography::DataStructures.OrderedDict{String,Entry}) -Export an entry or a bibliography to BibTeX format. + export_bibtex(target, bibliography) +Export a bibliography to BibTeX format. """ -function export_bibtex(target::String, bibliography::DataStructures.OrderedDict{String,Entry}) +function export_bibtex(target, bibliography) data = export_bibtex(bibliography) if target != "" f = open(target, "w") @@ -42,8 +40,6 @@ end bibtex_to_web(source::String) Convert a BibTeX file to a web compatible format, specifically for the [StaticWebPages.jl](https://github.com/Azzaare/StaticWebPages.jl) package. """ -function bibtex_to_web(source::String) - export_web(import_bibtex(source)) -end +bibtex_to_web(source) = export_web(import_bibtex(source)) end # module diff --git a/src/bibtex.jl b/src/bibtex.jl index 5bb200b..ada3648 100644 --- a/src/bibtex.jl +++ b/src/bibtex.jl @@ -1,37 +1,41 @@ """ - import_bibtex(file::String) -Import a BibTeX file and convert it to the internal bibliography format. + import_bibtex(input) +Import a BibTeX file or parse a BibTeX string and convert it to the internal bibliography format. """ -function import_bibtex(file::String) - return BibParser.parse_file(file) +function import_bibtex(input) + return isfile(input) ? BibParser.parse_file(input) : BibParser.parse_entry(input) end -function int_to_spaces(n::Int) - str = "" - for i in 1:n - str *= " " - end - return str -end +""" + int_to_spaces(n) + +Make a string of `n` spaces. +""" +int_to_spaces(n) = repeat(" ", n) -# Dictionnary to handle spaces while exporting BibTeX const spaces = Dict{String,String}(map( s -> (string(s) => int_to_spaces(BibInternal.space(s))), BibInternal.fields) ) -# Function to write required fields -function field_to_bibtex( - key::String, - value::String - ) +""" + field_to_bibtex(key, value) + +Convert an entry field to BibTeX format. +""" +function field_to_bibtex(key, value) space = get(spaces, key, int_to_spaces(BibInternal.space(Symbol(key)))) swp = length(key) > 3 && key[1:3] == "swp" o,f = isnothing(match(r"@", value)) ? ('{','}') : ('"','"') return value == "" || swp ? "" : " $key$space = $o$value$f,\n" end -function name_to_string(name::BibInternal.Name) +""" + name_to_string(name::BibInternal.Name) + +Convert a name in an `Entry` to a string. +""" +function name_to_string(name) str = "$(name.particle)" if str != "" != name.last str *= " " @@ -47,7 +51,12 @@ function name_to_string(name::BibInternal.Name) return str end -function names_to_strings(names::BibInternal.Names) +""" + names_to_strings(names) + +Convert a collection of names to a BibTeX string. +""" +function names_to_strings(names) if length(names) ≥ 1 str = name_to_string(names[1]) end @@ -59,51 +68,64 @@ function names_to_strings(names::BibInternal.Names) return str end -function access_to_bibtex!( - fields::BibInternal.Fields, - a::BibInternal.Access - ) +""" + access_to_bibtex!(fields, a) + +Transform the how-to-`access` field to a BibTeX string. +""" +function access_to_bibtex!(fields, a) fields["doi"] = a.doi fields["howpublished"] = a.howpublished fields["url"] = a.url end -function date_to_bibtex!( - fields::BibInternal.Fields, - d::BibInternal.Date - ) - fields["day"] = d.day - fields["month"] = d.month - fields["year"] = d.year +""" + date_to_bibtex!(fields, date) + +Convert a date to a BibTeX string. +""" +function date_to_bibtex!(fields, date) + fields["day"] = date.day + fields["month"] = date.month + fields["year"] = date.year end -function eprint_to_bibtex!( - fields::BibInternal.Fields, - e::BibInternal.Eprint - ) - fields["archivePrefix"] = e.archive_prefix - fields["eprint"] = e.eprint - fields["primaryClass"] = e.primary_class +""" + eprint_to_bibtex!(fields, eprint) + +Convert eprint information to a BibTeX string. +""" +function eprint_to_bibtex!(fields, ep) + fields["archivePrefix"] = ep.archive_prefix + fields["eprint"] = ep.eprint + fields["primaryClass"] = ep.primary_class end -function in_to_bibtex!( - fields::BibInternal.Fields, - i::BibInternal.In - ) - fields["address"] = i.address - fields["chapter"] = i.chapter - fields["edition"] = i.edition - fields["institution"] = i.institution - fields["journal"] = i.journal - fields["number"] = i.number - fields["organization"] = i.organization - fields["pages"] = i.pages - fields["publisher"] = i.publisher - fields["school"] = i.school - fields["series"] = i.series - fields["volume"] = i.volume +""" + in_to_bibtex!(fields::BibInternal.Fields, i::BibInternal.In) + +Convert the "published `in`" information to a BibTeX string. +""" +function in_to_bibtex!(fields, in_) + fields["address"] = in_.address + fields["chapter"] = in_.chapter + fields["edition"] = in_.edition + fields["institution"] = in_.institution + fields["journal"] = in_.journal + fields["number"] = in_.number + fields["organization"] = in_.organization + fields["pages"] = in_.pages + fields["publisher"] = in_.publisher + fields["school"] = in_.school + fields["series"] = in_.series + fields["volume"] = in_.volume end +""" + export_bibtex(e::Entry) + +Export an `Entry` to a BibTeX string. +""" function export_bibtex(e::Entry) access_to_bibtex!(e.fields, e.access) e.fields["author"] = names_to_strings(e.authors) @@ -124,10 +146,14 @@ function export_bibtex(e::Entry) return str[1:end - 2] * "\n}" end -function export_bibtex(bibliography::DataStructures.OrderedDict{String,Entry}) +""" + export_bibtex(bibliography) + +Export a bibliography to a BibTeX string. +""" +function export_bibtex(bibliography) str = "" for e in values(bibliography) - # @info "Test for eprint" e str *= export_bibtex(e) * "\n\n" end return str[1:end - 1] diff --git a/src/staticweb.jl b/src/staticweb.jl index 325cbe9..0126415 100644 --- a/src/staticweb.jl +++ b/src/staticweb.jl @@ -15,14 +15,29 @@ const type_to_label = Dict{String, String}([ "unpublished" => "other" ]) -function xtitle(entry::T) where T <: BibInternal.Entry +""" + xtitle(entry + +Format the title of an `Entry` for web export. +""" +function xtitle(entry) return :title ∈ fieldnames(typeof(entry)) ? entry.title : get(entry.fields, "title", "") end +""" + xnames(entry, editors = false; names = :full) + +Format the name of an `Entry` for web export. + +# Arguments: +- `entry`: an entry +- `editors`: `true` if the name describes editors +- `names`: :full (full names) or :last (last names + first name abbreviation) +""" function xnames( - entry::BibInternal.Entry, - editors::Bool=false; - names::Symbol=:full # Current options: :last, :full + entry, + editors=false; + names=:full # Current options: :last, :full ) # forces the names to be editors' name if the entry are Proceedings if !editors && entry.type ∈ ["proceedings"] @@ -41,12 +56,15 @@ function xnames( str *= s.first * " " * s.middle * " " * s.particle * " " * s.last * " " * s.junior end end - # str *= editors ? ", editors" : "" return replace(str, r"[\n\r ]+" => " ") # TODO: make it cleaner (is replace still necessary) end -function xin(entry::BibInternal.Entry) - # @info "Entry type" entry entry.type +""" + xin(entry) + +Format the appears-`in` field of an `Entry` for web export. +""" +function xin(entry) str = "" if entry.type == "article" str *= entry.in.journal * ", " * entry.in.volume @@ -115,11 +133,19 @@ function xin(entry::BibInternal.Entry) return str end -function xyear(entry::BibInternal.Entry) - return entry.date.year -end +""" + xyear(entry) + +Format the year of an `Entry` for web export. +""" +xyear(entry) = entry.date.year -function xlink(entry::BibInternal.Entry) +""" + xlink(entry) + +Format the download link of an `Entry` for web export. +""" +function xlink(entry) if entry.access.doi != "" return "https://doi.org/" * entry.access.doi elseif entry.access.url != "" @@ -128,20 +154,36 @@ function xlink(entry::BibInternal.Entry) return "" end -function xfile(entry::BibInternal.Entry) - return "files/$(entry.id).pdf" -end +""" + xfile(entry) -function xcite(entry::BibInternal.Entry) - string(entry) -end +Format the downloadable path of an `Entry` file for web export. +""" +xfile(entry) = "files/$(entry.id).pdf" + +""" + xcite(entry) + +Format the BibTeX cite output of an `Entry` for web export. +""" +xcite(entry) = string(entry) + +""" + xlabels(entry) -function xlabels(entry::BibInternal.Entry) +Format the labels of an `Entry` for web export. +""" +function xlabels(entry) str = get(entry.fields, "swp-labels", "") str = str == "" ? get(entry.fields, "labels", "") : str return str == "" ? [entry.type] : split(str, r"[\n\r ]*,[\n\r ]*") end +""" + Publication + +A structure to store all the information necessary to web export. +""" struct Publication id::String type::String @@ -155,8 +197,12 @@ struct Publication labels::Vector{String} end -function Publication(entry::BibInternal.Entry) - # @info "New Publication for StaticWebPages" entry +""" + Publication(entry) + +Construct a `Publication` (compatible with web export) from an `Entry`. +""" +function Publication(entry) id = entry.id type = entry.type title = entry.title @@ -172,12 +218,9 @@ end """ export_web(bibliography::DataStructures.OrderedDict{String,BibInternal.Entry}) -Export a biblography in internal format to the web format of the [StaticWebPages.jl](https://github.com/Azzaare/StaticWebPages.jl) pakcage. +Export a biblography in internal format to the web format of the [StaticWebPages.jl](https://github.com/Humans-of-Julia/StaticWebPages.jl) pakcage. Also used by [DocumenterCitations.jl](https://github.com/ali-ramadhan/DocumenterCitations.jl). """ -function export_web( - bibliography::DataStructures.OrderedDict{String,BibInternal.Entry} - ) - # @show values(bibliography) +function export_web(bibliography) entries = Vector{Publication}() for entry in values(bibliography) p = Publication(entry) diff --git a/test/runtests.jl b/test/runtests.jl index 423b639..836694f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -28,6 +28,7 @@ testdata = """@inproceedings{demo2020proceedings, }""" write("demo.bib",testdata) +Bibliography.import_bibtex(testdata) mybib = Bibliography.import_bibtex("demo.bib") Bibliography.export_bibtex("demo_export.bib",mybib) mybib2 = Bibliography.import_bibtex("demo_export.bib")