2017-08-20
Word dokumentumból HTML - nagyban2004-02-26

Nemrég olyan feladatot kaptam, melyben több száz word dokumenumból kellett html-t készítenem. A "mentés másként" erre nem elég hatékony megoldás.


Erre a célra is csak valamilyen parancssoros utility jöhet számításba. A debian csomag neve wv, amivel a Microsoft Wordjéből nemcsak html-t, hanem "ráadásképp" abiword, latex, pdf, s sok egyéb formátumot is konvertálhatunk.

A parancs szintaxisa:

wvHtml forrásfájl.doc célfájl.html

Most hajtsuk ezt végre egy könyvtár összes állományán. Használjunk egy ciklust a shellben! Nem olyan nehéz, mint ahogy első hallásra gondolnánk. Íme egy egyszerű példa a ciklusra.

for i in *; do echo $i; done

Mit csinál a fenti sor? Az első pontosvesszőig az i-edik fájl neve bekerül az i változóba. a "do" utáni ciklusmagban erre a fájlnévre $i-ként hivatkozhatunk. A második pontosvessző utáni "done" pedig lezárja a ciklusmagot. A fenti példa tehát megjeleníti az aktuális könyvtár összes állományát. Másoljuk tehát egy könyvtárba az összes doc-fájlt, majd adjuk ki az alábbi parancsot!

for i in *; do wvHtml $i $i.html; done

A célfájl neve ekkor az eredeti fájlnév, plusz .html lesz, tehát a valami.doc mellett megtaláljuk a valami.doc.html állományt. Ha meg kívánjuk tartani az eredeti neveket, a feleslegessé vált ".doc" részt a ugyanezzel a módszerrel szedhetjük ki, a cikluson belül használjuk a sed-et!
(Természetesen előzőleg mindig töröljük a korábbi forrásfájlokat. Nem sok értelme lenne az eredeti word dokumentumok nevéből is törölni a .doc-ot!)

for i in *; do cp $i `echo $i | sed 's/.doc//g'`; done

Egy kis magyarázat:
Az úgynevezett accent grave ` jelek között parancsbehelyettesítés történik. (Backticknek is nevezik. Magyar billentyűzeten AltGr+7). A shell először ezt értelmezi, azaz

  1. az echo $i kiírja a fájlnevet a standard outputra
  2. ezt a pipe (az | jel) átirányítja a sed program bemenetére
  3. a sed a szimpla aposztófok között kapja meg a paramétereit
  4. s, azaz cserélje az első első két / között található mintát (.doc), a második két / között találhatóra, azaz semmire
  5. g, azaz mindezt ne csak egyszer, hanem a minta összes előfordulásán hajtsa végre

A két ` jel közé tehát behelyettesítődik a fájlnév .doc nélküli alakja. Az eredmény tehát a cp valami.doc.html valami.html parancs lesz.

A stream editor (sed) a kész html fájlokon belül is igen jól használható. A wordben gyakorta előforduló balos-jobbos idézőjeleket cseréljük le egy egyszerű idézőjelre. A konvertált html állományunkban a jobbos-balos idézőjelek helyén már a kódot találjuk, úgymint „ és ”

Egy füst alatt mindkettőt lecserélhetjük, ha reguláris kifejezést használunk. A bármilyen mintára illeszkedő regexp a sima pont, azaz a &.dquo; mind a balos, mind a jobbos idézőjelre illeszkedni fog.

for i in *; do cat $i | sed 's/&.dquo;/"/g' > b_$i; done

Még valami

A wvHtml a magyar ékezetes dokumentumokból - alapértelmezés szerint UTF-8 as kódolású html-t készít. Nekem ez nem felelt meg, ezért a konvertálásról is gondoskodnom kellett.

Erre a célra az iconv parancsot használhatjuk:

iconv -t UTF-8 -f ISO_8859-2 forrásfájl > célfájl

A program természetesen nem csak a példában írt kódkiosztások között tud konvertálni. A támogatott kódokról lásd a man-oldalt. Mivel a program - nagyon helyesen - a standard outputra, vagyis a monitorra küldi a kimenetet, ide egyéb trükköket tudunk beszúrni.

Fontos!
Az iconv hibaüzenetet küld, ha a dokumentum UTF-kódja ISO_8859-2 ben nem értelmezhető karaktert tartalmaz, márpedig ez viszonylag gyakran előfordul, ha például görög betűk, vagy csak a latin1-ben lévő karakterek is előfordulnak a szövegben. Ezért én inkább saját sed-fájlt használtam. (Letölthető innen). Ez természetesen csak példa, a cserélendő karakterek gyűjteménye bővíthető.

Hogyan használjuk?

for i in *; do cat $i | sed -f ~/utility/utftoascii.sed > b_$i; done

Tegyük fel, hogy ha mindennel készen vagyunk, nem érjük be azzal, hogy a csupasz html oldalakat kézhez kaptuk, hanem olyan egységes szerkezetbe kívánjuk befoglalni azokat, ahol a fejlécben saját style-sheetet, logót és egyebeket definiálhatunk. Szerencsére a wvHtml egyforma hosszú fejléceket generál, így ezeket egyszerűen levághatjuk - megintcsak egy ciklusba ágyazott sed - programmal.

for i in *; do cat $i | sed '1,17 d' > b_$i; done

Ezzel az utasítással minden állományunk elejéről levágtuk az első 17 sort, a maradék pedig a b_ kezdetű állományokba kerül. Ezekhez kellene hozzáragasztanunk a saját fejlécet. Ez az a művelet, ami "fordítva" sokkal egyszerűbb. Ha saját html-fejlécünket előkészítettük, mondjuk a ~/stuff könyvtárba, akkor ebből kell a szükséges mennyiséget sorszámozva létrehoznunk. Ehhez a következő scriptet használhatjuk.

#!/bin/sh # Egy állományból max számú másolatot hozunk létre a=0 max=111 while [ $a -le $max ] do cp header.html ~/temp/convert/$a-cikk.html a=`expr $a + 1` done

(A példát szándékosan nem tettem letölthetővé. Ezt még "csinosítanom" kell. Az egy dolog, hogy a kezdő és végső sorszámot meg lehessen adni paraméterként. Fontosabb lenne, hogy a sorbarendezés miatt a számok x számú bevezető 0-val kezdődjenek!)

A temp könyvtárban most van 111 sorszámozott példányunk a header.html nevű fájlból. Ezekhez kell hozzátoldanunk a másik könyvtárban telálható, de ugyanolyan nevű, sorszámozott fájlokat. Ismét ugyanazokat a parancsokat használjuk:

for i in *; do cat $i >> ~/temp/$i; done

Már csak a befejező szakaszt kell hozzáfűznünk a kész fájlokhoz. Ezt előre létrehoztuk, és foot.html néven elhelyeztük a ~/temp könyvtárba.

for i in *; do cat ~/temp/foot.html >> $i; done


Nos, a további lehetőségeknek csak a találékonység, a kreativitás szabhat határt. Az itt vázoltak mindössze a kiindulási pontot jelentik. Mindezt nyilván sokkal elegánsabban és egyszerűbben is meg lehet csinálni, de talán ez is elég annak bemutatására, hogy a Linux parancsértelmezőjével egy két óra alatt elvégezhetjük azt a munkát, amihez "hagyományos körülmények között" hónapok kellenének.

Sajnos az átolvasást, eseti javításokat úgysem takaríthatjuk meg. Ahhoz a WinWordben dolgozó titkárnők túl gyakran felejtenek a szövegben sorvégi kötőjelet, vagy több száz szóközzel jobbra rendezett aláírást...

status