libzypp 17.37.17
richtext.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------/
9*
10* This file contains private API, this might break at any time between releases.
11* Strictly for internal use!
12*/
13#include <sstream>
14#include <map>
15#include <vector>
16#include <string>
17
20
21namespace ztui {
22
23using std::endl;
24using namespace zypp;
25
51
52std::map<std::string,tags> _rtTagmap;
53
54bool pre;
57
59{
60 _rtTagmap["p"] = PARAGRAPH;
61 _rtTagmap["a"] = ANCHOR;
62 _rtTagmap["b"] = BOLD;
63 _rtTagmap["u"] = UNDERLINED;
64 _rtTagmap["i"] = ITALIC;
65 _rtTagmap["br"] = BREAK_LINE;
66 _rtTagmap["em"] = EM;
67 _rtTagmap["h1"] = HEADER1;
68 _rtTagmap["h2"] = HEADER2;
69 _rtTagmap["h3"] = HEADER3;
70 _rtTagmap["hr"] = HR;
71 _rtTagmap["li"] = LI;
72 _rtTagmap["ol"] = OL;
73 _rtTagmap["ul"] = UL;
74 _rtTagmap["qt"] = QT;
75 _rtTagmap["tt"] = TT;
76 _rtTagmap["big"] = BIG;
77 _rtTagmap["pre"] = PRE;
78 _rtTagmap["bold"] = BOLD;
79 _rtTagmap["code"] = CODE;
80 _rtTagmap["font"] = UNKNOWN; //not parsed in parser
81 _rtTagmap["large"] = UNKNOWN; //same as ncurses
82 _rtTagmap["small"] = UNKNOWN; // same as necurses
83 _rtTagmap["center"] = CENTER;
84 _rtTagmap["strong"] = BOLD; // same as necurses
85 _rtTagmap["blockquote"] = BLOCKQUOTE; // same as necurses
86
87}
88
89std::string closeTag( std::vector<tags>& tagStack )
90{
91 if( tagStack.empty() )
92 {
93 WAR << "closing tag before any opening" << endl;;
94 return "";
95 }
96 tags t = tagStack.back();
97 tagStack.pop_back();
98 switch ( t )
99 {
100 case PARAGRAPH:
101 return "\n\n";
102 case LI:
103 return "\n";
104 case PRE:
105 pre = false; //fall thrue
106 default:
107 return "";
108 }
109}
110
111std::string openTag( std::vector<tags>& tagStack, std::string & tag )
112{
113 tag = str::trim(tag);
114 std::map<std::string,tags>::const_iterator it = _rtTagmap.find( tag );
115 tags t;
116 if ( it == _rtTagmap.end() )
117 {
118 if ( tag.size() > 3 && tag[0] == '!' && tag[1] == '-' && tag[2] == '-' )
119 return ""; //comment
120 WAR << "unknown rich text tag " << tag << endl;
121 t = UNKNOWN;
122 }
123 else
124 {
125 t = it->second;
126 }
127 tagStack.push_back( t );
128 switch ( t )
129 {
130 case HR:
131 tagStack.pop_back(); //hr haven't closing tag
132 return "--------------------";
133
134 case PARAGRAPH:
135 return "";
136 case BREAK_LINE:
137 tagStack.pop_back(); //br haven't closing tag
138 return "\n";
139 case OL:
140 ordered = true;
142 return "\n";
143 case UL:
144 ordered = false;
145 return "\n";
146 case LI:
147 if ( ordered )
148 {
149 std::ostringstream res;
150 res << ++count_list_items << ") ";
151 return res.str();
152 }
153 else
154 {
155 return "- ";
156 }
157 case PRE:
158 pre = true; //fall thrue
159 default:
160 return "";
161 }
162}
163
164std::map<std::string,std::string> ampersmap;
165
167{
168 ampersmap["gt"] =">";
169 ampersmap["lt"] ="<";
170 ampersmap["amp"] ="&";
171 ampersmap["quot"] ="\"";
172 ampersmap["nbsp"] =" "; //TODO REAL NBSP
173 ampersmap["product"] ="product"; //TODO replace with real name
174}
175
176std::string getStringFromAmpr( const std::string & str )
177{
178 if ( ampersmap.empty() )
180
181 std::string::size_type end = str.find( ';' );
182 DBG << "val ampr is: " << str << endl;
183 if ( str[0] == '#' ) //first is value
184 {
185 int res = 0;
186 std::istringstream sstr( str.substr( 1, end ) );
187 sstr >> res;
188 DBG << res << endl;
189 if ( res != 0 )
190 {
191 return std::string( 1,(char)res ); //return char
192 }
193 else
194 {
195 WAR << "unknown number " << str << endl;
196 return "";
197 }
198 }
199
200 DBG << end << " " << str.substr( 0, end ) << endl;
201 return ampersmap[str.substr( 0, end )];
202
203}
204
205std::string processRichText( const std::string& text )
206{
207 if ( _rtTagmap.empty() )
208 fillTagmap();
209 //state machine vars
210 pre = false;
211
212 std::vector<tags> tagStack;
213
214 std::string res;
215 res.reserve( text.size() );
216 std::string::size_type pos = 0;
217 do {
218 switch( text[pos] )
219 {
220 case ' ':
221 case '\n':
222 case '\t':
223 case '\v':
224 case '\r':
225 if ( pre )
226 res.push_back( text[pos] );
227 else
228 {
229 if ( text[pos] == ' ' )
230 res.push_back( ' ' );
231 }
232 break;
233 case '<':
234 if ( pos+1 == text.npos )
235 {
236 WAR << "ended with nonclosed tag."<< endl;
237 return res; //chyba, tohle by se nemelo stavat
238 }
239 if ( text[pos+1] == '/' ) //close tag
240 {
241 pos = text.find( '>', pos );
242 res.append( closeTag( tagStack ) );
243 }
244 else
245 {
246 std::string::size_type tagEndPos = text.find( '>', pos );
247 if ( tagEndPos == text.npos )
248 {
249 WAR << "ended with non-closed tag " << endl;
250 return res;
251 }
252 std::string tagname( text.substr( pos+1, tagEndPos-pos-1 ) );
253 pos = tagEndPos;
254 res.append( openTag( tagStack, tagname ) );
255 }
256 break;
257 case '&':
258 {
259 std::string::size_type semipos = text.find( ';', pos );
260 std::string tmp = getStringFromAmpr( text.substr( pos+1, pos-semipos-1 ) );
261 DBG << "tmp is: " << tmp << endl;
262 res.append( tmp );
263 pos = semipos;
264 break;
265 }
266 default:
267 res.push_back( text[pos] );
268 }
269
270 ++pos;
271 } while ( pos != text.size() );
272 return res;
273}
274
275}
String related utilities and Regular expression matching.
void fillAmpersmap()
Definition richtext.cc:166
bool ordered
Definition richtext.cc:55
std::string getStringFromAmpr(const std::string &str)
Definition richtext.cc:176
std::string openTag(std::vector< tags > &tagStack, std::string &tag)
Definition richtext.cc:111
std::string processRichText(const std::string &text)
Definition richtext.cc:205
unsigned count_list_items
Definition richtext.cc:56
std::map< std::string, std::string > ampersmap
Definition richtext.cc:164
void fillTagmap()
Definition richtext.cc:58
@ ITALIC
Definition richtext.cc:38
@ PARAGRAPH
Definition richtext.cc:27
@ BLOCKQUOTE
Definition richtext.cc:29
@ HEADER2
Definition richtext.cc:34
@ CODE
Definition richtext.cc:46
@ QT
Definition richtext.cc:44
@ HR
Definition richtext.cc:39
@ HEADER3
Definition richtext.cc:35
@ LI
Definition richtext.cc:40
@ BOLD
Definition richtext.cc:30
@ OL
Definition richtext.cc:41
@ UNKNOWN
Definition richtext.cc:49
@ BREAK_LINE
Definition richtext.cc:36
@ CENTER
Definition richtext.cc:47
@ TT
Definition richtext.cc:43
@ HEADER1
Definition richtext.cc:33
@ BIG
Definition richtext.cc:45
@ EM
Definition richtext.cc:37
@ UNDERLINED
Definition richtext.cc:31
@ UL
Definition richtext.cc:42
@ PRE
Definition richtext.cc:28
@ ANCHOR
Definition richtext.cc:32
std::map< std::string, tags > _rtTagmap
Definition richtext.cc:52
std::string closeTag(std::vector< tags > &tagStack)
Definition richtext.cc:89
bool pre
Definition richtext.cc:54
std::string trim(const std::string &s, const Trim trim_r)
Definition String.cc:226
#define DBG
Definition Logger.h:99
#define WAR
Definition Logger.h:101