first draft
This commit is contained in:
		
						commit
						f1abfbfa5b
					
				
					 15 changed files with 2893 additions and 0 deletions
				
			
		
							
								
								
									
										85
									
								
								lib/abstracts.typ
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								lib/abstracts.typ
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,85 @@
 | 
			
		|||
 | 
			
		||||
#let assets-folder = "../assets/"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// workaround for: https://github.com/typst/typst/issues/466
 | 
			
		||||
#let balanced-cols(n-cols, gutter: 11pt, body) = layout(bounds => context {
 | 
			
		||||
  // Measure the height of the container of the text if it was single
 | 
			
		||||
  // column, full width
 | 
			
		||||
  let text-height = measure(box(
 | 
			
		||||
    width: (bounds.width - (n-cols - 1) *  gutter) / n-cols,
 | 
			
		||||
    body
 | 
			
		||||
  )).height
 | 
			
		||||
 | 
			
		||||
  // Recompute the height of the new container. Add a few points to avoid the
 | 
			
		||||
  // second column being longer than the first one
 | 
			
		||||
  let balanced-height = text-height/n-cols + text.size/2
 | 
			
		||||
 | 
			
		||||
  box(
 | 
			
		||||
    height: balanced-height,
 | 
			
		||||
    columns(n-cols, gutter: gutter, body)
 | 
			
		||||
  )
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
#let abstracts(
 | 
			
		||||
  title-fr: "",
 | 
			
		||||
  keywords-fr: (),
 | 
			
		||||
  abstract-fr: [],
 | 
			
		||||
  title-en: "",
 | 
			
		||||
  keywords-en: (),
 | 
			
		||||
  abstract-en: [],
 | 
			
		||||
  heading-font: "TeX Gyre Heros",
 | 
			
		||||
  school-color-verso: rgb("0054a0")
 | 
			
		||||
) = {
 | 
			
		||||
  set page(
 | 
			
		||||
    numbering: none,
 | 
			
		||||
    header: none,
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  pagebreak()
 | 
			
		||||
  pagebreak(to: "even")
 | 
			
		||||
 | 
			
		||||
  set page(
 | 
			
		||||
    margin: (
 | 
			
		||||
      left: 20mm, right: 30mm,
 | 
			
		||||
      top: 30mm, bottom: 30mm,
 | 
			
		||||
    ),
 | 
			
		||||
    background: image(assets-folder + "abstracts-bg.svg")
 | 
			
		||||
  )
 | 
			
		||||
  set text(font: heading-font, fill: black)
 | 
			
		||||
 | 
			
		||||
  place(dx: 100mm, dy: -15mm, image(assets-folder + "UR.png", width: 6cm))
 | 
			
		||||
  place(dx: 0mm, dy: -15mm, image(assets-folder + "logo.png", width: 7.5cm))
 | 
			
		||||
 | 
			
		||||
  v(2cm)
 | 
			
		||||
  line(length: 100%, stroke: .2cm + school-color-verso)
 | 
			
		||||
  v(.4cm)
 | 
			
		||||
 | 
			
		||||
  [
 | 
			
		||||
    #show linebreak: none
 | 
			
		||||
    #text(school-color-verso)[Titre :] #title-fr
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
  [
 | 
			
		||||
 | 
			
		||||
    Mots clés : #keywords-fr.join(", ")
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
  balanced-cols(2,gutter: 11pt)[Résumé : #abstract-fr]
 | 
			
		||||
 | 
			
		||||
  v(1cm)
 | 
			
		||||
  line(length: 100%, stroke: .2cm + school-color-verso)
 | 
			
		||||
  v(.4cm)
 | 
			
		||||
 | 
			
		||||
  [
 | 
			
		||||
    #show linebreak: none
 | 
			
		||||
    #text(school-color-verso)[Title :] #title-en
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
  [
 | 
			
		||||
 | 
			
		||||
    Keywords: #keywords-en.join(", ")
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
  balanced-cols(2, gutter: 11pt)[Abstract: #abstract-en]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										85
									
								
								lib/cover.typ
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								lib/cover.typ
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,85 @@
 | 
			
		|||
 | 
			
		||||
#let assets-folder = "../assets/"
 | 
			
		||||
 | 
			
		||||
#let cover(
 | 
			
		||||
  title-en: "",
 | 
			
		||||
  title-fr: "",
 | 
			
		||||
  author: "",
 | 
			
		||||
  affiliation: "",
 | 
			
		||||
  defense-place: "",
 | 
			
		||||
  defense-date: "",
 | 
			
		||||
  jury-content: [],
 | 
			
		||||
  university: [],
 | 
			
		||||
  speciality: "Informatique",
 | 
			
		||||
  heading-font: "TeX Gyre Heros",
 | 
			
		||||
) = {
 | 
			
		||||
  set page(
 | 
			
		||||
    margin: (left: 20mm, right: 20mm, top: 30mm, bottom: 30mm),
 | 
			
		||||
    header: none,
 | 
			
		||||
    numbering: none,
 | 
			
		||||
    background: image(assets-folder + "cover-bg.svg")
 | 
			
		||||
  )
 | 
			
		||||
  set text(font: heading-font, fill: black)
 | 
			
		||||
 | 
			
		||||
  place(dx: 110mm, dy: -15mm, image(assets-folder + "UR.png", width: 6cm))
 | 
			
		||||
  place(dx: 0mm, dy: -15mm, image(assets-folder + "logo.png", width: 7.5cm))
 | 
			
		||||
 | 
			
		||||
  v(2.1cm)
 | 
			
		||||
  text(size: 2em, smallcaps[Thèse de doctorat de])
 | 
			
		||||
  v(2.25cm)
 | 
			
		||||
 | 
			
		||||
  set text(fill: white)
 | 
			
		||||
  text(size: 1.5em, smallcaps[l'Université de Rennes])
 | 
			
		||||
  v(.01cm)
 | 
			
		||||
  text(size: 1.2em)[
 | 
			
		||||
    #smallcaps[École Doctorale N° 601] \
 | 
			
		||||
    _Mathématiques, Télécommunications, Informatique, \
 | 
			
		||||
    Signal, Systèmes, Électronique_ \
 | 
			
		||||
    Spécialité : _ #speciality _ \
 | 
			
		||||
    #v(.1cm) #h(.6cm) Par \
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
  // Add a blue background with the width of the page
 | 
			
		||||
  context {
 | 
			
		||||
    let y-start = locate(<cover:title-en>).position().y - 1cm
 | 
			
		||||
    let y-end = locate(<cover:defense-info>).position().y + measure(query(<cover:defense-info>).first()).height + .5cm
 | 
			
		||||
    let height = 5em
 | 
			
		||||
 | 
			
		||||
    place(
 | 
			
		||||
      top + left, float: false,
 | 
			
		||||
      dy: y-start - page.margin.top,
 | 
			
		||||
      dx: -page.margin.left,
 | 
			
		||||
      block(
 | 
			
		||||
        width: page.width,
 | 
			
		||||
        height: y-end - y-start,
 | 
			
		||||
        fill: blue
 | 
			
		||||
      )
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Author name
 | 
			
		||||
  v(0em)
 | 
			
		||||
  h(.6cm)
 | 
			
		||||
  text(size: 1.9em)[*#author* \ ]
 | 
			
		||||
  v(.1cm)
 | 
			
		||||
 | 
			
		||||
  // Title + defense info block
 | 
			
		||||
  text(size: 1.6em)[*#title-en* <cover:title-en>]
 | 
			
		||||
  parbreak()
 | 
			
		||||
  text(size: 1.4em, title-fr)
 | 
			
		||||
  parbreak()
 | 
			
		||||
 | 
			
		||||
  text(size: 1.1em)[
 | 
			
		||||
    *Thèse présentée et soutenue à #defense-place, le #defense-date* \
 | 
			
		||||
    *Unité de recherche : #affiliation*
 | 
			
		||||
    <cover:defense-info>
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
  v(1em)
 | 
			
		||||
 | 
			
		||||
  set text(fill: black)
 | 
			
		||||
  jury-content
 | 
			
		||||
 | 
			
		||||
  pagebreak()
 | 
			
		||||
  set page(background: none)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								lib/lib.typ
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								lib/lib.typ
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
#import "matisse-thesis.typ": *
 | 
			
		||||
#import "todos.typ": *
 | 
			
		||||
							
								
								
									
										214
									
								
								lib/matisse-thesis.typ
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								lib/matisse-thesis.typ
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,214 @@
 | 
			
		|||
#import "@preview/hydra:0.6.1": hydra
 | 
			
		||||
 | 
			
		||||
#import "cover.typ": cover
 | 
			
		||||
#import "abstracts.typ": abstracts
 | 
			
		||||
 | 
			
		||||
#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: [l'Université de Rennes],
 | 
			
		||||
  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
 | 
			
		||||
) = {
 | 
			
		||||
 | 
			
		||||
  // ---------- 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 ----------
 | 
			
		||||
  body
 | 
			
		||||
 | 
			
		||||
  // ---------- ABSTRACT ----------
 | 
			
		||||
  abstracts(
 | 
			
		||||
    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,
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								lib/todos.typ
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								lib/todos.typ
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
#let todo-list = state("todo-list",())
 | 
			
		||||
#let show-todos = state("show-todos", true)
 | 
			
		||||
 | 
			
		||||
#let todo(done: false, content) = context {
 | 
			
		||||
  if (not done) and (show-todos.get()) {
 | 
			
		||||
    let todonum = todo-list.get().len() + 1
 | 
			
		||||
    text(weight: "bold", fill: red, [TODO n°#todonum #label("todo-"+str(todonum)): #content])
 | 
			
		||||
    todo-list.update(x => x + (("todo-"+str(x.len()+1),x.len()+1, content),))
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#let todos() = context {
 | 
			
		||||
  if (todo-list.final().len() != 0) and (show-todos.get()) {
 | 
			
		||||
    pagebreak(weak: true)
 | 
			
		||||
    [= TO-DOs]
 | 
			
		||||
    for t in todo-list.final() {
 | 
			
		||||
      let l =  label(t.first())
 | 
			
		||||
      list.item(link(l)[TODO n°#t.at(1) p.#locate(l).page() : #t.last()])
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue