Makrá v OpenOffice.org: prevod externých súborov do XML kódov

Július Pastierik  /  22. 12. 2010, 00:00

Potrebujete v XML súboroch previesť znaky s diakritikou na ich kódové označenie? Naprogramujte si na tento účel makro v OpenOffice.org.

Pri tvorbe rozšírení pre OpenOffice.org (ale nielen vtedy) sa stretávate s problematikou vytvárania xml súborov, ktoré musia byť vo formátovaní UTF-8 a ktoré nesmú obsahovať znaky s diakritikou, ale ich kódové označenie v tvare &#kód;. Pravdaže, s takouto požiadavkou sa môžete stretnúť aj pri tvorbe HTML dokumentov a pod.

Na tento účel si preto v prostredí OpenOffice.org vytvoríme makro, ktoré túto zmenu prevedie automaticky. Pretože pri praktickej tvorbe rozšírení sa potrebuje takto upraviť nie práve jeden, ale niekoľko súborov, makro budeme koncipovať tak, že spracuje všetky súbory s vybraného adresára.

Hoci je problematika zdanlivo jednoduchá, pristupuje tu ďalší problém – súbor je v XML tvare, t. j. znaky <> považuje za XML značky a pre označovanie kódov považuje za špeciálne znaky aj znaky &#;. Pokiaľ chceme tieto znaky použiť napr. v popise, máme dve možnosti – zadáme ich kód priamo (čo je však nepraktické), alebo si povieme, že ak ich napíšeme dvakrát za sebou (<<, >>, &&, ##,;;), budeme ich pri prevode považovať za znak, ktorého kód chceme vložiť do dokumentu.

Pretože budeme spracovávať celý adresár so všetkými súbormi, ktoré sa v ňom nachádzajú, budeme zároveň v pracovnom okne zobrazovať názov práve spracovávaného súboru. Zatvorením tohto okna zároveň budeme indikovať ukončenie spracovania.

Aby sme pri spracovaní nezničili pôvodný súbor, tento najprv zálohujeme pridaním prípony „.old“. Táto záloha má aj iný význam – pretože pri zapisovaní sa pôvodný súbor najprv vymaže, musíme ju použiť aj pre vlastné spracovávanie. A, aby sme nemuseli vždy vyhľadávať adresár pre spracovanie, budeme si posledne zadaný adresár ukladať do pracovného súboru, takže pri opätovnom spustení makra môžeme pracovať pohodlnejšie.

REM Odpamätanie pracovnej cesty do pracovného súboru "jp_xml_konverzia_set.txt"

sub uloz_cestu(sCesta as string)

 dim sf, outStream, outFile ' Pre zápis do súboru

 dim sNazov$, kde$


 kde=basiclibraries.getLibraryLinkURL("JP_XML_konverzia") ' Adresár, kde je rozšírenie nainštalované

 sNazov=left(kde,len(kde)-10)+"jp_xml_konverzia_set.txt" ' Súbor s textom

 sf = createUnoService("com.sun.star.ucb.SimpleFileAccess")

 outStream = sf.openFileWrite(sNazov)

 outFile = createUnoService("com.sun.star.io.TextOutputStream")

 outFile.OutputStream = outStream

 outFile.Encoding = "UTF-8" ' Súbor bude v UTF-8 aby bola dobrá diakritika

 outStream.truncate() ' Vymazanie predchádzajúceho obsahu

 outFile.writeString(sCesta) ' Zápis do súboru

 outStream.closeOutput ' Zatvorenie definičného súboru

 outFile.closeOutput

end sub



REM Načítanie pracovnej cesty z pracovného súboru "jp_xml_konverzia_set.txt"

function citaj_cestu as string

 dim riadok$ : riadok=""

 dim sNazov$, kde$

 dim sf, inStream, inFile ' Pre čítanie z lokalizačného súboru



 on error resume next

 

 kde=basiclibraries.getLibraryLinkURL("JP_XML_konverzia") ' Adresár, kde je rozšírenie nainštalované

 sNazov=left(kde,len(kde)-10)+"jp_xml_konverzia_set.txt" ' Súbor s textom

  

 if fileexists(sNazov) then ' Ak lokalizačný súbor existuje, tak ho načítame

  sf = createUnoService("com.sun.star.ucb.SimpleFileAccess")

  inStream = sf.openFileRead(sNazov)

  inFile = createUnoService("com.sun.star.io.TextInputStream")

  inFile.InputStream = inStream

  inFile.Encoding = "UTF-8" ' lokalizačný súbor musí byť v UTF-8, inak nebude dobrá diakritika

  if not inFile.IsEOF then riadok=inFile.readLine ' Čítanie zo súboru

  inStream.closeInput ' Zatvorenie definičného súboru

  inFile.closeInput

 end if

 citaj_cestu=riadok

end function



