libzypp  17.35.12
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 
18 #include <zypp-core/base/Logger.h>
19 #include <zypp-core/base/String.h>
20 
21 namespace ztui {
22 
23 using std::endl;
24 using namespace zypp;
25 
26 enum tags {
28  PRE,
37  EM,
39  HR,
40  LI,
41  OL,
42  UL,
43  TT,
44  QT,
45  BIG,
48  //special for unknown tags
50 };
51 
52 std::map<std::string,tags> _rtTagmap;
53 
54 bool pre;
55 bool ordered;
57 
58 void fillTagmap()
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 
89 std::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 
111 std::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;
141  count_list_items = 0;
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 
164 std::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 
176 std::string getStringFromAmpr( const std::string & str )
177 {
178  if ( ampersmap.empty() )
179  fillAmpersmap();
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 
205 std::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 }
std::string getStringFromAmpr(const std::string &str)
Definition: richtext.cc:176
void fillAmpersmap()
Definition: richtext.cc:166
std::map< std::string, std::string > ampersmap
Definition: richtext.cc:164
String related utilities and Regular expression matching.
bool pre
Definition: richtext.cc:54
std::string trim(const std::string &s, const Trim trim_r)
Definition: String.cc:224
#define WAR
Definition: Logger.h:99
std::map< std::string, tags > _rtTagmap
Definition: richtext.cc:52
std::string closeTag(std::vector< tags > &tagStack)
Definition: richtext.cc:89
bool ordered
Definition: richtext.cc:55
void fillTagmap()
Definition: richtext.cc:58
std::string processRichText(const std::string &text)
Definition: richtext.cc:205
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
SolvableIdType size_type
Definition: PoolMember.h:126
unsigned count_list_items
Definition: richtext.cc:56
std::string openTag(std::vector< tags > &tagStack, std::string &tag)
Definition: richtext.cc:111
tags
Definition: richtext.cc:26
#define DBG
Definition: Logger.h:97