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

Konsole

  • kde-4.14
  • applications
  • konsole
  • src
TerminalCharacterDecoder.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Konsole, an X terminal.
3 
4  Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301 USA.
20 */
21 
22 // Own
23 #include "TerminalCharacterDecoder.h"
24 
25 // Qt
26 #include <QtCore/QTextStream>
27 #include <KDebug>
28 
29 // Konsole
30 #include "konsole_wcwidth.h"
31 #include "ExtendedCharTable.h"
32 #include "ColorScheme.h"
33 
34 using namespace Konsole;
35 PlainTextDecoder::PlainTextDecoder()
36  : _output(0)
37  , _includeTrailingWhitespace(true)
38  , _recordLinePositions(false)
39 {
40 }
41 void PlainTextDecoder::setTrailingWhitespace(bool enable)
42 {
43  _includeTrailingWhitespace = enable;
44 }
45 bool PlainTextDecoder::trailingWhitespace() const
46 {
47  return _includeTrailingWhitespace;
48 }
49 void PlainTextDecoder::begin(QTextStream* output)
50 {
51  _output = output;
52  if (!_linePositions.isEmpty())
53  _linePositions.clear();
54 }
55 void PlainTextDecoder::end()
56 {
57  _output = 0;
58 }
59 
60 void PlainTextDecoder::setRecordLinePositions(bool record)
61 {
62  _recordLinePositions = record;
63 }
64 QList<int> PlainTextDecoder::linePositions() const
65 {
66  return _linePositions;
67 }
68 void PlainTextDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
69  )
70 {
71  Q_ASSERT(_output);
72 
73  if (_recordLinePositions && _output->string()) {
74  int pos = _output->string()->count();
75  _linePositions << pos;
76  }
77 
78  //TODO should we ignore or respect the LINE_WRAPPED line property?
79 
80  //note: we build up a QString and send it to the text stream rather writing into the text
81  //stream a character at a time because it is more efficient.
82  //(since QTextStream always deals with QStrings internally anyway)
83  QString plainText;
84  plainText.reserve(count);
85 
86  int outputCount = count;
87 
88  // if inclusion of trailing whitespace is disabled then find the end of the
89  // line
90  if (!_includeTrailingWhitespace) {
91  for (int i = count - 1 ; i >= 0 ; i--) {
92  if (!characters[i].isSpace())
93  break;
94  else
95  outputCount--;
96  }
97  }
98 
99  // find out the last technically real character in the line
100  int realCharacterGuard = -1;
101  for (int i = count - 1 ; i >= 0 ; i--) {
102  // FIXME: the special case of '\n' here is really ugly
103  // Maybe the '\n' should be added after calling this method in
104  // Screen::copyLineToStream()
105  if (characters[i].isRealCharacter && characters[i].character != '\n') {
106  realCharacterGuard = i;
107  break;
108  }
109  }
110 
111  for (int i = 0; i < outputCount;) {
112  if (characters[i].rendition & RE_EXTENDED_CHAR) {
113  ushort extendedCharLength = 0;
114  const ushort* chars = ExtendedCharTable::instance.lookupExtendedChar(characters[i].character, extendedCharLength);
115  if (chars) {
116  const QString s = QString::fromUtf16(chars, extendedCharLength);
117  plainText.append(s);
118  i += qMax(1, string_width(s));
119  }
120  } else {
121  // All characters which appear before the last real character are
122  // seen as real characters, even when they are technically marked as
123  // non-real.
124  //
125  // This feels tricky, but otherwise leading "whitespaces" may be
126  // lost in some situation. One typical example is copying the result
127  // of `dialog --infobox "qwe" 10 10` .
128  if (characters[i].isRealCharacter || i <= realCharacterGuard) {
129  plainText.append(QChar(characters[i].character));
130  i += qMax(1, konsole_wcwidth(characters[i].character));
131  } else {
132  ++i; // should we 'break' directly here?
133  }
134  }
135  }
136  *_output << plainText;
137 }
138 
139 HTMLDecoder::HTMLDecoder() :
140  _output(0)
141  , _colorTable(ColorScheme::defaultTable)
142  , _innerSpanOpen(false)
143  , _lastRendition(DEFAULT_RENDITION)
144 {
145 }
146 
147 void HTMLDecoder::begin(QTextStream* output)
148 {
149  _output = output;
150 
151  QString text;
152 
153  text.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n");
154  text.append("\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
155  text.append("<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n");
156  text.append("<head>\n");
157  text.append("<title>Konsole output</title>\n");
158  text.append("<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n");
159  text.append("</head>\n");
160  text.append("<body>\n");
161  text.append("<div>\n");
162 
163  //open monospace span
164  openSpan(text, "font-family:monospace");
165 
166  *output << text;
167 }
168 
169 void HTMLDecoder::end()
170 {
171  Q_ASSERT(_output);
172 
173  QString text;
174 
175  closeSpan(text);
176  text.append("</div>\n");
177  text.append("</body>\n");
178  text.append("</html>\n");
179 
180  *_output << text;
181 
182  _output = 0;
183 }
184 
185 //TODO: Support for LineProperty (mainly double width , double height)
186 void HTMLDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
187  )
188 {
189  Q_ASSERT(_output);
190 
191  QString text;
192 
193  int spaceCount = 0;
194 
195  for (int i = 0; i < count; i++) {
196  //check if appearance of character is different from previous char
197  if (characters[i].rendition != _lastRendition ||
198  characters[i].foregroundColor != _lastForeColor ||
199  characters[i].backgroundColor != _lastBackColor) {
200  if (_innerSpanOpen) {
201  closeSpan(text);
202  _innerSpanOpen = false;
203  }
204 
205  _lastRendition = characters[i].rendition;
206  _lastForeColor = characters[i].foregroundColor;
207  _lastBackColor = characters[i].backgroundColor;
208 
209  //build up style string
210  QString style;
211 
212  bool useBold;
213 
214  //colors - a color table must have been defined first
215  if (_colorTable) {
216  ColorEntry::FontWeight weight = characters[i].fontWeight(_colorTable);
217  if (weight == ColorEntry::UseCurrentFormat)
218  useBold = _lastRendition & RE_BOLD;
219  else
220  useBold = weight == ColorEntry::Bold;
221 
222  if (useBold)
223  style.append("font-weight:bold;");
224 
225  if (_lastRendition & RE_UNDERLINE)
226  style.append("font-decoration:underline;");
227 
228  style.append(QString("color:%1;").arg(_lastForeColor.color(_colorTable).name()));
229 
230  style.append(QString("background-color:%1;").arg(_lastBackColor.color(_colorTable).name()));
231  }
232 
233  //open the span with the current style
234  openSpan(text, style);
235  _innerSpanOpen = true;
236  }
237 
238  //handle whitespace
239  if (characters[i].isSpace())
240  spaceCount++;
241  else
242  spaceCount = 0;
243 
244  //output current character
245  if (spaceCount < 2) {
246  if (characters[i].rendition & RE_EXTENDED_CHAR) {
247  ushort extendedCharLength = 0;
248  const ushort* chars = ExtendedCharTable::instance.lookupExtendedChar(characters[i].character, extendedCharLength);
249  if (chars) {
250  text.append(QString::fromUtf16(chars, extendedCharLength));
251  }
252  } else {
253  //escape HTML tag characters and just display others as they are
254  const QChar ch = characters[i].character;
255  if (ch == '<')
256  text.append("&lt;");
257  else if (ch == '>')
258  text.append("&gt;");
259  else
260  text.append(ch);
261  }
262  } else {
263  // HTML truncates multiple spaces, so use a space marker instead
264  // Use &#160 instead of &nbsp so xmllint will work.
265  text.append("&#160;");
266  }
267  }
268 
269  //close any remaining open inner spans
270  if (_innerSpanOpen) {
271  closeSpan(text);
272  _innerSpanOpen = false;
273  }
274 
275  //start new line
276  text.append("<br />");
277 
278  *_output << text;
279 }
280 void HTMLDecoder::openSpan(QString& text , const QString& style)
281 {
282  text.append(QString("<span style=\"%1\">").arg(style));
283 }
284 
285 void HTMLDecoder::closeSpan(QString& text)
286 {
287  text.append("</span>");
288 }
289 
290 void HTMLDecoder::setColorTable(const ColorEntry* table)
291 {
292  _colorTable = table;
293 }
QList::clear
void clear()
Konsole::PlainTextDecoder::end
virtual void end()
End decoding.
Definition: TerminalCharacterDecoder.cpp:55
Konsole::PlainTextDecoder::setRecordLinePositions
void setRecordLinePositions(bool record)
Enables recording of character positions at which new lines are added.
Definition: TerminalCharacterDecoder.cpp:60
QString::append
QString & append(QChar ch)
ExtendedCharTable.h
Konsole::Character::character
quint16 character
The unicode character value for this character.
Definition: Character.h:108
QColor::name
QString name() const
Konsole::ExtendedCharTable::instance
static ExtendedCharTable instance
The global ExtendedCharTable instance.
Definition: ExtendedCharTable.h:68
QChar
konsole_wcwidth
int KONSOLEPRIVATE_EXPORT konsole_wcwidth(quint16 oucs)
Definition: konsole_wcwidth.cpp:129
Konsole::LineProperty
unsigned char LineProperty
Definition: Character.h:31
Konsole::RE_UNDERLINE
const int RE_UNDERLINE
Definition: Character.h:41
Konsole::PlainTextDecoder::PlainTextDecoder
PlainTextDecoder()
Definition: TerminalCharacterDecoder.cpp:35
Konsole::PlainTextDecoder::decodeLine
virtual void decodeLine(const Character *const characters, int count, LineProperty properties)
Converts a line of terminal characters with associated properties into a text string and writes the s...
Definition: TerminalCharacterDecoder.cpp:68
QTextStream
Konsole::HTMLDecoder::decodeLine
virtual void decodeLine(const Character *const characters, int count, LineProperty properties)
Converts a line of terminal characters with associated properties into a text string and writes the s...
Definition: TerminalCharacterDecoder.cpp:186
Konsole::ColorEntry::Bold
Always draw text in this color with a bold weight.
Definition: CharacterColor.h:46
Konsole::HTMLDecoder::setColorTable
void setColorTable(const ColorEntry *table)
Sets the color table which the decoder uses to produce the HTML color codes in its output...
Definition: TerminalCharacterDecoder.cpp:290
Konsole::Character
A single character in the terminal which consists of a unicode character value, foreground and backgr...
Definition: Character.h:77
konsole_wcwidth.h
Konsole::HTMLDecoder::end
virtual void end()
End decoding.
Definition: TerminalCharacterDecoder.cpp:169
Konsole::PlainTextDecoder::setTrailingWhitespace
void setTrailingWhitespace(bool enable)
Set whether trailing whitespace at the end of lines should be included in the output.
Definition: TerminalCharacterDecoder.cpp:41
QString::fromUtf16
QString fromUtf16(const ushort *unicode, int size)
Konsole::ColorEntry
An entry in a terminal display's color palette.
Definition: CharacterColor.h:40
QList::isEmpty
bool isEmpty() const
Konsole::ColorEntry::FontWeight
FontWeight
Specifies the weight to use when drawing text with this color.
Definition: CharacterColor.h:44
Konsole::ExtendedCharTable::lookupExtendedChar
ushort * lookupExtendedChar(ushort hash, ushort &length) const
Looks up and returns a pointer to a sequence of unicode characters which was added to the table using...
Definition: ExtendedCharTable.cpp:113
Konsole::CharacterColor::color
QColor color(const ColorEntry *palette) const
Returns the color within the specified color palette.
Definition: CharacterColor.h:277
Konsole::Character::backgroundColor
CharacterColor backgroundColor
The color used to draw this character's background.
Definition: Character.h:117
QString
QList< int >
Konsole::PlainTextDecoder::trailingWhitespace
bool trailingWhitespace() const
Returns whether trailing whitespace at the end of lines is included in the output.
Definition: TerminalCharacterDecoder.cpp:45
Konsole::DEFAULT_RENDITION
const int DEFAULT_RENDITION
Definition: Character.h:38
Konsole::PlainTextDecoder::linePositions
QList< int > linePositions() const
Returns of character positions in the output stream at which new lines where added.
Definition: TerminalCharacterDecoder.cpp:64
ColorScheme.h
Konsole::Character::fontWeight
ColorEntry::FontWeight fontWeight(const ColorEntry *base) const
Returns true if this character should always be drawn in bold when it is drawn with the specified pal...
Definition: Character.h:188
Konsole::PlainTextDecoder::begin
virtual void begin(QTextStream *output)
Begin decoding characters.
Definition: TerminalCharacterDecoder.cpp:49
QTextStream::string
QString * string() const
TerminalCharacterDecoder.h
QString::count
int count() const
Konsole::RE_BOLD
const int RE_BOLD
Definition: Character.h:39
QString::reserve
void reserve(int size)
Konsole::HTMLDecoder::HTMLDecoder
HTMLDecoder()
Constructs an HTML decoder using a default black-on-white color scheme.
Definition: TerminalCharacterDecoder.cpp:139
Konsole::ColorEntry::UseCurrentFormat
Use the current font weight set by the terminal application.
Definition: CharacterColor.h:53
Konsole::Character::rendition
quint8 rendition
A combination of RENDITION flags which specify options for drawing the character. ...
Definition: Character.h:111
string_width
int string_width(const QString &text)
Definition: konsole_wcwidth.cpp:217
Konsole::HTMLDecoder::begin
virtual void begin(QTextStream *output)
Begin decoding characters.
Definition: TerminalCharacterDecoder.cpp:147
Konsole::Character::foregroundColor
CharacterColor foregroundColor
The foreground color used to draw this character.
Definition: Character.h:114
Konsole::ColorScheme
Represents a color scheme for a terminal display.
Definition: ColorScheme.h:72
Konsole::RE_EXTENDED_CHAR
const int RE_EXTENDED_CHAR
Definition: Character.h:46
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat May 9 2020 03:56:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Konsole

Skip menu "Konsole"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

applications API Reference

Skip menu "applications API Reference"
  •   kate
  •       kate
  •   KTextEditor
  •   Kate
  • Konsole

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