I've put together a webpage for my research group using quarto - we have a page listing the lab's publications
I've adapted a .csl file to fit most of my formatting needs (eg. listing chronologically instead of alphabetically), but I'm stuck on one last thing. We want to format authors from our lab in bold - while leaving external collaborators in normal font-weight. Its easy enough to set all authors to render in bold, but from what I can gather there isn't a way to define a list of specific strings that should be formatted in bold?
I've found some documentation that suggests using rich text in my .bib file. However, I'm finding that if I put something like this in the .bib file:
author = <b>Skeeter</b>
When I run quarto render
the formatting is output in the .html file as:
<b>Skeeter</b>
so it shows up literally as <b>Skeeter</b>
in the document rather than Skeeter.
My question is whether anyone is aware of a work around that I could employ to achieve this goal? Is there a way to have quarto format specific text values in bold or a way to have a simple script run every time quarto render
is called to format things after the fact? Ideally I'd like to render the publications.qmd file to both .html and .pdf formats - so running a completely separate script after rendering is complete to edit docs/Publications.html would only solve half the problem - the .pdf would still be rendered without the bold formatting.
edit: As mentioned in an answer below - \textbf{Skeeter}
would be more appropriate for a .bib file. And this does work for formatting words in titles - but unfortunately does not work for authors because of the way they are parsed, sorted, etc. I also tried a csl json format instead, but same issue - adding <b>Skeeter</b>
does not result in Skeeter
The Solution: @shafee provided a great solution below that works like a charm. Create a bold-author.lua filter, save it it the main directory, and specify the author names you want to bold in the YAML header, eg.
filters:
- section-bibliographies
- bold-author.lua
bold-auth-name:
- family: Knox
given: S. H.
- family: Skeeter
given: J.
One minor quirk however - it skipped over authors with two given names, ie. a first & middle initial for authors with two given names, so
Skeeter, J., & Knox, S. H. (2023, April). Ongoing and Proposed Research in the Burns Bog Ecological Conservancy Area.
Changing to:
bold-auth-name:
- family: Knox
given: S.
would give: Skeeter, J., & Knox, S. H. (2023, April). Ongoing and Proposed Research in the Burns Bog Ecological Conservancy Area.
So I updated the provided lua filter slightly to:
str = pandoc.utils.stringify
local function highlight_author_filter(auths)
return {
Para = function(el)
if el.t == "Para" then
for k,_ in ipairs(el.content) do
for key, val in ipairs(auths) do
local first_part = val.family .. ","
local full = val.family .. ", " .. val.given
given_initials = {}
for w in val.given:gmatch("%S+") do
table.insert(given_initials,w)
end
if #given_initials == 1 then
if el.content[k].t == "Str" and el.content[k].text == first_part
and el.content[k+1].t == "Space" and el.content[k+2].t == "Str"
and el.content[k+2].text:find(given_initials[1]) then
local _,e = el.content[k+2].text:find(given_initials[1])
local rest = el.content[k+2].text:sub(e+1)
el.content[k] = pandoc.Strong { pandoc.Str(full) }
el.content[k+1] = pandoc.Str(rest)
table.remove(el.content, k+2)
end
elseif #given_initials == 2 and #el.content >= k+4 and el.content[k+4].text ~= nil then
if el.content[k].t == "Str" and el.content[k].text == first_part
and el.content[k+1].t == "Space" and el.content[k+2].t == "Str"
and el.content[k+2].text:find(given_initials[1])
and el.content[k+4].text:find(given_initials[2]) then
local _,e = el.content[k+4].text:find(given_initials[2])
local rest = el.content[k+4].text:sub(e+1)
el.content[k] = pandoc.Strong { pandoc.Str(full) }
el.content[k+1] = pandoc.Str(rest)
table.remove(el.content, k+4)
table.remove(el.content, k+3)
table.remove(el.content, k+2)
end
end
end
end
end
return el
end
}
end
local function get_auth_name(auths)
return {
Meta = function(m)
for key, val in ipairs(m['bold-auth-name']) do
local auth = {
["family"] = str(val.family),
["given"] = str(val.given)
}
table.insert(auths, auth)
end
end
}
end
local function highlight_author_name(auths)
return {
Div = function(el)
if el.classes:includes("references") then
return el:walk(highlight_author_filter(auths))
end
return nil
end
}
end
function Pandoc(doc)
local bold_auth_name = {}
doc:walk(get_auth_name(bold_auth_name))
return doc:walk(highlight_author_name(bold_auth_name))
end
Probably a more elegant way to do it, but I'm not super familiar w/ Lua. Just providing here for anyone who needs it. Again all credit to @shafee :D