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