sh_xml.pp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. {
  2. $Id$
  3. "SHEdit" - Text editor with syntax highlighting
  4. Copyright (C) 1999-2000 by Sebastian Guenther ([email protected])
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. }
  11. // viewer class for XML files
  12. {$MODE objfpc}
  13. {$H+}
  14. unit sh_xml;
  15. interface
  16. uses doc_text, shedit;
  17. type
  18. TSHXMLEdit = class(TSHTextEdit)
  19. protected
  20. procedure DoHighlighting(var flags: Byte; source, dest: PChar); override;
  21. public
  22. // Syntax highlighter style indices
  23. shTag, shTagName, shDefTagName, shArgName, shString, shReference,
  24. shInvalid, shComment, shCDATA: Integer;
  25. end;
  26. implementation
  27. uses Strings;
  28. const
  29. LF_SH_Tag = LF_SH_Multiline1;
  30. LF_SH_Comment = LF_SH_Multiline2;
  31. LF_SH_String1 = LF_SH_Multiline3; // Single quotation mark
  32. LF_SH_String2 = LF_SH_Multiline4; // Double quotation mark
  33. LF_SH_CDATA = LF_SH_Multiline5;
  34. procedure TSHXMLEdit.DoHighlighting(var flags: Byte; source, dest: PChar);
  35. var
  36. dp: Integer; {Destination postion - current offset in dest}
  37. LastSHPos: Integer; {Position of last highlighting character, or 0}
  38. procedure AddSH(sh: Byte);
  39. begin
  40. if (LastSHPos > 0) and (dp = LastSHPos + 1) then Dec(dp, 2);
  41. dest[dp] := LF_Escape; Inc(dp);
  42. LastSHPos := dp;
  43. dest[dp] := Chr(sh); Inc(dp);
  44. end;
  45. procedure PutChar;
  46. begin
  47. dest[dp] := source[0]; Inc(dp); Inc(source);
  48. end;
  49. procedure ProcessComment;
  50. begin
  51. flags := flags or LF_SH_Comment;
  52. AddSH(shComment);
  53. while source[0] <> #0 do begin
  54. if (source[0] = '-') and (source[1] = '-') and (source[2] = '>') then begin
  55. PutChar; PutChar; PutChar;
  56. flags := flags and not LF_SH_Comment;
  57. AddSH(shDefault);
  58. break;
  59. end;
  60. PutChar;
  61. end;
  62. end;
  63. procedure ProcessReference;
  64. begin
  65. AddSH(shReference);
  66. while source[0] <> #0 do begin
  67. if source[0] = ';' then begin
  68. PutChar;
  69. AddSH(shDefault);
  70. break;
  71. end else if (source[0] = '''') or (source[0] = '"') then begin
  72. AddSH(shString);
  73. break;
  74. end else
  75. PutChar;
  76. end;
  77. end;
  78. procedure ProcessString(EndChar: Char);
  79. begin
  80. while source[0] <> #0 do begin
  81. if source[0] = EndChar then begin
  82. PutChar;
  83. AddSH(shDefault);
  84. flags := flags and not (LF_SH_String1 or LF_SH_String2);
  85. break;
  86. end else if source[0] = '&' then
  87. ProcessReference
  88. else
  89. PutChar;
  90. end;
  91. end;
  92. procedure ProcessTagContd;
  93. var
  94. c: Char;
  95. begin
  96. while source[0] <> #0 do begin
  97. if (source[0] in ['/', '?']) and (source[1] = '>') then begin
  98. AddSH(shTag);
  99. PutChar;
  100. PutChar;
  101. AddSH(shDefault);
  102. flags := flags and not LF_SH_Tag;
  103. break;
  104. end else if (source[0] = '>') then begin
  105. AddSH(shTag);
  106. PutChar;
  107. AddSH(shDefault);
  108. flags := flags and not LF_SH_Tag;
  109. break;
  110. end else if (source[0] = '''') or (source[0] = '"') then begin
  111. c := source[0];
  112. if source[0] = '''' then
  113. flags := flags or LF_SH_String1
  114. else
  115. flags := flags or LF_SH_String2;
  116. AddSH(shString);
  117. PutChar;
  118. ProcessString(c);
  119. end else if source[0] in [#9, ' ', '=', '(', ')', '+', '*', '?', ','] then begin
  120. AddSH(shDefault);
  121. PutChar;
  122. end else begin
  123. AddSH(shArgName);
  124. PutChar;
  125. end;
  126. end;
  127. end;
  128. procedure ProcessTag;
  129. begin
  130. flags := flags or LF_SH_Tag;
  131. AddSH(shTag);
  132. PutChar;
  133. if source[0] = '/' then PutChar;
  134. if (source[0] = '!') or (source[0] = '?') then
  135. AddSH(shDefTagName)
  136. else
  137. AddSH(shTagName);
  138. while not (source[0] in [#0, ' ', '/', '>']) do
  139. PutChar;
  140. AddSH(shDefault);
  141. ProcessTagContd;
  142. end;
  143. procedure ProcessCDATAContd;
  144. begin
  145. AddSH(shCDATA);
  146. while source[0] <> #0 do begin
  147. if (source[0] = ']') and (source[1] = ']') and
  148. (source[2] = '>') then begin
  149. AddSH(shTag);
  150. PutChar; PutChar; PutChar;
  151. AddSH(shDefault);
  152. flags := flags and not LF_SH_CDATA;
  153. break;
  154. end;
  155. PutChar;
  156. end;
  157. end;
  158. procedure ProcessCDATA;
  159. var
  160. i: Integer;
  161. begin
  162. flags := flags or LF_SH_CDATA;
  163. AddSH(shTag);
  164. for i := 1 to 9 do PutChar;
  165. ProcessCDATAContd;
  166. end;
  167. begin
  168. dp := 0;
  169. LastSHPos := 0;
  170. if (flags and LF_SH_Comment) <> 0 then begin
  171. AddSH(shComment);
  172. ProcessComment;
  173. end;
  174. if (flags and LF_SH_String1) <> 0 then begin
  175. AddSH(shString);
  176. ProcessString('''');
  177. end;
  178. if (flags and LF_SH_String2) <> 0 then begin
  179. AddSH(shString);
  180. ProcessString('"');
  181. end;
  182. if (flags and LF_SH_Tag) <> 0 then
  183. ProcessTagContd;
  184. if (flags and LF_SH_CDATA) <> 0 then
  185. ProcessCDATAContd;
  186. while source[0] <> #0 do begin
  187. case source[0] of
  188. '<':
  189. if (source[1] = '!') and (source[2] = '-') and (source[3] = '-') then
  190. ProcessComment
  191. else if (source[1] = '!') and (source[2] = '[') and (source[3] = 'C')
  192. and (source[4] = 'D') and (source[5] = 'A') and (source[6] = 'T')
  193. and (source[7] = 'A') and (source[8] = '[') then
  194. ProcessCDATA
  195. else
  196. ProcessTag;
  197. '&': ProcessReference;
  198. else
  199. PutChar;
  200. end;
  201. end;
  202. dest[dp] := #0;
  203. end;
  204. end.
  205. {
  206. $Log$
  207. Revision 1.2 2000-07-13 11:33:02 michael
  208. + removed logs
  209. }