Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BibTeX types/tags are case-insensitive, etc #1478

Merged
merged 4 commits into from
Jul 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions packages/bibtex/bibliography.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ end

local function split(str, pat, find) --- return list of substrings separated by pat
find = find or string.find -- could be find_outside_braces
-- @Omikhelia: I added this check here to avoid breaking on error,
-- but probably in could have been done earlier...
if not str then return {} end

local len = string.len(str)
local t = { }
local insert = table.insert
Expand Down Expand Up @@ -285,9 +289,9 @@ Bibliography = {
if not item then
return Bibliography.Errors.UNKNOWN_REFERENCE
end
item.type = (item.type:gsub("^%l", string.upper))
item.type = item.type:gsub("^%l", string.upper)
if not style[item.type] then
return Bibliography.Errors.UNKNOWN_TYPE
return Bibliography.Errors.UNKNOWN_TYPE, item.type
end

local t = Bibliography.buildEnv(cite, item.attributes, style)
Expand All @@ -299,7 +303,10 @@ Bibliography = {
local t = pl.tablex.copy(getfenv and getfenv(1) or _ENV)
t.cite = cite
t.item = item
for k,v in pairs(item) do t[k:lower()] = v end
for k,v in pairs(item) do
if k:lower() == "type" then k = "bibtype" end -- HACK: don't override the type() function
t[k:lower()] = v
end
return pl.tablex.update(t, style)
end,

Expand All @@ -319,11 +326,12 @@ Bibliography = {

Errors = {
UNKNOWN_REFERENCE = 1,
UNKNOWN_TYPE = 2,
},

Style = {
andAuthors = function(item)
local authors = namesplit(item.Author)
local authors = namesplit(item.author)
if #authors == 1 then
return parse_name(authors[1]).ll
else
Expand All @@ -337,23 +345,29 @@ Bibliography = {

andSurnames = function (max)
return function(item)
local authors = namesplit(item.Author)
local authors = namesplit(item.author)
if #authors > max then
return parse_name(authors[1]).ll .. SILE.fluent:get_message("bibliography-et-al")
return parse_name(authors[1]).ll .. " "..SILE.fluent:get_message("bibliography-et-al")
else
for i = 1,#authors do authors[i] = parse_name(authors[i]).ll end
return Bibliography.Style.commafy(authors)
end
end
end,

pageRange = function(item)
if item.pages then
return item.pages:gsub("%-%-", "–")
end
end,

transEditor = function(item)
local r = {}
if item.Editor then
r[#r+1] = SILE.fluent:get_message("bibliography-edited-by")({ name = item.Editor })
if item.editor then
r[#r+1] = SILE.fluent:get_message("bibliography-edited-by")({ name = item.editor })
end
if item.Translator then
r[#r+1] = SILE.fluent:get_message("bibliography-translated-by")({ name = item.Translator })
if item.translator then
r[#r+1] = SILE.fluent:get_message("bibliography-translated-by")({ name = item.translator })
end
if #r then return table.concat(r, ", ") end
return nil
Expand Down
23 changes: 16 additions & 7 deletions packages/bibtex/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,21 @@ local bibtexparser = epnf.define(function (_ENV)
local _ = WS^0
local sep = lpeg.S(",;") * _
local myID = C(identifier + lpeg.P(1)) / function (t) return t end
local myTag = C(identifier + lpeg.P(1)) / function (t) return t:lower() end
local value = balanced + doubleq + myID
local pair = lpeg.Cg(myID * _ * "=" * _ * C(value)) * _ * sep^-1 / function (...) local t= {...}; return t[1], t[#t] end
local pair = lpeg.Cg(myTag * _ * "=" * _ * C(value)) * _ * sep^-1 / function (...) local t= {...}; return t[1], t[#t] end
local list = lpeg.Cf(lpeg.Ct("") * pair^0, rawset)
local commentKey = lpeg.Cmt(R("az", "AZ")^1, function(_, _, a)
return a:lower() == "comment"
end)

START "document"
document = (V"entry" + V"comment")^1 * (-1 + E("Unexpected character at end of input"))
document = (V"comment" + V"entry")^1 -- order important: @comment must have precedence over @other
* (-1 + E("Unexpected character at end of input"))
comment = WS +
( V"blockcomment" + (P("%") * (1-lpeg.S("\r\n"))^0 * lpeg.S("\r\n")) /function () return "" end) -- Don't bother telling me about comments
blockcomment = P("@comment")+ balanced/function () return "" end -- Don't bother telling me about comments
entry = Ct( P("@") * Cg(myID, "type") * _ * P("{") * _ * Cg(myID, "label") * _ * sep * list * P("}") * _ )
blockcomment = (P("@") * commentKey) + balanced/function () return "" end -- Don't bother telling me about comments
entry = Ct( P("@") * Cg(myTag, "type") * _ * P("{") * _ * Cg(myID, "label") * _ * sep * list * P("}") * _ )
end)
-- luacheck: pop

Expand Down Expand Up @@ -76,7 +81,7 @@ local function registerCommands (_)
local bibstyle = require("packages.bibtex.styles." .. style)
local cite = Bibliography.produceCitation(options, SILE.scratch.bibtex.bib, bibstyle)
if cite == Bibliography.Errors.UNKNOWN_REFERENCE then
SU.warn("Unknown reference in citation "..options)
SU.warn("Unknown reference in citation "..options.key)
return
end
SILE.doTexlike(cite)
Expand All @@ -86,9 +91,13 @@ local function registerCommands (_)
if not options.key then options.key = content[1] end
local style = SILE.settings:get("bibtex.style")
local bibstyle = require("packages.bibtex.styles." .. style)
local cite = Bibliography.produceReference(options, SILE.scratch.bibtex.bib, bibstyle)
local cite, err = Bibliography.produceReference(options, SILE.scratch.bibtex.bib, bibstyle)
if cite == Bibliography.Errors.UNKNOWN_REFERENCE then
SU.warn("Unknown reference in citation "..options)
SU.warn("Unknown reference in citation "..options.key)
return
end
if cite == Bibliography.Errors.UNKNOWN_TYPE then
SU.warn("Unknown type @"..err.." in citation for reference "..options.key)
return
end
SILE.doTexlike(cite)
Expand Down
73 changes: 66 additions & 7 deletions packages/bibtex/styles/chicago.lua
Original file line number Diff line number Diff line change
@@ -1,18 +1,77 @@
local Bibliography = require("packages.bibtex.bibliography")

return pl.tablex.merge(Bibliography.Style, {
local ChicagoStyles = pl.tablex.merge(Bibliography.Style, {
CitationStyle = Bibliography.CitationStyles.AuthorYear,

-- luacheck: push ignore
Article = function(_ENV)
-- Chicago Citation Style 17th Edition
-- https://guides.rdpolytech.ca/chicago/citation/article
-- General format = Author Surname, First Name. "Article Title."
-- Journal Title Volume, no. Issue (Year): Page range of article.
-- DOI OR URL of journal article web page OR Name of database.
-- Magazine = Author Surname, First Name. "Article Title." Magazine Title, Month Day, Year. URL.
-- Newspaper = Author Surname, First Name. "Article Title." Newspaper Title, Month Day, Year.
-- So we try to match the closest format.
if number or volume then
-- General format
return andAuthors, ". ", quotes(title, "."), " ", italic(journal),
optional(" ", volume), optional(" no. ", number), optional(" ", parens(optional(month, " "), year)),
optional(": ", pageRange), ".",
optional(" ", doi, "."), optional(" ", url, ".")
end
-- Magazine or newspaper format
return andAuthors, ". ", quotes(title, "."), " ", italic(journal),
optional(", ", month), optional(", ", year ),
optional(": ", pageRange), ".",
optional(" ", doi, "."), optional(" ", url, ".")
end,

Book = function(_ENV)
return andAuthors, " ", year, ". ", italic(title), ". ",
-- Chicago Citation Style 17th Edition
-- https://guides.rdpolytech.ca/chicago/citation/book
-- Simple: Author Surname, First Name or Initial. Book Title: Subtitle. Place of Publication: Publisher, Year.
-- With chapter: Author Surname, First Name or Initial. "Chapter Title in Quotation Marks." In Book Title: Subtitle,
-- edited by Editor First Name Surname, page range of chapter. Place of Publication: Publisher, Year.
-- Dictionary etc.: Author Surname, First Name. "Title of Entry." In Title of Reference Book,
-- edited by Editor First Name Surname. Publisher, Year. URL.
-- Likewise, we try to match the colsets format...
local pub = publisher or institution or organization or howpublished
if booktitle then
return optional(andAuthors, ", "), quotes(title, "."), " ",
optional("In ", italic(booktitle), ". "),
optional(transEditor, ". "),
optional(address, ": "), optional(pub, year and ", " or ". "), optional(year, ". "),
optional(number, ". "), optional(doi, ". "), optional(url, ".")
end
return optional(andAuthors, ", "), italic(title), ". ",
optional(transEditor, ". "),
address, ": ", publisher, "."
optional(address, ": "), optional(pub, year and ", " or ". "), optional(year, ". "),
optional(number, ". "), optional(doi, ". "), optional(url, ". ")
end,

Article = function(_ENV)
return andAuthors, ". ", year, ". ", quotes(title, "."), " ", italic(journal), " ",
parens(volume), number, optional(":", pages)
end
Thesis = function(_ENV)
local pub = publisher or institution or organization or howpublished or school
return optional(andSurnames(3), ", "), quotes(title, "."), " ",
optional(transEditor, ". "),
optional(bibtype, ". "), -- "type" from BibTeX entry
optional(address, ": "), optional(pub, ", "), optional(year, ".")
end,
-- luacheck: pop
}, true)

return pl.tablex.merge(ChicagoStyles, {
-- Add fallback mappings for usual BibTeX keys not defined above.
Booklet = ChicagoStyles.Book,
Conference = ChicagoStyles.Book,
Inbook = ChicagoStyles.Book,
Incollection = ChicagoStyles.Book,
Inproceedings = ChicagoStyles.Book,
Manual = ChicagoStyles.Book,
Misc = ChicagoStyles.Book, -- NOTE: So we assume at least a title...
Proceedings = ChicagoStyles.Book,
Techreport = ChicagoStyles.Book,
Phdthesis = ChicagoStyles.Thesis,
Mastersthesis = ChicagoStyles.Thesis,
Unpublished = ChicagoStyles.Book,
}, true)
Loading