|
108 | 108 | set document(title: title, author: authors.map(author => author.name)) |
109 | 109 |
|
110 | 110 |
|
111 | | - |
112 | 111 | // layout |
113 | | - |
114 | | - set page(columns: 2, |
115 | | - ..if paper-size == "a4" { |
116 | | - (paper: "a4", margin: (top: 37mm, bottom: 19mm, x: 20mm)) |
117 | | - } else if paper-size in ("letter", "us-letter") { |
118 | | - (paper: "us-letter", margin: (y: 0.75in, left: 0.79in, right: 1.02in)) |
119 | | - } else if paper-size == "jacow" { // jacow size is intersection of both |
120 | | - (width: 21cm, height: 11in, margin: (x: 20mm, y: 0.75in)) |
121 | | - } else if paper-size == "test" { |
122 | | - (width: 21cm, height: auto, margin: (x: 20mm, y: 0.75in)) |
123 | | - } else { |
124 | | - panic("Unsupported paper-size, use 'a4', 'us-letter' or 'jacow'!") |
125 | | - }, |
126 | | - ..if show-grid { |
127 | | - (background: [ |
128 | | - #let at = (x: 0pt, y: 0pt, c) => place(bottom + left, move(dx: x, dy: -y, c)) |
129 | | - // grid |
130 | | - #for i in range(-1, 28){ |
131 | | - let style = (length: 100%, stroke: silver) |
132 | | - at(x: 20mm + i*1cm, line(angle: 90deg, ..style)) |
133 | | - at(y: 0.75in + i*0.5in, line(..style)) |
134 | | - set text(fill: gray.darken(50%)) |
135 | | - at(x: 20mm + i*1cm, y: 0.25in, if i == 1 [1 cm] else if i >= 0 [#i]) |
136 | | - at(x: 1cm, y: 0.75in + i*0.5in, if i == 1 [½ in] else if i >= 0 {str(i/2).replace(".5", "½")}) |
137 | | - } |
138 | | - // page and column borders |
139 | | - #at(rect(width: 21cm, height: 29.7cm)) // DIN A4 |
140 | | - #at(rect(width: 8.5in, height: 11in)) // US letter |
141 | | - #at(x: 2cm, y: 0.75in, rect(width: 82.5mm, height: 9.5in, stroke: green)) |
142 | | - #at(x: 19cm, y: 0.75in, rect(width: -82.5mm, height: 9.5in, stroke: green)) |
143 | | - ]) |
144 | | - } |
| 112 | + |
| 113 | + let paper = ( |
| 114 | + if lower(paper-size) == "a4" {(width: 21mm, height: 29.7mm)} |
| 115 | + else if lower(paper-size) in ("us", "letter", "us-letter") {(width: 8.5in, height: 11in)} |
| 116 | + else if lower(paper-size) in ("jacow", "test") {(width: 21cm, height: 11in)} |
| 117 | + else {panic("Unsupported paper-size, use 'a4', 'us-letter' or 'jacow'!")} |
| 118 | + ) |
| 119 | + |
| 120 | + // jacow margins slightly increased as per editor request |
| 121 | + let left-margin = 20mm |
| 122 | + let column-width = 82.5mm |
| 123 | + let column-gutter = 5mm |
| 124 | + let bottom-margin = 0.75in + 0.1in |
| 125 | + let column-height = 9.5in - 0.1in |
| 126 | + |
| 127 | + set page( |
| 128 | + width: paper.width, |
| 129 | + height: if lower(paper-size) == "test" {auto} else {paper.height}, |
| 130 | + margin: ( |
| 131 | + left: left-margin, |
| 132 | + right: paper.width - left-margin - 2*column-width - column-gutter + 0.4mm, |
| 133 | + top: paper.height - bottom-margin - column-height + 0.005in, |
| 134 | + bottom: bottom-margin + 0.03in |
| 135 | + ), |
| 136 | + columns: 2, |
145 | 137 | ) |
146 | 138 |
|
147 | | - set columns(gutter: 0.2in) |
| 139 | + set columns(gutter: column-gutter + 0.4mm) |
| 140 | + |
| 141 | + |
148 | 142 |
|
149 | 143 | set text( |
150 | 144 | font: "TeX Gyre Termes", |
|
156 | 150 | leading: 0.5em, |
157 | 151 | ) |
158 | 152 |
|
| 153 | + |
| 154 | + // draft utilities |
| 155 | + |
159 | 156 | set page( |
160 | 157 | header: grid(columns: (2fr, 3fr), align: (left, right))[ |
161 | 158 | // Page limit warning with note in header |
162 | 159 | // until we have https://github.com/typst/typst/issues/1322 |
163 | 160 | #set text(fill: red, size: 13pt, weight: "bold") |
164 | | - #context if page-limit != none and query(<references>).at(0).location().page() > page-limit [ |
| 161 | + #context if page-limit != none and query(<content-end>).at(0).location().page() > page-limit [ |
165 | 162 | Limit of #page-limit pages exceeded |
166 | 163 | ] |
167 | 164 | ][ |
168 | 165 | // Draft note |
169 | 166 | #set text(fill: red) |
170 | 167 | #draft-note |
171 | | - ] |
| 168 | + ], |
| 169 | + ..if show-grid { |
| 170 | + (background: [ |
| 171 | + #let at = (x: 0pt, y: 0pt, c) => place(bottom + left, move(dx: x, dy: -y, c)) |
| 172 | + // grid |
| 173 | + #context for i in range(-1, 28){ |
| 174 | + let style = (length: 100%, stroke: silver) |
| 175 | + at(x: left-margin + i*1cm, line(angle: 90deg, ..style)) |
| 176 | + at(y: bottom-margin + i*0.5in, line(..style)) |
| 177 | + set text(fill: gray.darken(50%)) |
| 178 | + at(x: left-margin + i*1cm, y: bottom-margin - 0.5in, if i == 1 [1 cm] else if i >= 0 [#i]) |
| 179 | + at(x: left-margin - 1cm, y: bottom-margin + i*0.5in, if i == 1 [½ in] else if i >= 0 {str(i/2).replace(".5", "½")}) |
| 180 | + } |
| 181 | + // page and column borders |
| 182 | + #at(rect(width: 21cm, height: 29.7cm)) // DIN A4 |
| 183 | + #at(rect(width: 8.5in, height: 11in)) // US letter |
| 184 | + #at(x: left-margin, y: bottom-margin, rect(width: column-width, height: column-height, stroke: green)) |
| 185 | + #at(x: left-margin + column-width + column-gutter, y: bottom-margin, rect(width: column-width, height: column-height, stroke: green)) |
| 186 | + ]) |
| 187 | + } |
172 | 188 | ) |
173 | 189 |
|
174 | | - |
175 | | - // Line numbers |
176 | 190 | set par.line(..if show-line-numbers {(numbering: it => text(fill: gray)[#it])}) |
177 | 191 |
|
178 | 192 |
|
|
219 | 233 | * Title |
220 | 234 | */ |
221 | 235 |
|
| 236 | + v(0.75pt) |
222 | 237 | text(size: 14pt, weight: "bold", [ |
223 | 238 | #allcaps(title) |
224 | 239 | #if funding != none { titlefootnote(funding) } |
|
244 | 259 | text(size: 12pt, { |
245 | 260 | let also_at = (); |
246 | 261 | for aff in authors.map(a => a.affiliation.at(0)).dedup() { |
247 | | - for auth in authors.filter(a => a.affiliation.at(0) == aff) { |
248 | | - // author name with superscripts |
249 | | - keep-together({ |
250 | | - auth.name |
251 | | - for aff2 in auth.affiliation.slice(1) { |
252 | | - if aff2 not in also_at { also_at += (aff2,) } |
253 | | - super(str(also_at.len())) |
254 | | - } |
255 | | - if "email" in auth { titlefootnote(auth.email) } |
256 | | - "," |
257 | | - }) |
258 | | - " " |
| 262 | + // all authors per affiliation |
| 263 | + let author_entry = { |
| 264 | + let authors_here = authors.filter(a => a.affiliation.at(0) == aff) |
| 265 | + for auth in authors_here { |
| 266 | + // author name with superscripts |
| 267 | + keep-together({ |
| 268 | + auth.name |
| 269 | + for aff2 in auth.affiliation.slice(1) { |
| 270 | + if aff2 not in also_at { also_at += (aff2,) } |
| 271 | + super(str(also_at.len())) |
| 272 | + } |
| 273 | + if "email" in auth { titlefootnote(auth.email) } |
| 274 | + }) |
| 275 | + if auth != authors_here.last() {", "} |
| 276 | + } |
259 | 277 | } |
260 | 278 | // primary affiliations |
261 | 279 | let a = affiliations.at( |
|
266 | 284 | // trim whitespaces, but allow newlines at start for manual linebreak |
267 | 285 | a = a.trim(" ").trim(at: end) |
268 | 286 | } |
269 | | - keep-together(a) + "\n" |
270 | | - }; |
| 287 | + let affiliation_entry = keep-together(a) |
| 288 | + // print author and affiliation entries on same or separate lines |
| 289 | + layout(it => { |
| 290 | + let combined_entry = author_entry + ", " + affiliation_entry |
| 291 | + if (measure(author_entry, width: it.width).height == measure(combined_entry, width: it.width).height){ |
| 292 | + combined_entry + "\n" |
| 293 | + } else { |
| 294 | + author_entry + affiliation_entry + "\n" // No comma here! |
| 295 | + } |
| 296 | + }) |
| 297 | + } |
271 | 298 | // secondary affiliations |
272 | 299 | for i in range(also_at.len()) { |
273 | 300 | let a = affiliations.at(also_at.at(i)) // sec. aff. only via key |
|
360 | 387 | ) |
361 | 388 | }) |
362 | 389 | } |
| 390 | + show "Figure": set text(hyphenate: false) |
363 | 391 |
|
364 | 392 | // tables |
365 | 393 | show figure.where( |
|
389 | 417 | }) |
390 | 418 |
|
391 | 419 | // bibliography |
392 | | - set bibliography(title: [#bibliography-title <references>], style: "jacow.csl") |
| 420 | + set bibliography(title: none, style: "jacow.csl") |
393 | 421 | show bibliography: it => { |
| 422 | + // marker to check for page limit |
| 423 | + [#block(height: 0pt, above: 0pt, below: 0pt)<content-end>] |
| 424 | + |
| 425 | + heading(bibliography-title) |
394 | 426 | set text(9pt) |
395 | 427 | set par(spacing: 9pt) |
| 428 | + show grid.cell.where(x: 0): set align(right) |
| 429 | + |
396 | 430 | //show link: it => it.body // no clickable links as per JACoW demand |
397 | 431 | show regex("\b(https?://\S+|10(\.\d+)+/\S+)"): it => { |
398 | | - let it = if it.text.starts-with("10") [doi:#it] else {it} |
| 432 | + let is-doi = it.text.starts-with("10") |
| 433 | + let it = if is-doi [doi:#it] else {it} |
399 | 434 | let link = text(font: "DejaVu Sans Mono", size: 7.2pt, hyphenate: false, it) |
400 | 435 |
|
401 | | - // Put link in same line if it fits, otherwise force a line break |
402 | | - let link-on-new-line = state("link-on-new-line", false) |
403 | | - box(width: 1fr, layout(it => { |
404 | | - let fits-in-same-line = measure(link).width < it.width |
405 | | - link-on-new-line.update(it => not fits-in-same-line) |
406 | | - if fits-in-same-line { link } |
407 | | - })) |
408 | | - context if link-on-new-line.get() { |
409 | | - linebreak() |
| 436 | + if is-doi { |
| 437 | + // Avoid breaking DOI: Put in same line if it fits, otherwise force into new line |
| 438 | + let link-on-new-line = state("link-on-new-line", false) |
| 439 | + box(width: 1fr, layout(it => { |
| 440 | + let fits-in-same-line = measure(link).width < it.width |
| 441 | + link-on-new-line.update(it => not fits-in-same-line) |
| 442 | + if fits-in-same-line { link } |
| 443 | + })) |
| 444 | + context if link-on-new-line.get() { |
| 445 | + linebreak() |
| 446 | + link |
| 447 | + } |
| 448 | + } else { |
| 449 | + // URL |
410 | 450 | link |
| 451 | + if it.text.ends-with("/") [.] |
411 | 452 | } |
| 453 | + |
412 | 454 | } |
413 | 455 | it |
414 | 456 | } |
|
0 commit comments