2 * Copyright (C) 2013 FooProject
\r
3 * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
\r
4 * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
\r
6 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
\r
9 You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
13 using FooEditEngine;
\r
24 class XmlHilighter : IHilighter
\r
26 private TextParserMode mode;
\r
27 private StringBuilder word;
\r
28 private TokenType KeyWordType;
\r
30 public XmlHilighter()
\r
32 this.word = new StringBuilder();
\r
36 #region IHilighter メンバー
\r
40 this.mode = TextParserMode.TextPart;
\r
41 this.KeyWordType = TokenType.None;
\r
45 public int DoHilight(string text, int length, TokenSpilitHandeler action)
\r
47 int encloserLevel = 0;
\r
49 for (i = 0; i < length;)
\r
51 if (IsMatch(text,i,"<!--"))
\r
54 if (TransModeAndAction(TextParserMode.MultiLineComment, action, word, 4, false,ref i, wordPos))
\r
57 else if (IsMatch(text, i, "-->"))
\r
60 if (TransModeAndAction(TextParserMode.TextPart, action, word, 3, true, ref i, wordPos))
\r
63 else if (text[i] == '<' && this.mode != TextParserMode.MultiLineComment)
\r
66 if (TransModeAndAction(TextParserMode.ScriptPart, action, word, 1, true, ref i, wordPos))
\r
68 this.KeyWordType = TokenType.Keyword1;
\r
70 else if (text[i] == '>' && this.mode == TextParserMode.ScriptPart)
\r
73 if (TransModeAndAction(TextParserMode.TextPart, action, word, 1, false, ref i, wordPos))
\r
76 else if (IsMatch(text, i, "![CDATA[") && this.mode == TextParserMode.ScriptPart)
\r
79 if (TransModeAndAction(TextParserMode.Literal, action, word, 8, false, ref i, wordPos))
\r
82 else if ((text[i] == '\"' || text[i] == '\'') && this.mode == TextParserMode.ScriptPart)
\r
85 if (TransModeAndAction(TextParserMode.Literal, action, word, 1, false, ref i, wordPos))
\r
88 else if ((text[i] == '\"' || text[i] == '\'' ) && this.mode == TextParserMode.Literal)
\r
91 if (TransModeAndAction(TextParserMode.ScriptPart, action, word, 1, true, ref i, wordPos))
\r
94 else if (IsMatch(text, i, "]]") && this.mode == TextParserMode.Literal)
\r
97 if (TransModeAndAction(TextParserMode.ScriptPart, action, word, 2, true, ref i, wordPos))
\r
100 else if (text[i] == ' ')
\r
102 if (TransModeAndAction(this.mode, action, word, 1, false, ref i, wordPos))
\r
104 this.KeyWordType = TokenType.Keyword2;
\r
106 else if (text[i] == '=')
\r
108 if (TransModeAndAction(this.mode, action, word, 1, false, ref i, wordPos))
\r
110 this.KeyWordType = TokenType.None;
\r
114 if (word.Length == 0)
\r
116 word.Append(text[i]);
\r
122 if (word.Length > 0)
\r
124 action(new TokenSpilitEventArgs(wordPos,word.Length, GetMode(this.mode,KeyWordType)));
\r
128 return encloserLevel;
\r
134 /// 文字列が一致するかどうか確かめる
\r
136 /// <param name="s">検査される文字列</param>
\r
137 /// <param name="index">検査を開始するインデックス</param>
\r
138 /// <param name="pattern">検査対象の文字列</param>
\r
139 /// <returns></returns>
\r
140 private bool IsMatch(string s, int index, string pattern)
\r
142 if (index + pattern.Length >= s.Length)
\r
144 bool result = false;
\r
145 for (int i = index, j = 0; i < index + pattern.Length; i++, j++)
\r
147 if ((j == 0 || j > 0 && result) && s[i] == pattern[j])
\r
156 private bool TransModeAndAction(TextParserMode toMode, TokenSpilitHandeler action, StringBuilder word, int tokenLength, bool TranAfterAction, ref int index, int wordPos)
\r
158 TokenSpilitEventArgs e = new TokenSpilitEventArgs();
\r
160 if (word.Length > 0)
\r
163 e.length = word.Length;
\r
164 e.type = GetMode(this.mode, this.KeyWordType);
\r
171 if (TranAfterAction == false)
\r
172 this.mode = toMode;
\r
175 e.length = tokenLength;
\r
176 e.type = GetMode(this.mode, TokenType.None);
\r
181 if (TranAfterAction)
\r
182 this.mode = toMode;
\r
184 index += tokenLength;
\r
189 private TokenType GetMode(TextParserMode mode,TokenType isKeyword)
\r
193 case TextParserMode.Literal:
\r
194 return TokenType.Literal;
\r
195 case TextParserMode.ScriptPart:
\r
197 case TextParserMode.MultiLineComment:
\r
198 return TokenType.Comment;
\r
200 return TokenType.None;
\r