Skip to content

Commit eb35fb2

Browse files
authored
bookly:4.1.0 (#5229)
1 parent d6005ca commit eb35fb2

51 files changed

Lines changed: 3922 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Mathieu Aucejo
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Book template
2+
3+
[![Generic badge](https://img.shields.io/badge/Version-4.1.0-cornflowerblue.svg)](https://github.com/maucejo/bookly/releases/tag/4.1.0)
4+
[![MIT License](https://img.shields.io/badge/License-MIT-forestgreen)](https://github.com/maucejo/book_template/blob/86195a989b4336f4a648c572d2a574de1d1ca6d2/LICENSE)
5+
[![User Manual](https://img.shields.io/badge/doc-.pdf-mediumpurple)](https://github.com/maucejo/bookly/blob/86195a989b4336f4a648c572d2a574de1d1ca6d2/docs/manual.pdf)
6+
7+
8+
The `bookly` template is a Typst package designed for writing academic documents such as theses, French habilitations, or scientific books. It provides a structured format that adheres to academic standards, making it easier for authors to focus on content rather than formatting.
9+
10+
## Basic usage
11+
12+
This section provides the minimal amount of information to get started with the template. For more detailed information, see the [manual](https://github.com/maucejo/bookly/blob/86195a989b4336f4a648c572d2a574de1d1ca6d2/docs/manual.pdf).
13+
14+
To use the `bookly` template, you need to include the following line at the beginning of your typ file:
15+
16+
```typ
17+
#import "@preview/bookly:4.1.0": *
18+
```
19+
20+
After importing `bookly`, you have to initialize the template by a show rule with the `#bookly()` command.
21+
22+
**Example**
23+
```typ
24+
#show: bookly.with(
25+
title: "My document",
26+
author: "Author Name",
27+
theme: modern,
28+
lang: "en",
29+
tufte: false,
30+
fonts: (
31+
body: "Lato",
32+
math: "Lete Sans Math"
33+
),
34+
title-page: book-title-page(
35+
series: "Typst book series",
36+
institution: "Typst community",
37+
logo: image("images/typst-logo.svg"),
38+
cover: image("images/book-cover.jpg", width: 45%)
39+
),
40+
config-options: (
41+
open-right: true,
42+
alt-margins: false
43+
)
44+
)
45+
```
46+
47+
## Main features
48+
49+
* Themes: `classic`, `modern`, `fancy`, `obook`, `orly`, `pretty`
50+
* Tufte layout powered by `marginalia` package
51+
* Language support: English, Chinese, French, German, Italian, Portuguese, Spanish
52+
* Font customization: Body, math and raw fonts can be customized
53+
* Environments: `front-matter`, `main-matter`, `appendix`, `back-matter`
54+
* Outlines: `tableofcontents`, `listoffigures`, `listoftables`, `minitoc`
55+
* Part and chapter definition: `part`, `chapter`, `chapter-nonum`
56+
57+
> **_Note:_** The chapters can be also written using the Typst standard markup syntax.
58+
59+
## Helper functions
60+
61+
* Subfigures - based on the `subpar` package
62+
```typ
63+
#subfigure(
64+
figure(image("image1.png"), caption: []),
65+
figure(image("image2.png"), caption: []), <b>,
66+
columns: (1fr, 1fr),
67+
caption: [Figure title],
68+
label: <fig:subfig>,
69+
)
70+
```
71+
72+
* Equations
73+
* Boxed equations
74+
```typ
75+
$
76+
#boxeq[$p(A|B) prop p(B|A) space p(A)$]
77+
$
78+
```
79+
80+
* Unnumbered equations
81+
```typ
82+
$
83+
integral_0^1 f(x) dif x = F(1) - F(0)
84+
$ <nonum-eq>
85+
```
86+
87+
* Subequation numbering based on the `equate` package
88+
89+
* Information boxes
90+
* `#info-box` for remarks
91+
* `#tip-box` for tips
92+
* `#important-box` for important notes
93+
* `proof-box` for proofs
94+
* `question-box` for questions
95+
* `custom-box` for user defined boxes
96+
97+
* `book-title-page` for defining the title page of a book
98+
99+
* `thesis-title-page` for defining the title page of a thesis
100+
101+
* `back-cover` for defining the back cover of a book
102+
103+
## Dependencies
104+
105+
`bookly` relies on the following packages:
106+
107+
* `marginalia:0.3.1`: for tufte layout.
108+
109+
* `hydra:0.6.2` : for bibliography management.
110+
111+
* `equate:0.3.3` : for advanced equation numbering.
112+
113+
* `showybox:2.0.4` : for custom boxes.
114+
115+
* `suboutline:0.3.0` : for mini tables of contents in chapters.
116+
117+
* `subpar:0.2.2` : for subfigures.
118+
119+
## Licence
120+
121+
MIT licensed
122+
123+
Copyright © 2026 Mathieu AUCEJO (maucejo)
124+
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#import "bookly-deps.typ": *
2+
#import "bookly-defaults.typ": *
3+
#import "bookly-helper.typ": *
4+
#import "bookly-themes.typ": *
5+
6+
// Chapter
7+
#let chapter(title: none, abstract: none, toc: true, numbered: true, label: none, body) = context {
8+
// Is the chapter numbered?
9+
if not numbered {
10+
numbering-heading = none
11+
numbering-eq = "(1a)"
12+
numbering-fig = "1"
13+
14+
// Heading numbering
15+
set heading(numbering: numbering-heading)
16+
17+
// Equation numbering
18+
set math.equation(numbering: numbering-eq)
19+
20+
// Figure numbering
21+
show figure.where(kind: image): set figure(
22+
supplement: fig-supplement,
23+
numbering: numbering-fig,
24+
gap: 1.5em
25+
)
26+
27+
// Table numbering
28+
show figure.where(kind: table): set figure(
29+
numbering: numbering-fig,
30+
gap: 1.5em
31+
)
32+
}
33+
34+
let toc-header = states.localization.get().toc
35+
if toc {
36+
set page(header: anchor())
37+
set align(horizon)
38+
[#heading(title)#label]
39+
40+
if abstract != none {
41+
abstract
42+
}
43+
44+
minitoc
45+
pagebreak()
46+
} else {
47+
[#heading(title)#label]
48+
}
49+
50+
body
51+
}
52+
}
53+
54+
#let chapter-nonum(body) = {
55+
let numbering-heading = none
56+
let numbering-eq = "(1a)"
57+
let numbering-fig = "1"
58+
59+
// Figure numbering
60+
show figure.where(kind: image): set figure(
61+
supplement: fig-supplement,
62+
numbering: numbering-fig,
63+
gap: 1.5em
64+
)
65+
66+
// Table numbering
67+
show figure.where(kind: table): set figure(
68+
numbering: numbering-fig,
69+
gap: 1.5em
70+
)
71+
72+
// Heading numbering
73+
set heading(numbering: numbering-heading)
74+
75+
// Equation numbering
76+
set math.equation(numbering: numbering-eq)
77+
78+
// Figure numbering
79+
show figure.where(kind: image): set figure(
80+
supplement: fig-supplement,
81+
numbering: numbering-fig,
82+
gap: 1.5em
83+
)
84+
85+
// Table numbering
86+
show figure.where(kind: table): set figure(
87+
numbering: numbering-fig,
88+
gap: 1.5em
89+
)
90+
91+
body
92+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#let fig-supplement = [Figure]
2+
#let par-indent = 1.5em
3+
4+
#let states = (
5+
alt-margins: state("alt-margins", false),
6+
author: state("author", none),
7+
colors: state("theme-colors"),
8+
counter-part: counter("part"),
9+
in-outline: state("in-outline", false),
10+
isappendix: state("isappendix", false),
11+
isfrontmatter: state("isfrontmatter", false),
12+
localization: state("localization"),
13+
num-heading: state("num-heading", "1"),
14+
num-pattern: state("num-pattern", "1.1."),
15+
num-pattern-eq: state("num-pattern-eq", "(1.1)"),
16+
num-pattern-fig: state("num-pattern-fig", "1.1"),
17+
num-pattern-subfig: state("num-pattern-subfig", "1.1a"),
18+
open-right: state("open-right", true),
19+
page-numbering: state("page-numbering", "1/1"),
20+
paper-size: state("paper-size", "a4"),
21+
par-indent: state("par-indent", false),
22+
part-numbering: state("part-numbering", "1"),
23+
sidenotecounter: counter("sidenotecounter"),
24+
theme: state("theme"),
25+
title: state("title", none),
26+
tufte: state("tufte", false),
27+
)
28+
29+
#let default-language = ("en", "de", "fr", "es", "it", "pt", "zh")
30+
31+
#let default-config-options = (
32+
part-numbering: "1",
33+
open-right: true,
34+
alt-margins: false,
35+
par-indent: false,
36+
paper-size: "a4",
37+
)
38+
39+
#let default-fonts = (
40+
size: 11pt,
41+
body: "New Computer Modern",
42+
math: "New Computer Modern Math",
43+
raw: "DejaVu Sans Mono",
44+
)
45+
46+
#let default-colors = (
47+
primary: rgb("#c1002a"),
48+
secondary: rgb("#dddddd").darken(15%),
49+
boxeq: rgb("#dddddd"),
50+
header: black,
51+
)
52+
53+
// Default Title page
54+
#let default-title-page = context {
55+
set page(
56+
paper: paper-size,
57+
header: none,
58+
footer: none,
59+
margin: auto
60+
)
61+
62+
align(center + horizon)[
63+
#text(size: 3em, fill: states.colors.get().primary)[*#states.title.get()*]
64+
#v(1em)
65+
#text(size: 1.5em)[#states.author.get()]
66+
]
67+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#import "@preview/equate:0.3.3": *
2+
#import "@preview/hydra:0.6.3": hydra, anchor
3+
#import "@preview/marginalia:0.3.1" as marginalia: note, notefigure, wideblock
4+
#import "@preview/showybox:2.0.4": *
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#import "bookly-defaults.typ": *
2+
3+
#let front-matter(body) = context {
4+
set heading(numbering: none)
5+
set page(numbering: "i")
6+
states.page-numbering.update("i")
7+
states.num-pattern.update(none)
8+
states.isfrontmatter.update(true)
9+
10+
if states.open-right.get() {
11+
counter(page).update(0)
12+
} else {
13+
counter(page).update(1)
14+
}
15+
16+
body
17+
}
18+
19+
// Main matter
20+
#let main-matter(body) = context {
21+
set heading(numbering: "1.1.")
22+
23+
let numbering = "1/1"
24+
set page(numbering: numbering)
25+
26+
states.isfrontmatter.update(false)
27+
states.page-numbering.update("1/1")
28+
states.num-heading.update("1")
29+
states.num-pattern.update("1.1.")
30+
states.num-pattern-fig.update("1.1")
31+
states.num-pattern-subfig.update("1.1a")
32+
states.num-pattern-eq.update("(1.1a)")
33+
34+
if states.open-right.get() {
35+
counter(page).update(0)
36+
} else {
37+
counter(page).update(1)
38+
}
39+
40+
// To be checked
41+
if states.isfrontmatter.get() and states.tufte.get() and states.open-right.get() {
42+
counter(page).update(page => page + 1)
43+
}
44+
45+
body
46+
}
47+
48+
// Back matter
49+
#let back-matter(body) = {
50+
set page(header: none, footer: none)
51+
52+
body
53+
}
54+
55+
// Appendix
56+
#let appendix(body) = context {
57+
set heading(numbering: "A.1.")
58+
59+
// Reset heading counter
60+
counter(heading.where(level: 1)).update(0)
61+
62+
// Reset heading counter for the table of contents
63+
counter(heading).update(0)
64+
65+
// Update states for chapter function
66+
states.isfrontmatter.update(false)
67+
states.num-heading.update("A")
68+
states.num-pattern.update("A.1.")
69+
states.num-pattern-fig.update("A.1")
70+
states.num-pattern-subfig.update("A.1a")
71+
states.num-pattern-eq.update("(A.1a)")
72+
states.isappendix.update(true)
73+
74+
body
75+
}

0 commit comments

Comments
 (0)