Vim: (dávkové) spouštění ex příkazů

Přítelem každého Vim-uchyláka je bravurní znalost (Vim-flavored) regexů. Ukážeme si, jak s nimi pracovat dávkově.

Text vyšel původně na autorově webu.

Co jsem řešil?

Když jsem před časem zmigroval web na Hugo, bylo to celkem jednoduché — tehdejší verze Hugo bez problémů požrala HTML čurbes z Bloggeru, a tak s tím nebylo moc starostí.

Bohužel, od verze v0.60.0 změnil Hugo Markdown knihovnu — z Blackfriday na Goldmark a mě se přestaly renderovat všechny nevyčištěné stránky (tedy ty, nepřevedené na čistý Markdown).

Rozhodl jsem se na to jít z gruntu a všechen HTML balast odstranit. To je hodně práce. A protože píšu ve Vimu, tak jsem čistil… ve Vimu.

Okno s historií příkazů

Přítelem každého Vim-uchyláka je bravurní znalost (Vim-flavored) regexů. A když vás po čase přestane bavit je psát zpaměti, začnete je hledat v historii.

Knížce Practical Vim vděčím mimo jiné za to, že vím, k čemu je ten příkaz, který mě vždycky přiváděl k šílenství, když jsem chtěl zavřít buffer, a omylem jsem se překlepl, takže jsem místo :q napsal q:

Vim buffer s otevřeným command-line oknem s historií příkazů

Vim buffer s otevřeným command-line oknem s historií příkazů

Příkazy q:q/ a q? totiž otevřou command-line window s načtenou historií :, či / příkazů. Výhodou je, že se v tom okně můžete chovat jako ve Vimu. 🤓 Můžete v něm vyhledávat, kopírovat, editovat… A znovu spouštět dané příkazy.

Spuštění příkazů ze souboru

Vyhledání a spuštění nějakého složitější příkazu je sice fajn, ale jsou tu dva problémy:

  • Jednak jde o historii a ta má nějaký limit (třeba já mám defaultní history=200), takže po čase může příkaz zmizet.
  • Pokud zpracovávám více souborů, je to repetitivní a chtělo by to nějak naskriptovat. 🤔

Ke slovu tak přichází příkaz source, který načte sadu příkazů ze souboru a postupně je provede.

Pro potřeby čištění blogu jsem si vytvořil následující sadu příkazů:

" -------------------
" Generic markdownify
" -------------------

" Put every tag to new line
%s/></>\r</g
" Separate paragraphs by one line
%s/<br \/>\n*<br \/>/\r\r/
%s/\n\n\{2,}/\r\r/
" Markdownify links
%s/<a href="https\?:\(.\{-}\)">\(.\{-}\)<\/a>/[\2](\1)/g
" Markdownify bold, cursiva & strikethrough
%s/<i>\(.\{-}\)<\/i>/_\1_/g
%s/<b>\(.\{-}\)<\/b>/**\1**/g
%s/<strike>\(.\{-}\)<\/strike>/\~\~\1\~\~/g
" Markdownify headers
%s/<h2.\{-}>\(.\{-}\)<\/h2>/## \1\r\r/g
%s/<h3.\{-}>\(.\{-}\)<\/h3>/### \1\r\r/g
%s/<h4.\{-}>\(.\{-}\)<\/h4>/#### \1\r\r/g
" Markdownify monospace
%s/<span.\{-}monospace.\{-}>\(.\{-}\)<\/span>/`\1`/g
" Markdownify items
%s/<li>\n\?\(.\{-}\)\n\?<\/li>/* \1/
" Replace a non-breaking-space with a space
%s/&nbsp;/ /g
" Markdownify dashes
%s/ - / --- /g
" Markdownify blockquotes
%s/<blockquote.\{-}>\n\?\(.\+\)\n\?<\/blockquote>/> \1\r\r/g

" -------------------------
" External sites shortcodes
" -------------------------

" Markdownify gists
%s/<script .\{-}\(gist\)\.github\.com\/\(.\{-}\)\/\(.\{-}\)\.js">\n\?<\/script>\s*\(<br \/>\)\?/{{< \1 \2 \3 >}}\r\r/g

" ---------------------------
" sw-samuraj.cz & clojure.cz specific changes
" ---------------------------

" Remove following prefix from links, plus .html suffix:
" * //sw-samuraj.cz
" * //www.sw-samuraj.cz
" * http://sw-samuraj.cz
" * https://sw-samuraj.cz
" * http://www.sw-samuraj.cz
" * https://www.sw-samuraj.cz
%s/(\(https\?:\)\?\/\/\(w\{3}\.\)\?sw-samuraj\.cz\(\/.\{-}\)\.html)/(\3\/)/cg
" Remove following prefix from links, plus .html suffix:
" * //clojure.cz
" * //www.clojure.cz
" * http://clojure.cz
" * https://clojure.cz
" * http://www.clojure.cz
" * https://www.clojure.cz
%s/(\(https\?:\)\?\/\/\(w\{3}\.\)\?clojure\.cz\(\/.\{-}\)\.html)/(\3\/)/cg

Teď stačí zadat v editoru tenhle příkaz a mám vyčištěno!

:source srcipts/html-to-markdown.vim

Fakt je to tak jednoduchý?

Jasně, je. Pořeší se tím všechno, co se dá zvládnout regulárním výrazy. Samozřejmě, my, co jsme měli na škole dva semestry předmětu Regulární a bezkontextové jazyky a není nám neznámá Chomského hierarchie jazyků, víme, že některé problémy se regexem vyřešit nedají. Ale na čištění HTML to bohatě stačí… (tak z 95 %).

Happy sourcing!

Související články

Externí odkazy

Poslední rok píšu micro-services v Golangu. Předtím jsem (sekvenčně) programoval 2 roky v JavaScriptu, 3 roky v PHP a 12 let v Javě. Paralelně k tomu jsem 8 let fungoval jako Team/Technical Leader. Píšu technologický blog SoftWare Samuraj, kde se věnuji různým aspektům z oblasti SW engineeringu.

Zatím nebyl přidán žádný komentář, buďte první!

Přidat komentář
Zdroj: https://www.zdrojak.cz/?p=23625