Sách HDSD Typst
Dùng Được Từ Đề Thi Đến Sách
Bộ hướng dẫn công khai, chi tiết cho hệ thống soạn thảo tài liệu toán học: đề thi THPT, sách giáo khoa, chuyên đề, ID, ngân hàng câu hỏi, BBT và hình vẽ Cetz.
Hệ thống được thiết kế bởi GV Nguyễn Văn Sang, tương thích hoàn toàn với Typst ≥ 0.12. Tất cả file template nằm trong thư mục typst/. Lệnh biên dịch chuẩn luôn dùng --root typst.
⚙️ Cài đặt & Biên dịch
Yêu cầu hệ thống
winget install Typst.Typst@preview/cetz:0.5.2Lệnh biên dịch chuẩn
--root typst để import tương đối hoạt động đúng.
# Biên dịch đề thi
typst compile --root typst typst/exams/de-01.typ output/de-01.pdf
# Biên dịch SGK / chuyên đề
typst compile --root typst typst/sgk.typ output/sach.pdf
# Chế độ watch (tự động biên dịch khi lưu)
typst watch --root typst typst/exams/de-01.typ output/de-01.pdf
# Biên dịch bộ đề thi
typst compile --root typst typst/bo-de.typ output/bo-de.pdf
Cấu trúc thư mục
typst/
├── template.typ ← Import cổng chính (dùng cái này)
├── sang-exam.typ ← Engine đề thi (tn, ds, tln, tl...)
├── bbt.typ ← Bảng biến thiên, xét dấu
├── geometry.typ ← Hình học phẳng & không gian
├── modules/
│ ├── book.typ ← Sách, SGK, chuyên đề
│ ├── exam.typ ← Wrapper cho engine thi
│ ├── exam-set.typ ← Bộ đề nhiều đề
│ └── research.typ ← Bài nghiên cứu
└── exams/ ← Đề thi mẫu
└── de-01.typ
Import chuẩn
// Cách 1: Import tất cả (khuyến nghị)
#import "template.typ": *
// Cách 2: Chỉ dùng engine thi
#import "sang-exam.typ": *
#import "@preview/cetz:0.5.2"
// Cách 3: Chỉ dùng module sách
#import "modules/book.typ": *
🚀 Khởi Động Nhanh
File đề thi cơ bản (5 phút)
// ① Import
#import "../sang-exam.typ": *
#import "@preview/cetz:0.5.2"
// ② Chế độ hiển thị
#let mode = "dethi" // "dethi" | "loigiai" | "solcolor"
#let accent = classic.blue // classic.blue | .emerald | .crimson
// ③ Tạo macro câu hỏi
#let (tn, ds, tln, tl) = exam-mode(mode: mode, accent: accent)
// ④ Show rules chuẩn
#show: sang-setup
// ⑤ Tiêu đề đề thi
#show: thpt-school-exam.with(
department: "SỞ GIÁO DỤC VÀ ĐÀO TẠO",
school: "TỈNH ĐỒNG THÁP",
exam-title: "KỲ THI THỬ TỐT NGHIỆP THPT NĂM 2025",
subject: "TOÁN",
duration: "90 phút, không kể thời gian phát đề",
code: "001",
)
// ⑥ Phần I — Trắc nghiệm
#exam-part([PHẦN I. Câu trắc nghiệm nhiều phương án.
Thí sinh chọn 1 phương án đúng.], count: 12)
#tn(
[Đạo hàm của $f(x) = x^3 - 3x + 1$ tại $x = 2$ là],
([$3$], [$6$], True([$9$]), [$-3$]),
loigiai: [$f'(x) = 3x^2 - 3 \Rightarrow f'(2) = 9$],
)
// ⑦ Phần II — Đúng-Sai
#exam-part([PHẦN II. Câu đúng sai.], count: 4)
#ds(
[Cho $f(x) = x^2 - 2x + 3$. Xét tính đúng/sai:],
(
True([Hàm đạt cực tiểu tại $x = 1$]),
True([Giá trị nhỏ nhất trên $[-1;3]$ bằng $2$]),
[Hàm nghịch biến trên $(1;3)$],
True([PT $f(x) = 3$ có nghiệm trên $[-1;3]$]),
),
loigiai: [Phân tích từng ý...],
)
// ⑧ Phần III — Tự luận
#exam-part([PHẦN III. Câu tự luận.])
#tl(
[Cho $f(x) = x^3 - 3x^2 + 4$.
a) Khảo sát sự biến thiên.
b) Tìm $m$ để $f(x) = m$ có 3 nghiệm phân biệt.],
lines: 8,
loigiai: [Lời giải mẫu...],
)
File sách / SGK cơ bản
#import "template.typ": *
#show: stexgv-doc.with(
doc-type: "sgk", // "sgk" | "book" | "chuyende"
title: "CHUYÊN ĐỀ TOÁN 12",
subtitle: "Giải tích & Hình học",
author: "GV Nguyễn Văn Sang",
institution: "Trường THPT...",
subject: "Toán",
grade: "Lớp 12",
academic-year: "2025–2026",
)
#chapter([Hàm Số & Đạo Hàm])
#bai([Khảo sát hàm bậc ba])
#muctieu[
- Lập được BBT của hàm bậc ba.
- Tìm được cực trị và khoảng đơn điệu.
]
#khoidong[
Quan sát đồ thị sau và trả lời: hàm có bao nhiêu cực trị?
]
#khampha[
Phương pháp: tính $f'(x)$, giải $f'(x) = 0$, lập BBT.
]
#vd(
[Khảo sát $f(x) = x^3 - 3x^2 + 4$.],
loigiai: [
$f'(x) = 3x^2 - 6x = 3x(x-2)$.
Lập BBT: cực đại $f(0) = 4$, cực tiểu $f(2) = 0$.
],
)
#bt(
[Tìm cực trị của $f(x) = -x^3 + 3x - 2$.],
lines: 4,
)
Bộ đề nhiều đề trong một file
#import "template.typ": *
#show: stexgv-doc.with(
doc-type: "bo-de",
title: "BỘ ĐỀ THI THỬ TOÁN 12",
author: "GV Nguyễn Văn Sang",
academic-year: "2025–2026",
)
#let (tn, ds, tln, tl) = exam-mode()
// ──── ĐỀ SỐ 1 ────
#de(
title: [Đề số 1],
code: "101",
subject: "TOÁN",
duration: "90 phút",
show-answer-key: true, // In đáp án ngay sau đề
)[\
#exam-part([PHẦN I. Trắc nghiệm.], count: 12)
#tn(
[Hàm $y = x^2$ có đạo hàm là],
([$x$], [$2$], True([$2x$]), [$x^2$]),
)
// ... thêm câu hỏi ...
]
// ──── ĐỀ SỐ 2 ────
#de(
title: [Đề số 2],
code: "102",
show-answer-key: true,
)[\
#exam-part([PHẦN I. Trắc nghiệm.], count: 12)
// ... câu hỏi đề 2 ...
]
📋 Tổng Quan Module Đề Thi
Module đề thi (sang-exam.typ) cung cấp đầy đủ công cụ soạn đề thi THPT theo cấu trúc Bộ GD&ĐT từ 2025.
Luồng làm việc
sang-exam.typ + cetz
dethi / loigiai / solcolor
Tạo macro tn/ds/tln/tl
thpt-school-exam
#tn #ds #tln #tl
Ba chế độ hiển thị
| mode | Hiển thị | Dùng khi |
|---|---|---|
"dethi" | Câu hỏi thuần, không đáp án, ô trống trắng | In đề cho học sinh |
"loigiai" | Câu hỏi + lời giải + đáp án đúng tô màu | Tài liệu ôn tập, đáp án |
"solcolor" | Như loigiai nhưng đáp án đúng nổi bật hơn | Đáp án chiếu trình chiếu |
4 loại câu hỏi
#tnTự chọn 1/2/4 cột
#dsBảng Đ/S tự động
#tln4 ô điền
#tlDòng kẻ tự động
① #tn — Câu Trắc Nghiệm Nhiều Phương Án
#tn (alias của #mcq) soạn câu trắc nghiệm 4 phương án, tự động chọn số cột 1/2/4 tuỳ độ rộng phương án.
Cú pháp đầy đủ
#tn(
[Nội dung đề bài],
( [$A$], True([$B$]), [$C$], [$D$] ),
loigiai: [Lời giải chi tiết],
// Các tham số tuỳ chọn:
fig: none,
fig-pos: "right",
fig-width: 35%,
cols: 0,
lines: 0,
num: auto,
prefix: "Câu",
boxed: false
)
Tham số chi tiết
[...].( ... ). Đáp án đúng phải được bọc trong hàm True(...).mode là "loigiai" hoặc "solcolor".cetz.canvas hoặc image)."right" (phải), "left" (trái), hoặc "center" (dưới đề).35%.0 (tự động chia 1, 2 hoặc 4 cột). Nhập 2 hoặc 4 để ép buộc.5 -> Câu 5). Mặc định tự tăng.Ví dụ 1 — Câu đơn không hình
#tn(
[Đạo hàm của hàm số $f(x) = x^3 - 3x + 1$ tại $x = 2$ bằng],
([$3$], [$6$], True([$9$]), [$-3$]),
loigiai: [
$f'(x) = 3x^2 - 3 \Rightarrow f'(2) = 12 - 3 = 9$.
],
)
Ví dụ 2 — Câu có hình bên phải
#tn(
[Đồ thị bên có bao nhiêu cực trị?],
([$0$], [$1$], True([$2$]), [$3$]),
fig: cetz.canvas(length: 0.7cm, {
import cetz.draw: *
line((-2.2, 0), (2.2, 0), mark: (end: ">"))
line((0, -1.5), (0, 2), mark: (end: ">"))
content((2.2, 0.3), $x$)
content((0.3, 2), $y$)
let pts = ()
for i in range(-21, 21) {
let x = i * 0.1
let y = -x * x * x / 3 + x
if y >= -1.5 and y <= 2 { pts.push((x, y)) }
}
line(..pts, stroke: 1.5pt + blue)
circle((-1, 2/3), radius: 2.5pt, fill: red)
circle((1, -2/3), radius: 2.5pt, fill: red)
}),
fig-pos: "right",
fig-width: 38%,
loigiai: [Quan sát đồ thị: hàm có 2 cực trị (1 cực đại, 1 cực tiểu).],
)
Ví dụ 3 — Phương án là hình vẽ
// Khi 4 phương án là hình vẽ (opt-fig: true)
#tn(
[Đồ thị nào sau đây là của hàm số $y = x^3$?],
(
True(cetz.canvas(length:0.5cm, { /* vẽ parabol */ })),
cetz.canvas(length:0.5cm, { /* vẽ ... */ }),
cetz.canvas(length:0.5cm, { /* vẽ ... */ }),
cetz.canvas(length:0.5cm, { /* vẽ ... */ }),
),
opt-fig: true, // BẮT BUỘC khi option là canvas
opt-fig-cols: 2, // 2×2 grid
)
cetz.canvas() và chuyển sang chế độ hình. Vẫn nên đặt opt-fig: true để rõ ràng.
② #ds — Câu Đúng / Sai
Câu hỏi gồm một thân chung và 4 phát biểu a/b/c/d, học sinh chọn Đúng/Sai cho từng ý. Tự động sinh bảng Đ/S có header màu.
Cú pháp đầy đủ
#ds(
[Thân câu chung — nêu tình huống / bài toán],
(
[Phát biểu a — SAI],
True([Phát biểu b — ĐÚNG]),
True([Phát biểu c — ĐÚNG]),
[Phát biểu d — SAI],
),
loigiai: [Phân tích từng ý.],
// Các tham số tuỳ chọn:
fig: none,
fig-pos: "right",
fig-width: 30%,
lines: 0,
num: auto,
prefix: "Câu",
)
Ví dụ đầy đủ
#ds(
[Cho $f(x) = x^2 - 2x + 3$ trên $[-1; 3]$. Xét tính đúng/sai:],
(
True([Hàm số đạt cực tiểu tại $x = 1$]),
True([Giá trị nhỏ nhất của hàm số trên đoạn là $2$]),
[Hàm số nghịch biến trên $(1; 3)$],
True([Phương trình $f(x) = 3$ có nghiệm trên $[-1; 3]$]),
),
loigiai: [
- *Ý a) Đúng.* $f'(x)=2x-2=0 \Rightarrow x=1$, $f''(1)=2>0$ → cực tiểu.
- *Ý b) Đúng.* $f(1) = 1 - 2 + 3 = 2$.
- *Ý c) Sai.* Hàm đồng biến trên $(1;3)$ vì $f'(x)>0$.
- *Ý d) Đúng.* $f(0) = 3$ là nghiệm.
],
)
True([...]), phát biểu sai để nguyên [...]. Trong chế độ loigiai, hệ thống tự tô màu ô Đ/S.
③ #tln — Câu Trả Lời Ngắn
Học sinh điền vào 4 ô trống (chế độ đề thi). Đáp án hiển thị trong ô màu xanh (chế độ lời giải).
Cú pháp đầy đủ
#tln(
[Nội dung đề bài],
[$6$],
loigiai: [Lời giải.],
// Các tham số tuỳ chọn:
fig: none,
fig-pos: "right",
fig-width: 30%,
show-boxes: true,
box-count: 4,
lines: 0,
num: auto,
prefix: "Câu",
)
Ví dụ 1 — Câu đơn
#tln(
[Giải phương trình $2x - 5 = 7$, tìm $x$.],
[$6$],
loigiai: [$2x = 12 \Rightarrow x = 6$.],
)
Ví dụ 2 — Có hình và dòng tính
#tln(
[Tính diện tích tam giác $OAB$ với $A(3;0)$, $B(0;4)$.],
[$6$],
fig: cetz.canvas(length: 0.8cm, {
import cetz.draw: *
line((0,0),(3,0),(0,4),(0,0), stroke: 1pt)
content((3.3,0), $A$)
content((-0.3,4.3), $B$)
content((-0.3,-0.3), $O$)
}),
fig-pos: "center", // hình dưới đề bài, căn giữa
lines: 2, // 2 dòng kẻ để tính
loigiai: [$S = \frac{1}{2} \cdot 3 \cdot 4 = 6$],
)
④ #tl — Câu Tự Luận
Cú pháp đầy đủ
#tl(
[Nội dung đề bài tự luận],
loigiai: [Lời giải mẫu.],
// Các tham số tuỳ chọn:
fig: none,
fig-pos: "right",
fig-width: 30%,
lines: 6,
num: auto,
prefix: "Câu",
boxed: false,
)
Ví dụ — Lời giải từng bước với #step
#tl(
[Cho hàm số $f(x) = x^3 - 3x^2 + 4$.
a) Khảo sát sự biến thiên và vẽ đồ thị.
b) Tìm $m$ để phương trình $f(x) = m$ có 3 nghiệm phân biệt.],
lines: 8,
loigiai: [
#ppgiai[Dùng đạo hàm và BBT để trả lời cả hai phần.]
#step[$f'(x) = 3x^2 - 6x = 3x(x-2)$. Cho $f'(x)=0 \Rightarrow x=0$ hoặc $x=2$.]
#step[Cực đại: $f(0) = 4$. Cực tiểu: $f(2) = 0$.]
#step[Phương trình $f(x)=m$ có 3 nghiệm phân biệt khi $0 < m < 4$.]
#reset-step()
],
)
Macro #step — Tô màu từng bước
loigiai: [
// Bước tự đếm, tự chọn màu xoay qua 6 màu
#step[Đặt ẩn phụ $t = e^x > 0$...]
#step[Giải: $t = 1$ hoặc $t = 2$.]
#step[Trả lại: $x = 0$ hoặc $x = \ln 2$.]
#step(color: red)[Lưu ý điều kiện $t > 0$.]
#reset-step() // Reset bộ đếm cho câu tiếp theo
]
🏷️ Tiêu Đề Đề Thi — #thpt-school-exam
#show: thpt-school-exam.with(
department: "SỞ GIÁO DỤC VÀ ĐÀO TẠO", // dòng 1 tiêu đề trái
school: "TỈNH ĐỒNG THÁP", // dòng 2 tiêu đề trái
exam-title: "KỲ THI THỬ TỐT NGHIỆP THPT", // tên kỳ thi, căn giữa
subject: "TOÁN",
duration: "90 phút, không kể thời gian phát đề",
code: "001", // mã đề
structure: auto, // tự sinh "Đề gồm X câu"
footer-left: [ĐỀ CHÍNH THỨC \ (Đề có 4 trang)],
accent: accent, // màu chủ đạo
show-topbar: true, // thanh màu phía trên
header-border: true, // đường kẻ dưới tiêu đề
)
#show: thpt-school-exam.with(...) phải đặt sau #let (tn,ds,tln,tl) = exam-mode(...) và sau #show: sang-setup, nhưng trước câu hỏi đầu tiên.
Macro #exam-part — Tiêu đề phần thi
// Phần trắc nghiệm — tự sinh "Câu 1 đến Câu 12"
#exam-part([PHẦN I. Câu trắc nghiệm nhiều phương án.
Thí sinh chọn 1 phương án đúng.], count: 12)
// Phần đúng-sai
#exam-part([PHẦN II. Câu đúng sai.
Thí sinh chọn Đúng hoặc Sai.], count: 4)
// Phần tự luận (không cần count)
#exam-part([PHẦN III. Câu tự luận.])
// Reset số câu giữa các phần nếu cần
#exam-part([PHẦN II.], reset-counter: true)
🔀 Chế Độ Hiển Thị
exam-mode() — Tạo bộ macro câu hỏi
// Tạo macro theo mode và màu sắc
#let (tn, ds, tln, tl) = exam-mode(
mode: "dethi", // "dethi" | "loigiai" | "solcolor"
accent: classic.blue // classic.blue | .emerald | .crimson
)
// Bảng màu có sẵn
classic.blue // = rgb("#0057b8") — xanh dương
classic.emerald // = rgb("#1a7a2e") — xanh lá
classic.crimson // = rgb("#cc2200") — đỏ đậm
mode = "loigiai" và biên dịch lại — không cần sửa nội dung câu hỏi. Đây là điểm mạnh nhất của hệ thống.
Điều khiển bộ đếm câu
// Đặt câu kế tiếp là Câu 13
#setcau(13)
// Reset về Câu 1
#resetcau()
// Đặt phần kế tiếp là PHẦN III
#setphan(3)
// Reset trạng thái đề thi mới (dùng trong bộ đề)
#resetexamstate(question-start: 1, part-start: 1)
🆔 ID, Tags & Ngân Hàng Câu Hỏi
Hệ thống dùng ID để quản lý câu hỏi bền vững. ID trong câu hỏi giúp đối soát khi trộn đề; ID trong bank.json là bản đồ phân loại để lọc theo lớp, chương, bài, dạng và mức độ.
Quy ước ID khuyến nghị
0D1N1-1
│││││ └─ số thứ tự trong cụm
││││└── bài/dạng
│││└── mức độ: N=NB, H=TH, V=VD, C=VDC
││└── chương
│└── phân môn: D=Đại số/Giải tích, H=Hình học
└── khối: 0=Lớp 10, 1=Lớp 11, 2=Lớp 12
npm run bank:gen-id để sinh ID mới, npm run bank:stat để thống kê, npm run sync:bank nếu vừa chỉnh bank.json ở root.
Gắn ID và tags trực tiếp trong câu
#tn(
[Hàm số $y = x^3 - 3x$ nghịch biến trên khoảng nào?],
([$(-oo;-1)$], True([$(-1;1)$]), [$(1;+oo)$], [$RR$]),
id: "2D1TH1-7",
tags: ("lop12", "dao-ham", "don-dieu", "bbt"),
loigiai: [
$y' = 3x^2 - 3 = 3(x-1)(x+1)$.
Hàm nghịch biến khi $-1 < x < 1$.
],
)
("lop12","bbt","vd"). #tn/#ds/#tln có thể render tags nhỏ cạnh stem.loigiai:; dùng được trong engine nếu loigiai để none.bank.json chỉ giữ metadata
Không nên nhét đề bài dài, công thức và hình Cetz vào JSON. Hãy để bank.json làm bản đồ mã, còn nội dung câu hỏi thật viết trong typst/questions.typ.
{
"0D1N1-1": "Lớp 10 | Đại số | Ch1: Mệnh đề | Bài 1: Mệnh đề | Nhận biết"
}
Khai báo câu hỏi thật trong Typst
#import "modules/question-bank.typ": (
ds-item, question-tn, question-ds, question-tln, question-tl,
render-question, render-selection,
)
#let question-bank = (
"0D1N1-1": question-tn(
[Phát biểu nào sau đây là một mệnh đề?],
([Bạn học tốt nhé!], [$2$ là số nguyên tố.], [Hôm nay đẹp quá!], [$x+1=3$]),
correct: 2,
solution: [Chỉ phát biểu "$2$ là số nguyên tố" xác định đúng/sai.],
tags: ("lop10", "menh-de"),
difficulty: "NB",
status: "ready",
source: "questions.typ",
),
)
API quản lý bank
| Lệnh | Ý nghĩa |
|---|---|
#load-bank() | Đọc metadata từ typst/bank.json. |
#bank-filter(...) | Lọc metadata theo lớp, phân môn, chương, bài, dạng, query hoặc danh sách ID. |
#bank-count(entries, by: "chapter") | Đếm số mã theo chương, bài, dạng, phân môn. |
#question-filter(...) | Lọc câu hỏi thật theo type, difficulty, status, source, tags, ids. |
#question-select(...) | Nối metadata trong bank với câu hỏi thật trong registry. |
#render-selection(..., show-id: true) | Render danh sách câu; bật ID khi biên tập nội bộ. |
Dựng câu theo bộ lọc
#import "template.typ": *
#import "questions.typ": question-bank
#let bank = load-bank()
#let selected = question-select(
bank,
question-bank,
chapter: "Mệnh đề",
status: "ready",
)
#render-selection(selected, mode: "loigiai", show-id: true)
⚙️ Tham Số Typst Thường Dùng
Đây là bảng đọc nhanh các lệnh Typst xuất hiện dày trong hệ thống. Hiểu nhóm này là đọc được phần lớn template.
Tham số nâng cao của câu hỏi
| Tham số | Macro | Ý nghĩa |
|---|---|---|
row-gutter: | #tn | Khoảng cách giữa các hàng phương án, hữu ích khi phương án có phân số/căn/log. |
opt-fig: | #tn | Đặt true khi phương án là hình vẽ để render dạng card. |
opt-fig-cols: | #tn | Số cột khi phương án là hình; thường dùng 2. |
box-count: | #tln | Số ô đáp số trong chế độ đề thi. |
show-boxes: | #tln | Tắt/bật cụm ô đáp số. |
boxed: | Tất cả | Đóng khung toàn câu, kèm box-fill, box-stroke, box-inset, box-radius. |
num: | Tất cả | Ép số câu thủ công; mặc định auto. |
prefix: | Tất cả | Đổi nhãn câu, ví dụ "Bài" hoặc "Question". |
Layout cốt lõi
| Lệnh | Cách hiểu nhanh |
|---|---|
#set page(...) | Khổ giấy, lề, header/footer, watermark/nền trang. |
#set text(...) | Font, cỡ chữ, ngôn ngữ, màu, độ đậm. |
#set par(...) | Căn đều đoạn văn và khoảng cách dòng. |
block(...)[...] | Khối lớn có nền, viền, padding, bo góc, khoảng cách trên/dưới. |
box(...)[...] | Hộp nhỏ/inline, hay dùng cho badge, ô đáp án, nhãn. |
grid(columns: (...), ...) | Bố cục nhiều cột. Ví dụ (1fr, 35%) là text co giãn + hình 35%. |
table(columns: (...), ...) | Bảng dữ liệu; có thể tô header hoặc zebra row bằng hàm fill. |
align(center)[...] | Căn nội dung trái/phải/giữa/trên/dưới. |
pad(x:, y:)[...] | Thêm khoảng đệm quanh nội dung. |
v(...) / h(...) | Khoảng trắng dọc/ngang. |
Kiểu dữ liệu hay gặp
| Kiểu | Ví dụ |
|---|---|
content | [Nội dung], [$x^2$], dùng cho stem/lời giải. |
string | "dethi", "right", "0D1N1-1". |
tuple | ([$A$], True([$B$]), [$C$], [$D$]); tuple 1 phần tử cần dấu phẩy như ("AC",). |
dictionary | (body: [text], correct: true); True([...]) là dictionary. |
color | rgb("#0057b8"), classic.blue, red. |
length | 12pt, 0.8em, 1cm. |
relative | 35%, 100%. |
auto | Để hệ thống tự tính: num: auto, structure: auto, h1: auto. |
none | Không có giá trị: tắt hình, lời giải, watermark, subtitle. |
Hình dài: dùng grid trong stem
#tln(
[
Đoạn mở đầu full-width.
#grid(
columns: (1fr, 38%),
column-gutter: 14pt,
align: (left + top, center + top),
[Đoạn văn song song với hình.],
cetz.canvas(length: 1cm, { /* hình */ }),
)
Đoạn kết vẫn full-width.
],
[$42$],
)
📦 Các Hộp Sư Phạm
Tất cả hộp dưới đây đều dùng được trong loigiai: của mọi loại câu hỏi.
Nhóm hộp lời giải
#ppgiai[...]#luuy[...]#meo[...]#nhanxet[...]#lythuyet[...]#note[...]Nhóm hộp học thuật (Theorem style)
#dn[...]#dl[...]#tc[...]#bode[...]Ví dụ sử dụng trong loigiai
#tl(
[Tìm min của $f(x) = x^2 - 4x + 5$.],
loigiai: [
#ppgiai[Dùng hoàn phương hoặc đạo hàm.]
#lythuyet[$f(x) = (x-a)^2 + b$ đạt min khi $x = a$, $\min = b$.]
#step[$f(x) = (x-2)^2 + 1$.]
#step[Min $= 1$ khi $x = 2$.]
#luuy[Không nhầm cực tiểu với giá trị nhỏ nhất trên đoạn.]
#reset-step()
],
)
📄 File Mẫu Đề Thi Hoàn Chỉnh
Copy file mẫu này, đổi thông tin tiêu đề và thêm câu hỏi vào đúng phần.
// ═══════════════════════════════════════════
// ĐỀ THI MẪU — Chỉnh sửa phần có dấu ◄
// Biên dịch: typst compile --root typst typst/exams/de-mau.typ output/de.pdf
// ═══════════════════════════════════════════
#import "../sang-exam.typ": *
#import "@preview/cetz:0.5.2"
// ── Chế độ ◄ ─────────────────────────────
#let mode = "dethi" // ◄ đổi thành "loigiai" để xem đáp án
#let accent = classic.blue // ◄ classic.blue | .emerald | .crimson
// ── Tạo macro ────────────────────────────
#let (tn, ds, tln, tl) = exam-mode(mode: mode, accent: accent)
#show: sang-setup
// ── Trang ────────────────────────────────
#set page(paper: "a4", margin: (x: 2cm, y: 2.5cm))
#set text(font: "New Computer Modern", size: 11pt, lang: "vi")
// ── Tiêu đề ◄ ────────────────────────────
#show: thpt-school-exam.with(
department: "SỞ GIÁO DỤC VÀ ĐÀO TẠO", // ◄ Đổi tên sở
school: "TỈNH ĐỒNG THÁP", // ◄ Đổi tên tỉnh
exam-title: "KỲ THI THỬ TỐT NGHIỆP THPT NĂM 2025", // ◄
subject: "TOÁN",
duration: "90 phút, không kể thời gian phát đề",
code: "001", // ◄ Mã đề
accent: accent,
)
// ═══════════════════════════════════════
// PHẦN I — TRẮC NGHIỆM (12 câu)
// ═══════════════════════════════════════
#exam-part([PHẦN I. Câu trắc nghiệm nhiều phương án. _(Câu 1 đến Câu 12)_
Thí sinh chọn *một phương án đúng* cho mỗi câu.], count: 12)
#tn(
[Đạo hàm của $f(x) = 2x^3 - 3x^2 + 1$ là],
([$6x^2 - 3$], True([$6x^2 - 6x$]), [$6x - 6$], [$2x^2 - 6x$]),
loigiai: [$f'(x) = 6x^2 - 6x$],
)
// ◄ Thêm câu 2–12 ở đây...
// ═══════════════════════════════════════
// PHẦN II — ĐÚNG SAI (4 câu)
// ═══════════════════════════════════════
#exam-part([PHẦN II. Câu đúng sai. _(Câu 13 đến Câu 16)_
Thí sinh chọn *Đúng hoặc Sai* cho mỗi mệnh đề.], count: 4)
#ds(
[Cho hàm số $f(x) = x^3 - 3x + 2$. Xét tính đúng/sai:],
(
[Hàm số có 2 cực trị.], // SAI
True([$f(1) = 0$]), // ĐÚNG
True([Cực đại tại $x = -1$]), // ĐÚNG
[Hàm đồng biến trên $\mathbb{R}$], // SAI
),
loigiai: [Phân tích từng ý...],
)
// ◄ Thêm câu 14–16 ở đây...
// ═══════════════════════════════════════
// PHẦN III — TRẢ LỜI NGẮN (4 câu)
// ═══════════════════════════════════════
#exam-part([PHẦN III. Câu trả lời ngắn. _(Câu 17 đến Câu 20)_
Thí sinh điền đáp án vào ô trống.], count: 4)
#tln(
[Tính $\lim_{x \to 2} \frac{x^2 - 4}{x - 2}$.],
[$4$],
loigiai: [Rút gọn: $\frac{(x-2)(x+2)}{x-2} = x+2 \to 4$.],
)
// ◄ Thêm câu 18–20 ở đây...
// ═══════════════════════════════════════
// PHẦN IV — TỰ LUẬN (2 câu)
// ═══════════════════════════════════════
#exam-part([PHẦN IV. Câu tự luận. _(Câu 21 đến Câu 22)_])
#tl(
[Khảo sát sự biến thiên của $f(x) = x^3 - 3x^2 + 4$.],
lines: 10,
loigiai: [
#ppgiai[Tính $f'$, giải $f' = 0$, lập BBT.]
#step[$f'(x) = 3x^2 - 6x = 3x(x-2)$.]
#step[CT: $f(0) = 4$; CT': $f(2) = 0$.]
#reset-step()
],
)
📚 Tổng Quan Module Sách / SGK
Module sách (modules/book.typ) cung cấp hệ thống soạn thảo đầy đủ cho SGK, chuyên đề và bộ đề thi nhiều đề.
Các loại tài liệu hỗ trợ
| doc-type | Mô tả | File mẫu |
|---|---|---|
"book" | Sách / chuyên đề cơ bản | typst/book.typ |
"sgk" | Sách giáo khoa đầy đủ mạch dạy học | typst/sgk.typ |
"chuyende" | Chuyên đề học tập dài | typst/chuyende.typ |
"bo-de" | Bộ đề thi nhiều đề trong một file | typst/bo-de.typ |
"research" | Bài nghiên cứu khoa học 2 cột | modules/research.typ |
Metadata chuẩn
#show: stexgv-doc.with(
doc-type: "sgk", // Loại tài liệu
title: "TÊN SÁCH",
subtitle: "Phụ đề nếu có",
author: "GV Nguyễn Văn Sang",
institution: "Trường THPT...",
subject: "Toán",
grade: "Lớp 12",
series: "Tên bộ tài liệu",
academic-year: "2025–2026",
publisher: "Đơn vị phát hành",
theme-color: classic.blue, // Màu chủ đạo
show-cover: true, // Bật/tắt trang bìa
show-outline: true, // Bật/tắt mục lục
outline-depth: 3, // Độ sâu mục lục
)
🗂️ Cấu Trúc Phân Cấp Sách
Các lệnh cấu trúc
#part([Tên phần]) alias: #unit#chapter([Tên chương])#bai([Tên bài]) alias: #lesson#dang([Tên dạng toán]) alias: #topic#muc([Tên mục]) alias: #section#appendix([Tên phụ lục]) alias: #phulucCác lệnh mở đầu tài liệu
#loinoidau[Lời nói đầu...] // alias: #preface
#gioithieu[Giới thiệu...] // alias: #introduction
#huongdansudung[Hướng dẫn...]
#muctieuchung[Mục tiêu chung...]
#bangthuatngu[...] // alias: #glossary
#tailieuthamkhao[...] // alias: #references
Ví dụ cấu trúc đầy đủ
#part([Phần 1: Giải Tích])
#chapter([Hàm Số Và Đạo Hàm])
#bai([Bài 1: Khảo sát hàm bậc ba])
#muctieu[
- Lập được BBT của hàm bậc ba.
- Vẽ đồ thị hàm số.
]
#khoidong[
Quan sát đồ thị và nhận xét số cực trị.
]
#khampha[
Phương pháp: tính $f'(x)$, giải $f'(x) = 0$, lập BBT.
]
#vd(
[Khảo sát $f(x) = x^3 - 3x^2 + 4$.],
loigiai: [Lời giải...],
)
#bt([Tìm cực trị của $f(x) = -x^3 + 3x$], lines: 4)
#luyentap[
#bt([Bài 1.], lines: 3)
#bt([Bài 2.], lines: 4)
]
#tomtat[
Hàm bậc ba $f(x) = ax^3 + bx^2 + cx + d$ ($a \ne 0$) có tối đa 2 cực trị.
]
#appendix([Phụ lục: Bảng đạo hàm])
📦 Các Hộp Nội Dung SGK
Hộp mạch dạy học SGK
#muctieu[...]#chuanbi[...]#khoidong[...]#khampha[...]#hoatdong[...]#luyentap[...]#vandung[...]#morang[...]#tomtat[...]#duan[...]Hộp lý thuyết
#phuongphap[...]#lythuyet[...]#ghinho[...]#nhanxet[...]#luuy[...]#note[...]#dn[...]#dl[...]#tc[...]#bode[...]Các khối nội dung đánh số
// Ví dụ có lời giải
#vd(
[Nội dung ví dụ.],
loigiai: [Lời giải chi tiết.],
)
// Bài tập với dòng trống
#bt(
[Bài tập luyện tập.],
lines: 4, // số dòng kẻ trống
)
// Câu hỏi củng cố
#cauhoi([Câu hỏi kiểm tra kiến thức.])
// Hoạt động nhóm
#hd([Thực hiện hoạt động sau...])
// Ôn luyện
#onluyen([Bài ôn luyện chương...])
🔢 Bộ Đếm Trong Sách
Điều khiển bộ đếm
// Đặt số chương / bài / mục / phụ lục
#setchuong(3) // Chương kế tiếp là Chương 3
#setbai(4) // Bài kế tiếp là Bài 4
#setmuc(2) // Mục kế tiếp là Mục 2
#setphuluc(2) // Phụ lục kế tiếp là Phụ lục 2
// Reset về đầu
#resetchuong()
#resetbai()
#resetmuc()
// Ví dụ và bài tập
#setvd(6) // Ví dụ kế tiếp là Ví dụ 6
#setbt(8) // Bài tập kế tiếp là Bài 8
#resetvd()
#resetbt()
// API tổng quát
#setbookcounter("chapter", 3) // = setchuong(3)
#resetbookcounter("vd")
setvd/setbt khi ghép nội dung từ nhiều nguồn.
📰 Bộ Đề Nhiều Đề — #de
Cú pháp #de
#de(
title: [Đề số 1], // tên trên mục lục bộ đề
exam-title: none, // tên trên đề (nếu khác title)
department: "SỞ GD&ĐT",
school: "TỈNH...",
subject: "TOÁN",
duration: "90 phút",
code: "101",
show-answer-key: true, // in đáp án sau đề
show-end: true, // in dòng HẾT
reset-state: true, // reset số câu/phần mỗi đề mới
question-start: 1,
)[
// Nội dung đề thi ở đây
#exam-part([PHẦN I.], count: 12)
#tn([...], (...))
// ...
]
Các hộp bổ sung trong bộ đề
// Đặt trước mỗi đề hoặc trước toàn tuyển tập
#matran[Ma trận đề thi...]
#dacta[Đặc tả câu hỏi...]
#huongdancham[Hướng dẫn chấm điểm...]
#luuybode[Lưu ý khi chấm...]
📄 File Mẫu Sách / Chuyên Đề
// Biên dịch: typst compile --root typst typst/chuyen-de-mau.typ output/cd.pdf
#import "template.typ": *
#import "@preview/cetz:0.5.2"
#import "bbt.typ": *
#show: stexgv-doc.with(
doc-type: "chuyende", // ◄ đổi thành "sgk" | "book" nếu cần
title: "CHUYÊN ĐỀ TOÁN 12",
subtitle: "Giải tích — Hình học — Xác suất",
author: "GV Nguyễn Văn Sang",
institution: "Trường THPT Nguyễn Du",
subject: "Toán",
grade: "Lớp 12",
academic-year: "2025–2026",
theme-color: classic.blue,
)
// ── Lời nói đầu ──────────────────────────
#loinoidau[
Chuyên đề này được biên soạn nhằm...
]
// ── Cấu trúc nội dung ────────────────────
#part([Phần 1: Giải Tích])
#chapter([Chương 1: Hàm Số Đơn Điệu])
#bai([Bài 1: Khảo sát hàm bậc ba])
#muctieu[
- Lập được bảng biến thiên.
- Tìm cực trị và khoảng đơn điệu.
]
#phuongphap[
*Phương pháp tổng quát:*
+ Tính $f'(x)$.
+ Giải $f'(x) = 0$, xác định dấu $f'$.
+ Lập BBT và kết luận.
]
#vd(
[Khảo sát $f(x) = 2x^3 - 3x^2 - 12x + 1$.],
loigiai: [
#step[$f'(x) = 6x^2 - 6x - 12 = 6(x-2)(x+1)$.]
#step[$f'(x) = 0 \Leftrightarrow x = -1$ hoặc $x = 2$.]
#step[CT: $f(-1) = 8$; ct: $f(2) = -19$.]
#reset-step()
],
)
#bt([Khảo sát $f(x) = x^3 - 6x^2 + 9x - 4$.], lines: 6)
#luyentap[
#bt([Tìm cực trị của $f(x) = x^4 - 8x^2 + 3$.], lines: 5)
]
#tomtat[
Hàm bậc ba $y = ax^3+bx^2+cx+d$ ($a \ne 0$):
- Có $\Delta' = b^2-3ac$: 2 cực trị khi $\Delta' > 0$.
]
📈 Tổng Quan Module Vẽ Hình
Module này gồm hai file: bbt.typ (bảng biến thiên, xét dấu) và geometry.typ (hình học phẳng, không gian, đồ thị).
Import
// Cần import cetz trước
#import "@preview/cetz:0.5.2"
// Bảng biến thiên & xét dấu
#import "bbt.typ": *
// Hình học
#import "geometry.typ": *
Tổng hợp các hàm
| Hàm | File | Mô tả |
|---|---|---|
bbtv2(...) | bbt.typ | BBT tiêu chuẩn, tự điều chỉnh chiều cao, hỗ trợ shade vùng gạch chéo |
bbbt(...) | bbt.typ | BBT đầy đủ, có ranks thủ công để chỉnh cao độ nhãn và mũi tên |
bxd(...) | bbt.typ | Bảng xét dấu một hoặc nhiều dòng |
bang-gia-tri(...) | bbt.typ | Bảng giá trị hàm số |
tri-xyz(...) | geometry.typ | Tam giác từ 3 điểm toạ độ |
tri-abc(...) | geometry.typ | Tam giác thường (đáy ngang) |
tri-right(...) | geometry.typ | Tam giác vuông tại A |
chop-sabc(...) | geometry.typ | Hình chóp S.ABC |
chop-sabcd(...) | geometry.typ | Hình chóp S.ABCD |
lang-tru-abc(...) | geometry.typ | Lăng trụ ABC.A'B'C' |
axis-xy(...) | geometry.typ | Hệ trục Oxy |
parabola(...) | geometry.typ | Đồ thị parabol y=ax²+bx+c |
circle-desc(...) | geometry.typ | Đường tròn tâm O bán kính R |
#bbtv2 — Bảng Biến Thiên Tiêu Chuẩn
bbtv2 là macro BBT chính, tự động điều chỉnh chiều cao ô, hỗ trợ vùng gạch chéo (tiệm cận đứng), tự tính vị trí mũi tên.
Cú pháp đầy đủ
#bbtv2(
var: $x$, // nhãn hàng x (mặc định $x$)
der: $y'$, // nhãn hàng đạo hàm
func: $y$, // nhãn hàng hàm số
x-vals: (), // mảng giá trị x (gồm cả −∞, +∞)
d-signs: (), // mảng dấu đạo hàm
v-vals: (), // mảng giá trị hàm tương ứng
shade: (), // vùng gạch chéo: ((i, j),) cho i..j
w1: 1.5, // chiều rộng cột nhãn (cm)
w2: 10, // chiều rộng cột nội dung (cm)
h1: auto, // chiều cao hàng x (tự điều chỉnh)
h2: 0.8, // chiều cao hàng đạo hàm (cm)
h3: auto, // chiều cao hàng hàm số (tự điều chỉnh)
)
Quy tắc d-signs / f-signs
n mốc x-vals, mảng dấu thường có 2n−3 phần tử: xen kẽ dấu khoảng và dấu tại các mốc giữa.
VD: 4 mốc x → 5 dấu:
(khoảng₁, tại₂, khoảng₂, tại₃, khoảng₃).
x-vals: ($-oo$, $-1$, $2$, $+oo$)
d-signs: ($+$, $0$, $-$, $0$, $+$)
// khoảng1 tại-1 khoảng2 tại2 khoảng3
| Giá trị dấu | Ý nghĩa |
|---|---|
$+$ hoặc "+" | Dấu dương. |
$-$ hoặc "-" | Dấu âm. |
$0$ hoặc "0" | Điểm bằng 0. |
"||" | Vạch đôi, tiệm cận hoặc điểm không xác định. |
none, "", [] | Ô trống. |
Ví dụ 1 — Hàm bậc ba đơn giản
// f(x) = x³ - 3x, cực đại x=-1, cực tiểu x=1
#bbtv2(
x-vals: ($-oo$, $-1$, $1$, $+oo$),
d-signs: ($+$, $0$, $-$, $0$, $+$),
// ^khoảng1 ^tại-1 ^khoảng2 ^tại1 ^khoảng3
v-vals: ($-oo$, $2$, $-2$, $+oo$),
)
Ví dụ 2 — Có tiệm cận đứng (dấu ||)
// y = 1/(x-1): tiệm cận đứng x=1
#bbtv2(
x-vals: ($-oo$, $1$, $+oo$),
d-signs: ($-$, "||", $-$),
v-vals: ($0$, ($+oo$, $-oo$), $0$),
// v-vals tại tiệm cận: tuple (trái, phải)
shade: ((1, 2),), // gạch chéo vùng [index 1, index 2)
)
Tham số đầy đủ
x, gồm vô cực, điểm cực trị hoặc điểm không xác định."||" cho tiệm cận/không xác định.($+oo$, $-oo$).((1, 2),). Đồng thời ngắt mũi tên qua vùng này.w2 khi nhiều mốc hoặc nhãn dài.h1, h3 có thể để auto để tự tăng khi có phân số/cases.Ví dụ 3 — Hàm có 1 cực trị trên đoạn (bbt-opt)
// Dành cho bài toán tối ưu
#bbt-opt(
x-vals: ($0$, $x_0$, $pi$),
d-signs: ($-$, $0$, $+$),
v-vals: ($f(0)$, $f(x_0)$, $f(\pi)$),
is-min: true, // true = \/ ; false = /\
)
#bbbt — Bảng Biến Thiên Đầy Đủ
bbbt là phiên bản đầy đủ hơn, cho phép truyền ranks thủ công để can thiệp vị trí mũi tên.
Ví dụ — Hàm có 2 cực trị, ranks thủ công
#bbbt(
var: $x$,
der: $f'(x)$,
func: $f(x)$,
x-vals: ($-oo$, $-1$, $2$, $+oo$),
d-signs: ($+$, $0$, $-$, $0$, $+$),
v-vals: ($-oo$, $8$, $-19$, $+oo$),
// ranks thủ công: điều chỉnh vị trí nhãn nếu cần
ranks: ((0,), (2,), (0,), (2,)),
w2: 12, // độ rộng cột nội dung
)
Cách hiểu ranks
Mỗi mốc x nhận một rank tương đối. Rank càng lớn thì nhãn càng cao. Với 4 mốc, truyền 4 tuple rank; tại tiệm cận có thể dùng hai rank cho hai phía.
// 4 mốc x nên có 4 phần tử ranks
ranks: ((0,), (2,), (0,), (2,))
// Mốc giữa là tiệm cận, có hai phía trái/phải
ranks: ((0,), (2, -2), (0,))
#bxd — Bảng Xét Dấu
Dùng cho bảng xét dấu $f'(x)$, bất phương trình. Hỗ trợ nhiều hàng dấu cùng lúc.
Ví dụ — 1 hàng dấu
#bxd(
var: $x$,
func: $f'(x)$,
x-vals: ($-oo$, $-1$, $2$, $+oo$),
f-signs: ($+$, $0$, $-$, $0$, $+$),
)
Ví dụ — Nhiều hàng dấu
// Xét dấu f'(x) = (x+1)(x-2)
#bxd(
var: $x$,
func: ($x+1$, $x-2$, $f'(x)$), // 3 hàng
x-vals: ($-oo$, $-1$, $2$, $+oo$),
f-signs: (
($-$, $0$, $+$, $+$, $+$), // dấu (x+1)
($-$, $-$, $-$, $0$, $+$), // dấu (x-2)
($+$, $0$, $-$, $0$, $+$), // dấu f'(x)
),
)
Lỗi BBT / BXD thường gặp
| Triệu chứng | Cách sửa |
|---|---|
| Lỗi index hoặc bảng không render | Kiểm tra số mốc x-vals và số phần tử d-signs/f-signs. |
| Nhãn đè mũi tên | Tăng w2, tăng h3, hoặc dùng #bbbt(ranks: ...). |
| Phân số làm hàng quá thấp | Để h1: auto, h3: auto; nếu vẫn chật, đặt thủ công h3: 3.2. |
| Tiệm cận không có vạch đôi | Dùng "||" đúng vị trí dấu tại mốc và dùng v-vals dạng hai phía. |
| Vùng không xác định vẫn có mũi tên | Thêm shade: ((i, j),) để tô vùng và ngắt mũi tên. |
📐 Hình Học Phẳng
Tất cả hàm trong geometry.typ trả về một cetz.canvas — dùng trực tiếp làm fig: trong câu hỏi.
Tam giác
// Tam giác từ 3 điểm toạ độ thật
#tri-xyz(
A: (0, 0), B: (5, 0), C: (2, 4),
labels: ("A", "B", "C"),
right-angle: none, // "A" | "B" | "C" để đánh dấu góc vuông
)
// Tam giác thường (đáy ngang, đỉnh trên)
#tri-abc(base: 6, height: 4, labels: ("A", "B", "C"))
// Tam giác vuông tại A
#tri-right(leg1: 4, leg2: 3, labels: ("A", "B", "C"))
Hình chữ nhật & Vuông
// Hình chữ nhật ABCD
#rect-abc(width: 6, height: 4, labels: ("A", "B", "C", "D"))
// Hình vuông
#square(a: 4, labels: ("A", "B", "C", "D"))
Đường tròn
// Đường tròn tâm O bán kính R
#circle-desc(center: (0, 0), radius: 2.5, label: "O")
// Elip ngang
#ellipse-h(center: (0, 0), a: 3, b: 2)
Dùng trực tiếp trong câu hỏi
#tn(
[Tam giác $ABC$ có $AB = 5$, $BC = 4$, $\hat{B} = 90°$. Tính $AC$.],
([$3$], [$\sqrt{41}$], True([$\sqrt{41}$]), [$9$]),
fig: tri-right(leg1: 5, leg2: 4, labels: ("B", "A", "C")),
fig-pos: "right",
fig-width: 30%,
loigiai: [$AC = \sqrt{AB^2 + BC^2} = \sqrt{41}$],
)
🗜️ Hình Học Không Gian
Hình chóp
// Hình chóp tam giác S.ABC
#chop-sabc(
S: (0, 8),
A: (-4, 0), B: (4, 0), C: (0, -2),
labels: ("S", "A", "B", "C"),
hidden: ("AC",), // cạnh AC vẽ nét đứt (bị che)
)
// Hình chóp tứ giác S.ABCD
#chop-sabcd(
S: (0, 7),
A: (-3, 0), B: (3, 0), C: (2, -2), D: (-2, -2),
labels: ("S", "A", "B", "C", "D"),
hidden: ("AD", "DC"), // 2 cạnh đáy bị che
)
Lăng trụ
// Lăng trụ tam giác đứng ABC.A'B'C'
#lang-tru-abc(
A: (-3, 0), B: (3, 0), C: (0, -2),
A2: (-3, 5), B2: (3, 5), C2: (0, 3),
labels: ("A", "B", "C", "A'", "B'", "C'"),
hidden: ("AA'", "AB"), // cạnh bị che → nét đứt
)
hidden nhận tuple các nhãn cạnh (VD: "SA", "BC"). Cạnh trong danh sách sẽ vẽ nét đứt thay vì nét liền.
📊 Đồ Thị Hàm Số
Hệ trục Oxy
#axis-xy(
xmin: -3, xmax: 3,
ymin: -2, ymax: 4,
xlabel: "x",
ylabel: "y",
xstep: 1, ystep: 1,
scale: 1cm,
ticks: true, // hiện số trên trục
)
Parabol y = ax² + bx + c
#parabola(
a: 1, b: -2, c: -3, // y = x² - 2x - 3
xmin: -2, xmax: 4,
npts: 80, // số điểm vẽ
show-vertex: true, // hiện đỉnh
show-roots: true, // hiện nghiệm
accent: rgb("#0057b8"),
)
Vẽ đồ thị tuỳ ý với cetz
// Dùng trực tiếp cetz để vẽ hàm số bất kỳ
fig: cetz.canvas(length: 0.8cm, {
import cetz.draw: *
// Trục
line((-3.2, 0), (3.2, 0), mark: (end: ">"))
line((0, -2.2), (0, 3.2), mark: (end: ">"))
content((3.2, 0.3), $x$)
content((0.3, 3.2), $y$)
// Vẽ đồ thị f(x) = x³ - 3x + 1
let pts = ()
for i in range(-30, 31) {
let x = i * 0.1
let y = x * x * x - 3 * x + 1
if y >= -2 and y <= 3 { pts.push((x, y)) }
}
line(..pts, stroke: 1.5pt + blue)
// Đánh dấu cực trị
circle((-1, 3), radius: 3pt, fill: red)
circle((1, -1), radius: 3pt, fill: red)
content((-1.5, 3.2), $(-1;\ 3)$)
content((1.5, -1.3), $(1;\ -1)$)
})
⬇️ Tải Về Gói Template
Tải về các gói template để bắt đầu soạn thảo ngay mà không cần cấu hình thêm.
Lệnh biên dịch sau khi tải về
# Giải nén vào thư mục dự án
unzip stexgv-template-full.zip -d my-typst-project/
cd my-typst-project
# Biên dịch đề thi mẫu
typst compile --root typst typst/exams/de-mau.typ de-mau.pdf
# Biên dịch sách mẫu
typst compile --root typst typst/chuyende.typ chuyen-de.pdf
# Chế độ watch (tự biên dịch khi lưu)
typst watch --root typst typst/exams/de-mau.typ de-mau.pdf
- Windows:
winget install Typst.Typst - macOS:
brew install typst - Linux:
snap install typst - Hoặc tải tại github.com/typst/typst/releases