-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtemplate.tex
More file actions
306 lines (274 loc) · 13.7 KB
/
Copy pathtemplate.tex
File metadata and controls
306 lines (274 loc) · 13.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
%% Elsevier template for MyST: CAS (cas-sc, cas-dc) and elsarticle
%% Based on cas-sc-template.tex, cas-dc-template.tex, elsarticle-template-num.tex
%% Original copyright 2007-2024 Elsevier Ltd (LPPL-1.3c)
%%
%% Two escapers for raw frontmatter strings; which field takes which is not
%% guessable from the template. See "Escaping" in README.md.
%% esc(): everything. Backslash rides a sentinel so braces cannot re-escape it.
[# macro esc(s) #][- s | default("") | replace("\\", "@BSL@") | replace("{", "\\{") | replace("}", "\\}") | replace("&", "\\&") | replace("%", "\\%") | replace("$", "\\$") | replace("#", "\\#") | replace("_", "\\_") | replace("~", "\\textasciitilde{}") | replace("^", "\\textasciicircum{}") | replace("@BSL@", "\\textbackslash{}") -][# endmacro #]
%% esctext(): & % # only, for fields that legitimately carry math ($x_1$,
%% $\alpha$-mixing). Those three corrupt output silently; a stray _ or $ raises
%% a TeX error the CI log grep already catches, so it need not be escaped here.
[# macro esctext(s) #][- s | default("") | replace("&", "\\&") | replace("%", "\\%") | replace("#", "\\#") -][# endmacro #]
[# if options.document_class == 'elsarticle' #]
%% Citation style rides on the class options (\@biboptions): elsarticle loads
%% natbib itself. Named options exist only where the classes disagree on a
%% NAME; everything else rides on class_options verbatim, future ones included.
[# set extra = (',' ~ options.class_options | trim) if options.class_options else '' #]
\documentclass[[- options.elsarticle_layout -],[# if options.columns == 'double' #]twocolumn,[# endif #][# if options.citation_style == 'numbers' #]number[# else #]authoryear[# endif #][# if options.review #],review[# endif #][# if options.blind == 'double' #],doubleblind[# endif #][-extra-]]{elsarticle}
[# elif options.columns == 'double' #]
\documentclass[a4paper,fleqn[# if options.longmktitle #],longmktitle[# endif #][# if options.review #],review[# endif #][# if options.blind == 'double' #],doubleblind[# elif options.blind == 'single' #],singleblind[# endif #][-extra-]]{cas-dc}
[# else #]
\documentclass[a4paper,fleqn[# if options.longmktitle #],longmktitle[# endif #][# if options.review #],review[# endif #][# if options.blind == 'double' #],doubleblind[# elif options.blind == 'single' #],singleblind[# endif #][-extra-]]{cas-sc}
[# endif #]
%% Engine check: XeLaTeX or LuaLaTeX is required for Unicode in author
%% names, titles, and stix/charis fonts. pdflatex falls back to CMR and
%% may mangle non-ASCII characters; warn loudly so users notice.
\usepackage{iftex}
\ifPDFTeX
\PackageWarningNoLine{elsevier-myst-template}{%
pdflatex detected. This template targets XeLaTeX or LuaLaTeX.\MessageBreak
Unicode in author names, titles, and affiliations may not render\MessageBreak
correctly. Re-run with `xelatex` or `lualatex` for full support%
}
\fi
\iftutex
\usepackage{fontspec}
\fi
[# if options.document_class == 'elsarticle' #]
%% natbib is already loaded by elsarticle.cls; loading it again would clash.
%% cas-sc.cls loads the table stack below, elsarticle does not, and MyST emits
%% markup needing it either way. Order: array first, xcolor before colortbl.
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{array}
\usepackage{booktabs}
\usepackage{makecell}
\usepackage{multirow}
\usepackage[svgnames,dvipsnames]{xcolor}
\usepackage{colortbl}
\usepackage{dcolumn}
\usepackage{stfloats}
\usepackage{xspace}
\usepackage{xstring}
\usepackage{etoolbox}
\usepackage[colorlinks,allcolors=blue]{hyperref}
%% CAS has a `bio' environment for author biographies; elsarticle has none,
%% so the same part would die on an undefined control sequence. The argument
%% is CAS's photo path, unused here. Shim keeps the content rather than drop it.
\newenvironment{bio}[1]{\par\medskip\small\noindent\ignorespaces}{\par\medskip}
[# elif options.citation_style == 'numbers' #]
\usepackage[numbers]{natbib}
[# else #]
\usepackage[authoryear,longnamesfirst]{natbib}
[# endif #]
%% Target journal comes from the BUILT-IN `venue`, MyST's key for where a work
%% is submitted or published, rather than a custom option. Backslash goes to a
%% SENTINEL and is expanded LAST, or the brace rules would re-escape its braces.
[# set jrnl = doc.venue.title if doc.venue and doc.venue.title else '' #]
[# if options.document_class == 'elsarticle' and jrnl #]
\journal{[- esc(jrnl) -]}
[# endif #]
%% Algorithm support
\usepackage{algorithm}
\usepackage{algpseudocode}
%% A blank `>` line followed by a dash-prefixed line makes MyST wrap the quote in
%% a figure with \caption*. Measured: the BLANK LINE is the trigger, `--` and
%% `---` behave alike, and without it neither does. Unshimmed: "Figure N: *".
\usepackage{caption}
[- IMPORTS -]
\begin{document}
[# if options.document_class != 'elsarticle' #]
\let\WriteBookmarks\relax
\def\floatpagefraction{1}
\def\textfraction{.001}
[# endif #]
[# if options.document_class == 'elsarticle' #]
%% elsarticle needs every frontmatter declaration inside this environment; the
%% CAS classes take them at top level. Everything down to \maketitle is shared.
\begin{frontmatter}
[# endif #]
%% \cormark and \fnmark are independent mark spaces and cannot collide, so only
%% \fnmark needs disjoint ranges: [1..N] per-author notes by loop.index, [N+1]
%% the shared equal-contributor note, for N authors.
[# set author_count = doc.authors | length if doc.authors else 0 #]
[# set eq_fnmark = author_count + 1 #]
[# set has_equal = doc.authors and (doc.authors | selectattr("equal_contributor") | list | length > 1) #]
%% elsarticle resolves title-note, corresponding and footnote labels in ONE
%% namespace shared with affiliations, so bare integers collide: \tnoteref{1}
%% would render the affiliation mark. Prefixes are empty for CAS, which is safe.
[# set tnp = 'tn' if options.document_class == 'elsarticle' else '' #]
[# set corp = 'cor' if options.document_class == 'elsarticle' else '' #]
[# set fnp = 'fn' if options.document_class == 'elsarticle' else '' #]
[# if options.document_class != 'elsarticle' #]
%% \shorttitle and \shortauthors are CAS-only; elsarticle has neither.
[# if doc.short_title #]
\shorttitle{[- esctext(doc.short_title) -]}
[# else #]
\shorttitle{[- esctext(doc.title) -]}
[# endif #]
%% Surname is the last word of the full name (handles middle initials). MyST only
%% WARNS on an author with no name, so a nameless author reaches here: filter the
%% list FIRST, or the separator is emitted for an entry that prints nothing.
[# set named_authors = doc.authors | selectattr("name") | list if doc.authors else [] #]
[# if named_authors #]
\shortauthors{[# for author in named_authors #][- esc(author.name.split(" ") | last) -][# if not loop.last #], [# endif #][# endfor #]}
[# endif #]
[# endif #]
[# if options.document_class == 'elsarticle' #]
%% elsarticle's \title takes no mode key and has no subtitle slot, so a
%% subtitle is appended after a colon rather than silently dropped.
\title{[- esctext(doc.title) -][# if doc.subtitle #]: [- esctext(doc.subtitle) -][# endif #][# if parts.title_note #]\tnoteref{[-tnp-]1}[# endif #]}
[# else #]
\title[mode=title]{[- esctext(doc.title) -]}
[# if doc.subtitle #]
\title[mode=sub]{[- esctext(doc.subtitle) -]}
[# endif #]
[# endif #]
%% CAS marks the title separately; elsarticle carries \tnoteref inside \title.
[# if parts.title_note #]
[# if options.document_class != 'elsarticle' #]
\tnotemark[1]
[# endif #]
\tnotetext[[-tnp-]1]{[-parts.title_note-]}
[# endif #]
[# for author in doc.authors #]
[#- set author_opts = '' -#]
[#- if author.orcid -#][#- set author_opts = 'orcid=' ~ author.orcid -#][#- endif -#]
[#- if author.deceased -#][#- set author_opts = author_opts ~ (',' if author_opts else '') ~ 'deceased' -#][#- endif -#]
[#- if author.facebook -#][#- set author_opts = author_opts ~ (',' if author_opts else '') ~ 'facebook=' ~ author.facebook -#][#- endif -#]
[#- if author.linkedin -#][#- set author_opts = author_opts ~ (',' if author_opts else '') ~ 'linkedin=' ~ author.linkedin -#][#- endif -#]
[#- if author.twitter -#][#- set author_opts = author_opts ~ (',' if author_opts else '') ~ 'twitter=' ~ author.twitter -#][#- endif -#]
%% Two CAS-only shapes here. The trailing [orcid=...] group: elsarticle's \author
%% takes only the affiliation label, so a second group prints as literal text.
%% The marks: elsarticle wants \corref/\fnref INSIDE the name group, not after.
[# if options.document_class == 'elsarticle' #]
\author[[- author.affiliations | join(",", "index") -]]{[- esc(author.name) -][# if author.corresponding #]\corref{[-corp-][-loop.index-]}[# endif #][# if author.note #]\fnref{[-fnp-][-loop.index-]}[# endif #][# if author.equal_contributor and has_equal #]\fnref{[-fnp-][-eq_fnmark-]}[# endif #]}
[# else #]
\author[[- author.affiliations | join(",", "index") -]]{[- esc(author.name) -]}[# if author_opts #][[- author_opts -]][# endif #]
[# if author.corresponding #]
\cormark[[-loop.index-]]
[# endif #]
[# if author.note #]
\fnmark[[-loop.index-]]
[# endif #]
[# if author.equal_contributor and has_equal #]
\fnmark[[-eq_fnmark-]]
[# endif #]
[# endif #]
[# if author.email #]
\ead{[-author.email-]}
[# endif #]
[# if author.url #]
\ead[url]{[-author.url-]}
[# endif #]
[# if author.roles and options.document_class != 'elsarticle' #]
\credit{[# for role in author.roles #][- esc(role) -][# if not loop.last #], [# endif #][# endfor #]}
[# endif #]
[# endfor #]
[# for affiliation in doc.affiliations #]
[#- set has_address = affiliation.department or affiliation.address or affiliation.city or affiliation.postal_code or affiliation.state or affiliation.country -#]
%% op={} is the organization-punctuation separator (cas-common.sty, and the same
%% key in elsarticle). Empty suppresses the trailing comma after a standalone
%% organization name with no department, address, or city.
\affiliation[[-affiliation.index-]]{organization={[- esc(affiliation.name) -]}[# if not has_address #],op={}[# endif #][# if affiliation.department #],
department={[- esc(affiliation.department) -]}[# endif #][# if affiliation.address #],
addressline={[- esc(affiliation.address) -]}[# endif #][# if affiliation.city #],
city={[- esc(affiliation.city) -]}[# endif #][# if affiliation.postal_code #],
postcode={[- esc(affiliation.postal_code) -]}[# endif #][# if affiliation.state #],
state={[- esc(affiliation.state) -]}[# endif #][# if affiliation.country #],
country={[- esc(affiliation.country) -]}[# endif #]}
[# endfor #]
[# for author in doc.authors #]
[# if author.corresponding #]
\cortext[[-corp-][-loop.index-]]{Corresponding author}
[# endif #]
[# if author.note #]
\fntext[[-fnp-][-loop.index-]]{[- esc(author.note) -]}
[# endif #]
[# endfor #]
[# if has_equal #]
\fntext[[-fnp-][-eq_fnmark-]]{These authors contributed equally to this work.}
[# endif #]
[# if parts.acknowledgments #]
\nonumnote{[-parts.acknowledgments-]}
[# endif #]
[# if parts.note #]
\nonumnote{[-parts.note-]}
[# endif #]
[# if parts.abstract #]
\begin{abstract}
[-parts.abstract-]
\end{abstract}
[# elif doc.abstract #]
\begin{abstract}
[-doc.abstract-]
\end{abstract}
[# endif #]
[# if parts.graphical_abstract #]
\begin{graphicalabstract}
[-parts.graphical_abstract-]
\end{graphicalabstract}
[# elif options.graphical_abstract #]
\begin{graphicalabstract}
%% A PNG that is BOTH 16-bit and alpha silently fails to paint here under
%% xdvipdfmx, in either class: it is embedded in the PDF but never drawn.
%% Convert to 8-bit first. See "Graphical abstract images" in README.md.
\includegraphics[width=\linewidth,keepaspectratio]{[-options.graphical_abstract-]}
\end{graphicalabstract}
[# endif #]
[# if parts.highlights #]
\begin{highlights}
[-parts.highlights-]
\end{highlights}
[# elif parts.keypoints #]
\begin{highlights}
\item [-parts.keypoints | trim | replace("\n\n", "\n") | replace("\n", "\n\\item ")-]
\end{highlights}
[# endif #]
%% `keyword' (singular) in elsarticle, `keywords' (plural) in CAS; JEL codes
%% come from the BUILT-IN `tags` and must sit INSIDE the environment.
%% elsarticle's \JEL is an argument-less SWITCH; cas-common's takes a group.
[# if doc.keywords or doc.tags #]
[# if options.document_class == 'elsarticle' #]
\begin{keyword}
[# if doc.keywords #][# for kw in doc.keywords #][- esctext(kw) -][# if not loop.last #] \sep [# endif #][# endfor #]
[# endif #][# if doc.tags #]\JEL [# for code in doc.tags #][- esc(code) -][# if not loop.last #]; [# endif #][# endfor #]
[# endif #]\end{keyword}
[# else #]
\begin{keywords}
[# if doc.keywords #][# for kw in doc.keywords #][- esctext(kw) -][# if not loop.last #] \sep [# endif #][# endfor #]
[# endif #][# if doc.tags #]\JEL{[# for code in doc.tags #][- esc(code) -][# if not loop.last #]; [# endif #][# endfor #]}
[# endif #]\end{keywords}
[# endif #]
[# endif #]
[# if options.document_class == 'elsarticle' #]
%% \end{frontmatter} typesets the frontmatter; elsarticle has no \maketitle.
\end{frontmatter}
[# else #]
\maketitle
[# endif #]
[-CONTENT-]
[# if options.document_class != 'elsarticle' #]
\printcredits
[# endif #]
[# if parts.ai_declaration #]
\section*{Declaration of generative AI and AI-assisted technologies in the manuscript preparation process}
[-parts.ai_declaration-]
[# endif #]
[# if options.document_class == 'elsarticle' #]
%% elsarticle provides three styles; the numeric one has an author-name variant.
\bibliographystyle{[# if options.citation_style == 'numbers' #]elsarticle-num[# else #]elsarticle-harv[# endif #]}
[# else #]
\bibliographystyle{cas-model2-names}
[# endif #]
[# if doc.bibliography #]
\bibliography{[-doc.bibliography | join(", ")-]}
[# endif #]
%% There is deliberately no parts.appendix branch: a work cited only inside a
%% frontmatter part reaches the .tex and never the .bib, which is an undefined
%% citation at exit 0. Put appendices in the body, per README.md "Appendices".
[# if parts.biography #]
[-parts.biography-]
[# endif #]
\end{document}