Delphi - Pascal forráskódot HTML-re konvertáló komponens

forráskód letöltése
Ha egy forráskódot szeretnénk publikálni a weboldalunkon, akkor azt úgy is megtehetjük, hogy egyszerűen átmásoljuk a forráskódot az oldalra, majd ott megformázzuk azt. Ez egy viszonylag rövidebb forráskód esetén is meglehetősen fárasztó művelet. Illetve csak volt, mert most egy olyan komponenst mutatunk be, amely elkészíti a forráskód HTML kódját, méghozzá az általunk megadott formázási tulajdonságok figyelembevételével. Az már csak hab a tortán, hogy a rendszerünkre telepített Delphi verziók beállításait egyszerűen kiválaszthatjuk egy menüből, így a weboldalon a forráskód ugyanúgy fog kinézni, mint a Delphi szerkesztőjében! A mellékelt példaprogram megnyitása előtt a PasToHtml.pas-ban lévő komponenst telepítenie kell a Delphi alá.

A komponens property-jein keresztül ugyanúgy megadhatjuk a forráskód elemeinek formázási tulajdonságait, mint a Delphi beépített szerkesztőjénél. A megjegyzések, foglalt szavak, szimbólumok, sztringek, számok és egyéb szövegrészek mind különböző módon jelenhetnek meg. A betű színét, háttérszínét és a betű stílusát adhatjuk meg egy-egy property-n keresztül. A Source property-ben adhatjuk meg a formázni kívánt forráskódot. A HTML property-n keresztül kapjuk meg a forráskód HTML kódját, valamint a Styles property-ben szintén HTML-ben a stílusok definícióját. Ezeket bemásolva egy HTML oldal forrásába a megfelelő helyre már publikálhatjuk is a forráskódot. A példaprogram egy teljes oldalt elkészít a komponens forráskódjából.

A komponenshez létrehozunk egy-egy menüpontot a telepített Delphi verziók neveivel. A menüpontok kiválasztásakor a Registry adatbázisból lekérdezzük az adott verzió aktuális beállításait.

A HTML kód elkészítése az Execute eljárás meghívásával történik. Amikor az eljárás lefutott, a kód kiolvasható a HTML és a Styles property-kből. Maga az eljárás meglehetősen bonyolultra sikeredett, de a célnak tökéletesen megfelel.

A line változó az éppen feldolgozott sor sorszámát, a CPos a soron belüli karakterpozíciót, a CLen az aktuális sor hosszát, a CLine az aktuális sort, a HtmLine pedig az aktuális sor HTML kódját tartalmazza.

A GetCurrentWord belső függvény az éppen feldolgozott sor aktuális pozíciójától kezdve kiolvassa az ott található szót, és ezt adja vissza.

A GetCurrentNumber a fenti függvénytől csak annyiban különbözik, hogy ez az aktuális pozíciótól az ott található számot olvassa ki, majd ezt adja vissza.

A CloseStyle lezárja stílust és a Close változó értékét igazra állítja.

A SetStyle eljárás hozzáadja a paraméterként megkapott stílus a HTML kódhoz. Ha az előző stílus még nem volt lezárva, akkor meghívja a CloseStyle eljárást.

Itt kezdődik a Execute eljárás. Töröljük a HTML és a Styles property-t, majd ez utóbbiban előállítjuk a stílusok definícióinak HTML kódját.

Soronként végighaladunk a forráskódon. A CLine változóban eltároljuk az aktuális sort, a HtmLine változó értékét pedig töröljük. Ebben a változóban fogjuk tárolni a feldolgozandó sor HTML kódját.

A CLine változóban kicseréljük a "&", "<" és ">" karaktereket a nekik megfelelő HTML kódra. A CLen változóban tároljuk a feldolgozandó sor hosszát.

Karakterenként fogjuk a sort feldolgozni, az aktuális karakter sorszámát a CPos változóban tároljuk.

Ellenőrizzük, hogy a comm változó értéke nem egy üres sztring-e. Ha az, akkor nem egy megjegyzés részben vagyunk, tehát mehet a rendes feldolgozás. Ellenkező esetben a comm változó értéke a megjegyzést nyitó karakterekkel ("{" vagy "(*") egyezik meg, tehát az ennek megfelelő lezáró karaktereket kell keresni ("}" vagy "*)", lásd lejjebb).

