
Transformace textů na základě regulárních výrazů – program sed a převod LaTeX/HTML
V tomto článku se podíváme na substituce regulárních výrazů pomocí programu sed, který je běžně dostupný v příkazové řádce u unixových systémů. Vyzkoušíme si základní transformace LaTeX a HTML tagů. Pro tento problém obecně použijte nějaký již hotový konvertor typu Tex4ht, smyslem tohoto článku je úvod do programu sed a demonstrace možností využití regulárních výrazů v textových substitucích.
Pokud pracujete na OS Windows, doporučuji stáhnout příkazový terminál Cygwin, který poměrně dobře unixovou příkazovou řádku zastupuje. Sed se při transformacích textů běžně používá pro záměnu textů. Pro začátku se podíváme na velice jednoduchou ukázku, kdy příkazem echo vypíšeme větu nad kterou budeme chtít transformaci provádět a na výstup tohoto příkazu aplikujeme sed.
echo "replace first with second" | sed 's/first/second/g'
Výstupem bude:
"replace second with second"
Nyní se podíváme na vzor, podle kterého jsme tuto transformaci provedli: ‚s/first/second/g‘
- s/first/second/gsdfgsdfg – písmeno s v tomto případě znamená substitute (náhrada), udává, že následuje vzor pro náhradu textů
- s/first/second/gsdfg – místo first můžeme napsat jakýkoliv text, který má být nahrazován
- s/first/second/gsdfgs – místo second můžeme napsat jakýkoliv text, který má ten předchozí nahradit
- s/first/second/g – písmeno g v tomto případě znamená global, v našem případě to bude znamenat, že pokud by jsme na vstupu měli vícekrát se vyskytující text first, tak se pokaždé nahradí
Sed samozřejmě poskytuje mnoho dalších vzorů, pro transformaci článků. Pro zatím si však vystačíme pouze s tímto. Dále se podíváme, jak lze do tohoto vzoru aplikovat práci regulárními výrazy. Ty nám dávají mnohem širší možnosti k popisu textu, který chceme nahrazovat. Podíváme se na další příklad
echo "(text inside brackets)" | sed 's/(\(.*\))/This was inside brackets: \1/g'
Výstupem bude:
"This was inside brackets: text inside brackets"
Následující vzor pro náhradu textu již vypadá značně složitěji, rozebereme si nejprve nahrazovaný text a poté text, který jej nahradil:
- (\(.*\)) – Závorky za zpětným lomítkem udávají, že se mezi nimi bude nacházet regulární výraz, tím je právě tečka a hvězdička. Tečka v regulárních výrazech reprezentuje jakékoliv písmeno a hvězdička za ním reprezentuje libovolný počet opakování tohoto písmena. Vidíme, že kolem těchto závorek máme ještě jedny závorky, což znamená, že tomuto vzoru by odpovídal jakýkoliv text ve tvaru (…cokoliv…)
- This was inside brackets: \1 – Jednička za lomítkem, reprezentuje první regulární výraz který je nahrazován (v našem případě máme pouze jeden). Vidíme, že touto transformací jsme z textu odstranili závorky a to co bylo uvnitř vypsali v jiném formátu.
Pro podrobnější pochopení regulárních výrazů si můžete prolétnout oficiální dokumentaci: https://www.gnu.org/software/sed/manual/html_node/Regular-Expressions.html. Následně se jíž podíváme na nějaký soubor ve formátu LaTeX a vytvoříme pro něj několik transformací, které tyto tagy budou podle regulárních výrazů převádět do HTML. Předpokládáme, že máme přehled o struktuře daného dokumentu, jinak by výsledný skript byl značně složitější. Vezmeme následující příklad:
Soubor MyLatex.tex
\section{Technologie: C\# - ASP.NET / ASP.NET Core}
\subsection{Principy technologie}
První podstatnou pomůckou pro práci s tímto frameworkem je vývojové prostředí, kterým je \textbf{Visual Studio}\cite{12}.
\begin{description}
\item [Model] Představuje stav aplikace, tedy data, se kterými \textit{REST API} pracuje.
\item [Controller] Komponenty, které zpracovávají interakci s uživatelem, která se pak promítne na změně modelu. V případě REST API sem řadíme veškeré zpracování HTTP požadavků.
\end{description}
\begin{itemize}
\item Nancy - http://nancyfx.org/
\item Manos - https://github.com/jacksonh/manos
\end{itemize}
Vidíme, že v textu se nachází řada různých LaTeX tagů. Nejprve bude nutné postupně transformovat jednoduché tagy typu tučných písmen, sekcí, podsekcí a poté bude již jednodušší zpracovat složitější věci jako jsou seznamy. Vytvoříme několik transformací z nichž se každá bude zaměřovat na záměnu nějakého tagu:
sed 's/\\section{\([^{}]*\)}/<h1>\1<\/h1>/g'
– nahradíme sekce za h1 tagy, vysvětlení: regulární výraz \([^{}]*\) přijme libovolný řetězec znaků, který neobsahuje složené závorky. Veškerá lomítka je také nutné backslashovat, aby nebyla porušena struktura výrazu.sed 's/\\subsection{\([^{}]*\)}/<h2>\1<\/h2>/g'
– nahradíme podsekce za h2 tagysed 's/\\textbf{\([^{}]*\)}/<b>\1<\/b>/g'
– nahradíme \textbf (tučná písmena) za <b>text</b>sed 's/\\textit{\([^{}]*\)}/<i>\1<\/i>/g'
– nahradíme \textit (kurzíva) za <i>tex</i>sed 's/\\cite{\([^{}]*\)}//g'
– citace v tomto případě odstranímesed 's/\\begin{\(itemize\|description\)}/<ul>/g'
– nahradíme tagy pro seznamy, vysvětlení: \| v regulárním výrazu znamená nebosed 's/\\end{\(itemize\|description\)}/<\/ul>/g'
sed 's/\\item\([^\\\n]*\)/<li>\1<\/li>/g''
– nahradíme prvky v seznamech
Následně všechny tyto transformace aplikujeme ve stejném pořadí, v jakém byly uvedeny:
cat MyLatex.tex | sed 's/\\section{\([^{}]*\)}/<h1>\1<\/h1>/g'
| sed 's/\\subsection{\([^{}]*\)}/<h2>\1<\/h2>/g'
| sed 's/\\textbf{\([^{}]*\)}/<b>\1<\/b>/g'
| sed 's/\\textit{\([^{}]*\)}/<i>\1<\/i>/g'
| sed 's/\\cite{\([^{}]*\)}//g'
| sed 's/\\begin{\(itemize\|description\)}/<ul>/g'
| sed 's/\\end{\(itemize\|description\)}/<\/ul>/g'
| sed 's/\\item \([^\\\n]*\)/<li>\1<\/li>/g' > MyLatex.html
Nyní by vše mělo být hotovo, podíváme se na náš výsledný soubor
Soubor MyLatex.html
<h1>Technologie: C\# - ASP.NET / ASP.NET Core</h1>
<h2>Principy technologie</h2>
První podstatnou pomůckou pro práci s tímto frameworkem je vývojové prostředí, kterým je <b>Visual Studio</b>.
<ul>
<li>[Model] Představuje stav aplikace, tedy data, se kterými <i>REST API</i> pracuje.</li>
<li>[Controller] Komponenty, které zpracovávají interakci s uživatelem, která se pak promítne na změně modelu. V případě REST API sem řadíme veškeré zpracování HTTP požadavků.</li>
</ul>
<ul>
<li>Nancy - http://nancyfx.org/</li>
<li>Manos - https://github.com/jacksonh/manos</li>
</ul>
Vidíme, že naše transformace zafungovaly a dosáhly požadovaných výsledků. Ovšem celý skript vypadá dost šíleně a je schopen zpracovat jen určitou část LaTeX tagů. Vhodné řešení pro konverzi těchto tagů by bylo použití již nějakého odladěného nástroje. Takové nástroje by však mohli fungovat právě na principu nahrazování textů podle regulárních výrazů.