H2LRF: Hromadná konverze HTML

Motivační úvod

(Přeskočit)

Z důvodů uvedených v minulém článku, jako svůj formát pro archivaci knih jsem zvolil HTML, přestože tento formát moje čtečka nepodporuje a já pro ni musím knihy konvertovat. Hned ze začátku bylo jasné, že konverze bude muset probíhat dávkově z příkazové řádky – prostě proto, že mám neustále spuštěný FAR Manager a spuštění commandlajnového programu je v něm otázka dvou stisknutých kláves ([písmeno] a [ENTER]), zatímco v grafickém prostředí bych tak rychle ani neotevřel start menu. Cílový formát byl nutně LRF (EPUB ještě nebyl v Sony Readeru podporován a ostatní formáty jsou výrazně horší), což ovšem určilo konverzní utilitu, kterou budu používat – nic jiného než Calibrovské HTML2LRF pro konverzi HTML do LRF z příkazové řádky neznám. Jediný problém byl v tom, že pokud má výstup HTML2LRF za něco stát, vyžaduje tato utilita poměrně hodně parametrů; také jsem rychle narazil na řadu nečekaných omezení tohoto programu. A tak vznikla myšlenka na H2LRF, jakýsi „frontend“ pro HTML2LRF, který by fungoval z příkazového řádku a ušetřil mě co nejvíce myšlení, pamatování a psaní.

Při analýze, co vlastně chci dělat, vyplynuly následující požadavky:

  1. Práce z příkazové řádky. Důvod už byl vysvětlen výše.

  2. Podpora pro adresáře a pro hromadnou konverzi. HTML2LRF sám o sobě neumí hromadné konverze, zpracovává vždy jen jeden HTML soubor a veškeré snahy o hromadnost nechává na operačním systému. Což o to, to bych mohl udělat i já a psát něco jako for /r %i in (*.htm) do html2lrf "%i", ale to je docela daleko od zamýšlené „konverze na dvě klávesy“. Navíc, i kdybych to zjednodušil dávkovým souborem, pořád by zůstal problém, že i výstupy (LRF soubory) by mohly zachovávat vstupní adresářovou strukturu.

  3. Všechny údaje o knize uvnitř souboru. Jak už jsem psal výše, pokud chci kvalitní výstup, potřebuji v HTML2LRF použít řadu parametrů: potřebuji vložit název knihy a jméno autora parametry --title="Název" a --author="Jméno Příjmení", potřebuji nadefinovat vhodný regulární výraz pro detekci kapitol, chci programu říct, před jakými HTML tagy má ukončit stránku a začít novou, atd. atd. Některé z těchto parametrů jsou sice u všech knih stejné nebo aspoň podobné, ale jiné se u každé knihy liší. Bylo by prima, kdyby mohly být zapsané přímo v HTML souboru a můj konverzní frontend si je odtamtud vytáhnul.

  4. Podpora pro „dědičnost“. Jak jsem napsal v minulém bodě, některé z parametrů HTML2LRF jsou víceméně stálé. Tudíž bych rád použil princip z HTML archívu (jeden společný stylopis, který používají všechny knihy a jen si v něm upravují ty části, které upravit potřebují) i pro parametry HTML2LRF – aby existoval jeden soubor, ve kterém jsou všechny společné definice, a k němu si jednotlivé knížky přidávaly nebo upravovaly parametry podle svých potřeb. A aby to tak šlo rekurzivně až do nekonečna*) – abych jméno autora a jméno autora pro řazení zadal v jednom souboru a ten potom použily všechny knihy tohoto autora (takže až zjistím, že jsem to jméno opsal špatně, budu moci změnit jediný soubor).

    *) A to myslím doslova. Program nijak netestuje a ani testovat nebude zacyklení vkládaných souborů…

