228 lines
5.6 KiB
Typst
228 lines
5.6 KiB
Typst
#import "@preview/hydra:0.6.1": hydra
|
|
|
|
#import "cover.typ": cover
|
|
#import "abstracts.typ": abstracts
|
|
#import "todos.typ": todos, show-todos
|
|
#import "etablissements.typ": *
|
|
|
|
#let matisse-thesis(
|
|
// English title, will be used for the document title metadata
|
|
title-en: "",
|
|
title-fr: "",
|
|
author: "",
|
|
affiliation: "",
|
|
defense-place: "",
|
|
defense-date: "",
|
|
jury-content: [],
|
|
university: "UR",
|
|
speciality: "Informatique",
|
|
// List of keyword for the abstract
|
|
keywords-en: (),
|
|
// List of french keywords for the abstract
|
|
keywords-fr: (),
|
|
abstract-en: [],
|
|
abstract-fr: [],
|
|
// If the current document is a draft
|
|
draft: true,
|
|
bibliography-style: "association-for-computing-machinery",
|
|
// text font
|
|
font: "New Computer Modern",
|
|
// font for heading
|
|
heading-font: "TeX Gyre Heros",
|
|
// text lang
|
|
lang: "en",
|
|
school-color-verso: rgb("0054a0"),
|
|
body
|
|
) = {
|
|
assert-etablissements(university)
|
|
|
|
if draft {
|
|
todos()
|
|
} else {
|
|
show-todos.update(false)
|
|
}
|
|
|
|
// ---------- GENERAL ----------
|
|
|
|
let draft-string = ""
|
|
if draft { draft-string = "DRAFT - " }
|
|
|
|
set document(
|
|
title: draft-string + title-en,
|
|
author: author,
|
|
)
|
|
set par(justify: true)
|
|
set text(font: font, fill: black, lang: lang)
|
|
|
|
// ---------- PAGE FORMAT ---------- //
|
|
|
|
set page("a4",
|
|
margin: (outside: 20mm, inside: 30mm, top: 50mm, bottom: 50mm),
|
|
numbering: "1",
|
|
number-align: center,
|
|
header: context {
|
|
// disable linebreaks in header
|
|
show linebreak: none
|
|
// get the current page number
|
|
let current-page = here().page()
|
|
|
|
let all-lvl1 = query(heading.where(level: 1))
|
|
if all-lvl1.any(it => it.location().page() == current-page) {
|
|
return
|
|
}
|
|
|
|
// if the page is odd
|
|
if calc.odd(current-page) {
|
|
// display the last level-1 heading
|
|
let header-content = hydra(1,
|
|
display: (_, it) => {
|
|
if it.numbering != none {
|
|
let nb = counter(heading).at(it.location())
|
|
let nb-fmt = numbering(it.numbering, ..nb)
|
|
[#it.supplement #nb-fmt -- _ #it.body _ ]
|
|
} else { emph(it.body) }
|
|
}
|
|
)
|
|
text(0.35cm, header-content)
|
|
}
|
|
// if the page is even
|
|
else {
|
|
// display last level-2 heading (current page included)
|
|
let header-content = hydra(2, use-last: true,
|
|
display: (_, it) => {
|
|
if it.numbering == none [_ #it.body _ ]
|
|
else {
|
|
let nb = counter(heading).at(it.location())
|
|
let nb-fmt = numbering(
|
|
it.numbering.replace(" ", "."),
|
|
..nb
|
|
)
|
|
[ _ #nb-fmt #it.body _ ]
|
|
}
|
|
}
|
|
)
|
|
align(right, text(0.35cm, header-content))
|
|
}
|
|
// horizontal rule
|
|
v(-.3cm)
|
|
line(length: 100%, stroke: .2mm)
|
|
}
|
|
)
|
|
|
|
// ---------- HEADINGS ----------
|
|
|
|
// for the thesis' body:
|
|
// 1. headings are normally numbered
|
|
// (there is a small space after the last number)
|
|
|
|
set heading(numbering: "1.1 ")
|
|
// 2. level-1 headings are called chapters
|
|
show heading.where(level: 1): set heading(supplement: [Chapter])
|
|
|
|
// for level-1 headings
|
|
show heading.where(level: 1): it => context {
|
|
// always start on odd pages
|
|
pagebreak(to: "odd")
|
|
set align(right)
|
|
v(-.8cm)
|
|
// if numbering is enabled, display level-1 heading number
|
|
if it.numbering != none {
|
|
let sec-nb = counter(heading).get().first()
|
|
let fmt-nb = numbering(heading.numbering, sec-nb)
|
|
text(
|
|
smallcaps[#heading.supplement #fmt-nb \ ],
|
|
size: .45cm, weight: "regular", font: font,
|
|
)
|
|
v(0cm)
|
|
}
|
|
// level-1 heading name
|
|
text(smallcaps(it.body), font: heading-font, size: .9cm)
|
|
set align(left)
|
|
// horizontal rule
|
|
v(.7cm)
|
|
line(length: 100%, stroke: .2mm)
|
|
v(.7cm)
|
|
}
|
|
|
|
|
|
// ---------- FIGURES ----------
|
|
|
|
show figure.caption: it => box(
|
|
inset: (left: 1em, right: 1em),
|
|
align(left, it)
|
|
)
|
|
|
|
// ---------- OUTLINES ----------
|
|
|
|
// justify outline entries
|
|
show outline.entry: set par(justify: true)
|
|
|
|
show outline: out => {
|
|
show outline.entry.where(level: 1): ent => {
|
|
// for the table of contents
|
|
if out.target == selector(heading) {
|
|
block(above: 1.2em)[#ent]
|
|
}
|
|
// for other types of outlines
|
|
else {
|
|
link(
|
|
ent.element.location(),
|
|
[#ent.prefix(): #h(.5em) #ent.inner()]
|
|
)
|
|
}
|
|
}
|
|
out
|
|
}
|
|
|
|
// disable linebreaks in outlines
|
|
show outline.entry: it => {
|
|
show linebreak: none
|
|
it
|
|
}
|
|
|
|
|
|
// ---------- FOOTNOTES ----------
|
|
|
|
show footnote.entry: it => {
|
|
let loc = it.note.location()
|
|
numbering(
|
|
"1. ",
|
|
..counter(footnote).at(loc),
|
|
)
|
|
it.note.body
|
|
}
|
|
|
|
// ---------- BIBLIOGRAPHY ----------
|
|
|
|
set bibliography(style: bibliography-style)
|
|
|
|
// ---------- COVER PAGE ----------
|
|
|
|
cover(
|
|
title-en: title-en,
|
|
title-fr: title-fr,
|
|
author: author,
|
|
affiliation: affiliation,
|
|
defense-place: defense-place,
|
|
defense-date: defense-date,
|
|
jury-content: jury-content,
|
|
university: university,
|
|
speciality: speciality,
|
|
heading-font: heading-font,
|
|
)
|
|
|
|
// ---------- BODY ----------
|
|
|
|
set par.line(numbering: n => text(red)[#n]) if draft
|
|
show figure: set par.line(numbering: none) if draft
|
|
|
|
body
|
|
|
|
// ---------- ABSTRACT ----------
|
|
abstracts(
|
|
university: university,
|
|
title-fr: title-fr, keywords-fr: keywords-fr, abstract-fr: abstract-fr,
|
|
title-en: title-en, keywords-en: keywords-en, abstract-en: abstract-en,
|
|
heading-font: heading-font, school-color-verso: school-color-verso,
|
|
)
|
|
}
|