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:
Práce z příkazové řádky. Důvod už byl vysvětlen výše.
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.
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.
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:
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).
Ř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 CSS 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 3000x2000 pixelů v plných barvách, když Sony Reader má zobrazitelnou plochu cca 570x760 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 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 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.
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.
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 znakem &
(pokud se například kniha jmenuje Sword & Sorcery - jenom samotný znak &
mnoho verzí HTML nepovoluje)
<
bude nahrazen znakem <
(důvody stejné jako u &
)
>
bude nahrazen znakem >
(důvody stejné jako u &
)
"
bude nahrazen znakem "
(důvody stejné jako u &
)
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
.
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.08 (8.4.2009, 206 KB)