Ellenőrizzük, hogy az aktuális pozícióban, és az utána következőben nem "/" karakter van-e. Ha az van, akkor ez egy megjegyzés, ami a sor végéig tart. A HtmLine változóban beállítjuk a megjegyzések stílusát, majd a pozíciót az utolsó karakter utánra állítjuk. Így elérjük, hogy ez a sor innentől kezdve megjegyzés, egészen a sor végéig, tehát jöhet a következő sor. A comm változó beállítására nincs szükség, mivel a megjegyzés csak a sor végéig, és biztos, hogy addig tart.
        if (CLine[CPos]='/') and (CLine[CPos+1]='/') then
        begin
          SetStyle(StyleCm);
          HtmLine:=HtmLine+Copy(CLine, CPos, CLen-CPos+1);
          CloseStyle;
          CPos:=CLen+1;
        end else
Ha az előző feltétel nem volt igaz, akkor ellenőrizzük, hogy az aktuális pozícióban nem "(*" karakterek következnek-e. Ha igen, akkor ez szintén egy megjegyzés, ami a "*)" karakterekig tart. Ezért megkeressük ezeket az aktuális sorban. Ha nem találjuk, akkor az egész sor innentől kezdve megjegyzés, tehát beállítjuk a comm változó értékét, és jöhet a következő sor. Ha megtaláltuk, akkor lezárjuk a stílust, ami egyben a comm változó törlését is jelenti. A "{" karakternél ugyanígy járunk el.

A következő a sztringek ellenőrzése lesz, tehát azt nézzük meg, hogy az aktuális karakter nem aposztróf-e. Ha az, akkor ez egy sztring lesz, tehát megkeressük a végét, amiről tudjuk, hogy az is biztosan ugyanebben a sorban lesz.

A #kód formátumban megadott karakter is sztringnek számít (pl. #32 vagy #$20 = szóköz), ezért ezeket is ugyanúgy kell megformáznunk. Ha az aktuális karakter pozícióban egy "#" karakter van, akkor a GetCurrentNumber függvénnyel beolvassuk az utána álló számot.

Innentől kezdve egy kicsit bonyolultabb dolgunk lesz, mivel foglalt szavak, számok és a szimbólumok keresése van soron. Elsőnek a foglalt szavakat ellenőrizzük, melyeket a ReservedWords konstans tömbben tárolunk. A GetCurrentWord függvénnyel lekérdezzük az aktuális pozíciótól kezdődő szót, és azt összehasonlítjuk egyenként az összes foglalt szóval. Ha megegyezik, akkor beállítjuk a stílust, és a pozíciót a szó utáni karakterre állítjuk. A foglalt szavak ellenőrzésénél figyelni kellett arra, hogy egy-egy szó, vagy foglalt szó tartalmazhat egy másikat (pl. "for" és "or"), és ez érdekes eredményt adna, ha nem kezelnénk le. Ezt a problémát a GetCurrentWord függvény megoldja.

A számok ellenőrzése viszonylag egyszerűbb, mert itt csak ellenőriznünk kell, hogy "$" jel, vagy szám-e az aktuális karakter, és ha igen, akkor meghívjuk a GetCurrentNumber függvényt, ami visszaadja nekünk ezt a számot.

A szimbólumok ellenőrzése hasonlóképpen történik a foglalt szavakéhoz, de itt egyszerűbb dolgunk van, mivel itt nem fordulhat elő olyan eset, hogy egy szimbólum tartalmaz egy másikat, illetve a végeredményben ez nem látszik meg.

Ha a fenti események közül egyik sem következett be, illetve az aktuális pozíció a sor valamelyik karakterére mutat, akkor ezt hozzáadjuk a HtmLine változóhoz.

Itt következik az a rész, ami a megjegyzések végét figyeli, és akkor hajtódik végre, amikor a comm változó értéke nem egy üres sztring. A kód viszonylag egyszerű, a fentiek megértése után nem kíván különösebb magyarázatot.

Mostanra már csak egy dolgunk van, mielőtt a sor HTML kódját tartalmazó változót (HtmLine) hozzáadnánk a HTML forráskódhoz. Ha még nincs HTML kód, akkor a nyitó elemeket is beillesztjük az első sor elejére.