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

KPIMTextedit Library

  • sources
  • kde-4.14
  • kdepimlibs
  • 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 HtmlHighlighter::HtmlHighlighter( QTextDocument *document )
65  : QSyntaxHighlighter( document ), d( new HtmlHighlighterPrivate )
66 {
67 }
68 
69 HtmlHighlighter::~HtmlHighlighter()
70 {
71  delete d;
72 }
73 
74 void HtmlHighlighter::highlightBlock( const QString &text )
75 {
76  int state = previousBlockState();
77  int len = text.length();
78  int start = 0;
79  int pos = 0;
80 
81  while ( pos < len ) {
82  switch ( state ) {
83  case HtmlHighlighterPrivate::State_Text:
84  default:
85  while ( pos < len ) {
86  QChar ch = text.at( pos );
87  if ( ch == QLatin1Char( '<' ) ) {
88  if ( text.mid( pos, 4 ) == QLatin1String( "<!--" ) ) {
89  state = HtmlHighlighterPrivate::State_Comment;
90  } else {
91  if ( text.mid( pos, 9 ).toUpper() == QLatin1String( "<!DOCTYPE" ) ) {
92  state = HtmlHighlighterPrivate::State_DocType;
93  } else {
94  state = HtmlHighlighterPrivate::State_TagStart;
95  }
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  case HtmlHighlighterPrivate::State_Comment:
110  start = pos;
111  while ( pos < len ) {
112  if ( text.mid( pos, 3 ) == QLatin1String( "-->" ) ) {
113  pos += 3;
114  state = HtmlHighlighterPrivate::State_Text;
115  break;
116  } else {
117  ++pos;
118  }
119  }
120  setFormat( start, pos - start, d->colors[HtmlHighlighterPrivate::Comment] );
121  break;
122 
123  case HtmlHighlighterPrivate::State_DocType:
124  start = pos;
125  while ( pos < len ) {
126  QChar ch = text.at( pos );
127  ++pos;
128  if ( ch == QLatin1Char( '>' ) ) {
129  state = HtmlHighlighterPrivate::State_Text;
130  break;
131  }
132  }
133  setFormat( start, pos - start, d->colors[HtmlHighlighterPrivate::DocType] );
134  break;
135 
136  // at '<' in e.g. "<span>foo</span>"
137  case HtmlHighlighterPrivate::State_TagStart:
138  start = pos + 1;
139  while ( pos < len ) {
140  QChar ch = text.at( pos );
141  ++pos;
142  if ( ch == QLatin1Char( '>' ) ) {
143  state = HtmlHighlighterPrivate::State_Text;
144  break;
145  }
146  if ( !ch.isSpace() ) {
147  --pos;
148  state = HtmlHighlighterPrivate::State_TagName;
149  break;
150  }
151  }
152  break;
153 
154  // at 'b' in e.g "<blockquote>foo</blockquote>"
155  case HtmlHighlighterPrivate::State_TagName:
156  start = pos;
157  while ( pos < len ) {
158  QChar ch = text.at( pos );
159  ++pos;
160  if ( ch.isSpace() ) {
161  --pos;
162  state = HtmlHighlighterPrivate::State_InsideTag;
163  break;
164  }
165  if ( ch == QLatin1Char( '>' ) ) {
166  state = HtmlHighlighterPrivate::State_Text;
167  break;
168  }
169  }
170  setFormat( start, pos - start, d->colors[HtmlHighlighterPrivate::Tag] );
171  break;
172 
173  // anywhere after tag name and before tag closing ('>')
174  case HtmlHighlighterPrivate::State_InsideTag:
175  start = pos;
176 
177  while ( pos < len ) {
178  QChar ch = text.at( pos );
179  ++pos;
180 
181  if ( ch == QLatin1Char( '/' ) ) {
182  continue;
183  }
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 
248  if ( state == HtmlHighlighterPrivate::State_AttributeValue ) {
249  // attribute value without quote
250  // just stop at non-space or tag delimiter
251  start = pos;
252  while ( pos < len ) {
253  QChar ch = text.at( pos );
254  if ( ch.isSpace() ) {
255  break;
256  }
257  if ( ch == QLatin1Char( '>' ) || ch == QLatin1Char( '/' ) ) {
258  break;
259  }
260  ++pos;
261  }
262  state = HtmlHighlighterPrivate::State_InsideTag;
263  setFormat( start, pos - start, d->colors[HtmlHighlighterPrivate::AttributeValue] );
264  }
265 
266  break;
267 
268  // after the opening single quote in an attribute value
269  case HtmlHighlighterPrivate::State_SingleQuote:
270  start = pos;
271 
272  while ( pos < len ) {
273  QChar ch = text.at(pos);
274  ++pos;
275  if ( ch == QLatin1Char( '\'' ) ) {
276  break;
277  }
278  }
279 
280  state = HtmlHighlighterPrivate::State_InsideTag;
281 
282  setFormat( start, pos - start, d->colors[HtmlHighlighterPrivate::AttributeValue] );
283  break;
284 
285  // after the opening double quote in an attribute value
286  case HtmlHighlighterPrivate::State_DoubleQuote:
287  start = pos;
288 
289  while ( pos < len ) {
290  QChar ch = text.at(pos);
291  ++pos;
292  if ( ch == QLatin1Char( '"' ) ) {
293  break;
294  }
295  }
296 
297  state = HtmlHighlighterPrivate::State_InsideTag;
298 
299  setFormat( start, pos - start, d->colors[HtmlHighlighterPrivate::AttributeValue] );
300  break;
301 
302  }
303  }
304 
305  setCurrentBlockState( state );
306 }
307 
308 }
309 
QString::toUpper
QString toUpper() const
QChar
QSyntaxHighlighter
QChar::isSpace
bool isSpace() const
QHash< int, QColor >
QString
QColor
QLatin1Char
QString::mid
QString mid(int position, int n) const
QLatin1String
QTextDocument
QString::at
const QChar at(int position) const
QString::length
int length() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:37:23 by doxygen 1.8.7 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 API Reference

Skip menu "kdepimlibs 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

Search



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