S těmito body na mysli jsem stvořil první verze programu, ale jak jsem ho začal používat, ukázalo se, že by se hodily i další funkce:

  1. Podpora pro více výstupních formátů. Když Sony vypustilo firmware s podporou EPUBu, bylo jasné, že stávající aplikaci zaměřenou na LRF bude třeba doplnit – není asi žádný rozumný důvod, proč vytvářet univerzální archív a neumožnit jeho konverzi do lepších formátů, když se tyto formáty objeví. Znamenalo to ovšem vypořádat se s tím, že Calibre se sice snaží o dodržování společné syntaxe, ale ne vždy se mu to daří – takže třeba definice kapitol je u HTML2EPUB úplně jiná než u HTML2LRF (a co hůř, když zadám LRFovský parametr do EPUBovského konvertoru, tak ten parametr nepřeskočí ale skončí s chybou).

  2. Řešení omezení jednotlivých formátů nebo konvertorů. Jakkoliv mám Calibre rád, nemohu zavírat oči nad některými jeho omezeními – například HTML2LRF nepodporovalo (a pokud vím, stále nepodporuje) direktivu @import pro vkládaní CSS stylů, což docela likviduje tu moji výchozí myšlenku, že kniha by měla odkazovat pouze svůj vlastní stylopis, ten zase svůj nadřízený stylopis, a tak dál až k nejvyššímu stylopisu. Nebo že HTML2LRF podporuje pokročilé CSS selektory (h3 + p a podobně) částečně, a to tak, že ve výsledku dopadne text úplně blbě (h3 + p je interpretováno jako „jakékoliv P následující po jakémkoliv H3“, tj. nenastyluje první odstavec v kapitole ale všechny odstavce ve všech kapitolách.

    Do toho pak ještě zasáhnou omezení jednotlivých formátů: EPUB například potřebuje mít v CSS nadefinované české fonty, naopak v LRF je velmi důležité je nedefinovat, protože by to zpomalovalo vykreslování stránek a zvětšovalo soubor knihy.

Postupně se objevují další a další nápady. Teď mě třeba velmi láká myšlenka rozšířit podporu ještě na více čtecích zařízení a například pro ně optimalizovat obrázky (k čemu mám mít v EPUBu obrázek 3000×2000 pixelů v plných barvách, když Sony Reader má zobrazitelnou plochu cca 570×760 pixelů v osmi stupních šedi a jeho implementace EPUBu dokonce takhle velký obrázek vůbec nezobrazí). Ale to je zatím hudba budoucnosti.

H2LRF

(Přeskočit návod)

H2LRF je jméno prográmku, který moje požadavky uvedené výše řeší. Spouští se z příkazové řádky minimálně v podobě h2lrf soubor.htm, zpracuje vstupní soubor a zavolá na něj HTML2LRF (nebo jiný konvertor) s příslušnými parametry. Nastavení si H2LRF bere z následujících zdrojů:

INI soubor

INI soubor se nachází ve stejném adresáři a pod stejným jménem souboru jako H2LRF sám, jen má příponu .ini (tj. pokud je H2LRF nahrán do adresáře C:\Utils pod standardním jménem, načítá inicializační soubor C:\Utils\h2lrf.ini). Tento soubor je pouze čten (předpokládá se, že obsahuje jednorázová nastavení, která se budou měnit jen zcela výjimečně, pokud vůbec), program sám do něj nic nezapisuje, celá utilita se tedy klidně může nacházet v nějakém chráněném adresáři. INI soubor obsahuje následující sekce:

  • [Config]

    Obsahuje jediný parametr DefaultTarget = výstupní formát, který programu říká, jakou výstupní formát použít, pokud nebyl na příkazové řádce zadán.

  • [výstupní formát]

    Těchto sekcí může být v souboru libovolně mnoho, jen je třeba zajistit, aby každá měla jedinečné jméno výstupního formátu. Sekce obsahuje základní nastavení pro vytváření tohoto formátu. Parametry jsou:

    • ExePath = cesta ke konvertoru – který program provádí konverzi. Obsahem by měla být plná cesta, ale není to nezbytné, pokud se konvertor nachází v PATH. Příkladem je například ExePath=D:\Progs\Calibre\html2lrf.exe.

    • Prefix = odpovídající prefix v HTML souboru – bude vysvětleno dále v popisu, jak H2LRF bere parametry přímo z HTML souboru.

    • Extension = přípona výstupního souboru včetně tečky – tady není co řešit, napíšete sem třeba .lrf pro soubory LRF nebo .epub pro soubory EPUB.

Příkazový řádek

Co by to bylo za commandlajnovou utilitu, kdyby nepřijímala nastavení z příkazové řádky. H2LRF si z ní bere parametry, které zřejmě budou při každém volání jiné – zejména jméno souboru(ů), který(é) má zpracovat, a několik dalších parametrů řídících zpracování. Parametry jsou zpracovávány postupně zleva doprava, jejich pořadí je v zásadě libovolné (ale efekt parametru se projeví až u souborů zadaných napravo od něj). Většinu parametrů nejspíš buď nepoužijete vůbec, nebo naopak vždycky, takže si je zapíšete do příslušného dávkového souboru. Všechny parametry jsou volitelné, jediná povinnost je uvést aspoň jeden soubor ke zpracování. Možné parametry jsou:

  • -r zapne rekurzivní procházení adresářů (jinými slovy, zadané soubory se hledají i ve všech podadresářích).

  • -r+ zapne rekurzivní procházení adresářů a nalezenou strukturu navíc použije i pro výstupní soubory (které jinak normálně sype všechny do jednoho adresáře).

  • -t formát vybere výstupní formát (viz konfigurační soubor). Pokud není uveden, použije se hodnota z DefaultTarget.

  • -o adresář určí, do kterého adresáře budou ukládány výstupní soubory. Pokud není uveden, ukládají se do aktuálního pracovního adresáře.

  • -e soubor určí soubor, do kterého budou ukládána chybová hlášení. V tomto případě bude konverze pokračovat i tehdy, když u některého souboru došlo k chybě (například byl použit parametr, který konvertor nezná). Pokud není uveden, vypisují se chybová hlášení normálně na standardní výstup a po první chybě konverze skončí.

    Pozn.: pokud chcete záznam průběhu do souboru, ale chcete zastavit hned po první chybě, nepoužívejte -e ale standardní přesměrování standardního výstupu do souboru h2lrf ... >zaznam.log.

  • soubor nebo maska určuje, který soubor nebo které soubory se mají konvertovat. Nejběžnější asi bude *.htm*. Toto je jediný povinný parametr, může být samozřejmě uveden i víc než jednou.

HTML soubor samotný

Ta hlavní funkčnost celého H2LRF je soustředěna v této sekci – jak jste si všimli v předchozích dvou částech, dosud se řešilo jen spouštění samotného H2LRF, ale zatím nepadlo ani slovo o parametrech pro vlastní konvertor. Tak tady se dočkáte.

H2LRF definuje speciální formát standardních HTML tagů <meta>, kterými řídí svoji práci a celou konverzi. Výhodou je, že tyto speciální tagy budou všemi specifikace-dodržujícími programy ignorovány, takže vstupní HTML soubor můžete úplně normálně používat – dokonce projde i validací (tedy za předpokladu, že jeho zbytek je validní).

K dizpozici jsou dva základní meta parametry:

  • <meta name="prefix@include" content="soubor"> celý tag smaže a na jeho místo vloží obsah souboru soubor. Tento soubor pochopitelně může obsahovat svoje vlastní <meta …> včetně dalších @include, ale i jakékoliv HTML tagy povolené v daném kontextu (takže například odkaz na další stylesheet, kterým obejdeme nepodporu HTML2LRF pro @import ve stylopisech). Jde tak udělat celý řetěz vkládání.

    Pokud je soubor relativní cesta, vztahuje se relativně k souboru, ze kterého byl bezprostředně vložen. Pokud budu ze souboru /knihy/autor/serie/prvni_dil.htm vkládat soubor ../abc.inc, značí to soubor /knihy/autor/abc.inc. Pokud v tomto souboru bude další meta @include odkazující na xyz.inc, bude vložen soubor /knihy/autor/xyz.inc, zatímco soubor ../klm.inc by byl /knihy/klm.inc (v obou případech se hledá relativně k /knihy/autor/abc.inc).

  • <meta name="prefixparametr" content="hodnota"> říká H2LRF, že má konvertoru předat na příkazové řádce text parametr=hodnota, respektive parametr, pokud je hodnota prázdná. Tohle právě zajistí, že si zdrojový HTML nese s sebou informaci, jak se vlastně má zkonvertovat do cílového formátu.

V obou případech prefix říká, pro který typ výstupního formátu se má daný META tag vyhodnocovat. Řekněme, že konverze probíhá do formátu EPUB a že v INI souboru je pro formát EPUB stanoven prefix epub:. H2LRF pak bude zpracovávat pouze ty meta tagy, které mají podobu <meta name="epub:něco" ... > respektive <meta name="*:něco" ... >, ostatní bude ignorovat (*: je tzv. univerzální prefix, který se zpracovává vždy). To vám umožní mít v jednom HTML souboru různé parametry pro různé konverzní utility. Například:

...
<meta name="*:--title" content="Jistě, pane ministře">
  (použije se pro všechny konverze)
<meta name="lrf:--header" content="">
  (tento parametr existuje pouze v HTML2LRF)
<meta name="epub:@include" content="epub.inc">
  (pokud konvertuji do EPUB, vloží se na tomto místě soubor epub.inc)
...

V atributu content mají speciální význam následující symboly:

  • %% bude nahrazen jedním znakem %

  • %e bude nahrazen prázdným řetězcem (je to proto, že atribut content nesmí být v některých verzích HTML prázdný.

  • %r znamená, že celý parametr bude zlikvidován. Je to proto, aby šlo zrušit nějaký parametr z nadřízeného souboru (řekněme, že v hlavním souboru pro všechny knihy zapnete --header, ale zrovna narazíte na tu jednu knihu, kde header mít nechcete; tak v ní prostě použijete <meta name="lrf:--header" content="%r"> a je hotovo).

  • %f bude nahrazen plnou (absolutní) cestou ke konvertovanému souboru. Hodí se to například tehdy, když máte vedle kniha.htm uložen ještě soubor kniha.htm.jpg, který chcete použít jako cover: <meta name="*:--cover" content="%f"> (tohle je zápis, který můžete dát do společného souboru pro všechny knihy).

  • %d bude nahrazen diskem, na kterém se nachází konvertovaný soubor. Nenapadá mě praktické použití, je to tu jen pro kompletnost (když už to je v příkazu FOR, tak to může být i tady).

  • %p bude nahrazen plnou (absolutní) cestou do adresáře, ve kterém se nachází konvertovaný soubor. Může se to hodit v případě, že obrázek z příkladu na %f není uložen v souboru kniha.htm.jpg ale v souboru cover.jpg: <meta name="*:--cover" content="%pcover.jpg">.

  • %n bude nahrazen pouze jménem konvertovaného souboru bez přípony. Dá se použít ve spolupráci s %p pro odkázání na cover v souboru kniha.jpg: <meta name="*:--cover" content="%p%f.jpg">.

  • %x bude nahrazen příponou konvertovaného souboru. Platí to samé co pro %d.

  • &amp; bude nahrazen znakem & (pokud se například kniha jmenuje Sword & Sorcery – jenom samotný znak & mnoho verzí HTML nepovoluje)

  • &lt; bude nahrazen znakem < (důvody stejné jako u &amp;)

  • &gt; bude nahrazen znakem > (důvody stejné jako u &amp;)

  • &quot; bude nahrazen znakem " (důvody stejné jako u &amp;)

Každopádně doporučuji vyzkoušet si, co H2LRF udělá na dodaném demo souboru (demo/demo.htm). Zkuste si vyházet některé META tagy nebo naopak nějaké přidat a sledujte, jak se mění příkazový řádek předávaný programu HTML2LRF – a co se stane, když při spouštění H2LRF použijete parametr -t epub.

verze 0.09

Verze 0.09 zavádí podporu pro Calibre 0.6 a v zásadě i jakéhokoliv jiného konverzního nástroje. Rozdíl je primárně v tom, že Calibre 0.6 mění strukturu příkazové řádky – na začátku musí být vstupní a výstupní soubor a teprve potom parametry konverze.

H2LRF na to reaguje zavedením parametru CommandLine v h2lrf, kde je uložen „vzor“ toho, jak má příkazová řádka vypadat. V podstatě to funguje tak, že konvertoru se jako parametr pošle právě tato CommandLine, ovšem s tím, že některé řetězce v ní budou nahrazeny: Z %% se stane % (aby šlo na příkazové řádce zadat procento). Místo %INPUT% se dosadí jméno vstupního souboru, místo %OUTPUT% přijde jméno výstupního souboru. Místo %PARAMS% program vloží seznam parametrů vygenerovaných z META tagů (viz výše).

Výchozím nastavením CommandLine je %PARAMS% "%INPUT%" --output="%OUTPUT%", které odpovídá požadavkům Calibre 0.4 a 0,5; pro použití Calibre 0.6 má mít CommandLine podobu "%INPUT%" "%OUTPUT%" %PARAMS%.

Kromě toho došlo k přejmenování ExePath na Converter a přibyla možnost umístit jako CommandLine tak Converter už do sekce Config (jako výchozí hodnotu pro všechny konverzní úlohy pro případ, že nejsou předefinovány v nastavení formátu).

Download

Program je určen a testován pro prostředí Windows, ale měl by fungovat na každém operačním systému, pro který lze kompilovat FreePascalem (nemám to ověřeno). Je distribuován jako freeware včetně zdrojového kódu (Delphi/FreePascal), pod podmínkou, že nebude prodáván a bude zachován odkaz na mě jakožto autora. Pokud uděláte nějaké úpravy, ocenil bych, kdybyste mi je poslali.

H2LRF v0.15 (9.3.2012, 479 KB): Podpora pro Unicode.

H2LRF v0.12 (1.8.2009, 165 KB)

H2LRF v0.08 (8.4.2009, 170 KB)

Podobné příspěvky:

16 Responses to “H2LRF: Hromadná konverze HTML”

  1. avatar pepak napsal:

    JirkaS: S Calibre (1.34) samotným by to souviset nemělo, stále ho s H2LRF používám a zcela bez problémů. Mám matnou vzpomínku, že jsem stejné varování kdysi měl taky a že byl možná problém v tom, když jsem .css soubory připojoval přímo z jiného .css pomocí @import. Teď používám systém, že kromě @import (užitečný kvůli prohlížení knih v prohlížeči) připojuji nadřazené .css soubory i pomocí normálního <link> v includovaných (<meta name="@include">) definičních souborech. Ale nejsem si stoprocentně jistý, že to opravdu řeší tvůj problém.

  2. avatar JirkaS napsal:

    Ahoj, potreboval bych radu – dlouha leta pouzivam tuhle vybornou utilitku. Nedavno jsem ale presel na novy pocitac a tam ksem si nainstaloval i novou Calibre (1.30 64b). Ted jsem zjistil, ze vsechny knizky, ktere pres utilitu udelam maji chybu v CSS. Dival jsem se do logu a bylo tam tohle:
    Flattening CSS and remapping font sizes…
    Stylesheet ‚c:/Users/xxx/My%20Books/~Cz/common.css‘ referenced by file u’zzzzzz.html‘ not in manifest
    Zkousel jsem pustit jen konverzi v Calibre a ta dopadla dobre.
    Nemas predstavu, cim by to mohlo byt?
    Dik Jirka

  3. avatar pepak napsal:

    Verze 0.15: Tak ještě jeden opravený bug v Unicode verzi – nezpracovávalo se @include.

  4. avatar pepak napsal:

    Verze 0.14: Chybně se zpracovávaly odkazy dovnitř dokumentů (se symbolem #).

  5. avatar pepak napsal:

    Verze 0.13: Podpora pro Unicode.

  6. avatar pepak napsal:

    To je v podstatě dobře – to demo bylo psané pro Calibre 0.5, kde skutečně byl parametr --author. Ten se ovšem v Calibre 0.6 změnil na --authors, takže to demo už s novým Calibre bez úprav nefunguje.

  7. avatar JirkaS napsal:

    Jeste jeden problem v demu: demo.html obsahuje meta „author“. Na to mi ebook-convert vyhodil chybu:
    ebook-convert.exe: error: ambiguous option: –author (–author-sort, –authors?).
    Po uprave hlavicky uz funguje demo dobre.

  8. avatar pepak napsal:

    Ano, dá se spustit i bez znalosti cesty. Utilitka však testuje cestu celou. Možná to není úplně šťastné řešení, ale je to tak.

  9. avatar JirkaS napsal:

    Mas pravdu, jakmile tam je cela cesta, zacne to fungovat. Nicmene ebook-convert.exe se da spustit i bez znalosti cele cesty – calibre se prida pri instalaci do cesty. Je to lepsi, protoze pokud ho preinstaluju na jine misto, nemusim resit upravu ini filu. Nicmene, zanechme zbytecne kritiky, presto diky, velmi hezka utilitka.

  10. avatar JirkaS napsal:

    Zjistil jsem, ze pokud upravim INI file tak, ze EPUB je defaultni target, zacne to fungovat. Po prohlidnuti zdrojaku si myslim, ze problem je ve funkci SetTarget, konkretne predpokladam, ze selze volani FileExists(Options.ConverterPath).

  11. avatar pepak napsal:

    Ano, mě to funguje s EPUBem.

    A tobě to bude fungovat taky, jen co Converter přepíšeš z ebook-convert.exe na c:\calibre\ebook-convert.exe (nebo něco podobného, podle toho, kde máš nainstalovaný Calibre) – v tom parametru musí být celá cesta ke konvertovacímu programu.

  12. avatar JirkaS napsal:

    Zkousim, zkousim, ale stale dostavam, ze epub is not valid …
    Ini file vypada takhle:
    [Config]
    DefaultTarget=lrf
    Converter=ebook-convert.exe
    CommandLine=“%INPUT%“ „%OUTPUT%“ %PARAMS%
    AbsoluteLocalUrlPrefix=

    [LRF]
    ;Converter=html2lrf.exe
    ;CommandLine=%PARAMS% „%INPUT%“ –output=“%OUTPUT%“
    Prefix=lrf:
    Extension=.lrf

    [EPUB]
    Converter=ebook-convert.exe
    ;CommandLine=%PARAMS% „%INPUT%“ –output=“%OUTPUT%“
    Prefix=epub:
    Extension=.epub

    Vsimni si, ze LRF nema converter, ale spusti se. Pro Epub je to jedno – at ho tam mam, nebo ne, stjne se nespusti.
    Zkusil jsem i nakopirovat html e exaci jak pises a stejne nic:

    C:\…\h2lrf>h2lrf -t EPUB .\demo\*.htm
    EPUB is not a valid target for conversion. Check your INI file.

    C:\…\h2lrf>h2lrf -t EPUB *.htm
    EPUB is not a valid target for conversion. Check your INI file.

    Jeste jsem zapomel pouzivam WinXP Pro Sp2.

    Tobe to funguje s epubem?

  13. avatar pepak napsal:

    Nejpravděpodobnější bude, že máš v sekci [EPUB] špatně nastavenou položku Converter – zřejmě neukazuje na existující soubor. Pokud používáš Calibre 0.6, měl by tam být stejný ebook-convert.exe jako u LRF.

    Calibre 0.6.24 zatím vyzkoušené nemám, momentálně jsem u 0.6.13 a ta běží dobře. Nelíbí se mi ale moc to tvoje demo\*.htm – pokud používáš výchozí archív bez jakýchkoliv změn, mělo by to být spíš ..\demo\*.htm – ujisti se, že máš tu cestu opravdu dobře (nebo ještě lépe, zkopíruj demo.htm i common.inc přímo k exáči a použij jen h2lrf -t epub *.htm.

  14. avatar JirkaS napsal:

    Tak jsem tento programek zkousel, bohuzel zatim neuspesne. Zkousim spustit: h2lrf -t epub demo\*.htm (pouzivam demo html, ciste abych vyloucil chybu mezi klavesnici a zidli).
    Vysledek je: „epub is not a valid target for conversion. Check your INI file.“
    Pritom ini file (v baleni dodavany) obsahuje sekci [EPUB], ktera vypada celkem stejne jako sekce LRF, se kterou to spustit jde.
    Dalsi problem je v Calibre. Verze 0.6.24 pokazde crashne na konci jakehokoli pokusu o zapis. Ale to je mozna zpusobene tim, ze se pokousim rozchodit vyvojarske prostredi (a moc mi to nejde).
    Chybu bych opravil, ale PAScal jsem nevidel uz fakt hodne let a ani na nej nemam zadny nastroj.

  15. avatar pepak napsal:

    Verze 0.12 – workaround pro chybnou práci s lokálními URL v ebook-convert.

  16. avatar pepak napsal:

    Verze 0.11 – jenom rychlá aktualizace, opravující jednu chybu a jeden detail.

Leave a Reply

Themocracy iconWordPress Themes

css.php