Typst - rychlotipy pro sazbu textu
28. února 2025 - Návody
Uživatelé LaTeXu můžou tento úvodní odstavec klidně přeskočit. Pro ty, co netuší nic o LaTeXu, Typst nebo sazbě textu, tak jde o pohodlné psaní a formátování textu dle nastavených pravidel a to nejen specificky vytvořených pro konkrétní dokument, ale také pravidla pro psaní textu ve zvoleném jazyce. Můžete si to představit jako MS Word, LibreOffice Writer a jiné textové procesory na steroidech. Největší krása pak spočívá ve zkompilování - převedení - dokumentu do požadovaného formátu, což bývá v drtivé většině PDF.
Článek mám v plánu průběžně doplňovat, jak budu doplňovat i svoje znalosti.
Poslední aktualizace: 04. 03. 2025.
Obsah
- Podmíněné nastavení
set
pravidla - Zvýrazněné liché/sudé řádky tabulky
- Funkce vracející argumenty jiné funkci
- Generování cenové tabulky s celkovou sumou
Úvod
Jak se od sebe LaTeX a Typst liší? Zejména syntakticky. Rád bych tu udělal sáhodlouhé pojednání o rozdílech, kladech a záporech, ale neudělám. LaTeX jsem použil na pár desítek poměrně jednoduchých dokumentů a jeho použití bylo pro mě většinou trochu krkolomné. Tady se chci zaměřit hlavně na Typst a na různé tipy a triky, které jsem pochytil s jeho používáním. Typst používám poměrně často na psaní dokumentů ať už pracovních a nebo soukromých. V obou případech jde o psaní čistého textu bez klikání, tak si vystačíte s Poznámkovým blokem a nebo jiným textovým editorem podle Vaší preference.
Typst lze stáhnout jako aplikace nebo lze využít online editor s živým náhledem dokumentu přímo na oficiálním webu: https://typst.app/. Když budu zmiňovat dokumentaci, je tím myšlena tato stránka, kde je popsána drtivá většina funkcí a konstrukcí dostupná v Typst. Jak takový jednoduchý dokument vypadá?
= Můj první článek
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sit amet mollis ipsum, vitae tincidunt erat. In non lectus eu sem pellentesque auctor ut vitae metus. In hac habitasse platea dictumst. Fusce sagittis scelerisque ante. Proin sollicitudin nunc mi, ut interdum sapien aliquet sed. Suspendisse vel elit maximus, consectetur erat in, faucibus nunc. Nulla odio turpis, bibendum a felis vitae, gravida rhoncus massa. Nulla ultricies pretium risus, at dignissim ligula bibendum vitae. Sed nisi augue, tempor vel augue id, bibendum consequat sem. Etiam ut lacinia sem. Mauris porta, ante quis volutpat hendrerit, urna arcu mollis ligula, a porta nunc mauris sed ligula. Praesent lobortis eu dolor id tincidunt. Pellentesque rutrum finibus turpis nec facilisis.
Na rozdíl od LaTeXu není potřeba nic dalšího, pokud nepotřebujete upravit formát stránky, odsazení od krajů a jiné. Vrhněme se ale na různé tipy a triky, protože naprosté základy psaní v Typst si můžete přečíst právě v dokumentaci. Ta je více než dostatečná a tenhle článek není o tom, aby Vás Typst naučil. Hlavně jde o mentální a viditelnou poznámku sobě samému pro budoucí použití. Proč se o ní veřejně nepodělit, že?
Podmíněné nastavení set
pravidla
U set
pravidel jsem sem tam potřeboval podmíněné nastavení, ale klasickým if
toho dosáhnout nelze. V rámci těla se tvoří nový obsah a pravidlo je tedy lokální pouze pro ten. Existuje ovšem varianta set-if
.
#let condition = true
#set text(red) if condition
Zvýrazněné liché/sudé řádky tabulky
Představte si, že máte tabulku přes celou stranu formátu A4. Pouhým okem se velmi jednoduše lze mezi řádky ztratit a tak by se hodil vizuální indikátor, například tmavší pozadí ob každý řádek.
#set table(
fill: (_, row) => if calc.odd(row) { color.hsl(0deg, 0%, 95%) },
)
#table(
columns: (1fr, 1fr),
[1. řádek 1. sloupec], [1. řádek 2. sloupec],
[2. řádek 1. sloupec], [2. řádek 2. sloupec],
[3. řádek 1. sloupec], [3. řádek 2. sloupec],
[4. řádek 1. sloupec], [4. řádek 2. sloupec],
[5. řádek 1. sloupec], [5. řádek 2. sloupec],
[6. řádek 1. sloupec], [6. řádek 2. sloupec],
)
Jak se tuhle informaci z dokumentace dozvědět? Parametr má informaci o možném předání funkce a v popisu je zmíněno kolik a jaké argumenty funkce přebírá. Tady index sloupce a řádku.
Funkce vracející argumenty jiné funkci
Potřeboval jsem vytvořit jednoduchou tabulku o dvou sloupcích. První sloupec je vždy prázdný, říkejme mu zaškrtávací, a druhý sloupec je s textem. Každý řádek tabulky by v kódu vypadal takto [], [Text pro řádek, vedle zaškrtávacího pole]
. Můžu si řádek zkopírovat a jen přepisovat, ale nešlo by to jednodušeji? Šlo! V tomhle konkrétním případě neušetříme počet znaků, ale rozhodně nezapomeneme na první (prázdný/zaškrtávací) sloupec.
#let row(value) = ([], [#value])
#table(
columns: (1fr, 1fr),
..row[1. řádek 2. sloupec],
..row[2. řádek 2. sloupec],
..row[3. řádek 2. sloupec],
..row[4. řádek 2. sloupec],
..row[5. řádek 2. sloupec],
..row[6. řádek 2. sloupec],
)
V dokumentaci najdete tuto možnost (operátor) jako arguments spreading
a konkrétně ..
(dvě tečky) jako spread operator
.
Případně je tu varianta pro vlastní funkci row
, aby vracela (typově) argumenty místo pole. Ve výsledku se nic nezmění.
#let row(value) = arguments([], [#value])
Generování cenové tabulky s celkovou sumou
Krásný příklad může být například ceník služeb. V takovém případě se opakují minimálně dvě věci. Název služby a její cena, nejčastěji v jednotné měně. Stejně jako v předešlém příkladu si vytvoříme funkci generující jeden řádek. Jako nápověda pro datový typ ceny uvádím výchozí argument nulu. V reálném případě by mělo jít o desetinné číslo, ale v zásadě to na funkci nemá vliv za předpokladu, že jí nepředáme řetězec znaků. Proč? Protože tahle "automatická" tabulka nám bude počítat i celkový součet všech služeb.
#let items = (
("Položka 1", 129),
("Položka 2", 1024),
("Položka 3", 99),
("Položka 4", 666),
("Položka 5", 9.99),
)
#let price_row(name, price: 0) = ([#name], table.cell(align: right)[#price Kč])
#let price_table(items: ()) = {
let total_price = 0
let rows = ()
for item in items {
total_price += item.at(1)
rows += price_row(item.at(0), price: item.at(1))
}
table(
columns: (1fr, 0.25fr),
..rows,
table.cell(align: right, colspan: 2)[*Celková cena: #total_price Kč*]
)
}
#price_table(items: items)
Proměnná items
je pole o pěti položkách. price_row
nám generuje jeden řádek tabulky. Funkce price_table
nám generuje celou tabulku a hlavně nám počítá celkovou sumu služeb. Pokaždé, když se změní proměnná items
, což znamená přidají se nebo odeberou položky, tabulka se změní a suma se přepočítá.