diff --git a/news/changelog-1.8.md b/news/changelog-1.8.md
index b1771ca5f53..7007254d3cf 100644
--- a/news/changelog-1.8.md
+++ b/news/changelog-1.8.md
@@ -4,6 +4,7 @@
- ([#13046](https://github.com/quarto-dev/quarto-cli/issues/13046)): Use new url for multiplex socket.io server as default for `format: revealjs` and `revealjs.multiplex: true`.
- ([#13506](https://github.com/quarto-dev/quarto-cli/issues/13506)): Fix navbar active state detection when sidebar has no logo configured. Prevents empty logo links from interfering with navigation highlighting.
+- ([#13633](https://github.com/quarto-dev/quarto-cli/issues/13633)): Fix detection and auto-installation of babel language packages from newer error format that doesn't explicitly mention `.ldf` filename.
## In previous releases
diff --git a/src/command/render/latexmk/parse-error.ts b/src/command/render/latexmk/parse-error.ts
index ca577e1f5ca..77b9772f55e 100644
--- a/src/command/render/latexmk/parse-error.ts
+++ b/src/command/render/latexmk/parse-error.ts
@@ -133,7 +133,7 @@ export function findMissingHyphenationFiles(logText: string) {
const babelWarningRegex = /^Package babel Warning:/m;
const hasWarning = logText.match(babelWarningRegex);
if (hasWarning) {
- const languageRegex = /^\(babel\).* language `(\S+)'.*$/m;
+ const languageRegex = /^\(babel\).* language [`'](\S+)[`'].*$/m;
const languageMatch = logText.match(languageRegex);
if (languageMatch) {
return filterLang(languageMatch[1]);
@@ -271,6 +271,12 @@ const packageMatchers = [
{ regex: /.*! LaTeX Error: File `([^']+)' not found.*/g },
{ regex: /.* file ['`]?([^' ]+)'? not found.*/g },
{ regex: /.*the language definition file ([^\s]*).*/g },
+ {
+ regex: /.*! Package babel Error: Unknown option [`']([^'`]+)'[.].*/g,
+ filter: (match: string, _text: string) => {
+ return `${match}.ldf`;
+ },
+ },
{ regex: /.* \\(file ([^)]+)\\): cannot open .*/g },
{ regex: /.*file `([^']+)' .*is missing.*/g },
{ regex: /.*! CTeX fontset `([^']+)' is unavailable.*/g },
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/print-affiliation.tex b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_affiliation.tex
similarity index 100%
rename from tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/print-affiliation.tex
rename to tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_affiliation.tex
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extension.yml b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extension.yml
index 4b24368a6c8..af9fa584fec 100644
--- a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extension.yml
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extension.yml
@@ -1,7 +1,30 @@
-name: Elsevier Journal Format
+title: ACS Journal Format
+author: Charles Teague
+version: 0.9.2
contributes:
- format:
+ formats:
common:
csl: american-chemical-society.csl
+ shortcodes:
+ - fancy-text
+ filters:
+ - latex-environment
+ environments:
+ - scheme
+ - chart
+ - graph
+ - tocentry
+ - acknowledgement
+ - suppinfo
+ commands:
+ - ce
+ html: default
pdf:
- template-partials: ["doc-class.tex", "title.tex", "print-affiliation.tex"]
+ cite-method: natbib
+ biblio-config: false
+ format-resources:
+ - achemso.bst
+ template-partials:
+ - "doc-class.tex"
+ - "title.tex"
+ - "_affiliation.tex"
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/fancy-text/_extension.yml b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/fancy-text/_extension.yml
new file mode 100644
index 00000000000..813e2387c0f
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/fancy-text/_extension.yml
@@ -0,0 +1,7 @@
+title: Fancy Text
+author: Posit Software, PBC
+version: 1.1.1
+quarto-required: ">=1.2.198"
+contributes:
+ shortcodes:
+ - fancy-text.lua
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/fancy-text/fancy-text.lua b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/fancy-text/fancy-text.lua
new file mode 100644
index 00000000000..0eec7d2dd55
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/fancy-text/fancy-text.lua
@@ -0,0 +1,78 @@
+-- shortcode that provides a nicely formatted 'LaTeX' string
+function latex()
+ if quarto.doc.is_format("pdf") then
+ return pandoc.RawBlock('tex', '{\\LaTeX}')
+ elseif quarto.doc.is_format("html") then
+ return pandoc.Math('InlineMath', "\\LaTeX")
+ else
+ return pandoc.Span('LaTeX')
+ end
+end
+
+function tex()
+ if quarto.doc.is_format("pdf") then
+ return pandoc.RawBlock('tex', '{\\TeX}')
+ elseif quarto.doc.is_format("html") then
+ return pandoc.Math('InlineMath', "\\TeX")
+ else
+ return pandoc.Span('TeX')
+ end
+end
+
+-- shortcode that provides a nicely formatted 'bibtex' string
+function bibtex()
+ if quarto.doc.is_format("pdf") then
+ return pandoc.RawBlock('tex', '\\textsc{Bib}{\\TeX}')
+ elseif quarto.doc.is_format("html") then
+ return pandoc.RawBlock('html', 'BibTEX')
+ else
+ return pandoc.Span('BibTeX')
+ end
+end
+
+function ldots()
+ if quarto.doc.is_format("pdf") then
+ return pandoc.RawBlock('tex', '\\ldots')
+ elseif quarto.doc.is_format("html") then
+ return pandoc.RawBlock('html', '…')
+ else
+ return "..."
+ end
+end
+
+function vdots()
+ if quarto.doc.is_format("pdf") then
+ return pandoc.Math('InlineMath', "\\vdots")
+ elseif quarto.doc.is_format("html") then
+ return pandoc.RawBlock('html', '⋮')
+ else
+ return "..."
+ end
+end
+
+function ddots()
+ if quarto.doc.is_format("pdf") then
+ return pandoc.Math('InlineMath', "\\ddots")
+ elseif quarto.doc.is_format("html") then
+ return pandoc.RawBlock('html', '⋱')
+ else
+ return "..."
+ end
+end
+
+function pct()
+ local pct
+ if quarto.doc.is_format("pdf") then
+ return pandoc.Math('InlineMath', '\\%')
+ else
+ return pandoc.Str("%")
+ end
+end
+
+function R2()
+ if quarto.doc.is_format("pdf") then
+ return pandoc.Math('InlineMath', "R^2")
+ else
+ return {pandoc.Str("R"), pandoc.Superscript("2")}
+ end
+end
\ No newline at end of file
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/latex-environment/_extension.yml b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/latex-environment/_extension.yml
new file mode 100644
index 00000000000..2f55b2fea6a
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/latex-environment/_extension.yml
@@ -0,0 +1,9 @@
+title: LaTeX Environment
+author: Posit Software, PBC
+version: 1.2.1
+quarto-required: ">=1.3"
+contributes:
+ filters:
+ - latex-environment.lua
+ format:
+ pdf: default
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/latex-environment/latex-environment.lua b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/latex-environment/latex-environment.lua
new file mode 100644
index 00000000000..389a25f4dfa
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/_extensions/quarto-ext/latex-environment/latex-environment.lua
@@ -0,0 +1,150 @@
+-- environment.lua
+-- Copyright (C) 2020 by RStudio, PBC
+
+local classEnvironments = pandoc.MetaMap({})
+local classCommands = pandoc.MetaMap({})
+
+-- helper that identifies arrays
+local function tisarray(t)
+ local i = 0
+ for _ in pairs(t) do
+ i = i + 1
+ if t[i] == nil then return false end
+ end
+ return true
+end
+
+-- reads the environments
+local function readEnvironments(meta)
+ local env = meta['environments']
+ if env ~= nil then
+ if tisarray(env) then
+ -- read an array of strings
+ for i, v in ipairs(env) do
+ local value = pandoc.utils.stringify(v)
+ classEnvironments[value] = value
+ end
+ else
+ -- read key value pairs
+ for k, v in pairs(env) do
+ local key = pandoc.utils.stringify(k)
+ local value = pandoc.utils.stringify(v)
+ classEnvironments[key] = value
+ end
+ end
+ end
+end
+
+local function readCommands(meta)
+ local env = meta['commands']
+ if env ~= nil then
+ if tisarray(env) then
+ -- read an array of strings
+ for i, v in ipairs(env) do
+ local value = pandoc.utils.stringify(v)
+ classCommands[value] = value
+ end
+ else
+ -- read key value pairs
+ for k, v in pairs(env) do
+ local key = pandoc.utils.stringify(k)
+ local value = pandoc.utils.stringify(v)
+ classCommands[key] = value
+ end
+ end
+ end
+end
+
+local function readEnvsAndCommands(meta)
+ readEnvironments(meta)
+ readCommands(meta)
+end
+
+-- use the environments from metadata to
+-- emit a custom environment for latex
+local function writeEnvironments(divEl)
+ if quarto.doc.is_format("latex") then
+ for k, v in pairs(classEnvironments) do
+ if divEl.attr.classes:includes(k) then
+ -- process this into a latex environment
+ local beginEnv = '\\begin' .. '{' .. v .. '}'
+ local endEnv = '\n\\end{' .. v .. '}'
+
+ -- check if custom options or arguments are present
+ -- and add them to the environment accordingly
+ local opts = divEl.attr.attributes['options']
+ if opts then
+ beginEnv = beginEnv .. '[' .. opts .. ']'
+ end
+
+ local args = divEl.attr.attributes['arguments']
+ if args then
+ beginEnv = beginEnv .. '{' .. args .. '}'
+ end
+
+ -- if the first and last div blocks are paragraphs then we can
+ -- bring the environment begin/end closer to the content
+ if #divEl.content > 0 and divEl.content[1].t == "Para" and divEl.content[#divEl.content].t == "Para" then
+ table.insert(divEl.content[1].content, 1, pandoc.RawInline('tex', beginEnv .. "\n"))
+ table.insert(divEl.content[#divEl.content].content, pandoc.RawInline('tex', "\n" .. endEnv))
+ else
+ table.insert(divEl.content, 1, pandoc.RawBlock('tex', beginEnv))
+ table.insert(divEl.content, pandoc.RawBlock('tex', endEnv))
+ end
+ return divEl
+ end
+ end
+ end
+end
+
+local function buildCommandArgs(opts, format)
+ local function wrap(o)
+ return string.format(format, o)
+ end
+ local t = pandoc.List()
+ for str in string.gmatch(opts, "([^"..",".."]+)") do
+ t:insert(str)
+ end
+ return table.concat(t:map(wrap), "")
+end
+
+-- use the environments from metadata to
+-- emit a custom environment for latex
+local function writeCommands(spanEl)
+ if quarto.doc.is_format("latex") then
+ for k, v in pairs(classCommands) do
+ if spanEl.attr.classes:includes(k) then
+
+ -- resolve the begin command
+ local beginCommand = '\\' .. pandoc.utils.stringify(v)
+ local opts = spanEl.attr.attributes['options']
+ local args = spanEl.attr.attributes['arguments']
+ if opts then
+ beginCommand = beginCommand .. buildCommandArgs(opts, "[%s]")
+ end
+ if args then
+ beginCommand = beginCommand .. buildCommandArgs(args, "{%s}")
+ end
+
+ local beginCommandRaw = pandoc.RawInline('latex', beginCommand .. '{')
+
+ -- the end command
+ local endCommandRaw = pandoc.RawInline('latex', '}')
+
+ -- attach the raw inlines to the span contents
+ local result = spanEl.content
+ table.insert(result, 1, beginCommandRaw)
+ table.insert(result, endCommandRaw)
+
+ return result
+ end
+ end
+ end
+end
+
+-- Run in two passes so we process metadata
+-- and then process the divs
+return {
+ { Meta = readEnvsAndCommands },
+ { Div = writeEnvironments, Span = writeCommands }
+}
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/achemso.bst b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/achemso.bst
new file mode 100644
index 00000000000..3713b0c3581
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/achemso.bst
@@ -0,0 +1,1745 @@
+%%
+%% This is file `achemso.bst',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% achemso.dtx (with options: `bst')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from achemso.bst.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file achemso.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+
+ENTRY
+ {
+ address
+ author
+ booktitle
+ chapter
+ ctrl-article-title
+ ctrl-chapter-title
+ ctrl-doi
+ ctrl-etal-firstonly
+ ctrl-etal-number
+ ctrl-use-title
+ doi
+ edition
+ editor
+ howpublished
+ institution
+ journal
+ key
+ maintitle
+ note
+ number
+ organization
+ pages
+ publisher
+ school
+ series
+ title
+ type
+ url
+ version
+ volume
+ year
+ }
+ { }
+ {
+ label
+ short.names
+ }
+
+
+FUNCTION { and } {
+ { }
+ {
+ pop$
+ #0
+ }
+ if$
+}
+
+FUNCTION { not } {
+ { #0 }
+ { #1 }
+ if$
+}
+
+FUNCTION { or } {
+ {
+ pop$
+ #1
+ }
+ { }
+ if$
+}
+
+FUNCTION { xor } {
+ { not }
+ { }
+ if$
+}
+
+
+FUNCTION { chr.to.value.error } {
+ #48 +
+ int.to.chr$
+ "'" swap$ *
+ "'" *
+ " is not a number: treated as zero." *
+ warning$
+ #0
+}
+
+FUNCTION { chr.to.value } {
+ chr.to.int$ #48 -
+ duplicate$
+ #0 <
+ { chr.to.value.error }
+ {
+ duplicate$
+ #9 >
+ { chr.to.value.error }
+ { }
+ if$
+ }
+ if$
+}
+
+STRINGS {
+ extract.input.str
+ extract.output.str
+}
+
+FUNCTION { is.a.digit } {
+ duplicate$
+ "" =
+ {
+ pop$
+ #0
+ }
+ {
+ chr.to.int$
+ #48 -
+ duplicate$
+ #0 < swap$ #9 > or not
+ }
+ if$
+}
+
+FUNCTION{ is.a.number } {
+ {
+ duplicate$
+ #1 #1 substring$
+ is.a.digit
+ }
+ { #2 global.max$ substring$ }
+ while$
+ "" =
+}
+
+FUNCTION { extract.number } {
+ duplicate$
+ 'extract.input.str :=
+ "" 'extract.output.str :=
+ { extract.input.str empty$ not }
+ {
+ extract.input.str #1 #1 substring$
+ extract.input.str #2 global.max$ substring$ 'extract.input.str :=
+ duplicate$
+ is.a.number
+ { extract.output.str swap$ * 'extract.output.str := }
+ {
+ pop$
+ "" 'extract.input.str :=
+ }
+ if$
+ }
+ while$
+ extract.output.str empty$
+ { }
+ {
+ pop$
+ extract.output.str
+ }
+ if$
+}
+
+FUNCTION { field.or.null } {
+ duplicate$
+ empty$
+ {
+ pop$
+ ""
+ }
+ { }
+ if$
+}
+
+INTEGERS {
+ multiply.a.int
+ multiply.b.int
+}
+
+FUNCTION { multiply } {
+ 'multiply.a.int :=
+ 'multiply.b.int :=
+ multiply.b.int #0 <
+ {
+ #-1
+ #0 multiply.b.int - 'multiply.b.int :=
+ }
+ { #1 }
+ if$
+ #0
+ { multiply.b.int #0 > }
+ {
+ multiply.a.int +
+ multiply.b.int #1 - 'multiply.b.int :=
+ }
+ while$
+ swap$
+ { }
+ { #0 swap$ - }
+ if$
+}
+
+INTEGERS { str.conversion.int }
+
+FUNCTION { str.to.int.aux.ii } {
+ {
+ duplicate$
+ empty$ not
+ }
+ {
+ swap$
+ #10 multiply 'str.conversion.int :=
+ duplicate$
+ #1 #1 substring$
+ chr.to.value
+ str.conversion.int +
+ swap$
+ #2 global.max$ substring$
+ }
+ while$
+ pop$
+}
+
+FUNCTION { str.to.int.aux.i } {
+ duplicate$
+ #1 #1 substring$
+ "-" =
+ {
+ #1 swap$
+ #2 global.max$ substring$
+ }
+ {
+ #0 swap$
+ }
+ if$
+ #0
+ swap$
+ str.to.int.aux.ii
+ swap$
+ { #0 swap$ - }
+ { }
+ if$
+}
+
+FUNCTION { str.to.int } {
+ duplicate$
+ empty$
+ {
+ pop$
+ #0
+ }
+ { str.to.int.aux.i }
+ if$
+}
+
+FUNCTION { tie.or.space.connect } {
+ duplicate$
+ text.length$ #3 <
+ { "~" }
+ { " " }
+ if$
+ swap$ * *
+}
+
+FUNCTION { yes.no.to.bool } {
+ duplicate$
+ empty$
+ {
+ pop$
+ #0
+ }
+ {
+ "l" change.case$
+ "yes" =
+ { #1 }
+ { #0 }
+ if$
+ }
+ if$
+}
+
+
+FUNCTION { bold } {
+ duplicate$
+ empty$
+ {
+ pop$
+ ""
+ }
+ { "\textbf{" swap$ * "}" * }
+ if$
+}
+
+FUNCTION { emph } {
+ duplicate$
+ empty$
+ {
+ pop$
+ ""
+ }
+ { "\emph{" swap$ * "}" * }
+ if$
+}
+
+FUNCTION { paren } {
+ duplicate$
+ empty$
+ {
+ pop$
+ ""
+ }
+ { "(" swap$ * ")" * }
+ if$
+}
+
+
+FUNCTION { add.comma } { ", " * }
+
+FUNCTION { add.colon } { ": " * }
+
+FUNCTION { add.period } { add.period$ " " * }
+
+FUNCTION { add.semicolon } { "; " * }
+
+FUNCTION { add.space } { " " * }
+
+
+FUNCTION { bbl.and } { "and" }
+
+FUNCTION { bbl.chapter } { "Chapter" }
+
+FUNCTION { bbl.doi } { "DOI:" }
+
+FUNCTION { bbl.editor } { "Ed." }
+
+FUNCTION { bbl.editors } { "Eds." }
+
+FUNCTION { bbl.edition } { "ed." }
+
+FUNCTION { bbl.etal } { "\latin{et~al.}" }
+
+FUNCTION { bbl.in } { "In" }
+
+FUNCTION { bbl.inpress } { "in press" }
+
+FUNCTION { bbl.msc } { "M.Sc.\ thesis" }
+
+FUNCTION { bbl.page } { "p" }
+
+FUNCTION { bbl.pages } { "pp" }
+
+FUNCTION { bbl.phd } { "Ph.D.\ thesis" }
+
+FUNCTION { bbl.version } { "version" }
+
+FUNCTION { bbl.volume } { "Vol." }
+
+
+STRINGS { pages.str }
+
+FUNCTION { hyphen.to.dash } {
+ 'pages.str :=
+ ""
+ { pages.str empty$ not }
+ {
+ pages.str #1 #1 substring$
+ "-" =
+ {
+ "--" *
+ {
+ pages.str #1 #1 substring$
+ "-" =
+ }
+ { pages.str #2 global.max$ substring$ 'pages.str := }
+ while$
+ }
+ {
+ pages.str #1 #1 substring$
+ *
+ pages.str #2 global.max$ substring$ 'pages.str :=
+ }
+ if$
+ }
+ while$
+}
+
+INTEGERS { multiresult.bool }
+
+FUNCTION { multi.page.check } {
+ 'pages.str :=
+ #0 'multiresult.bool :=
+ {
+ multiresult.bool not
+ pages.str empty$ not
+ and
+ }
+ {
+ pages.str #1 #1 substring$
+ duplicate$
+ "-" = swap$ duplicate$
+ "," = swap$
+ "+" =
+ or or
+ { #1 'multiresult.bool := }
+ { pages.str #2 global.max$ substring$ 'pages.str := }
+ if$
+ }
+ while$
+ multiresult.bool
+}
+
+
+INTEGERS {
+ current.name.int
+ names.separate.comma
+ names.separate.semicolon
+ names.separate.comma.bool
+ remaining.names.int
+ total.names.int
+}
+
+STRINGS {
+ current.name.str
+ names.str
+}
+
+FUNCTION { full.format.names } {
+ 'names.str :=
+ #1 'current.name.int :=
+ names.str num.names$ 'remaining.names.int :=
+ { remaining.names.int #0 > }
+ {
+ names.str current.name.int "{vv~}{ll}" format.name$
+ current.name.int #1 >
+ {
+ swap$ add.comma swap$
+ remaining.names.int #1 >
+ { }
+ {
+ duplicate$
+ "others" =
+ { bbl.etal }
+ { bbl.and }
+ if$
+ add.space swap$ *
+ }
+ if$
+ *
+ }
+ { }
+ if$
+ remaining.names.int #1 - 'remaining.names.int :=
+ current.name.int #1 + 'current.name.int :=
+ }
+ while$
+}
+
+FUNCTION { full.author } {
+ author empty$
+ { "" }
+ { author full.format.names }
+ if$
+}
+
+FUNCTION { full.author.editor } {
+ author empty$
+ {
+ editor empty$
+ { "" }
+ { editor full.format.names }
+ if$
+ }
+ { author full.format.names }
+ if$
+}
+
+FUNCTION { full.editor } {
+ editor empty$
+ { "" }
+ { editor full.format.names }
+ if$
+}
+
+FUNCTION { short.format.names } {
+ 'names.str :=
+ names.str #1 "{vv~}{ll}" format.name$
+ names.str num.names$
+ duplicate$
+ #2 >
+ {
+ pop$
+ add.space bbl.etal *
+ }
+ {
+ #2 <
+ { }
+ {
+ names.str #2 "{ff }{vv }{ll}{ jj}" format.name$
+ "others" =
+ { add.space bbl.etal * }
+ {
+ add.space
+ bbl.and add.space
+ *
+ names.str #2 "{vv~}{ll}" format.name$
+ *
+ }
+ if$
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION { short.author.key } {
+ author empty$
+ {
+ key empty$
+ { cite$ #1 #3 substring$ }
+ { key }
+ if$
+ }
+ { author short.format.names }
+ if$
+}
+
+FUNCTION { short.author.editor.key } {
+ author empty$
+ {
+ editor empty$
+ {
+ key empty$
+ { cite$ #1 #3 substring$ }
+ { key }
+ if$
+ }
+ { editor short.format.names }
+ if$
+ }
+ { author short.format.names }
+ if$
+}
+
+FUNCTION { short.author.key.organization } {
+ author empty$
+ {
+ key empty$
+ {
+ organization empty$
+ { cite$ #1 #3 substring$ }
+ {
+ organization #1 #4 substring$
+ "The " =
+ { organization }
+ { organization #5 global.max$ substring$ }
+ if$
+ #3 text.prefix$
+ }
+ if$
+ }
+ { key }
+ if$
+ }
+ { author short.format.names }
+ if$
+}
+
+FUNCTION { short.editor.key.organization } {
+ editor empty$
+ {
+ key empty$
+ {
+ organization empty$
+ { cite$ #1 #3 substring$ }
+ {
+ organization #1 #4 substring$
+ "The " =
+ { organization }
+ { organization #5 global.max$ substring$ }
+ if$
+ #3 text.prefix$
+ }
+ if$
+ }
+ { key }
+ if$
+ }
+ { editor short.format.names }
+ if$
+}
+
+FUNCTION { calculate.full.names } {
+ type$ "book" =
+ type$ "inbook" =
+ or
+ { full.author.editor }
+ {
+ type$ "proceedings" =
+ { full.editor }
+ { full.author }
+ if$
+ }
+ if$
+}
+
+FUNCTION { calculate.short.names } {
+ type$ "book" =
+ type$ "inbook" =
+ or
+ { short.author.editor.key }
+ {
+ type$ "proceedings" =
+ { short.editor.key.organization }
+ {
+ type$ "manual" =
+ { short.author.key.organization }
+ { short.author.key }
+ if$
+ }
+ if$
+ }
+ if$
+ 'short.names :=
+}
+
+FUNCTION { calculate.names } {
+ calculate.short.names
+ short.names
+ year empty$
+ { "()" }
+ { "(" year * ")" * }
+ if$
+ *
+ 'label :=
+}
+
+
+INTEGERS { entries.int }
+
+FUNCTION { initialize.count.entries } {
+ #0 'entries.int :=
+}
+
+FUNCTION { count.entries } {
+ entries.int #1 + 'entries.int :=
+}
+
+
+FUNCTION { begin.bib } {
+ "achemso 2022-11-25 v3.13f" top$
+ preamble$ empty$
+ { }
+ {
+ preamble$ write$
+ newline$
+ }
+ if$
+ "\providecommand{\latin}[1]{#1}" write$
+ newline$
+ "\makeatletter" write$
+ newline$
+ "\providecommand{\doi}" write$
+ newline$
+ " {\begingroup\let\do\@makeother\dospecials" write$
+ newline$
+ " \catcode`\{=1 \catcode`\}=2 \doi@aux}" write$
+ newline$
+ "\providecommand{\doi@aux}[1]{\endgroup\texttt{#1}}" write$
+ newline$
+ "\makeatother" write$
+ newline$
+ "\providecommand*\mcitethebibliography{\thebibliography}" write$
+ newline$
+ "\csname @ifundefined\endcsname{endmcitethebibliography}" write$
+ " {\let\endmcitethebibliography\endthebibliography}{}" write$
+ newline$
+ "\begin{mcitethebibliography}{"
+ entries.int int.to.str$ * "}" * write$
+ newline$
+ "\providecommand*\natexlab[1]{#1}" write$
+ newline$
+ "\providecommand*\mciteSetBstSublistMode[1]{}" write$
+ newline$
+ "\providecommand*\mciteSetBstMaxWidthForm[2]{}" write$
+ newline$
+ "\providecommand*\mciteBstWouldAddEndPuncttrue" write$
+ newline$
+ " {\def\EndOfBibitem{\unskip.}}" write$
+ newline$
+ "\providecommand*\mciteBstWouldAddEndPunctfalse" write$
+ newline$
+ " {\let\EndOfBibitem\relax}" write$
+ newline$
+ "\providecommand*\mciteSetBstMidEndSepPunct[3]{}" write$
+ newline$
+ "\providecommand*\mciteSetBstSublistLabelBeginEnd[3]{}" write$
+ newline$
+ "\providecommand*\EndOfBibitem{}" write$
+ newline$
+ "\mciteSetBstSublistMode{f}" write$
+ newline$
+ "\mciteSetBstMaxWidthForm{subitem}{(\alph{mcitesubitemcount})}" write$
+ newline$
+ "\mciteSetBstSublistLabelBeginEnd" write$
+ newline$
+ " {\mcitemaxwidthsubitemform\space}" write$
+ newline$
+ " {\relax}" write$
+ newline$
+ " {\relax}" write$
+ newline$
+}
+
+FUNCTION { end.bib } {
+ newline$
+ "\end{mcitethebibliography}" write$
+ newline$
+}
+
+
+INTEGERS {
+ ctrl.article.title.bool
+ ctrl.chapter.title.bool
+ ctrl.doi.bool
+ ctrl.etal.firstonly.bool
+ ctrl.etal.number.int
+}
+
+FUNCTION { initialize.control.values } {
+ #1 'ctrl.article.title.bool :=
+ #0 'ctrl.chapter.title.bool :=
+ #0 'ctrl.doi.bool :=
+ #1 'ctrl.etal.firstonly.bool :=
+ #15 'ctrl.etal.number.int :=
+}
+
+FUNCTION { control } {
+ ctrl-article-title yes.no.to.bool 'ctrl.article.title.bool :=
+ ctrl-chapter-title yes.no.to.bool 'ctrl.chapter.title.bool :=
+ ctrl-doi yes.no.to.bool 'ctrl.doi.bool :=
+ ctrl-etal-firstonly yes.no.to.bool 'ctrl.etal.firstonly.bool :=
+ ctrl-etal-number str.to.int 'ctrl.etal.number.int :=
+ ctrl-use-title empty$
+ 'skip$
+ { ctrl-use-title yes.no.to.bool 'ctrl.article.title.bool := }
+ if$
+}
+
+
+INTEGERS {
+ next.punct.comma
+ next.punct.period
+ next.punct.semicolon
+ next.punct.space
+}
+
+FUNCTION { initialize.tracker } {
+ #0 'next.punct.comma :=
+ #1 'next.punct.period :=
+ #2 'next.punct.semicolon :=
+ #3 'next.punct.space :=
+}
+
+INTEGERS { next.punct.int }
+
+FUNCTION { output } {
+ swap$
+ duplicate$ empty$
+ { pop$ }
+ {
+ next.punct.int next.punct.space =
+ { add.space }
+ {
+ next.punct.int next.punct.comma =
+ { add.comma }
+ {
+ next.punct.int next.punct.semicolon =
+ { add.semicolon }
+ { add.period }
+ if$
+ }
+ if$
+ }
+ if$
+ write$
+ }
+ if$
+ next.punct.comma 'next.punct.int :=
+}
+
+
+FUNCTION { begin.bibitem } {
+ newline$
+ "\bibitem" write$
+ label
+ calculate.full.names
+ duplicate$
+ short.names =
+ { pop$ }
+ { * }
+ if$
+ "[" swap$ * "]" * write$
+ "{" cite$ * "}" * write$
+ newline$
+ ""
+ next.punct.comma 'next.punct.int :=
+}
+
+INTEGERS { add.period.length.int }
+
+FUNCTION { would.add.period } {
+ duplicate$
+ add.period$
+ text.length$ 'add.period.length.int :=
+ duplicate$
+ text.length$
+ add.period.length.int =
+ { #0 }
+ { #1 }
+ if$
+}
+
+FUNCTION { end.bibitem } {
+ would.add.period
+ {
+ "\relax" * write$
+ newline$
+ "\mciteBstWouldAddEndPuncttrue" write$
+ newline$
+ "\mciteSetBstMidEndSepPunct{\mcitedefaultmidpunct}" write$
+ newline$
+ "{\mcitedefaultendpunct}{\mcitedefaultseppunct}\relax"
+ }
+ {
+ "\relax" * write$
+ newline$
+ "\mciteBstWouldAddEndPunctfalse" write$
+ newline$
+ "\mciteSetBstMidEndSepPunct{\mcitedefaultmidpunct}" write$
+ newline$
+ "{}{\mcitedefaultseppunct}\relax"
+ }
+ if$
+ write$
+ newline$
+ "\EndOfBibitem" write$
+}
+
+
+FUNCTION { initialize.name.separator } {
+ #1 'names.separate.comma :=
+ #0 'names.separate.semicolon :=
+}
+
+FUNCTION { format.names.loop } {
+ { remaining.names.int #0 > }
+ {
+ names.str current.name.int "{vv~}{ll}{,~f.}{,~jj}" format.name$
+ duplicate$
+ 'current.name.str :=
+ current.name.int #1 >
+ {
+ duplicate$
+ "others," =
+ {
+ pop$
+ *
+ bbl.etal
+ add.space
+ remaining.names.int #1 - 'remaining.names.int :=
+ }
+ {
+ swap$
+ names.separate.comma.bool
+ { add.comma }
+ { add.semicolon }
+ if$
+ swap$
+ *
+ }
+ if$
+ }
+ { }
+ if$
+ remaining.names.int #1 - 'remaining.names.int :=
+ current.name.int #1 + 'current.name.int :=
+ }
+ while$
+}
+
+FUNCTION { format.names.all } {
+ total.names.int 'remaining.names.int :=
+ format.names.loop
+}
+
+FUNCTION { format.names.etal } {
+ ctrl.etal.firstonly.bool
+ { #1 'remaining.names.int := }
+ { ctrl.etal.number.int 'remaining.names.int := }
+ if$
+ format.names.loop
+ current.name.str "others," =
+ { }
+ {
+ add.space
+ bbl.etal
+ add.space
+ *
+ }
+ if$
+}
+
+FUNCTION { format.names } {
+ 'names.separate.comma.bool :=
+ 'names.str :=
+ #1 'current.name.int :=
+ names.str num.names$ 'total.names.int :=
+ total.names.int ctrl.etal.number.int >
+ {
+ ctrl.etal.number.int #0 =
+ { format.names.all }
+ { format.names.etal }
+ if$
+ }
+ { format.names.all }
+ if$
+}
+
+
+FUNCTION { bbl.first } { "1st" }
+
+FUNCTION { bbl.second } { "2nd" }
+
+FUNCTION { bbl.third } { "3rd" }
+
+FUNCTION { bbl.fourth } { "4th" }
+
+FUNCTION { bbl.fifth } { "5th" }
+
+FUNCTION { bbl.st } { "st" }
+
+FUNCTION { bbl.nd } { "nd" }
+
+FUNCTION { bbl.rd } { "rd" }
+
+FUNCTION { bbl.th } { "th" }
+
+STRINGS {
+ ord.input.str
+ ord.output.str
+}
+
+FUNCTION { make.ordinal } {
+ duplicate$
+ "1" swap$
+ *
+ #-2 #1 substring$
+ "1" =
+ {
+ bbl.th *
+ }
+ {
+ duplicate$
+ #-1 #1 substring$
+ duplicate$
+ "1" =
+ {
+ pop$
+ bbl.st *
+ }
+ {
+ duplicate$
+ "2" =
+ {
+ pop$
+ bbl.nd *
+ }
+ {
+ "3" =
+ { bbl.rd * }
+ { bbl.th * }
+ if$
+ }
+ if$
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION { convert.to.ordinal } {
+ extract.number
+ "l" change.case$ 'ord.input.str :=
+ ord.input.str "first" = ord.input.str "1" = or
+ { bbl.first 'ord.output.str := }
+ {
+ ord.input.str "second" = ord.input.str "2" = or
+ { bbl.second 'ord.output.str := }
+ {
+ ord.input.str "third" = ord.input.str "3" = or
+ { bbl.third 'ord.output.str := }
+ {
+ ord.input.str "fourth" = ord.input.str "4" = or
+ { bbl.fourth 'ord.output.str := }
+ {
+ ord.input.str "fifth" = ord.input.str "5" = or
+ { bbl.fifth 'ord.output.str := }
+ {
+ ord.input.str #1 #1 substring$
+ is.a.number
+ { ord.input.str make.ordinal }
+ { ord.input.str }
+ if$
+ 'ord.output.str :=
+ }
+ if$
+ }
+ if$
+ }
+ if$
+ }
+ if$
+ }
+ if$
+ ord.output.str
+}
+
+
+FUNCTION { format.address } {
+ address empty$
+ { }
+ {
+ address
+ output
+ }
+ if$
+}
+
+FUNCTION { format.authors } {
+ author empty$
+ { }
+ {
+ author names.separate.semicolon format.names
+ output
+ next.punct.space 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.editors } {
+ editor empty$
+ { }
+ {
+ editor names.separate.comma format.names
+ add.comma
+ editor num.names$ #1 >
+ { bbl.editors }
+ { bbl.editor }
+ if$
+ *
+ output
+ next.punct.semicolon 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.authors.or.editors } {
+ author empty$
+ { format.editors }
+ { format.authors }
+ if$
+ next.punct.space 'next.punct.int :=
+}
+
+FUNCTION { format.chapter } {
+ chapter empty$
+ { }
+ {
+ bbl.chapter add.space
+ chapter
+ *
+ output
+ }
+ if$
+}
+
+FUNCTION { format.doi } {
+ doi empty$
+ 'skip$
+ {
+ bbl.doi add.space
+ "\doi{" * doi * "}" *
+ output
+ }
+ if$
+}
+
+FUNCTION { format.edition } {
+ edition empty$
+ { }
+ {
+ edition convert.to.ordinal
+ add.space bbl.edition *
+ output
+ }
+ if$
+ next.punct.semicolon 'next.punct.int :=
+}
+
+FUNCTION { format.group.address } {
+ duplicate$
+ empty$
+ { pop$ }
+ {
+ address empty$
+ { }
+ {
+ add.colon
+ address
+ *
+ }
+ if$
+ output
+ }
+ if$
+}
+
+FUNCTION { format.howpublished } {
+ howpublished empty$
+ { }
+ {
+ howpublished
+ output
+ }
+ if$
+}
+
+FUNCTION { format.journal } {
+ journal emph
+ output
+ next.punct.space 'next.punct.int :=
+}
+
+FUNCTION { format.journal.unpub } {
+ journal emph
+ output
+}
+
+FUNCTION { format.note } {
+ note empty$
+ { }
+ {
+ note
+ output
+ }
+ if$
+}
+
+FUNCTION { format.number.series } {
+ series empty$
+ { }
+ {
+ series
+ number empty$
+ { }
+ {
+ add.space
+ number *
+ }
+ if$
+ output
+ next.punct.semicolon 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.organization } {
+ organization empty$
+ { }
+ {
+ organization paren
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.organization.address } {
+ organization format.group.address
+}
+
+FUNCTION { format.pages } {
+ pages empty$
+ { }
+ {
+ pages multi.page.check
+ {
+ bbl.pages
+ pages hyphen.to.dash
+ }
+ { bbl.page pages }
+ if$
+ tie.or.space.connect
+ output
+ }
+ if$
+ ctrl.doi.bool
+ { format.doi }
+ 'skip$
+ if$
+}
+
+FUNCTION { format.pages.article } {
+ pages empty$
+ { }
+ {
+ pages hyphen.to.dash
+ output
+ }
+ if$
+ ctrl.doi.bool
+ { format.doi }
+ 'skip$
+ if$
+}
+
+FUNCTION { format.publisher.address } {
+ publisher format.group.address
+}
+
+FUNCTION { format.school.address } {
+ school
+ duplicate$
+ empty$
+ { pop$ }
+ {
+ address empty$
+ { }
+ {
+ add.comma
+ address
+ *
+ }
+ if$
+ output
+ }
+ if$
+}
+
+FUNCTION { format.title } {
+ title empty$
+ { }
+ {
+ title
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.title.article } {
+ ctrl.article.title.bool
+ {
+ title empty$
+ { }
+ {
+ title
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+ }
+ { }
+ if$
+}
+
+FUNCTION { format.title.techreport } {
+ title empty$
+ { }
+ {
+ title emph
+ output
+ next.punct.semicolon 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.title.booktitle } {
+ title empty$
+ { }
+ {
+ title
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+ booktitle empty$
+ { }
+ {
+ booktitle
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+}
+
+STRINGS {
+ book.title
+ chapter.title
+}
+
+FUNCTION { format.title.booktitle.book } {
+ "" 'chapter.title :=
+ booktitle empty$
+ {
+ "" 'chapter.title :=
+ title 'book.title :=
+ }
+ {
+ ctrl.chapter.title.bool
+ {
+ title empty$
+ 'skip$
+ { title 'chapter.title := }
+ if$
+ }
+ 'skip$
+ if$
+ maintitle empty$
+ { booktitle 'book.title := }
+ { maintitle add.period booktitle * 'book.title := }
+ if$
+ }
+ if$
+ chapter.title empty$
+ { }
+ {
+ chapter.title
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+ book.title emph
+ chapter.title empty$
+ {
+ author empty$
+ { }
+ {
+ editor empty$
+ { }
+ { bbl.in add.space swap$ * }
+ if$
+ }
+ if$
+ }
+ { bbl.in add.space swap$ * }
+ if$
+ output
+}
+
+FUNCTION { format.type } {
+ type empty$
+ { }
+ {
+ pop$
+ type
+ }
+ if$
+ output
+}
+
+FUNCTION { format.type.number } {
+ type empty$
+ { }
+ {
+ type
+ number empty$
+ { }
+ { number tie.or.space.connect }
+ if$
+ output
+ }
+ if$
+}
+
+FUNCTION { format.url } {
+ url empty$
+ { }
+ {
+ "\url{" url * "}" *
+ output
+ }
+ if$
+}
+
+FUNCTION { format.year } {
+ year empty$
+ { }
+ {
+ year
+ output
+ next.punct.semicolon 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.year.article } {
+ year empty$
+ { }
+ {
+ year bold
+ output
+ }
+ if$
+}
+
+FUNCTION { format.version } {
+ version empty$
+ { }
+ {
+ bbl.version add.space
+ version
+ *
+ output
+ }
+ if$
+}
+
+FUNCTION { format.volume.article } {
+ volume emph
+ output
+}
+
+FUNCTION { format.volume } {
+ volume empty$
+ { }
+ {
+ bbl.volume
+ volume
+ tie.or.space.connect
+ output
+ next.punct.semicolon 'next.punct.int :=
+ }
+ if$
+}
+
+
+FUNCTION { article } {
+ begin.bibitem
+ format.authors
+ format.title.article
+ format.journal
+ format.year.article
+ format.volume.article
+ format.pages.article
+ format.note
+ end.bibitem
+}
+
+FUNCTION { book } {
+ begin.bibitem
+ format.authors.or.editors
+ format.title.booktitle.book
+ format.edition
+ author empty$
+ { }
+ { format.editors }
+ if$
+ format.number.series
+ format.publisher.address
+ format.year
+ format.volume
+ format.chapter
+ format.pages
+ format.note
+ end.bibitem
+}
+
+FUNCTION { inbook } { book }
+
+FUNCTION { booklet } {
+ begin.bibitem
+ format.authors
+ format.title
+ format.howpublished
+ format.address
+ format.year
+ format.note
+ end.bibitem
+}
+
+FUNCTION { collection } { book }
+
+FUNCTION { incollection } { book }
+
+FUNCTION { inpress } {
+ begin.bibitem
+ format.authors
+ format.journal.unpub
+ doi empty$
+ {
+ bbl.inpress
+ output
+ }
+ {
+ format.year.article
+ next.punct.comma 'next.punct.int :=
+ format.doi
+ }
+ if$
+ format.note
+ end.bibitem
+}
+
+FUNCTION { inproceedings } {
+ begin.bibitem
+ format.authors
+ format.title.booktitle
+ format.address
+ format.year
+ format.pages
+ format.note
+ end.bibitem
+}
+
+FUNCTION { manual } {
+ begin.bibitem
+ format.authors
+ format.title
+ format.version
+ format.organization.address
+ format.year
+ format.note
+ end.bibitem
+}
+
+FUNCTION { mastersthesis } {
+ begin.bibitem
+ format.authors
+ format.title
+ bbl.msc format.type
+ format.school.address
+ format.year
+ format.note
+ end.bibitem
+}
+
+FUNCTION { misc } {
+ begin.bibitem
+ format.authors
+ format.title
+ format.howpublished
+ format.year
+ format.url
+ format.note
+ end.bibitem
+}
+
+FUNCTION { patent } {
+ begin.bibitem
+ format.authors
+ format.organization
+ format.title
+ format.type.number
+ format.year
+ format.note
+ end.bibitem
+}
+
+FUNCTION { phdthesis } {
+ begin.bibitem
+ format.authors
+ format.title
+ bbl.phd format.type
+ format.school.address
+ format.year
+ format.note
+ end.bibitem
+}
+
+FUNCTION { proceeding } {
+ begin.bibitem
+ format.title
+ format.address
+ format.year
+ format.pages
+ format.note
+ end.bibitem
+}
+
+FUNCTION { techreport } {
+ begin.bibitem
+ format.authors.or.editors
+ format.title.techreport
+ format.type.number
+ format.organization.address
+ format.year
+ format.volume
+ format.pages
+ format.note
+ end.bibitem
+}
+
+FUNCTION { unpublished } {
+ begin.bibitem
+ format.authors
+ format.journal.unpub
+ doi empty$
+ { format.howpublished }
+ {
+ format.year
+ next.punct.comma 'next.punct.int :=
+ format.doi
+ }
+ if$
+ format.note
+ end.bibitem
+}
+
+FUNCTION { default.type } { misc }
+
+
+MACRO { jan } { "Jan." }
+MACRO { feb } { "Feb." }
+MACRO { mar } { "Mar." }
+MACRO { apr } { "Apr." }
+MACRO { may } { "May" }
+MACRO { jun } { "June" }
+MACRO { jul } { "July" }
+MACRO { aug } { "Aug." }
+MACRO { sep } { "Sept." }
+MACRO { oct } { "Oct." }
+MACRO { nov } { "Nov." }
+MACRO { dec } { "Dec." }
+
+MACRO { acbcct } { "ACS Chem.\ Biol." }
+MACRO { achre4 } { "Acc.\ Chem.\ Res." }
+MACRO { acncdm } { "ACS Chem.\ Neurosci." }
+MACRO { ancac3 } { "ACS Nano" }
+MACRO { ancham } { "Anal.\ Chem." }
+MACRO { bichaw } { "Biochemistry" }
+MACRO { bcches } { "Bioconjugate Chem." }
+MACRO { bomaf6 } { "Biomacromolecules" }
+MACRO { bipret } { "Biotechnol.\ Prog." }
+MACRO { crtoec } { "Chem.\ Res.\ Toxicol." }
+MACRO { chreay } { "Chem.\ Rev." }
+MACRO { cmatex } { "Chem.\ Mater." }
+MACRO { cgdefu } { "Cryst.\ Growth Des." }
+MACRO { enfuem } { "Energy Fuels" }
+MACRO { esthag } { "Environ.\ Sci.\ Technol." }
+MACRO { iechad } { "Ind.\ Eng.\ Chem.\ Res." }
+MACRO { inoraj } { "Inorg.\ Chem." }
+MACRO { jafcau } { "J.~Agric.\ Food Chem." }
+MACRO { jceaax } { "J.~Chem.\ Eng.\ Data" }
+MACRO { jceda8 } { "J.~Chem.\ Ed." }
+MACRO { jcisd8 } { "J.~Chem.\ Inf.\ Model." }
+MACRO { jctcce } { "J.~Chem.\ Theory Comput." }
+MACRO { jcchff } { "J. Comb. Chem." }
+MACRO { jmcmar } { "J. Med. Chem." }
+MACRO { jnprdf } { "J. Nat. Prod." }
+MACRO { joceah } { "J.~Org.\ Chem." }
+MACRO { jpcafh } { "J.~Phys.\ Chem.~A" }
+MACRO { jpcbfk } { "J.~Phys.\ Chem.~B" }
+MACRO { jpccck } { "J.~Phys.\ Chem.~C" }
+MACRO { jpclcd } { "J.~Phys.\ Chem.\ Lett." }
+MACRO { jprobs } { "J.~Proteome Res." }
+MACRO { jacsat } { "J.~Am.\ Chem.\ Soc." }
+MACRO { langd5 } { "Langmuir" }
+MACRO { mamobx } { "Macromolecules" }
+MACRO { mpohbp } { "Mol.\ Pharm." }
+MACRO { nalefd } { "Nano Lett." }
+MACRO { orlef7 } { "Org.\ Lett." }
+MACRO { oprdfk } { "Org.\ Proc.\ Res.\ Dev." }
+MACRO { orgnd7 } { "Organometallics" }
+
+
+READ
+
+EXECUTE { initialize.control.values }
+
+EXECUTE { initialize.count.entries }
+
+EXECUTE { initialize.name.separator }
+
+EXECUTE { initialize.tracker }
+
+ITERATE { calculate.names }
+
+ITERATE { count.entries }
+
+EXECUTE { begin.bib }
+
+ITERATE { call.type$ }
+
+EXECUTE { end.bib }
+%%
+%% Originally developed by Mats Dahlgren
+%% Copyright (C) 1996-1998 by Mats Dahlgren
+%% Copyright (C) 2008-2022 by
+%% Joseph Wright
+%%
+%% Part of this bundle is derived from cite.sty, to which the
+%% following license applies:
+%% Copyright (C) 1989-2009 by Donald Arseneau
+%% These macros may be freely transmitted, reproduced, or
+%% modified provided that this notice is left intact.
+%%
+%% It may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License (LPPL), either version 1.3c of
+%% this license or (at your option) any later version. The latest
+%% version of this license is in the file:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% This work is "maintained" (as per LPPL maintenance status) by
+%% Joseph Wright.
+%%
+%% This work consists of the files achemso.dtx,
+%% achemso-demo.bib and
+%% achemso-demo.tex,
+%% and the derived files achemso.cls,
+%% achemso.ins,
+%% achemso.pdf,
+%% achemso.sty,
+%% natmove.sty and
+%% a number of configuration files.
+%%
+%%
+%% End of file `achemso.bst'.
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/biochem.bst b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/biochem.bst
new file mode 100644
index 00000000000..26f1495c8cd
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/biochem.bst
@@ -0,0 +1,1750 @@
+%%
+%% This is file `biochem.bst',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% achemso.dtx (with options: `bst,bio')
+%%
+%% IMPORTANT NOTICE:
+%%
+%% For the copyright see the source file.
+%%
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from biochem.bst.
+%%
+%% For distribution of the original source see the terms
+%% for copying and modification in the file achemso.dtx.
+%%
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+
+ENTRY
+ {
+ address
+ author
+ booktitle
+ chapter
+ ctrl-article-title
+ ctrl-chapter-title
+ ctrl-doi
+ ctrl-etal-firstonly
+ ctrl-etal-number
+ ctrl-use-title
+ doi
+ edition
+ editor
+ howpublished
+ institution
+ journal
+ key
+ maintitle
+ note
+ number
+ organization
+ pages
+ publisher
+ school
+ series
+ title
+ type
+ url
+ version
+ volume
+ year
+ }
+ { }
+ {
+ label
+ short.names
+ }
+
+
+FUNCTION { and } {
+ { }
+ {
+ pop$
+ #0
+ }
+ if$
+}
+
+FUNCTION { not } {
+ { #0 }
+ { #1 }
+ if$
+}
+
+FUNCTION { or } {
+ {
+ pop$
+ #1
+ }
+ { }
+ if$
+}
+
+FUNCTION { xor } {
+ { not }
+ { }
+ if$
+}
+
+
+FUNCTION { chr.to.value.error } {
+ #48 +
+ int.to.chr$
+ "'" swap$ *
+ "'" *
+ " is not a number: treated as zero." *
+ warning$
+ #0
+}
+
+FUNCTION { chr.to.value } {
+ chr.to.int$ #48 -
+ duplicate$
+ #0 <
+ { chr.to.value.error }
+ {
+ duplicate$
+ #9 >
+ { chr.to.value.error }
+ { }
+ if$
+ }
+ if$
+}
+
+STRINGS {
+ extract.input.str
+ extract.output.str
+}
+
+FUNCTION { is.a.digit } {
+ duplicate$
+ "" =
+ {
+ pop$
+ #0
+ }
+ {
+ chr.to.int$
+ #48 -
+ duplicate$
+ #0 < swap$ #9 > or not
+ }
+ if$
+}
+
+FUNCTION{ is.a.number } {
+ {
+ duplicate$
+ #1 #1 substring$
+ is.a.digit
+ }
+ { #2 global.max$ substring$ }
+ while$
+ "" =
+}
+
+FUNCTION { extract.number } {
+ duplicate$
+ 'extract.input.str :=
+ "" 'extract.output.str :=
+ { extract.input.str empty$ not }
+ {
+ extract.input.str #1 #1 substring$
+ extract.input.str #2 global.max$ substring$ 'extract.input.str :=
+ duplicate$
+ is.a.number
+ { extract.output.str swap$ * 'extract.output.str := }
+ {
+ pop$
+ "" 'extract.input.str :=
+ }
+ if$
+ }
+ while$
+ extract.output.str empty$
+ { }
+ {
+ pop$
+ extract.output.str
+ }
+ if$
+}
+
+FUNCTION { field.or.null } {
+ duplicate$
+ empty$
+ {
+ pop$
+ ""
+ }
+ { }
+ if$
+}
+
+INTEGERS {
+ multiply.a.int
+ multiply.b.int
+}
+
+FUNCTION { multiply } {
+ 'multiply.a.int :=
+ 'multiply.b.int :=
+ multiply.b.int #0 <
+ {
+ #-1
+ #0 multiply.b.int - 'multiply.b.int :=
+ }
+ { #1 }
+ if$
+ #0
+ { multiply.b.int #0 > }
+ {
+ multiply.a.int +
+ multiply.b.int #1 - 'multiply.b.int :=
+ }
+ while$
+ swap$
+ { }
+ { #0 swap$ - }
+ if$
+}
+
+INTEGERS { str.conversion.int }
+
+FUNCTION { str.to.int.aux.ii } {
+ {
+ duplicate$
+ empty$ not
+ }
+ {
+ swap$
+ #10 multiply 'str.conversion.int :=
+ duplicate$
+ #1 #1 substring$
+ chr.to.value
+ str.conversion.int +
+ swap$
+ #2 global.max$ substring$
+ }
+ while$
+ pop$
+}
+
+FUNCTION { str.to.int.aux.i } {
+ duplicate$
+ #1 #1 substring$
+ "-" =
+ {
+ #1 swap$
+ #2 global.max$ substring$
+ }
+ {
+ #0 swap$
+ }
+ if$
+ #0
+ swap$
+ str.to.int.aux.ii
+ swap$
+ { #0 swap$ - }
+ { }
+ if$
+}
+
+FUNCTION { str.to.int } {
+ duplicate$
+ empty$
+ {
+ pop$
+ #0
+ }
+ { str.to.int.aux.i }
+ if$
+}
+
+FUNCTION { tie.or.space.connect } {
+ duplicate$
+ text.length$ #3 <
+ { "~" }
+ { " " }
+ if$
+ swap$ * *
+}
+
+FUNCTION { yes.no.to.bool } {
+ duplicate$
+ empty$
+ {
+ pop$
+ #0
+ }
+ {
+ "l" change.case$
+ "yes" =
+ { #1 }
+ { #0 }
+ if$
+ }
+ if$
+}
+
+
+FUNCTION { bold } {
+ duplicate$
+ empty$
+ {
+ pop$
+ ""
+ }
+ { "\textbf{" swap$ * "}" * }
+ if$
+}
+
+FUNCTION { emph } {
+ duplicate$
+ empty$
+ {
+ pop$
+ ""
+ }
+ { "\emph{" swap$ * "}" * }
+ if$
+}
+
+FUNCTION { paren } {
+ duplicate$
+ empty$
+ {
+ pop$
+ ""
+ }
+ { "(" swap$ * ")" * }
+ if$
+}
+
+
+FUNCTION { add.comma } { ", " * }
+
+FUNCTION { add.colon } { ": " * }
+
+FUNCTION { add.period } { add.period$ " " * }
+
+FUNCTION { add.semicolon } { "; " * }
+
+FUNCTION { add.space } { " " * }
+
+
+FUNCTION { bbl.and } { "and" }
+
+FUNCTION { bbl.chapter } { "Chapter" }
+
+FUNCTION { bbl.doi } { "DOI:" }
+
+FUNCTION { bbl.editor } { "Ed." }
+
+FUNCTION { bbl.editors } { "Eds." }
+
+FUNCTION { bbl.edition } { "ed." }
+
+FUNCTION { bbl.etal } { "\latin{et~al.}" }
+
+FUNCTION { bbl.in } { "In" }
+
+FUNCTION { bbl.inpress } { "in press" }
+
+FUNCTION { bbl.msc } { "M.Sc.\ thesis" }
+
+FUNCTION { bbl.page } { "p" }
+
+FUNCTION { bbl.pages } { "pp" }
+
+FUNCTION { bbl.phd } { "Ph.D.\ thesis" }
+
+FUNCTION { bbl.version } { "version" }
+
+FUNCTION { bbl.volume } { "Vol." }
+
+
+STRINGS { pages.str }
+
+FUNCTION { hyphen.to.dash } {
+ 'pages.str :=
+ ""
+ { pages.str empty$ not }
+ {
+ pages.str #1 #1 substring$
+ "-" =
+ {
+ "--" *
+ {
+ pages.str #1 #1 substring$
+ "-" =
+ }
+ { pages.str #2 global.max$ substring$ 'pages.str := }
+ while$
+ }
+ {
+ pages.str #1 #1 substring$
+ *
+ pages.str #2 global.max$ substring$ 'pages.str :=
+ }
+ if$
+ }
+ while$
+}
+
+INTEGERS { multiresult.bool }
+
+FUNCTION { multi.page.check } {
+ 'pages.str :=
+ #0 'multiresult.bool :=
+ {
+ multiresult.bool not
+ pages.str empty$ not
+ and
+ }
+ {
+ pages.str #1 #1 substring$
+ duplicate$
+ "-" = swap$ duplicate$
+ "," = swap$
+ "+" =
+ or or
+ { #1 'multiresult.bool := }
+ { pages.str #2 global.max$ substring$ 'pages.str := }
+ if$
+ }
+ while$
+ multiresult.bool
+}
+
+
+INTEGERS {
+ current.name.int
+ names.separate.comma
+ names.separate.semicolon
+ names.separate.comma.bool
+ remaining.names.int
+ total.names.int
+}
+
+STRINGS {
+ current.name.str
+ names.str
+}
+
+FUNCTION { full.format.names } {
+ 'names.str :=
+ #1 'current.name.int :=
+ names.str num.names$ 'remaining.names.int :=
+ { remaining.names.int #0 > }
+ {
+ names.str current.name.int "{vv~}{ll}" format.name$
+ current.name.int #1 >
+ {
+ swap$ add.comma swap$
+ remaining.names.int #1 >
+ { }
+ {
+ duplicate$
+ "others" =
+ { bbl.etal }
+ { bbl.and }
+ if$
+ add.space swap$ *
+ }
+ if$
+ *
+ }
+ { }
+ if$
+ remaining.names.int #1 - 'remaining.names.int :=
+ current.name.int #1 + 'current.name.int :=
+ }
+ while$
+}
+
+FUNCTION { full.author } {
+ author empty$
+ { "" }
+ { author full.format.names }
+ if$
+}
+
+FUNCTION { full.author.editor } {
+ author empty$
+ {
+ editor empty$
+ { "" }
+ { editor full.format.names }
+ if$
+ }
+ { author full.format.names }
+ if$
+}
+
+FUNCTION { full.editor } {
+ editor empty$
+ { "" }
+ { editor full.format.names }
+ if$
+}
+
+FUNCTION { short.format.names } {
+ 'names.str :=
+ names.str #1 "{vv~}{ll}" format.name$
+ names.str num.names$
+ duplicate$
+ #2 >
+ {
+ pop$
+ add.space bbl.etal *
+ }
+ {
+ #2 <
+ { }
+ {
+ names.str #2 "{ff }{vv }{ll}{ jj}" format.name$
+ "others" =
+ { add.space bbl.etal * }
+ {
+ add.space
+ bbl.and add.space
+ *
+ names.str #2 "{vv~}{ll}" format.name$
+ *
+ }
+ if$
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION { short.author.key } {
+ author empty$
+ {
+ key empty$
+ { cite$ #1 #3 substring$ }
+ { key }
+ if$
+ }
+ { author short.format.names }
+ if$
+}
+
+FUNCTION { short.author.editor.key } {
+ author empty$
+ {
+ editor empty$
+ {
+ key empty$
+ { cite$ #1 #3 substring$ }
+ { key }
+ if$
+ }
+ { editor short.format.names }
+ if$
+ }
+ { author short.format.names }
+ if$
+}
+
+FUNCTION { short.author.key.organization } {
+ author empty$
+ {
+ key empty$
+ {
+ organization empty$
+ { cite$ #1 #3 substring$ }
+ {
+ organization #1 #4 substring$
+ "The " =
+ { organization }
+ { organization #5 global.max$ substring$ }
+ if$
+ #3 text.prefix$
+ }
+ if$
+ }
+ { key }
+ if$
+ }
+ { author short.format.names }
+ if$
+}
+
+FUNCTION { short.editor.key.organization } {
+ editor empty$
+ {
+ key empty$
+ {
+ organization empty$
+ { cite$ #1 #3 substring$ }
+ {
+ organization #1 #4 substring$
+ "The " =
+ { organization }
+ { organization #5 global.max$ substring$ }
+ if$
+ #3 text.prefix$
+ }
+ if$
+ }
+ { key }
+ if$
+ }
+ { editor short.format.names }
+ if$
+}
+
+FUNCTION { calculate.full.names } {
+ type$ "book" =
+ type$ "inbook" =
+ or
+ { full.author.editor }
+ {
+ type$ "proceedings" =
+ { full.editor }
+ { full.author }
+ if$
+ }
+ if$
+}
+
+FUNCTION { calculate.short.names } {
+ type$ "book" =
+ type$ "inbook" =
+ or
+ { short.author.editor.key }
+ {
+ type$ "proceedings" =
+ { short.editor.key.organization }
+ {
+ type$ "manual" =
+ { short.author.key.organization }
+ { short.author.key }
+ if$
+ }
+ if$
+ }
+ if$
+ 'short.names :=
+}
+
+FUNCTION { calculate.names } {
+ calculate.short.names
+ short.names
+ year empty$
+ { "()" }
+ { "(" year * ")" * }
+ if$
+ *
+ 'label :=
+}
+
+
+INTEGERS { entries.int }
+
+FUNCTION { initialize.count.entries } {
+ #0 'entries.int :=
+}
+
+FUNCTION { count.entries } {
+ entries.int #1 + 'entries.int :=
+}
+
+
+FUNCTION { begin.bib } {
+ "achemso 2022-11-25 v3.13f" top$
+ preamble$ empty$
+ { }
+ {
+ preamble$ write$
+ newline$
+ }
+ if$
+ "\providecommand{\latin}[1]{#1}" write$
+ newline$
+ "\makeatletter" write$
+ newline$
+ "\providecommand{\doi}" write$
+ newline$
+ " {\begingroup\let\do\@makeother\dospecials" write$
+ newline$
+ " \catcode`\{=1 \catcode`\}=2 \doi@aux}" write$
+ newline$
+ "\providecommand{\doi@aux}[1]{\endgroup\texttt{#1}}" write$
+ newline$
+ "\makeatother" write$
+ newline$
+ "\providecommand*\mcitethebibliography{\thebibliography}" write$
+ newline$
+ "\csname @ifundefined\endcsname{endmcitethebibliography}" write$
+ " {\let\endmcitethebibliography\endthebibliography}{}" write$
+ newline$
+ "\begin{mcitethebibliography}{"
+ entries.int int.to.str$ * "}" * write$
+ newline$
+ "\providecommand*\natexlab[1]{#1}" write$
+ newline$
+ "\providecommand*\mciteSetBstSublistMode[1]{}" write$
+ newline$
+ "\providecommand*\mciteSetBstMaxWidthForm[2]{}" write$
+ newline$
+ "\providecommand*\mciteBstWouldAddEndPuncttrue" write$
+ newline$
+ " {\def\EndOfBibitem{\unskip.}}" write$
+ newline$
+ "\providecommand*\mciteBstWouldAddEndPunctfalse" write$
+ newline$
+ " {\let\EndOfBibitem\relax}" write$
+ newline$
+ "\providecommand*\mciteSetBstMidEndSepPunct[3]{}" write$
+ newline$
+ "\providecommand*\mciteSetBstSublistLabelBeginEnd[3]{}" write$
+ newline$
+ "\providecommand*\EndOfBibitem{}" write$
+ newline$
+ "\mciteSetBstSublistMode{f}" write$
+ newline$
+ "\mciteSetBstMaxWidthForm{subitem}{(\alph{mcitesubitemcount})}" write$
+ newline$
+ "\mciteSetBstSublistLabelBeginEnd" write$
+ newline$
+ " {\mcitemaxwidthsubitemform\space}" write$
+ newline$
+ " {\relax}" write$
+ newline$
+ " {\relax}" write$
+ newline$
+}
+
+FUNCTION { end.bib } {
+ newline$
+ "\end{mcitethebibliography}" write$
+ newline$
+}
+
+
+INTEGERS {
+ ctrl.article.title.bool
+ ctrl.chapter.title.bool
+ ctrl.doi.bool
+ ctrl.etal.firstonly.bool
+ ctrl.etal.number.int
+}
+
+FUNCTION { initialize.control.values } {
+ #1 'ctrl.article.title.bool :=
+ #0 'ctrl.chapter.title.bool :=
+ #0 'ctrl.doi.bool :=
+ #1 'ctrl.etal.firstonly.bool :=
+ #15 'ctrl.etal.number.int :=
+}
+
+FUNCTION { control } {
+ ctrl-article-title yes.no.to.bool 'ctrl.article.title.bool :=
+ ctrl-chapter-title yes.no.to.bool 'ctrl.chapter.title.bool :=
+ ctrl-doi yes.no.to.bool 'ctrl.doi.bool :=
+ ctrl-etal-firstonly yes.no.to.bool 'ctrl.etal.firstonly.bool :=
+ ctrl-etal-number str.to.int 'ctrl.etal.number.int :=
+ ctrl-use-title empty$
+ 'skip$
+ { ctrl-use-title yes.no.to.bool 'ctrl.article.title.bool := }
+ if$
+}
+
+
+INTEGERS {
+ next.punct.comma
+ next.punct.period
+ next.punct.semicolon
+ next.punct.space
+}
+
+FUNCTION { initialize.tracker } {
+ #0 'next.punct.comma :=
+ #1 'next.punct.period :=
+ #2 'next.punct.semicolon :=
+ #3 'next.punct.space :=
+}
+
+INTEGERS { next.punct.int }
+
+FUNCTION { output } {
+ swap$
+ duplicate$ empty$
+ { pop$ }
+ {
+ next.punct.int next.punct.space =
+ { add.space }
+ {
+ next.punct.int next.punct.comma =
+ { add.comma }
+ {
+ next.punct.int next.punct.semicolon =
+ { add.semicolon }
+ { add.period }
+ if$
+ }
+ if$
+ }
+ if$
+ write$
+ }
+ if$
+ next.punct.comma 'next.punct.int :=
+}
+
+
+FUNCTION { begin.bibitem } {
+ newline$
+ "\bibitem" write$
+ label
+ calculate.full.names
+ duplicate$
+ short.names =
+ { pop$ }
+ { * }
+ if$
+ "[" swap$ * "]" * write$
+ "{" cite$ * "}" * write$
+ newline$
+ ""
+ next.punct.comma 'next.punct.int :=
+}
+
+INTEGERS { add.period.length.int }
+
+FUNCTION { would.add.period } {
+ duplicate$
+ add.period$
+ text.length$ 'add.period.length.int :=
+ duplicate$
+ text.length$
+ add.period.length.int =
+ { #0 }
+ { #1 }
+ if$
+}
+
+FUNCTION { end.bibitem } {
+ would.add.period
+ {
+ "\relax" * write$
+ newline$
+ "\mciteBstWouldAddEndPuncttrue" write$
+ newline$
+ "\mciteSetBstMidEndSepPunct{\mcitedefaultmidpunct}" write$
+ newline$
+ "{\mcitedefaultendpunct}{\mcitedefaultseppunct}\relax"
+ }
+ {
+ "\relax" * write$
+ newline$
+ "\mciteBstWouldAddEndPunctfalse" write$
+ newline$
+ "\mciteSetBstMidEndSepPunct{\mcitedefaultmidpunct}" write$
+ newline$
+ "{}{\mcitedefaultseppunct}\relax"
+ }
+ if$
+ write$
+ newline$
+ "\EndOfBibitem" write$
+}
+
+
+FUNCTION { initialize.name.separator } {
+ #1 'names.separate.comma :=
+ #0 'names.separate.semicolon :=
+}
+
+FUNCTION { format.names.loop } {
+ { remaining.names.int #0 > }
+ {
+ names.str current.name.int "{vv~}{ll}{,~f.}{,~jj}" format.name$
+ duplicate$
+ 'current.name.str :=
+ current.name.int #1 >
+ {
+ duplicate$
+ "others," =
+ {
+ pop$
+ *
+ bbl.etal
+ add.space
+ remaining.names.int #1 - 'remaining.names.int :=
+ }
+ {
+ swap$
+ names.separate.comma.bool
+ { add.comma }
+ { add.semicolon }
+ if$
+ remaining.names.int #1 >
+ { }
+ { bbl.and add.space * }
+ if$
+ swap$
+ *
+ }
+ if$
+ }
+ { }
+ if$
+ remaining.names.int #1 - 'remaining.names.int :=
+ current.name.int #1 + 'current.name.int :=
+ }
+ while$
+}
+
+FUNCTION { format.names.all } {
+ total.names.int 'remaining.names.int :=
+ format.names.loop
+}
+
+FUNCTION { format.names.etal } {
+ ctrl.etal.firstonly.bool
+ { #1 'remaining.names.int := }
+ { ctrl.etal.number.int 'remaining.names.int := }
+ if$
+ format.names.loop
+ current.name.str "others," =
+ { }
+ {
+ add.space
+ bbl.etal
+ add.space
+ *
+ }
+ if$
+}
+
+FUNCTION { format.names } {
+ 'names.separate.comma.bool :=
+ 'names.str :=
+ #1 'current.name.int :=
+ names.str num.names$ 'total.names.int :=
+ total.names.int ctrl.etal.number.int >
+ {
+ ctrl.etal.number.int #0 =
+ { format.names.all }
+ { format.names.etal }
+ if$
+ }
+ { format.names.all }
+ if$
+}
+
+
+FUNCTION { bbl.first } { "1st" }
+
+FUNCTION { bbl.second } { "2nd" }
+
+FUNCTION { bbl.third } { "3rd" }
+
+FUNCTION { bbl.fourth } { "4th" }
+
+FUNCTION { bbl.fifth } { "5th" }
+
+FUNCTION { bbl.st } { "st" }
+
+FUNCTION { bbl.nd } { "nd" }
+
+FUNCTION { bbl.rd } { "rd" }
+
+FUNCTION { bbl.th } { "th" }
+
+STRINGS {
+ ord.input.str
+ ord.output.str
+}
+
+FUNCTION { make.ordinal } {
+ duplicate$
+ "1" swap$
+ *
+ #-2 #1 substring$
+ "1" =
+ {
+ bbl.th *
+ }
+ {
+ duplicate$
+ #-1 #1 substring$
+ duplicate$
+ "1" =
+ {
+ pop$
+ bbl.st *
+ }
+ {
+ duplicate$
+ "2" =
+ {
+ pop$
+ bbl.nd *
+ }
+ {
+ "3" =
+ { bbl.rd * }
+ { bbl.th * }
+ if$
+ }
+ if$
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION { convert.to.ordinal } {
+ extract.number
+ "l" change.case$ 'ord.input.str :=
+ ord.input.str "first" = ord.input.str "1" = or
+ { bbl.first 'ord.output.str := }
+ {
+ ord.input.str "second" = ord.input.str "2" = or
+ { bbl.second 'ord.output.str := }
+ {
+ ord.input.str "third" = ord.input.str "3" = or
+ { bbl.third 'ord.output.str := }
+ {
+ ord.input.str "fourth" = ord.input.str "4" = or
+ { bbl.fourth 'ord.output.str := }
+ {
+ ord.input.str "fifth" = ord.input.str "5" = or
+ { bbl.fifth 'ord.output.str := }
+ {
+ ord.input.str #1 #1 substring$
+ is.a.number
+ { ord.input.str make.ordinal }
+ { ord.input.str }
+ if$
+ 'ord.output.str :=
+ }
+ if$
+ }
+ if$
+ }
+ if$
+ }
+ if$
+ }
+ if$
+ ord.output.str
+}
+
+
+FUNCTION { format.address } {
+ address empty$
+ { }
+ {
+ address
+ output
+ }
+ if$
+}
+
+FUNCTION { format.authors } {
+ author empty$
+ { }
+ {
+ author names.separate.comma format.names
+ output
+ next.punct.space 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.editors } {
+ editor empty$
+ { }
+ {
+ editor names.separate.comma format.names
+ add.comma
+ editor num.names$ #1 >
+ { bbl.editors }
+ { bbl.editor }
+ if$
+ *
+ output
+ next.punct.semicolon 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.authors.or.editors } {
+ author empty$
+ { format.editors }
+ { format.authors }
+ if$
+ next.punct.space 'next.punct.int :=
+}
+
+FUNCTION { format.chapter } {
+ chapter empty$
+ { }
+ {
+ bbl.chapter add.space
+ chapter
+ *
+ output
+ }
+ if$
+}
+
+FUNCTION { format.doi } {
+ doi empty$
+ 'skip$
+ {
+ bbl.doi add.space
+ "\doi{" * doi * "}" *
+ output
+ }
+ if$
+}
+
+FUNCTION { format.edition } {
+ edition empty$
+ { }
+ {
+ edition convert.to.ordinal
+ add.space bbl.edition *
+ output
+ }
+ if$
+ next.punct.semicolon 'next.punct.int :=
+}
+
+FUNCTION { format.group.address } {
+ duplicate$
+ empty$
+ { pop$ }
+ {
+ address empty$
+ { }
+ {
+ add.colon
+ address
+ *
+ }
+ if$
+ output
+ }
+ if$
+}
+
+FUNCTION { format.howpublished } {
+ howpublished empty$
+ { }
+ {
+ howpublished
+ output
+ }
+ if$
+}
+
+FUNCTION { format.journal } {
+ journal emph
+ output
+ next.punct.space 'next.punct.int :=
+}
+
+FUNCTION { format.journal.unpub } {
+ journal emph
+ output
+}
+
+FUNCTION { format.note } {
+ note empty$
+ { }
+ {
+ note
+ output
+ }
+ if$
+}
+
+FUNCTION { format.number.series } {
+ series empty$
+ { }
+ {
+ series
+ number empty$
+ { }
+ {
+ add.space
+ number *
+ }
+ if$
+ output
+ next.punct.semicolon 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.organization } {
+ organization empty$
+ { }
+ {
+ organization paren
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.organization.address } {
+ organization format.group.address
+}
+
+FUNCTION { format.pages } {
+ pages empty$
+ { }
+ {
+ pages multi.page.check
+ {
+ bbl.pages
+ pages hyphen.to.dash
+ }
+ { bbl.page pages }
+ if$
+ tie.or.space.connect
+ output
+ }
+ if$
+ ctrl.doi.bool
+ { format.doi }
+ 'skip$
+ if$
+}
+
+FUNCTION { format.pages.article } {
+ pages empty$
+ { }
+ {
+ pages hyphen.to.dash
+ output
+ }
+ if$
+ ctrl.doi.bool
+ { format.doi }
+ 'skip$
+ if$
+}
+
+FUNCTION { format.publisher.address } {
+ publisher format.group.address
+}
+
+FUNCTION { format.school.address } {
+ school
+ duplicate$
+ empty$
+ { pop$ }
+ {
+ address empty$
+ { }
+ {
+ add.comma
+ address
+ *
+ }
+ if$
+ output
+ }
+ if$
+}
+
+FUNCTION { format.title } {
+ title empty$
+ { }
+ {
+ title
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.title.article } {
+ ctrl.article.title.bool
+ {
+ title empty$
+ { }
+ {
+ title
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+ }
+ { }
+ if$
+}
+
+FUNCTION { format.title.techreport } {
+ title empty$
+ { }
+ {
+ title emph
+ output
+ next.punct.semicolon 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.title.booktitle } {
+ title empty$
+ { }
+ {
+ title
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+ booktitle empty$
+ { }
+ {
+ booktitle
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+}
+
+STRINGS {
+ book.title
+ chapter.title
+}
+
+FUNCTION { format.title.booktitle.book } {
+ "" 'chapter.title :=
+ booktitle empty$
+ {
+ "" 'chapter.title :=
+ title 'book.title :=
+ }
+ {
+ ctrl.chapter.title.bool
+ {
+ title empty$
+ 'skip$
+ { title 'chapter.title := }
+ if$
+ }
+ 'skip$
+ if$
+ maintitle empty$
+ { booktitle 'book.title := }
+ { maintitle add.period booktitle * 'book.title := }
+ if$
+ }
+ if$
+ chapter.title empty$
+ { }
+ {
+ chapter.title
+ output
+ next.punct.period 'next.punct.int :=
+ }
+ if$
+ book.title emph
+ chapter.title empty$
+ {
+ author empty$
+ { }
+ {
+ editor empty$
+ { }
+ { bbl.in add.space swap$ * }
+ if$
+ }
+ if$
+ }
+ { bbl.in add.space swap$ * }
+ if$
+ output
+}
+
+FUNCTION { format.type } {
+ type empty$
+ { }
+ {
+ pop$
+ type
+ }
+ if$
+ output
+}
+
+FUNCTION { format.type.number } {
+ type empty$
+ { }
+ {
+ type
+ number empty$
+ { }
+ { number tie.or.space.connect }
+ if$
+ output
+ }
+ if$
+}
+
+FUNCTION { format.url } {
+ url empty$
+ { }
+ {
+ "\url{" url * "}" *
+ output
+ }
+ if$
+}
+
+FUNCTION { format.year } {
+ year empty$
+ { }
+ {
+ year
+ output
+ next.punct.semicolon 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.year.article } {
+ year empty$
+ { }
+ {
+ year paren
+ output
+ next.punct.space 'next.punct.int :=
+ }
+ if$
+}
+
+FUNCTION { format.version } {
+ version empty$
+ { }
+ {
+ bbl.version add.space
+ version
+ *
+ output
+ }
+ if$
+}
+
+FUNCTION { format.volume.article } {
+ volume emph
+ output
+}
+
+FUNCTION { format.volume } {
+ volume empty$
+ { }
+ {
+ bbl.volume
+ volume
+ tie.or.space.connect
+ output
+ next.punct.semicolon 'next.punct.int :=
+ }
+ if$
+}
+
+
+FUNCTION { article } {
+ begin.bibitem
+ format.authors
+ format.year.article
+ format.title.article
+ format.journal
+ format.volume.article
+ format.pages.article
+ format.note
+ end.bibitem
+}
+
+FUNCTION { book } {
+ begin.bibitem
+ format.authors.or.editors
+ format.title.booktitle.book
+ format.edition
+ author empty$
+ { }
+ { format.editors }
+ if$
+ format.number.series
+ format.publisher.address
+ format.year
+ format.volume
+ format.chapter
+ format.pages
+ format.note
+ end.bibitem
+}
+
+FUNCTION { inbook } { book }
+
+FUNCTION { booklet } {
+ begin.bibitem
+ format.authors
+ format.title
+ format.howpublished
+ format.address
+ format.year
+ format.note
+ end.bibitem
+}
+
+FUNCTION { collection } { book }
+
+FUNCTION { incollection } { book }
+
+FUNCTION { inpress } {
+ begin.bibitem
+ format.authors
+ format.year.article
+ format.journal.unpub
+ doi empty$
+ {
+ bbl.inpress
+ output
+ }
+ {
+ next.punct.comma 'next.punct.int :=
+ format.doi
+ }
+ if$
+ format.note
+ end.bibitem
+}
+
+FUNCTION { inproceedings } {
+ begin.bibitem
+ format.authors
+ format.title.booktitle
+ format.address
+ format.year
+ format.pages
+ format.note
+ end.bibitem
+}
+
+FUNCTION { manual } {
+ begin.bibitem
+ format.authors
+ format.title
+ format.version
+ format.organization.address
+ format.year
+ format.note
+ end.bibitem
+}
+
+FUNCTION { mastersthesis } {
+ begin.bibitem
+ format.authors
+ format.title
+ bbl.msc format.type
+ format.school.address
+ format.year
+ format.note
+ end.bibitem
+}
+
+FUNCTION { misc } {
+ begin.bibitem
+ format.authors
+ format.title
+ format.howpublished
+ format.year
+ format.url
+ format.note
+ end.bibitem
+}
+
+FUNCTION { patent } {
+ begin.bibitem
+ format.authors
+ format.organization
+ format.title
+ format.type.number
+ format.year
+ format.note
+ end.bibitem
+}
+
+FUNCTION { phdthesis } {
+ begin.bibitem
+ format.authors
+ format.title
+ bbl.phd format.type
+ format.school.address
+ format.year
+ format.note
+ end.bibitem
+}
+
+FUNCTION { proceeding } {
+ begin.bibitem
+ format.title
+ format.address
+ format.year
+ format.pages
+ format.note
+ end.bibitem
+}
+
+FUNCTION { techreport } {
+ begin.bibitem
+ format.authors.or.editors
+ format.title.techreport
+ format.type.number
+ format.organization.address
+ format.year
+ format.volume
+ format.pages
+ format.note
+ end.bibitem
+}
+
+FUNCTION { unpublished } {
+ begin.bibitem
+ format.authors
+ format.journal.unpub
+ doi empty$
+ { format.howpublished }
+ {
+ format.year
+ next.punct.comma 'next.punct.int :=
+ format.doi
+ }
+ if$
+ format.note
+ end.bibitem
+}
+
+FUNCTION { default.type } { misc }
+
+
+MACRO { jan } { "Jan." }
+MACRO { feb } { "Feb." }
+MACRO { mar } { "Mar." }
+MACRO { apr } { "Apr." }
+MACRO { may } { "May" }
+MACRO { jun } { "June" }
+MACRO { jul } { "July" }
+MACRO { aug } { "Aug." }
+MACRO { sep } { "Sept." }
+MACRO { oct } { "Oct." }
+MACRO { nov } { "Nov." }
+MACRO { dec } { "Dec." }
+
+MACRO { acbcct } { "ACS Chem.\ Biol." }
+MACRO { achre4 } { "Acc.\ Chem.\ Res." }
+MACRO { acncdm } { "ACS Chem.\ Neurosci." }
+MACRO { ancac3 } { "ACS Nano" }
+MACRO { ancham } { "Anal.\ Chem." }
+MACRO { bichaw } { "Biochemistry" }
+MACRO { bcches } { "Bioconjugate Chem." }
+MACRO { bomaf6 } { "Biomacromolecules" }
+MACRO { bipret } { "Biotechnol.\ Prog." }
+MACRO { crtoec } { "Chem.\ Res.\ Toxicol." }
+MACRO { chreay } { "Chem.\ Rev." }
+MACRO { cmatex } { "Chem.\ Mater." }
+MACRO { cgdefu } { "Cryst.\ Growth Des." }
+MACRO { enfuem } { "Energy Fuels" }
+MACRO { esthag } { "Environ.\ Sci.\ Technol." }
+MACRO { iechad } { "Ind.\ Eng.\ Chem.\ Res." }
+MACRO { inoraj } { "Inorg.\ Chem." }
+MACRO { jafcau } { "J.~Agric.\ Food Chem." }
+MACRO { jceaax } { "J.~Chem.\ Eng.\ Data" }
+MACRO { jceda8 } { "J.~Chem.\ Ed." }
+MACRO { jcisd8 } { "J.~Chem.\ Inf.\ Model." }
+MACRO { jctcce } { "J.~Chem.\ Theory Comput." }
+MACRO { jcchff } { "J. Comb. Chem." }
+MACRO { jmcmar } { "J. Med. Chem." }
+MACRO { jnprdf } { "J. Nat. Prod." }
+MACRO { joceah } { "J.~Org.\ Chem." }
+MACRO { jpcafh } { "J.~Phys.\ Chem.~A" }
+MACRO { jpcbfk } { "J.~Phys.\ Chem.~B" }
+MACRO { jpccck } { "J.~Phys.\ Chem.~C" }
+MACRO { jpclcd } { "J.~Phys.\ Chem.\ Lett." }
+MACRO { jprobs } { "J.~Proteome Res." }
+MACRO { jacsat } { "J.~Am.\ Chem.\ Soc." }
+MACRO { langd5 } { "Langmuir" }
+MACRO { mamobx } { "Macromolecules" }
+MACRO { mpohbp } { "Mol.\ Pharm." }
+MACRO { nalefd } { "Nano Lett." }
+MACRO { orlef7 } { "Org.\ Lett." }
+MACRO { oprdfk } { "Org.\ Proc.\ Res.\ Dev." }
+MACRO { orgnd7 } { "Organometallics" }
+
+
+READ
+
+EXECUTE { initialize.control.values }
+
+EXECUTE { initialize.count.entries }
+
+EXECUTE { initialize.name.separator }
+
+EXECUTE { initialize.tracker }
+
+ITERATE { calculate.names }
+
+ITERATE { count.entries }
+
+EXECUTE { begin.bib }
+
+ITERATE { call.type$ }
+
+EXECUTE { end.bib }
+%%
+%% Originally developed by Mats Dahlgren
+%% Copyright (C) 1996-1998 by Mats Dahlgren
+%% Copyright (C) 2008-2022 by
+%% Joseph Wright
+%%
+%% Part of this bundle is derived from cite.sty, to which the
+%% following license applies:
+%% Copyright (C) 1989-2009 by Donald Arseneau
+%% These macros may be freely transmitted, reproduced, or
+%% modified provided that this notice is left intact.
+%%
+%% It may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License (LPPL), either version 1.3c of
+%% this license or (at your option) any later version. The latest
+%% version of this license is in the file:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% This work is "maintained" (as per LPPL maintenance status) by
+%% Joseph Wright.
+%%
+%% This work consists of the files achemso.dtx,
+%% achemso-demo.bib and
+%% achemso-demo.tex,
+%% and the derived files achemso.cls,
+%% achemso.ins,
+%% achemso.pdf,
+%% achemso.sty,
+%% natmove.sty and
+%% a number of configuration files.
+%%
+%%
+%% End of file `biochem.bst'.
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/doc-class.tex b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/doc-class.tex
index e87a259f450..988de810306 100644
--- a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/doc-class.tex
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/doc-class.tex
@@ -1,4 +1,5 @@
-\documentclass[journal=$journal$,manuscript=$type$]{achemso}
+\documentclass[journal=$journal.id$,manuscript=$journal.type$$if(journal.layout)$,layout=$journal.layout$$endif$$if(journal.hide-email)$,email=false$endif$]{achemso}
\usepackage[version=3]{mhchem}
-\usepackage{amsmath}
-\newcommand*\mycommand[1]{\texttt{\emph{#1}}}
\ No newline at end of file
+\newcommand*\mycommand[1]{\texttt{\emph{#1}}}
+
+
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/title.tex b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/title.tex
index 5af0f7b7bf3..5ebf2c22879 100644
--- a/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/title.tex
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/acs/title.tex
@@ -3,21 +3,20 @@
$if(by-author.affiliations)$
$if(by-author.affiliations/first)$
$for(by-author.affiliations/first)$
-\affiliation{$print-affiliation.tex()$}
+\affiliation{$_affiliation.tex()$}
$endfor$
$if(by-author.affiliations/rest/first)$
$for(by-author.affiliations/rest/first)$
-\alsoaffiliation{$print-affiliation.tex()$}
+\affiliation{$_affiliation.tex()$}
$endfor$
$endif$
-$if(by-author.affiliations/rest/rest/first)$
-$for(by-author.affiliations/rest/rest/first)$
-\altaffiliation{$print-affiliation.tex()$}
-$endfor$
$endif$
$endif$
+$if(by-author.note.text)$
+\altaffiliation{$by-author.note.text$}
$endif$
+
$if(by-author.email)$
\email{$by-author.email$}
$endif$
@@ -30,12 +29,12 @@
$endfor$
$if(abbr)$
-\abbreviations{$abbr$}
+\abbreviations{$journal.abbreviations$}
$endif$
$if(keywords)$
\keywords{$keywords$}
$endif$
-\title[$title-short$]{$title-formatted$}
+\title[$title-short$]{$title$}
\makeatletter
\ No newline at end of file
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/_extension.yml b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/_extension.yml
index 7303bc88d8d..fbacb40c8b2 100644
--- a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/_extension.yml
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/_extension.yml
@@ -1,11 +1,19 @@
-name: Elsevier Journal Format
+title: Elsevier Journal Format
+author: Charles Teague
+version: 0.4.5
+quarto-required: ">=1.2.198"
contributes:
formats:
common:
date-format: full
+ filters:
+ - elsevier.lua
pdf:
+ documentclass: elsarticle
+ template-partials: ["partials/before-body.tex", "partials/title.tex"]
+ format-resources:
+ - elsarticle.cls
cite-method: natbib
- template-partials:
- [before-body.tex, doc-class.tex, title.tex, elsarticle.cls]
- classoption: preprint, 3p, authoryear
number-sections: true
+ html:
+ theme: styles/elsevier.scss
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/before-body.tex b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/before-body.tex
deleted file mode 100644
index e7545712f8e..00000000000
--- a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/before-body.tex
+++ /dev/null
@@ -1,29 +0,0 @@
-
-\begin{frontmatter}
-
- \title{$title$}
- $for(by-author)$\author[$for(by-author.affiliations)$$it.number$$endfor$]{$by-author.name.literal$%
- $if(by-author.attributes.corresponding)$\corref{cor1}$endif$%
- $if(by-author.note.text)$\fnref{fn$by-author.note.number$}$endif$}
- $if(by-author.email)$ \ead{$by-author.email$} $endif$
- $endfor$
- $for(by-affiliation)$
- \affiliation[$it.number$]{$it.name$ $it.address$ $it.city$ $it.region$ $it.postal-code$}
- $endfor$
- \cortext[cor1]{Corresponding author}
- $for(by-author)$
- $if(by-author.note.text)$\fntext[fn$by-author.note.number$]{$by-author.note.text$}$endif$
- $endfor$
-
- \begin{abstract}
- $abstract$
- \end{abstract}
- $if(keywords)$
- \begin{keyword}
- $for(keywords/allbutlast)$$keywords$ \sep $endfor$
- $for(keywords/last)$$keywords$$endfor$
- \end{keyword}
- $endif$
-
-
-\end{frontmatter}
\ No newline at end of file
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsarticle-harv.bst b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsarticle-harv.bst
new file mode 100644
index 00000000000..ca105f27467
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsarticle-harv.bst
@@ -0,0 +1,1598 @@
+%%
+%% This is file `elsarticle-harv.bst' (Version 2.1),
+%%
+%% Copyright 2009-2025 Elsevier Ltd
+%%
+%% This file is part of the 'Elsarticle Bundle'.
+%% ---------------------------------------------
+%%
+%% It may be distributed under the conditions of the LaTeX Project Public
+%% License, either version 1.3 of this license or (at your option) any
+%% later version. The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 1999/12/01 or later.
+%%
+%% $Id: elsarticle-harv.bst 271 2025-01-09 17:33:11Z rishi $
+%%
+%% $URL: https://lenova.river-valley.com/svn/elsarticle/trunk/elsarticle-harv.bst $
+%%
+
+ENTRY
+ { address
+ archive
+ author
+ booktitle
+ chapter
+ collaboration
+ edition
+ editor
+ howpublished
+ institution
+ journal
+ key
+ month
+ note
+ number
+ organization
+ pages
+ publisher
+ school
+ series
+ title
+ type
+ volume
+ year
+ url
+ doi
+ eprint
+ pubmed
+ }
+ {}
+ { label extra.label sort.label short.list }
+
+INTEGERS { output.state before.all mid.sentence after.sentence after.block }
+
+STRINGS { urlprefix doiprefix eprintprefix pubmedprefix }
+
+FUNCTION {init.web.variables}
+{
+ "\URLprefix " 'urlprefix :=
+ "\DOIprefix" 'doiprefix :=
+ "\ArXivprefix " 'eprintprefix :=
+ "\Pubmedprefix " 'pubmedprefix :=
+}
+
+FUNCTION {init.state.consts}
+{ #0 'before.all :=
+ #1 'mid.sentence :=
+ #2 'after.sentence :=
+ #3 'after.block :=
+}
+STRINGS { s t}
+FUNCTION {output.comma}
+{ ", " * write$}
+
+FUNCTION {output.nonnull}
+{ 's :=
+ output.state mid.sentence =
+ { ". " * write$ }
+ { output.state after.block =
+ { add.period$ write$
+ newline$
+ "\newblock " write$
+ }
+ { output.state before.all =
+ 'write$
+ { ", " * write$ }
+ if$
+ }
+ if$
+ mid.sentence 'output.state :=
+ }
+ if$
+ s
+}
+FUNCTION {output.commanull}
+{ 's :=
+ output.state mid.sentence =
+ { ", " * write$ }
+ { output.state after.block =
+ { ", " * write$
+ newline$
+ "\newblock " write$
+ }
+ { output.state before.all =
+ 'write$
+ { add.period$ " " * write$ }
+ if$
+ }
+ if$
+ mid.sentence 'output.state :=
+ }
+ if$
+ s
+}
+FUNCTION {output}
+{ duplicate$ empty$
+ 'pop$
+ 'output.nonnull
+ if$
+}
+FUNCTION {output.check}
+{ 't :=
+ duplicate$ empty$
+ { pop$ "empty " t * " in " * cite$ * warning$ }
+ 'output.nonnull
+ if$
+}
+FUNCTION {output.book.check}
+{ 't :=
+ duplicate$ empty$
+ { pop$ "empty " t * " in " * cite$ * warning$ }
+ 'output.nonnull
+ if$
+}
+FUNCTION {fin.entry}
+{ add.period$
+ write$
+ newline$
+}
+
+FUNCTION {new.block}
+{ output.state before.all =
+ 'skip$
+ { after.block 'output.state := }
+ if$
+}
+FUNCTION {new.sentence}
+{ output.state after.block =
+ 'skip$
+ { output.state before.all =
+ 'skip$
+ { after.sentence 'output.state := }
+ if$
+ }
+ if$
+}
+FUNCTION {add.blank}
+{ " " * before.all 'output.state :=
+}
+
+FUNCTION {date.block}
+{
+ new.block
+}
+
+FUNCTION {not}
+{ { #0 }
+ { #1 }
+ if$
+}
+FUNCTION {and}
+{ 'skip$
+ { pop$ #0 }
+ if$
+}
+FUNCTION {or}
+{ { pop$ #1 }
+ 'skip$
+ if$
+}
+FUNCTION {new.block.checkb}
+{ empty$
+ swap$ empty$
+ and
+ 'skip$
+ 'new.block
+ if$
+}
+FUNCTION {field.or.null}
+{ duplicate$ empty$
+ { pop$ "" }
+ 'skip$
+ if$
+}
+FUNCTION {emphasize}
+{ duplicate$ empty$
+ { pop$ "" }
+ { "\textit{" swap$ * "}" * }
+ if$
+}
+FUNCTION {tie.or.space.prefix}
+{ duplicate$ text.length$ #3 <
+ { "~" }
+ { " " }
+ if$
+ swap$
+}
+
+FUNCTION {capitalize}
+{ "u" change.case$ "t" change.case$ }
+
+FUNCTION {space.word}
+{ " " swap$ * " " * }
+ % Here are the language-specific definitions for explicit words.
+ % Each function has a name bbl.xxx where xxx is the English word.
+ % The language selected here is ENGLISH
+FUNCTION {bbl.and}
+{ "and"}
+
+FUNCTION {bbl.etal}
+{ "et~al." }
+
+FUNCTION {bbl.editors}
+{ "Eds." }
+
+FUNCTION {bbl.editor}
+{ "Ed." }
+
+FUNCTION {bbl.edby}
+{ "edited by" }
+
+FUNCTION {bbl.edition}
+{ "ed." }
+
+FUNCTION {bbl.volume}
+{ "volume" }
+
+FUNCTION {bbl.of}
+{ "of" }
+
+FUNCTION {bbl.number}
+{ "number" }
+
+FUNCTION {bbl.nr}
+{ "no." }
+
+FUNCTION {bbl.in}
+{ "in" }
+
+FUNCTION {bbl.pages}
+{ "pp." }
+
+FUNCTION {bbl.page}
+{ "p." }
+
+FUNCTION {bbl.chapter}
+{ "chapter" }
+
+FUNCTION {bbl.techrep}
+{ "Technical Report" }
+
+FUNCTION {bbl.mthesis}
+{ "Master's thesis" }
+
+FUNCTION {bbl.phdthesis}
+{ "Ph.D. thesis" }
+
+MACRO {jan} {"January"}
+
+MACRO {feb} {"February"}
+
+MACRO {mar} {"March"}
+
+MACRO {apr} {"April"}
+
+MACRO {may} {"May"}
+
+MACRO {jun} {"June"}
+
+MACRO {jul} {"July"}
+
+MACRO {aug} {"August"}
+
+MACRO {sep} {"September"}
+
+MACRO {oct} {"October"}
+
+MACRO {nov} {"November"}
+
+MACRO {dec} {"December"}
+
+MACRO {acmcs} {"ACM Comput. Surv."}
+
+MACRO {acta} {"Acta Inf."}
+
+MACRO {cacm} {"Commun. ACM"}
+
+MACRO {ibmjrd} {"IBM J. Res. Dev."}
+
+MACRO {ibmsj} {"IBM Syst.~J."}
+
+MACRO {ieeese} {"IEEE Trans. Software Eng."}
+
+MACRO {ieeetc} {"IEEE Trans. Comput."}
+
+MACRO {ieeetcad}
+ {"IEEE Trans. Comput. Aid. Des."}
+
+MACRO {ipl} {"Inf. Process. Lett."}
+
+MACRO {jacm} {"J.~ACM"}
+
+MACRO {jcss} {"J.~Comput. Syst. Sci."}
+
+MACRO {scp} {"Sci. Comput. Program."}
+
+MACRO {sicomp} {"SIAM J. Comput."}
+
+MACRO {tocs} {"ACM Trans. Comput. Syst."}
+
+MACRO {tods} {"ACM Trans. Database Syst."}
+
+MACRO {tog} {"ACM Trans. Graphic."}
+
+MACRO {toms} {"ACM Trans. Math. Software"}
+
+MACRO {toois} {"ACM Trans. Office Inf. Syst."}
+
+MACRO {toplas} {"ACM Trans. Progr. Lang. Syst."}
+
+MACRO {tcs} {"Theor. Comput. Sci."}
+
+FUNCTION {bibinfo.check}
+{ swap$
+ duplicate$ missing$
+ {
+ pop$ pop$
+ ""
+ }
+ { duplicate$ empty$
+ {
+ swap$ pop$
+ }
+ { swap$
+ "\bibinfo{" swap$ * "}{" * swap$ * "}" *
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {bibinfo.warn}
+{ swap$
+ duplicate$ missing$
+ {
+ swap$ "missing " swap$ * " in " * cite$ * warning$ pop$
+ ""
+ }
+ { duplicate$ empty$
+ {
+ swap$ "empty " swap$ * " in " * cite$ * warning$
+ }
+ { swap$
+ pop$
+ }
+ if$
+ }
+ if$
+}
+
+STRINGS { bibinfo}
+
+INTEGERS { nameptr namesleft numnames }
+
+FUNCTION {format.names}
+{ 'bibinfo :=
+ duplicate$ empty$ 'skip$ {
+ 's :=
+ "" 't :=
+ #1 'nameptr :=
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{vv~}{ll}{, jj}{, f{.}.}"
+ format.name$
+ bibinfo bibinfo.check
+ 't :=
+ nameptr #1 >
+ {
+ namesleft #1 >
+ { ", " * t * }
+ {
+ "," *
+ s nameptr "{ll}" format.name$ duplicate$ "others" =
+ { 't := }
+ { pop$ }
+ if$
+ t "others" =
+ {
+ " " * bbl.etal *
+ }
+ { " " * t * }
+ if$
+ }
+ if$
+ }
+ 't
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+ } if$
+}
+FUNCTION {format.names.ed}
+{
+ format.names
+}
+FUNCTION {format.key}
+{ empty$
+ { key field.or.null }
+ { "" }
+ if$
+}
+
+FUNCTION {format.authors}
+{ author "author" format.names
+ duplicate$ empty$ 'skip$
+ { collaboration "collaboration" bibinfo.check
+ duplicate$ empty$ 'skip$
+ { " (" swap$ * ")" * }
+ if$
+ *
+ }
+ if$
+}
+
+FUNCTION {get.bbl.editor}
+{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ }
+
+FUNCTION {format.editors}
+{ editor "editor" format.names duplicate$ empty$ 'skip$
+ {
+ " " *
+ get.bbl.editor
+ capitalize
+ "(" swap$ * ")" *
+ *
+ }
+ if$
+}
+FUNCTION {format.note}
+{
+ note empty$
+ { "" }
+ { note #1 #1 substring$
+ duplicate$ "{" =
+ 'skip$
+ { output.state mid.sentence =
+ { "l" }
+ { "u" }
+ if$
+ change.case$
+ }
+ if$
+ note #2 global.max$ substring$ * "note" bibinfo.check
+ }
+ if$
+}
+
+FUNCTION {format.title}
+{ title
+ duplicate$ empty$ 'skip$
+ { "t" change.case$ }
+ if$
+ "title" bibinfo.check
+}
+FUNCTION {format.full.names}
+{'s :=
+ "" 't :=
+ #1 'nameptr :=
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{vv~}{ll}" format.name$
+ 't :=
+ nameptr #1 >
+ {
+ namesleft #1 >
+ { ", " * t * }
+ {
+ s nameptr "{ll}" format.name$ duplicate$ "others" =
+ { 't := }
+ { pop$ }
+ if$
+ t "others" =
+ {
+ " " * bbl.etal *
+ }
+ {
+ bbl.and
+ space.word * t *
+ }
+ if$
+ }
+ if$
+ }
+ 't
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+}
+
+FUNCTION {author.editor.key.full}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.full.names }
+ if$
+ }
+ { author format.full.names }
+ if$
+}
+
+FUNCTION {author.key.full}
+{ author empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { author format.full.names }
+ if$
+}
+
+FUNCTION {editor.key.full}
+{ editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.full.names }
+ if$
+}
+
+FUNCTION {make.full.names}
+{ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.key.full
+ { type$ "proceedings" =
+ 'editor.key.full
+ 'author.key.full
+ if$
+ }
+ if$
+}
+
+FUNCTION {output.bibitem}
+{ newline$
+ "\bibitem[{" write$
+ label write$
+ ")" make.full.names duplicate$ short.list =
+ { pop$ }
+ { * }
+ if$
+ "}]{" * write$
+ cite$ write$
+ "}" write$
+ newline$
+ ""
+ before.all 'output.state :=
+}
+
+FUNCTION {n.dashify}
+{
+ 't :=
+ ""
+ { t empty$ not }
+ { t #1 #1 substring$ "-" =
+ { t #1 #2 substring$ "--" = not
+ { "--" *
+ t #2 global.max$ substring$ 't :=
+ }
+ { { t #1 #1 substring$ "-" = }
+ { "-" *
+ t #2 global.max$ substring$ 't :=
+ }
+ while$
+ }
+ if$
+ }
+ { t #1 #1 substring$ *
+ t #2 global.max$ substring$ 't :=
+ }
+ if$
+ }
+ while$
+}
+
+FUNCTION {word.in}
+{ bbl.in %capitalize
+ ":" *
+ " " * }
+
+FUNCTION {format.date}
+{ year "year" bibinfo.check duplicate$ empty$
+ {
+ }
+ 'skip$
+ if$
+ extra.label *
+ before.all 'output.state :=
+ ", " swap$ *
+}
+FUNCTION {format.btitle}
+{ title "title" bibinfo.check
+ duplicate$ empty$ 'skip$
+ {
+ }
+ if$
+}
+FUNCTION {either.or.check}
+{ empty$
+ 'pop$
+ { "can't use both " swap$ * " fields in " * cite$ * warning$ }
+ if$
+}
+FUNCTION {format.bvolume}
+{ volume empty$
+ { "" }
+ { bbl.volume volume tie.or.space.prefix
+ "volume" bibinfo.check * *
+ series "series" bibinfo.check
+ duplicate$ empty$ 'pop$
+ { swap$ bbl.of space.word * swap$
+ emphasize * }
+ if$
+ "volume and number" number either.or.check
+ }
+ if$
+}
+FUNCTION {format.number.series}
+{ volume empty$
+ { number empty$
+ { series field.or.null }
+ { series empty$
+ { number "number" bibinfo.check }
+ { output.state mid.sentence =
+ { bbl.number }
+ { bbl.number capitalize }
+ if$
+ number tie.or.space.prefix "number" bibinfo.check * *
+ bbl.in space.word *
+ series "series" bibinfo.check *
+ }
+ if$
+ }
+ if$
+ }
+ { "" }
+ if$
+}
+
+FUNCTION {format.edition}
+{ edition duplicate$ empty$ 'skip$
+ {
+ output.state mid.sentence =
+ { "l" }
+ { "t" }
+ if$ change.case$
+ "edition" bibinfo.check
+ " " * bbl.edition *
+ }
+ if$
+}
+INTEGERS { multiresult }
+FUNCTION {multi.page.check}
+{ 't :=
+ #0 'multiresult :=
+ { multiresult not
+ t empty$ not
+ and
+ }
+ { t #1 #1 substring$
+ duplicate$ "-" =
+ swap$ duplicate$ "," =
+ swap$ "+" =
+ or or
+ { #1 'multiresult := }
+ { t #2 global.max$ substring$ 't := }
+ if$
+ }
+ while$
+ multiresult
+}
+%FUNCTION {format.pages}
+%{ pages duplicate$ empty$ 'skip$
+% { duplicate$ multi.page.check
+% {
+% n.dashify
+% }
+% {
+% }
+% if$
+% "pages" bibinfo.check
+% }
+% if$
+%}
+
+FUNCTION {format.pages}
+{ pages duplicate$ empty$ 'skip$
+ { duplicate$ multi.page.check
+ {
+ bbl.pages swap$
+ n.dashify
+ }
+ {
+ bbl.page swap$
+ }
+ if$
+ tie.or.space.prefix
+ "pages" bibinfo.check
+ * *
+ }
+ if$
+}
+
+FUNCTION {format.journal.pages}
+{ pages duplicate$ empty$ 'pop$
+ { swap$ duplicate$ empty$
+ { pop$ pop$ format.pages }
+ {
+ ", " *
+ swap$
+ n.dashify
+ "pages" bibinfo.check
+ *
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.vol.num.pages}
+{ volume field.or.null
+ duplicate$ empty$ 'skip$
+ {
+ "volume" bibinfo.check
+ }
+ if$
+}
+
+FUNCTION {format.chapter.pages}
+{ chapter empty$
+ { "" }
+ { type empty$
+ { bbl.chapter }
+ { type "l" change.case$
+ "type" bibinfo.check
+ }
+ if$
+ chapter tie.or.space.prefix
+ "chapter" bibinfo.check
+ * *
+ }
+ if$
+}
+
+FUNCTION {format.booktitle}
+{
+ booktitle "booktitle" bibinfo.check
+}
+FUNCTION {format.in.ed.booktitle}
+{ format.booktitle duplicate$ empty$ 'skip$
+ {
+ editor "editor" format.names.ed duplicate$ empty$ 'pop$
+ {
+ " " *
+ get.bbl.editor
+ capitalize
+ "(" swap$ * "), " *
+ * swap$
+ * }
+ if$
+ word.in swap$ *
+ }
+ if$
+}
+FUNCTION {format.thesis.type}
+{ type duplicate$ empty$
+ 'pop$
+ { swap$ pop$
+ "t" change.case$ "type" bibinfo.check
+ }
+ if$
+}
+FUNCTION {format.tr.number}
+{ number "number" bibinfo.check
+ type duplicate$ empty$
+ { pop$ bbl.techrep }
+ 'skip$
+ if$
+ "type" bibinfo.check
+ swap$ duplicate$ empty$
+ { pop$ "t" change.case$ }
+ { tie.or.space.prefix * * }
+ if$
+}
+FUNCTION {format.article.crossref}
+{
+ word.in
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.book.crossref}
+{ volume duplicate$ empty$
+ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
+ pop$ word.in
+ }
+ { bbl.volume
+ capitalize
+ swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word *
+ }
+ if$
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.incoll.inproc.crossref}
+{
+ word.in
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.org.or.pub}
+{ 't :=
+ ""
+ address empty$ t empty$ and
+ 'skip$
+ {
+ t empty$
+ { address "address" bibinfo.check *
+ }
+ { t *
+ address empty$
+ 'skip$
+ { ", " * address "address" bibinfo.check * }
+ if$
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.publisher.address}
+{ publisher "publisher" bibinfo.check format.org.or.pub
+}
+
+FUNCTION {format.organization.address}
+{ organization "organization" bibinfo.check format.org.or.pub
+}
+
+FUNCTION {print.url}
+ {url duplicate$ empty$
+ { pop$ "" }
+ { new.sentence
+ urlprefix "\url{" * swap$ * "}" *
+ }
+ if$
+ }
+
+FUNCTION {print.doi}
+ {doi duplicate$ empty$
+ { pop$ "" }
+ { new.sentence
+ doiprefix "\doi{" * swap$ * "}" *
+ }
+ if$
+ }
+
+FUNCTION {print.eprint}
+ {eprint duplicate$ empty$
+ { pop$ "" }
+ { new.sentence
+ duplicate$ "\href{http://arxiv.org/abs/" swap$ * "}{{\tt arXiv:" * swap$ * "}}" * }
+ if$
+ }
+
+FUNCTION {print.pubmed}
+ {pubmed duplicate$ empty$
+ { pop$ "" }
+ { new.sentence
+ pubmedprefix "\Pubmed{" * swap$ * "}" *
+ }
+ if$
+ }
+
+FUNCTION {webpage}
+{ "%Type = Webpage" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ author empty$
+ {
+ format.title "title" output.check
+ new.block
+ format.date "year" output.check
+ date.block
+ }
+ {
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+}
+ if$
+ print.url output
+ fin.entry
+}
+
+
+FUNCTION {article}
+{ "%Type = Article" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ {
+ journal
+ "journal" bibinfo.check
+ "journal" output.check
+ add.blank
+ format.vol.num.pages output
+ }
+ { format.article.crossref output.nonnull
+ }
+ if$
+ format.journal.pages
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {book}
+{ "%Type = Book" write$
+ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check
+ editor format.key output
+ }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ crossref missing$
+ { format.bvolume output
+ new.block
+ format.number.series output
+ format.edition output
+ new.sentence
+ format.publisher.address output
+ }
+ {
+ new.block
+ format.book.crossref output.nonnull
+ }
+ if$
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {booklet}
+{ "%Type = Booklet" write$
+ output.bibitem
+ format.authors output
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+ howpublished "howpublished" bibinfo.check output
+ address "address" bibinfo.check output
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {inbook}
+{ "%Type = Inbook" write$
+ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check
+ editor format.key output
+ }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ format.edition output
+ crossref missing$
+ {
+ format.publisher.address output
+ format.bvolume output
+ format.chapter.pages "chapter and pages" output.check
+ new.block
+ format.number.series output
+ new.sentence
+ }
+ {
+ format.chapter.pages "chapter and pages" output.check
+ new.block
+ format.book.crossref output.nonnull
+ }
+ if$
+ format.pages "pages" output.check
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {incollection}
+{ "%Type = Incollection" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title "title" output.book.check
+ new.sentence
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.book.check
+ format.edition output
+ format.publisher.address output
+ format.bvolume output
+ format.number.series output
+ format.chapter.pages output
+ new.sentence
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ format.chapter.pages output
+ }
+ if$
+ format.pages "pages" output.check
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {inproceedings}
+{ "%Type = Inproceedings" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title "title" output.book.check
+ new.sentence
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ new.sentence
+ publisher empty$
+ { format.organization.address output }
+ { organization "organization" bibinfo.check output
+ format.publisher.address output
+ }
+ if$
+% format.bvolume output
+% format.number.series output
+% format.pages output
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ format.pages output
+ }
+ if$
+ format.pages "pages" output.check
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {conference} { inproceedings }
+
+FUNCTION {manual}
+{ "%Type = Manual" write$
+ output.bibitem
+ format.authors output
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ format.edition output
+ organization address new.block.checkb
+ organization "organization" bibinfo.check output
+ address "address" bibinfo.check output
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {mastersthesis}
+{ "%Type = Masterthesis" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.btitle
+ "title" output.check
+ new.block
+ bbl.mthesis format.thesis.type output.nonnull
+ school "school" bibinfo.warn output
+ address "address" bibinfo.check output
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {misc}
+{ "%Type = Misc" write$
+ output.bibitem
+ format.authors output
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title output
+ new.block
+ howpublished "howpublished" bibinfo.check output
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {phdthesis}
+{ "%Type = Phdthesis" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.btitle
+ "title" output.check
+ new.block
+ bbl.phdthesis format.thesis.type output.nonnull
+ school "school" bibinfo.warn output
+ address "address" bibinfo.check output
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {proceedings}
+{ "%Type = Proceedings" write$
+ output.bibitem
+ format.editors output
+ editor format.key output
+ format.date "year" output.check
+ date.block
+ format.btitle "title" output.check
+ format.bvolume output
+ format.number.series output
+ new.sentence
+ publisher empty$
+ { format.organization.address output }
+ { organization "organization" bibinfo.check output
+ format.publisher.address output
+ }
+ if$
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {techreport}
+{ "%Type = Techreport" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.btitle
+ "title" output.check
+ new.block
+ format.tr.number output.nonnull
+ institution "institution" bibinfo.warn output
+ address "address" bibinfo.check output
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {unpublished}
+{ "%Type = Unpublished" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note "note" output.check
+ fin.entry
+}
+
+FUNCTION {default.type} { misc }
+READ
+FUNCTION {sortify}
+{ purify$
+ "l" change.case$
+}
+INTEGERS { len }
+FUNCTION {chop.word}
+{ 's :=
+ 'len :=
+ s #1 len substring$ =
+ { s len #1 + global.max$ substring$ }
+ 's
+ if$
+}
+FUNCTION {format.lab.names}
+{ 's :=
+ "" 't :=
+ s #1 "{vv~}{ll}" format.name$
+ s num.names$ duplicate$
+ #2 >
+ { pop$
+ " " * bbl.etal *
+ }
+ { #2 <
+ 'skip$
+ { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
+ {
+ " " * bbl.etal *
+ }
+ { bbl.and space.word * s #2 "{vv~}{ll}" format.name$
+ * }
+ if$
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION {author.key.label}
+{ author empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { author format.lab.names }
+ if$
+}
+
+FUNCTION {author.editor.key.label}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.lab.names }
+ if$
+ }
+ { author format.lab.names }
+ if$
+}
+
+FUNCTION {editor.key.label}
+{ editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.lab.names }
+ if$
+}
+
+FUNCTION {calc.short.authors}
+{ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.key.label
+ { type$ "proceedings" =
+ 'editor.key.label
+ 'author.key.label
+ if$
+ }
+ if$
+ 'short.list :=
+}
+
+FUNCTION {calc.label}
+{ calc.short.authors
+ short.list
+ "("
+ *
+ year duplicate$ empty$
+ short.list key field.or.null = or
+ { pop$ "" }
+ 'skip$
+ if$
+ *
+ 'label :=
+}
+
+FUNCTION {sort.format.names}
+{ 's :=
+ #1 'nameptr :=
+ ""
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{ll{ }}{ f{ }}{ jj{ }}"
+ format.name$ 't :=
+ nameptr #1 >
+ {
+ " " *
+ namesleft #1 = t "others" = and
+ { "zzzzz" * }
+ { t sortify * }
+ if$
+ }
+ { t sortify * }
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+}
+
+FUNCTION {sort.format.title}
+{ 't :=
+ "A " #2
+ "An " #3
+ "The " #4 t chop.word
+ chop.word
+ chop.word
+ sortify
+ #1 global.max$ substring$
+}
+FUNCTION {author.sort}
+{ author empty$
+ { key empty$
+ { "to sort, need author or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+FUNCTION {author.editor.sort}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { "to sort, need author, editor, or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { editor sort.format.names }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+FUNCTION {editor.sort}
+{ editor empty$
+ { key empty$
+ { "to sort, need editor or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { editor sort.format.names }
+ if$
+}
+FUNCTION {presort}
+{ calc.label
+ label sortify
+ " "
+ *
+ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.sort
+ { type$ "proceedings" =
+ 'editor.sort
+ 'author.sort
+ if$
+ }
+ if$
+ #1 entry.max$ substring$
+ 'sort.label :=
+ sort.label
+ *
+ " "
+ *
+ title field.or.null
+ sort.format.title
+ *
+ #1 entry.max$ substring$
+ 'sort.key$ :=
+}
+
+ITERATE {presort}
+SORT
+STRINGS { last.label next.extra }
+INTEGERS { last.extra.num number.label }
+FUNCTION {initialize.extra.label.stuff}
+{ #0 int.to.chr$ 'last.label :=
+ "" 'next.extra :=
+ #0 'last.extra.num :=
+ #0 'number.label :=
+}
+FUNCTION {forward.pass}
+{ last.label label =
+ { last.extra.num #1 + 'last.extra.num :=
+ last.extra.num int.to.chr$ 'extra.label :=
+ }
+ { "a" chr.to.int$ 'last.extra.num :=
+ "" 'extra.label :=
+ label 'last.label :=
+ }
+ if$
+ number.label #1 + 'number.label :=
+}
+FUNCTION {reverse.pass}
+{ next.extra "b" =
+ { "a" 'extra.label := }
+ 'skip$
+ if$
+ extra.label 'next.extra :=
+ extra.label
+ duplicate$ empty$
+ 'skip$
+% { "{\natexlab{" swap$ * "}}" * }
+ { "" swap$ * "" * }
+ if$
+ 'extra.label :=
+ label extra.label * 'label :=
+}
+EXECUTE {initialize.extra.label.stuff}
+ITERATE {forward.pass}
+REVERSE {reverse.pass}
+FUNCTION {bib.sort.order}
+{ sort.label
+ " "
+ *
+ year field.or.null sortify
+ *
+ " "
+ *
+ title field.or.null
+ sort.format.title
+ *
+ #1 entry.max$ substring$
+ 'sort.key$ :=
+}
+ITERATE {bib.sort.order}
+SORT
+FUNCTION {begin.bib}
+{ preamble$ empty$
+ 'skip$
+ { preamble$ write$ newline$ }
+ if$
+ "\begin{thebibliography}{" number.label int.to.str$ * "}" *
+ write$ newline$
+ "\expandafter\ifx\csname natexlab\endcsname\relax\def\natexlab#1{#1}\fi"
+ write$ newline$
+ "\providecommand{\url}[1]{\texttt{#1}}"
+ write$ newline$
+ "\providecommand{\href}[2]{#2}"
+ write$ newline$
+ "\providecommand{\path}[1]{#1}"
+ write$ newline$
+ "\providecommand{\DOIprefix}{doi:}"
+ write$ newline$
+ "\providecommand{\ArXivprefix}{arXiv:}"
+ write$ newline$
+ "\providecommand{\URLprefix}{URL: }"
+ write$ newline$
+ "\providecommand{\Pubmedprefix}{pmid:}"
+ write$ newline$
+ "\providecommand{\doi}[1]{\href{http://dx.doi.org/#1}{\path{#1}}}"
+ write$ newline$
+ "\providecommand{\Pubmed}[1]{\href{pmid:#1}{\path{#1}}}"
+ write$ newline$
+ "\providecommand{\bibinfo}[2]{#2}"
+ write$ newline$
+ "\ifx\xfnm\relax \def\xfnm[#1]{\unskip,\space#1}\fi"
+ write$ newline$
+}
+EXECUTE {begin.bib}
+EXECUTE {init.state.consts}
+EXECUTE {init.web.variables}
+ITERATE {call.type$}
+FUNCTION {end.bib}
+{ newline$
+ "\end{thebibliography}" write$ newline$
+}
+EXECUTE {end.bib}
+%% End of customized bst file
+%%
+%% End of file `elsarticle-harv.bst'.
+%%
+%% Change log:
+%% -----------
+%% 22.04.2011
+%%
+%% 10.08.2012
+%% a. doi, url, eprint, pmid added
+%% b. Bibtype `webpage' defined
+%%
+%% 30.08.2012
+%% a. collaboration added.
+%%
+
+
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsarticle-num-names.bst b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsarticle-num-names.bst
new file mode 100644
index 00000000000..93c56a25fe1
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsarticle-num-names.bst
@@ -0,0 +1,1535 @@
+%%
+%% This is file `elsarticle-num-names.bst' (Version 2.1),
+%%
+%% Copyright 2009-2025 Elsevier Ltd
+%%
+%% This file is part of the 'Elsarticle Bundle'.
+%% ---------------------------------------------
+%%
+%% It may be distributed under the conditions of the LaTeX Project Public
+%% License, either version 1.3 of this license or (at your option) any
+%% later version. The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 1999/12/01 or later.
+%%
+%% $Id: elsarticle-num-names.bst 272 2025-01-09 17:36:26Z rishi $
+%%
+%% $URL: https://lenova.river-valley.com/svn/elsarticle/trunk/elsarticle-num-names.bst $
+%%
+%%
+
+ENTRY
+ { address
+ author
+ booktitle
+ chapter
+ collaboration
+ edition
+ editor
+ howpublished
+ institution
+ journal
+ key
+ month
+ note
+ number
+ organization
+ pages
+ publisher
+ school
+ series
+ title
+ type
+ volume
+ year
+ url
+ doi
+ eprint
+ pubmed
+ }
+ {}
+ { label extra.label sort.label short.list }
+
+INTEGERS { output.state before.all mid.sentence after.sentence after.block }
+
+STRINGS { urlprefix doiprefix eprintprefix pubmedprefix }
+
+FUNCTION {init.web.variables}
+{
+ "\URLprefix " 'urlprefix :=
+ "\DOIprefix" 'doiprefix :=
+ "\ArXivprefix " 'eprintprefix :=
+ "\Pubmedprefix " 'pubmedprefix :=
+}
+
+FUNCTION {init.state.consts}
+{ #0 'before.all :=
+ #1 'mid.sentence :=
+ #2 'after.sentence :=
+ #3 'after.block :=
+}
+STRINGS { s t}
+FUNCTION {output.nonnull}
+{ 's :=
+ output.state mid.sentence =
+ { ", " * write$ }
+ { output.state after.block =
+% { add.period$ write$
+ { ", " * write$
+ newline$
+ "\newblock " write$
+ }
+ { output.state before.all =
+ 'write$
+ { add.period$ " " * write$ }
+ if$
+ }
+ if$
+ mid.sentence 'output.state :=
+ }
+ if$
+ s
+}
+FUNCTION {output}
+{ duplicate$ empty$
+ 'pop$
+ 'output.nonnull
+ if$
+}
+FUNCTION {output.check}
+{ 't :=
+ duplicate$ empty$
+ { pop$ "empty " t * " in " * cite$ * warning$ }
+ 'output.nonnull
+ if$
+}
+FUNCTION {fin.entry}
+{ add.period$
+ write$
+ newline$
+}
+
+FUNCTION {new.block}
+{ output.state before.all =
+ 'skip$
+ { after.block 'output.state := }
+ if$
+}
+FUNCTION {new.sentence}
+{ output.state after.block =
+ 'skip$
+ { output.state before.all =
+ 'skip$
+ { after.sentence 'output.state := }
+ if$
+ }
+ if$
+}
+FUNCTION {add.blank}
+{ " " * before.all 'output.state :=
+}
+
+FUNCTION {date.block}
+{
+ skip$
+}
+
+FUNCTION {not}
+{ { #0 }
+ { #1 }
+ if$
+}
+FUNCTION {and}
+{ 'skip$
+ { pop$ #0 }
+ if$
+}
+FUNCTION {or}
+{ { pop$ #1 }
+ 'skip$
+ if$
+}
+FUNCTION {new.block.checkb}
+{ empty$
+ swap$ empty$
+ and
+ 'skip$
+ 'new.block
+ if$
+}
+FUNCTION {field.or.null}
+{ duplicate$ empty$
+ { pop$ "" }
+ 'skip$
+ if$
+}
+FUNCTION {emphasize}
+{ duplicate$ empty$
+ { pop$ "" }
+ { "\textit{" swap$ * "}" * }
+ if$
+}
+FUNCTION {tie.or.space.prefix}
+{ duplicate$ text.length$ #3 <
+ { "~" }
+ { " " }
+ if$
+ swap$
+}
+
+FUNCTION {capitalize}
+{ "u" change.case$ "t" change.case$ }
+
+FUNCTION {space.word}
+{ " " swap$ * " " * }
+ % Here are the language-specific definitions for explicit words.
+ % Each function has a name bbl.xxx where xxx is the English word.
+ % The language selected here is ENGLISH
+FUNCTION {bbl.and}
+{ "and"}
+
+FUNCTION {bbl.etal}
+{ "et~al." }
+
+FUNCTION {bbl.editors}
+{ "eds." }
+
+FUNCTION {bbl.editor}
+{ "ed." }
+
+FUNCTION {bbl.edby}
+{ "edited by" }
+
+FUNCTION {bbl.edition}
+{ "ed." }
+
+FUNCTION {bbl.volume}
+{ "volume" }
+
+FUNCTION {bbl.of}
+{ "of" }
+
+FUNCTION {bbl.number}
+{ "number" }
+
+FUNCTION {bbl.nr}
+{ "no." }
+
+FUNCTION {bbl.in}
+{ "in" }
+
+FUNCTION {bbl.pages}
+{ "pp." }
+
+FUNCTION {bbl.page}
+{ "p." }
+
+FUNCTION {bbl.chapter}
+{ "chapter" }
+
+FUNCTION {bbl.techrep}
+{ "Technical Report" }
+
+FUNCTION {bbl.mthesis}
+{ "Master's thesis" }
+
+FUNCTION {bbl.phdthesis}
+{ "Ph.D. thesis" }
+
+MACRO {jan} {"January"}
+
+MACRO {feb} {"February"}
+
+MACRO {mar} {"March"}
+
+MACRO {apr} {"April"}
+
+MACRO {may} {"May"}
+
+MACRO {jun} {"June"}
+
+MACRO {jul} {"July"}
+
+MACRO {aug} {"August"}
+
+MACRO {sep} {"September"}
+
+MACRO {oct} {"October"}
+
+MACRO {nov} {"November"}
+
+MACRO {dec} {"December"}
+
+MACRO {acmcs} {"ACM Comput. Surv."}
+
+MACRO {acta} {"Acta Inf."}
+
+MACRO {cacm} {"Commun. ACM"}
+
+MACRO {ibmjrd} {"IBM J. Res. Dev."}
+
+MACRO {ibmsj} {"IBM Syst.~J."}
+
+MACRO {ieeese} {"IEEE Trans. Software Eng."}
+
+MACRO {ieeetc} {"IEEE Trans. Comput."}
+
+MACRO {ieeetcad}
+ {"IEEE Trans. Comput. Aid. Des."}
+
+MACRO {ipl} {"Inf. Process. Lett."}
+
+MACRO {jacm} {"J.~ACM"}
+
+MACRO {jcss} {"J.~Comput. Syst. Sci."}
+
+MACRO {scp} {"Sci. Comput. Program."}
+
+MACRO {sicomp} {"SIAM J. Comput."}
+
+MACRO {tocs} {"ACM Trans. Comput. Syst."}
+
+MACRO {tods} {"ACM Trans. Database Syst."}
+
+MACRO {tog} {"ACM Trans. Graphic."}
+
+MACRO {toms} {"ACM Trans. Math. Software"}
+
+MACRO {toois} {"ACM Trans. Office Inf. Syst."}
+
+MACRO {toplas} {"ACM Trans. Progr. Lang. Syst."}
+
+MACRO {tcs} {"Theor. Comput. Sci."}
+
+FUNCTION {bibinfo.check}
+{ swap$
+ duplicate$ missing$
+ {
+ pop$ pop$
+ ""
+ }
+ { duplicate$ empty$
+ {
+ swap$ pop$
+ }
+ { swap$
+ "\bibinfo{" swap$ * "}{" * swap$ * "}" *
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {bibinfo.warn}
+{ swap$
+ duplicate$ missing$
+ {
+ swap$ "missing " swap$ * " in " * cite$ * warning$ pop$
+ ""
+ }
+ { duplicate$ empty$
+ {
+ swap$ "empty " swap$ * " in " * cite$ * warning$
+ }
+ { swap$
+ pop$
+ }
+ if$
+ }
+ if$
+}
+STRINGS { bibinfo}
+INTEGERS { nameptr namesleft numnames }
+
+FUNCTION {format.names}
+{ 'bibinfo :=
+ duplicate$ empty$ 'skip$ {
+ 's :=
+ "" 't :=
+ #1 'nameptr :=
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{f.~}{vv~}{ll}{, jj}"
+ format.name$
+ bibinfo bibinfo.check
+ 't :=
+ nameptr #1 >
+ {
+ namesleft #1 >
+ { ", " * t * }
+ {
+ "," *
+ s nameptr "{ll}" format.name$ duplicate$ "others" =
+ { 't := }
+ { pop$ }
+ if$
+ t "others" =
+ {
+ " " * bbl.etal *
+ }
+ { " " * t * }
+ if$
+ }
+ if$
+ }
+ 't
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+ } if$
+}
+FUNCTION {format.names.ed}
+{
+ format.names
+}
+FUNCTION {format.key}
+{ empty$
+ { key field.or.null }
+ { "" }
+ if$
+}
+
+%FUNCTION {format.authors}
+%{ author "author" format.names
+%}
+
+FUNCTION {format.authors}
+{ author "author" format.names
+ duplicate$ empty$ 'skip$
+ { collaboration "collaboration" bibinfo.check
+ duplicate$ empty$ 'skip$
+ { " (" swap$ * ")" * }
+ if$
+ *
+ }
+ if$
+}
+
+FUNCTION {get.bbl.editor}
+{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ }
+
+FUNCTION {format.editors}
+{ editor "editor" format.names duplicate$ empty$ 'skip$
+ {
+ " " *
+ get.bbl.editor
+ capitalize
+ "(" swap$ * ")" *
+ *
+ }
+ if$
+}
+FUNCTION {format.note}
+{
+ note empty$
+ { "" }
+ { note #1 #1 substring$
+ duplicate$ "{" =
+ 'skip$
+ { output.state mid.sentence =
+ { "l" }
+ { "u" }
+ if$
+ change.case$
+ }
+ if$
+ note #2 global.max$ substring$ * "note" bibinfo.check
+ }
+ if$
+}
+
+FUNCTION {format.title}
+{ title
+ duplicate$ empty$ 'skip$
+ { "t" change.case$ }
+ if$
+ "title" bibinfo.check
+}
+
+FUNCTION {format.full.names}
+{'s :=
+ "" 't :=
+ #1 'nameptr :=
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{vv~}{ll}" format.name$
+ 't :=
+ nameptr #1 >
+ {
+ namesleft #1 >
+ { ", " * t * }
+ {
+ s nameptr "{ll}" format.name$ duplicate$ "others" =
+ { 't := }
+ { pop$ }
+ if$
+ t "others" =
+ {
+ " " * bbl.etal *
+ }
+ {
+ numnames #2 >
+ { "," * }
+ 'skip$
+ if$
+ bbl.and
+ space.word * t *
+ }
+ if$
+ }
+ if$
+ }
+ 't
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+}
+
+FUNCTION {author.editor.key.full}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.full.names }
+ if$
+ }
+ { author format.full.names }
+ if$
+}
+
+FUNCTION {author.key.full}
+{ author empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { author format.full.names }
+ if$
+}
+
+FUNCTION {editor.key.full}
+{ editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.full.names }
+ if$
+}
+
+FUNCTION {make.full.names}
+{ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.key.full
+ { type$ "proceedings" =
+ 'editor.key.full
+ 'author.key.full
+ if$
+ }
+ if$
+}
+
+FUNCTION {output.bibitem}
+{ newline$
+ "\bibitem[{" write$
+ label write$
+ ")" make.full.names duplicate$ short.list =
+ { pop$ }
+ { * }
+ if$
+ "}]{" * write$
+ cite$ write$
+ "}" write$
+ newline$
+ ""
+ before.all 'output.state :=
+}
+
+FUNCTION {n.dashify}
+{
+ 't :=
+ ""
+ { t empty$ not }
+ { t #1 #1 substring$ "-" =
+ { t #1 #2 substring$ "--" = not
+ { "--" *
+ t #2 global.max$ substring$ 't :=
+ }
+ { { t #1 #1 substring$ "-" = }
+ { "-" *
+ t #2 global.max$ substring$ 't :=
+ }
+ while$
+ }
+ if$
+ }
+ { t #1 #1 substring$ *
+ t #2 global.max$ substring$ 't :=
+ }
+ if$
+ }
+ while$
+}
+
+FUNCTION {word.in}
+{ bbl.in
+ ":" *
+ " " * }
+
+FUNCTION {format.date}
+{ year "year" bibinfo.check duplicate$ empty$
+ {
+ "empty year in " cite$ * "; set to ????" * warning$
+ pop$ "????"
+ }
+ 'skip$
+ if$
+ extra.label *
+}
+FUNCTION{format.year}
+{ year "year" bibinfo.check duplicate$ empty$
+ { "empty year in " cite$ *
+ "; set to ????" *
+ warning$
+ pop$ "????"
+ }
+ {
+ }
+ if$
+ extra.label *
+ " (" swap$ * ")" *
+}
+FUNCTION {format.btitle}
+{ title "title" bibinfo.check
+ duplicate$ empty$ 'skip$
+ {
+ }
+ if$
+}
+FUNCTION {either.or.check}
+{ empty$
+ 'pop$
+ { "can't use both " swap$ * " fields in " * cite$ * warning$ }
+ if$
+}
+FUNCTION {format.bvolume}
+{ volume empty$
+ { "" }
+ { bbl.volume volume tie.or.space.prefix
+ "volume" bibinfo.check * *
+ series "series" bibinfo.check
+ duplicate$ empty$ 'pop$
+ { swap$ bbl.of space.word * swap$
+ emphasize * }
+ if$
+ "volume and number" number either.or.check
+ }
+ if$
+}
+FUNCTION {format.number.series}
+{ volume empty$
+ { number empty$
+ { series field.or.null }
+ { series empty$
+ { number "number" bibinfo.check }
+ { output.state mid.sentence =
+ { bbl.number }
+ { bbl.number capitalize }
+ if$
+ number tie.or.space.prefix "number" bibinfo.check * *
+ bbl.in space.word *
+ series "series" bibinfo.check *
+ }
+ if$
+ }
+ if$
+ }
+ { "" }
+ if$
+}
+
+FUNCTION {format.edition}
+{ edition duplicate$ empty$ 'skip$
+ {
+ output.state mid.sentence =
+ { "l" }
+ { "t" }
+ if$ change.case$
+ "edition" bibinfo.check
+ " " * bbl.edition *
+ }
+ if$
+}
+INTEGERS { multiresult }
+FUNCTION {multi.page.check}
+{ 't :=
+ #0 'multiresult :=
+ { multiresult not
+ t empty$ not
+ and
+ }
+ { t #1 #1 substring$
+ duplicate$ "-" =
+ swap$ duplicate$ "," =
+ swap$ "+" =
+ or or
+ { #1 'multiresult := }
+ { t #2 global.max$ substring$ 't := }
+ if$
+ }
+ while$
+ multiresult
+}
+FUNCTION {format.pages}
+{ pages duplicate$ empty$ 'skip$
+ { duplicate$ multi.page.check
+ {
+ bbl.pages swap$
+ n.dashify
+ }
+ {
+ bbl.page swap$
+ }
+ if$
+ tie.or.space.prefix
+ "pages" bibinfo.check
+ * *
+ }
+ if$
+}
+FUNCTION {format.journal.pages}
+{ pages duplicate$ empty$ 'pop$
+ { swap$ duplicate$ empty$
+ { pop$ pop$ format.pages }
+ {
+ " " *
+ swap$
+ n.dashify
+ "pages" bibinfo.check
+ *
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.vol.num.pages}
+{ volume field.or.null
+ duplicate$ empty$ 'skip$
+ {
+ "volume" bibinfo.check
+ }
+ if$
+ format.year *
+}
+
+FUNCTION {format.chapter.pages}
+{ chapter empty$
+ { "" }
+ { type empty$
+ { bbl.chapter }
+ { type "l" change.case$
+ "type" bibinfo.check
+ }
+ if$
+ chapter tie.or.space.prefix
+ "chapter" bibinfo.check
+ * *
+ }
+ if$
+}
+
+FUNCTION {format.booktitle}
+{
+ booktitle "booktitle" bibinfo.check
+}
+FUNCTION {format.in.ed.booktitle}
+{ format.booktitle duplicate$ empty$ 'skip$
+ {
+ editor "editor" format.names.ed duplicate$ empty$ 'pop$
+ {
+ " " *
+ get.bbl.editor
+ capitalize
+ "(" swap$ * "), " *
+ * swap$
+ * }
+ if$
+ word.in swap$ *
+ }
+ if$
+}
+FUNCTION {format.thesis.type}
+{ type duplicate$ empty$
+ 'pop$
+ { swap$ pop$
+ "t" change.case$ "type" bibinfo.check
+ }
+ if$
+}
+FUNCTION {format.tr.number}
+{ number "number" bibinfo.check
+ type duplicate$ empty$
+ { pop$ bbl.techrep }
+ 'skip$
+ if$
+ "type" bibinfo.check
+ swap$ duplicate$ empty$
+ { pop$ "t" change.case$ }
+ { tie.or.space.prefix * * }
+ if$
+}
+FUNCTION {format.article.crossref}
+{
+ word.in
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.book.crossref}
+{ volume duplicate$ empty$
+ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
+ pop$ word.in
+ }
+ { bbl.volume
+ swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word *
+ }
+ if$
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.incoll.inproc.crossref}
+{
+ word.in
+ " \cite{" * crossref * "}" *
+}
+FUNCTION {format.org.or.pub}
+{ 't :=
+ ""
+ address empty$ t empty$ and
+ 'skip$
+ {
+ t empty$
+ { address "address" bibinfo.check *
+ }
+ { t *
+ address empty$
+ 'skip$
+ { ", " * address "address" bibinfo.check * }
+ if$
+ }
+ if$
+ }
+ if$
+}
+FUNCTION {format.publisher.address}
+{ publisher "publisher" bibinfo.check format.org.or.pub
+}
+
+FUNCTION {format.organization.address}
+{ organization "organization" bibinfo.check format.org.or.pub
+}
+
+FUNCTION {print.url}
+ {url duplicate$ empty$
+ { pop$ "" }
+ { new.sentence
+ urlprefix "\url{" * swap$ * "}" *
+ }
+ if$
+ }
+
+FUNCTION {print.doi}
+ {doi duplicate$ empty$
+ { pop$ "" }
+ { new.sentence
+ doiprefix "\doi{" * swap$ * "}" *
+ }
+ if$
+ }
+
+FUNCTION {print.eprint}
+ {eprint duplicate$ empty$
+ { pop$ "" }
+ { new.sentence
+ duplicate$ "\href{http://arxiv.org/abs/" swap$ * "}{{\tt arXiv:" * swap$ * "}}" *
+ }
+ if$
+ }
+
+FUNCTION {print.pubmed}
+ {pubmed duplicate$ empty$
+ { pop$ "" }
+ { new.sentence
+ pubmedprefix "\Pubmed{" * swap$ * "}" *
+ }
+ if$
+ }
+
+FUNCTION {webpage}
+{ "%Type = Webpage" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ author empty$
+ {
+ format.title "title" output.check
+ new.block
+ format.date "year" output.check
+ date.block
+ }
+ {
+ format.date "year" output.check
+ date.block
+ format.title "title" output.check
+ new.block
+}
+ if$
+ print.url output
+ fin.entry
+}
+
+
+FUNCTION {article}
+{ "%Type = Article" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ new.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ {
+ journal
+ "journal" bibinfo.check
+ "journal" output.check
+ add.blank
+ format.vol.num.pages output
+ }
+ { format.article.crossref output.nonnull
+ }
+ if$
+ format.journal.pages
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+FUNCTION {book}
+{ "%Type = Book" write$
+ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check
+ editor format.key output
+ }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ format.btitle "title" output.check
+ crossref missing$
+ { format.bvolume output
+ format.number.series output
+ format.edition output
+ format.publisher.address output
+ }
+ {
+ format.book.crossref output.nonnull
+ }
+ if$
+ format.date "year" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+FUNCTION {booklet}
+{ "%Type = Booklet" write$
+ output.bibitem
+ format.authors output
+ author format.key output
+ format.title "title" output.check
+ howpublished "howpublished" bibinfo.check output
+ address "address" bibinfo.check output
+ format.date "year" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {inbook}
+{ "%Type = Inbook" write$
+ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check
+ editor format.key output
+ }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ format.btitle "title" output.check
+ crossref missing$
+ {
+ format.bvolume output
+ format.number.series output
+ format.edition output
+ format.publisher.address output
+ }
+ {
+ format.book.crossref output.nonnull
+ }
+ if$
+ format.date "year" output.check
+ format.pages "pages" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {incollection}
+{ "%Type = Incollection" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ new.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ format.bvolume output
+ format.number.series output
+ format.edition output
+ format.publisher.address output
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ }
+ if$
+ format.date "year" output.check
+ format.pages "pages" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+FUNCTION {inproceedings}
+{ "%Type = Inproceedings" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ new.block
+ format.title "title" output.check
+ new.block
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ format.bvolume output
+ format.number.series output
+ publisher empty$
+ { format.organization.address output }
+ { organization "organization" bibinfo.check output
+ format.publisher.address output
+ }
+ if$
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ }
+ if$
+ format.date output
+ format.pages "pages" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+FUNCTION {conference} { inproceedings }
+FUNCTION {manual}
+{ "%Type = Manual" write$
+ output.bibitem
+ format.authors output
+ author format.key output
+ format.btitle "title" output.check
+ format.edition output
+ organization "organization" bibinfo.check output
+ address "address" bibinfo.check output
+ format.date "year" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {mastersthesis}
+{ "%Type = Masterthesis" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.btitle
+ "title" output.check
+ bbl.mthesis format.thesis.type output.nonnull
+ school "school" bibinfo.warn output
+ address "address" bibinfo.check output
+ format.date "year" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {misc}
+{ "%Type = Misc" write$
+ output.bibitem
+ format.authors output
+ author format.key output
+ format.title output
+ howpublished "howpublished" bibinfo.check output
+ format.date "year" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+FUNCTION {phdthesis}
+{ "%Type = Phdthesis" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.btitle
+ "title" output.check
+ bbl.phdthesis format.thesis.type output.nonnull
+ school "school" bibinfo.warn output
+ address "address" bibinfo.check output
+ format.date "year" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {proceedings}
+{ "%Type = Proceedings" write$
+ output.bibitem
+ format.editors output
+ editor format.key output
+ format.btitle "title" output.check
+ format.bvolume output
+ format.number.series output
+ publisher empty$
+ { format.organization.address output }
+ { organization "organization" bibinfo.check output
+ format.publisher.address output
+ }
+ if$
+ format.date "year" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {techreport}
+{ "%Type = Techreport" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.btitle
+ "title" output.check
+ format.tr.number output.nonnull
+ institution "institution" bibinfo.warn output
+ address "address" bibinfo.check output
+ format.date "year" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note output
+ fin.entry
+}
+
+FUNCTION {unpublished}
+{ "%Type = Unpublished" write$
+ output.bibitem
+ format.authors "author" output.check
+ author format.key output
+ format.title "title" output.check
+ format.date "year" output.check
+ new.sentence
+ print.url output
+ print.doi output
+ print.eprint output
+ print.pubmed output
+ format.note "note" output.check
+ fin.entry
+}
+
+FUNCTION {default.type} { misc }
+READ
+FUNCTION {sortify}
+{ purify$
+ "l" change.case$
+}
+INTEGERS { len }
+FUNCTION {chop.word}
+{ 's :=
+ 'len :=
+ s #1 len substring$ =
+ { s len #1 + global.max$ substring$ }
+ 's
+ if$
+}
+FUNCTION {format.lab.names}
+{ 's :=
+ "" 't :=
+ s #1 "{vv~}{ll}" format.name$
+ s num.names$ duplicate$
+ #2 >
+ { pop$
+ " " * bbl.etal *
+ }
+ { #2 <
+ 'skip$
+ { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
+ {
+ " " * bbl.etal *
+ }
+ { bbl.and space.word * s #2 "{vv~}{ll}" format.name$
+ * }
+ if$
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION {author.key.label}
+{ author empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { author format.lab.names }
+ if$
+}
+
+FUNCTION {author.editor.key.label}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.lab.names }
+ if$
+ }
+ { author format.lab.names }
+ if$
+}
+
+FUNCTION {editor.key.label}
+{ editor empty$
+ { key empty$
+ { cite$ #1 #3 substring$ }
+ 'key
+ if$
+ }
+ { editor format.lab.names }
+ if$
+}
+
+FUNCTION {calc.short.authors}
+{ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.key.label
+ { type$ "proceedings" =
+ 'editor.key.label
+ 'author.key.label
+ if$
+ }
+ if$
+ 'short.list :=
+}
+
+FUNCTION {calc.label}
+{ calc.short.authors
+ short.list
+ "("
+ *
+ year duplicate$ empty$
+ { pop$ "????" }
+ { purify$ #-1 #4 substring$ }
+ if$
+ *
+ 'label :=
+}
+
+FUNCTION {sort.format.names}
+{ 's :=
+ #1 'nameptr :=
+ ""
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}"
+ format.name$ 't :=
+ nameptr #1 >
+ {
+ " " *
+ namesleft #1 = t "others" = and
+ { "zzzzz" * }
+ { t sortify * }
+ if$
+ }
+ { t sortify * }
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+}
+
+FUNCTION {sort.format.title}
+{ 't :=
+ "A " #2
+ "An " #3
+ "The " #4 t chop.word
+ chop.word
+ chop.word
+ sortify
+ #1 global.max$ substring$
+}
+FUNCTION {author.sort}
+{ author empty$
+ { key empty$
+ { "to sort, need author or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+FUNCTION {author.editor.sort}
+{ author empty$
+ { editor empty$
+ { key empty$
+ { "to sort, need author, editor, or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { editor sort.format.names }
+ if$
+ }
+ { author sort.format.names }
+ if$
+}
+FUNCTION {editor.sort}
+{ editor empty$
+ { key empty$
+ { "to sort, need editor or key in " cite$ * warning$
+ ""
+ }
+ { key sortify }
+ if$
+ }
+ { editor sort.format.names }
+ if$
+}
+FUNCTION {presort}
+{ calc.label
+ label sortify
+ " "
+ *
+ type$ "book" =
+ type$ "inbook" =
+ or
+ 'author.editor.sort
+ { type$ "proceedings" =
+ 'editor.sort
+ 'author.sort
+ if$
+ }
+ if$
+ #1 entry.max$ substring$
+ 'sort.label :=
+ sort.label
+ *
+ " "
+ *
+ title field.or.null
+ sort.format.title
+ *
+ #1 entry.max$ substring$
+ 'sort.key$ :=
+}
+
+ITERATE {presort}
+%SORT
+STRINGS { last.label next.extra }
+INTEGERS { last.extra.num number.label }
+FUNCTION {initialize.extra.label.stuff}
+{ #0 int.to.chr$ 'last.label :=
+ "" 'next.extra :=
+ #0 'last.extra.num :=
+ #0 'number.label :=
+}
+FUNCTION {forward.pass}
+{ last.label label =
+ { last.extra.num #1 + 'last.extra.num :=
+ last.extra.num int.to.chr$ 'extra.label :=
+ }
+ { "a" chr.to.int$ 'last.extra.num :=
+ "" 'extra.label :=
+ label 'last.label :=
+ }
+ if$
+ number.label #1 + 'number.label :=
+}
+FUNCTION {reverse.pass}
+{ next.extra "b" =
+ { "a" 'extra.label := }
+ 'skip$
+ if$
+ extra.label 'next.extra :=
+ extra.label
+ duplicate$ empty$
+ 'skip$
+ { "{\natexlab{" swap$ * "}}" * }
+ if$
+ 'extra.label :=
+ label extra.label * 'label :=
+}
+EXECUTE {initialize.extra.label.stuff}
+ITERATE {forward.pass}
+REVERSE {reverse.pass}
+FUNCTION {bib.sort.order}
+{ sort.label
+ " "
+ *
+ year field.or.null sortify
+ *
+ " "
+ *
+ title field.or.null
+ sort.format.title
+ *
+ #1 entry.max$ substring$
+ 'sort.key$ :=
+}
+ITERATE {bib.sort.order}
+%SORT
+FUNCTION {begin.bib}
+{ preamble$ empty$
+ 'skip$
+ { preamble$ write$ newline$ }
+ if$
+ "\begin{thebibliography}{" number.label int.to.str$ * "}" *
+ write$ newline$
+ "\expandafter\ifx\csname natexlab\endcsname\relax\def\natexlab#1{#1}\fi"
+ write$ newline$
+ "\providecommand{\url}[1]{\texttt{#1}}"
+ write$ newline$
+ "\providecommand{\href}[2]{#2}"
+ write$ newline$
+ "\providecommand{\path}[1]{#1}"
+ write$ newline$
+ "\providecommand{\DOIprefix}{doi:}"
+ write$ newline$
+ "\providecommand{\ArXivprefix}{arXiv:}"
+ write$ newline$
+ "\providecommand{\URLprefix}{URL: }"
+ write$ newline$
+ "\providecommand{\Pubmedprefix}{pmid:}"
+ write$ newline$
+ "\providecommand{\doi}[1]{\href{http://dx.doi.org/#1}{\path{#1}}}"
+ write$ newline$
+ "\providecommand{\Pubmed}[1]{\href{pmid:#1}{\path{#1}}}"
+ write$ newline$
+ "\providecommand{\bibinfo}[2]{#2}"
+ write$ newline$
+ "\ifx\xfnm\relax \def\xfnm[#1]{\unskip,\space#1}\fi"
+ write$ newline$
+}
+EXECUTE {begin.bib}
+EXECUTE {init.state.consts}
+EXECUTE {init.web.variables}
+ITERATE {call.type$}
+FUNCTION {end.bib}
+{ newline$
+ "\end{thebibliography}" write$ newline$
+}
+EXECUTE {end.bib}
+%% End of customized bst file
+%%
+%% End of file `elsarticle-num-names.bst'.
+%%
+%%
+%% Change log:
+%% -----------
+%% 22.04.2011
+%%
+%% 10.08.2012
+%% a. doi, url, eprint, pmid added
+%% b. Bibtype `webpage' defined
+%%
+%% 30.08.2012
+%% a. collaboration added.
+
+
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsarticle-num.bst b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsarticle-num.bst
new file mode 100644
index 00000000000..855a14e4281
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsarticle-num.bst
@@ -0,0 +1,1509 @@
+%%
+%% This is file `elsarticle-num.bst' (Version 2.1),
+%%
+%% Copyright 2007-2025 Elsevier Ltd
+%%
+%% This file is part of the 'Elsarticle Bundle'.
+%% ---------------------------------------------
+%%
+%% It may be distributed under the conditions of the LaTeX Project Public
+%% License, either version 1.3 of this license or (at your option) any
+%% later version. The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 1999/12/01 or later.
+%%
+%%
+%% $Id: elsarticle-num.bst 272 2025-01-09 17:36:26Z rishi $
+%%
+%% $URL: https://lenova.river-valley.com/svn/elsarticle/trunk/elsarticle-num.bst $
+%%
+%% ----------------------------------------
+
+ENTRY
+ { address
+ author
+ booktitle
+ chapter
+ edition
+ editor
+ howpublished
+ institution
+ journal
+ key
+ month
+ note
+ number
+ organization
+ pages
+ publisher
+ school
+ series
+ title
+ type
+ volume
+ year
+ eprint % urlbst
+ doi % urlbst
+ url % urlbst
+ lastchecked % urlbst
+ }
+ {}
+ { label }
+
+INTEGERS { output.state before.all mid.sentence after.sentence after.block }
+
+STRINGS { urlintro eprinturl eprintprefix doiprefix doiurl openinlinelink closeinlinelink } % urlbst...
+INTEGERS { hrefform inlinelinks makeinlinelink addeprints adddoiresolver }
+FUNCTION {init.urlbst.variables}
+{
+ "Available from: " 'urlintro := % prefix before URL
+ "http://arxiv.org/abs/" 'eprinturl := % prefix to make URL from eprint ref
+ "arXiv:" 'eprintprefix := % text prefix printed before eprint ref
+ "https://doi.org/" 'doiurl := % prefix to make URL from DOI
+ "doi:" 'doiprefix := % text prefix printed before DOI ref
+ #1 'addeprints := % 0=no eprints; 1=include eprints
+ #1 'adddoiresolver := % 0=no DOI resolver; 1=include it
+ #2 'hrefform := % 0=no crossrefs; 1=hypertex xrefs; 2=hyperref refs
+ #1 'inlinelinks := % 0=URLs explicit; 1=URLs attached to titles
+ % the following are internal state variables, not config constants
+ #0 'makeinlinelink := % state variable managed by setup.inlinelink
+ "" 'openinlinelink := % ditto
+ "" 'closeinlinelink := % ditto
+}
+INTEGERS {
+ bracket.state
+ outside.brackets
+ open.brackets
+ within.brackets
+ close.brackets
+}
+FUNCTION {init.state.consts}
+{ #0 'outside.brackets := % urlbst
+ #1 'open.brackets :=
+ #2 'within.brackets :=
+ #3 'close.brackets :=
+
+ #0 'before.all :=
+ #1 'mid.sentence :=
+ #2 'after.sentence :=
+ #3 'after.block :=
+}
+
+STRINGS { s t }
+
+FUNCTION {output.nonnull.original}
+{ 's :=
+ output.state mid.sentence =
+ { ", " * write$ }
+ { output.state after.block =
+ { add.period$ write$
+ newline$
+ "\newblock " write$
+ }
+ { output.state before.all =
+ 'write$
+ { add.period$ " " * write$ }
+ if$
+ }
+ if$
+ mid.sentence 'output.state :=
+ }
+ if$
+ s
+}
+
+FUNCTION {setup.inlinelink}
+{ makeinlinelink
+ { hrefform #1 = % hypertex
+ { "\special {html: }{" * 'openinlinelink :=
+ "\special {html:}" 'closeinlinelink :=
+ }
+ { hrefform #2 = % hyperref
+ { "\href{" url * "}{" * 'openinlinelink :=
+ "}" 'closeinlinelink :=
+ }
+ 'skip$
+ if$ % hrefform #2 =
+ }
+ if$ % hrefform #1 =
+ #0 'makeinlinelink :=
+ }
+ 'skip$
+ if$ % makeinlinelink
+}
+FUNCTION {add.inlinelink}
+{ openinlinelink empty$
+ 'skip$
+ { openinlinelink swap$ * closeinlinelink *
+ "" 'openinlinelink :=
+ }
+ if$
+}
+FUNCTION {output.nonnull}
+{ % Save the thing we've been asked to output
+ 's :=
+ % If the bracket-state is close.brackets, then add a close-bracket to
+ % what is currently at the top of the stack, and set bracket.state
+ % to outside.brackets
+ bracket.state close.brackets =
+ { "]" *
+ outside.brackets 'bracket.state :=
+ }
+ 'skip$
+ if$
+ bracket.state outside.brackets =
+ { % We're outside all brackets -- this is the normal situation.
+ % Write out what's currently at the top of the stack, using the
+ % original output.nonnull function.
+ s
+ add.inlinelink
+ output.nonnull.original % invoke the original output.nonnull
+ }
+ { % Still in brackets. Add open-bracket or (continuation) comma, add the
+ % new text (in s) to the top of the stack, and move to the close-brackets
+ % state, ready for next time (unless inbrackets resets it). If we come
+ % into this branch, then output.state is carefully undisturbed.
+ bracket.state open.brackets =
+ { " [" * }
+ { ", " * } % bracket.state will be within.brackets
+ if$
+ s *
+ close.brackets 'bracket.state :=
+ }
+ if$
+}
+
+FUNCTION {inbrackets}
+{ bracket.state close.brackets =
+ { within.brackets 'bracket.state := } % reset the state: not open nor closed
+ { open.brackets 'bracket.state := }
+ if$
+}
+
+FUNCTION {format.lastchecked}
+{ lastchecked empty$
+ { "" }
+ { inbrackets "cited " lastchecked * }
+ if$
+}
+
+FUNCTION {output}
+{ duplicate$ empty$
+ 'pop$
+ 'output.nonnull
+ if$
+}
+
+FUNCTION {output.check}
+{ 't :=
+ duplicate$ empty$
+ { pop$ "empty " t * " in " * cite$ * warning$ }
+ 'output.nonnull
+ if$
+}
+
+FUNCTION {fin.entry.original}
+{ add.period$
+ write$
+ newline$
+}
+
+FUNCTION {new.block}
+{ output.state before.all =
+ 'skip$
+ { after.block 'output.state := }
+ if$
+}
+
+FUNCTION {new.sentence}
+{ output.state after.block =
+ 'skip$
+ { output.state before.all =
+ 'skip$
+ { after.sentence 'output.state := }
+ if$
+ }
+ if$
+}
+
+FUNCTION {add.blank}
+{ " " * before.all 'output.state :=
+}
+
+FUNCTION {date.block}
+{
+ add.blank
+}
+
+FUNCTION {not}
+{ { #0 }
+ { #1 }
+ if$
+}
+
+FUNCTION {and}
+{ 'skip$
+ { pop$ #0 }
+ if$
+}
+
+FUNCTION {or}
+{ { pop$ #1 }
+ 'skip$
+ if$
+}
+
+FUNCTION {new.block.checka}
+{ empty$
+ 'skip$
+ 'new.block
+ if$
+}
+
+FUNCTION {new.block.checkb}
+{ empty$
+ swap$ empty$
+ and
+ 'skip$
+ 'new.block
+ if$
+}
+
+FUNCTION {new.sentence.checka}
+{ empty$
+ 'skip$
+ 'new.sentence
+ if$
+}
+
+FUNCTION {new.sentence.checkb}
+{ empty$
+ swap$ empty$
+ and
+ 'skip$
+ 'new.sentence
+ if$
+}
+
+FUNCTION {field.or.null}
+{ duplicate$ empty$
+ { pop$ "" }
+ 'skip$
+ if$
+}
+
+FUNCTION {emphasize}
+{ skip$ }
+
+FUNCTION {capitalize}
+{ "u" change.case$ "t" change.case$ }
+
+FUNCTION {space.word}
+{ " " swap$ * " " * }
+
+ % Here are the language-specific definitions for explicit words.
+ % Each function has a name bbl.xxx where xxx is the English word.
+ % The language selected here is ENGLISH
+FUNCTION {bbl.and}
+{ "and"}
+
+FUNCTION {bbl.etal}
+{ "et~al." }
+
+FUNCTION {bbl.editors}
+{ "Eds." }
+
+FUNCTION {bbl.editor}
+{ "Ed." }
+
+FUNCTION {bbl.edby}
+{ "edited by" }
+
+FUNCTION {bbl.edition}
+{ "Edition" }
+
+FUNCTION {bbl.volume}
+{ "Vol." }
+
+FUNCTION {bbl.of}
+{ "of" }
+
+FUNCTION {bbl.number}
+{ "no." }
+
+FUNCTION {bbl.nr}
+{ "no." }
+
+FUNCTION {bbl.in}
+{ "in" }
+
+FUNCTION {bbl.pages}
+{ "pp." }
+
+FUNCTION {bbl.page}
+{ "p." }
+
+FUNCTION {bbl.chapter}
+{ "Ch." }
+
+FUNCTION {bbl.techrep}
+{ "Tech. Rep." }
+
+FUNCTION {bbl.mthesis}
+{ "Master's thesis" }
+
+FUNCTION {bbl.phdthesis}
+{ "Ph.D. thesis" }
+
+FUNCTION {bbl.first}
+{ "1st" }
+
+FUNCTION {bbl.second}
+{ "2nd" }
+
+FUNCTION {bbl.third}
+{ "3rd" }
+
+FUNCTION {bbl.fourth}
+{ "4th" }
+
+FUNCTION {bbl.fifth}
+{ "5th" }
+
+FUNCTION {bbl.st}
+{ "st" }
+
+FUNCTION {bbl.nd}
+{ "nd" }
+
+FUNCTION {bbl.rd}
+{ "rd" }
+
+FUNCTION {bbl.th}
+{ "th" }
+
+MACRO {jan} {"Jan."}
+
+MACRO {feb} {"Feb."}
+
+MACRO {mar} {"Mar."}
+
+MACRO {apr} {"Apr."}
+
+MACRO {may} {"May"}
+
+MACRO {jun} {"Jun."}
+
+MACRO {jul} {"Jul."}
+
+MACRO {aug} {"Aug."}
+
+MACRO {sep} {"Sep."}
+
+MACRO {oct} {"Oct."}
+
+MACRO {nov} {"Nov."}
+
+MACRO {dec} {"Dec."}
+
+FUNCTION {eng.ord}
+{ duplicate$ "1" swap$ *
+ #-2 #1 substring$ "1" =
+ { bbl.th * }
+ { duplicate$ #-1 #1 substring$
+ duplicate$ "1" =
+ { pop$ bbl.st * }
+ { duplicate$ "2" =
+ { pop$ bbl.nd * }
+ { "3" =
+ { bbl.rd * }
+ { bbl.th * }
+ if$
+ }
+ if$
+ }
+ if$
+ }
+ if$
+}
+
+MACRO {acmcs} {"ACM Comput. Surv."}
+
+MACRO {acta} {"Acta Inf."}
+
+MACRO {cacm} {"Commun. ACM"}
+
+MACRO {ibmjrd} {"IBM J. Res. Dev."}
+
+MACRO {ibmsj} {"IBM Syst.~J."}
+
+MACRO {ieeese} {"IEEE Trans. Softw. Eng."}
+
+MACRO {ieeetc} {"IEEE Trans. Comput."}
+
+MACRO {ieeetcad}
+ {"IEEE Trans. Comput.-Aided Design Integrated Circuits"}
+
+MACRO {ipl} {"Inf. Process. Lett."}
+
+MACRO {jacm} {"J.~ACM"}
+
+MACRO {jcss} {"J.~Comput. Syst. Sci."}
+
+MACRO {scp} {"Sci. Comput. Programming"}
+
+MACRO {sicomp} {"SIAM J. Comput."}
+
+MACRO {tocs} {"ACM Trans. Comput. Syst."}
+
+MACRO {tods} {"ACM Trans. Database Syst."}
+
+MACRO {tog} {"ACM Trans. Gr."}
+
+MACRO {toms} {"ACM Trans. Math. Softw."}
+
+MACRO {toois} {"ACM Trans. Office Inf. Syst."}
+
+MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."}
+
+MACRO {tcs} {"Theoretical Comput. Sci."}
+
+FUNCTION {write.url}
+{ url empty$
+ { skip$ }
+ { "\newline\urlprefix\url{" url * "}" * write$ newline$ }
+ if$
+}
+
+INTEGERS { nameptr namesleft numnames }
+
+FUNCTION {format.names}
+{ 's :=
+ #1 'nameptr :=
+ s num.names$ 'numnames :=
+ numnames 'namesleft :=
+ { namesleft #0 > }
+ { s nameptr
+ "{f.~}{vv~}{ll}{, jj}" format.name$
+ 't :=
+ nameptr #1 >
+ {
+ namesleft #1 >
+ { ", " * t * }
+ {
+ "," *
+ s nameptr "{ll}" format.name$ duplicate$ "others" =
+ { 't := }
+ { pop$ }
+ if$
+ t "others" =
+ {
+ " " * bbl.etal *
+ }
+ { " " * t * }
+ if$
+ }
+ if$
+ }
+ 't
+ if$
+ nameptr #1 + 'nameptr :=
+ namesleft #1 - 'namesleft :=
+ }
+ while$
+}
+FUNCTION {format.names.ed}
+{ format.names }
+FUNCTION {format.authors}
+{ author empty$
+ { "" }
+ { author format.names }
+ if$
+}
+
+FUNCTION {format.editors}
+{ editor empty$
+ { "" }
+ { editor format.names
+ editor num.names$ #1 >
+ { " (" * bbl.editors * ")" * }
+ { " (" * bbl.editor * ")" * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.in.editors}
+{ editor empty$
+ { "" }
+ { editor format.names.ed
+ editor num.names$ #1 >
+ { " (" * bbl.editors * ")" * }
+ { " (" * bbl.editor * ")" * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.note}
+{
+ note empty$
+ { "" }
+ { note #1 #1 substring$
+ duplicate$ "{" =
+ 'skip$
+ { output.state mid.sentence =
+ { "l" }
+ { "u" }
+ if$
+ change.case$
+ }
+ if$
+ note #2 global.max$ substring$ *
+ }
+ if$
+}
+
+FUNCTION {format.title}
+{ title empty$
+ { "" }
+ { title "t" change.case$
+ }
+ if$
+}
+
+FUNCTION {output.bibitem.original}
+{ newline$
+ "\bibitem{" write$
+ cite$ write$
+ "}" write$
+ newline$
+ ""
+ before.all 'output.state :=
+}
+
+FUNCTION {n.dashify}
+{
+ 't :=
+ ""
+ { t empty$ not }
+ { t #1 #1 substring$ "-" =
+ { t #1 #2 substring$ "--" = not
+ { "--" *
+ t #2 global.max$ substring$ 't :=
+ }
+ { { t #1 #1 substring$ "-" = }
+ { "-" *
+ t #2 global.max$ substring$ 't :=
+ }
+ while$
+ }
+ if$
+ }
+ { t #1 #1 substring$ *
+ t #2 global.max$ substring$ 't :=
+ }
+ if$
+ }
+ while$
+}
+
+FUNCTION {word.in}
+{ bbl.in
+ ":" *
+ " " * }
+
+FUNCTION {format.date}
+{ year empty$
+ { month empty$
+ { "" }
+ { "there's a month but no year in " cite$ * warning$
+ month
+ }
+ if$
+ }
+ { month empty$
+ 'year
+ { month " " * year * }
+ if$
+ }
+ if$
+ duplicate$ empty$
+ 'skip$
+ {
+ before.all 'output.state :=
+ " (" swap$ * ")" *
+ }
+ if$
+}
+
+FUNCTION{format.year}
+{ year duplicate$ empty$
+ { "empty year in " cite$ * warning$ pop$ "" }
+ { "(" swap$ * ")" * }
+ if$
+}
+
+FUNCTION {format.btitle}
+{ title
+}
+
+FUNCTION {tie.or.space.connect}
+{ duplicate$ text.length$ #3 <
+ { "~" }
+ { " " }
+ if$
+ swap$ * *
+}
+
+FUNCTION {either.or.check}
+{ empty$
+ 'pop$
+ { "can't use both " swap$ * " fields in " * cite$ * warning$ }
+ if$
+}
+
+FUNCTION {format.bvolume}
+{ volume empty$
+ { "" }
+ { bbl.volume volume tie.or.space.connect
+ series empty$
+ 'skip$
+ { bbl.of space.word * series emphasize * }
+ if$
+ "volume and number" number either.or.check
+ }
+ if$
+}
+
+FUNCTION {format.number.series}
+{ volume empty$
+ { number empty$
+ { series field.or.null }
+ { output.state mid.sentence =
+ { bbl.number }
+ { bbl.number capitalize }
+ if$
+ number tie.or.space.connect
+ series empty$
+ { "there's a number but no series in " cite$ * warning$ }
+ { bbl.in space.word * series * }
+ if$
+ }
+ if$
+ }
+ { "" }
+ if$
+}
+
+FUNCTION {is.num}
+{ chr.to.int$
+ duplicate$ "0" chr.to.int$ < not
+ swap$ "9" chr.to.int$ > not and
+}
+
+FUNCTION {extract.num}
+{ duplicate$ 't :=
+ "" 's :=
+ { t empty$ not }
+ { t #1 #1 substring$
+ t #2 global.max$ substring$ 't :=
+ duplicate$ is.num
+ { s swap$ * 's := }
+ { pop$ "" 't := }
+ if$
+ }
+ while$
+ s empty$
+ 'skip$
+ { pop$ s }
+ if$
+}
+
+FUNCTION {convert.edition}
+{ edition extract.num "l" change.case$ 's :=
+ s "first" = s "1" = or
+ { bbl.first 't := }
+ { s "second" = s "2" = or
+ { bbl.second 't := }
+ { s "third" = s "3" = or
+ { bbl.third 't := }
+ { s "fourth" = s "4" = or
+ { bbl.fourth 't := }
+ { s "fifth" = s "5" = or
+ { bbl.fifth 't := }
+ { s #1 #1 substring$ is.num
+ { s eng.ord 't := }
+ { edition 't := }
+ if$
+ }
+ if$
+ }
+ if$
+ }
+ if$
+ }
+ if$
+ }
+ if$
+ t
+}
+
+FUNCTION {format.edition}
+{ edition empty$
+ { "" }
+ { output.state mid.sentence =
+ { convert.edition "l" change.case$ " " * bbl.edition * }
+ { convert.edition "t" change.case$ " " * bbl.edition * }
+ if$
+ }
+ if$
+}
+
+INTEGERS { multiresult }
+
+FUNCTION {multi.page.check}
+{ 't :=
+ #0 'multiresult :=
+ { multiresult not
+ t empty$ not
+ and
+ }
+ { t #1 #1 substring$
+ duplicate$ "-" =
+ swap$ duplicate$ "," =
+ swap$ "+" =
+ or or
+ { #1 'multiresult := }
+ { t #2 global.max$ substring$ 't := }
+ if$
+ }
+ while$
+ multiresult
+}
+
+FUNCTION {format.pages}
+{ pages empty$
+ { "" }
+ { pages multi.page.check
+ { bbl.pages pages n.dashify tie.or.space.connect }
+ { bbl.page pages tie.or.space.connect }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.journal.pages}
+{ pages empty$
+ 'skip$
+ { duplicate$ empty$
+ { pop$ format.pages }
+ {
+ " " *
+ format.year * " " *
+ pages n.dashify *
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.vol.num.pages}
+{
+ % volume field.or.null
+ " "
+ volume empty$
+ { pop$ "" }
+ { volume * }
+ if$
+ number empty$
+ 'skip$
+ {
+ "~(" number * ")" * *
+ volume empty$
+ { "there's a number but no volume in " cite$ * warning$ }
+ 'skip$
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.chapter.pages}
+{ chapter empty$
+ { "" }
+ { type empty$
+ { bbl.chapter }
+ { type "l" change.case$ }
+ if$
+ chapter tie.or.space.connect
+ }
+ if$
+}
+
+FUNCTION {format.in.ed.booktitle}
+{ booktitle empty$
+ { "" }
+ { editor empty$
+ { word.in booktitle * }
+ { word.in format.in.editors * ", " *
+ booktitle * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {empty.misc.check}
+{ author empty$ title empty$ howpublished empty$
+ month empty$ year empty$ note empty$
+ and and and and and
+ { "all relevant fields are empty in " cite$ * warning$ }
+ 'skip$
+ if$
+}
+
+FUNCTION {format.thesis.type}
+{ type empty$
+ 'skip$
+ { pop$
+ type "t" change.case$
+ }
+ if$
+}
+
+FUNCTION {format.tr.number}
+{ type empty$
+ { bbl.techrep }
+ 'type
+ if$
+ number empty$
+ { "t" change.case$ }
+ { number tie.or.space.connect }
+ if$
+}
+
+FUNCTION {format.article.crossref}
+{
+ key empty$
+ { journal empty$
+ { "need key or journal for " cite$ * " to crossref " * crossref *
+ warning$
+ ""
+ }
+ { word.in journal emphasize * }
+ if$
+ }
+ { word.in key * " " *}
+ if$
+ " \cite{" * crossref * "}" *
+}
+
+FUNCTION {format.crossref.editor}
+{ editor #1 "{vv~}{ll}" format.name$
+ editor num.names$ duplicate$
+ #2 >
+ { pop$
+ " " * bbl.etal *
+ }
+ { #2 <
+ 'skip$
+ { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
+ {
+ " " * bbl.etal *
+ }
+ { bbl.and space.word * editor #2 "{vv~}{ll}" format.name$
+ * }
+ if$
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.book.crossref}
+{ volume empty$
+ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
+ word.in
+ }
+ { bbl.volume volume tie.or.space.connect
+ bbl.of space.word *
+ }
+ if$
+ editor empty$
+ editor field.or.null author field.or.null =
+ or
+ { key empty$
+ { series empty$
+ { "need editor, key, or series for " cite$ * " to crossref " *
+ crossref * warning$
+ "" *
+ }
+ { series emphasize * }
+ if$
+ }
+ { key * }
+ if$
+ }
+ { format.crossref.editor * }
+ if$
+ " \cite{" * crossref * "}" *
+}
+
+FUNCTION {format.incoll.inproc.crossref}
+{
+ editor empty$
+ editor field.or.null author field.or.null =
+ or
+ { key empty$
+ { booktitle empty$
+ { "need editor, key, or booktitle for " cite$ * " to crossref " *
+ crossref * warning$
+ ""
+ }
+ { word.in booktitle * }
+ if$
+ }
+ { word.in key * " " *}
+ if$
+ }
+ { word.in format.crossref.editor * " " *}
+ if$
+ " \cite{" * crossref * "}" *
+}
+
+FUNCTION {format.org.or.pub}
+{ 't :=
+ ""
+ year empty$
+ { "empty year in " cite$ * warning$ }
+ 'skip$
+ if$
+ address empty$ t empty$ and
+ year empty$ and
+ 'skip$
+ {
+ t empty$
+ { address empty$
+ 'skip$
+ { address * }
+ if$
+ }
+ { t *
+ address empty$
+ 'skip$
+ { ", " * address * }
+ if$
+ }
+ if$
+ year empty$
+ 'skip$
+ { t empty$ address empty$ and
+ 'skip$
+ { ", " * }
+ if$
+ year *
+ }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.publisher.address}
+{ publisher empty$
+ { "empty publisher in " cite$ * warning$
+ ""
+ }
+ { publisher }
+ if$
+ format.org.or.pub
+}
+
+FUNCTION {format.organization.address}
+{ organization empty$
+ { "" }
+ { organization }
+ if$
+ format.org.or.pub
+}
+
+FUNCTION {make.href.null}
+{
+ pop$
+}
+FUNCTION {make.href.hypertex}
+{
+ "\special {html: }" * swap$ *
+ "\special {html:}" *
+}
+FUNCTION {make.href.hyperref}
+{
+ "\href {" swap$ * "} {\path{" * swap$ * "}}" *
+}
+FUNCTION {make.href}
+{ hrefform #2 =
+ 'make.href.hyperref % hrefform = 2
+ { hrefform #1 =
+ 'make.href.hypertex % hrefform = 1
+ 'make.href.null % hrefform = 0 (or anything else)
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.url}
+{ inlinelinks #1 = url empty$ or
+ { "" }
+ { hrefform #1 =
+ { % special case -- add HyperTeX specials
+ urlintro "\url{" url * "}" * url make.href.hypertex * }
+ { urlintro "\url{" * url * "}" * }
+ if$
+ }
+ if$
+}
+
+FUNCTION {format.eprint}
+{ eprint empty$
+ { "" }
+ { eprintprefix eprint * eprinturl eprint * make.href }
+ if$
+}
+
+FUNCTION {format.doi}
+{ doi empty$
+ { "" }
+ { doiprefix doi * doiurl doi * make.href }
+ if$
+}
+
+FUNCTION {output.url}
+{ url empty$
+ 'skip$
+ { new.block
+ format.url output
+ format.lastchecked output
+ }
+ if$
+}
+
+FUNCTION {output.web.refs}
+{
+ new.block
+ output.url
+ addeprints eprint empty$ not and
+ { format.eprint output.nonnull }
+ 'skip$
+ if$
+ adddoiresolver doi empty$ not and
+ { format.doi output.nonnull }
+ 'skip$
+ if$
+}
+
+FUNCTION {output.bibitem}
+{ outside.brackets 'bracket.state :=
+ output.bibitem.original
+ inlinelinks url empty$ not and
+ { #1 'makeinlinelink := }
+ { #0 'makeinlinelink := }
+ if$
+}
+
+FUNCTION {fin.entry}
+{ output.web.refs % urlbst
+ makeinlinelink % ooops, it appears we didn't have a title for inlinelink
+ { setup.inlinelink % add some artificial link text here, as a fallback
+ "[link]" output.nonnull }
+ 'skip$
+ if$
+ bracket.state close.brackets = % urlbst
+ { "]" * }
+ 'skip$
+ if$
+ fin.entry.original
+}
+
+FUNCTION {webpage}
+{ output.bibitem
+ author empty$
+ { editor empty$
+ 'skip$ % author and editor both optional
+ { format.editors output.nonnull }
+ if$
+ }
+ { editor empty$
+ { format.authors output.nonnull }
+ { "can't use both author and editor fields in " cite$ * warning$ }
+ if$
+ }
+ if$
+ new.block
+ title empty$ 'skip$ 'setup.inlinelink if$
+ format.title "title" output.check
+ inbrackets "online" output
+ new.block
+ year empty$
+ 'skip$
+ { format.date "year" output.check }
+ if$
+ % We don't need to output the URL details ('lastchecked' and 'url'),
+ % because fin.entry does that for us, using output.web.refs. The only
+ % reason we would want to put them here is if we were to decide that
+ % they should go in front of the rather miscellaneous information in 'note'.
+ new.block
+ note output
+ fin.entry
+}
+
+FUNCTION {article}
+{ output.bibitem
+ format.authors "author" output.check
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.title "title" output.check
+ crossref missing$
+ { journal
+ "journal" output.check
+ % add.blank
+ before.all 'output.state :=
+ format.vol.num.pages output
+ }
+ { format.article.crossref output.nonnull
+ format.pages output
+ }
+ if$
+ format.journal.pages
+ format.note output
+ pages empty$
+ { format.date "year" output.check }
+ 'skip$
+ if$
+ fin.entry
+ write.url
+}
+
+FUNCTION {book}
+{ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check
+ }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.btitle "title" output.check
+ crossref missing$
+ { format.edition output
+ format.bvolume output
+ format.number.series output
+ format.publisher.address output
+ }
+ {
+ format.book.crossref output.nonnull
+ }
+ if$
+ format.note output
+ fin.entry
+ write.url
+}
+
+FUNCTION {booklet}
+{ output.bibitem
+ format.authors output
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.title "title" output.check
+ howpublished output
+ address output
+ format.note output
+ format.date "year" output.check
+ fin.entry
+ write.url
+}
+
+FUNCTION {inbook}
+{ output.bibitem
+ author empty$
+ { format.editors "author and editor" output.check
+ }
+ { format.authors output.nonnull
+ crossref missing$
+ { "author and editor" editor either.or.check }
+ 'skip$
+ if$
+ }
+ if$
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.btitle "title" output.check
+ crossref missing$
+ {
+ format.edition output
+ format.bvolume output
+ format.number.series output
+ format.publisher.address output
+ format.chapter.pages "chapter and pages" output.check
+ }
+ {
+ format.chapter.pages "chapter and pages" output.check
+ format.book.crossref output.nonnull
+ }
+ if$
+ format.pages "pages" output.check
+ format.note output
+ fin.entry
+ write.url
+}
+
+FUNCTION {incollection}
+{ output.bibitem
+ format.authors "author" output.check
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.title "title" output.check
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ format.edition output
+ format.bvolume output
+ format.number.series output
+ format.publisher.address output
+ format.chapter.pages output
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ format.chapter.pages output
+ }
+ if$
+ format.pages "pages" output.check
+ format.note output
+ fin.entry
+ write.url
+}
+
+FUNCTION {inproceedings}
+{ output.bibitem
+ format.authors "author" output.check
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.title "title" output.check
+ crossref missing$
+ { format.in.ed.booktitle "booktitle" output.check
+ format.edition output
+ format.bvolume output
+ format.number.series output
+ publisher empty$
+ { format.organization.address output }
+ { organization output
+ format.publisher.address output
+ }
+ if$
+ }
+ { format.incoll.inproc.crossref output.nonnull
+ }
+ if$
+ format.pages "pages" output.check
+ format.note output
+ fin.entry
+ write.url
+}
+
+FUNCTION {conference} { inproceedings }
+
+FUNCTION {manual}
+{ output.bibitem
+ author empty$
+ { organization empty$
+ 'skip$
+ { organization output.nonnull
+ address output
+ }
+ if$
+ }
+ { format.authors output.nonnull }
+ if$
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.btitle "title" output.check
+ author empty$
+ { organization empty$
+ {
+ address output
+ }
+ 'skip$
+ if$
+ }
+ {
+ organization output
+ address output
+ }
+ if$
+ format.edition output
+ format.note output
+ format.date "year" output.check
+ fin.entry
+ write.url
+}
+
+FUNCTION {mastersthesis}
+{ output.bibitem
+ format.authors "author" output.check
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.title "title" output.check
+ bbl.mthesis format.thesis.type output.nonnull
+ school "school" output.check
+ address output
+ format.note output
+ format.date "year" output.check
+ fin.entry
+ write.url
+}
+
+FUNCTION {misc}
+{ output.bibitem
+ format.authors output
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.title output
+ howpublished output
+ format.note output
+ format.date "year" output.check
+ fin.entry
+ write.url
+ empty.misc.check
+}
+
+FUNCTION {phdthesis}
+{ output.bibitem
+ format.authors "author" output.check
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.title "title" output.check
+ bbl.phdthesis format.thesis.type output.nonnull
+ school "school" output.check
+ address output
+ format.note output
+ format.date "year" output.check
+ fin.entry
+ write.url
+}
+
+FUNCTION {proceedings}
+{ output.bibitem
+ editor empty$
+ { organization output }
+ { format.editors output.nonnull }
+ if$
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.btitle "title" output.check
+ format.bvolume output
+ format.number.series output
+ editor empty$
+ { publisher empty$
+ 'skip$
+ {
+ format.publisher.address output
+ }
+ if$
+ }
+ { publisher empty$
+ {
+ format.organization.address output }
+ {
+ organization output
+ format.publisher.address output
+ }
+ if$
+ }
+ if$
+ format.note output
+ fin.entry
+ write.url
+}
+
+FUNCTION {techreport}
+{ output.bibitem
+ format.authors "author" output.check
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.title "title" output.check
+ format.tr.number output.nonnull
+ institution "institution" output.check
+ address output
+ format.note output
+ format.date "year" output.check
+ fin.entry
+ write.url
+}
+
+FUNCTION {unpublished}
+{ output.bibitem
+ format.authors "author" output.check
+ title empty$ 'skip$ 'setup.inlinelink if$ % urlbst
+ format.title "title" output.check
+ format.note "note" output.check
+ format.date "year" output.check
+ fin.entry
+ write.url
+}
+
+FUNCTION {default.type} { misc }
+
+READ
+
+STRINGS { longest.label }
+
+INTEGERS { number.label longest.label.width }
+
+FUNCTION {initialize.longest.label}
+{ "" 'longest.label :=
+ #1 'number.label :=
+ #0 'longest.label.width :=
+}
+
+FUNCTION {longest.label.pass}
+{ number.label int.to.str$ 'label :=
+ number.label #1 + 'number.label :=
+ label width$ longest.label.width >
+ { label 'longest.label :=
+ label width$ 'longest.label.width :=
+ }
+ 'skip$
+ if$
+}
+
+EXECUTE {initialize.longest.label}
+
+ITERATE {longest.label.pass}
+
+FUNCTION {begin.bib}
+{ preamble$ empty$
+ 'skip$
+ { preamble$ write$ newline$ }
+ if$
+ "\begin{thebibliography}{" longest.label * "}" *
+ write$ newline$
+ "\expandafter\ifx\csname url\endcsname\relax"
+ write$ newline$
+ " \def\url#1{\texttt{#1}}\fi"
+ write$ newline$
+ "\expandafter\ifx\csname urlprefix\endcsname\relax\def\urlprefix{URL }\fi"
+ write$ newline$
+ "\expandafter\ifx\csname href\endcsname\relax"
+ write$ newline$
+ " \def\href#1#2{#2} \def\path#1{#1}\fi"
+ write$ newline$
+}
+
+EXECUTE {begin.bib}
+
+EXECUTE {init.urlbst.variables}
+EXECUTE {init.state.consts}
+
+ITERATE {call.type$}
+
+FUNCTION {end.bib}
+{ newline$
+ "\end{thebibliography}" write$ newline$
+}
+
+EXECUTE {end.bib}
+%% End of customized bst file
+%%
+%% End of file `elsarticle-num.bst'.
+
+
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsevier-harvard.csl b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsevier-harvard.csl
new file mode 100644
index 00000000000..0ef7b190f55
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/bib/elsevier-harvard.csl
@@ -0,0 +1,239 @@
+
+
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/doc-class.tex b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/doc-class.tex
deleted file mode 100644
index 7c0a6b63794..00000000000
--- a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/doc-class.tex
+++ /dev/null
@@ -1,9 +0,0 @@
-\documentclass[$if(layout)$$layout$$else$$for(classoption)$$classoption$$sep$,$endfor$$endif$]{elsarticle} %review=doublespace preprint=single 5p=2 column
-
-$if(journal)$
- \journal{$journal$} % Sets Journal name
-$endif$
-$if(number-lines)$
-\usepackage{lineno} % add
- \linenumbers % turns line numbering on
-$endif$
\ No newline at end of file
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/elsarticle.cls b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/elsarticle.cls
index cf20bdff618..58b0bacd004 100644
--- a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/elsarticle.cls
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/elsarticle.cls
@@ -6,32 +6,33 @@
%%
%% elsarticle.dtx (with options: `class')
%%
-%% Copyright 2007-2020 Elsevier Ltd
+%% Copyright 2007-2025 Elsevier Ltd
%%
%% This file is part of the 'Elsarticle Bundle'.
%% -------------------------------------------
%%
%% It may be distributed under the conditions of the LaTeX Project Public
-%% License, either version 1.2 of this license or (at your option) any
+%% License, either version 1.3 of this license or (at your option) any
%% later version. The latest version of this license is in
%% http://www.latex-project.org/lppl.txt
-%% and version 1.2 or later is part of all distributions of LaTeX
+%% and version 1.3 or later is part of all distributions of LaTeX
%% version 1999/12/01 or later.
%%
%% The list of all files belonging to the 'Elsarticle Bundle' is
%% given in the file `manifest.txt'.
%%
+
%%
%%
%%
- \def\RCSfile{elsarticle}%
- \def\RCSversion{3.3}%
- \def\RCSdate{2020/11/20}%
- \def\@shortjnl{\relax}
- \def\@journal{Elsevier Ltd}
- \def\@company{Elsevier Ltd}
- \def\@issn{000-0000}
- \def\@shortjid{elsarticle}
+\def\RCSfile{elsarticle}%
+\def\RCSversion{3.4c}%
+\def\RCSdate{2025/01/11}%
+\def\@shortjnl{\relax}
+\def\@journal{Elsevier Ltd}
+\def\@company{Elsevier Ltd}
+\def\@issn{000-0000}
+\def\@shortjid{elsarticle}
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesClass{\@shortjid}[\RCSdate, \RCSversion: \@journal]
\def\ABD{\AtBeginDocument}
@@ -43,9 +44,11 @@
\newif\ifuseexplthreefunctions \useexplthreefunctionsfalse
+\RequirePackage[T1]{fontenc}
+
\IfFileExists{expl3.sty}{%
- \global\useexplthreefunctionstrue%
- \RequirePackage{expl3}}{}
+ \global\useexplthreefunctionstrue%
+ \RequirePackage{expl3}}{}
\ifuseexplthreefunctions\relax%
\IfFileExists{xparse.sty}{\RequirePackage{xparse}}{}
\IfFileExists{etoolbox.sty}{\RequirePackage{etoolbox}}{}
@@ -56,18 +59,18 @@
\@bls=\baselineskip
\def\@finalWarning{%
- *****************************************************\MessageBreak
- This document is typeset in the CRC style which\MessageBreak
- is not suitable for submission.\MessageBreak
- \MessageBreak
- Please typeset again using 'preprint' option\MessageBreak
- for creating PDF suitable for submission.\MessageBreak
- ******************************************************\MessageBreak
+ *****************************************************\MessageBreak
+ This document is typeset in the CRC style which\MessageBreak
+ is not suitable for submission.\MessageBreak
+ \MessageBreak
+ Please typeset again using 'preprint' option\MessageBreak
+ for creating PDF suitable for submission.\MessageBreak
+ ******************************************************\MessageBreak
}
\DeclareOption{preprint}{\global\preprinttrue
- \gdef\@blstr{1}\xdef\jtype{0}%
- \AtBeginDocument{\@twosidefalse\@mparswitchfalse}}
+ \gdef\@blstr{1}\xdef\jtype{0}%
+ \AtBeginDocument{\@twosidefalse\@mparswitchfalse}}
\DeclareOption{nopreprintline}{\global\nopreprintlinetrue}
\DeclareOption{final}{\gdef\@blstr{1}\global\preprintfalse}
\DeclareOption{review}{\global\preprinttrue\gdef\@blstr{1.5}}
@@ -77,33 +80,33 @@
\DeclareOption{nonatbib}{\global\nonatbibtrue}
\DeclareOption{longtitle}{\global\longmktitletrue}
\DeclareOption{5p}{\xdef\jtype{5}\global\preprintfalse
- \ExecuteOptions{twocolumn}}
- \def\jtype{0}
+ \ExecuteOptions{twocolumn}}
+ \def\jtype{0}
\DeclareOption{3p}{\xdef\jtype{3}\global\preprintfalse}
\DeclareOption{1p}{\xdef\jtype{1}\global\preprintfalse
- \AtBeginDocument{\@twocolumnfalse}}
+ \AtBeginDocument{\@twocolumnfalse}}
\DeclareOption{times}{\IfFileExists{txfonts.sty}%
- {\AtEndOfClass{\RequirePackage{txfonts}%
- \gdef\ttdefault{cmtt}%
- \let\iint\relax
- \let\iiint\relax
- \let\iiiint\relax
- \let\idotsint\relax
- \let\openbox\relax}}{\AtEndOfClass{\RequirePackage{times}}}}
+ {\AtEndOfClass{\RequirePackage{txfonts}%
+ \gdef\ttdefault{cmtt}%
+ \let\iint\relax
+ \let\iiint\relax
+ \let\iiiint\relax
+ \let\idotsint\relax
+ \let\openbox\relax}}{\AtEndOfClass{\RequirePackage{times}}}}
\DeclareOption{endfloat}{\IfFileExists{endfloat.sty}
- {\AtEndOfClass{\RequirePackage[markers]{endfloat}}}{}}
+ {\AtEndOfClass{\RequirePackage[markers]{endfloat}}}{}}
\DeclareOption{endfloats}{\IfFileExists{endfloat.sty}
- {\AtEndOfClass{\RequirePackage[markers]{endfloat}}}{}}
+ {\AtEndOfClass{\RequirePackage[markers]{endfloat}}}{}}
\DeclareOption{numafflabel}
- {\AtBeginDocument{\def\theaffn{\arabic{affn}}}} %*%
+ {\AtBeginDocument{\def\theaffn{\arabic{affn}}}} %*%
\DeclareOption{lefttitle}
- {\AtBeginDocument{\def\elsarticletitlealign{flushleft}}} %*%
+ {\AtBeginDocument{\def\elsarticletitlealign{flushleft}}} %*%
\DeclareOption{centertitle}
- {\AtBeginDocument{\def\elsarticletitlealign{center}}} %*%
+ {\AtBeginDocument{\def\elsarticletitlealign{center}}} %*%
\DeclareOption{reversenotenum}
- {\AtBeginDocument{\def\theaffn{\arabic{affn}}
- \def\thefnote{\alph{fnote}}}}
+ {\AtBeginDocument{\def\theaffn{\arabic{affn}}
+ \def\thefnote{\alph{fnote}}}}
\DeclareOption{doubleblind}{\doubleblindtrue}
\ExecuteOptions{a4paper,10pt,oneside,onecolumn,number,preprint,centertitle}
@@ -118,11 +121,11 @@
\def\useelstitle{}
\def\title#1{\g@addto@macro\@title{#1%
- \global\let\tnoteref\@gobble}%
- \g@addto@macro\useelstitle{#1}}
+ \global\let\tnoteref\@gobble}%
+ \g@addto@macro\useelstitle{#1}}
\def\elsLabel#1{\@bsphack\protected@write\@auxout{}%
- {\string\Newlabel{#1}{\@currentlabel}}\@esphack}
+ {\string\Newlabel{#1}{\@currentlabel}}\@esphack}
\def\Newlabel#1#2{\expandafter\xdef\csname X@#1\endcsname{#2}}
\def\elsRef#1{\@ifundefined{X@#1}{0}{\csname X@#1\endcsname}}
@@ -130,12 +133,12 @@
\let\@tnotemark\@empty
\ifdoubleblind
- \def\tnotemark[#1]{}
+ \def\tnotemark[#1]{}
\else
- \def\tnotemark[#1]{\@for\mytmark:=#1\do{%
- \expandafter\ifcase\elsRef{\mytmark}\or$^{\star}$\or
- $^{,\star\star}$\fi
- }%
+ \def\tnotemark[#1]{\@for\mytmark:=#1\do{%
+ \expandafter\ifcase\elsRef{\mytmark}\or$^{\star}$\or
+ $^{,\star\star}$\fi
+ }%
}
\fi
@@ -143,51 +146,51 @@
\let\@tnotes\@empty
\newcounter{tnote}
\def\tnotetext[#1]#2{\g@addto@macro\@tnotes{%
- \stepcounter{tnote}\elsLabel{#1}%
- \def\thefootnote{\ifcase\c@tnote\or$\star$\or$\star\star$\fi}%
- \footnotetext{#2}}}
+ \stepcounter{tnote}\elsLabel{#1}%
+ \def\thefootnote{\ifcase\c@tnote\or$\star$\or$\star\star$\fi}%
+ \footnotetext{#2}}}
\let\@nonumnotes\@empty
\def\nonumnote#1{\g@addto@macro\@nonumnotes{%
- \let\thefootnote\relax\footnotetext{#1}}}
+ \let\thefootnote\relax\footnotetext{#1}}}
\newcounter{fnote}
\def\thefnote{\arabic{fnote}}
\def\fnmark[#1]{\let\comma\@empty
- \def\@fnmark{\@for\@@fnmark:=#1\do{%
- \edef\fnotenum{\@ifundefined{X@\@@fnmark}{1}{\elsRef{\@@fnmark}}}%
- \unskip\comma\fnotenum\let\comma,}}%
+ \def\@fnmark{\@for\@@fnmark:=#1\do{%
+ \edef\fnotenum{\@ifundefined{X@\@@fnmark}{1}{\elsRef{\@@fnmark}}}%
+ \unskip\comma\fnotenum\let\comma,}}%
}
\def\fnref#1{\fnmark[#1]}
\let\@fnotes\@empty\let\@fnmark\@empty
\def\fntext[#1]#2{\g@addto@macro\@fnotes{%
- \refstepcounter{fnote}\elsLabel{#1}%
- \def\thefootnote{\c@fnote}%
- \global\setcounter{footnote}{\c@fnote}%
- \footnotetext{#2}}}
+ \refstepcounter{fnote}\elsLabel{#1}%
+ \def\thefootnote{\thefnote}%
+ \global\setcounter{footnote}{\c@fnote}%
+ \footnotetext{#2}}}
\def\cormark[#1]{\edef\cnotenum{\elsRef{#1}}%
- \unskip\textsuperscript{\sep\ifcase\cnotenum\or
- $\ast$\or$\ast\ast$\fi\hspace{-1pt}}\let\sep=,}
+ \unskip\textsuperscript{\sep\ifcase\cnotenum\or
+ $\ast$\or$\ast\ast$\fi\hspace{-1pt}}\let\sep=,}
\let\@cormark\@empty
\let\@cornotes\@empty
\newcounter{cnote}
\def\cortext[#1]#2{\g@addto@macro\@cornotes{%
- \refstepcounter{cnote}\elsLabel{#1}%
- \def\thefootnote{\ifcase\thecnote\or$\ast$\or
- $\ast\ast$\fi}%
- \footnotetext{#2}}}
+ \refstepcounter{cnote}\elsLabel{#1}%
+ \def\thefootnote{\ifcase\thecnote\or$\ast$\or
+ $\ast\ast$\fi}%
+ \footnotetext{#2}}}
\let\@corref\@empty
\def\corref#1{\edef\cnotenum{\elsRef{#1}}%
- \edef\@corref{\ifcase\cnotenum\or
- $\ast$\or$\ast\ast$\fi\hskip-1pt}}
+ \edef\@corref{\ifcase\cnotenum\or
+ $\ast$\or$\ast\ast$\fi\hskip-1pt}}
\def\resetTitleCounters{\c@cnote=0
- \c@fnote=0 \c@tnote=0 \c@footnote=0}
+ \c@fnote=0 \c@tnote=0 \c@footnote=0}
\let\eadsep\@empty
\def\@elseads{}
@@ -200,36 +203,36 @@
\gdef\ead{\@ifnextchar[{\@uad}{\@ead}}
\gdef\@ead#1{\bgroup
- \def\_{\underscorechar}%
- \def\{{\lbracechar}%
- \def~{\hashchar}%
- \def\}{\rbracechar}%
- \edef\tmp{\the\@eadauthor}%
- \immediate\write\@auxout{\string\emailauthor
- {#1}{\expandafter\strip@prefix\meaning\tmp}}%
- \egroup
+ \def\_{\underscorechar}%
+ \def\{{\lbracechar}%
+ \def~{\hashchar}%
+ \def\}{\rbracechar}%
+ \edef\tmp{\the\@eadauthor}%
+ \immediate\write\@auxout{\string\emailauthor
+ {#1}{\expandafter\strip@prefix\meaning\tmp}}%
+ \egroup
}
\newcounter{ead}
\gdef\emailauthor#1#2{\stepcounter{ead}%
- \g@addto@macro\@elseads{\raggedright%
- \let\corref\@gobble\def\@@tmp{#1}%
- \eadsep{\ttfamily\expandafter\strip@prefix\meaning\@@tmp}
- (#2)\def\eadsep{\unskip,\space}}%
+ \g@addto@macro\@elseads{\raggedright%
+ \let\corref\@gobble\def\@@tmp{#1}%
+ \eadsep{\ttfamily\expandafter\strip@prefix\meaning\@@tmp}
+ (#2)\def\eadsep{\unskip,\space}}%
}
\gdef\@uad[#1]#2{\bgroup
- \def~{\hashchar}%
- \def\_{\underscorechar}%
- \def~{\hashchar}%
- \def\}{\rbracechar}%
- \edef\tmp{\the\@eadauthor}
- \immediate\write\@auxout{\string\urlauthor
- {#2}{\expandafter\strip@prefix\meaning\tmp}}%
- \egroup
+ \def~{\hashchar}%
+ \def\_{\underscorechar}%
+ \def~{\hashchar}%
+ \def\}{\rbracechar}%
+ \edef\tmp{\the\@eadauthor}
+ \immediate\write\@auxout{\string\urlauthor
+ {#2}{\expandafter\strip@prefix\meaning\tmp}}%
+ \egroup
}
\gdef\urlauthor#1#2{\g@addto@macro\@elsuads{\let\corref\@gobble%
- \def\@@tmp{#1}\raggedright\eadsep
- {\ttfamily\expandafter\strip@prefix\meaning\@@tmp}\space(#2)%
- \def\eadsep{\unskip,\space}}%
+ \def\@@tmp{#1}\raggedright\eadsep
+ {\ttfamily\expandafter\strip@prefix\meaning\@@tmp}\space(#2)%
+ \def\eadsep{\unskip,\space}}%
}
\def\elsauthors{}
@@ -240,422 +243,439 @@
\let\authorsep\@empty
\let\prelimauthorsep\@empty
\let\sep\@empty
-\newcounter{author}
+\newcounter{elsarticle@author}
\def\author{\@ifnextchar[{\@@author}{\@author}}
\newtoks\@eadauthor
\def\@@author[#1]#2{%
- \g@addto@macro\elsprelimauthors{%
- \prelimauthorsep#2%
- \def\prelimauthorsep{\unskip,\space}}%
- \g@addto@macro\elsauthors{%
- \def\baselinestretch{1}%
- \authorsep#2\unskip\textsuperscript{%#1%
- \@for\@@affmark:=#1\do{%
- \edef\affnum{\@ifundefined{X@\@@affmark}{1}{\elsRef{\@@affmark}}}%
- \unskip\sep\affnum\let\sep=,}%
- \ifx\@fnmark\@empty\else\unskip\sep\@fnmark\let\sep=,\fi
- \ifx\@corref\@empty\else\unskip\sep\@corref\let\sep=,\fi
- }%
- \def\authorsep{\unskip,\space}%
- \global\let\sep\@empty\global\let\@corref\@empty
- \global\let\@fnmark\@empty}%
- \@eadauthor={#2}%
- \g@addto@macro\useauthors{#2; }%
+ \g@addto@macro\elsprelimauthors{%
+ \prelimauthorsep#2%
+ \def\prelimauthorsep{\unskip,\space}}%
+ \g@addto@macro\elsauthors{%
+ \def\baselinestretch{1}%
+ \authorsep#2\unskip\textsuperscript{%#1%
+ \@for\@@affmark:=#1\do{%
+ \edef\affnum{\@ifundefined{X@\@@affmark}{1}{\elsRef{\@@affmark}}}%
+ \unskip\sep\affnum\let\sep=,}%
+ \ifx\@fnmark\@empty\else\unskip\sep\@fnmark\let\sep=,\fi
+ \ifx\@corref\@empty\else\unskip\sep\@corref\let\sep=,\fi
+ }%
+ \def\authorsep{\unskip,\space}%
+ \global\let\sep\@empty\global\let\@corref\@empty
+ \global\let\@fnmark\@empty}%
+ \@eadauthor={#2}%
+ \g@addto@macro\useauthors{#2; }%
}
\def\@author#1{%
- \g@addto@macro\elsprelimauthors{%
- \prelimauthorsep#1%
- \def\prelimauthorsep{\unskip,\space}}%
- \g@addto@macro\elsauthors{\normalsize%
- \def\baselinestretch{1}%
- \upshape\authorsep#1\unskip\textsuperscript{%
- \ifx\@fnmark\@empty\else\unskip\sep\@fnmark\let\sep=,\fi
- \ifx\@corref\@empty\else\unskip\sep\@corref\let\sep=,\fi
- }%
- \def\authorsep{\unskip,\space}%
- \global\let\@fnmark\@empty
- \global\let\@corref\@empty \global\let\sep\@empty}%
- \@eadauthor={#1}%
- \g@addto@macro\useauthors{#1; }%
+ \g@addto@macro\elsprelimauthors{%
+ \prelimauthorsep#1%
+ \def\prelimauthorsep{\unskip,\space}}%
+ \g@addto@macro\elsauthors{\normalsize%
+ \def\baselinestretch{1}%
+ \upshape\authorsep#1\unskip\textsuperscript{%
+ \ifx\@fnmark\@empty\else\unskip\sep\@fnmark\let\sep=,\fi
+ \ifx\@corref\@empty\else\unskip\sep\@corref\let\sep=,\fi
+ }%
+ \def\authorsep{\unskip,\space}%
+ \global\let\@fnmark\@empty
+ \global\let\@corref\@empty \global\let\sep\@empty}%
+ \@eadauthor={#1}%
+ \g@addto@macro\useauthors{#1; }%
}
\AtBeginDocument{%
- \@ifpackageloaded{hyperref}{%
- \expandafter\gdef\csname Hy@title\endcsname{\useelstitle}%
- \expandafter\gdef\csname Hy@author\endcsname{\useauthors}%
- }{}
+ \@ifpackageloaded{hyperref}{%
+ \expandafter\gdef\csname Hy@title\endcsname{\useelstitle}%
+ \expandafter\gdef\csname Hy@author\endcsname{\useauthors}%
+ }{}
}
\def\elsaddress{}
\def\addsep{\par\vskip6pt}
\def\@alph#1{%
- \ifcase#1\or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or
- l\or m\or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or
- y\or z%
- \or aa\or ab\or ac\or ad\or ae\or af\or ag\or ah\or ai\or aj\or
- ak\or al\or am\or an\or ao\or ap\or aq\or ar\or as\or at\or au\or
- av\or aw\or ax\or ay\or az%
- \or ba\or bb\or bc\or bd\or be\or bf\or bg\or bh\or bi\or bj\or
- bk\or bl\or bm\or bn\or bo\or bp\or bq\or br\or bs\or bt\or bu\or
- bv\or bw\or bx\or by\or bz%
- \or ca\or cb\or cc\or cd\or ce\or cf\or cg\or ch\or ci\or cj\or
- ck\or cl\or cm\or cn\or co\or cp\or cq\or cr\or cs\or ct\or cu\or
- cv\or cw\or cx\or cy\or cz%
- \or da\or db\or dc\or dd\or de\or df\or dg\or dh\or di\or dj\or
- dk\or dl\or dm\or dn\or do\or dp\or dq\or dr\or ds\or dt\or du\or
- dv\or dw\or dx\or dy\or dz%
- \or ea\or eb\or ec\or ed\or ee\or ef\or eg\or eh\or ei\or ej\or
- ek\or el\or em\or en\or eo\or ep\or eq\or er\or es\or et\or eu\or
- ev\or ew\or ex\or ey\or ez%
- \or fa\or fb\or fc\or fd\or fe\or ff\or fg\or fh\or fi\or fj\or
- fk\or fl\or fm\or fn\or fo\or fp\or fq\or fr\or fs\or ft\or fu\or
- fv\or fw\or fx\or fy\or fz%
- \or ga\or gb\or gc\or gd\or ge\or gf\or gg\or gh\or gi\or gj\or
- gk\or gl\or gm\or gn\or go\or gp\or gq\or gr\or gs\or gt\or gu\or
- gv\or gw\or gx\or gy\or gz%
- \else\@ctrerr\fi}
+ \ifcase#1\or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or
+ l\or m\or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or
+ y\or z%
+ \or aa\or ab\or ac\or ad\or ae\or af\or ag\or ah\or ai\or aj\or
+ ak\or al\or am\or an\or ao\or ap\or aq\or ar\or as\or at\or au\or
+ av\or aw\or ax\or ay\or az%
+ \or ba\or bb\or bc\or bd\or be\or bf\or bg\or bh\or bi\or bj\or
+ bk\or bl\or bm\or bn\or bo\or bp\or bq\or br\or bs\or bt\or bu\or
+ bv\or bw\or bx\or by\or bz%
+ \or ca\or cb\or cc\or cd\or ce\or cf\or cg\or ch\or ci\or cj\or
+ ck\or cl\or cm\or cn\or co\or cp\or cq\or cr\or cs\or ct\or cu\or
+ cv\or cw\or cx\or cy\or cz%
+ \or da\or db\or dc\or dd\or de\or df\or dg\or dh\or di\or dj\or
+ dk\or dl\or dm\or dn\or do\or dp\or dq\or dr\or ds\or dt\or du\or
+ dv\or dw\or dx\or dy\or dz%
+ \or ea\or eb\or ec\or ed\or ee\or ef\or eg\or eh\or ei\or ej\or
+ ek\or el\or em\or en\or eo\or ep\or eq\or er\or es\or et\or eu\or
+ ev\or ew\or ex\or ey\or ez%
+ \or fa\or fb\or fc\or fd\or fe\or ff\or fg\or fh\or fi\or fj\or
+ fk\or fl\or fm\or fn\or fo\or fp\or fq\or fr\or fs\or ft\or fu\or
+ fv\or fw\or fx\or fy\or fz%
+ \or ga\or gb\or gc\or gd\or ge\or gf\or gg\or gh\or gi\or gj\or
+ gk\or gl\or gm\or gn\or go\or gp\or gq\or gr\or gs\or gt\or gu\or
+ gv\or gw\or gx\or gy\or gz%
+ \else\@ctrerr\fi}
\newcounter{affn}
\renewcommand\theaffn{\alph{affn}}
\ifuseexplthreefunctions\relax%
- \ExplSyntaxOn
- \def\ca_affitem_postskip{\mbox{~}\unskip\ignorespaces}
- %%Author Address
- \DeclareDocumentCommand \ca_organization { O{,} m }
- {
- % #2 #1\mbox{~}\unskip\ignorespaces
- \csgappto { ca_affiliation_values } { #2 #1\ca_affitem_postskip }
- }
- \DeclareDocumentCommand \ca_postal_code { O{,} m }
- {
- % #2 #1\mbox{~}\unskip\ignorespaces
- \csgappto { ca_affiliation_values } { #2 #1\ca_affitem_postskip }
- }
- \DeclareDocumentCommand \ca_aff_city { O{,} m }
- {
- % #2 #1\mbox{~}\unskip\ignorespaces
- \csgappto { ca_affiliation_values } { #2 #1\ca_affitem_postskip }
- }
- \DeclareDocumentCommand \ca_address_line { O{,}m }
- {
- % #2 #1\mbox{~}\unskip\ignorespaces
- \csgappto { ca_affiliation_values } { #2 #1\ca_affitem_postskip }
- }
- \DeclareDocumentCommand \ca_state { O{,} m }
- {
- % #2 #1\mbox{~}\unskip\ignorespaces
- \csgappto { ca_affiliation_values } { #2 #1\ca_affitem_postskip }
- }
- \DeclareDocumentCommand \ca_country { O{ } m }
- {
- % #2 #1
- \csgappto { ca_affiliation_values } { #2 #1 }
- }
-
- \DeclareDocumentCommand \ca_stm_organization { O{,} m }
- {
- #2 #1\ca_affitem_postskip
- }
- \DeclareDocumentCommand \ca_stm_postal_code { O{,} m }
- {
- #2 #1\ca_affitem_postskip
- }
- \DeclareDocumentCommand \ca_stm_aff_city { O{,} m }
- {
- #2 #1\ca_affitem_postskip
- }
- \DeclareDocumentCommand \ca_stm_aff_address_line { O{,}m }
- {
- #2 #1\ca_affitem_postskip
- }
- \DeclareDocumentCommand \ca_stm_state { O{,} m }
- {
- #2 #1\ca_affitem_postskip
- }
- \DeclareDocumentCommand \ca_stm_country { O{ } m }
- {
- #2 #1
- }
-
- \keys_define:nn { stm / affiliation }
- {
- op .tl_set_x:N = \l_organization_punc_tl,
- oraganizationsep .tl_set_x:N = \l_organization_punc_tl,
- ap .tl_set_x:N = \l_address_line_punc_tl,
- addresslinesep .tl_set_x:N = \l_address_line_punc_tl,
- cp .tl_set_x:N = \l_city_punc_tl,
- citysep .tl_set_x:N = \l_city_punc_tl,
- pp .tl_set_x:N = \l_postal_code_punc_tl,
- postcodesep .tl_set_x:N = \l_postal_code_punc_tl,
- sp .tl_set_x:N = \l_state_punc_tl,
- statesep .tl_set_x:N = \l_state_punc_tl,
- o .code:n = { \ca_organization[\l_organization_punc_tl]{#1} },
- organization .code:n = { \ca_organization[\l_organization_punc_tl]{#1} },
- a .code:n = { \ca_address_line[\l_address_line_punc_tl]{#1} },
- addressline .code:n = { \ca_address_line[\l_address_line_punc_tl]{#1} },
- c .code:n = { \ca_aff_city[\l_city_punc_tl]{#1} },
- city .code:n = { \ca_aff_city[\l_city_punc_tl]{#1} },
- p .code:n = { \ca_postal_code[\l_postal_code_punc_tl]{#1} },
- postcode .code:n = { \ca_postal_code[\l_postal_code_punc_tl]{#1} },
- s .code:n = { \ca_state[\l_state_punc_tl]{#1} },
- state .code:n = { \ca_state[\l_state_punc_tl]{#1} },
- orp .tl_set_x:N = \l_organization_punc_tl,
- adp .tl_set_x:N = \l_address_line_punc_tl,
- cip .tl_set_x:N = \l_city_punc_tl,
- pcp .tl_set_x:N = \l_postal_code_punc_tl,
- stp .tl_set_x:N = \l_state_punc_tl,
- cyp .tl_set_x:N = \l_country_punc_tl,
- or .code:n = { \ca_organization[\l_organization_punc_tl]{#1} },
- ad .code:n = { \ca_address_line[\l_address_line_punc_tl]{#1} },
- ci .code:n = { \ca_aff_city[\l_city_punc_tl]{#1} },
- pc .code:n = { \ca_postal_code[\l_postal_code_punc_tl]{#1} },
- st .code:n = { \ca_state[\l_state_punc_tl]{#1} },
- cy .code:n = { \ca_country[\l_country_punc_tl]{#1} },
- country .code:n = { \ca_country[\l_country_punc_tl]{#1} },
- unknown .code:n = {
- \ifstrempty { #1 } {
- \csxappto { ca_affiliation_values }
- { {\l_keys_key_tl}~ }
- } {
- \csxappto { ca_affiliation_values }
- { {#1}~ }
- }
- }
- }
-
- \cs_set:Npn \__reset_affiliation:
- {
- \tl_gset:Nn \l_organization_punc_tl { , }
- \tl_gset:Nn \l_address_line_punc_tl { , }
- \tl_gset:Nn \l_city_punc_tl { , }
- \tl_gset:Nn \l_postal_code_punc_tl { , }
- \tl_gset:Nn \l_state_punc_tl { , }
- \tl_gset:Nn \l_country_punc_tl { }
- }
-
- \DeclareDocumentCommand\affiliation{ o m }{
- \__reset_affiliation:
- \csgdef { ca_affiliation_values } { }
- \IfNoValueTF { #2 }
- { }
- {
- \keys_set:nn { stm / affiliation } { #2 }
- }
- \csgappto{elsaddress}{
- \def\baselinestretch{1}%
- \refstepcounter{affn}
- \xdef\@currentlabel{\theaffn}
- \IfNoValueTF { #1 }
- { }
- { \elsLabel{#1} }
- \textsuperscript{\theaffn}}
- \csxappto{elsaddress}{
- \csuse { ca_affiliation_values }
- \par
- }
- }
- \ExplSyntaxOff
- \else%
- \def\caaffitempostskip{\space}
-
- \DeclareRobustCommand\caorganization[2][,]{%
- \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
- }
- \DeclareRobustCommand\capostalcode[2][,]{%
- \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
- }
- \DeclareRobustCommand\caaffcity[2][,]{%
- \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
- }
- \DeclareRobustCommand\caaddressline[2][,]{%
- \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
- }
- \DeclareRobustCommand\castate[2][,]{%
- \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
- }
- \DeclareRobustCommand\cacountry[2][,]{%
- \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
- }
- \DeclareRobustCommand\castmorganization[2][,]{%
- #2#1\caaffitempostskip%
- }
- \DeclareRobustCommand\castmpostalcode[2][,]{%
- #2#1\caaffitempostskip%
- }
- \DeclareRobustCommand\castmaffcity[2][,]{%
- #2#1\caaffitempostskip%
- }
- \DeclareRobustCommand\castmaddressline[2][,]{%
- #2#1\caaffitempostskip%
- }
- \DeclareRobustCommand\castmstate[2][,]{%
- #2#1\caaffitempostskip%
- }
- \DeclareRobustCommand\castmcountry[2][,]{%
- #2#1\caaffitempostskip%
- }
-
- \define@key{affiliation}{op}{\xdef\@organizationpunc{#1}}
- \define@key{affiliation}{orp}{\xdef\@organizationpunc{#1}}
- \define@key{affiliation}{organizationsep}{\xdef\@organizationpunc{#1}}
- \define@key{affiliation}{ap}{\xdef\@addresslinepunc{#1}}
- \define@key{affiliation}{adp}{\xdef\@addresslinepunc{#1}}
- \define@key{affiliation}{addresslinesep}{\xdef\@addresslinepunc{#1}}
- \define@key{affiliation}{cp}{\xdef\@citypunc{#1}}
- \define@key{affiliation}{cip}{\xdef\@citypunc{#1}}
- \define@key{affiliation}{cyp}{\xdef\@countrypunc{#1}}
- \define@key{affiliation}{citysep}{\xdef\@citypunc{#1}}
- \define@key{affiliation}{pp}{\xdef\@postcodepunc{#1}}
- \define@key{affiliation}{pop}{\xdef\@postcodepunc{#1}}
- \define@key{affiliation}{postcodesep}{\xdef\@postcodepunc{#1}}
- \define@key{affiliation}{sp}{\xdef\@statepunc{#1}}
- \define@key{affiliation}{stp}{\xdef\@statepunc{#1}}
- \define@key{affiliation}{statesep}{\xdef\@statepunc{#1}}
- \define@key{affiliation}{countrysep}{\xdef\@countrypunc{#1}}
-
- \define@key{affiliation}{organization}{%
- \caorganization[\@organizationpunc]{#1}}
- \define@key{affiliation}{addressline}{%
- \caaddressline[\@addresslinepunc]{#1}}
- \define@key{affiliation}{city}{%
- \caaffcity[\@citypunc]{#1}}
- \define@key{affiliation}{postcode}{%
- \capostalcode[\@postcodepunc]{#1}}
- \define@key{affiliation}{state}{%
- \castate[\@statepunc]{#1}}
- \define@key{affiliation}{or}{%
- \caorganization[\@organizationpunc]{#1}}
- \define@key{affiliation}{ad}{%
- \caaddressline[\@addresslinepunc]{#1}}
- \define@key{affiliation}{ci}{%
- \caaffcity[\@citypunc]{#1}}
- \define@key{affiliation}{po}{%
- \capostalcode[\@postcodepunc]{#1}}
- \define@key{affiliation}{st}{%
- \castate[\@statepunc]{#1}}
- \define@key{affiliation}{o}{%
- \caorganization[\@organizationpunc]{#1}}
- \define@key{affiliation}{a}{%
- \caaddressline[\@addresslinepunc]{#1}}
- \define@key{affiliation}{c}{%
- \cacity[\@citypunc]{#1}}
- \define@key{affiliation}{p}{%
- \capostcode[\@postcodepunc]{#1}}
- \define@key{affiliation}{s}{%
- \castate[\@statepunc]{#1}}
- \define@key{affiliation}{cy}{%
- \cacountry[\@countrypunc]{#1}}
- \define@key{affiliation}{country}{%
- \cacountry[\@countrypunc]{#1}}
-
- \gdef\@resetaffiliation{%
- \gdef\@organizationpunc{,}%
- \gdef\@addresslinepunc{,}%
- \gdef\@citypunc{,}%
- \gdef\@statepunc{,}%
- \gdef\@postcodepunc{,}%
- \gdef\@countrypunc{}%
- }
-
- \def\affiliation{\@ifnextchar[{\@@affiliation}{\@affiliation}}
-
- \newcommand*{\newstmrobustcmd}{}
- \protected\def\newstmrobustcmd{\@star@or@long\stmetb@new@command}
-
- \def\stmetb@new@command#1{\@testopt{\stmetb@newcommand#1}0}
-
- \def\stmetb@newcommand#1[#2]{%
- \@ifnextchar[%]
- {\stmetb@xargdef#1[#2]}
- {\ifx\l@ngrel@x\relax
- \let\l@ngrel@x\protected
- \else
- \protected\def\l@ngrel@x{\protected\long}%
- \fi
- \@argdef#1[#2]}}
-
- \long\def\stmetb@xargdef#1[#2][#3]#4{%
- \@ifdefinable#1{%
- \expandafter\protected
- \expandafter\def
- \expandafter#1%
- \expandafter{%
- \expandafter\@testopt
- \csname\string#1\endcsname{#3}}%
- \expandafter\@yargdef\csname\string#1\endcsname\tw@{#2}{#4}}}
- %
- \newcommand{\ifstmundef}[1]{%
- \ifdefined#1%
- \ifx#1\relax
- \expandafter\expandafter
- \expandafter\@firstoftwo
+ \ExplSyntaxOn
+ \def\ca_affitem_postskip{\mbox{~}\unskip\ignorespaces}
+ %%Author Address
+ \DeclareDocumentCommand \ca_organization { O{,} m }
+ {
+ % #2 #1\mbox{~}\unskip\ignorespaces
+ \csgappto { ca_affiliation_values } { #2 #1\ca_affitem_postskip }
+ }
+ \DeclareDocumentCommand \ca_postal_code { O{,} m }
+ {
+ % #2 #1\mbox{~}\unskip\ignorespaces
+ \csgappto { ca_affiliation_values } { #2 #1\ca_affitem_postskip }
+ }
+ \DeclareDocumentCommand \ca_aff_city { O{,} m }
+ {
+ % #2 #1\mbox{~}\unskip\ignorespaces
+ \csgappto { ca_affiliation_values } { #2 #1\ca_affitem_postskip }
+ }
+ \DeclareDocumentCommand \ca_address_line { O{,}m }
+ {
+ % #2 #1\mbox{~}\unskip\ignorespaces
+ \csgappto { ca_affiliation_values } { #2 #1\ca_affitem_postskip }
+ }
+ \DeclareDocumentCommand \ca_state { O{,} m }
+ {
+ % #2 #1\mbox{~}\unskip\ignorespaces
+ \csgappto { ca_affiliation_values } { #2 #1\ca_affitem_postskip }
+ }
+ \DeclareDocumentCommand \ca_country { O{ } m }
+ {
+ % #2 #1
+ \csgappto { ca_affiliation_values } { #2 #1 }
+ }
+
+ \DeclareDocumentCommand \ca_stm_organization { O{,} m }
+ {
+ #2 #1\ca_affitem_postskip
+ }
+ \DeclareDocumentCommand \ca_stm_postal_code { O{,} m }
+ {
+ #2 #1\ca_affitem_postskip
+ }
+ \DeclareDocumentCommand \ca_stm_aff_city { O{,} m }
+ {
+ #2 #1\ca_affitem_postskip
+ }
+ \DeclareDocumentCommand \ca_stm_aff_address_line { O{,}m }
+ {
+ #2 #1\ca_affitem_postskip
+ }
+ \DeclareDocumentCommand \ca_stm_state { O{,} m }
+ {
+ #2 #1\ca_affitem_postskip
+ }
+ \DeclareDocumentCommand \ca_stm_country { O{ } m }
+ {
+ #2 #1
+ }
+
+ \keys_define:nn { stm / affiliation }
+ {
+ op .tl_set_x:N = \l_organization_punc_tl,
+ oraganizationsep .tl_set_x:N = \l_organization_punc_tl,
+ oraganisationsep .tl_set_x:N = \l_organization_punc_tl,
+ ap .tl_set_x:N = \l_address_line_punc_tl,
+ addresslinesep .tl_set_x:N = \l_address_line_punc_tl,
+ cp .tl_set_x:N = \l_city_punc_tl,
+ citysep .tl_set_x:N = \l_city_punc_tl,
+ pp .tl_set_x:N = \l_postal_code_punc_tl,
+ postcodesep .tl_set_x:N = \l_postal_code_punc_tl,
+ sp .tl_set_x:N = \l_state_punc_tl,
+ statesep .tl_set_x:N = \l_state_punc_tl,
+ o .code:n = { \ca_organization[\l_organization_punc_tl]{#1} },
+ organization .code:n = { \ca_organization[\l_organization_punc_tl]{#1} },
+ organisation .code:n = { \ca_organization[\l_organization_punc_tl]{#1} },
+ a .code:n = { \ca_address_line[\l_address_line_punc_tl]{#1} },
+ addressline .code:n = { \ca_address_line[\l_address_line_punc_tl]{#1} },
+ c .code:n = { \ca_aff_city[\l_city_punc_tl]{#1} },
+ city .code:n = { \ca_aff_city[\l_city_punc_tl]{#1} },
+ p .code:n = { \ca_postal_code[\l_postal_code_punc_tl]{#1} },
+ postcode .code:n = { \ca_postal_code[\l_postal_code_punc_tl]{#1} },
+ s .code:n = { \ca_state[\l_state_punc_tl]{#1} },
+ state .code:n = { \ca_state[\l_state_punc_tl]{#1} },
+ orp .tl_set_x:N = \l_organization_punc_tl,
+ adp .tl_set_x:N = \l_address_line_punc_tl,
+ cip .tl_set_x:N = \l_city_punc_tl,
+ pcp .tl_set_x:N = \l_postal_code_punc_tl,
+ stp .tl_set_x:N = \l_state_punc_tl,
+ cyp .tl_set_x:N = \l_country_punc_tl,
+ or .code:n = { \ca_organization[\l_organization_punc_tl]{#1} },
+ ad .code:n = { \ca_address_line[\l_address_line_punc_tl]{#1} },
+ ci .code:n = { \ca_aff_city[\l_city_punc_tl]{#1} },
+ pc .code:n = { \ca_postal_code[\l_postal_code_punc_tl]{#1} },
+ st .code:n = { \ca_state[\l_state_punc_tl]{#1} },
+ cy .code:n = { \ca_country[\l_country_punc_tl]{#1} },
+ country .code:n = { \ca_country[\l_country_punc_tl]{#1} },
+ unknown .code:n = {
+ \ifstrempty { #1 } {
+ \csxappto { ca_affiliation_values }
+ { {\l_keys_key_tl}~ }
+ } {
+ \csxappto { ca_affiliation_values }
+ { {#1}~ }
+ }
+ }
+ }
+
+ \cs_set:Npn \__reset_affiliation:
+ {
+ \tl_gset:Nn \l_organization_punc_tl { , }
+ \tl_gset:Nn \l_address_line_punc_tl { , }
+ \tl_gset:Nn \l_city_punc_tl { , }
+ \tl_gset:Nn \l_postal_code_punc_tl { , }
+ \tl_gset:Nn \l_state_punc_tl { , }
+ \tl_gset:Nn \l_country_punc_tl { }
+ }
+
+ \DeclareDocumentCommand\affiliation{ o m }{
+ \__reset_affiliation:
+ \csgdef { ca_affiliation_values } { }
+ \IfNoValueTF { #2 }
+ { }
+ {
+ \keys_set:nn { stm / affiliation } { #2 }
+ }
+ \IfNoValueTF { #1 }
+ {
+ \csgappto{elsauthors}{%
+ \par\vspace*{6pt}\noindent
+ \bgroup\def\baselinestretch{1}%
+ \footnotesize\itshape%
+ \unskip\ignorespaces}
+ \csxappto{elsauthors}{\csuse { ca_affiliation_values }}
+ \csgappto{elsauthors}{\par\vspace*{6pt}
+ \noindent\unskip\ignorespaces
+ \gdef\authorsep{}
+ \egroup}
+ }
+ {
+ \csgappto{elsaddress}{
+ \def\baselinestretch{1}%
+ \refstepcounter{affn}
+ \xdef\@currentlabel{\theaffn}
+ \IfNoValueTF { #1 }
+ { }
+ { \elsLabel{#1} }
+ \textsuperscript{\theaffn}}
+ \csxappto{elsaddress}{
+ \csuse { ca_affiliation_values }
+ \par
+ }
+ }
+ }
+ \ExplSyntaxOff
+ \else%
+ \def\caaffitempostskip{\space}
+
+ \DeclareRobustCommand\caorganization[2][,]{%
+ \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
+ }
+ \DeclareRobustCommand\capostalcode[2][,]{%
+ \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
+ }
+ \DeclareRobustCommand\caaffcity[2][,]{%
+ \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
+ }
+ \DeclareRobustCommand\caaddressline[2][,]{%
+ \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
+ }
+ \DeclareRobustCommand\castate[2][,]{%
+ \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
+ }
+ \DeclareRobustCommand\cacountry[2][,]{%
+ \g@addto@macro\caaffiliationvalues{#2#1\caaffitempostskip}%
+ }
+ \DeclareRobustCommand\castmorganization[2][,]{%
+ #2#1\caaffitempostskip%
+ }
+ \DeclareRobustCommand\castmpostalcode[2][,]{%
+ #2#1\caaffitempostskip%
+ }
+ \DeclareRobustCommand\castmaffcity[2][,]{%
+ #2#1\caaffitempostskip%
+ }
+ \DeclareRobustCommand\castmaddressline[2][,]{%
+ #2#1\caaffitempostskip%
+ }
+ \DeclareRobustCommand\castmstate[2][,]{%
+ #2#1\caaffitempostskip%
+ }
+ \DeclareRobustCommand\castmcountry[2][,]{%
+ #2#1\caaffitempostskip%
+ }
+
+ \define@key{affiliation}{op}{\xdef\@organizationpunc{#1}}
+ \define@key{affiliation}{orp}{\xdef\@organizationpunc{#1}}
+ \define@key{affiliation}{organizationsep}{\xdef\@organizationpunc{#1}}
+ \define@key{affiliation}{ap}{\xdef\@addresslinepunc{#1}}
+ \define@key{affiliation}{adp}{\xdef\@addresslinepunc{#1}}
+ \define@key{affiliation}{addresslinesep}{\xdef\@addresslinepunc{#1}}
+ \define@key{affiliation}{cp}{\xdef\@citypunc{#1}}
+ \define@key{affiliation}{cip}{\xdef\@citypunc{#1}}
+ \define@key{affiliation}{cyp}{\xdef\@countrypunc{#1}}
+ \define@key{affiliation}{citysep}{\xdef\@citypunc{#1}}
+ \define@key{affiliation}{pp}{\xdef\@postcodepunc{#1}}
+ \define@key{affiliation}{pop}{\xdef\@postcodepunc{#1}}
+ \define@key{affiliation}{postcodesep}{\xdef\@postcodepunc{#1}}
+ \define@key{affiliation}{sp}{\xdef\@statepunc{#1}}
+ \define@key{affiliation}{stp}{\xdef\@statepunc{#1}}
+ \define@key{affiliation}{statesep}{\xdef\@statepunc{#1}}
+ \define@key{affiliation}{countrysep}{\xdef\@countrypunc{#1}}
+
+ \define@key{affiliation}{organization}{%
+ \caorganization[\@organizationpunc]{#1}}
+ \define@key{affiliation}{addressline}{%
+ \caaddressline[\@addresslinepunc]{#1}}
+ \define@key{affiliation}{city}{%
+ \caaffcity[\@citypunc]{#1}}
+ \define@key{affiliation}{postcode}{%
+ \capostalcode[\@postcodepunc]{#1}}
+ \define@key{affiliation}{state}{%
+ \castate[\@statepunc]{#1}}
+ \define@key{affiliation}{or}{%
+ \caorganization[\@organizationpunc]{#1}}
+ \define@key{affiliation}{ad}{%
+ \caaddressline[\@addresslinepunc]{#1}}
+ \define@key{affiliation}{ci}{%
+ \caaffcity[\@citypunc]{#1}}
+ \define@key{affiliation}{po}{%
+ \capostalcode[\@postcodepunc]{#1}}
+ \define@key{affiliation}{st}{%
+ \castate[\@statepunc]{#1}}
+ \define@key{affiliation}{o}{%
+ \caorganization[\@organizationpunc]{#1}}
+ \define@key{affiliation}{a}{%
+ \caaddressline[\@addresslinepunc]{#1}}
+ \define@key{affiliation}{c}{%
+ \cacity[\@citypunc]{#1}}
+ \define@key{affiliation}{p}{%
+ \capostcode[\@postcodepunc]{#1}}
+ \define@key{affiliation}{s}{%
+ \castate[\@statepunc]{#1}}
+ \define@key{affiliation}{cy}{%
+ \cacountry[\@countrypunc]{#1}}
+ \define@key{affiliation}{country}{%
+ \cacountry[\@countrypunc]{#1}}
+
+ \gdef\@resetaffiliation{%
+ \gdef\@organizationpunc{,}%
+ \gdef\@addresslinepunc{,}%
+ \gdef\@citypunc{,}%
+ \gdef\@statepunc{,}%
+ \gdef\@postcodepunc{,}%
+ \gdef\@countrypunc{}%
+ }
+
+ \def\affiliation{\@ifnextchar[{\@@affiliation}{\@affiliation}}
+
+ \newcommand*{\newstmrobustcmd}{}
+ \protected\def\newstmrobustcmd{\@star@or@long\stmetb@new@command}
+
+ \def\stmetb@new@command#1{\@testopt{\stmetb@newcommand#1}0}
+
+ \def\stmetb@newcommand#1[#2]{%
+ \@ifnextchar[%]
+ {\stmetb@xargdef#1[#2]}
+ {\ifx\l@ngrel@x\relax
+ \let\l@ngrel@x\protected
\else
- \expandafter\expandafter
- \expandafter\@secondoftwo
+ \protected\def\l@ngrel@x{\protected\long}%
\fi
- \else
- \expandafter\@firstoftwo
- \fi}
- \newcommand{\stmexpandonce}[1]{%
- \unexpanded\expandafter{#1}}
- \newstmrobustcmd{\gstmappto}[2]{%
- \ifundef{#1}
- {\xdef#1{\unexpanded{#2}}}
- {\xdef#1{\stmexpandonce#1\unexpanded{#2}}}}
- \newstmrobustcmd{\xstmappto}[2]{%
- \ifstmundef{#1}
- {\xdef#1{#2}}
- {\xdef#1{\stmexpandonce#1#2}}}
-
- \long\def\@@affiliation[#1]#2{%
- \@resetaffiliation%
- \gdef\caaffiliationvalues{}%
- \elsLabel{#1}%
- \setkeys{affiliation}{#2}%
- \g@addto@macro\elsaddress{%
- \def\baselinestretch{1}%
- \refstepcounter{affn}%
- \xdef\@currentlabel{\theaffn}%
- \elsLabel{#1}%
- \textsuperscript{\theaffn}}
- \xstmappto\elsaddress{\caaffiliationvalues\par}}
-
- \long\def\@affiliation#1{%
- \@resetaffiliation%
- \gdef\caaffiliationvalues{}%
- \setkeys{affiliation}{#1}%
- \g@addto@macro\elsauthors{%
- \def\baselinestretch{1}}%
- \xstmappto\elsaddress{\caaffiliationvalues\par}}
+ \@argdef#1[#2]}}
+
+ \long\def\stmetb@xargdef#1[#2][#3]#4{%
+ \@ifdefinable#1{%
+ \expandafter\protected
+ \expandafter\def
+ \expandafter#1%
+ \expandafter{%
+ \expandafter\@testopt
+ \csname\string#1\endcsname{#3}}%
+ \expandafter\@yargdef\csname\string#1\endcsname\tw@{#2}{#4}}}
+ %
+ \newcommand{\ifstmundef}[1]{%
+ \ifdefined#1%
+ \ifx#1\relax
+ \expandafter\expandafter
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\expandafter
+ \expandafter\@secondoftwo
+ \fi
+ \else
+ \expandafter\@firstoftwo
+ \fi}
+ \newcommand{\stmexpandonce}[1]{%
+ \unexpanded\expandafter{#1}}
+ \newstmrobustcmd{\gstmappto}[2]{%
+ \ifundef{#1}
+ {\xdef#1{\unexpanded{#2}}}
+ {\xdef#1{\stmexpandonce#1\unexpanded{#2}}}}
+ \newstmrobustcmd{\xstmappto}[2]{%
+ \ifstmundef{#1}
+ {\xdef#1{#2}}
+ {\xdef#1{\stmexpandonce#1#2}}}
+
+ \long\def\@@affiliation[#1]#2{%
+ \@resetaffiliation%
+ \gdef\caaffiliationvalues{}%
+ \elsLabel{#1}%
+ \setkeys{affiliation}{#2}%
+ \g@addto@macro\elsaddress{%
+ \def\baselinestretch{1}%
+ \refstepcounter{affn}%
+ \xdef\@currentlabel{\theaffn}%
+ \elsLabel{#1}%
+ \textsuperscript{\theaffn}}
+ \xstmappto\elsaddress{\caaffiliationvalues\par}}
+
+ \long\def\@affiliation#1{%
+ \@resetaffiliation%
+ \gdef\caaffiliationvalues{}%
+ \setkeys{affiliation}{#1}%
+ \g@addto@macro\elsauthors{%
+ \def\baselinestretch{1}}%
+ \xstmappto\elsaddress{\caaffiliationvalues\par}}
\fi
\def\address{\@ifnextchar[{\@@address}{\@address}}
\long\def\@@address[#1]#2{\g@addto@macro\elsaddress{%
- \def\baselinestretch{1}%
- \refstepcounter{affn}
- \xdef\@currentlabel{\theaffn}
- \elsLabel{#1}%
- \textsuperscript{\theaffn}#2\par}}
+ \def\baselinestretch{1}%
+ \refstepcounter{affn}
+ \xdef\@currentlabel{\theaffn}
+ \elsLabel{#1}%
+ \textsuperscript{\theaffn}#2\par}}
\long\def\@address#1{\g@addto@macro\elsauthors{%
- \def\baselinestretch{1}%
- \addsep\footnotesize\itshape#1\def\addsep{\par\vskip6pt}%
- \def\authorsep{\par\vskip8pt}}}
+ \def\baselinestretch{1}%
+ \addsep\footnotesize\itshape#1\def\addsep{\par\vskip6pt}%
+ \def\authorsep{\par\vskip8pt}}}
\newbox\absbox
\let\@elsarticleabstitle\@empty %*%
\def\abstracttitle#1{\gdef\@elsarticleabstitle{#1}} %*%
\abstracttitle{Abstract} %*%
\renewenvironment{abstract}{\global\setbox\absbox=\vbox\bgroup
- \hsize=\textwidth\def\baselinestretch{1}%
- \noindent\unskip\textbf{\@elsarticleabstitle} %*%
- \par\medskip\noindent\unskip\ignorespaces}
- {\egroup}
+ \hsize=\textwidth\def\baselinestretch{1}%
+ \noindent\unskip\textbf{\@elsarticleabstitle} %*%
+\par\medskip\noindent\unskip\ignorespaces}
+{\egroup}
\newbox\elsarticlehighlightsbox
\newbox\elsarticlegrabsbox
@@ -664,43 +684,53 @@
\newif\ifelsprelimpagegrabs\global\elsprelimpagegrabsfalse
\newif\ifelsprelimpagehl\global\elsprelimpagehlfalse
\def\elsarticleprelims{%
- \ifelsprelimpagegrabs\relax%
- \thispagestyle{empty}%
- \unvbox\elsarticlegrabsbox%
- \pagebreak\clearpage%
- \fi%
- \ifelsprelimpagehl\relax%
- \thispagestyle{empty}
- \unvbox\elsarticlehighlightsbox%
- \pagebreak\clearpage%
- \setcounter{page}{1}%
- \fi%
+\ifelsprelimpagegrabs\relax%
+ \thispagestyle{empty}%
+ \unvbox\elsarticlegrabsbox%
+ \pagebreak\clearpage%
+\fi%
+\ifelsprelimpagehl\relax%
+ \thispagestyle{empty}
+ \unvbox\elsarticlehighlightsbox%
+ \pagebreak\clearpage%
+ \setcounter{page}{1}%
+\fi%
}
\newenvironment{highlights}{%
- \global\elsprelimpagehltrue%
- \global\setbox\elsarticlehighlightsbox=\vbox\bgroup
- \hsize=\textwidth\def\baselinestretch{1}%
- \noindent\unskip{\Large\@elsarticlehighlightstitle}%*%
- \par\vskip12pt\noindent\unskip\ignorespaces\textbf{\@title}%
- \ifx\elsprelimauthors\@empty\relax\else%
- \par\vskip6pt\noindent\unskip\ignorespaces\elsprelimauthors%
- \fi%
- \par\medskip\noindent\unskip\ignorespaces
- \begin{itemize}
- }
- {\end{itemize}
- \egroup}
+ \global\elsprelimpagehltrue%
+ \global\setbox\elsarticlehighlightsbox=\vbox\bgroup
+ \hsize=\textwidth\def\baselinestretch{1}%
+ \noindent\unskip{\Large\@elsarticlehighlightstitle}%*%
+ \par\vskip12pt\noindent\unskip\ignorespaces\textbf{\@title}%
+ \ifx\elsprelimauthors\@empty\relax\else%
+ \par\vskip6pt\noindent\unskip\ignorespaces%
+ \ifdoubleblind%
+ \vspace*{2pc}
+ \else%
+ \elsprelimauthors%
+ \fi%
+ \fi%
+ \par\medskip\noindent\unskip\ignorespaces
+\begin{itemize}
+}
+{\end{itemize}
+ \egroup}
\newenvironment{graphicalabstract}{%
- \global\elsprelimpagegrabstrue%
- \global\setbox\elsarticlegrabsbox=\vbox\bgroup
- \hsize=\textwidth\def\baselinestretch{1}%
- \noindent\unskip{\Large\@elsarticlegrabstitle}%*%
- \par\vskip12pt\noindent\unskip\ignorespaces\textbf{\@title}%
- \ifx\elsprelimauthors\@empty\relax\else%
- \par\vskip6pt\noindent\unskip\ignorespaces\elsprelimauthors%
- \fi%
- \par\medskip\noindent\unskip\ignorespaces}
- {\egroup}
+ \global\elsprelimpagegrabstrue%
+ \global\setbox\elsarticlegrabsbox=\vbox\bgroup
+ \hsize=\textwidth\def\baselinestretch{1}%
+ \noindent\unskip{\Large\@elsarticlegrabstitle}%*%
+ \par\vskip12pt\noindent\unskip\ignorespaces\textbf{\@title}%
+ \ifx\elsprelimauthors\@empty\relax\else%
+ \par\vskip6pt\noindent\unskip\ignorespaces%
+ \ifdoubleblind%
+ \vspace*{2pc}
+ \else%
+ \elsprelimauthors%
+ \fi%
+ \fi%
+\par\medskip\noindent\unskip\ignorespaces}
+{\egroup}
\newbox\keybox
\let\@elsarticlekwdtitle\@empty %*%
@@ -709,45 +739,45 @@
\keywordtitle{Keywords} %*%
\keywordtitlesep{:\ }
\def\keyword{%
- \def\sep{\unskip, }%
- \def\MSC{\@ifnextchar[{\@MSC}{\@MSC[2000]}}
- \def\@MSC[##1]{\par\leavevmode\hbox {\it ##1~MSC:\space}}%
- \def\PACS{\par\leavevmode\hbox {\it PACS:\space}}%
- \def\JEL{\par\leavevmode\hbox {\it JEL:\space}}%
- \global\setbox\keybox=\vbox\bgroup\hsize=\textwidth
- \normalsize\normalfont\def\baselinestretch{1}
- \parskip\z@
- \noindent\textit{\@elsarticlekwdtitle\@elsarticlekeywordtitlesep}
- \raggedright % Keywords are not justified.
- \ignorespaces}
+ \def\sep{\unskip, }%
+\def\MSC{\@ifnextchar[{\@MSC}{\@MSC[2000]}}
+ \def\@MSC[##1]{\par\leavevmode\hbox {\it ##1~MSC:\space}}%
+ \def\PACS{\par\leavevmode\hbox {\it PACS:\space}}%
+ \def\JEL{\par\leavevmode\hbox {\it JEL:\space}}%
+ \global\setbox\keybox=\vbox\bgroup\hsize=\textwidth
+ \normalsize\normalfont\def\baselinestretch{1}
+ \parskip\z@
+ \noindent\textit{\@elsarticlekwdtitle\@elsarticlekeywordtitlesep}
+ \raggedright % Keywords are not justified.
+ \ignorespaces}
\def\endkeyword{\par \egroup}
\newdimen\Columnwidth
\Columnwidth=\columnwidth
\def\printFirstPageNotes{%
- \iflongmktitle
- \let\columnwidth=\textwidth
- \fi
+ \iflongmktitle
+ \let\columnwidth=\textwidth
+ \fi
\ifdoubleblind
\else
- \ifx\@tnotes\@empty\else\@tnotes\fi
- \ifx\@nonumnotes\@empty\else\@nonumnotes\fi
- \ifx\@cornotes\@empty\else\@cornotes\fi
- \ifx\@elseads\@empty\relax\else
- \let\thefootnote\relax
- \footnotetext{\ifnum\theead=1\relax
- \textit{Email address:\space}\else
- \textit{Email addresses:\space}\fi
- \@elseads}\fi
- \ifx\@elsuads\@empty\relax\else
- \let\thefootnote\relax
- \footnotetext{\textit{URL:\space}%
- \@elsuads}\fi
+ \ifx\@tnotes\@empty\else\@tnotes\fi
+ \ifx\@nonumnotes\@empty\else\@nonumnotes\fi
+ \ifx\@cornotes\@empty\else\@cornotes\fi
+ \ifx\@elseads\@empty\relax\else
+ \let\thefootnote\relax
+ \footnotetext{\ifnum\theead=1\relax
+ \textit{Email address:\space}\else
+ \textit{Email addresses:\space}\fi
+ \@elseads}\fi
+ \ifx\@elsuads\@empty\relax\else
+ \let\thefootnote\relax
+ \footnotetext{\textit{URL:\space}%
+ \@elsuads}\fi
\fi
- \ifx\@fnotes\@empty\else\@fnotes\fi
- \iflongmktitle\if@twocolumn
- \let\columnwidth=\Columnwidth\fi\fi
+ \ifx\@fnotes\@empty\else\@fnotes\fi
+ \iflongmktitle\if@twocolumn
+ \let\columnwidth=\Columnwidth\fi\fi
}
%% Pushing text to begin on newpage %*%
@@ -755,233 +785,233 @@
\def\newpage@after@author{author}
\def\newpage@after@abstract{abstract}
\def\newpageafter#1%
- {\gdef\@elsarticlenewpageafter{#1}}
+ {\gdef\@elsarticlenewpageafter{#1}}
\long\def\pprintMaketitle{\clearpage
- \iflongmktitle\if@twocolumn\let\columnwidth=\textwidth\fi\fi
- \resetTitleCounters
+ \iflongmktitle\if@twocolumn\let\columnwidth=\textwidth\fi\fi
+ \resetTitleCounters
+ \def\baselinestretch{1}%
+ \printFirstPageNotes
+ \begin{\elsarticletitlealign}%
+\thispagestyle{pprintTitle}%
\def\baselinestretch{1}%
- \printFirstPageNotes
- \begin{\elsarticletitlealign}%
- \thispagestyle{pprintTitle}%
- \def\baselinestretch{1}%
- \Large\@title\par\vskip18pt%
- \ifx\@elsarticlenewpageafter\newpage@after@title% %*%
- \newpage
- \fi%
- \ifdoubleblind
- \vspace*{2pc}
- \else
- \normalsize\elsauthors\par\vskip10pt
- \footnotesize\itshape\elsaddress\par\vskip36pt
- \fi
- \ifx\@elsarticlenewpageafter\newpage@after@author% %*%
- \newpage
- \fi%
- \hrule\vskip12pt
- \ifvoid\absbox\else\unvbox\absbox\par\vskip10pt\fi
- \ifvoid\keybox\else\unvbox\keybox\par\vskip10pt\fi
- \hrule\vskip12pt
- \ifx\@elsarticlenewpageafter\newpage@after@abstract% %*%
- \newpage
- \fi%
- \end{\elsarticletitlealign}%
- \gdef\thefootnote{\arabic{footnote}}%
- }
+ \Large\@title\par\vskip18pt%
+ \ifx\@elsarticlenewpageafter\newpage@after@title% %*%
+ \newpage
+ \fi%
+ \ifdoubleblind
+ \vspace*{2pc}
+ \else
+ \normalsize\elsauthors\par\vskip10pt
+ \footnotesize\itshape\elsaddress\par\vskip36pt
+ \fi
+ \ifx\@elsarticlenewpageafter\newpage@after@author% %*%
+ \newpage
+ \fi%
+ \hrule\vskip12pt
+ \ifvoid\absbox\else\unvbox\absbox\par\vskip10pt\fi
+ \ifvoid\keybox\else\unvbox\keybox\par\vskip10pt\fi
+ \hrule\vskip12pt
+ \ifx\@elsarticlenewpageafter\newpage@after@abstract% %*%
+ \newpage
+ \fi%
+ \end{\elsarticletitlealign}%
+ \gdef\thefootnote{\arabic{footnote}}%
+ }
\def\printWarning{%
- \mbox{}\par\vfill\par\bgroup
- \fboxsep12pt\fboxrule1pt
- \hspace*{.18\textwidth}
- \fcolorbox{gray50}{gray10}{\box\warnbox}
- \egroup\par\vfill\thispagestyle{empty}
- \setcounter{page}{0}
- \clearpage}
+ \mbox{}\par\vfill\par\bgroup
+ \fboxsep12pt\fboxrule1pt
+ \hspace*{.18\textwidth}
+ \fcolorbox{gray50}{gray10}{\box\warnbox}
+ \egroup\par\vfill\thispagestyle{empty}
+ \setcounter{page}{0}
+ \clearpage}
\long\def\finalMaketitle{%
- \resetTitleCounters
- \def\baselinestretch{1}%
- \MaketitleBox
- \thispagestyle{pprintTitle}%
- \gdef\thefootnote{\arabic{footnote}}%
- }
+ \resetTitleCounters
+ \def\baselinestretch{1}%
+ \MaketitleBox
+ \thispagestyle{pprintTitle}%
+ \gdef\thefootnote{\arabic{footnote}}%
+ }
\long\def\MaketitleBox{%
- \resetTitleCounters
+ \resetTitleCounters
+ \def\baselinestretch{1}%
+ \begin{\elsarticletitlealign}%
\def\baselinestretch{1}%
- \begin{\elsarticletitlealign}%
- \def\baselinestretch{1}%
- \Large\@title\par\vskip18pt
- \ifdoubleblind
- \vspace*{2pc}
- \else
- \normalsize\elsauthors\par\vskip10pt
- \footnotesize\itshape\elsaddress\par\vskip36pt
- \fi
- \hrule\vskip12pt
- \ifvoid\absbox\else\unvbox\absbox\par\vskip10pt\fi
- \ifvoid\keybox\else\unvbox\keybox\par\vskip10pt\fi
- \hrule\vskip12pt
- \end{\elsarticletitlealign}%
+ \Large\@title\par\vskip18pt
+ \ifdoubleblind
+ \vspace*{2pc}
+ \else
+ \normalsize\elsauthors\par\vskip10pt
+ \footnotesize\itshape\elsaddress\par\vskip36pt
+ \fi
+ \hrule\vskip12pt
+ \ifvoid\absbox\else\unvbox\absbox\par\vskip10pt\fi
+ \ifvoid\keybox\else\unvbox\keybox\par\vskip10pt\fi
+ \hrule\vskip12pt
+ \end{\elsarticletitlealign}%
}
\def\FNtext#1{\par\bgroup\footnotesize#1\egroup}
\newdimen\space@left
\def\alarm#1{\typeout{******************************}%
- \typeout{#1}%
- \typeout{******************************}%
+ \typeout{#1}%
+ \typeout{******************************}%
}
\def\titlespancalculator#1#2#3#4{%
- % break count
- \@tempcnta=#4\relax%
- % pagebreakcount increment
- \advance\@tempcnta by 1\relax%
- % title page height
- \@tempdima=#1\relax%
- % Page height - title page notes height (only for first break)
- % Page height - textheight (for remaining breaks)
- % Page height - title page notes height
- \@tempdimb=#2\relax%
- % Remaining title page height
- \advance\@tempdima -\the\@tempdimb%
- % Checks if remaining title page
- % height less than textheight
- \ifdim\the\@tempdima>#3\relax%
- \titlespancalculator%
- {\the\@tempdima}{#3}{#3}{\the\@tempcnta}%Break again
- \else%
- % Save break count and exit.
- \xdef\savetitlepagespan{\the\@tempcnta}%
- \fi%
+ % break count
+ \@tempcnta=#4\relax%
+ % pagebreakcount increment
+ \advance\@tempcnta by 1\relax%
+ % title page height
+ \@tempdima=#1\relax%
+ % Page height - title page notes height (only for first break)
+ % Page height - textheight (for remaining breaks)
+ % Page height - title page notes height
+ \@tempdimb=#2\relax%
+ % Remaining title page height
+ \advance\@tempdima -\the\@tempdimb%
+ % Checks if remaining title page
+ % height less than textheight
+ \ifdim\the\@tempdima>#3\relax%
+ \titlespancalculator%
+ {\the\@tempdima}{#3}{#3}{\the\@tempcnta}%Break again
+ \else%
+ % Save break count and exit.
+ \xdef\savetitlepagespan{\the\@tempcnta}%
+ \fi%
}%
\long\def\myfor#1#2#3{%
- \@tempcnta=#1\relax%
- \ifnum#1<#2\relax%
- \advance\@tempcnta by 1\relax%
- #3%
- \myfor{\the\@tempcnta}{#2}{#3}%
- \fi}
+ \@tempcnta=#1\relax%
+ \ifnum#1<#2\relax%
+ \advance\@tempcnta by 1\relax%
+ #3%
+ \myfor{\the\@tempcnta}{#2}{#3}%
+ \fi}
\long\def\getSpaceLeft{%\global\@twocolumnfalse%
- \global\setbox0=\vbox{\hsize=\textwidth\MaketitleBox}%
- \global\setbox1=\vbox{\hsize=\textwidth
- \let\footnotetext\FNtext
- \printFirstPageNotes}%
- \xdef\noteheight{\the\ht1}%
- \xdef\titleheight{\the\ht0}%
- \@tempdima=\vsize
- \advance\@tempdima-\noteheight
- \advance\@tempdima-1\baselineskip
- \xdef\savefpageheight{\the\@tempdima}%
- \setbox2=\vbox{\titlespancalculator{\titleheight}%
- {\savefpageheight}{\textheight}{0}}%
+ \global\setbox0=\vbox{\hsize=\textwidth\MaketitleBox}%
+ \global\setbox1=\vbox{\hsize=\textwidth
+ \let\footnotetext\FNtext
+ \printFirstPageNotes}%
+ \xdef\noteheight{\the\ht1}%
+ \xdef\titleheight{\the\ht0}%
+ \@tempdima=\vsize
+ \advance\@tempdima-\noteheight
+ \advance\@tempdima-1\baselineskip
+ \xdef\savefpageheight{\the\@tempdima}%
+ \setbox2=\vbox{\titlespancalculator{\titleheight}%
+ {\savefpageheight}{\textheight}{0}}%
}
- \skip\footins=24pt
+ \skip\footins=24pt
\newbox\els@boxa
\newbox\els@boxb
\ifpreprint
- \def\maketitle{\elsarticleprelims\pprintMaketitle}
- \else
- \ifnum\jtype=1
- \def\maketitle{%
- \elsarticleprelims%
- \iflongmktitle\getSpaceLeft
- \ifdim\noteheight>0pt%
- \advance\@tempdima-1.35\baselineskip
- \fi%
- \global\setbox\els@boxa=\vsplit0 to \@tempdima
- \box\els@boxa\par\resetTitleCounters
- \thispagestyle{pprintTitle}%
- \printFirstPageNotes
- \ifnum\savetitlepagespan>1\relax%
- \myfor{2}{\savetitlepagespan}{%
- \global\setbox\els@boxb=\vsplit0 to \textheight%\@tempdima
- \box\els@boxb}
- \else%
- \fi%
- \box0%
- \else
- \finalMaketitle\printFirstPageNotes
- \fi
- \gdef\thefootnote{\arabic{footnote}}}%
- \else
- \ifnum\jtype=5
- \def\maketitle{%
- \elsarticleprelims%
- \iflongmktitle\getSpaceLeft
- \ifdim\noteheight>0pt%
- \advance\@tempdima-1.35\baselineskip
- \fi%
- \global\setbox\els@boxa=\vsplit0 to \@tempdima
- \box\els@boxa\par\resetTitleCounters
- \thispagestyle{pprintTitle}%
- \printFirstPageNotes
- \ifnum\savetitlepagespan>1\relax%
- \myfor{2}{\savetitlepagespan}{%
- \global\setbox\els@boxb=\vsplit0 to \textheight%\@tempdima
- \twocolumn[\box\els@boxb]}
- \else%
+ \def\maketitle{\elsarticleprelims\pprintMaketitle}
+ \else
+ \ifnum\jtype=1
+ \def\maketitle{%
+ \elsarticleprelims%
+ \iflongmktitle\getSpaceLeft
+ \ifdim\noteheight>0pt%
+ \advance\@tempdima-1.35\baselineskip
\fi%
- \twocolumn[\box0]%\printFirstPageNotes
- \else
- \twocolumn[\finalMaketitle]\printFirstPageNotes
+ \global\setbox\els@boxa=\vsplit0 to \@tempdima
+ \box\els@boxa\par\resetTitleCounters
+ \thispagestyle{pprintTitle}%
+ \printFirstPageNotes
+ \ifnum\savetitlepagespan>1\relax%
+ \myfor{2}{\savetitlepagespan}{%
+ \global\setbox\els@boxb=\vsplit0 to \textheight%\@tempdima
+ \box\els@boxb}
+ \else%
+ \fi%
+ \box0%
+ \else
+ \finalMaketitle\printFirstPageNotes
\fi
- \gdef\thefootnote{\arabic{footnote}}}
- \else
- \if@twocolumn
- \def\maketitle{%
- \elsarticleprelims%
- \iflongmktitle\getSpaceLeft
- \ifdim\noteheight>0pt%
- \advance\@tempdima-1.35\baselineskip
- \fi%
- \global\setbox\els@boxa=\vsplit0 to \@tempdima
- \box\els@boxa\par\resetTitleCounters
- \thispagestyle{pprintTitle}%
- \printFirstPageNotes
- \ifnum\savetitlepagespan>1\relax%
- \myfor{2}{\savetitlepagespan}{%
- \global\setbox\els@boxb=\vsplit0 to \textheight%\@tempdima
- \twocolumn[\box\els@boxb]}
- \else%
- \fi%
- \twocolumn[\box0]%
- \else
- \twocolumn[\finalMaketitle]\printFirstPageNotes
- \fi
- \gdef\thefootnote{\arabic{footnote}}}%
- \else
- \def\maketitle{%
- \elsarticleprelims%
- \iflongmktitle\getSpaceLeft
- \ifdim\noteheight>0pt%
- \advance\@tempdima-1.35\baselineskip
- \fi%
- \global\setbox\els@boxa=\vsplit0 to \@tempdima
- \box\els@boxa\par\resetTitleCounters
- \thispagestyle{pprintTitle}%
- \printFirstPageNotes
- \ifnum\savetitlepagespan>1\relax%
- \myfor{2}{\savetitlepagespan}{%
- \global\setbox\els@boxb=\vsplit0 to \textheight%\@tempdima
- \box\els@boxb}
- \else%
+ \gdef\thefootnote{\arabic{footnote}}}%
+ \else
+\ifnum\jtype=5
+ \def\maketitle{%
+ \elsarticleprelims%
+ \iflongmktitle\getSpaceLeft
+ \ifdim\noteheight>0pt%
+ \advance\@tempdima-1.35\baselineskip
\fi%
- \box0%
+ \global\setbox\els@boxa=\vsplit0 to \@tempdima
+ \box\els@boxa\par\resetTitleCounters
+ \thispagestyle{pprintTitle}%
+ \printFirstPageNotes
+ \ifnum\savetitlepagespan>1\relax%
+ \myfor{2}{\savetitlepagespan}{%
+ \global\setbox\els@boxb=\vsplit0 to \textheight%\@tempdima
+ \twocolumn[\box\els@boxb]}
+ \else%
+ \fi%
+ \twocolumn[\box0]%\printFirstPageNotes
\else
+ \twocolumn[\finalMaketitle]\printFirstPageNotes
+ \fi
+ \gdef\thefootnote{\arabic{footnote}}}
+ \else
+ \if@twocolumn
+ \def\maketitle{%
\elsarticleprelims%
- \finalMaketitle\printFirstPageNotes
- \fi
+ \iflongmktitle\getSpaceLeft
+ \ifdim\noteheight>0pt%
+ \advance\@tempdima-1.35\baselineskip
+ \fi%
+ \global\setbox\els@boxa=\vsplit0 to \@tempdima
+ \box\els@boxa\par\resetTitleCounters
+ \thispagestyle{pprintTitle}%
+ \printFirstPageNotes
+ \ifnum\savetitlepagespan>1\relax%
+ \myfor{2}{\savetitlepagespan}{%
+ \global\setbox\els@boxb=\vsplit0 to \textheight%\@tempdima
+ \twocolumn[\box\els@boxb]}
+ \else%
+ \fi%
+ \twocolumn[\box0]%
+ \else
+ \twocolumn[\finalMaketitle]\printFirstPageNotes
+ \fi
\gdef\thefootnote{\arabic{footnote}}}%
- \fi
+ \else
+ \def\maketitle{%
+ \elsarticleprelims%
+ \iflongmktitle\getSpaceLeft
+ \ifdim\noteheight>0pt%
+ \advance\@tempdima-1.35\baselineskip
+ \fi%
+ \global\setbox\els@boxa=\vsplit0 to \@tempdima
+ \box\els@boxa\par\resetTitleCounters
+ \thispagestyle{pprintTitle}%
+ \printFirstPageNotes
+ \ifnum\savetitlepagespan>1\relax%
+ \myfor{2}{\savetitlepagespan}{%
+ \global\setbox\els@boxb=\vsplit0 to \textheight%\@tempdima
+ \box\els@boxb}
+ \else%
+ \fi%
+ \box0%
+ \else
+ \elsarticleprelims%
+ \finalMaketitle\printFirstPageNotes
+ \fi
+ \gdef\thefootnote{\arabic{footnote}}}%
\fi
\fi
\fi
+\fi
\let\@elsarticlemyfooter\@empty
\let\@elsarticlemyfooteralign\@empty
@@ -990,387 +1020,381 @@
\def\@elsarticlemyfooteraligncenter{C}
\def\myfooter[#1]#2 %*%
- {\gdef\@elsarticlemyfooteralign{#1}
- \gdef\@elsarticlemyfooter{#2}}
+ {\gdef\@elsarticlemyfooteralign{#1}
+ \gdef\@elsarticlemyfooter{#2}}
\def\myfooterfont#1{\gdef\@myfooterfont{#1}}
\myfooterfont{\footnotesize\itshape}
\def\ps@pprintTitle{%
- \let\@oddhead\@empty
- \let\@evenhead\@empty
- \def\@oddfoot
- {\hbox to \textwidth%
- {\ifnopreprintline\relax\else
- \@myfooterfont%
- \ifx\@elsarticlemyfooteralign\@elsarticlemyfooteraligncenter%
- \hfil\@elsarticlemyfooter\hfil%
- \else%
- \ifx\@elsarticlemyfooteralign\@elsarticlemyfooteralignleft%
- \@elsarticlemyfooter\hfill{}%
- \else%
- \ifx\@elsarticlemyfooteralign\@elsarticlemyfooteralignright%
- {}\hfill\@elsarticlemyfooter%
- \else%
- Preprint submitted to \ifx\@journal\@empty%
- Elsevier%
- \else\@journal\fi\hfill\@date\fi%
- \fi%
- \fi%
- \fi%
- }
- }%
- \let\@evenfoot\@oddfoot}
+ \let\@oddhead\@empty
+ \let\@evenhead\@empty
+ \def\@oddfoot
+ {\hbox to \textwidth%
+ {\ifnopreprintline\relax\else
+ \@myfooterfont%
+ \ifx\@elsarticlemyfooteralign\@elsarticlemyfooteraligncenter%
+ \hfil\@elsarticlemyfooter\hfil%
+ \else%
+ \ifx\@elsarticlemyfooteralign\@elsarticlemyfooteralignleft%
+ \@elsarticlemyfooter\hfill{}%
+ \else%
+ \ifx\@elsarticlemyfooteralign\@elsarticlemyfooteralignright%
+ {}\hfill\@elsarticlemyfooter%
+%% Removed the preprint submitted line as per the instruction
+%% received on 22 Oct 2024 from Arun Shanmugam (ELS) with the
+%% subject line "FW: Preprint sentence in EM submissions"
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ }%
+ }%
+ \let\@evenfoot\@oddfoot}
\def\@seccntDot{.}
\def\@seccntformat#1{\csname the#1\endcsname\@seccntDot\hskip 0.5em}
\renewcommand\section{\@startsection {section}{1}{\z@}%
- {18\p@ \@plus 6\p@ \@minus 3\p@}%
- {9\p@ \@plus 6\p@ \@minus 3\p@}%
- {\normalsize\bfseries\boldmath}}
+ {18\p@ \@plus 6\p@ \@minus 3\p@}%
+ {9\p@ \@plus 6\p@ \@minus 3\p@}%
+ {\normalsize\bfseries\boldmath}}
\renewcommand\subsection{\@startsection{subsection}{2}{\z@}%
- {12\p@ \@plus 6\p@ \@minus 3\p@}%
- {3\p@ \@plus 6\p@ \@minus 3\p@}%
- {\normalfont\normalsize\itshape}}
+ {12\p@ \@plus 6\p@ \@minus 3\p@}%
+ {3\p@ \@plus 6\p@ \@minus 3\p@}%
+ {\normalfont\normalsize\itshape}}
\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}%
- {12\p@ \@plus 6\p@ \@minus 3\p@}%
- {\p@}%
- {\normalfont\normalsize\itshape}}
+ {12\p@ \@plus 6\p@ \@minus 3\p@}%
+ {\p@}%
+ {\normalfont\normalsize\itshape}}
\def\paragraph{\secdef{\els@aparagraph}{\els@bparagraph}}
\def\els@aparagraph[#1]#2{\elsparagraph[#1]{#2.}}
\def\els@bparagraph#1{\elsparagraph*{#1.}}
\newcommand\elsparagraph{\@startsection{paragraph}{4}{0\z@}%
- {10\p@ \@plus 6\p@ \@minus 3\p@}%
- {-6\p@}%
- {\normalfont\itshape}}
+ {10\p@ \@plus 6\p@ \@minus 3\p@}%
+ {-6\p@}%
+ {\normalfont\itshape}}
\newdimen\leftMargin
\leftMargin=2em
\newtoks\@enLab %\newtoks\@enfont
\def\@enQmark{?}
\def\@enLabel#1#2{%
- \edef\@enThe{\noexpand#1{\@enumctr}}%
- \@enLab\expandafter{\the\@enLab\csname the\@enumctr\endcsname}%
- \@enloop}
+ \edef\@enThe{\noexpand#1{\@enumctr}}%
+ \@enLab\expandafter{\the\@enLab\csname the\@enumctr\endcsname}%
+ \@enloop}
\def\@enSpace{\afterassignment\@enSp@ce\let\@tempa= }
\def\@enSp@ce{\@enLab\expandafter{\the\@enLab\space}\@enloop}
\def\@enGroup#1{\@enLab\expandafter{\the\@enLab{#1}}\@enloop}
\def\@enOther#1{\@enLab\expandafter{\the\@enLab#1}\@enloop}
\def\@enloop{\futurelet\@entemp\@enloop@}
\def\@enloop@{%
- \ifx A\@entemp \def\@tempa{\@enLabel\Alph }\else
- \ifx a\@entemp \def\@tempa{\@enLabel\alph }\else
- \ifx i\@entemp \def\@tempa{\@enLabel\roman }\else
- \ifx I\@entemp \def\@tempa{\@enLabel\Roman }\else
- \ifx 1\@entemp \def\@tempa{\@enLabel\arabic}\else
- \ifx \@sptoken\@entemp \let\@tempa\@enSpace \else
- \ifx \bgroup\@entemp \let\@tempa\@enGroup \else
- \ifx \@enum@\@entemp \let\@tempa\@gobble \else
- \let\@tempa\@enOther
- \fi\fi\fi\fi\fi\fi\fi\fi
- \@tempa}
+ \ifx A\@entemp \def\@tempa{\@enLabel\Alph }\else
+ \ifx a\@entemp \def\@tempa{\@enLabel\alph }\else
+ \ifx i\@entemp \def\@tempa{\@enLabel\roman }\else
+ \ifx I\@entemp \def\@tempa{\@enLabel\Roman }\else
+ \ifx 1\@entemp \def\@tempa{\@enLabel\arabic}\else
+ \ifx \@sptoken\@entemp \let\@tempa\@enSpace \else
+ \ifx \bgroup\@entemp \let\@tempa\@enGroup \else
+ \ifx \@enum@\@entemp \let\@tempa\@gobble \else
+ \let\@tempa\@enOther
+ \fi\fi\fi\fi\fi\fi\fi\fi
+ \@tempa}
\newlength{\@sep} \newlength{\@@sep}
\setlength{\@sep}{.5\baselineskip plus.2\baselineskip
- minus.2\baselineskip}
+ minus.2\baselineskip}
\setlength{\@@sep}{.1\baselineskip plus.01\baselineskip
- minus.05\baselineskip}
+ minus.05\baselineskip}
\providecommand{\sfbc}{\rmfamily\upshape}
\providecommand{\sfn}{\rmfamily\upshape}
\def\@enfont{\ifnum \@enumdepth >1\let\@nxt\sfn \else\let\@nxt\sfbc \fi\@nxt}
\def\enumerate{%
- \ifnum \@enumdepth >3 \@toodeep\else
- \advance\@enumdepth \@ne
- \edef\@enumctr{enum\romannumeral\the\@enumdepth}\fi
- \@ifnextchar[{\@@enum@}{\@enum@}}
+ \ifnum \@enumdepth >3 \@toodeep\else
+ \advance\@enumdepth \@ne
+ \edef\@enumctr{enum\romannumeral\the\@enumdepth}\fi
+ \@ifnextchar[{\@@enum@}{\@enum@}}
\def\@@enum@[#1]{%
- \@enLab{}\let\@enThe\@enQmark
- \@enloop#1\@enum@
- \ifx\@enThe\@enQmark\@warning{The counter will not be printed.%
- ^^J\space\@spaces\@spaces\@spaces The label is: \the\@enLab}\fi
- \expandafter\edef\csname label\@enumctr\endcsname{\the\@enLab}%
- \expandafter\let\csname the\@enumctr\endcsname\@enThe
- \csname c@\@enumctr\endcsname7
- \expandafter\settowidth
- \csname leftmargin\romannumeral\@enumdepth\endcsname
- {\the\@enLab\hskip\labelsep}%
- \@enum@}
+ \@enLab{}\let\@enThe\@enQmark
+ \@enloop#1\@enum@
+ \ifx\@enThe\@enQmark\@warning{The counter will not be printed.%
+ ^^J\space\@spaces\@spaces\@spaces The label is: \the\@enLab}\fi
+ \expandafter\edef\csname label\@enumctr\endcsname{\the\@enLab}%
+ \expandafter\let\csname the\@enumctr\endcsname\@enThe
+ \csname c@\@enumctr\endcsname7
+ \expandafter\settowidth
+ \csname leftmargin\romannumeral\@enumdepth\endcsname
+ {\the\@enLab\hskip\labelsep}%
+ \@enum@}
\def\@enum@{\list{{\@enfont\csname label\@enumctr\endcsname}}%
- {\usecounter{\@enumctr}\def\makelabel##1{\hss\llap{##1}}%
- \ifnum \@enumdepth>1\setlength{\topsep}{\@@sep}\else
- \setlength{\topsep}{\@sep}\fi
- \ifnum \@enumdepth>1\setlength{\itemsep}{0pt plus1pt minus1pt}%
- \else \setlength{\itemsep}{\@@sep}\fi
- %\setlength\leftmargin{\leftMargin}%%%{1.8em}
- \setlength{\parsep}{0pt plus1pt minus1pt}%
- \setlength{\parskip}{0pt plus1pt minus1pt}
- }}
+ {\usecounter{\@enumctr}\def\makelabel##1{\hss\llap{##1}}%
+ \ifnum \@enumdepth>1\setlength{\topsep}{\@@sep}\else
+ \setlength{\topsep}{\@sep}\fi
+ \ifnum \@enumdepth>1\setlength{\itemsep}{0pt plus1pt minus1pt}%
+ \else \setlength{\itemsep}{\@@sep}\fi
+ %\setlength\leftmargin{\leftMargin}%%%{1.8em}
+ \setlength{\parsep}{0pt plus1pt minus1pt}%
+ \setlength{\parskip}{0pt plus1pt minus1pt}
+ }}
\def\endenumerate{\par\ifnum \@enumdepth >1\addvspace{\@@sep}\else
- \addvspace{\@sep}\fi \endlist}
+ \addvspace{\@sep}\fi \endlist}
\def\sitem{\@noitemargtrue\@item[\@itemlabel *]}
\def\itemize{\@ifnextchar[{\@Itemize}{\@Itemize[]}}
\def\@Itemize[#1]{\def\next{#1}%
- \ifnum \@itemdepth >\thr@@\@toodeep\else
- \advance\@itemdepth\@ne
- \ifx\next\@empty\else\expandafter\def\csname
- labelitem\romannumeral\the\@itemdepth\endcsname{#1}\fi%
- \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}%
- \expandafter\list\csname\@itemitem\endcsname
- {\def\makelabel##1{\hss\llap{##1}}}%
- \fi}
+ \ifnum \@itemdepth >\thr@@\@toodeep\else
+ \advance\@itemdepth\@ne
+ \ifx\next\@empty\else\expandafter\def\csname
+ labelitem\romannumeral\the\@itemdepth\endcsname{#1}\fi%
+ \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}%
+ \expandafter\list\csname\@itemitem\endcsname
+ {\def\makelabel##1{\hss\llap{##1}}}%
+\fi}
\def\newdefinition#1{%
- \@ifnextchar[{\@odfn{#1}}{\@ndfn{#1}}}%]
+ \@ifnextchar[{\@odfn{#1}}{\@ndfn{#1}}}%]
\def\@ndfn#1#2{%
- \@ifnextchar[{\@xndfn{#1}{#2}}{\@yndfn{#1}{#2}}}
+ \@ifnextchar[{\@xndfn{#1}{#2}}{\@yndfn{#1}{#2}}}
\def\@xndfn#1#2[#3]{%
- \expandafter\@ifdefinable\csname #1\endcsname
- {\@definecounter{#1}\@newctr{#1}[#3]%
- \expandafter\xdef\csname the#1\endcsname{%
- \expandafter\noexpand\csname the#3\endcsname \@dfncountersep
- \@dfncounter{#1}}%
- \global\@namedef{#1}{\@dfn{#1}{#2}}%
- \global\@namedef{end#1}{\@enddefinition}}}
+ \expandafter\@ifdefinable\csname #1\endcsname
+ {\@definecounter{#1}\@newctr{#1}[#3]%
+ \expandafter\xdef\csname the#1\endcsname{%
+ \expandafter\noexpand\csname the#3\endcsname \@dfncountersep
+ \@dfncounter{#1}}%
+ \global\@namedef{#1}{\@dfn{#1}{#2}}%
+ \global\@namedef{end#1}{\@enddefinition}}}
\def\@yndfn#1#2{%
- \expandafter\@ifdefinable\csname #1\endcsname
- {\@definecounter{#1}%
- \expandafter\xdef\csname the#1\endcsname{\@dfncounter{#1}}%
- \global\@namedef{#1}{\@dfn{#1}{#2}}%
- \global\@namedef{end#1}{\@enddefinition}}}
+ \expandafter\@ifdefinable\csname #1\endcsname
+ {\@definecounter{#1}%
+ \expandafter\xdef\csname the#1\endcsname{\@dfncounter{#1}}%
+ \global\@namedef{#1}{\@dfn{#1}{#2}}%
+ \global\@namedef{end#1}{\@enddefinition}}}
\def\@odfn#1[#2]#3{%
- \@ifundefined{c@#2}{\@nocounterr{#2}}%
- {\expandafter\@ifdefinable\csname #1\endcsname
- {\global\@namedef{the#1}{\@nameuse{the#2}}
- \global\@namedef{#1}{\@dfn{#2}{#3}}%
- \global\@namedef{end#1}{\@enddefinition}}}}
+ \@ifundefined{c@#2}{\@nocounterr{#2}}%
+ {\expandafter\@ifdefinable\csname #1\endcsname
+ {\global\@namedef{the#1}{\@nameuse{the#2}}
+ \global\@namedef{#1}{\@dfn{#2}{#3}}%
+ \global\@namedef{end#1}{\@enddefinition}}}}
\def\@dfn#1#2{%
- \refstepcounter{#1}%
- \@ifnextchar[{\@ydfn{#1}{#2}}{\@xdfn{#1}{#2}}}
+ \refstepcounter{#1}%
+ \@ifnextchar[{\@ydfn{#1}{#2}}{\@xdfn{#1}{#2}}}
\def\@xdfn#1#2{%
- \@begindefinition{#2}{\csname the#1\endcsname}\ignorespaces}
+ \@begindefinition{#2}{\csname the#1\endcsname}\ignorespaces}
\def\@ydfn#1#2[#3]{%
- \@opargbegindefinition{#2}{\csname the#1\endcsname}{#3}\ignorespaces}
+ \@opargbegindefinition{#2}{\csname the#1\endcsname}{#3}\ignorespaces}
\def\@dfncounter#1{\noexpand\arabic{#1}}
\def\@dfncountersep{.}
\def\@begindefinition#1#2{\trivlist
- \item[\hskip\labelsep{\bfseries #1\ #2.}]\upshape}
+ \item[\hskip\labelsep{\bfseries #1\ #2.}]\upshape}
\def\@opargbegindefinition#1#2#3{\trivlist
- \item[\hskip\labelsep{\bfseries #1\ #2\ (#3).}]\upshape}
+ \item[\hskip\labelsep{\bfseries #1\ #2\ (#3).}]\upshape}
\def\@enddefinition{\endtrivlist}
\def\@begintheorem#1#2{\trivlist
- \let\baselinestretch\@blstr
- \item[\hskip \labelsep{\bfseries #1\ #2.}]\itshape}
+ \let\baselinestretch\@blstr
+ \item[\hskip \labelsep{\bfseries #1\ #2.}]\itshape}
\def\@opargbegintheorem#1#2#3{\trivlist
- \let\baselinestretch\@blstr
- \item[\hskip \labelsep{\bfseries #1\ #2\ (#3).}]\itshape}
+ \let\baselinestretch\@blstr
+ \item[\hskip \labelsep{\bfseries #1\ #2\ (#3).}]\itshape}
\def\newproof#1{%
- \@ifnextchar[{\@oprf{#1}}{\@nprf{#1}}}
+ \@ifnextchar[{\@oprf{#1}}{\@nprf{#1}}}
\def\@nprf#1#2{%
- \@ifnextchar[{\@xnprf{#1}{#2}}{\@ynprf{#1}{#2}}}
+ \@ifnextchar[{\@xnprf{#1}{#2}}{\@ynprf{#1}{#2}}}
\def\@xnprf#1#2[#3]{%
- \expandafter\@ifdefinable\csname #1\endcsname
- {\@definecounter{#1}\@newctr{#1}[#3]%
- \expandafter\xdef\csname the#1\endcsname{%
- \expandafter\noexpand\csname the#3\endcsname \@prfcountersep
- \@prfcounter{#1}}%
- \global\@namedef{#1}{\@prf{#1}{#2}}%
- \global\@namedef{end#1}{\@endproof}}}
+ \expandafter\@ifdefinable\csname #1\endcsname
+ {\@definecounter{#1}\@newctr{#1}[#3]%
+ \expandafter\xdef\csname the#1\endcsname{%
+ \expandafter\noexpand\csname the#3\endcsname \@prfcountersep
+ \@prfcounter{#1}}%
+ \global\@namedef{#1}{\@prf{#1}{#2}}%
+ \global\@namedef{end#1}{\@endproof}}}
\def\@ynprf#1#2{%
- \expandafter\@ifdefinable\csname #1\endcsname
- {\@definecounter{#1}%
- \expandafter\xdef\csname the#1\endcsname{\@prfcounter{#1}}%
- \global\@namedef{#1}{\@prf{#1}{#2}}%
- \global\@namedef{end#1}{\@endproof}}}
+ \expandafter\@ifdefinable\csname #1\endcsname
+ {\@definecounter{#1}%
+ \expandafter\xdef\csname the#1\endcsname{\@prfcounter{#1}}%
+ \global\@namedef{#1}{\@prf{#1}{#2}}%
+ \global\@namedef{end#1}{\@endproof}}}
\def\@oprf#1[#2]#3{%
- \@ifundefined{c@#2}{\@nocounterr{#2}}%
- {\expandafter\@ifdefinable\csname #1\endcsname
- {\global\@namedef{the#1}{\@nameuse{the#2}}%
- \global\@namedef{#1}{\@prf{#2}{#3}}%
- \global\@namedef{end#1}{\@endproof}}}}
+ \@ifundefined{c@#2}{\@nocounterr{#2}}%
+ {\expandafter\@ifdefinable\csname #1\endcsname
+ {\global\@namedef{the#1}{\@nameuse{the#2}}%
+ \global\@namedef{#1}{\@prf{#2}{#3}}%
+ \global\@namedef{end#1}{\@endproof}}}}
\def\@prf#1#2{%
- \refstepcounter{#1}%
- \@ifnextchar[{\@yprf{#1}{#2}}{\@xprf{#1}{#2}}}
+ \refstepcounter{#1}%
+ \@ifnextchar[{\@yprf{#1}{#2}}{\@xprf{#1}{#2}}}
\def\@xprf#1#2{%
- \@beginproof{#2}{\csname the#1\endcsname}\ignorespaces}
+ \@beginproof{#2}{\csname the#1\endcsname}\ignorespaces}
\def\@yprf#1#2[#3]{%
- \@opargbeginproof{#2}{\csname the#1\endcsname}{#3}\ignorespaces}
+ \@opargbeginproof{#2}{\csname the#1\endcsname}{#3}\ignorespaces}
\def\@prfcounter#1{\noexpand\arabic{#1}}
\def\@prfcountersep{.}
\def\@beginproof#1#2{\trivlist\let\baselinestretch\@blstr
- \item[\hskip \labelsep{\scshape #1.}]\rmfamily}
+ \item[\hskip \labelsep{\scshape #1.}]\rmfamily}
\def\@opargbeginproof#1#2#3{\trivlist\let\baselinestretch\@blstr
- \item[\hskip \labelsep{\scshape #1\ (#3).}]\rmfamily}
+ \item[\hskip \labelsep{\scshape #1\ (#3).}]\rmfamily}
\def\@endproof{\endtrivlist}
\newcommand*{\qed}{\hbox{}\hfill$\Box$}
\@ifundefined{@biboptions}{\xdef\@biboptions{numbers}}{}
\InputIfFileExists{\jobname.spl}{}{}
\ifnonatbib\relax\else
- \RequirePackage[\@biboptions]{natbib}
+ \RequirePackage[\@biboptions]{natbib}
\fi
\newwrite\splwrite
\immediate\openout\splwrite=\jobname.spl
\def\biboptions#1{\def\next{#1}\immediate\write\splwrite{%
- \string\g@addto@macro\string\@biboptions{%
- ,\expandafter\strip@prefix\meaning\next}}}
+ \string\g@addto@macro\string\@biboptions{%
+ ,\expandafter\strip@prefix\meaning\next}}}
\let\baselinestretch=\@blstr
\ifnum\jtype=1
- \RequirePackage{geometry}
- \geometry{twoside,
- paperwidth=210mm,
- paperheight=297mm,
- textheight=562pt,
- textwidth=384pt,
- centering,
- headheight=50pt,
- headsep=12pt,
- footskip=12pt,
- footnotesep=24pt plus 2pt minus 12pt,
- }
- \global\let\bibfont=\footnotesize
- \global\bibsep=0pt
- \if@twocolumn\global\@twocolumnfalse\fi
+\RequirePackage{geometry}
+\geometry{twoside,
+ paperwidth=210mm,
+ paperheight=297mm,
+ textheight=562pt,
+ textwidth=384pt,
+ centering,
+ headheight=50pt,
+ headsep=12pt,
+ footskip=12pt,
+ footnotesep=24pt plus 2pt minus 12pt,
+}
+\if@twocolumn\global\@twocolumnfalse\fi
\else\ifnum\jtype=3
- \RequirePackage{geometry}
- \geometry{twoside,
- paperwidth=210mm,
- paperheight=297mm,
- textheight=622pt,
- textwidth=468pt,
- centering,
- headheight=50pt,
- headsep=12pt,
- footskip=18pt,
- footnotesep=24pt plus 2pt minus 12pt,
- columnsep=2pc
- }
- \global\let\bibfont=\footnotesize
- \global\bibsep=0pt
- \if@twocolumn\input{fleqn.clo}\fi
-\else\ifnum\jtype=5
- \RequirePackage{geometry}
- \geometry{twoside,
- paperwidth=210mm,
- paperheight=297mm,
- textheight=682pt,
- textwidth=522pt,
- centering,
+\RequirePackage{geometry}
+\geometry{twoside,
+ paperwidth=210mm,
+ paperheight=297mm,
+ textheight=622pt,
+ textwidth=468pt,
+ centering,
headheight=50pt,
- headsep=12pt,
- footskip=18pt,
- footnotesep=24pt plus 2pt minus 12pt,
- columnsep=18pt
- }%
- \global\let\bibfont=\footnotesize
- \global\bibsep=0pt
- \input{fleqn.clo}
- \global\@twocolumntrue
+ headsep=12pt,
+ footskip=18pt,
+ footnotesep=24pt plus 2pt minus 12pt,
+ columnsep=2pc
+}
+\if@twocolumn\input{fleqn.clo}\fi
+\else\ifnum\jtype=5
+\RequirePackage{geometry}
+\geometry{twoside,
+ paperwidth=210mm,
+ paperheight=297mm,
+ textheight=682pt,
+ textwidth=522pt,
+ centering,
+headheight=50pt,
+ headsep=12pt,
+ footskip=18pt,
+ footnotesep=24pt plus 2pt minus 12pt,
+ columnsep=18pt
+}%
+\input{fleqn.clo}
+\global\@twocolumntrue
%%
%% End of option '5p'
%%
\fi\fi\fi
\def\journal#1{\gdef\@journal{#1}}
- \let\@journal\@empty
+\let\@journal\@empty
\newenvironment{frontmatter}{}{\maketitle}
\long\def\@makecaption#1#2{%
- \vskip\abovecaptionskip\footnotesize
- \sbox\@tempboxa{#1: #2}%
- \ifdim \wd\@tempboxa >\hsize
- #1: #2\par
- \else
- \global \@minipagefalse
- \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
- \fi
- \vskip\belowcaptionskip}
+ \vskip\abovecaptionskip\footnotesize
+ \sbox\@tempboxa{#1: #2}%
+ \ifdim \wd\@tempboxa >\hsize
+ #1: #2\par
+ \else
+ \global \@minipagefalse
+ \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
+ \fi
+ \vskip\belowcaptionskip}
\AtBeginDocument{\@ifpackageloaded{hyperref}
- {\def\@linkcolor{blue}
- \def\@anchorcolor{blue}
- \def\@citecolor{blue}
- \def\@filecolor{blue}
- \def\@urlcolor{blue}
- \def\@menucolor{blue}
- \def\@pagecolor{blue}
+ {\def\@linkcolor{blue}
+ \def\@anchorcolor{blue}
+ \def\@citecolor{blue}
+ \def\@filecolor{blue}
+ \def\@urlcolor{blue}
+ \def\@menucolor{blue}
+ \def\@pagecolor{blue}
\begingroup
- \@makeother\`%
- \@makeother\=%
- \edef\x{%
- \edef\noexpand\x{%
- \endgroup
- \noexpand\toks@{%
- \catcode 96=\noexpand\the\catcode`\noexpand\`\relax
- \catcode 61=\noexpand\the\catcode`\noexpand\=\relax
- }%
- }%
- \noexpand\x
- }%
+ \@makeother\`%
+ \@makeother\=%
+ \edef\x{%
+ \edef\noexpand\x{%
+ \endgroup
+ \noexpand\toks@{%
+ \catcode 96=\noexpand\the\catcode`\noexpand\`\relax
+ \catcode 61=\noexpand\the\catcode`\noexpand\=\relax
+ }%
+ }%
+ \noexpand\x
+ }%
\x
\@makeother\`
\@makeother\=
}{}}
%%
-\def\appendixname{Appendix }
+\def\appendixname{Appendix}
\renewcommand\appendix{\par
- \setcounter{section}{0}%
- \setcounter{subsection}{0}%
- \setcounter{equation}{0}
- \gdef\thefigure{\@Alph\c@section.\arabic{figure}}%
- \gdef\thetable{\@Alph\c@section.\arabic{table}}%
- \gdef\thesection{\appendixname~\@Alph\c@section}%
- \@addtoreset{equation}{section}%
- \gdef\theequation{\@Alph\c@section.\arabic{equation}}%
- \addtocontents{toc}{\string\let\string\numberline\string\tmptocnumberline}{}{}
+ \setcounter{section}{0}%
+ \setcounter{subsection}{0}%
+ \setcounter{equation}{0}
+ \gdef\thefigure{\@Alph\c@section.\arabic{figure}}%
+ \gdef\thetable{\@Alph\c@section.\arabic{table}}%
+ \gdef\thesection{\appendixname~\@Alph\c@section}%
+ \@addtoreset{equation}{section}%
+ \gdef\theequation{\@Alph\c@section.\arabic{equation}}%
+ \addtocontents{toc}{\string\let\string\numberline\string\tmptocnumberline}{}{}
}
%%%% \numberline width calculation for appendix.
\newdimen\appnamewidth
\def\tmptocnumberline#1{%
- \setbox0=\hbox{\appendixname}
- \appnamewidth=\wd0
- \addtolength\appnamewidth{2.5pc}
- \hb@xt@\appnamewidth{#1\hfill}
+ \setbox0=\hbox{\appendixname}
+ \appnamewidth=\wd0
+ \addtolength\appnamewidth{2.5pc}
+ \hb@xt@\appnamewidth{#1\hfill}
}
%% Added for work with amsrefs.sty
\@ifpackageloaded{amsrefs}%
- {}
- {%\let\bibsection\relax%
- \AtBeginDocument{\def\cites@b#1#2,#3{%
- \begingroup[%
- \toks@{\InnerCite{#2}#1}%
- \ifx\@empty#3\@xp\@gobble\fi
- \cites@c#3%
+ {}
+ {%\let\bibsection\relax%
+ \AtBeginDocument{\def\cites@b#1#2,#3{%
+ \begingroup[%
+ \toks@{\InnerCite{#2}#1}%
+ \ifx\@empty#3\@xp\@gobble\fi
+ \cites@c#3%
}}}
%%
%% Added for avoiding clash with cleveref.sty
\@ifpackageloaded{cleveref}%
- {}
- {\def\tnotetext[#1]#2{\g@addto@macro\@tnotes{%
- \refstepcounter{tnote}%
- \immediate\write\@auxout{\string\Newlabel{#1}{\thetnote}}
- \def\thefootnote{\ifcase\c@tnote\or$\star$\or$\star\star$\fi}%
- \footnotetext{#2}}}
+{}
+{\def\tnotetext[#1]#2{\g@addto@macro\@tnotes{%
+ \refstepcounter{tnote}%
+ \immediate\write\@auxout{\string\Newlabel{#1}{\thetnote}}
+ \def\thefootnote{\ifcase\c@tnote\or$\star$\or$\star\star$\fi}%
+ \footnotetext{#2}}}
%%%
- \def\fntext[#1]#2{\g@addto@macro\@fnotes{%
- \refstepcounter{fnote}%
- \immediate\write\@auxout{\string\Newlabel{#1}{\thefnote}}
- \def\thefootnote{\thefnote}%
- \global\setcounter{footnote}{\c@fnote}%
- \footnotetext{#2}}}
+ \def\fntext[#1]#2{\g@addto@macro\@fnotes{%
+ \refstepcounter{fnote}%
+ \immediate\write\@auxout{\string\Newlabel{#1}{\thefnote}}
+ \def\thefootnote{\thefnote}%
+ \global\setcounter{footnote}{\c@fnote}%
+ \footnotetext{#2}}}
%%%
- \def\cortext[#1]#2{\g@addto@macro\@cornotes{%
- \refstepcounter{cnote}%
- \immediate\write\@auxout{\string\Newlabel{#1}{\thecnote}}
- \def\thefootnote{\ifcase\c@cnote\or$\ast$\or
- $\ast\ast$\fi}%
- \footnotetext{#2}}}
+ \def\cortext[#1]#2{\g@addto@macro\@cornotes{%
+ \refstepcounter{cnote}%
+ \immediate\write\@auxout{\string\Newlabel{#1}{\thecnote}}
+ \def\thefootnote{\ifcase\c@cnote\or$\ast$\or
+ $\ast\ast$\fi}%
+ \footnotetext{#2}}}
}
\def\textmarker#1#2{\textcolor{#1}{#2}}%*%
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/elsevier.lua b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/elsevier.lua
new file mode 100644
index 00000000000..b77a984c5a0
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/elsevier.lua
@@ -0,0 +1,176 @@
+local kClassOpt = "classoption"
+
+-- cite style constants
+local kBibStyleDefault = 'number'
+local kBibStyles = { 'number', 'numbername', 'authoryear' }
+local kBibStyleAuthYr = 'elsarticle-harv'
+local kBibStyleNumber = 'elsarticle-num'
+local kBibStyleNumberName = 'elsarticle-num-names'
+local kBibStyleUnknown = kBibStyleNumberName
+
+-- layout and style
+local kFormatting = pandoc.List({ 'preprint', 'review', 'doubleblind' })
+local kModels = pandoc.List({ '1p', '3p', '5p' })
+local kLayouts = pandoc.List({ 'onecolumn', 'twocolumn' })
+
+
+local function setBibStyle(meta, style)
+ -- .bst files are only supported with natbib
+ if quarto.doc.cite_method() ~= "natbib" then
+ return
+ end
+ if meta['biblio-style'] == nil then
+ meta['biblio-style'] = style
+ quarto.doc.add_format_resource('bib/' .. style .. '.bst')
+ end
+end
+
+local function hasClassOption(meta, option)
+ if meta[kClassOpt] then
+ for i,v in ipairs(meta[kClassOpt]) do
+ if pandoc.utils.stringify(v) == option then
+ return true
+ end
+ end
+ end
+ return false
+end
+
+local function addClassOption(meta, option)
+ if meta[kClassOpt] == nil then
+ meta[kClassOpt] = pandoc.List({})
+ elseif pandoc.utils.type(meta[kClassOpt]) == "Inlines" then
+ -- handle classoption: as a string
+ meta[kClassOpt] = pandoc.List({meta[kClassOpt]})
+ end
+ if not hasClassOption(meta, option) then
+ meta[kClassOpt]:insert({ pandoc.Str(option) })
+ end
+end
+
+local function printList(list)
+ local result = ''
+ local sep = ''
+ for i, v in ipairs(list) do
+ result = result .. sep .. v
+ sep = ', '
+ end
+ return result
+end
+
+local bibstyle
+
+return {
+ {
+ Meta = function(meta)
+ -- If citeproc is being used, switch to the proper
+ -- CSL file
+ if quarto.doc.cite_method() == 'citeproc' and meta['csl'] == nil then
+ meta['csl'] = quarto.utils.resolve_path('bib/elsevier-harvard.csl')
+ end
+
+ if quarto.doc.is_format("pdf") then
+
+ -- read the journal settings
+ local journal = meta['journal']
+ local citestyle = nil
+ local formatting = nil
+ local model = nil
+ local layout = nil
+ local name = nil
+
+ if journal ~= nil then
+ citestyle = journal['cite-style']
+ formatting = journal['formatting']
+ model = journal['model']
+ layout = journal['layout']
+ name = journal['name']
+ end
+
+ -- process the site style
+ if citestyle ~= nil then
+ citestyle = pandoc.utils.stringify(citestyle)
+ else
+ citestyle = kBibStyleDefault
+ end
+ -- capture the bibstyle
+ bibstyle = citestyle
+ if citestyle == 'numbername' then
+ setBibStyle(meta, kBibStyleNumberName)
+ addClassOption(meta, 'number')
+ elseif citestyle == 'authoryear' then
+ setBibStyle(meta, kBibStyleAuthYr)
+ addClassOption(meta, 'authoryear')
+ elseif citestyle == 'number' then
+ setBibStyle(meta, kBibStyleNumber)
+ addClassOption(meta, 'number')
+ elseif citestyle == 'super' then
+ addClassOption(meta, 'super')
+ setBibStyle(meta, kBibStyleNumber)
+ else
+ error("Unknown journal cite-style " .. citestyle .. "\nPlease use one of " .. printList(kBibStyles))
+ setBibStyle(meta, kBibStyleUnknown)
+ end
+
+ -- process the layout
+ if formatting ~= nil then
+ formatting = pandoc.utils.stringify(formatting)
+ if kFormatting:includes(formatting) then
+ addClassOption(meta, formatting)
+ else
+ error("Unknown journal formatting " .. formatting .. "\nPlease use one of " .. printList(kFormatting))
+ end
+ end
+
+ -- process the type
+ if model ~= nil then
+ model = pandoc.utils.stringify(model)
+ if kModels:includes(model) then
+ addClassOption(meta, model)
+ else
+ error("Unknown journal model " .. model .. "\nPlease use one of " .. printList(kModels))
+ end
+ end
+
+ -- 5p models should be two column always
+ if model == '5p' and layout == nil then
+ layout = 'twocolumn'
+ end
+
+ -- process the type
+ if layout ~= nil then
+ layout = pandoc.utils.stringify(layout)
+ if kLayouts:includes(layout) then
+ addClassOption(meta, layout)
+ if layout == 'twocolumn' then
+ quarto.doc.include_file('in-header', 'partials/_two-column-longtable.tex')
+ end
+ else
+ error("Unknown journal layout " .. layout .. "\nPlease use one of " .. printList(kLayouts))
+ end
+ end
+
+ -- process the name
+ if name ~= nil then
+ name = pandoc.utils.stringify(name)
+ quarto.doc.include_text('in-header', '\\journal{' .. name .. '}')
+ end
+ end
+
+ return meta
+ end
+ },
+ {
+ Cite = function(cite)
+ if bibstyle == 'number' or bibstyle == 'super' then
+ -- If we are numbered, force citations into normal mode
+ -- as the author styles don't make sense
+ for i, v in ipairs(cite.citations) do
+ v.mode = 'NormalCitation'
+ end
+ return cite
+ end
+ end,
+
+ }
+}
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/partials/_two-column-longtable.tex b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/partials/_two-column-longtable.tex
new file mode 100644
index 00000000000..9ba482a5af5
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/partials/_two-column-longtable.tex
@@ -0,0 +1,20 @@
+\usepackage{float}
+\makeatletter
+\let\oldlt\longtable
+\let\endoldlt\endlongtable
+\def\longtable{\@ifnextchar[\longtable@i \longtable@ii}
+\def\longtable@i[#1]{\begin{figure}[H]
+\onecolumn
+\begin{minipage}{0.5\textwidth}
+\oldlt[#1]
+}
+\def\longtable@ii{\begin{figure}[H]
+\onecolumn
+\begin{minipage}{0.5\textwidth}
+\oldlt
+}
+\def\endlongtable{\endoldlt
+\end{minipage}
+\twocolumn
+\end{figure}}
+\makeatother
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/partials/before-body.tex b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/partials/before-body.tex
new file mode 100644
index 00000000000..115418273cd
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/partials/before-body.tex
@@ -0,0 +1,41 @@
+
+\begin{frontmatter}
+\title{$title$$if(subtitle)$ \\\large{$subtitle$} $endif$}
+$for(by-author)$\author[$for(by-author.affiliations)$$it.number$$sep$,$endfor$]{$by-author.name.literal$%
+$if(by-author.attributes.corresponding)$\corref{cor1}$endif$%
+$if(by-author.note.text)$\fnref{fn$by-author.note.number$}$endif$}
+$if(by-author.email)$ \ead{$by-author.email$} $endif$
+$endfor$
+$for(by-affiliation)$
+\affiliation[$it.number$]{organization={$it.name$$if(it.department)$, $it.department$$endif$},$if(it.address)$addressline={$it.address$}$endif$$if(it.city)$$if(it.address)$,$endif$city={$it.city$}$endif$$if(it.country)$$if(it.city)$,$elseif(it.address)$,$endif$country={$it.country$},countrysep={,}$endif$$if(it.postal-code)$$if(it.country)$,$elseif(it.city)$,$elseif(it.address)$,$endif$postcode={$it.postal-code$}$endif$,postcodesep={}}
+$endfor$
+
+\cortext[cor1]{Corresponding author}
+$for(by-author)$
+$if(by-author.note.text)$\fntext[fn$by-author.note.number$]{$by-author.note.text$}$endif$
+$endfor$
+
+$if(abstract)$
+\begin{abstract}
+$abstract$
+\end{abstract}
+$endif$
+
+$if(journal.graphical-abstract)$\begin{graphicalabstract}
+$journal.graphical-abstract$
+\end{graphicalabstract}
+$endif$
+
+$if(journal.highlights)$\begin{highlights}
+$for(journal.highlights)$\item $it$$endfor$
+\end{highlights}
+$endif$
+
+$if(keywords)$
+\begin{keyword}
+ $for(keywords/allbutlast)$$keywords$ \sep $endfor$
+ $for(keywords/last)$$keywords$$endfor$
+\end{keyword}
+$endif$
+\end{frontmatter}
+
\ No newline at end of file
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/title.tex b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/partials/title.tex
similarity index 100%
rename from tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/title.tex
rename to tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/partials/title.tex
diff --git a/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/styles/elsevier.scss b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/styles/elsevier.scss
new file mode 100644
index 00000000000..d002b364571
--- /dev/null
+++ b/tests/docs/extensions/format/academic/_extensions/quarto-journals/elsevier/styles/elsevier.scss
@@ -0,0 +1 @@
+/*-- scss:defaults --*/
diff --git a/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es-no-install.qmd b/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es-no-install.qmd
index 294d822314e..cb9ccba544d 100644
--- a/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es-no-install.qmd
+++ b/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es-no-install.qmd
@@ -4,13 +4,20 @@ format: pdf
lang: es
latex-auto-install: false
_quarto:
+ tests-on-ci: false
tests:
- pdf: default
+ pdf:
+ noErrors: true
+ printsMessage:
+ level: WARN
+ regex: "Possibly missing hyphenation"
---
+** This test is to be run manually as we don't want to uninstall and reinstall package in CI**
+
```{r}
#| include: false
-
+#| messages: 'NA'
# Remove the hyphen package for spanish so that the test is meaningful
if (tinytex::check_installed("hyphen-spanish")) {
message("Removing 'hyphen-spanish' package for the render")
diff --git a/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es.qmd b/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es.qmd
index 89bafffd58b..ce1b6b66703 100644
--- a/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es.qmd
+++ b/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es.qmd
@@ -6,14 +6,21 @@ _quarto:
pdf: null
---
+**Only remove package on CI**
```{r}
+#| eval: !expr isFALSE(as.logical(Sys.getenv("CI", "false")))
#| include: false
+#| messages: "NA"
# Remove the hyphen package for spanish
if (tinytex::check_installed("hyphen-spanish")) {
message("Removing 'hyphen-spanish' package for the render")
tinytex::tlmgr_remove("hyphen-spanish")
}
+if (tinytex::check_installed("babel-spanish")) {
+ message("Removing 'babel-spanish' package for the render")
+ tinytex::tlmgr_remove("babel-spanish")
+}
```
# Hola !
diff --git a/tests/docs/smoke-all/2025/11/04/13633.qmd b/tests/docs/smoke-all/2025/11/04/13633.qmd
new file mode 100644
index 00000000000..24685a399b8
--- /dev/null
+++ b/tests/docs/smoke-all/2025/11/04/13633.qmd
@@ -0,0 +1,22 @@
+---
+title: "Babel English Auto-Install (#13633)"
+format: pdf
+lang: en
+_quarto:
+ tests:
+ pdf: null
+---
+
+```{r}
+#| eval: !expr isFALSE(as.logical(Sys.getenv("CI", "false")))
+#| include: false
+#| messages: "NA"
+
+# Remove babel-english package to test auto-installation
+if (tinytex::check_installed("babel-english")) {
+ message("Removing 'babel-english' package for the render")
+ tinytex::tlmgr_remove("babel-english")
+}
+```
+
+This document tests that Quarto correctly detects and auto-installs babel-english when rendering with `lang: en`.
diff --git a/tests/smoke/render/render-format-extension.test.ts b/tests/smoke/render/render-format-extension.test.ts
index 0ecbf96dd1c..f82374cf32f 100644
--- a/tests/smoke/render/render-format-extension.test.ts
+++ b/tests/smoke/render/render-format-extension.test.ts
@@ -6,19 +6,65 @@
// TODO re-enable the ACM tests once the template has been updated
+// This test file focuses on rendering documents with journal extensions.
+// It tests HTML formats, PDF formats, and format variants (e.g., elsevier-pdf+foobar).
+// Note: extension-render-journals.test.ts tests template scaffolding (quarto use template).
+// Both files serve different purposes and should remain separate.
+
import { safeRemoveSync } from "../../../src/core/path.ts";
import { docs } from "../../utils.ts";
+import { quarto } from "../../../src/quarto.ts";
import { testRender } from "./render.ts";
+// Update extensions to latest versions before testing
+// Falls back to committed versions on network failure
+//
+// Maintenance note: Committed extension files serve as fallback for offline/CI
+// failure scenarios. They don't need frequent updates since tests always fetch
+// latest versions. When extension-related issues occur, consider updating the
+// committed files to document the working version (see commits c3149a9ba and
+// b8421caf9 for example).
+const updateExtensions = async () => {
+ try {
+ console.log("Updating quarto-journals extensions to latest versions...");
+ const wd = Deno.cwd();
+ Deno.chdir(docs("extensions/format/academic"));
+
+ for (const repo of ["acs", "elsevier"]) {
+ await quarto([
+ "update",
+ "extension",
+ `quarto-journals/${repo}`,
+ "--no-prompt",
+ ]);
+ }
+
+ Deno.chdir(wd);
+ console.log("Extensions updated successfully");
+ } catch (error) {
+ const message = error instanceof Error ? error.message : String(error);
+ console.warn(`Failed to update extensions: ${message}`);
+ console.warn("Falling back to committed extension versions");
+ }
+};
+
// Some HTML tests
testRender(docs("extensions/format/academic/document.qmd"), "html", false);
// testRender(docs("extensions/format/academic/document.qmd"), "acm-html", false);
-testRender(docs("extensions/format/academic/document.qmd"), "acs-html", false);
+testRender(
+ docs("extensions/format/academic/document.qmd"),
+ "acs-html",
+ false,
+ [],
+ { setup: updateExtensions },
+);
testRender(
docs("extensions/format/academic/document.qmd"),
"elsevier-html",
false,
+ [],
+ { setup: updateExtensions },
);
// some PDF tests
@@ -43,10 +89,12 @@ testRender(
true,
[],
{
+ setup: updateExtensions,
// deno-lint-ignore require-await
teardown: async () => {
- // Clean up the bib file that is generated by the elesevier class
+ // Clean up files generated by the acs extension
safeRemoveSync(docs("extensions/format/academic/acs-document.bib"));
+ safeRemoveSync(docs("extensions/format/academic/achemso.bst"));
},
},
);
@@ -56,10 +104,13 @@ testRender(
true,
[],
{
+ setup: updateExtensions,
// deno-lint-ignore require-await
teardown: async () => {
- // Clean up the SPL file that is generated by the elesevier class
+ // Clean up files generated by the elsevier extension
safeRemoveSync(docs("extensions/format/academic/document.spl"));
+ safeRemoveSync(docs("extensions/format/academic/elsarticle.cls"));
+ safeRemoveSync(docs("extensions/format/academic/elsarticle-num.bst"));
},
},
);
@@ -71,10 +122,13 @@ testRender(
true,
[],
{
+ setup: updateExtensions,
// deno-lint-ignore require-await
teardown: async () => {
- // Clean up the SPL file that is generated by the elesevier class
+ // Clean up files generated by the elsevier extension
safeRemoveSync(docs("extensions/format/academic/document+foobar.spl"));
+ safeRemoveSync(docs("extensions/format/academic/elsarticle.cls"));
+ safeRemoveSync(docs("extensions/format/academic/elsarticle-num.bst"));
},
},
);
diff --git a/tests/unit/latexmk/parse-error.test.ts b/tests/unit/latexmk/parse-error.test.ts
index 7da758cef00..aa577531655 100644
--- a/tests/unit/latexmk/parse-error.test.ts
+++ b/tests/unit/latexmk/parse-error.test.ts
@@ -5,7 +5,7 @@
*
*/
-import { findMissingFontsAndPackages } from "../../../src/command/render/latexmk/parse-error.ts"
+import { findMissingFontsAndPackages, findMissingHyphenationFiles } from "../../../src/command/render/latexmk/parse-error.ts"
import { unitTest } from "../../test.ts";
import { assert } from "testing/asserts";
@@ -41,6 +41,10 @@ unitTest("Detect missing files with `findMissingFontsAndPackages`", async () =>
(babel) There is a locale ini file for this language.
(babel) If it’s the main language, try adding \`provide=*'
(babel) to the babel package options.`, "ngerman.ldf")
+ assertFound("! Package babel Error: Unknown option 'english'.", "english.ldf");
+ assertFound(`! Package babel Error: Unknown option 'ngerman'.
+(babel) Suggested actions:
+(babel) * Make sure you haven't misspelled it`, "ngerman.ldf");
assertFound("!pdfTeX error: pdflatex (file 8r.enc): cannot open encoding file for reading", "8r.enc");
assertFound("! CTeX fontset `fandol' is unavailable in current mode", "fandol");
assertFound('Package widetext error: Install the flushend package which is a part of sttools', "flushend.sty");
@@ -50,4 +54,61 @@ unitTest("Detect missing files with `findMissingFontsAndPackages`", async () =>
assertFound("luaotfload-features.lua:835: module 'lua-uni-normalize' not found:", "lua-uni-algos.lua");
},{
cwd: () => "unit/latexmk/"
+})
+
+unitTest("Detect missing hyphenation with babel warnings", async () => {
+ // Test backtick-quote format (old format)
+ const logWithBacktick = `Package babel Warning: No hyphenation patterns were preloaded for
+(babel) the language \`Spanish' into the format.
+(babel) Please, configure your TeX system to add them and
+(babel) rebuild the format. Now I will use the patterns
+(babel) preloaded for \\language=0 instead on input line 51.`;
+ assert(
+ findMissingHyphenationFiles(logWithBacktick) === "hyphen-spanish",
+ "Should detect hyphen-spanish from backtick-quote format"
+ );
+
+ // Test straight-quote format (new format - the bug we're fixing)
+ const logWithStraightQuotes = `Package babel Warning: No hyphenation patterns were preloaded for
+(babel) the language 'Spanish' into the format.
+(babel) Please, configure your TeX system to add them and
+(babel) rebuild the format. Now I will use the patterns
+(babel) preloaded for \\language=0 instead on input line 51.`;
+ assert(
+ findMissingHyphenationFiles(logWithStraightQuotes) === "hyphen-spanish",
+ "Should detect hyphen-spanish from straight-quote format"
+ );
+
+ // Test ngerman special case (should return hyphen-german, not hyphen-ngerman)
+ const logGerman = `Package babel Warning: No hyphenation patterns were preloaded for
+(babel) the language 'ngerman' into the format.`;
+ assert(
+ findMissingHyphenationFiles(logGerman) === "hyphen-german",
+ "Should map ngerman to hyphen-german"
+ );
+
+ // Test Chinese - no hyphen package exists
+ const logChinese = `Package babel Warning: No hyphenation patterns were preloaded for
+(babel) the language 'chinese' into the format.`;
+ assert(
+ findMissingHyphenationFiles(logChinese) === undefined,
+ "Should return undefined for Chinese (no hyphen package)"
+ );
+
+ // Test alternative Info pattern (issue #10291)
+ const logInfoChinese = `Package babel Info: Hyphen rules for 'chinese-hans' set to \\l@nil
+(babel) (\\language10). Reported on input line 143.`;
+ assert(
+ findMissingHyphenationFiles(logInfoChinese) === undefined,
+ "Should return undefined for chinese-hans via Info pattern"
+ );
+
+ // Test no warning present
+ const logNoWarning = "Some other log text without babel warnings";
+ assert(
+ findMissingHyphenationFiles(logNoWarning) === undefined,
+ "Should return undefined when no babel warning present"
+ );
+}, {
+ cwd: () => "unit/latexmk/"
})
\ No newline at end of file