first commit
This commit is contained in:
commit
c7730985d2
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.pdf
|
92
in-dexter.typ
Normal file
92
in-dexter.typ
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// Copyright 2023 Rolf Bremer, Jutta Klebe
|
||||||
|
// Use of this code is governed by the License in the LICENSE.txt file.
|
||||||
|
// For a 'how to use this package', see the accompanying .md, .pdf + .typ documents.
|
||||||
|
|
||||||
|
// Index Entry; used to mark an entry in the document to be included in the Index.
|
||||||
|
// An optional initial may be provided.
|
||||||
|
#let index(
|
||||||
|
content,
|
||||||
|
initial: none
|
||||||
|
) = locate(loc => [#metadata((initial: initial, content: content, location: loc.position()))<jkrb_index>])
|
||||||
|
|
||||||
|
// Create the index page.
|
||||||
|
#let make-index(title: none, outlined: false) = {
|
||||||
|
|
||||||
|
// This function combines the text(s) of a content.
|
||||||
|
let content-text(content) = {
|
||||||
|
let ct = ""
|
||||||
|
if content.has("text") {
|
||||||
|
ct = content.text
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for cc in content.children {
|
||||||
|
if cc.has("text") {
|
||||||
|
ct += cc.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ct
|
||||||
|
}
|
||||||
|
|
||||||
|
locate(loc => {
|
||||||
|
let elements = query(<jkrb_index>, loc)
|
||||||
|
let pages = (:)
|
||||||
|
let words = (:)
|
||||||
|
for el in elements {
|
||||||
|
let ct = content-text(el.value.content)
|
||||||
|
|
||||||
|
// Have we already know that entry text? If not,
|
||||||
|
// add it to our list of entry words
|
||||||
|
if pages.keys().contains(ct) != true {
|
||||||
|
pages.insert(ct, ())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new page entry to the list.
|
||||||
|
let ent = (page: el.value.location.page)
|
||||||
|
if not pages.at(ct).contains(ent){
|
||||||
|
pages.at(ct).push(ent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for el in elements {
|
||||||
|
let ct = content-text(el.value.content)
|
||||||
|
if words.keys().contains(ct) != true {
|
||||||
|
words.insert(ct, ())
|
||||||
|
words.at(ct) = (content: el.value.content, initial: el.value.initial, pages: pages.at(ct))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the entries.
|
||||||
|
let initial-sorted(ct) = {
|
||||||
|
let char = words.at(ct).initial
|
||||||
|
if char == none {
|
||||||
|
char = content-text(words.at(ct).content)
|
||||||
|
}
|
||||||
|
return char
|
||||||
|
}
|
||||||
|
let sortedkeys = words.keys().sorted(key: initial-sorted)
|
||||||
|
|
||||||
|
// Output.
|
||||||
|
let register = ""
|
||||||
|
if title != none { heading(outlined: outlined, numbering: none, title) }
|
||||||
|
for sk in sortedkeys [
|
||||||
|
// Use class specific formatting for the page numbers.
|
||||||
|
#let formattedPageNumbers = words.at(sk).pages.map(en => {
|
||||||
|
link((page: en.page, x:0pt, y:0pt))[#strong[#en.page]]
|
||||||
|
})
|
||||||
|
|
||||||
|
#let firstCharacter = content-text(words.at(sk).content).first()
|
||||||
|
#if (words.at(sk).initial != none) {
|
||||||
|
firstCharacter = words.at(sk).initial
|
||||||
|
}
|
||||||
|
|
||||||
|
#if firstCharacter != register {
|
||||||
|
heading(level: 2, numbering: none, outlined: false, firstCharacter)
|
||||||
|
register = firstCharacter
|
||||||
|
}
|
||||||
|
#words.at(sk).content
|
||||||
|
#box(width: 1fr)
|
||||||
|
#formattedPageNumbers.join(", ")
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
398
lapreprint.typ
Normal file
398
lapreprint.typ
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
#import "@preview/i-figured:0.2.3"
|
||||||
|
|
||||||
|
#let count-words(it) = {
|
||||||
|
let fn = repr(it.func())
|
||||||
|
if fn == "sequence" { it.children.map(count-words).sum() }
|
||||||
|
else if fn == "heading" { count-words(it.body) }
|
||||||
|
else if fn == "figure" { count-words(it.caption.body) }
|
||||||
|
else if fn == "text" { it.text.split().len() }
|
||||||
|
else if fn in ("styled") { count-words(it.child) }
|
||||||
|
else if fn in ("highlight", "item", "strong", "link") { count-words(it.body) }
|
||||||
|
else if fn == "equation" { 1 }
|
||||||
|
else { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#let lapreprint(
|
||||||
|
// The paper's title.
|
||||||
|
title: "Paper Title",
|
||||||
|
subtitle: none,
|
||||||
|
|
||||||
|
// An array of authors. For each author you can specify a name, orcid, and affiliations.
|
||||||
|
// affiliations should be content, e.g. "1", which is shown in superscript and should match the affiliations list.
|
||||||
|
// Everything but but the name is optional.
|
||||||
|
authors: (),
|
||||||
|
// This is the affiliations list. Include an id and `name` in each affiliation. These are shown below the authors.
|
||||||
|
affiliations: (),
|
||||||
|
// The paper's abstract. Can be omitted if you don't have one.
|
||||||
|
abstract: none,
|
||||||
|
// The short-title is shown in the running header
|
||||||
|
short-title: none,
|
||||||
|
// The short-citation is shown in the running header, if set to auto it will show the author(s) and the year in APA format.
|
||||||
|
short-citation: auto,
|
||||||
|
// The venue is show in the footer
|
||||||
|
venue: none,
|
||||||
|
// An image path that is shown in the top right of the page. Can also be content.
|
||||||
|
logo: none,
|
||||||
|
// A DOI link, shown in the header on the first page. Should be just the DOI, e.g. `10.10123/123456` ,not a URL
|
||||||
|
doi: none,
|
||||||
|
heading-numbering: "1.a.i",
|
||||||
|
// Show an Open Access badge on the first page, and support open science, default is true, because that is what the default should be.
|
||||||
|
open-access: true,
|
||||||
|
// A list of keywords to display after the abstract
|
||||||
|
keywords: (),
|
||||||
|
// The "kind" of the content, e.g. "Original Research", this is shown as the title of the margin content on the first page.
|
||||||
|
kind: none,
|
||||||
|
// Content to put on the margin of the first page
|
||||||
|
// Should be a list of dicts with `title` and `content`
|
||||||
|
margin: (),
|
||||||
|
paper-size: "us-letter",
|
||||||
|
// A color for the theme of the document
|
||||||
|
theme: blue.darken(30%),
|
||||||
|
// Date published, for example, when you publish your preprint to an archive server.
|
||||||
|
// To hide the date, set this to `none`. You can also supply a list of dicts with `title` and `date`.
|
||||||
|
date: datetime.today(),
|
||||||
|
// Feel free to change this, the font applies to the whole document
|
||||||
|
font-face: "Noto Sans",
|
||||||
|
// The path to a bibliography file if you want to cite some external works.
|
||||||
|
bibliography-file: none,
|
||||||
|
bibliography-style: "apa",
|
||||||
|
// The outline
|
||||||
|
outline-show: true,
|
||||||
|
outline-depth: 2,
|
||||||
|
// Language of the document
|
||||||
|
lang: "en",
|
||||||
|
// The paper's content.
|
||||||
|
body
|
||||||
|
) = {
|
||||||
|
|
||||||
|
/* Logos */
|
||||||
|
let orcidSvg = ```<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24"> <path fill="#AECD54" d="M21.8,12c0,5.4-4.4,9.8-9.8,9.8S2.2,17.4,2.2,12S6.6,2.2,12,2.2S21.8,6.6,21.8,12z M8.2,5.8c-0.4,0-0.8,0.3-0.8,0.8s0.3,0.8,0.8,0.8S9,7,9,6.6S8.7,5.8,8.2,5.8z M10.5,15.4h1.2v-6c0,0-0.5,0,1.8,0s3.3,1.4,3.3,3s-1.5,3-3.3,3s-1.9,0-1.9,0H10.5v1.1H9V8.3H7.7v8.2h2.9c0,0-0.3,0,3,0s4.5-2.2,4.5-4.1s-1.2-4.1-4.3-4.1s-3.2,0-3.2,0L10.5,15.4z"/></svg>```.text
|
||||||
|
|
||||||
|
let spacer = text(fill: gray)[#h(8pt) | #h(8pt)]
|
||||||
|
|
||||||
|
let dates;
|
||||||
|
if (type(date) == "datetime") {
|
||||||
|
dates = ((title: "Published", date: date),)
|
||||||
|
}else if (type(date) == "dictionary") {
|
||||||
|
dates = (date,)
|
||||||
|
} else {
|
||||||
|
dates = date
|
||||||
|
}
|
||||||
|
date = dates.at(0).date
|
||||||
|
|
||||||
|
// Create a short-citation, e.g. Cockett et al., 2023
|
||||||
|
let year = if (date != none) { ", " + date.display("[year]") }
|
||||||
|
if (short-citation == auto and authors.len() == 1) {
|
||||||
|
short-citation = authors.at(0).name.split(" ").last() + year
|
||||||
|
} else if (short-citation == auto and authors.len() == 2) {
|
||||||
|
short-citation = authors.at(0).name.split(" ").last() + " & " + authors.at(1).name.split(" ").last() + year
|
||||||
|
} else if (short-citation == auto and authors.len() > 2) {
|
||||||
|
short-citation = authors.at(0).name.split(" ").last() + " " + emph("et al.") + year
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set document metadata.
|
||||||
|
set document(title: title, author: authors.map(author => author.name))
|
||||||
|
|
||||||
|
if short-title == none { short-title = title }
|
||||||
|
set page(
|
||||||
|
paper-size,
|
||||||
|
margin: (left: 20%, bottom: 1.5cm),
|
||||||
|
header: locate(loc => {
|
||||||
|
if(loc.page() == 1) {
|
||||||
|
let headers = (
|
||||||
|
if (open-access) {smallcaps[Open Access]},
|
||||||
|
if (doi != none) { link("https://doi.org/" + doi, "https://doi.org/" + doi)}
|
||||||
|
)
|
||||||
|
return align(left, text(size: 8pt, fill: gray, headers.filter(header => header != none).join(spacer)))
|
||||||
|
} else {
|
||||||
|
return align(right, text(size: 8pt, fill: gray.darken(50%),
|
||||||
|
(short-title, short-citation).join(spacer)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
footer: block(
|
||||||
|
width: 100%,
|
||||||
|
stroke: (top: 1pt + gray),
|
||||||
|
inset: (top: 8pt, right: 2pt),
|
||||||
|
[
|
||||||
|
#grid(columns: (75%, 25%),
|
||||||
|
align(left, text(size: 9pt, fill: gray.darken(50%),
|
||||||
|
(
|
||||||
|
if(venue != none) {emph(venue)},
|
||||||
|
if(date != none) {
|
||||||
|
if (lang == "en") {
|
||||||
|
date.display("[month repr:short] [day], [year]")
|
||||||
|
} else {
|
||||||
|
[#date.year() 年 #date.month() 月 #date.day() 日]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).filter(t => t != none).join(spacer)
|
||||||
|
)),
|
||||||
|
align(right)[
|
||||||
|
#text(
|
||||||
|
size: 9pt, fill: gray.darken(50%)
|
||||||
|
)[
|
||||||
|
#counter(page).display() of #locate((loc) => {counter(page).final(loc).first()})
|
||||||
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Set the body font.
|
||||||
|
set text(font: font-face, size: 10pt)
|
||||||
|
|
||||||
|
// Configure lists.
|
||||||
|
set enum(indent: 10pt, body-indent: 9pt)
|
||||||
|
set list(indent: 10pt, body-indent: 9pt)
|
||||||
|
|
||||||
|
// Configure i-figured
|
||||||
|
show figure: i-figured.show-figure
|
||||||
|
show figure.where(
|
||||||
|
kind: table
|
||||||
|
): set figure.caption(position: top)
|
||||||
|
show math.equation: i-figured.show-equation
|
||||||
|
|
||||||
|
// Configure Reference Link
|
||||||
|
show link: it => [#text(fill: theme)[#it]]
|
||||||
|
show ref: it => [#text(fill: theme)[#it]]
|
||||||
|
show ref: it => {
|
||||||
|
let el = it.element
|
||||||
|
if (el != none) {
|
||||||
|
let fn = repr(el.func())
|
||||||
|
if (fn == "equation") {link(
|
||||||
|
it.target,
|
||||||
|
if (lang == "en") {"Eq."} else {"式 "} +
|
||||||
|
numbering(
|
||||||
|
el.numbering,
|
||||||
|
..counter(math.equation).at(el.location())
|
||||||
|
)
|
||||||
|
)} else if (fn == "heading") {link(
|
||||||
|
it.target,
|
||||||
|
if (lang == "en") {"Section "} else {"第 "} +
|
||||||
|
numbering(
|
||||||
|
el.numbering,
|
||||||
|
..counter(heading).at(el.location())
|
||||||
|
) + if (lang == "zh") {" 节"}
|
||||||
|
)}
|
||||||
|
else { it }
|
||||||
|
} else {it}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure headings.
|
||||||
|
set heading(numbering: heading-numbering)
|
||||||
|
show heading: it => locate(loc => {
|
||||||
|
// Find out the final number of the heading counter.
|
||||||
|
let levels = counter(heading).at(loc)
|
||||||
|
set text(10pt, weight: 400)
|
||||||
|
if it.level == 1 [
|
||||||
|
// First-level headings are centered smallcaps.
|
||||||
|
// We don't want to number of the acknowledgment section.
|
||||||
|
#let is-ack = it.body in ([Acknowledgment], [Acknowledgement])
|
||||||
|
// #set align(center)
|
||||||
|
#set text(if is-ack { 10pt } else { 12pt })
|
||||||
|
#show: smallcaps
|
||||||
|
#v(20pt, weak: true)
|
||||||
|
#if it.numbering != none and not is-ack {
|
||||||
|
numbering(heading-numbering, ..levels)
|
||||||
|
h(7pt, weak: true)
|
||||||
|
}
|
||||||
|
#it.body
|
||||||
|
#v(13.75pt, weak: true)
|
||||||
|
|
||||||
|
#for kind in (image, table, raw) {
|
||||||
|
counter(figure.where(kind: "i-figured-" + repr(kind))).update(0)
|
||||||
|
}
|
||||||
|
#counter(math.equation).update(0)
|
||||||
|
] else if it.level == 2 [
|
||||||
|
// Second-level headings are run-ins.
|
||||||
|
#set par(first-line-indent: 0pt)
|
||||||
|
#v(10pt, weak: true)
|
||||||
|
#if it.numbering != none {
|
||||||
|
numbering(heading-numbering, ..levels)
|
||||||
|
h(7pt, weak: true)
|
||||||
|
}
|
||||||
|
#it.body
|
||||||
|
#v(10pt, weak: true)
|
||||||
|
] else if it.level == 3 [
|
||||||
|
#set par(first-line-indent: 0pt)
|
||||||
|
#v(10pt, weak: true)
|
||||||
|
#if it.numbering != none {
|
||||||
|
numbering(heading-numbering, ..levels)
|
||||||
|
}
|
||||||
|
#it.body
|
||||||
|
#v(10pt, weak: true)
|
||||||
|
] else [
|
||||||
|
// Fourth level headings are run-ins too, but different.
|
||||||
|
#set par(first-line-indent: 0pt)
|
||||||
|
#if it.level >= 4 {
|
||||||
|
numbering(heading-numbering, ..levels)
|
||||||
|
}
|
||||||
|
#it.body
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
if (logo != none) {
|
||||||
|
place(
|
||||||
|
top,
|
||||||
|
dx: -33%,
|
||||||
|
float: false,
|
||||||
|
box(
|
||||||
|
width: 27%,
|
||||||
|
{
|
||||||
|
if (type(logo) == "content") {
|
||||||
|
logo
|
||||||
|
} else {
|
||||||
|
image(logo, width: 100%)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Title and subtitle
|
||||||
|
box(inset: (bottom: 2pt), text(17pt, weight: "bold", fill: theme, title))
|
||||||
|
if subtitle != none {
|
||||||
|
parbreak()
|
||||||
|
box(text(14pt, fill: gray.darken(30%), subtitle))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authors and affiliations
|
||||||
|
linebreak()
|
||||||
|
if authors.len() > 0 {
|
||||||
|
box(inset: (y: 10pt), {
|
||||||
|
authors.map(author => {
|
||||||
|
text(11pt, weight: "semibold", author.name)
|
||||||
|
h(1pt)
|
||||||
|
if "affiliations" in author {
|
||||||
|
super(author.affiliations)
|
||||||
|
}
|
||||||
|
if "orcid" in author {
|
||||||
|
link("https://orcid.org/" + author.orcid)[#box(height: 1.1em, baseline: 13.5%)[#image.decode(orcidSvg)]]
|
||||||
|
}
|
||||||
|
}).join(", ", last: ", and ")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if affiliations.len() > 0 {
|
||||||
|
linebreak()
|
||||||
|
box(inset: (bottom: 10pt), {
|
||||||
|
affiliations.map(affiliation => {
|
||||||
|
super(affiliation.id)
|
||||||
|
h(1pt)
|
||||||
|
affiliation.name
|
||||||
|
}).join(", ")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
place(
|
||||||
|
left + bottom,
|
||||||
|
dx: -25%,
|
||||||
|
dy: -10pt,
|
||||||
|
box(width: 22%, {
|
||||||
|
if (kind != none) {
|
||||||
|
show par: set block(spacing: 0em)
|
||||||
|
text(11pt, fill: theme, weight: "semibold", smallcaps(kind))
|
||||||
|
parbreak()
|
||||||
|
}
|
||||||
|
if (dates != none) {
|
||||||
|
let formatted-dates
|
||||||
|
|
||||||
|
grid(columns: (40%, 60%), gutter: 7pt,
|
||||||
|
..dates.zip(range(dates.len())).map((formatted-dates) => {
|
||||||
|
let d = formatted-dates.at(0);
|
||||||
|
let i = formatted-dates.at(1);
|
||||||
|
return (
|
||||||
|
if (i == 0){
|
||||||
|
strong[#text(size: 7pt, fill: theme, d.title)]
|
||||||
|
} else {
|
||||||
|
text(size: 7pt, fill: theme, d.title)
|
||||||
|
},
|
||||||
|
if (lang == "en") {
|
||||||
|
text(size: 7pt, d.date.display("[month repr:short] [day], [year]"))
|
||||||
|
} else {[
|
||||||
|
#set text(7pt)
|
||||||
|
#d.date.year()-#d.date.month()-#d.date.day()
|
||||||
|
]}
|
||||||
|
)
|
||||||
|
}).flatten()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
v(2em)
|
||||||
|
grid(columns: 1, gutter: 2em, ..margin.map(side => {
|
||||||
|
text(size: 7pt, {
|
||||||
|
if ("title" in side) {
|
||||||
|
text(fill: theme, weight: "bold", side.title)
|
||||||
|
[\ ]
|
||||||
|
}
|
||||||
|
set enum(indent: 0.1em, body-indent: 0.25em)
|
||||||
|
set list(indent: 0.1em, body-indent: 0.25em)
|
||||||
|
side.content
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
let abstracts
|
||||||
|
if (type(abstract) == "content") {
|
||||||
|
abstracts = (title: "Abstract", content: abstract)
|
||||||
|
} else {
|
||||||
|
abstracts = abstract
|
||||||
|
}
|
||||||
|
if abstracts != none {
|
||||||
|
box(inset: (top: 16pt, bottom: 16pt), stroke: (top: 1pt + gray, bottom: 1pt + gray), {
|
||||||
|
abstracts.map(abs => {
|
||||||
|
set par(justify: true)
|
||||||
|
text(fill: theme, weight: "semibold", size: 9pt, abs.title)
|
||||||
|
parbreak()
|
||||||
|
abs.content
|
||||||
|
}).join(parbreak())
|
||||||
|
})
|
||||||
|
if (keywords.len() > 0) {
|
||||||
|
text(size: 9pt, {
|
||||||
|
if (lang == "en") {
|
||||||
|
text(fill: theme, weight: "semibold", "Keywords")
|
||||||
|
} else {
|
||||||
|
text(fill: theme, weight: "semibold", "关键词")
|
||||||
|
}
|
||||||
|
h(8pt)
|
||||||
|
keywords.join(", ")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
v(10pt)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outline-show) {outline(
|
||||||
|
title: if (lang == "en") {"Content"} else {"目录"},
|
||||||
|
indent: 2em,
|
||||||
|
depth: outline-depth,
|
||||||
|
)}
|
||||||
|
|
||||||
|
pagebreak()
|
||||||
|
|
||||||
|
// Display the paper's contents.
|
||||||
|
show par: set block(spacing: 1.5em)
|
||||||
|
set page(
|
||||||
|
margin: (left: auto, bottom: 1.5cm),
|
||||||
|
)
|
||||||
|
|
||||||
|
// show: rest => {
|
||||||
|
// let n = count-words(rest)
|
||||||
|
// if (lang == "en") {
|
||||||
|
// rest + align(right, [(#n words)])
|
||||||
|
// } else {
|
||||||
|
// rest + align(right, [(#n 字)])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
body
|
||||||
|
|
||||||
|
if (bibliography-file != none) {
|
||||||
|
show bibliography: set text(8pt)
|
||||||
|
bibliography(bibliography-file, title: text(10pt, "References"), style: bibliography-style)
|
||||||
|
}
|
||||||
|
}
|
5
lib.typ
Normal file
5
lib.typ
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#import "utils.typ": *
|
||||||
|
#import "table.typ": *
|
||||||
|
#import "in-dexter.typ": index, make-index
|
||||||
|
#import "lapreprint.typ": lapreprint
|
||||||
|
#import "slides.typ": slides-theme, slide, matrix-slide, title-slide, slide-outline, slide-outline-length
|
200
slides.typ
Normal file
200
slides.typ
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
#import "@preview/polylux:0.3.1": *
|
||||||
|
#import themes.university as uni
|
||||||
|
|
||||||
|
#let count-length(it) = {
|
||||||
|
let fn = repr(it.func())
|
||||||
|
if fn == "sequence" { it.children.map(count-length).sum() }
|
||||||
|
else if fn == "heading" { count-length(it.body) }
|
||||||
|
else if fn == "figure" { count-length(it.caption.body) }
|
||||||
|
else if fn == "text" { it.text.len() }
|
||||||
|
else if fn in ("styled") { count-length(it.child) }
|
||||||
|
else if fn in ("highlight", "item", "strong", "link") { count-length(it.body) }
|
||||||
|
else if fn == "equation" { count-length(it.body) }
|
||||||
|
else { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#let progress-barline = locate( loc => {
|
||||||
|
if uni.uni-progress-bar.at(loc) {
|
||||||
|
let cell = block.with( width: 100%, height: 100%, above: 0pt, below: 0pt, breakable: false )
|
||||||
|
let colors = uni.uni-colors.at(loc)
|
||||||
|
|
||||||
|
utils.polylux-progress( ratio => {
|
||||||
|
grid(
|
||||||
|
rows: 2pt, columns: (ratio * 100%, 1fr),
|
||||||
|
cell(fill: colors.a),
|
||||||
|
cell(fill: colors.b)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
} else { [] }
|
||||||
|
})
|
||||||
|
|
||||||
|
#let header-text(
|
||||||
|
title: none,
|
||||||
|
new-section: none
|
||||||
|
) = {
|
||||||
|
if title != none {
|
||||||
|
if new-section != none {
|
||||||
|
utils.register-section(new-section)
|
||||||
|
}
|
||||||
|
|
||||||
|
locate( loc => {
|
||||||
|
let colors = uni.uni-colors.at(loc)
|
||||||
|
block(fill: colors.c, inset: (x: .5em), grid(
|
||||||
|
columns: (1fr, auto),
|
||||||
|
align(top + left, heading(level: 2, text(fill: colors.a, title))),
|
||||||
|
align(top + right, text(fill: colors.a.lighten(65%), utils.current-section))
|
||||||
|
))
|
||||||
|
})
|
||||||
|
} else { [] }
|
||||||
|
}
|
||||||
|
|
||||||
|
#let slides-theme(
|
||||||
|
aspect-ratio: "16-9",
|
||||||
|
short-title: none,
|
||||||
|
short-author: none,
|
||||||
|
short-date: none,
|
||||||
|
color-a: rgb("#0C6291"),
|
||||||
|
color-b: rgb("#A63446"),
|
||||||
|
color-c: rgb("#FBFEF9"),
|
||||||
|
progress-bar: true,
|
||||||
|
body
|
||||||
|
) = {
|
||||||
|
uni.university-theme(
|
||||||
|
aspect-ratio: aspect-ratio,
|
||||||
|
short-title: short-title,
|
||||||
|
short-author: short-author,
|
||||||
|
short-date: short-date,
|
||||||
|
color-a: color-a,
|
||||||
|
color-b: color-b,
|
||||||
|
color-c: color-c,
|
||||||
|
progress-bar: progress-bar,
|
||||||
|
body
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let title-slide(
|
||||||
|
title: [],
|
||||||
|
subtitle: none,
|
||||||
|
authors: (),
|
||||||
|
institution-name: "University",
|
||||||
|
date: none,
|
||||||
|
) = {
|
||||||
|
let authors = if type(authors) == "array" { authors }else { (authors,) }
|
||||||
|
|
||||||
|
let content = locate( loc => {
|
||||||
|
let colors = uni.uni-colors.at(loc)
|
||||||
|
|
||||||
|
align(center + horizon, {
|
||||||
|
block(
|
||||||
|
inset: 0em,
|
||||||
|
breakable: false,
|
||||||
|
{
|
||||||
|
text(size: 1.8em, fill: colors.a, strong(title))
|
||||||
|
if subtitle != none {
|
||||||
|
parbreak()
|
||||||
|
text(size: 1.2em, fill: colors.a, subtitle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
set text(size: .8em)
|
||||||
|
grid(
|
||||||
|
columns: (1fr,) * calc.min(authors.len(), 3),
|
||||||
|
column-gutter: 1em,
|
||||||
|
row-gutter: 1em,
|
||||||
|
..authors.map(author => text(fill: black, author))
|
||||||
|
)
|
||||||
|
v(1em)
|
||||||
|
if institution-name != none {
|
||||||
|
parbreak()
|
||||||
|
text(size: .9em, institution-name)
|
||||||
|
}
|
||||||
|
if date != none {
|
||||||
|
parbreak()
|
||||||
|
text(size: .8em, date)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
logic.polylux-slide(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let slide(
|
||||||
|
title: none,
|
||||||
|
new-section: none,
|
||||||
|
body
|
||||||
|
) = {
|
||||||
|
uni.slide(title: title, header: header-text(title: title, new-section: new-section), footer: none, new-section: new-section, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let matrix-slide(
|
||||||
|
title: none,
|
||||||
|
new-section: none,
|
||||||
|
columns: none,
|
||||||
|
rows: none,
|
||||||
|
..bodies
|
||||||
|
) = {
|
||||||
|
let header = {
|
||||||
|
set align(top)
|
||||||
|
grid(rows: (auto, auto), row-gutter: 3mm, progress-barline, header-text(title: title, new-section: new-section))
|
||||||
|
}
|
||||||
|
|
||||||
|
let footer = {
|
||||||
|
set text(size: 10pt)
|
||||||
|
set align(center + bottom)
|
||||||
|
let cell(fill: none, it) = rect(
|
||||||
|
width: 100%, height: 100%, inset: 1mm, outset: 0mm, fill: fill, stroke: none,
|
||||||
|
align(horizon, text(fill: white, it))
|
||||||
|
)
|
||||||
|
locate( loc => {
|
||||||
|
let colors = uni.uni-colors.at(loc)
|
||||||
|
|
||||||
|
show: block.with(width: 100%, height: auto, fill: colors.b)
|
||||||
|
grid(
|
||||||
|
columns: (25%, 1fr, 15%, 10%),
|
||||||
|
rows: (1.5em, auto),
|
||||||
|
cell(fill: colors.a, uni.uni-short-author.display()),
|
||||||
|
cell(uni.uni-short-title.display()),
|
||||||
|
cell(uni.uni-short-date.display()),
|
||||||
|
cell(logic.logical-slide.display() + [~/~] + utils.last-slide-number)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
set page(
|
||||||
|
margin: ( top: 2em, bottom: 1em, x: 0em ),
|
||||||
|
header: header,
|
||||||
|
footer: footer,
|
||||||
|
footer-descent: 0em,
|
||||||
|
header-ascent: .6em,
|
||||||
|
)
|
||||||
|
|
||||||
|
uni.matrix-slide(..bodies)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let slide-outline-length(loc) = {
|
||||||
|
let section-state = state("polylux-sections", ())
|
||||||
|
let sections = section-state.final(loc)
|
||||||
|
sections.len() - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#let slide-outline(num) = {
|
||||||
|
set text(font: "Cascadia Mono")
|
||||||
|
locate(loc => {
|
||||||
|
let section-state = state("polylux-sections", ())
|
||||||
|
let sections = section-state.final(loc)
|
||||||
|
for p in range(0, num) {
|
||||||
|
let section = sections.at(p)
|
||||||
|
let content = {
|
||||||
|
let url = link(section.loc, section.body)
|
||||||
|
let page = logic.logical-slide.at(section.loc).at(0)
|
||||||
|
let length = 46 - str(page).len() - count-length(section.body)
|
||||||
|
let dots = " " + "." * length
|
||||||
|
[#grid(
|
||||||
|
columns: (auto, 1fr, 1fr),
|
||||||
|
url, align[#dots], align(right)[#page]
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
[+ #content ]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
19
table.typ
Normal file
19
table.typ
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#import "@preview/tablex:0.0.6": tablex, rowspanx, colspanx, hlinex, vlinex
|
||||||
|
|
||||||
|
#let three-line-table(columns, headers, contents, caption, lang: "en",rows: auto) = {figure(
|
||||||
|
tablex(
|
||||||
|
columns: columns,
|
||||||
|
rows: rows,
|
||||||
|
align: center + horizon,
|
||||||
|
auto-lines: false,
|
||||||
|
repeat-header: true,
|
||||||
|
hlinex(stroke: 1.5pt),
|
||||||
|
..headers,
|
||||||
|
hlinex(stroke: 0.75pt),
|
||||||
|
..contents,
|
||||||
|
hlinex(stroke: 1.5pt),
|
||||||
|
),
|
||||||
|
kind: table,
|
||||||
|
supplement: [#if (lang == "en") {"Table"} else {"表"}],
|
||||||
|
caption: caption,
|
||||||
|
)}
|
4
typst.toml
Normal file
4
typst.toml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[package]
|
||||||
|
name = "custom"
|
||||||
|
version = "0.1.0"
|
||||||
|
entrypoint = "lib.typ"
|
85
utils.typ
Normal file
85
utils.typ
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#import "@preview/showybox:2.0.1": showybox
|
||||||
|
#import "@preview/physica:0.9.0" as ph
|
||||||
|
#import "@preview/pinit:0.1.2": *
|
||||||
|
|
||||||
|
#let sp = [#h(0.5em)]
|
||||||
|
#let pm = [#sym.plus.minus]
|
||||||
|
#let le = [#sym.lt.eq.slant]
|
||||||
|
#let ge = [#sym.gt.eq.slant]
|
||||||
|
#let sim = [#sym.tilde.op]
|
||||||
|
#let inf = [#sym.infinity]
|
||||||
|
#let rm(body) = {math.upright(body)}
|
||||||
|
#let iso(b, A) = [#ph.isotope(b, a: A)]
|
||||||
|
#let isoz(b, A, Z) = [#ph.isotope(b, a: A, z: Z)]
|
||||||
|
#let isobox(body, width: 25pt, fill: white) = {block(
|
||||||
|
fill: fill,
|
||||||
|
stroke: black,
|
||||||
|
width: width,
|
||||||
|
height: width,
|
||||||
|
align(center + horizon)[#body]
|
||||||
|
)}
|
||||||
|
|
||||||
|
#let box-quote(body, width: 100%, inset: 5pt, outset: 0pt) = {block(
|
||||||
|
fill: green.lighten(80%),
|
||||||
|
width: width,
|
||||||
|
inset: inset,
|
||||||
|
outset: outset,
|
||||||
|
radius: 4pt,
|
||||||
|
stroke: green.darken(60%),
|
||||||
|
breakable: true,
|
||||||
|
body
|
||||||
|
)}
|
||||||
|
|
||||||
|
#let box-confusion(body, width: 100%, inset: 8pt, outset: 0pt) = {block(
|
||||||
|
fill: red.lighten(80%),
|
||||||
|
width: width,
|
||||||
|
inset: inset,
|
||||||
|
outset: outset,
|
||||||
|
radius: 4pt,
|
||||||
|
stroke: red.darken(60%),
|
||||||
|
breakable: false,
|
||||||
|
body
|
||||||
|
)}
|
||||||
|
|
||||||
|
#let box-title(content, title: none) = {showybox(
|
||||||
|
title: title,
|
||||||
|
frame: (
|
||||||
|
title-color: red.darken(30%),
|
||||||
|
border-color: red.darken(30%),
|
||||||
|
body-color: red.lighten(90%),
|
||||||
|
radius: 0pt,
|
||||||
|
thickness: 2pt,
|
||||||
|
),
|
||||||
|
above: 0.5em,
|
||||||
|
below: 0.5em,
|
||||||
|
breakable: false,
|
||||||
|
content
|
||||||
|
)}
|
||||||
|
|
||||||
|
#let mark-quote(body) = {
|
||||||
|
rect(fill: luma(240), stroke: (left: 0.25em), inset: (left: 0.5em), body)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let pinit-highlight-equation-from(height: 2em, extended-height: 1.4em, pos: bottom, fill: rgb(0, 180, 255), highlight-pins, point-pin, body) = {
|
||||||
|
pinit-highlight(..highlight-pins, dy: -extended-height / 2, extended-height: extended-height, fill: rgb(..fill.components().slice(0, -1), 40))
|
||||||
|
pinit-point-from(
|
||||||
|
fill: fill,
|
||||||
|
pin-dx: -0.6em,
|
||||||
|
pin-dy: if pos == bottom { 0.8em } else { -0.6em },
|
||||||
|
body-dx: 0pt,
|
||||||
|
body-dy: if pos == bottom { -0.05em } else { -1.4em },
|
||||||
|
offset-dx: -0.6em,
|
||||||
|
offset-dy: if pos == bottom { 0.8em + height } else { -0.6em - height },
|
||||||
|
point-pin,
|
||||||
|
rect(
|
||||||
|
inset: if pos == bottom { 0.4em } else { 0.4em },
|
||||||
|
stroke: (
|
||||||
|
bottom: if pos == bottom { 0em } else { 0.12em } + fill,
|
||||||
|
top: if pos == bottom { 0.12em } else { 0em } + fill
|
||||||
|
), {
|
||||||
|
set text(fill: fill)
|
||||||
|
body
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user