A modular and organized TYPST template for creating professional documents using CNAM branding and styling.
Originally based on hzkonor’s bubble-template and uses CNAM’s logo and colors.
Dependencies
This template uses the following external packages:
@preview/great-theorems:0.1.2- Mathematical theorem environments@preview/headcount:0.1.0- Counter management@preview/hydra:0.6.2- Intelligent page headers with section awareness@preview/i-figured:0.2.4- Figure and equation numbering@preview/orchid:0.1.0- ORCID link generation (required when using ORCID author fields)
Project Structure
├── src/
│ ├── lib/ # Template library files
│ │ ├── config.typ # Main configuration and document setup
│ │ ├── fonts.typ # Centralized font configuration
│ │ ├── components.typ # UI components (blockquote, my-block, code)
│ │ ├── headers.typ # Header management logic
│ │ ├── layout.typ # Document layout and styling
│ │ ├── utils.typ # Utility functions
│ │ ├── colors.typ # Color definitions
│ │ └── math.typ # Mathematical environments
│ └── lib.typ # Main package entrypoint (local import)
├── template/
│ └── assets/ # Static assets (logos, images)
│ └── cnam_logo.svg # CNAM logo
├── main.typ # Example document using the published package
└── README.md
Features
- Modular Design: Template split into logical, maintainable modules
- CNAM Branding: Official CNAM colors and styling
- Centralized Font Configuration: Global font settings for consistency
- Enhanced Code Blocks: Syntax highlighting, line numbers, filename labels
- Rich Components: Custom blockquotes, styled content blocks
- Math Support: Mathematical definitions, theorems, examples
- Smart Headers: Context-aware page headers
- Responsive Layout: Professional document layout with decorative elements
Usage
Basic Usage
-
Import the template in your document:
- Using the published package (as in
main.typ):
#import "@preview/clean-cnam-template:1.6.4": *- Using this repository locally (from
src/):
#import "src/lib.typ": * - Using the published package (as in
-
Configure your document with basic parameters:
#show: clean-cnam-template.with(
title: "Your Title",
author: "Your Name",
class: "Course Name",
subtitle: "Subtitle",
// If using the package, point to your own copy of the logo
// If using this repo locally, you can use the provided logo path
logo: image("template/assets/cnam_logo.svg"),
start-date: datetime(day: 4, month: 9, year: 2024),
main-color: "#C4122E", // Custom color (default is "E94845")
default-font: (name: "New Computer Modern Math", weight: 400),
code-font: (name: "Zed Plex Mono", weight: 400),
)
- Write your content using the available components and styling.
Complete Parameter Reference
The clean-cnam-template function accepts the following parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
title |
string | "" |
Document title |
subtitle |
string | "" |
Document subtitle |
author |
string / dict / array | "" |
Author name(s). Accepts a plain string, a dict (name: "..", orcid: (id: "..", name: "..")), or a mixed array of both. When orcid.id is present, a clickable ORCID link is rendered on the cover. |
affiliation |
string | "" |
Author’s affiliation/institution |
year |
int | current year | Year for school year calculation |
class |
string/none | none |
Class/course name |
start-date |
datetime | today | Document start date |
last-updated-date |
datetime | today | Last updated date |
logo |
image/none | none |
Logo image to display |
main-color |
string | "E94845" |
Primary color (hex string) |
color-words |
array | () |
Words to highlight with primary color |
default-font |
object | (name: "New Computer Modern Math", weight: 400) |
Default font object (fallback for body and title fonts) |
body-font |
object/none | none |
Body text font object (defaults to default-font) |
title-font |
object/none | none |
Title and heading font object (defaults to default-font) |
code-font |
object | (name: "Zed Plex Mono", weight: 400) |
Code block font object |
show-secondary-header |
bool | true |
Show secondary headers |
outline-code |
content/bool/none | none |
Custom outline configuration |
cover |
dictionary | (:) |
Cover page configuration (see Cover Page) |
Advanced Configuration
Cover Page Customization
The cover parameter lets you control the cover page background, decorative circles, and text styling for every element. You only need to specify the keys you want to override – all others fall back to defaults.
Cover Dictionary Structure
| Key | Type | Default | Description |
|---|---|---|---|
bg |
color/none | none |
Page background color (none = transparent) |
decorations |
bool | true |
Show decorative circles on the cover page |
decorations.second-logo |
dict / none | none |
Secondary logo placed inside the top-left circle. Keys: image (content), scale (float, default 1.0), dx / dy (length, default 0pt) |
padding |
length | 1em |
Space between the horizontal lines and the content |
spacing |
length | 1em |
Space between elements (title, subtitle, date) |
title |
dictionary | see below | Title text configuration |
subtitle |
dictionary | see below | Subtitle text configuration |
date |
dictionary | see below | Date text configuration |
author |
dictionary | see below | Author/affiliation text configuration |
Element Dictionaries
All four element dictionaries (title, subtitle, date, author) share these keys:
| Key | Type | title | subtitle | date | author |
|---|---|---|---|---|---|
color |
color/auto | auto (main-color) |
auto (title color) |
auto (title color) |
auto (title color) |
weight |
int/string/auto | 700 |
700 |
auto (body-font weight) |
"bold" |
size |
length | 2.5em |
2em |
1.1em |
14pt |
font |
string/auto | auto (title-font) |
auto (title-font) |
auto (body-font) |
auto (body-font) |
The date dictionary also accepts:
| Key | Type | Default | Description |
|---|---|---|---|
range |
bool | true |
Show date range (start-date - last-updated-date). When false, only start-date is shown. |
All auto color values cascade from the title color. Setting cover: (title: (color: white)) makes every element white unless individually overridden. The horizontal lines also follow the title color.
Examples
Override only the background:
#show: clean-cnam-template.with(
// ... other parameters
cover: (bg: rgb("#1a1a2e")),
)
Dark background with white text and no decorative circles:
#show: clean-cnam-template.with(
// ... other parameters
cover: (
bg: rgb("#1a1a2e"),
decorations: false,
title: (color: white, size: 3em),
subtitle: (color: rgb("#cccccc")),
),
)
Custom fonts and sizes while keeping default colors:
#show: clean-cnam-template.with(
// ... other parameters
cover: (
title: (font: "Inter Display", weight: 800, size: 3em),
subtitle: (font: "Inter", weight: 400, size: 1.5em),
),
)
Partial overrides work at every level. For example, cover: (title: (size: 3em)) only changes the title size – color, weight, and font keep their defaults.
The title color cascades: setting cover: (title: (color: white)) also applies white to the subtitle and the horizontal lines, unless the subtitle explicitly overrides its own color.
Font Configuration
The template includes centralized font management that allows you to set consistent fonts across your document. Fonts are specified as objects with name and weight properties:
#show: clean-cnam-template.with(
default-font: (name: "Inter", weight: 400), // Sets default font (fallback for body and title)
body-font: (name: "Inter", weight: 400), // Optional: body text font (defaults to default-font)
title-font: (name: "Inter Display", weight: 600), // Optional: title font (defaults to default-font)
code-font: (name: "JetBrains Mono", weight: 400), // Sets code block font
// ... other parameters
)
Font Object Structure:
name: The font family name (string)weight: The font weight (integer: 100-900, or string: “regular”, “bold”, etc.)
The template uses a hierarchical font system:
default-fontserves as the base font object for the documentbody-fontis used for body text and defaults todefault-fontif not specifiedtitle-fontis used for titles and headings and defaults todefault-fontif not specifiedcode-fontis used for all code blocks and monospace text
This allows you to use different fonts and weights for body text and headings while maintaining a fallback to default-font.
Color Highlighting
You can automatically highlight specific words throughout your document with the primary color:
#show: clean-cnam-template.with(
// ... other parameters
color-words: ("important", "CNAM", "theorem"),
main-color: "#C4122E",
)
Any occurrence of the specified words will be rendered in the main-color.
Header Configuration
Control the display of secondary headers (sub-headings in page headers):
#show: clean-cnam-template.with(
// ... other parameters
show-secondary-header: false, // Only show main section in headers
)
Date Range Display
The template automatically formats date ranges. If start-date and last-updated-date are the same, only one date is shown. Otherwise, both dates are displayed as a range:
#show: clean-cnam-template.with(
start-date: datetime(day: 1, month: 9, year: 2024),
last-updated-date: datetime(day: 15, month: 12, year: 2024),
// Displays: 01/09/2024 - 15/12/2024
)
Custom Outline
The template allows you to customize or disable the table of contents (outline) on the title page:
Default Outline
#show: clean-cnam-template.with(
// ... other parameters
// outline-code: none, // This is the default - standard outline
)
Custom Outline
You can provide your own outline configuration:
#show: clean-cnam-template.with(
// ... other parameters
outline-code: outline(
title: "Table des matières",
depth: 2,
indent: auto,
),
)
Disable Outline
To disable the outline completely:
#show: clean-cnam-template.with(
// ... other parameters
outline-code: false,
)
Code Blocks
The template provides enhanced code blocks with multiple features including syntax highlighting, line numbers, and filename labels.
Note: Examples below use text fences and Typst raw(...) to avoid nested backticks so automated package checks pass. In your own documents, you can use normal Markdown code fences and standard Typst code blocks.
Basic Usage
#code(
lang: "Python",
raw(block: true, lang: "python", "def hello_world():\n print(\"Hello, World!\")")
)
With Filename
#code(
filename: "main.py",
lang: "Python",
raw(block: true, lang: "python", "def hello_world():\n print(\"Hello, World!\")")
)
Advanced Options
The code() function supports many customization options:
| Parameter | Type | Default | Description |
|---|---|---|---|
lang |
string/none | none |
Programming language for syntax highlighting |
filename |
string/none | none |
Optional filename to display |
numbering |
bool | true |
Whether to show line numbers |
line-spacing |
length | 5pt |
Vertical spacing between lines |
fill |
color | luma(250) |
Background color |
stroke |
stroke | 1pt + luma(180) |
Border style |
radius |
length | 3pt |
Border radius |
width |
length/% | 100% |
Block width |
lines |
range/auto | auto |
Line range to display |
number-align |
alignment | right |
Line number alignment |
text-style |
dict | (size: 8pt) |
Text styling options |
Example with custom styling:
#code(
numbering: false,
fill: rgb("#f8f8f8"),
stroke: 2pt + rgb("#e0e0e0"),
radius: 5pt,
lang: "Rust",
raw(block: true, lang: "rust", "fn main() {\n println!(\\\"Hello, world!\\\");\n}")
)
Components
UI Components
blockquote()
Styled quote blocks with customizable colors and borders.
Parameters:
color: Stroke color (default:luma(170))fill: Background color (default:luma(230))inset: Padding (default: custom spacing)radius: Border radius (default: rounded right side)stroke: Stroke configuration (default: left border only)
Example:
#blockquote[
This is an important quote that needs highlighting.
]
my-block()
Custom content blocks with configurable styling.
Parameters:
fill: Background color (default:luma(230))inset: Padding (default:15pt)radius: Border radius (default:4pt)outline: Border stroke (default:none)alignment: Block alignment (default:center)
Example:
#my-block(fill: rgb("#e3f2fd"))[
Important note or callout content.
]
code()
Enhanced code blocks with line numbers, syntax highlighting, and filename labels. See the Code Blocks section for detailed documentation.
Math Components
definition()
Mathematical definition blocks with red styling.
Example:
#definition(title: "Derivative")[
The derivative of a function $f$ at point $a$ is defined as...
]
example()
Example blocks with blue styling.
Example:
#example(title: "Computing a limit")[
Calculate: $lim_(x -> 0) sin(x)/x = 1$
]
theorem()
Theorem blocks with purple styling.
Example:
#theorem(title: "Pythagorean Theorem")[
For a right triangle: $a^2 + b^2 = c^2$
]
Utilities
ar(name)
Creates vector arrow notation in math mode.
Example:
$ar(v) = (x, y, z)$
icon(codepoint)
Displays an icon with proper sizing and spacing for inline use.
Example:
#icon("path/to/icon.svg") Inline text with icon
date-format(date)
Formats a datetime object to French format (DD/MM/YYYY).
Example:
#date-format(datetime(day: 4, month: 9, year: 2024))
// Outputs: 04/09/2024
Recent Updates
v1.6.4 - Cover Page Improvements (Latest)
- ORCID author links: The
authorparameter now accepts a dict or mixed array with anorcidfield; a clickable ORCID link is rendered on the cover when provided - Second cover logo: New
second-logokey incover.decorationsplaces a secondary logo inside the top-left circle decoration
v1.6.2 - Math and Block Styling
my-blockbody styling: Newbody-styleparameter for body text customization- Math component text styling: New
title-styleandbody-styleparameters fordefinition,example, andtheorem - Math components refactored: Converted from
.with()wrappers to proper functions with explicit parameters
v1.5.0 - Font Customization
- BREAKING: Font parameters use objects: All font parameters now accept
(name: "..", weight: 400)instead of plain strings - New
body-fontandtitle-fontparameters: Independent font selection for body text and headings
Previous Updates
Font Configuration System
- Added centralized font management with
default-fontandcode-fontparameters - Created separate
fonts.typmodule to avoid circular dependencies - All components now use consistent font configuration
Enhanced Code Blocks
- Added optional
filenameparameter for code blocks - Language labels now appear above code blocks instead of inline
- Improved visual connection between filename/language labels and code content
- Fixed font inheritance issues with proper context handling
Improved Modularity
- Restructured imports to eliminate circular dependencies
- Added
lib.typas main package entrypoint - Better separation of concerns across modules
Author
- Tom Planche
License
MIT