Jak jsem vyhrál bustu Járy Cimrmana

V březnu 2014 mi přišla od @seznam_cz busta Járy Cirmana. Ta se strhanými rysy.

Cimrmanova busta se strhanými rysy

Podařilo se mi totiž do jednoho tweetu nacpat nejvíc Cimrmanových vynálezů:

Jak jsem k tomu dospěl?

Nápad

Pár odpovědí se už sešlo, ale řekl jsem si, že nebude těžké je trumfnout. Můj první nápad byl vyparsovat z wikipedie všechny vynálezy, seřadit od nejkratšího a nakopírovat do tweetu.

Hned druhý ale byl: když už mám vynálezy naparsované, proč nezkusit do tweetu nacpat celý skript?

Co skript musí splňovat

Takové malé MVP.

  • Vypsat vynálezy
  • Vejít se do 106 znaků (11 zabere handle na @seznam_cz, 23 odkaz na wiki)

Nice to have

Stanovil jsem si pár dalších cílů:

  • Nezávislost na externích knihovnách
  • Multiplatformnost
  • Plná funkčnost jen přes copy + paste

Postupná iterace k výsledku

První pokus: Nativní DOM API
Všechny skripty jsou odsazené pro lepší čitelnost. Sčítám znaky kromě mezer a newline, kde nejsou potřeba.

1
2
3
4
Array.prototype.forEach.call(
document.querySelectorAll("#mw-content-text ul:first-of-type li"),
function(element) { console.log(element.textContent)}
)

Skvělé, dělá to přesně to, co potřebuju. Jenže je to 150 znaků dlouhé. Je tu ale prostor pro zkrácení:

1
2
3
4
[].forEach.call(
$$("#bodyContent li"),
function(e){console.log(e.innerText)}
)

76 znaků. Paráda. Skript sice kvůli kratšímu selektoru vypisuje i navigaci, ale tu jsem ochotný obětovat. Zbyde mi ještě místo na nějaké to moudro.

Jenže: na uživatele kladu příliš velké nároky. Musí sám kliknout na odkaz, pak si vzpomenout, že zapomněl skript zkopírovat, překliknout se zpátky, otevřít devtools nebo firebug, … je toho moc. Na podrobný návod není prostor.

Dá se vyrobit odkaz, který rovnou spustí JavaScript? Nedá. A je to tak dobře.

curl

Multiplatformnost tady vzdávám, přesouvám se do bashe. Předpokládám, že publikum na Twitteru bude rozumět.

Budu potřebovat | pipe. wget má přepínač -O pro směřování na stdout. curl mi tyto dva znaky ušetří.

Čím parsovat HTML? Regulárním výrazem asi ne, nevešel by se do tweetu.

Externí knihovnu se mi využívat nechtělo. Ale když už jsem si odříznul Windows, můžu pokračovat: OSX má předinstalovaný xpath příkaz.

1
2
curl -L http://cs.wikipedia.org/wiki/Cimrmanovy_vynálezy |\
xpath "//div[@id='bodyContent']//li//text()"

53 znaků, spousta chyb, špatně formátovaná čeština. Wide character in print značí potíže s UTF8. Hrabat do perlového kódu xpath v jednom tweetu nezvládnu, takže iconv:

1
2
3
curl -L http://cs.wikipedia.org/wiki/Cimrmanovy_vynálezy |\
iconv -f iso8859-1|\
xpath "//div[@id='bodyContent']//ul//text()"

72 znaků. Měl bych použít i -t utf-8 pro specifikaci cílového kódování, ale na mém stroji defaultuje správně.

Ještě se zbavím značek pro začátek a konec tagu, které perl moudře vypisuje na stderr:

1
2
3
curl -L http://cs.wikipedia.org/wiki/Cimrmanovy_vynálezy |\
iconv -f iso8859-1|\
xpath "//div[@id='bodyContent']//ul//text()" 2>/dev/null

84 znaků. Kdybych použil delší selektor, nevypsala by se navigace, ale takto mám ještě rezervu na screenshot s důkazem.

Výsledek

Očekával jsem drobné pobavení, možná pár favourite, ale výhru určitě ne :)

Skript funguje jenom v OSX a copy + paste jsem taky nesplnil: Twitter za odkaz přidává trojtečku.

Upraveno 2016

Wikipedia oproti roku 2014 přesměrovává na https a navíc zvládá diakritiku v URL a nespoléhá se jen na prohlížeč. To jsou dva redirecty a několik znaků navíc. Aby vše fungovalo, přidal jsem k volání curl parametr -L.