Noltio logo
Jan Švábík 17. 10. 2020 /  3 minuty čtení
automatic space replacement typography hugo

Hugo: Jak na automatické nahrazení mezer nedělitelnými

V dnešním článku se dozvíte, jak docílit lepší čitelnosti a prestižnosti tím, že nebudou zůstávat jednopísmenná slova nebo číslice na konci řádků. Běžné mezery budou nahrazeny nedělitelnými automaticky.

Úvod

Chcete-li texty na svém webu mít na úrovni, ale nechcete se starat o některé typografické konvence, používáte-li generátor statických stránek Hugo, níže vám popíšu kód, který nahradí běžné mezery za nedělitelné mezery automaticky při buildu webu.

Finální kód

{{ $content := .Content }}
{{ $content = replaceRE "(>|\\(|\\[|\\{)?(A|I|O|U|K|S|V|Z)(</[a-z0-9]>)? " "$1$2$3&nbsp;" $content }}
{{ $content = replaceRE " (\\(|\\[|\\{)?(A|I|O|U|K|S|V|Z|a|i|o|u|k|s|v|z)(</[a-z0-9]>)? " " $1$2$3&nbsp;" $content }}
{{ $content = replaceRE "( |>|\\(|\\[|\\{)(\\d\\.?)(</[a-z0-9]>)? " "$1$2$3&nbsp;" $content }}
{{ $content = replaceRE "( |>|\\(|\\[|\\{)([A-Z]\\.)(</[a-z0-9]>)? " "$1$2$3&nbsp;" $content }}
{{ $content | safeHTML }}

Nyní si každý řádek kódu postupně rozebereme.

Vysvětlení kódu

Na prvním řádku kódu je celý hlavní obsah stránky z markdown souboru uložen do proměnné $content. Nic víc se tu neděje.

Nahrazení mezer za prvním písmenem

Pokud je na začátku odstavce nebo jiného elementu jednopísmenné slovo následované mezerou, bude tato mezera nahrazena nedělitelnou mezerou. Před slovem může být znak (, [ nebo také {.

{{ $content = replaceRE "(>|\\(|\\[|\\{)?(A|I|O|U|K|S|V|Z)(</[a-z0-9]>)? " "$1$2$3&nbsp;" $content }}

Nahrazení mezer uprostřed textu

Třetí řádek kódu zajišťuje nahrazení mezer za jednopísmennými slovy uprostřed textu, tedy včetně malých písmen. Slova mohou být opět uzavřená v závorkách a pokud je za slovem uzavírací HTML tag, bude nedělitelná mezera vložena až za tento tag.

{{ $content = replaceRE " (\\(|\\[|\\{)?(A|I|O|U|K|S|V|Z|a|i|o|u|k|s|v|z)(</[a-z0-9]>)? " " $1$2$3&nbsp;" $content }}

Nahrazení mezer za číslovkami

Další řádek se stará o nahrazení mezer za číslovkami, ať už jsou obyčejné nebo řadové (tedy následované tečkou). Za každou číslovkou bude nedělitelná mezera.

{{ $content = replaceRE "( |>|\\(|\\[|\\{)(\\d\\.?)(</[a-z0-9]>)? " "$1$2$3&nbsp;" $content }}

Nahrazení mezer za iniciálami

Vyskytnou-li se v textu iniciály (tedy velké písmeno následované tečkou a mezerou), bude mezera nahrazena za nedělitelnou, aby nebylo zkrácené jméno rozdělené do dvou řádků.

{{ $content = replaceRE "( |>|\\(|\\[|\\{)([A-Z]\\.)(</[a-z0-9]>)? " "$1$2$3&nbsp;" $content }}

Vypsání HTML

Při nahrazování funkcí replaceRE dojde k vygenerování nových stringů, které nebudou považovány za bezpečné pro vypsání bez nahrazení znaků HTML kódu za HTML entity. Abychom na výstup dostali čistý HTML kód, je nutné použít funkci safeHTML.

{{ $content | safeHTML }}

Samostatná partial

Můžeme si také vytvořit partial, která bude volána vždy s kontextem, v němž potřebujeme provést typografické úpravy. V tomto případě se bude drobně lišit první a poslední řádek kódu.

Vytvořme soubor layouts/partials/typographied.html a vložme do něj následující kód:

{{ $content := . }}
{{ $content = replaceRE "(>|\\(|\\[|\\{)?(A|I|O|U|K|S|V|Z)(</[a-z0-9]>)? " "$1$2$3&nbsp;" $content }}
{{ $content = replaceRE " (\\(|\\[|\\{)?(A|I|O|U|K|S|V|Z|a|i|o|u|k|s|v|z)(</[a-z0-9]>)? " " $1$2$3&nbsp;" $content }}
{{ $content = replaceRE "( |>|\\(|\\[|\\{)(\\d\\.?)(</[a-z0-9]>)? " "$1$2$3&nbsp;" $content }}
{{ $content = replaceRE "( |>|\\(|\\[|\\{)([A-Z]\\.)(</[a-z0-9]>)? " "$1$2$3&nbsp;" $content }}
{{ return ($content | safeHTML) }}

Na místě, kde budeme chtít vložit text nebo HTML kód s typografickými úpravami, nyní stačí partial zavolat a předat jí kontext ke zpracování.

{{ partial "typographied" .Content }}

Závěr

Kód nepočítá se všemi možnými kombinacemi znaků, které mohou nastat, nýbrž jen s těmi nejčastějšími, se kterými se lze setkat při běžném psaní textů, zejména článků. V některých případech nemusí k nahrazení dojít, takové případy by ale měly být velmi ojedinělé.