1 | program PAS2HTML; |
2 | {$I-} {$B-} |
3 | |
4 | { PAS2HTML |
5 | program pro převod Pascalských zdrojových textů do (X)HTML |
6 | (c) 1996, 2009 Pavel Satrapa} |
7 | |
8 | uses Objects, Dos; |
9 | |
10 | const Verze = '1.10'; |
11 | |
12 | JmenoKlicu = 'keyws.def'; |
13 | JmenoZnaku = 'chars.def'; |
14 | |
15 | type PKlicSlovo = ^KlicSlovo; |
16 | KlicSlovo = record |
17 | Slovo : string[20]; |
18 | Dalsi : PKlicSlovo; |
19 | end; |
20 | |
21 | var JmenoZdroje, JmenoSazby : string; |
22 | Zdroj, Sazba : Text; |
23 | DomaciAdr : string; |
24 | Cislovat, {číslovat řádky?} |
25 | Komplet, {kompletní WWW stránku?} |
26 | Barvit, {barvu pozadí?} |
27 | Komentar1, {ve složených závorkách} |
28 | Komentar2 : Boolean; {v kulatých s hvězdičkou} |
29 | Kodovani : string; {jaké kódování se má vyznačit} |
30 | Radek : string; |
31 | CisloR : LongInt; |
32 | BGColor : string [6]; |
33 | Klice : array ['A'..'Z'] of PKlicSlovo; |
34 | Znaky : array [Char] of PString; |
35 | |
36 | |
37 | {*************** podpůrné podprogramy ***************} |
38 | |
39 | procedure Chyba ( Napis : string ); |
40 | {vypíše chybové hlášení} |
41 | begin |
42 | Writeln ( '!!! ERROR: ', Napis ); |
43 | end; |
44 | |
45 | function NaVelka ( Retezec : string ) : string; |
46 | {převede řetězec na velká písmena} |
47 | {!!! zneužívá toho, že parametr je předáván hodnotou !!!} |
48 | var I : Integer; |
49 | begin |
50 | for I := 1 to Length(Retezec) do |
51 | Retezec[I] := UpCase ( Retezec[I] ); |
52 | NaVelka := Retezec; |
53 | end; |
54 | |
55 | |
56 | {*************** vlastní sazba ***************} |
57 | |
58 | procedure ZpracujRadek; |
59 | {vysází jeden řádek vstupu} |
60 | var Pozice : Integer; {index zpracovávaného znaku} |
61 | |
62 | procedure PisZnak ( Znak : Char ); |
63 | {zapíše do výstupu text, odpovídající danému znaku} |
64 | begin |
65 | Write ( Sazba, Znaky[Znak]^ ); |
66 | end; |
67 | |
68 | procedure PisAPostup; |
69 | {vypíše aktuální znak řádku a popojde na další} |
70 | begin |
71 | PisZnak ( Radek[Pozice] ); |
72 | Pozice := Pozice + 1; |
73 | end; |
74 | |
75 | function PristiZnak : Char; |
76 | {vydá znak, který v řádku následuje za aktuálním} |
77 | begin |
78 | if Pozice < Length(Radek) then |
79 | PristiZnak := Radek[Pozice+1] |
80 | else |
81 | PristiZnak := Chr(0); |
82 | end; |
83 | |
84 | procedure ZpracujSlovo; |
85 | {načte slovo a vypíše jako identifikátor nebo klíč} |
86 | |
87 | function JeKlic ( Slovo : string ) : Boolean; |
88 | {je 'Slovo' v tabulce klíčových slov ?} |
89 | var Pom : PKlicSlovo; |
90 | JeToKlic : Boolean; |
91 | begin |
92 | JeToKlic := False; |
93 | Pom := Klice[Slovo[1]]; |
94 | while not JeToKlic and (Pom <> nil) do |
95 | if Slovo = Pom^.Slovo then JeToKlic := True |
96 | else Pom := Pom^.Dalsi; |
97 | JeKlic := JeToKlic; |
98 | end; |
99 | |
100 | var Slovo : string; |
101 | begin {ZpracujSlovo} |
102 | Slovo := ''; |
103 | while (Pozice <= Length(Radek)) and |
104 | (Radek[Pozice] in ['a'..'z','A'..'Z','_','0'..'9']) do |
105 | begin |
106 | Slovo := Slovo + Radek[Pozice]; |
107 | Pozice := Pozice + 1; |
108 | end; |
109 | if JeKlic ( NaVelka(Slovo) ) then |
110 | Write ( Sazba, '<b>', Slovo, '</b>' ) |
111 | else |
112 | Write ( Sazba, '<i>', Slovo, '</i>' ); |
113 | end; {ZpracujSlovo} |
114 | |
115 | procedure PreskocMezery; |
116 | {vypustí mezery ze začátku řádku} |
117 | var PocetMezer, I : Integer; |
118 | Dal : Boolean; |
119 | begin |
120 | I := 1; |
121 | Dal := I <= Length ( Radek ); |
122 | while Dal do |
123 | if Radek[I] <> ' ' then Dal := False |
124 | else |
125 | begin |
126 | I := I + 1; |
127 | Dal := I <= Length ( Radek ); |
128 | end; |
129 | PocetMezer := I - 1; |
130 | Delete ( Radek, 1, PocetMezer ); |
131 | if Cislovat then |
132 | Write ( Sazba, '<tr><td align="right"> <small>', CisloR, |
133 | '</small> </td><td>' ) |
134 | else |
135 | Write ( Sazba, '<tr><td> ' ); |
136 | if (Radek <> '') and (PocetMezer > 0) then |
137 | begin |
138 | Write ( Sazba, '<tt>' ); |
139 | for I := 1 to PocetMezer do |
140 | Write ( Sazba, ' ' ); |
141 | Write ( Sazba, '</tt>' ); |
142 | end; |
143 | end; |
144 | |
145 | procedure DokonciKomentar1; |
146 | {hledá koncovou složenou závorku, text opisuje} |
147 | var Dal : Boolean; |
148 | begin |
149 | Dal := Pozice <= Length(Radek); |
150 | while Dal do |
151 | begin |
152 | if Radek[Pozice] = '}' then |
153 | begin |
154 | Komentar1 := False; |
155 | Dal := False; |
156 | end |
157 | else Dal := Pozice < Length(Radek); |
158 | PisAPostup; |
159 | end; |
160 | end; |
161 | |
162 | procedure DokonciKomentar2; |
163 | {hledá koncové '*)', text opisuje} |
164 | var Dal : Boolean; |
165 | begin |
166 | Dal := Pozice <= Length(Radek); |
167 | while Dal do |
168 | begin |
169 | if (Radek[Pozice] = '*') and |
170 | (PristiZnak = ')') then |
171 | begin |
172 | PisAPostup; |
173 | Komentar2 := False; |
174 | Dal := False; |
175 | end |
176 | else Dal := Pozice < Length(Radek); |
177 | PisAPostup |
178 | end; |
179 | end; |
180 | |
181 | procedure DokonciRetezec; |
182 | {hledá ukončující apostrof, text opisuje} |
183 | begin |
184 | repeat |
185 | PisAPostup; |
186 | until Radek[Pozice]=''''; |
187 | PisAPostup; |
188 | end; |
189 | |
190 | begin {ZpracujRadek} |
191 | Inc ( CisloR ); |
192 | PreskocMezery; |
193 | if Radek <> '' then |
194 | begin |
195 | Pozice := 1; |
196 | if Komentar1 then DokonciKomentar1; |
197 | if Komentar2 then DokonciKomentar2; |
198 | while Pozice <= Length(Radek) do |
199 | case Radek[Pozice] of |
200 | 'a'..'z','A'..'Z','_' : ZpracujSlovo; |
201 | '''' : DokonciRetezec; |
202 | '{' : begin |
203 | Write ( Sazba, ' ' ); |
204 | PisAPostup; |
205 | Komentar1 := True; |
206 | DokonciKomentar1; |
207 | end; |
208 | '(' : if PristiZnak <> '*' then PisAPostup |
209 | else |
210 | begin |
211 | Write ( Sazba, ' ' ); |
212 | PisAPostup; PisAPostup; |
213 | Komentar2 := True; |
214 | DokonciKomentar2; |
215 | end; |
216 | else PisAPostup; |
217 | end; |
218 | end; |
219 | Writeln ( Sazba, ' </td></tr>' ); |
220 | if IOResult <> 0 then |
221 | Chyba ( 'By write to "' + JmenoSazby + '"' ); |
222 | end; {ZpracujRadek} |
223 | |
224 | |
225 | {*************** zahájení, ukončení a spol. ***************} |
226 | |
227 | procedure ZpracujParametry; |
228 | {zpracuje parametry programu} |
229 | |
230 | procedure NapovedaKonec ( Kod : Integer ); |
231 | {návodný text a ukončení programu} |
232 | begin |
233 | Writeln ( ' PAS2HTML ', Verze ); |
234 | Writeln ( '===============' ); |
235 | Writeln ( 'Program for typesetting Pascal sources in HTML.' ); |
236 | Writeln ( '(c) 1996 Pavel Satrapa' ); |
237 | Writeln; |
238 | Writeln ( 'Usage: PAS2HTML [input_file [output_file]] [options]' ); |
239 | Writeln ( ' default input is standard intput' ); |
240 | Writeln ( ' default output is standard output' ); |
241 | Writeln ( ' options are:' ); |
242 | Writeln ( ' /H print this Help text' ); |
243 | Writeln ( ' /N include line Numbers to output' ); |
244 | Writeln ( ' /C=RRGGBB bacground color' ); |
245 | Writeln ( ' /F full web page' ); |
246 | Writeln ( ' /E=encoding announce given encoding (default utf=8, valid only with /F)' ); |
247 | Halt (Kod); |
248 | end; |
249 | |
250 | procedure PriradJmeno ( Jmeno : string ); |
251 | {přiřazení jména souboru} |
252 | begin |
253 | if JmenoZdroje = '' then JmenoZdroje := Jmeno |
254 | else |
255 | if JmenoSazby = '' then JmenoSazby := Jmeno |
256 | else |
257 | begin |
258 | Chyba ( 'Too much parameters "' + Jmeno + '"' ); |
259 | NapovedaKonec (1); |
260 | end; |
261 | end; |
262 | |
263 | var I : Integer; |
264 | Param : string; |
265 | begin {ZpracujParametry} |
266 | JmenoZdroje := ''; |
267 | JmenoSazby := ''; |
268 | Cislovat := False; |
269 | Komplet := False; |
270 | Barvit := False; |
271 | Kodovani := 'utf-8'; |
272 | for I := 1 to ParamCount do |
273 | begin |
274 | Param := ParamStr(I); |
275 | if Param[1] in ['/','-'] then |
276 | case Param[2] of |
277 | 'h', 'H', '?' : NapovedaKonec (0); |
278 | 'n', 'N' : Cislovat := True; |
279 | 'f', 'F' : Komplet := True; |
280 | 'e', 'E' : Kodovani := Copy ( Param, 4, Length(Param) - 3 ); |
281 | 'c', 'C' : begin |
282 | Barvit := True; |
283 | BGColor := Copy ( Param, 4, 6 ); |
284 | end; |
285 | else |
286 | begin |
287 | Chyba ( 'Bad parameter "' + Param + '"' ); |
288 | NapovedaKonec (1); |
289 | end; |
290 | end |
291 | else |
292 | PriradJmeno ( Param ); |
293 | end; |
294 | end; {ZpracujParametry} |
295 | |
296 | procedure Inicializace; |
297 | {počáteční inicializace programu} |
298 | |
299 | procedure UrciAdresar; |
300 | {najde adresář, ve kterém se nachází program} |
301 | var |
302 | EXEJmeno: PathStr; |
303 | Jmeno : NameStr; |
304 | Pripona : ExtStr; |
305 | begin |
306 | EXEJmeno := ParamStr(0); |
307 | FSplit(EXEJmeno, DomaciAdr, Jmeno, Pripona); |
308 | { if DomaciAdr [ Length(DomaciAdr) ] <> '\' then |
309 | DomaciAdr := DomaciAdr + '\'; } |
310 | end; |
311 | |
312 | procedure NactiKlice; |
313 | {načte ze souboru klíčová slova a inicalizuje 'Klice'} |
314 | |
315 | procedure PridejKlic ( KlSlovo : string ); |
316 | {přidá 'KlSlovo' do tabulky klíčových slov} |
317 | var NovyKlic : PKlicSlovo; |
318 | begin |
319 | New ( NovyKlic ); |
320 | NovyKlic^.Slovo := KlSlovo; |
321 | NovyKlic^.Dalsi := Klice[KlSlovo[1]]; |
322 | Klice[KlSlovo[1]] := NovyKlic; |
323 | end; |
324 | |
325 | var C : Char; |
326 | KlSoub : Text; |
327 | Radek : string; |
328 | begin {NactiKlice} |
329 | for C := 'A' to 'Z' do Klice[C] := nil; |
330 | Assign ( KlSoub, DomaciAdr + JmenoKlicu ); |
331 | Reset ( KlSoub ); |
332 | if IOResult <> 0 then |
333 | Chyba ( 'Cannot open keyword file "' + JmenoKlicu + '"' ); |
334 | while not Eof(KlSoub) do |
335 | begin |
336 | Readln ( KlSoub, Radek ); |
337 | if Pos ( ' ', Radek ) <> 0 then |
338 | Delete ( radek, Pos(' ',Radek), Length(Radek) ); |
339 | if Radek <> '' then PridejKlic ( NaVelka(Radek) ); |
340 | end; |
341 | Close ( KlSoub ); |
342 | if IOResult <> 0 then |
343 | Chyba ( 'By reading keyword file "' + JmenoKlicu + '"' ); |
344 | end; {NactiKlice} |
345 | |
346 | procedure NactiZnaky; |
347 | {načte definice speciálních znaků} |
348 | var C : Char; |
349 | ZnSoub : Text; |
350 | Radek : string; |
351 | begin |
352 | for C := Chr(0) to Chr(255) do |
353 | Znaky[C] := nil; |
354 | Assign ( ZnSoub, DomaciAdr + JmenoZnaku ); |
355 | Reset ( ZnSoub ); |
356 | if IOResult <> 0 then |
357 | Chyba ( 'Cannot open char definiton file "' + JmenoZnaku + '"' ); |
358 | while not Eof(ZnSoub) do |
359 | begin |
360 | Readln ( ZnSoub, Radek ); |
361 | if Radek <> '' then |
362 | begin |
363 | C := Radek[1]; |
364 | Delete ( Radek, 1, 2 ); |
365 | Znaky[C] := NewStr ( Radek ); |
366 | end; |
367 | end; |
368 | Close ( ZnSoub ); |
369 | if IOResult <> 0 then |
370 | Chyba ( 'By reading char definiton file "' + JmenoZnaku + '"' ); |
371 | for C := Chr(0) to Chr(255) do |
372 | if Znaky[C] = nil then Znaky[C] := NewStr ( C ); |
373 | end; |
374 | |
375 | begin {Inicializace} |
376 | UrciAdresar; |
377 | NactiKlice; |
378 | NactiZnaky; |
379 | Komentar1 := False; |
380 | Komentar2 := False; |
381 | CisloR := 0; |
382 | Assign ( Zdroj, JmenoZdroje ); |
383 | Reset ( Zdroj ); |
384 | if IOResult <> 0 then |
385 | Chyba ( 'Cannot open input file "' + JmenoZdroje + '"' ); |
386 | Assign ( Sazba, JmenoSazby ); |
387 | Rewrite ( Sazba ); |
388 | if IOResult <> 0 then |
389 | Chyba ( 'Cannot open output file "' + JmenoSazby + '"' ); |
390 | if Komplet then |
391 | begin |
392 | Writeln ( Sazba, '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'); |
393 | Writeln ( Sazba, ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'); |
394 | Writeln ( Sazba, '<html xmlns="http://www.w3.org/1999/xhtml">'); |
395 | Writeln ( Sazba, '<head>'); |
396 | Writeln ( Sazba, '<meta http-equiv="content-type" content="text/html; charset=', |
397 | Kodovani, '" />'); |
398 | Writeln ( Sazba, '<title>', JmenoZdroje, '</title>'); |
399 | Writeln ( Sazba, '</head>'); |
400 | Writeln ( Sazba, '<body>'); |
401 | Writeln ( Sazba, '<h1>', JmenoZdroje, '</h1>'); |
402 | end; |
403 | Write ( Sazba, '<table border="0" cellspacing="0" cellpadding="0"' ); |
404 | if Barvit then |
405 | Write ( Sazba, ' bgcolor="#', BGColor, '"' ); |
406 | Writeln ( Sazba, '>' ); |
407 | if IOResult <> 0 then |
408 | Chyba ( 'By writing to "' + JmenoSazby + '"' ); |
409 | end; {Inicializace} |
410 | |
411 | procedure Konec; |
412 | {zakončení programu} |
413 | begin |
414 | Close ( Zdroj ); |
415 | if IOResult <> 0 then |
416 | Chyba ( 'Cannot close input "' + JmenoZdroje + '"' ); |
417 | Writeln ( Sazba, '</table>' ); |
418 | if Komplet then |
419 | begin |
420 | Writeln ( Sazba, '</body>'); |
421 | Writeln ( Sazba, '</html>'); |
422 | end; |
423 | if IOResult <> 0 then |
424 | Chyba ( 'By writing to "' + JmenoSazby + '"' ); |
425 | Close ( Sazba ); |
426 | if IOResult <> 0 then |
427 | Chyba ( 'Cannot close output "' + JmenoSazby + '"' ); |
428 | end; |
429 | |
430 | |
431 | {*************** hlavní program ***************} |
432 | |
433 | begin |
434 | ZpracujParametry; |
435 | Inicializace; |
436 | while not Eof(Zdroj) do |
437 | begin |
438 | Readln ( Zdroj, Radek ); |
439 | if IOResult <> 0 then |
440 | Chyba ( 'By reading from "' + JmenoSazby + '"' ); |
441 | ZpracujRadek; |
442 | end; |
443 | Konec; |
444 | end. |