REM Vlastná konverzia

sub SpracujSubor(sCesta as string, sSubor as string)

 dim sZaloha$ : sZaloha=sCesta+sSubor+".old"

 dim sNazov$ : sNazov=sCesta+sSubor

 dim sRiadok$, sPom$, sZnak$

 dim sNasl$

 dim bZapisuj as boolean : bZapisuj=true

 dim sf, inStream, inFile, outStream, outFile ' Pre čítanie a zápis z/do súboru

 

 on error resume next

 

 if fileexists(sNazov) then ' Ak súbor existuje, tak ho spracujeme

  Filecopy sNazov, sZaloha ' Zálohovanie spracovávaného súboru do súboru s prílohou "old"

  sf = createUnoService("com.sun.star.ucb.SimpleFileAccess")

  

  inStream = sf.openFileRead(sZaloha) ' Vstupný súbor budeme načítavať zo zálohy

  inFile = createUnoService("com.sun.star.io.TextInputStream")

  inFile.InputStream = inStream

  inFile.Encoding = "UTF-8" ' Súbor musí byť v UTF-8, inak nebude dobre spracovaný

  

  outStream = sf.openFileWrite(sNazov) ' Výstupný súbor sa bude volať ako pôvodný súbor

  outFile = createUnoService("com.sun.star.io.TextOutputStream")

  outFile.OutputStream = outStream

  outFile.Encoding = "UTF-8" ' Súbor bude v UTF-8

  outStream.truncate() ' Vymazanie predchádzajúceho obsahu

  

  Do While not inFile.IsEOF

   sRiadok = inFile.readLine ' Vstupný riadok

   sPom="" ' Výstupný riadok je zatiaľ prázdny

   for i=1 to len(sRiadok)

    if bZapisuj then ' Ak nebol dvojitý znak, tak zapisujeme

     sZnak=mid(sRiadok,i,1)

     if instr("<>&#;",sZnak)>0 then ' Ak je špeciálny znak

      sNasl=""

      if i<len(sRiadok) then sNasl=mid(sRiadok,i+1,1) ' Ak nie sme na konci riadku, zoberieme i+1 znak

      if sNasl=sZnak then ' Sú to dva rovnaké znaky, zapíšeme ich kód a nasledujúci znak budeme ignorovať

       sPom=sPom+"&#"+trim(str(asc(sZnak)))+";"

       bZapisuj=false ' Príznak, že nasledujú znak už nemusíme spracovávať

      else ' nie je to dvojitý znak, zapisujeme ho priamo

       sPom=sPom+sZnak

      endif

     else ' Ak sú to ostatné znaky

      if asc(sZnak)<128 then ' Základné znaky sa vkladajú priamo

       sPom=sPom+sZnak

      else ' Ostatné cez kód – &#kód;

       sPom=sPom+"&#"+trim(str(asc(sZnak)))+";"

      endif

     endif

    else ' Spracovali sme druhý znak z dvojitého znaku, zrušíme príznak

     bZapisuj=true

    end if

   next i

   outFile.writeString(sPom+chr$(13))

  loop

  ' Zatvorenie súborov

  inStream.closeInput

  inFile.closeInput

  outStream.closeOutput

  outFile.closeOutput

 end if

end sub



REM Výber adresára so súbormi a ich postupné spracovanie

sub konvertuj

 dim oAdresarDialog : oAdresarDialog=CreateUnoService("com.sun.star.ui.dialogs.FolderPicker")

 dim oAdresarExistuje : oAdresarExistuje=createUnoService("com.sun.star.ucb.SimpleFileAccess")

 dim sAdresar$ : sAdresar=citaj_cestu

 dim sAdresarURL$ : sAdresarURL=ConvertToUrl(sAdresar)

 dim sSubor$

 dim oDlg

 

 if oAdresarExistuje.Exists(sAdresarURL) then oAdresarDialog.SetDisplayDirectory(sAdresarURL)

 if oAdresarDialog.Execute() then

  sAdresarURL=oAdresarDialog.GetDirectory()+"/"

  sAdresar=ConvertFromUrl(oAdresarDialog.GetDirectory())

  uloz_cestu(sAdresar)

  DialogLibraries.LoadLibrary("JP_XML_konverzia")

  oDlg=CreateUnoDialog(DialogLibraries.JP_XML_konverzia.ZobrazNazov) ' Dialóg pre zobrazovanie názvov súborov

  oDlg.setVisible(true) ' zviditeľnenie dialógu

  sSubor=dir(sAdresarURL, 0)

  While sSubor<>""

   oDlg.model.Subor.Text=sSubor ' Zobrazenie názvu súboru v dialógu

   SpracujSubor(sAdresarURL, sSubor)

   sSubor=dir()

  Wend

  oDlg.dispose() ' Zatvorenie dialógu

 endif

end sub

Neprehliadnite: