• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.10.5 API Reference
  • KDE Home
  • Contact Us
 

KPIMTextedit Library

  • kpimtextedit
htmlhighlighter.cpp
1 /*
2  Copyright (c) 2012 Montel Laurent <montel@kde.org>
3 
4  based on code from qt-labs-graphics-dojo/htmleditor/highlighter.*
5 
6  This library is free software; you can redistribute it and/or modify it
7  under the terms of the GNU Library General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or (at your
9  option) any later version.
10 
11  This library is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14  License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301, USA.
20 
21 */
22 
23 #include "htmlhighlighter.h"
24 
25 namespace KPIMTextEdit {
26 
27 class HtmlHighlighterPrivate
28 {
29 public:
30  enum Construct {
31  DocType,
32  Entity,
33  Tag,
34  Comment,
35  AttributeName,
36  AttributeValue
37  };
38 
39  enum State {
40  State_Text = -1,
41  State_DocType,
42  State_Comment,
43  State_TagStart,
44  State_TagName,
45  State_InsideTag,
46  State_AttributeName,
47  State_SingleQuote,
48  State_DoubleQuote,
49  State_AttributeValue
50  };
51 
52  HtmlHighlighterPrivate()
53  {
54  colors[DocType] = QColor(192, 192, 192);
55  colors[Entity] = QColor(128, 128, 128);
56  colors[Tag] = QColor(136, 18, 128);
57  colors[Comment] = QColor( 35, 110, 37);
58  colors[AttributeName] = QColor(153, 69, 0);
59  colors[AttributeValue] = QColor( 36, 36, 170);
60  }
61  QHash<int, QColor> colors;
62 };
63 
64 
65 HtmlHighlighter::HtmlHighlighter(QTextDocument *document)
66  : QSyntaxHighlighter(document),d(new HtmlHighlighterPrivate)
67 {
68 }
69 
70 HtmlHighlighter::~HtmlHighlighter()
71 {
72  delete d;
73 }
74 
75 void HtmlHighlighter::highlightBlock(const QString &text)
76 {
77  int state = previousBlockState();
78  int len = text.length();
79  int start = 0;
80  int pos = 0;
81 
82  while (pos < len) {
83  switch (state) {
84  case HtmlHighlighterPrivate::State_Text:
85  default:
86  while (pos < len) {
87  QChar ch = text.at(pos);
88  if (ch == QLatin1Char('<')) {
89  if (text.mid(pos, 4) == QLatin1String("<!--")) {
90  state = HtmlHighlighterPrivate::State_Comment;
91  } else {
92  if (text.mid(pos, 9).toUpper() == QLatin1String("<!DOCTYPE"))
93  state = HtmlHighlighterPrivate::State_DocType;
94  else
95  state = HtmlHighlighterPrivate::State_TagStart;
96  }
97  break;
98  } else if (ch == QLatin1Char('&')) {
99  start = pos;
100  while (pos < len && text.at(pos++) != QLatin1Char(';'))
101  ;
102  setFormat(start, pos - start, d->colors[HtmlHighlighterPrivate::Entity]);
103  } else {
104  ++pos;
105  }
106  }
107  break;
108 
109 
110  case HtmlHighlighterPrivate::State_Comment:
111  start = pos;
112  while (pos < len) {
113  if (text.mid(pos, 3) == QLatin1String("-->")) {
114  pos += 3;
115  state = HtmlHighlighterPrivate::State_Text;
116  break;
117  } else {
118  ++pos;
119  }
120  }
121  setFormat(start, pos - start, d->colors[HtmlHighlighterPrivate::Comment]);
122  break;
123 
124  case HtmlHighlighterPrivate::State_DocType:
125  start = pos;
126  while (pos < len) {
127  QChar ch = text.at(pos);
128  ++pos;
129  if (ch == QLatin1Char('>')) {
130  state = HtmlHighlighterPrivate::State_Text;
131  break;
132  }
133  }
134  setFormat(start, pos - start, d->colors[HtmlHighlighterPrivate::DocType]);
135  break;
136 
137  // at '<' in e.g. "<span>foo</span>"
138  case HtmlHighlighterPrivate::State_TagStart:
139  start = pos + 1;
140  while (pos < len) {
141  QChar ch = text.at(pos);
142  ++pos;
143  if (ch == QLatin1Char('>')) {
144  state = HtmlHighlighterPrivate::State_Text;
145  break;
146  }
147  if (!ch.isSpace()) {
148  --pos;
149  state = HtmlHighlighterPrivate::State_TagName;
150  break;
151  }
152  }
153  break;
154 
155  // at 'b' in e.g "<blockquote>foo</blockquote>"
156  case HtmlHighlighterPrivate::State_TagName:
157  start = pos;
158  while (pos < len) {
159  QChar ch = text.at(pos);
160  ++pos;
161  if (ch.isSpace()) {
162  --pos;
163  state = HtmlHighlighterPrivate::State_InsideTag;
164  break;
165  }
166  if (ch == QLatin1Char('>')) {
167  state = HtmlHighlighterPrivate::State_Text;
168  break;
169  }
170  }
171  setFormat(start, pos - start, d->colors[HtmlHighlighterPrivate::Tag]);
172  break;
173 
174  // anywhere after tag name and before tag closing ('>')
175  case HtmlHighlighterPrivate::State_InsideTag:
176  start = pos;
177 
178  while (pos < len) {
179  QChar ch = text.at(pos);
180  ++pos;
181 
182  if (ch == QLatin1Char('/'))
183  continue;
184 
185  if (ch == QLatin1Char('>')) {
186  state = HtmlHighlighterPrivate::State_Text;
187  break;
188  }
189 
190  if (!ch.isSpace()) {
191  --pos;
192  state = HtmlHighlighterPrivate::State_AttributeName;
193  break;
194  }
195 
196  }
197 
198  break;
199 
200  // at 's' in e.g. <img src=bla.png/>
201  case HtmlHighlighterPrivate::State_AttributeName:
202  start = pos;
203 
204  while (pos < len) {
205  QChar ch = text.at(pos);
206  ++pos;
207 
208  if (ch == QLatin1Char('=')) {
209  state = HtmlHighlighterPrivate::State_AttributeValue;
210  break;
211  }
212 
213  if (ch == QLatin1Char('>') || ch == QLatin1Char('/')) {
214  state = HtmlHighlighterPrivate::State_InsideTag;
215  break;
216  }
217  }
218 
219  setFormat(start, pos - start, d->colors[HtmlHighlighterPrivate::AttributeName]);
220  break;
221 
222  // after '=' in e.g. <img src=bla.png/>
223  case HtmlHighlighterPrivate::State_AttributeValue:
224  start = pos;
225 
226  // find first non-space character
227  while (pos < len) {
228  QChar ch = text.at(pos);
229  ++pos;
230 
231  // handle opening single quote
232  if (ch == QLatin1Char('\'')) {
233  state = HtmlHighlighterPrivate::State_SingleQuote;
234  break;
235  }
236 
237  // handle opening double quote
238  if (ch == QLatin1Char('"')) {
239  state = HtmlHighlighterPrivate::State_DoubleQuote;
240  break;
241  }
242 
243  if (!ch.isSpace())
244  break;
245  }
246 
247  if (state == HtmlHighlighterPrivate::State_AttributeValue) {
248  // attribute value without quote
249  // just stop at non-space or tag delimiter
250  start = pos;
251  while (pos < len) {
252  QChar ch = text.at(pos);
253  if (ch.isSpace())
254  break;
255  if (ch == QLatin1Char('>') || ch == QLatin1Char('/'))
256  break;
257  ++pos;
258  }
259  state = HtmlHighlighterPrivate::State_InsideTag;
260  setFormat(start, pos - start, d->colors[HtmlHighlighterPrivate::AttributeValue]);
261  }
262 
263  break;
264 
265  // after the opening single quote in an attribute value
266  case HtmlHighlighterPrivate::State_SingleQuote:
267  start = pos;
268 
269  while (pos < len) {
270  QChar ch = text.at(pos);
271  ++pos;
272  if (ch == QLatin1Char('\''))
273  break;
274  }
275 
276  state = HtmlHighlighterPrivate::State_InsideTag;
277 
278  setFormat(start, pos - start, d->colors[HtmlHighlighterPrivate::AttributeValue]);
279  break;
280 
281  // after the opening double quote in an attribute value
282  case HtmlHighlighterPrivate::State_DoubleQuote:
283  start = pos;
284 
285  while (pos < len) {
286  QChar ch = text.at(pos);
287  ++pos;
288  if (ch == QLatin1Char('"'))
289  break;
290  }
291 
292  state = HtmlHighlighterPrivate::State_InsideTag;
293 
294  setFormat(start, pos - start, d->colors[HtmlHighlighterPrivate::AttributeValue]);
295  break;
296 
297  }
298  }
299 
300  setCurrentBlockState(state);
301 }
302 
303 }
304 #include "moc_htmlhighlighter.cpp"
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jul 13 2013 01:26:01 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KPIMTextedit Library

Skip menu "KPIMTextedit Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.10.5 API Reference

Skip menu "kdepimlibs-4.10.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal