whtml.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. unit WHTML;
  2. interface
  3. {$ifndef FPC}
  4. {$define TPUNIXLF}
  5. {$endif}
  6. uses Objects;
  7. type
  8. PTextFile = ^TTextFile;
  9. TTextFile = object(TObject)
  10. function GetLine(Idx: sw_integer; var S: string): boolean; virtual;
  11. end;
  12. PDOSTextFile = ^TDOSTextFile;
  13. TDOSTextFile = object(TTextFile)
  14. constructor Init(AFileName: string);
  15. function GetLine(Idx: sw_integer; var S: string): boolean; virtual;
  16. destructor Done; virtual;
  17. private
  18. Lines : PUnsortedStrCollection;
  19. end;
  20. PSGMLParser = ^TSGMLParser;
  21. TSGMLParser = object(TObject)
  22. constructor Init;
  23. function Process(HTMLFile: PTextFile): boolean; virtual;
  24. function ProcessLine(LineText: string): boolean; virtual;
  25. destructor Done; virtual;
  26. public
  27. Line,LinePos: sw_integer;
  28. procedure DocSoftBreak; virtual;
  29. procedure DocAddTextChar(C: char); virtual;
  30. procedure DocAddText(S: string); virtual;
  31. procedure DocProcessTag(Tag: string); virtual;
  32. procedure DocProcessComment(Comment: string); virtual;
  33. function DocDecodeNamedEntity(Name: string; var Entity: string): boolean; virtual;
  34. private
  35. CurTag: string;
  36. InTag,InComment,InString: boolean;
  37. end;
  38. PHTMLParser = ^THTMLParser;
  39. THTMLParser = object(TSGMLParser)
  40. procedure DocSoftBreak; virtual;
  41. procedure DocAddTextChar(C: char); virtual;
  42. procedure DocProcessTag(Tag: string); virtual;
  43. function DocGetTagParam(Name: string; var Value: string): boolean; virtual;
  44. procedure DocProcessComment(Comment: string); virtual;
  45. function DocDecodeNamedEntity(Name: string; var E: string): boolean; virtual;
  46. public
  47. TagName,TagParams: string;
  48. procedure DocUnknownTag; virtual;
  49. procedure DocTYPE; virtual;
  50. procedure DocHTML(Entered: boolean); virtual;
  51. procedure DocHEAD(Entered: boolean); virtual;
  52. procedure DocMETA; virtual;
  53. procedure DocTITLE(Entered: boolean); virtual;
  54. procedure DocBODY(Entered: boolean); virtual;
  55. procedure DocAnchor(Entered: boolean); virtual;
  56. procedure DocHeading(Level: integer; Entered: boolean); virtual;
  57. procedure DocParagraph(Entered: boolean); virtual;
  58. procedure DocBreak; virtual;
  59. procedure DocImage; virtual;
  60. procedure DocBold(Entered: boolean); virtual;
  61. procedure DocCite(Entered: boolean); virtual;
  62. procedure DocCode(Entered: boolean); virtual;
  63. procedure DocEmphasized(Entered: boolean); virtual;
  64. procedure DocItalic(Entered: boolean); virtual;
  65. procedure DocKbd(Entered: boolean); virtual;
  66. procedure DocPreformatted(Entered: boolean); virtual;
  67. procedure DocSample(Entered: boolean); virtual;
  68. procedure DocStrong(Entered: boolean); virtual;
  69. procedure DocTeleType(Entered: boolean); virtual;
  70. procedure DocVariable(Entered: boolean); virtual;
  71. procedure DocList(Entered: boolean); virtual;
  72. procedure DocOrderedList(Entered: boolean); virtual;
  73. procedure DocListItem; virtual;
  74. procedure DocDefList(Entered: boolean); virtual;
  75. procedure DocDefTerm; virtual;
  76. procedure DocDefExp; virtual;
  77. procedure DocHorizontalRuler; virtual;
  78. end;
  79. implementation
  80. function UpcaseStr(S: string): string;
  81. var I: Longint;
  82. begin
  83. for I:=1 to length(S) do
  84. S[I]:=Upcase(S[I]);
  85. UpcaseStr:=S;
  86. end;
  87. function LowCase(C: char): char;
  88. begin
  89. if ('A'<=C) and (C<='Z') then C:=chr(ord(C)+32);
  90. LowCase:=C;
  91. end;
  92. function LowcaseStr(S: string): string;
  93. var I: Longint;
  94. begin
  95. for I:=1 to length(S) do
  96. S[I]:=Lowcase(S[I]);
  97. LowcaseStr:=S;
  98. end;
  99. function LTrim(S: string): string;
  100. begin
  101. while copy(S,1,1)=' ' do Delete(S,1,1);
  102. LTrim:=S;
  103. end;
  104. function RTrim(S: string): string;
  105. begin
  106. while copy(S,length(S),1)=' ' do Delete(S,length(S),1);
  107. RTrim:=S;
  108. end;
  109. function Trim(S: string): string;
  110. begin
  111. Trim:=RTrim(LTrim(S));
  112. end;
  113. function TTextFile.GetLine(Idx: sw_integer; var S: string): boolean;
  114. begin
  115. Abstract;
  116. end;
  117. constructor TDOSTextFile.Init(AFileName: string);
  118. {$ifdef TPUNIXLF}
  119. procedure readln(var t:text;var s:string);
  120. var
  121. c : char;
  122. i : longint;
  123. begin
  124. c:=#0;
  125. i:=0;
  126. while (not eof(t)) and (c<>#10) and (i<255) do
  127. begin
  128. read(t,c);
  129. if (i<255) and (c<>#10) then
  130. begin
  131. inc(i);
  132. s[i]:=c;
  133. end;
  134. end;
  135. if (i>0) and (s[i]=#13) then
  136. dec(i);
  137. s[0]:=chr(i);
  138. end;
  139. {$endif}
  140. var f: text;
  141. S: string;
  142. begin
  143. inherited Init;
  144. {$I-}
  145. Assign(f,AFileName);
  146. Reset(f);
  147. if IOResult<>0 then Fail;
  148. New(Lines, Init(500,2000));
  149. while (Eof(f)=false) and (IOResult=0) do
  150. begin
  151. readln(f,S);
  152. Lines^.Insert(NewStr(S));
  153. end;
  154. Close(f);
  155. {$I+}
  156. end;
  157. function TDOSTextFile.GetLine(Idx: sw_integer; var S: string): boolean;
  158. var OK: boolean;
  159. PS: PString;
  160. begin
  161. OK:=(Lines<>nil) and (Idx<Lines^.Count);
  162. if OK then
  163. begin
  164. PS:=Lines^.At(Idx);
  165. if PS=nil then S:='' else S:=PS^;
  166. end;
  167. GetLine:=OK;
  168. end;
  169. destructor TDOSTextFile.Done;
  170. begin
  171. inherited Done;
  172. if Lines<>nil then Dispose(Lines, Done); Lines:=nil;
  173. end;
  174. constructor TSGMLParser.Init;
  175. begin
  176. inherited Init;
  177. end;
  178. function TSGMLParser.Process(HTMLFile: PTextFile): boolean;
  179. var S: string;
  180. OK,LineOK: boolean;
  181. begin
  182. if HTMLFile=nil then Exit;
  183. InTag:=false; InComment:=false; InString:=false; CurTag:='';
  184. Line:=0; OK:=true;
  185. repeat
  186. LineOK:=HTMLFile^.GetLine(Line,S);
  187. if LineOK then
  188. begin
  189. OK:=ProcessLine(S);
  190. Inc(Line);
  191. end;
  192. until (LineOK=false) or (OK=false);
  193. Process:=OK;
  194. end;
  195. function TSGMLParser.ProcessLine(LineText: string): boolean;
  196. var OK: boolean;
  197. C: char;
  198. NewInString: boolean;
  199. OldInComment: boolean;
  200. WasThereAnyText: boolean;
  201. Pos2: integer;
  202. Name,Entity: string;
  203. LiteralCode: boolean;
  204. LiteralStart,LiteralEnd: integer;
  205. begin
  206. WasThereAnyText:=false;
  207. OK:=true; LinePos:=1;
  208. LiteralStart:=0; LiteralEnd:=0;
  209. while (LinePos<=length(LineText)) and OK do
  210. begin
  211. LiteralCode:=false;
  212. NewInString:=InString; OldInComment:=InComment;
  213. C:=LineText[LinePos];
  214. LiteralCode:=(LiteralStart<=LinePos) and (LinePos<=LiteralEnd);
  215. if (LiteralCode=false) and (C='&') then
  216. begin
  217. LiteralStart:=0; LiteralEnd:=0;
  218. Name:=''; Pos2:=LinePos+1;
  219. while (Pos2<=length(LineText)) and (LineText[Pos2]<>';') do
  220. begin
  221. Name:=Name+LineText[Pos2];
  222. Inc(Pos2);
  223. end;
  224. Inc(Pos2);
  225. if DocDecodeNamedEntity(Name,Entity) then
  226. begin
  227. LineText:=copy(LineText,1,LinePos-1)+Entity+copy(LineText,Pos2,255);
  228. LiteralStart:=LinePos; LiteralEnd:=LiteralStart+length(Entity)-1;
  229. C:=LineText[LinePos];
  230. end;
  231. end;
  232. LiteralCode:=(LiteralStart<=LinePos) and (LinePos<=LiteralEnd);
  233. if (LiteralCode=false) and (C='"') and (InTag=true) and (InString=false) then
  234. NewInString:=true;
  235. if (LiteralCode=false) and (C='<') and (InTag=false) then
  236. InTag:=true;
  237. if InTag then CurTag:=CurTag+C else
  238. begin
  239. DocAddTextChar(C);
  240. WasThereAnyText:=true;
  241. end;
  242. if (LiteralCode=false) and InTag and (InString=false) and (CurTag='<!--') then
  243. InComment:=true;
  244. if (LiteralCode=false) and InTag and InComment and (InString=false) and (length(CurTag)>=3) and
  245. (copy(CurTag,length(CurTag)-2,3)='-->') then
  246. InComment:=false;
  247. if (LiteralCode=false) and (C='"') and (InTag=true) and (InString=true) then
  248. NewInString:=false;
  249. if (LiteralCode=false) and (C='>') and (InTag=true) then
  250. begin
  251. InTag:=false;
  252. if OldInComment then
  253. DocProcessComment(CurTag)
  254. else
  255. DocProcessTag(CurTag);
  256. CurTag:='';
  257. end;
  258. InString:=NewInString;
  259. Inc(LinePos);
  260. end;
  261. if WasThereAnyText then DocSoftBreak;
  262. end;
  263. procedure TSGMLParser.DocSoftBreak;
  264. begin
  265. Abstract;
  266. end;
  267. procedure TSGMLParser.DocAddTextChar(C: char);
  268. begin
  269. Abstract;
  270. end;
  271. procedure TSGMLParser.DocAddText(S: string);
  272. var I: sw_integer;
  273. begin
  274. for I:=1 to length(S) do
  275. DocAddTextChar(S[I]);
  276. end;
  277. function TSGMLParser.DocDecodeNamedEntity(Name: string; var Entity: string): boolean;
  278. begin
  279. DocDecodeNamedEntity:=false;
  280. end;
  281. procedure TSGMLParser.DocProcessTag(Tag: string);
  282. begin
  283. Abstract;
  284. end;
  285. procedure TSGMLParser.DocProcessComment(Comment: string);
  286. begin
  287. Abstract;
  288. end;
  289. destructor TSGMLParser.Done;
  290. begin
  291. inherited Done;
  292. end;
  293. procedure THTMLParser.DocSoftBreak;
  294. begin
  295. end;
  296. procedure THTMLParser.DocAddTextChar(C: char);
  297. begin
  298. end;
  299. function THTMLParser.DocDecodeNamedEntity(Name: string; var E: string): boolean;
  300. var Found: boolean;
  301. Code: integer;
  302. CC: integer;
  303. begin
  304. Found:=true; Code:=-1;
  305. Name:=LowCaseStr(Name);
  306. if copy(Name,1,1)='#' then
  307. begin
  308. Val(copy(Name,2,255),Code,CC);
  309. if CC<>0 then Code:=-1;
  310. end;
  311. if (Name='lt') then E:='<' else { less-than sign }
  312. if (Name='gt') then E:='>' else { greater-than sign }
  313. if (Name='amp') then E:='&' else { ampersand }
  314. if (Name='quot') then E:='"' else { double quote sign }
  315. if (Code=160) or (Name='nbsp') then E:=#255 else { no-break space }
  316. if (Code=161) or (Name='iexcl') then E:='­' else { inverted excalamation mark }
  317. if (Code=162) or (Name='cent') then E:='›' else { cent sign }
  318. if (Code=163) or (Name='pound') then E:='œ' else { pound sterling sign }
  319. if (Code=164) or (Name='curren') then E:='$' else { general currency sign }
  320. if (Code=165) or (Name='yen') then E:='�' else { yen sign }
  321. if (Code=166) or (Name='brvbar') then E:='|' else { broken vertical bar }
  322. (* if (Code=167) or (Name='sect') then E:=#255 else { section sign }*)
  323. (* if (Code=168) or (Name='uml') then E:=#255 else { umlaut (dieresis) }*)
  324. if (Code=169) or (Name='copy') then E:='(C)' else { copyright sign }
  325. (* if (Code=170) or (Name='ordf') then E:=#255 else { ordinal indicator, feminine }*)
  326. if (Code=171) or (Name='laquo') then E:='"' else { angle quotation mark -left }
  327. if (Code=172) or (Name='not') then E:='!' else { not sign }
  328. if (Code=173) or (Name='shy') then E:='-' else { soft hypen }
  329. if (Code=174) or (Name='reg') then E:='(R)' else { registered sign }
  330. (* if (Code=175) or (Name='macr') then E:='?' else { macron }*)
  331. if (Code=176) or (Name='deg') then E:='ø' else { degree sign }
  332. if (Code=177) or (Name='plusmn') then E:='ñ' else { plus-or-minus sign }
  333. if (Code=178) or (Name='sup2') then E:='ý' else { superscript 2 }
  334. if (Code=179) or (Name='sup3') then E:='^3' else { superscript 3 }
  335. if (Code=180) or (Name='acute') then E:='''' else { acute accent }
  336. if (Code=181) or (Name='micro') then E:='æ' else { micro sign }
  337. (* if (Code=182) or (Name='para') then E:='?' else { paragraph sign }*)
  338. if (Code=183) or (Name='middot') then E:='ù' else { middle dot }
  339. (* if (Code=184) or (Name='cedil') then E:='?' else { cedilla }*)
  340. if (Code=185) or (Name='sup1') then E:='^1' else { superscript 1 }
  341. (* if (Code=186) or (Name='ordm') then E:='?' else { ordinal indicator, masculine }*)
  342. if (Code=187) or (Name='raquo') then E:='"' else { angle quoatation mark -right }
  343. if (Code=188) or (Name='frac14') then E:='¬' else { fraction one-quarter }
  344. if (Code=189) or (Name='frac12') then E:='«' else { fraction one-half }
  345. if (Code=190) or (Name='frac34') then E:='3/4' else { fraction three-quarters }
  346. if (Code=191) or (Name='iquest') then E:='¨' else { inverted question mark }
  347. if (Code=192) or (Name='Agrave') then E:='A' else { capital A, grave accent }
  348. if (Code=193) or (Name='Aacute') then E:='A' else { capital A, acute accent }
  349. if (Code=194) or (Name='Acirc') then E:='A' else { capital A, circumflex accent }
  350. if (Code=195) or (Name='Atilde') then E:='A' else { capital A, tilde accent }
  351. if (Code=196) or (Name='Auml') then E:='Ž' else { capital A, dieresis or umlaut }
  352. if (Code=197) or (Name='Aring') then E:='�' else { capital A, ring }
  353. if (Code=198) or (Name='AElig') then E:='AE' else { capital AE diphthong }
  354. (* if (Code=199) or (Name='Ccedil') then E:='?' else { capital C, cedilla }*)
  355. if (Code=200) or (Name='Egrave') then E:='�' else { capital E, grave accent }
  356. if (Code=201) or (Name='Eacute') then E:='�' else { capital E, acute accent }
  357. if (Code=202) or (Name='Ecirc') then E:='E' else { capital E, circumflex accent }
  358. if (Code=203) or (Name='Euml') then E:='E' else { capital E, dieresis or umlaut }
  359. if (Code=204) or (Name='Igrave') then E:='I' else { capital I, grave accent }
  360. if (Code=205) or (Name='Iacute') then E:='I' else { capital I, acute accent }
  361. if (Code=206) or (Name='Icirc') then E:='I' else { capital I, circumflex accent }
  362. if (Code=207) or (Name='Iuml') then E:='I' else { capital I, dieresis or umlaut }
  363. (* if (Code=208) or (Name='ETH') then E:='?' else { capital Eth, Icelandic }*)
  364. if (Code=209) or (Name='Ntidle') then E:='¥' else { capital N, tilde }
  365. if (Code=210) or (Name='Ograve') then E:='O' else { capital O, grave accent }
  366. if (Code=211) or (Name='Oacute') then E:='O' else { capital O, acute accent }
  367. if (Code=212) or (Name='Ocirc') then E:='O' else { capital O, circumflex accent }
  368. if (Code=213) or (Name='Otilde') then E:='O' else { capital O, tilde }
  369. if (Code=214) or (Name='Ouml') then E:='™' else { capital O, dieresis or umlaut }
  370. if (Code=215) or (Name='times') then E:='*' else { multiply sign }
  371. if (Code=216) or (Name='Oslash') then E:='O' else { capital O, slash }
  372. if (Code=217) or (Name='Ugrave') then E:='U' else { capital U, grave accent }
  373. if (Code=218) or (Name='Uacute') then E:='U' else { capital U, acute accent }
  374. if (Code=219) or (Name='Ucirc') then E:='U' else { capital U, circumflex accent }
  375. if (Code=220) or (Name='Uuml') then E:='š' else { capital U, dieresis or umlaut }
  376. if (Code=221) or (Name='Yacute') then E:='Y' else { capital Y, acute accent }
  377. (* if (Code=222) or (Name='THORN') then E:='?' else { capital THORN, Icelandic }*)
  378. if (Code=223) or (Name='szlig') then E:='á' else { small sharp S, German }
  379. if (Code=224) or (Name='agrave') then E:='…' else { small a, grave accent }
  380. if (Code=225) or (Name='aacute') then E:=' ' else { small a, acute accent }
  381. if (Code=226) or (Name='acirc') then E:='ƒ' else { small a, circumflex accent }
  382. if (Code=227) or (Name='atilde') then E:='ƒ' else { small a, tilde }
  383. if (Code=228) or (Name='auml') then E:='„' else { small a, dieresis or umlaut }
  384. if (Code=229) or (Name='aring') then E:='†' else { small a, ring }
  385. if (Code=230) or (Name='aelig') then E:='ae' else { small ae, diphthong }
  386. (* if (Code=231) or (Name='ccedil') then E:='?' else { small c, cedilla }*)
  387. if (Code=232) or (Name='egrave') then E:='Š' else { small e, grave accent }
  388. if (Code=233) or (Name='eacute') then E:='‚' else { small e, acute accent }
  389. if (Code=234) or (Name='ecirc') then E:='ˆ' else { small e, circumflex accent }
  390. if (Code=235) or (Name='euml') then E:='‰' else { small e, dieresis or umlaut }
  391. if (Code=236) or (Name='igrave') then E:='�' else { small i, grave accent }
  392. if (Code=237) or (Name='iacute') then E:='¡' else { small i, acute accent }
  393. if (Code=238) or (Name='icirc') then E:='Œ' else { small i, circumflex accent }
  394. if (Code=239) or (Name='iuml') then E:='‹' else { small i, dieresis or umlaut }
  395. (* if (Code=240) or (Name='eth') then E:='?' else { small eth, Icelandic }*)
  396. if (Code=241) or (Name='ntilde') then E:='¤' else { small n, tilde }
  397. if (Code=242) or (Name='ograve') then E:='•' else { small o, grave accent }
  398. if (Code=243) or (Name='oacute') then E:='¢' else { small o, acute accent }
  399. if (Code=244) or (Name='ocirc') then E:='“' else { small o, circumflex accent }
  400. if (Code=245) or (Name='otilde') then E:='“' else { small o, tilde }
  401. if (Code=246) or (Name='ouml') then E:='”' else { small o, dieresis or umlaut }
  402. if (Code=247) or (Name='divide') then E:='/' else { divide sign }
  403. if (Code=248) or (Name='oslash') then E:='"' else { small o, slash }
  404. if (Code=249) or (Name='ugrave') then E:='—' else { small u, grave accent }
  405. if (Code=250) or (Name='uacute') then E:='£' else { small u, acute accent }
  406. if (Code=251) or (Name='ucirc') then E:='–' else { small u, circumflex accent }
  407. if (Code=252) or (Name='uuml') then E:='�' else { small u, dieresis or umlaut }
  408. if (Code=253) or (Name='yacute') then E:='y' else { small y, acute accent }
  409. (* if (Code=254) or (Name='thorn') then E:='?' else { small thorn, Icelandic }*)
  410. if (Code=255) or (Name='yuml') then E:='y' else { small y, dieresis or umlaut }
  411. Found:=false;
  412. DocDecodeNamedEntity:=Found;
  413. end;
  414. procedure THTMLParser.DocProcessTag(Tag: string);
  415. var UTagName,ETagName: string[30];
  416. P: byte;
  417. NotEndTag: boolean;
  418. begin
  419. if copy(Tag,1,1)='<' then Delete(Tag,1,1);
  420. if copy(Tag,length(Tag),1)='>' then Delete(Tag,length(Tag),1);
  421. Tag:=Trim(Tag);
  422. P:=Pos(' ',Tag); if P=0 then P:=length(Tag)+1;
  423. TagName:=copy(Tag,1,P-1); TagParams:=copy(Tag,P+1,255);
  424. UTagName:=UpcaseStr(TagName);
  425. NotEndTag:=copy(TagName,1,1)<>'/';
  426. if NotEndTag then ETagName:=UTagName else ETagName:=copy(UTagName,2,255);
  427. if (UTagName='!DOCTYPE') then DocTYPE else
  428. { Section tags }
  429. if (ETagName='HTML') then DocHTML(NotEndTag) else
  430. if (ETagName='HEAD') then DocHEAD(NotEndTag) else
  431. if (ETagName='TITLE') then DocTITLE(NotEndTag) else
  432. if (ETagName='BODY') then DocBODY(NotEndTag) else
  433. { Anchor tags }
  434. if (ETagName='A') then DocAnchor(NotEndTag) else
  435. { Direct formatting directives }
  436. if (ETagName='H1') then DocHeading(1,NotEndTag) else
  437. if (ETagName='H2') then DocHeading(2,NotEndTag) else
  438. if (ETagName='H3') then DocHeading(3,NotEndTag) else
  439. if (ETagName='H4') then DocHeading(4,NotEndTag) else
  440. if (ETagName='H5') then DocHeading(5,NotEndTag) else
  441. if (ETagName='H6') then DocHeading(6,NotEndTag) else
  442. if (ETagName='P') then DocParagraph(NotEndTag) else
  443. if (ETagName='BR') then DocBreak else
  444. if (ETagName='B') then DocBold(NotEndTag) else
  445. if (ETagName='CITE') then DocCite(NotEndTag) else
  446. if (ETagName='CODE') then DocCode(NotEndTag) else
  447. if (ETagName='EM') then DocEmphasized(NotEndTag) else
  448. if (ETagName='I') then DocItalic(NotEndTag) else
  449. if (ETagName='KBD') then DocKbd(NotEndTag) else
  450. if (ETagName='PRE') then DocPreformatted(NotEndTag) else
  451. if (ETagName='SAMP') then DocSample(NotEndTag) else
  452. if (ETagName='STRONG') then DocStrong(NotEndTag) else
  453. if (ETagName='TT') then DocTeleType(NotEndTag) else
  454. if (ETagName='VAR') then DocVariable(NotEndTag) else
  455. { Unordered & ordered lists }
  456. if (ETagName='UL') then DocList(NotEndTag) else
  457. if (ETagName='OL') then DocOrderedList(NotEndTag) else
  458. if (UTagName='LI') then DocListItem else
  459. { Definition list }
  460. if (ETagName='DL') then DocDefList(NotEndTag) else
  461. if (UTagName='DT') then DocDefTerm else
  462. if (UTagName='DD') then DocDefExp else
  463. { Misc. tags }
  464. if (UTagName='META') then DocMETA else
  465. if (UTagName='IMG') then DocImage else
  466. if (UTagName='HR') then DocHorizontalRuler else
  467. DocUnknownTag;
  468. end;
  469. function THTMLParser.DocGetTagParam(Name: string; var Value: string): boolean;
  470. var Found: boolean;
  471. S: string;
  472. ParamName,ParamValue: string;
  473. InStr: boolean;
  474. I: sw_integer;
  475. begin
  476. Found:=false; Name:=UpcaseStr(Name);
  477. S:=TagParams;
  478. repeat
  479. InStr:=false;
  480. ParamName:=''; ParamValue:='';
  481. S:=Trim(S); I:=1;
  482. while (I<=length(S)) and (S[I]<>'=') do
  483. begin
  484. ParamName:=ParamName+S[I];
  485. Inc(I);
  486. end;
  487. ParamName:=Trim(ParamName);
  488. if S[I]='=' then
  489. begin
  490. Inc(I); InStr:=false;
  491. while (I<=length(S)) and (S[I]=' ') do
  492. Inc(I);
  493. if (I<=length(S)) and (S[I]='"') then
  494. begin
  495. InStr:=true;
  496. Inc(I);
  497. end;
  498. while (I<=length(S)) and ((InStr=true) or (S[I]<>' ')) do
  499. begin
  500. if S[I]='"' then
  501. begin
  502. InStr:=not InStr;
  503. if InStr=false then Break;
  504. end
  505. else
  506. ParamValue:=ParamValue+S[I];
  507. Inc(I);
  508. end;
  509. end;
  510. Found:=(Name=UpcaseStr(ParamName));
  511. if Found then Value:=ParamValue;
  512. Delete(S,1,I);
  513. until Found or (S='');
  514. DocGetTagParam:=Found;
  515. end;
  516. procedure THTMLParser.DocProcessComment(Comment: string);
  517. begin
  518. end;
  519. procedure THTMLParser.DocUnknownTag;
  520. begin
  521. end;
  522. procedure THTMLParser.DocTYPE;
  523. begin
  524. end;
  525. procedure THTMLParser.DocHTML(Entered: boolean);
  526. begin
  527. end;
  528. procedure THTMLParser.DocHEAD(Entered: boolean);
  529. begin
  530. end;
  531. procedure THTMLParser.DocMETA;
  532. begin
  533. end;
  534. procedure THTMLParser.DocTITLE(Entered: boolean);
  535. begin
  536. end;
  537. procedure THTMLParser.DocBODY(Entered: boolean);
  538. begin
  539. end;
  540. procedure THTMLParser.DocAnchor(Entered: boolean);
  541. begin
  542. end;
  543. procedure THTMLParser.DocHeading(Level: integer; Entered: boolean);
  544. begin
  545. end;
  546. procedure THTMLParser.DocParagraph(Entered: boolean);
  547. begin
  548. end;
  549. procedure THTMLParser.DocBreak;
  550. begin
  551. end;
  552. procedure THTMLParser.DocImage;
  553. begin
  554. end;
  555. procedure THTMLParser.DocBold(Entered: boolean);
  556. begin
  557. end;
  558. procedure THTMLParser.DocCite(Entered: boolean);
  559. begin
  560. end;
  561. procedure THTMLParser.DocCode(Entered: boolean);
  562. begin
  563. end;
  564. procedure THTMLParser.DocEmphasized(Entered: boolean);
  565. begin
  566. end;
  567. procedure THTMLParser.DocItalic(Entered: boolean);
  568. begin
  569. end;
  570. procedure THTMLParser.DocKbd(Entered: boolean);
  571. begin
  572. end;
  573. procedure THTMLParser.DocPreformatted(Entered: boolean);
  574. begin
  575. end;
  576. procedure THTMLParser.DocSample(Entered: boolean);
  577. begin
  578. end;
  579. procedure THTMLParser.DocStrong(Entered: boolean);
  580. begin
  581. end;
  582. procedure THTMLParser.DocTeleType(Entered: boolean);
  583. begin
  584. end;
  585. procedure THTMLParser.DocVariable(Entered: boolean);
  586. begin
  587. end;
  588. procedure THTMLParser.DocList(Entered: boolean);
  589. begin
  590. end;
  591. procedure THTMLParser.DocOrderedList(Entered: boolean);
  592. begin
  593. end;
  594. procedure THTMLParser.DocListItem;
  595. begin
  596. end;
  597. procedure THTMLParser.DocDefList(Entered: boolean);
  598. begin
  599. end;
  600. procedure THTMLParser.DocDefTerm;
  601. begin
  602. end;
  603. procedure THTMLParser.DocDefExp;
  604. begin
  605. end;
  606. procedure THTMLParser.DocHorizontalRuler;
  607. begin
  608. end;
  609. END.