Line data Source code
1 : // Copyright (c) 2006-2025 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/snaplogger
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU 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 General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : // self
21 : //
22 : #include "catch_main.h"
23 :
24 :
25 : // snaplogger
26 : //
27 : #include <snaplogger/convert_ansi.h>
28 : #include <snaplogger/exception.h>
29 :
30 :
31 : // snapdev
32 : //
33 : #include <snapdev/string_replace_many.h>
34 :
35 :
36 : // libutf8
37 : //
38 : #include <libutf8/libutf8.h>
39 :
40 :
41 : // C
42 : //
43 : //#include <unistd.h>
44 :
45 :
46 :
47 : namespace
48 : {
49 :
50 :
51 :
52 : struct convert_t
53 : {
54 : char const * f_input = nullptr;
55 : char const * f_plain_text = nullptr;
56 : char const * f_html = nullptr;
57 : char const * f_optimized_html = nullptr;
58 : char const * f_markdown = nullptr;
59 : char const * f_styles = nullptr;
60 : char const * f_styles_with_defaults = nullptr;
61 : };
62 :
63 :
64 : constexpr convert_t const g_convert_data[] =
65 : {
66 : // plain text
67 : {
68 : .f_input = "plain",
69 : .f_plain_text = "plain",
70 : .f_html = "plain",
71 : },
72 :
73 : // normal
74 : {
75 : .f_input = "\033[0mnormal\033[m",
76 : .f_plain_text = "normal",
77 : .f_html = "normal",
78 : },
79 :
80 : // bold
81 : {
82 : .f_input = "\033[1mbold\033[m",
83 : .f_plain_text = "bold",
84 : .f_html = "<span class=\"ansi-b\">bold</span>",
85 : .f_optimized_html = "<b>bold</b>",
86 : .f_markdown = "*bold*",
87 : .f_styles = ".ansi-b{font-weight:bold}\n",
88 : .f_styles_with_defaults = "b,.ansi-b{font-weight:bold}\n",
89 : },
90 :
91 : // light
92 : {
93 : .f_input = "\033[2mlight\033[m",
94 : .f_plain_text = "light",
95 : .f_html = "<span class=\"ansi-l\">light</span>",
96 : .f_styles = ".ansi-l{font-weight:light}\n",
97 : },
98 :
99 : // italic
100 : {
101 : .f_input = "\033[3mitalic\033[m",
102 : .f_plain_text = "italic",
103 : .f_html = "<span class=\"ansi-i\">italic</span>",
104 : .f_optimized_html = "<i>italic</i>",
105 : .f_markdown = "**italic**",
106 : .f_styles = ".ansi-i{font-style:italic}\n",
107 : .f_styles_with_defaults = "i,.ansi-i{font-style:italic}\n",
108 : },
109 :
110 : // underline
111 : {
112 : .f_input = "\033[4munderline\033[m",
113 : .f_plain_text = "underline",
114 : .f_html = "<span class=\"ansi-u\">underline</span>",
115 : .f_optimized_html = "<u>underline</u>",
116 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
117 : ".ansi-u{text-decoration-line:underline}\n"
118 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
119 : ".ansi-v{text-decoration-line:overline;}\n"
120 : ".ansi-us{text-decoration-line:underline line-through}\n"
121 : ".ansi-uv{text-decoration-line:underline overline}\n"
122 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
123 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
124 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
125 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
126 : ".ansi-vs{text-decoration-line:overline line-through}\n",
127 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
128 : "u,.ansi-u{text-decoration-line:underline}\n"
129 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
130 : ".ansi-v{text-decoration-line:overline;}\n"
131 : ".ansi-us{text-decoration-line:underline line-through}\n"
132 : ".ansi-uv{text-decoration-line:underline overline}\n"
133 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
134 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
135 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
136 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
137 : ".ansi-vs{text-decoration-line:overline line-through}\n",
138 : },
139 :
140 : // slow blink
141 : {
142 : .f_input = "\033[5mslow blink\033[m",
143 : .f_plain_text = "slow blink",
144 : .f_html = "<span class=\"ansi-sb\">slow blink</span>",
145 : .f_styles = "@keyframes ansi-blinker{50%{opacity:0}}\n.ansi-sb{animation:ansi-blinker 2s linear infinite}\n",
146 : },
147 :
148 : // fast blink
149 : {
150 : .f_input = "\033[6mfast blink\033[m",
151 : .f_plain_text = "fast blink",
152 : .f_html = "<span class=\"ansi-fb\">fast blink</span>",
153 : .f_styles = "@keyframes ansi-blinker{50%{opacity:0}}\n.ansi-fb{animation:ansi-blinker 0.4s linear infinite}\n",
154 : },
155 :
156 : // inverse
157 : {
158 : .f_input = "\033[7minverse\033[m",
159 : .f_plain_text = "inverse",
160 : .f_html = "<span style=\"color:#ffffff;background-color:#000000\">inverse</span>",
161 : },
162 :
163 : // conceal
164 : {
165 : .f_input = "\033[8mconceal this now\033[m",
166 : .f_plain_text = "",
167 : .f_html = "",
168 : },
169 :
170 : // cross out
171 : {
172 : .f_input = "\033[9mcross out\033[m",
173 : .f_plain_text = "cross out",
174 : .f_html = "<span class=\"ansi-s\">cross out</span>",
175 : .f_optimized_html = "<s>cross out</s>",
176 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
177 : ".ansi-u{text-decoration-line:underline}\n"
178 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
179 : ".ansi-v{text-decoration-line:overline;}\n"
180 : ".ansi-us{text-decoration-line:underline line-through}\n"
181 : ".ansi-uv{text-decoration-line:underline overline}\n"
182 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
183 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
184 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
185 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
186 : ".ansi-vs{text-decoration-line:overline line-through}\n",
187 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
188 : "u,.ansi-u{text-decoration-line:underline}\n"
189 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
190 : ".ansi-v{text-decoration-line:overline;}\n"
191 : ".ansi-us{text-decoration-line:underline line-through}\n"
192 : ".ansi-uv{text-decoration-line:underline overline}\n"
193 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
194 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
195 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
196 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
197 : ".ansi-vs{text-decoration-line:overline line-through}\n",
198 : },
199 :
200 : // cross out + underline
201 : {
202 : .f_input = "\033[9;4mcross out + underline\033[m",
203 : .f_plain_text = "cross out + underline",
204 : .f_html = "<span class=\"ansi-us\">cross out + underline</span>",
205 : .f_optimized_html = "<u><s>cross out + underline</s></u>",
206 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
207 : ".ansi-u{text-decoration-line:underline}\n"
208 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
209 : ".ansi-v{text-decoration-line:overline;}\n"
210 : ".ansi-us{text-decoration-line:underline line-through}\n"
211 : ".ansi-uv{text-decoration-line:underline overline}\n"
212 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
213 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
214 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
215 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
216 : ".ansi-vs{text-decoration-line:overline line-through}\n",
217 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
218 : "u,.ansi-u{text-decoration-line:underline}\n"
219 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
220 : ".ansi-v{text-decoration-line:overline;}\n"
221 : ".ansi-us{text-decoration-line:underline line-through}\n"
222 : ".ansi-uv{text-decoration-line:underline overline}\n"
223 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
224 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
225 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
226 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
227 : ".ansi-vs{text-decoration-line:overline line-through}\n",
228 : },
229 :
230 : // underline + cross out
231 : {
232 : .f_input = "\033[4;9munderline + cross out\033[m",
233 : .f_plain_text = "underline + cross out",
234 : .f_html = "<span class=\"ansi-us\">underline + cross out</span>",
235 : .f_optimized_html = "<u><s>underline + cross out</s></u>",
236 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
237 : ".ansi-u{text-decoration-line:underline}\n"
238 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
239 : ".ansi-v{text-decoration-line:overline;}\n"
240 : ".ansi-us{text-decoration-line:underline line-through}\n"
241 : ".ansi-uv{text-decoration-line:underline overline}\n"
242 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
243 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
244 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
245 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
246 : ".ansi-vs{text-decoration-line:overline line-through}\n",
247 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
248 : "u,.ansi-u{text-decoration-line:underline}\n"
249 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
250 : ".ansi-v{text-decoration-line:overline;}\n"
251 : ".ansi-us{text-decoration-line:underline line-through}\n"
252 : ".ansi-uv{text-decoration-line:underline overline}\n"
253 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
254 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
255 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
256 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
257 : ".ansi-vs{text-decoration-line:overline line-through}\n",
258 : },
259 :
260 : // double underline
261 : {
262 : .f_input = "\033[21mdouble underline\033[m",
263 : .f_plain_text = "double underline",
264 : .f_html = "<span class=\"ansi-d\">double underline</span>",
265 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
266 : ".ansi-u{text-decoration-line:underline}\n"
267 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
268 : ".ansi-v{text-decoration-line:overline;}\n"
269 : ".ansi-us{text-decoration-line:underline line-through}\n"
270 : ".ansi-uv{text-decoration-line:underline overline}\n"
271 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
272 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
273 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
274 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
275 : ".ansi-vs{text-decoration-line:overline line-through}\n",
276 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
277 : "u,.ansi-u{text-decoration-line:underline}\n"
278 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
279 : ".ansi-v{text-decoration-line:overline;}\n"
280 : ".ansi-us{text-decoration-line:underline line-through}\n"
281 : ".ansi-uv{text-decoration-line:underline overline}\n"
282 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
283 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
284 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
285 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
286 : ".ansi-vs{text-decoration-line:overline line-through}\n",
287 : },
288 :
289 : // cross out + double underline
290 : {
291 : .f_input = "\033[9;21mcross out + double underline\033[m",
292 : .f_plain_text = "cross out + double underline",
293 : .f_html = "<span class=\"ansi-ds\">cross out + double underline</span>",
294 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
295 : ".ansi-u{text-decoration-line:underline}\n"
296 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
297 : ".ansi-v{text-decoration-line:overline;}\n"
298 : ".ansi-us{text-decoration-line:underline line-through}\n"
299 : ".ansi-uv{text-decoration-line:underline overline}\n"
300 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
301 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
302 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
303 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
304 : ".ansi-vs{text-decoration-line:overline line-through}\n",
305 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
306 : "u,.ansi-u{text-decoration-line:underline}\n"
307 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
308 : ".ansi-v{text-decoration-line:overline;}\n"
309 : ".ansi-us{text-decoration-line:underline line-through}\n"
310 : ".ansi-uv{text-decoration-line:underline overline}\n"
311 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
312 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
313 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
314 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
315 : ".ansi-vs{text-decoration-line:overline line-through}\n",
316 : },
317 :
318 : // double underline + cross out
319 : {
320 : .f_input = "\033[21;9mdouble underline + cross out\033[m",
321 : .f_plain_text = "double underline + cross out",
322 : .f_html = "<span class=\"ansi-ds\">double underline + cross out</span>",
323 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
324 : ".ansi-u{text-decoration-line:underline}\n"
325 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
326 : ".ansi-v{text-decoration-line:overline;}\n"
327 : ".ansi-us{text-decoration-line:underline line-through}\n"
328 : ".ansi-uv{text-decoration-line:underline overline}\n"
329 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
330 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
331 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
332 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
333 : ".ansi-vs{text-decoration-line:overline line-through}\n",
334 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
335 : "u,.ansi-u{text-decoration-line:underline}\n"
336 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
337 : ".ansi-v{text-decoration-line:overline;}\n"
338 : ".ansi-us{text-decoration-line:underline line-through}\n"
339 : ".ansi-uv{text-decoration-line:underline overline}\n"
340 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
341 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
342 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
343 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
344 : ".ansi-vs{text-decoration-line:overline line-through}\n",
345 : },
346 :
347 : // bold + normal intensity
348 : {
349 : .f_input = "normal then \033[1mbold\033[22m and not\033[m",
350 : .f_plain_text = "normal then bold and not",
351 : .f_html = "normal then <span class=\"ansi-b\">bold </span>and not",
352 : .f_optimized_html = "normal then <b>bold </b>and not",
353 : .f_markdown = "normal then *bold* and not",
354 : .f_styles = ".ansi-b{font-weight:bold}\n",
355 : .f_styles_with_defaults = "b,.ansi-b{font-weight:bold}\n",
356 : },
357 :
358 : // light + normal intensity
359 : {
360 : .f_input = "normal then \033[2mlight\033[22m and not\033[m",
361 : .f_plain_text = "normal then light and not",
362 : .f_html = "normal then <span class=\"ansi-l\">light </span>and not",
363 : .f_styles = ".ansi-l{font-weight:light}\n",
364 : },
365 :
366 : // italic + normal intensity
367 : {
368 : .f_input = "normal then \033[3mitalic\033[23m and not\033[m",
369 : .f_plain_text = "normal then italic and not",
370 : .f_html = "normal then <span class=\"ansi-i\">italic </span>and not",
371 : .f_optimized_html = "normal then <i>italic </i>and not",
372 : .f_markdown = "normal then **italic** and not",
373 : .f_styles = ".ansi-i{font-style:italic}\n",
374 : .f_styles_with_defaults = "i,.ansi-i{font-style:italic}\n",
375 : },
376 :
377 : // underline + not-underline
378 : {
379 : .f_input = "normal then \033[4munderline\033[24m and not\033[m",
380 : .f_plain_text = "normal then underline and not",
381 : .f_html = "normal then <span class=\"ansi-u\">underline </span>and not",
382 : .f_optimized_html = "normal then <u>underline </u>and not",
383 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
384 : ".ansi-u{text-decoration-line:underline}\n"
385 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
386 : ".ansi-v{text-decoration-line:overline;}\n"
387 : ".ansi-us{text-decoration-line:underline line-through}\n"
388 : ".ansi-uv{text-decoration-line:underline overline}\n"
389 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
390 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
391 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
392 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
393 : ".ansi-vs{text-decoration-line:overline line-through}\n",
394 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
395 : "u,.ansi-u{text-decoration-line:underline}\n"
396 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
397 : ".ansi-v{text-decoration-line:overline;}\n"
398 : ".ansi-us{text-decoration-line:underline line-through}\n"
399 : ".ansi-uv{text-decoration-line:underline overline}\n"
400 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
401 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
402 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
403 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
404 : ".ansi-vs{text-decoration-line:overline line-through}\n",
405 : },
406 :
407 : // double underline + not-underline
408 : {
409 : .f_input = "normal then \033[21mdouble underline\033[24m and not\033[m",
410 : .f_plain_text = "normal then double underline and not",
411 : .f_html = "normal then <span class=\"ansi-d\">double underline </span>and not",
412 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
413 : ".ansi-u{text-decoration-line:underline}\n"
414 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
415 : ".ansi-v{text-decoration-line:overline;}\n"
416 : ".ansi-us{text-decoration-line:underline line-through}\n"
417 : ".ansi-uv{text-decoration-line:underline overline}\n"
418 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
419 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
420 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
421 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
422 : ".ansi-vs{text-decoration-line:overline line-through}\n",
423 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
424 : "u,.ansi-u{text-decoration-line:underline}\n"
425 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
426 : ".ansi-v{text-decoration-line:overline;}\n"
427 : ".ansi-us{text-decoration-line:underline line-through}\n"
428 : ".ansi-uv{text-decoration-line:underline overline}\n"
429 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
430 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
431 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
432 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
433 : ".ansi-vs{text-decoration-line:overline line-through}\n",
434 : },
435 :
436 : // slow blink + not blink
437 : {
438 : .f_input = "normal then \033[5mslow blink\033[25m and not\033[m",
439 : .f_plain_text = "normal then slow blink and not",
440 : .f_html = "normal then <span class=\"ansi-sb\">slow blink </span>and not",
441 : .f_styles = "@keyframes ansi-blinker{50%{opacity:0}}\n.ansi-sb{animation:ansi-blinker 2s linear infinite}\n",
442 : },
443 :
444 : // fast blink + not blink
445 : {
446 : .f_input = "normal then \033[6mfast blink\033[25m and not\033[m",
447 : .f_plain_text = "normal then fast blink and not",
448 : .f_html = "normal then <span class=\"ansi-fb\">fast blink </span>and not",
449 : .f_styles = "@keyframes ansi-blinker{50%{opacity:0}}\n.ansi-fb{animation:ansi-blinker 0.4s linear infinite}\n",
450 : },
451 :
452 : // proportional
453 : {
454 : .f_input = "normal then \033[26mproportional\033[50m and not\033[m",
455 : .f_plain_text = "normal then proportional and not",
456 : .f_html = "normal then <span class=\"ansi-p\">proportional </span>and not",
457 : .f_styles = ".ansi-p{font-family:sans-serif}\n",
458 : },
459 :
460 : // inverse + positive
461 : {
462 : .f_input = "normal then \033[7minverse\033[27m and not\033[m",
463 : .f_plain_text = "normal then inverse and not",
464 : .f_html = "normal then <span style=\"color:#ffffff;background-color:#000000\">inverse </span>and not",
465 : },
466 :
467 : // conceal + visible
468 : {
469 : .f_input = "normal then \033[8mconcealed\033[28m and not\033[m",
470 : .f_plain_text = "normal then and not",
471 : .f_html = "normal then and not",
472 : },
473 :
474 : // cross out + not cross out
475 : {
476 : .f_input = "normal then \033[9mcross out\033[29m and not\033[m",
477 : .f_plain_text = "normal then cross out and not",
478 : .f_html = "normal then <span class=\"ansi-s\">cross out </span>and not",
479 : .f_optimized_html = "normal then <s>cross out </s>and not",
480 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
481 : ".ansi-u{text-decoration-line:underline}\n"
482 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
483 : ".ansi-v{text-decoration-line:overline;}\n"
484 : ".ansi-us{text-decoration-line:underline line-through}\n"
485 : ".ansi-uv{text-decoration-line:underline overline}\n"
486 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
487 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
488 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
489 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
490 : ".ansi-vs{text-decoration-line:overline line-through}\n",
491 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
492 : "u,.ansi-u{text-decoration-line:underline}\n"
493 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
494 : ".ansi-v{text-decoration-line:overline;}\n"
495 : ".ansi-us{text-decoration-line:underline line-through}\n"
496 : ".ansi-uv{text-decoration-line:underline overline}\n"
497 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
498 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
499 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
500 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
501 : ".ansi-vs{text-decoration-line:overline line-through}\n",
502 : },
503 :
504 : // foreground black color
505 : {
506 : .f_input = "foreground \033[30mblack\033[39m color\033[m",
507 : .f_plain_text = "foreground black color",
508 : .f_html = "foreground <span style=\"color:#000000;background-color:#ffffff\">black </span>color",
509 : },
510 :
511 : // foreground red color
512 : {
513 : .f_input = "foreground \033[31mred\033[39m color\033[m",
514 : .f_plain_text = "foreground red color",
515 : .f_html = "foreground <span style=\"color:#de382b;background-color:#ffffff\">red </span>color",
516 : },
517 :
518 : // foreground green color
519 : {
520 : .f_input = "foreground \033[32mgreen\033[39m color\033[m",
521 : .f_plain_text = "foreground green color",
522 : .f_html = "foreground <span style=\"color:#39b54a;background-color:#ffffff\">green </span>color",
523 : },
524 :
525 : // foreground yellow color
526 : {
527 : .f_input = "foreground \033[33myellow\033[39m color\033[m",
528 : .f_plain_text = "foreground yellow color",
529 : .f_html = "foreground <span style=\"color:#ffc706;background-color:#ffffff\">yellow </span>color",
530 : },
531 :
532 : // foreground blue color
533 : {
534 : .f_input = "foreground \033[34mblue\033[39m color\033[m",
535 : .f_plain_text = "foreground blue color",
536 : .f_html = "foreground <span style=\"color:#006fb8;background-color:#ffffff\">blue </span>color",
537 : },
538 :
539 : // foreground magenta color
540 : {
541 : .f_input = "foreground \033[35mmagenta\033[39m color\033[m",
542 : .f_plain_text = "foreground magenta color",
543 : .f_html = "foreground <span style=\"color:#762671;background-color:#ffffff\">magenta </span>color",
544 : },
545 :
546 : // foreground cyan color
547 : {
548 : .f_input = "foreground \033[36mcyan\033[39m color\033[m",
549 : .f_plain_text = "foreground cyan color",
550 : .f_html = "foreground <span style=\"color:#2cb5e9;background-color:#ffffff\">cyan </span>color",
551 : },
552 :
553 : // foreground white color
554 : {
555 : .f_input = "foreground \033[37mwhite\033[39m color\033[m",
556 : .f_plain_text = "foreground white color",
557 : .f_html = "foreground <span style=\"color:#cccccc;background-color:#ffffff\">white </span>color",
558 : },
559 :
560 : // foreground transparent
561 : {
562 : .f_input = "foreground \033[38;1mtransparent\033[39m color\033[m",
563 : .f_plain_text = "foreground transparent color",
564 : .f_html = "foreground <span style=\"opacity:0%;background-color:#ffffff\">transparent </span>color",
565 : },
566 :
567 : // foreground RGB color
568 : {
569 : .f_input = "foreground \033[38;2;32;64;96mRGB\033[39m color\033[m",
570 : .f_plain_text = "foreground RGB color",
571 : .f_html = "foreground <span style=\"color:#204060;background-color:#ffffff\">RGB </span>color",
572 : },
573 :
574 : // foreground CMY color
575 : {
576 : .f_input = "foreground \033[38;3;32;64;96mCMY\033[39m color\033[m",
577 : .f_plain_text = "foreground CMY color",
578 : .f_html = "foreground <span style=\"color:#dfbf9f;background-color:#ffffff\">CMY </span>color",
579 : },
580 :
581 : // foreground CMYK color
582 : {
583 : .f_input = "foreground \033[38;4;32;64;96;128mCMYK\033[39m color\033[m",
584 : .f_plain_text = "foreground CMYK color",
585 : .f_html = "foreground <span style=\"color:#6f5f4f;background-color:#ffffff\">CMYK </span>color",
586 : },
587 :
588 : // foreground index color 100
589 : {
590 : .f_input = "foreground \033[38;5;100mindex color 100\033[39m color\033[m",
591 : .f_plain_text = "foreground index color 100 color",
592 : .f_html = "foreground <span style=\"color:#878700;background-color:#ffffff\">index color 100 </span>color",
593 : },
594 :
595 : // inverse does not work on foreground transparent
596 : // (i.e. the background color is #ffffff when foreground is transparent)
597 : {
598 : .f_input = "foreground \033[7minverse here \033[38;1mthen transparent\033[39m then not\033[m",
599 : .f_plain_text = "foreground inverse here then transparent then not",
600 : .f_html = "foreground <span style=\"color:#ffffff;background-color:#000000\">inverse here </span><span style=\"opacity:0%;background-color:#ffffff\">then transparent </span><span style=\"color:#ffffff;background-color:#000000\">then not</span>",
601 : },
602 :
603 : // background black color
604 : {
605 : .f_input = "background \033[40mblack\033[49m color\033[m",
606 : .f_plain_text = "background black color",
607 : .f_html = "background <span style=\"color:#000000;background-color:#000000\">black </span>color",
608 : },
609 :
610 : // background red color
611 : {
612 : .f_input = "background \033[41mred\033[49m color\033[m",
613 : .f_plain_text = "background red color",
614 : .f_html = "background <span style=\"color:#000000;background-color:#de382b\">red </span>color",
615 : },
616 :
617 : // background green color
618 : {
619 : .f_input = "background \033[42mgreen\033[49m color\033[m",
620 : .f_plain_text = "background green color",
621 : .f_html = "background <span style=\"color:#000000;background-color:#39b54a\">green </span>color",
622 : },
623 :
624 : // background yellow color
625 : {
626 : .f_input = "background \033[43myellow\033[49m color\033[m",
627 : .f_plain_text = "background yellow color",
628 : .f_html = "background <span style=\"color:#000000;background-color:#ffc706\">yellow </span>color",
629 : },
630 :
631 : // background blue color
632 : {
633 : .f_input = "background \033[44mblue\033[49m color\033[m",
634 : .f_plain_text = "background blue color",
635 : .f_html = "background <span style=\"color:#000000;background-color:#006fb8\">blue </span>color",
636 : },
637 :
638 : // background magenta color
639 : {
640 : .f_input = "background \033[45mmagenta\033[49m color\033[m",
641 : .f_plain_text = "background magenta color",
642 : .f_html = "background <span style=\"color:#000000;background-color:#762671\">magenta </span>color",
643 : },
644 :
645 : // background cyan color
646 : {
647 : .f_input = "background \033[46mcyan\033[49m color\033[m",
648 : .f_plain_text = "background cyan color",
649 : .f_html = "background <span style=\"color:#000000;background-color:#2cb5e9\">cyan </span>color",
650 : },
651 :
652 : // background white color
653 : {
654 : .f_input = "background \033[47mwhite\033[49m color\033[m",
655 : .f_plain_text = "background white color",
656 : .f_html = "background <span style=\"color:#000000;background-color:#cccccc\">white </span>color",
657 : },
658 :
659 : // background RGB color
660 : {
661 : .f_input = "background \033[48;2;32;64;96mRGB\033[49m color\033[m",
662 : .f_plain_text = "background RGB color",
663 : .f_html = "background <span style=\"color:#000000;background-color:#204060\">RGB </span>color",
664 : },
665 :
666 : // background CMY color
667 : {
668 : .f_input = "background \033[48;3;32;64;96mCMY\033[49m color\033[m",
669 : .f_plain_text = "background CMY color",
670 : .f_html = "background <span style=\"color:#000000;background-color:#dfbf9f\">CMY </span>color",
671 : },
672 :
673 : // background CMYK color
674 : {
675 : .f_input = "background \033[48;4;32;64;96;128mCMYK\033[49m color\033[m",
676 : .f_plain_text = "background CMYK color",
677 : .f_html = "background <span style=\"color:#000000;background-color:#6f5f4f\">CMYK </span>color",
678 : },
679 :
680 : // background index color 100
681 : {
682 : .f_input = "background \033[48;5;100mindex color 100\033[49m color\033[m",
683 : .f_plain_text = "background index color 100 color",
684 : .f_html = "background <span style=\"color:#000000;background-color:#878700\">index color 100 </span>color",
685 : },
686 :
687 : // overline
688 : {
689 : .f_input = "\033[53moverline\033[m",
690 : .f_plain_text = "overline",
691 : .f_html = "<span class=\"ansi-v\">overline</span>",
692 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
693 : ".ansi-u{text-decoration-line:underline}\n"
694 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
695 : ".ansi-v{text-decoration-line:overline;}\n"
696 : ".ansi-us{text-decoration-line:underline line-through}\n"
697 : ".ansi-uv{text-decoration-line:underline overline}\n"
698 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
699 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
700 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
701 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
702 : ".ansi-vs{text-decoration-line:overline line-through}\n",
703 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
704 : "u,.ansi-u{text-decoration-line:underline}\n"
705 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
706 : ".ansi-v{text-decoration-line:overline;}\n"
707 : ".ansi-us{text-decoration-line:underline line-through}\n"
708 : ".ansi-uv{text-decoration-line:underline overline}\n"
709 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
710 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
711 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
712 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
713 : ".ansi-vs{text-decoration-line:overline line-through}\n",
714 : },
715 :
716 : // overline + not overline
717 : {
718 : .f_input = "normal \033[53mthen overline\033[55m and not\033[m",
719 : .f_plain_text = "normal then overline and not",
720 : .f_html = "normal <span class=\"ansi-v\">then overline </span>and not",
721 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
722 : ".ansi-u{text-decoration-line:underline}\n"
723 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
724 : ".ansi-v{text-decoration-line:overline;}\n"
725 : ".ansi-us{text-decoration-line:underline line-through}\n"
726 : ".ansi-uv{text-decoration-line:underline overline}\n"
727 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
728 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
729 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
730 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
731 : ".ansi-vs{text-decoration-line:overline line-through}\n",
732 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
733 : "u,.ansi-u{text-decoration-line:underline}\n"
734 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
735 : ".ansi-v{text-decoration-line:overline;}\n"
736 : ".ansi-us{text-decoration-line:underline line-through}\n"
737 : ".ansi-uv{text-decoration-line:underline overline}\n"
738 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
739 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
740 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
741 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
742 : ".ansi-vs{text-decoration-line:overline line-through}\n",
743 : },
744 :
745 : // cross out + overline
746 : {
747 : .f_input = "\033[9;53mcross out + overline\033[m",
748 : .f_plain_text = "cross out + overline",
749 : .f_html = "<span class=\"ansi-vs\">cross out + overline</span>",
750 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
751 : ".ansi-u{text-decoration-line:underline}\n"
752 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
753 : ".ansi-v{text-decoration-line:overline;}\n"
754 : ".ansi-us{text-decoration-line:underline line-through}\n"
755 : ".ansi-uv{text-decoration-line:underline overline}\n"
756 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
757 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
758 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
759 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
760 : ".ansi-vs{text-decoration-line:overline line-through}\n",
761 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
762 : "u,.ansi-u{text-decoration-line:underline}\n"
763 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
764 : ".ansi-v{text-decoration-line:overline;}\n"
765 : ".ansi-us{text-decoration-line:underline line-through}\n"
766 : ".ansi-uv{text-decoration-line:underline overline}\n"
767 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
768 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
769 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
770 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
771 : ".ansi-vs{text-decoration-line:overline line-through}\n",
772 : },
773 :
774 : // overline + cross out
775 : {
776 : .f_input = "\033[53;9moverline + cross out\033[m",
777 : .f_plain_text = "overline + cross out",
778 : .f_html = "<span class=\"ansi-vs\">overline + cross out</span>",
779 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
780 : ".ansi-u{text-decoration-line:underline}\n"
781 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
782 : ".ansi-v{text-decoration-line:overline;}\n"
783 : ".ansi-us{text-decoration-line:underline line-through}\n"
784 : ".ansi-uv{text-decoration-line:underline overline}\n"
785 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
786 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
787 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
788 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
789 : ".ansi-vs{text-decoration-line:overline line-through}\n",
790 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
791 : "u,.ansi-u{text-decoration-line:underline}\n"
792 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
793 : ".ansi-v{text-decoration-line:overline;}\n"
794 : ".ansi-us{text-decoration-line:underline line-through}\n"
795 : ".ansi-uv{text-decoration-line:underline overline}\n"
796 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
797 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
798 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
799 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
800 : ".ansi-vs{text-decoration-line:overline line-through}\n",
801 : },
802 :
803 : // cross out + overline + underline
804 : {
805 : .f_input = "\033[9;53;4mcross out + overline + underline\033[m",
806 : .f_plain_text = "cross out + overline + underline",
807 : .f_html = "<span class=\"ansi-uvs\">cross out + overline + underline</span>",
808 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
809 : ".ansi-u{text-decoration-line:underline}\n"
810 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
811 : ".ansi-v{text-decoration-line:overline;}\n"
812 : ".ansi-us{text-decoration-line:underline line-through}\n"
813 : ".ansi-uv{text-decoration-line:underline overline}\n"
814 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
815 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
816 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
817 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
818 : ".ansi-vs{text-decoration-line:overline line-through}\n",
819 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
820 : "u,.ansi-u{text-decoration-line:underline}\n"
821 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
822 : ".ansi-v{text-decoration-line:overline;}\n"
823 : ".ansi-us{text-decoration-line:underline line-through}\n"
824 : ".ansi-uv{text-decoration-line:underline overline}\n"
825 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
826 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
827 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
828 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
829 : ".ansi-vs{text-decoration-line:overline line-through}\n",
830 : },
831 :
832 : // overline + cross out + underline
833 : {
834 : .f_input = "\033[53;9;4moverline + cross out + underline\033[m",
835 : .f_plain_text = "overline + cross out + underline",
836 : .f_html = "<span class=\"ansi-uvs\">overline + cross out + underline</span>",
837 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
838 : ".ansi-u{text-decoration-line:underline}\n"
839 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
840 : ".ansi-v{text-decoration-line:overline;}\n"
841 : ".ansi-us{text-decoration-line:underline line-through}\n"
842 : ".ansi-uv{text-decoration-line:underline overline}\n"
843 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
844 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
845 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
846 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
847 : ".ansi-vs{text-decoration-line:overline line-through}\n",
848 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
849 : "u,.ansi-u{text-decoration-line:underline}\n"
850 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
851 : ".ansi-v{text-decoration-line:overline;}\n"
852 : ".ansi-us{text-decoration-line:underline line-through}\n"
853 : ".ansi-uv{text-decoration-line:underline overline}\n"
854 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
855 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
856 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
857 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
858 : ".ansi-vs{text-decoration-line:overline line-through}\n",
859 : },
860 :
861 : // underline + cross out + overline
862 : {
863 : .f_input = "\033[4;9;53munderline + cross out + overline\033[m",
864 : .f_plain_text = "underline + cross out + overline",
865 : .f_html = "<span class=\"ansi-uvs\">underline + cross out + overline</span>",
866 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
867 : ".ansi-u{text-decoration-line:underline}\n"
868 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
869 : ".ansi-v{text-decoration-line:overline;}\n"
870 : ".ansi-us{text-decoration-line:underline line-through}\n"
871 : ".ansi-uv{text-decoration-line:underline overline}\n"
872 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
873 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
874 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
875 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
876 : ".ansi-vs{text-decoration-line:overline line-through}\n",
877 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
878 : "u,.ansi-u{text-decoration-line:underline}\n"
879 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
880 : ".ansi-v{text-decoration-line:overline;}\n"
881 : ".ansi-us{text-decoration-line:underline line-through}\n"
882 : ".ansi-uv{text-decoration-line:underline overline}\n"
883 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
884 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
885 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
886 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
887 : ".ansi-vs{text-decoration-line:overline line-through}\n",
888 : },
889 :
890 : // underline + overline + cross out
891 : {
892 : .f_input = "\033[4;53;9munderline + overline + cross out\033[m",
893 : .f_plain_text = "underline + overline + cross out",
894 : .f_html = "<span class=\"ansi-uvs\">underline + overline + cross out</span>",
895 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
896 : ".ansi-u{text-decoration-line:underline}\n"
897 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
898 : ".ansi-v{text-decoration-line:overline;}\n"
899 : ".ansi-us{text-decoration-line:underline line-through}\n"
900 : ".ansi-uv{text-decoration-line:underline overline}\n"
901 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
902 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
903 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
904 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
905 : ".ansi-vs{text-decoration-line:overline line-through}\n",
906 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
907 : "u,.ansi-u{text-decoration-line:underline}\n"
908 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
909 : ".ansi-v{text-decoration-line:overline;}\n"
910 : ".ansi-us{text-decoration-line:underline line-through}\n"
911 : ".ansi-uv{text-decoration-line:underline overline}\n"
912 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
913 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
914 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
915 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
916 : ".ansi-vs{text-decoration-line:overline line-through}\n",
917 : },
918 :
919 : // cross out + underline + overline
920 : {
921 : .f_input = "\033[9;4;53mcross out + underline + overline\033[m",
922 : .f_plain_text = "cross out + underline + overline",
923 : .f_html = "<span class=\"ansi-uvs\">cross out + underline + overline</span>",
924 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
925 : ".ansi-u{text-decoration-line:underline}\n"
926 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
927 : ".ansi-v{text-decoration-line:overline;}\n"
928 : ".ansi-us{text-decoration-line:underline line-through}\n"
929 : ".ansi-uv{text-decoration-line:underline overline}\n"
930 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
931 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
932 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
933 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
934 : ".ansi-vs{text-decoration-line:overline line-through}\n",
935 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
936 : "u,.ansi-u{text-decoration-line:underline}\n"
937 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
938 : ".ansi-v{text-decoration-line:overline;}\n"
939 : ".ansi-us{text-decoration-line:underline line-through}\n"
940 : ".ansi-uv{text-decoration-line:underline overline}\n"
941 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
942 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
943 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
944 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
945 : ".ansi-vs{text-decoration-line:overline line-through}\n",
946 : },
947 :
948 : // overline + underline + cross out
949 : {
950 : .f_input = "\033[53;4;9moverline + underline + cross out\033[m",
951 : .f_plain_text = "overline + underline + cross out",
952 : .f_html = "<span class=\"ansi-uvs\">overline + underline + cross out</span>",
953 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
954 : ".ansi-u{text-decoration-line:underline}\n"
955 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
956 : ".ansi-v{text-decoration-line:overline;}\n"
957 : ".ansi-us{text-decoration-line:underline line-through}\n"
958 : ".ansi-uv{text-decoration-line:underline overline}\n"
959 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
960 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
961 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
962 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
963 : ".ansi-vs{text-decoration-line:overline line-through}\n",
964 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
965 : "u,.ansi-u{text-decoration-line:underline}\n"
966 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
967 : ".ansi-v{text-decoration-line:overline;}\n"
968 : ".ansi-us{text-decoration-line:underline line-through}\n"
969 : ".ansi-uv{text-decoration-line:underline overline}\n"
970 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
971 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
972 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
973 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
974 : ".ansi-vs{text-decoration-line:overline line-through}\n",
975 : },
976 :
977 : // cross out + overline + double underline
978 : {
979 : .f_input = "\033[9;53;21mcross out + overline + double underline\033[m",
980 : .f_plain_text = "cross out + overline + double underline",
981 : .f_html = "<span class=\"ansi-dvs\">cross out + overline + double underline</span>",
982 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
983 : ".ansi-u{text-decoration-line:underline}\n"
984 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
985 : ".ansi-v{text-decoration-line:overline;}\n"
986 : ".ansi-us{text-decoration-line:underline line-through}\n"
987 : ".ansi-uv{text-decoration-line:underline overline}\n"
988 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
989 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
990 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
991 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
992 : ".ansi-vs{text-decoration-line:overline line-through}\n",
993 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
994 : "u,.ansi-u{text-decoration-line:underline}\n"
995 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
996 : ".ansi-v{text-decoration-line:overline;}\n"
997 : ".ansi-us{text-decoration-line:underline line-through}\n"
998 : ".ansi-uv{text-decoration-line:underline overline}\n"
999 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1000 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1001 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1002 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1003 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1004 : },
1005 :
1006 : // overline + cross out + double underline
1007 : {
1008 : .f_input = "\033[53;9;21moverline + cross out + double underline\033[m",
1009 : .f_plain_text = "overline + cross out + double underline",
1010 : .f_html = "<span class=\"ansi-dvs\">overline + cross out + double underline</span>",
1011 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
1012 : ".ansi-u{text-decoration-line:underline}\n"
1013 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1014 : ".ansi-v{text-decoration-line:overline;}\n"
1015 : ".ansi-us{text-decoration-line:underline line-through}\n"
1016 : ".ansi-uv{text-decoration-line:underline overline}\n"
1017 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1018 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1019 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1020 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1021 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1022 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
1023 : "u,.ansi-u{text-decoration-line:underline}\n"
1024 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1025 : ".ansi-v{text-decoration-line:overline;}\n"
1026 : ".ansi-us{text-decoration-line:underline line-through}\n"
1027 : ".ansi-uv{text-decoration-line:underline overline}\n"
1028 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1029 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1030 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1031 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1032 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1033 : },
1034 :
1035 : // double underline + cross out + overline
1036 : {
1037 : .f_input = "\033[21;9;53mdouble underline + cross out + overline\033[m",
1038 : .f_plain_text = "double underline + cross out + overline",
1039 : .f_html = "<span class=\"ansi-dvs\">double underline + cross out + overline</span>",
1040 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
1041 : ".ansi-u{text-decoration-line:underline}\n"
1042 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1043 : ".ansi-v{text-decoration-line:overline;}\n"
1044 : ".ansi-us{text-decoration-line:underline line-through}\n"
1045 : ".ansi-uv{text-decoration-line:underline overline}\n"
1046 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1047 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1048 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1049 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1050 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1051 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
1052 : "u,.ansi-u{text-decoration-line:underline}\n"
1053 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1054 : ".ansi-v{text-decoration-line:overline;}\n"
1055 : ".ansi-us{text-decoration-line:underline line-through}\n"
1056 : ".ansi-uv{text-decoration-line:underline overline}\n"
1057 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1058 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1059 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1060 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1061 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1062 : },
1063 :
1064 : // double underline + overline + cross out
1065 : {
1066 : .f_input = "\033[21;53;9mdouble underline + overline + cross out\033[m",
1067 : .f_plain_text = "double underline + overline + cross out",
1068 : .f_html = "<span class=\"ansi-dvs\">double underline + overline + cross out</span>",
1069 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
1070 : ".ansi-u{text-decoration-line:underline}\n"
1071 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1072 : ".ansi-v{text-decoration-line:overline;}\n"
1073 : ".ansi-us{text-decoration-line:underline line-through}\n"
1074 : ".ansi-uv{text-decoration-line:underline overline}\n"
1075 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1076 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1077 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1078 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1079 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1080 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
1081 : "u,.ansi-u{text-decoration-line:underline}\n"
1082 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1083 : ".ansi-v{text-decoration-line:overline;}\n"
1084 : ".ansi-us{text-decoration-line:underline line-through}\n"
1085 : ".ansi-uv{text-decoration-line:underline overline}\n"
1086 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1087 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1088 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1089 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1090 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1091 : },
1092 :
1093 : // cross out + double underline + overline
1094 : {
1095 : .f_input = "\033[9;21;53mcross out + double underline + overline\033[m",
1096 : .f_plain_text = "cross out + double underline + overline",
1097 : .f_html = "<span class=\"ansi-dvs\">cross out + double underline + overline</span>",
1098 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
1099 : ".ansi-u{text-decoration-line:underline}\n"
1100 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1101 : ".ansi-v{text-decoration-line:overline;}\n"
1102 : ".ansi-us{text-decoration-line:underline line-through}\n"
1103 : ".ansi-uv{text-decoration-line:underline overline}\n"
1104 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1105 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1106 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1107 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1108 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1109 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
1110 : "u,.ansi-u{text-decoration-line:underline}\n"
1111 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1112 : ".ansi-v{text-decoration-line:overline;}\n"
1113 : ".ansi-us{text-decoration-line:underline line-through}\n"
1114 : ".ansi-uv{text-decoration-line:underline overline}\n"
1115 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1116 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1117 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1118 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1119 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1120 : },
1121 :
1122 : // overline + double underline + cross out
1123 : {
1124 : .f_input = "\033[53;21;9moverline + double underline + cross out\033[m",
1125 : .f_plain_text = "overline + double underline + cross out",
1126 : .f_html = "<span class=\"ansi-dvs\">overline + double underline + cross out</span>",
1127 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
1128 : ".ansi-u{text-decoration-line:underline}\n"
1129 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1130 : ".ansi-v{text-decoration-line:overline;}\n"
1131 : ".ansi-us{text-decoration-line:underline line-through}\n"
1132 : ".ansi-uv{text-decoration-line:underline overline}\n"
1133 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1134 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1135 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1136 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1137 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1138 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
1139 : "u,.ansi-u{text-decoration-line:underline}\n"
1140 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1141 : ".ansi-v{text-decoration-line:overline;}\n"
1142 : ".ansi-us{text-decoration-line:underline line-through}\n"
1143 : ".ansi-uv{text-decoration-line:underline overline}\n"
1144 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1145 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1146 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1147 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1148 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1149 : },
1150 :
1151 : // underline + overline
1152 : {
1153 : .f_input = "\033[4;53munderline + overline\033[m",
1154 : .f_plain_text = "underline + overline",
1155 : .f_html = "<span class=\"ansi-uv\">underline + overline</span>",
1156 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
1157 : ".ansi-u{text-decoration-line:underline}\n"
1158 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1159 : ".ansi-v{text-decoration-line:overline;}\n"
1160 : ".ansi-us{text-decoration-line:underline line-through}\n"
1161 : ".ansi-uv{text-decoration-line:underline overline}\n"
1162 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1163 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1164 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1165 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1166 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1167 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
1168 : "u,.ansi-u{text-decoration-line:underline}\n"
1169 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1170 : ".ansi-v{text-decoration-line:overline;}\n"
1171 : ".ansi-us{text-decoration-line:underline line-through}\n"
1172 : ".ansi-uv{text-decoration-line:underline overline}\n"
1173 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1174 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1175 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1176 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1177 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1178 : },
1179 :
1180 : // overline + underline
1181 : {
1182 : .f_input = "\033[53;4moverline + underline\033[m",
1183 : .f_plain_text = "overline + underline",
1184 : .f_html = "<span class=\"ansi-uv\">overline + underline</span>",
1185 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
1186 : ".ansi-u{text-decoration-line:underline}\n"
1187 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1188 : ".ansi-v{text-decoration-line:overline;}\n"
1189 : ".ansi-us{text-decoration-line:underline line-through}\n"
1190 : ".ansi-uv{text-decoration-line:underline overline}\n"
1191 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1192 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1193 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1194 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1195 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1196 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
1197 : "u,.ansi-u{text-decoration-line:underline}\n"
1198 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1199 : ".ansi-v{text-decoration-line:overline;}\n"
1200 : ".ansi-us{text-decoration-line:underline line-through}\n"
1201 : ".ansi-uv{text-decoration-line:underline overline}\n"
1202 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1203 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1204 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1205 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1206 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1207 : },
1208 :
1209 : // double underline + overline
1210 : {
1211 : .f_input = "\033[21;53mdouble underline + overline\033[m",
1212 : .f_plain_text = "double underline + overline",
1213 : .f_html = "<span class=\"ansi-dv\">double underline + overline</span>",
1214 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
1215 : ".ansi-u{text-decoration-line:underline}\n"
1216 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1217 : ".ansi-v{text-decoration-line:overline;}\n"
1218 : ".ansi-us{text-decoration-line:underline line-through}\n"
1219 : ".ansi-uv{text-decoration-line:underline overline}\n"
1220 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1221 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1222 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1223 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1224 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1225 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
1226 : "u,.ansi-u{text-decoration-line:underline}\n"
1227 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1228 : ".ansi-v{text-decoration-line:overline;}\n"
1229 : ".ansi-us{text-decoration-line:underline line-through}\n"
1230 : ".ansi-uv{text-decoration-line:underline overline}\n"
1231 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1232 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1233 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1234 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1235 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1236 : },
1237 :
1238 : // overline + double underline
1239 : {
1240 : .f_input = "\033[53;21moverline + double underline\033[m",
1241 : .f_plain_text = "overline + double underline",
1242 : .f_html = "<span class=\"ansi-dv\">overline + double underline</span>",
1243 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
1244 : ".ansi-u{text-decoration-line:underline}\n"
1245 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1246 : ".ansi-v{text-decoration-line:overline;}\n"
1247 : ".ansi-us{text-decoration-line:underline line-through}\n"
1248 : ".ansi-uv{text-decoration-line:underline overline}\n"
1249 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1250 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1251 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1252 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1253 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1254 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
1255 : "u,.ansi-u{text-decoration-line:underline}\n"
1256 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1257 : ".ansi-v{text-decoration-line:overline;}\n"
1258 : ".ansi-us{text-decoration-line:underline line-through}\n"
1259 : ".ansi-uv{text-decoration-line:underline overline}\n"
1260 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1261 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1262 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1263 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1264 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1265 : },
1266 :
1267 : // underline with a different color
1268 : {
1269 : .f_input = "normal \033[4mthen underline\033[58;5;200m with color\033[59m and not\033[m",
1270 : .f_plain_text = "normal then underline with color and not",
1271 : .f_html = "normal <span class=\"ansi-u\">then underline </span><span class=\"ansi-u\" style=\"text-decoration-color:#ff00d7\">with color </span><span class=\"ansi-u\">and not</span>",
1272 : .f_optimized_html = "normal <u>then underline </u><u><span style=\"text-decoration-color:#ff00d7\">with color </span></u><u>and not</u>",
1273 : .f_styles = ".ansi-s{text-decoration-line:line-through}\n"
1274 : ".ansi-u{text-decoration-line:underline}\n"
1275 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1276 : ".ansi-v{text-decoration-line:overline;}\n"
1277 : ".ansi-us{text-decoration-line:underline line-through}\n"
1278 : ".ansi-uv{text-decoration-line:underline overline}\n"
1279 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1280 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1281 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1282 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1283 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1284 : .f_styles_with_defaults = "s,.ansi-s{text-decoration-line:line-through}\n"
1285 : "u,.ansi-u{text-decoration-line:underline}\n"
1286 : ".ansi-d{text-decoration-line:underline;text-decoration-style:double}\n"
1287 : ".ansi-v{text-decoration-line:overline;}\n"
1288 : ".ansi-us{text-decoration-line:underline line-through}\n"
1289 : ".ansi-uv{text-decoration-line:underline overline}\n"
1290 : ".ansi-uvs{text-decoration-line:underline overline line-through}\n"
1291 : ".ansi-ds{text-decoration-line:underline line-through;text-decoration-style:double}\n"
1292 : ".ansi-dv{text-decoration-line:underline overline;text-decoration-style:double}\n"
1293 : ".ansi-dvs{text-decoration-line:underline overline line-through;text-decoration-style:double}\n"
1294 : ".ansi-vs{text-decoration-line:overline line-through}\n",
1295 : },
1296 :
1297 : // foreground, background, and underline colors
1298 : {
1299 : .f_input = "normal \033[38;2;5;15;35;48;2;65;85;95;58;2;4;44;144mcolorful\033[39;49;59m normal",
1300 : .f_plain_text = "normal colorful normal",
1301 : .f_html = "normal <span style=\"color:#050f23;background-color:#41555f;text-decoration-color:#042c90\">colorful </span>normal",
1302 : },
1303 :
1304 : // superscript
1305 : {
1306 : .f_input = "\033[73msuperscript\033[m",
1307 : .f_plain_text = "superscript",
1308 : .f_html = "<span class=\"ansi-sup\">superscript</span>",
1309 : .f_optimized_html = "<sup>superscript</sup>",
1310 : .f_styles = ".ansi-sup{font-size:60%;vertical-align:super}\n",
1311 : .f_styles_with_defaults = "sup,.ansi-sup{font-size:60%;vertical-align:super}\n",
1312 : },
1313 :
1314 : // subscript
1315 : {
1316 : .f_input = "\033[74msubscript\033[m",
1317 : .f_plain_text = "subscript",
1318 : .f_html = "<span class=\"ansi-sub\">subscript</span>",
1319 : .f_optimized_html = "<sub>subscript</sub>",
1320 : .f_styles = ".ansi-sub{font-size:60%;vertical-align:sub}\n",
1321 : .f_styles_with_defaults = "sub,.ansi-sub{font-size:60%;vertical-align:sub}\n",
1322 : },
1323 :
1324 : // superscript + not superscript
1325 : {
1326 : .f_input = "normal \033[73mthen superscript\033[75m and not\033[m",
1327 : .f_plain_text = "normal then superscript and not",
1328 : .f_html = "normal <span class=\"ansi-sup\">then superscript </span>and not",
1329 : .f_optimized_html = "normal <sup>then superscript </sup>and not",
1330 : .f_styles = ".ansi-sup{font-size:60%;vertical-align:super}\n",
1331 : .f_styles_with_defaults = "sup,.ansi-sup{font-size:60%;vertical-align:super}\n",
1332 : },
1333 :
1334 : // subscript + not subscript
1335 : {
1336 : .f_input = "normal \033[74mthen subscript\033[75m and not\033[m",
1337 : .f_plain_text = "normal then subscript and not",
1338 : .f_html = "normal <span class=\"ansi-sub\">then subscript </span>and not",
1339 : .f_optimized_html = "normal <sub>then subscript </sub>and not",
1340 : .f_styles = ".ansi-sub{font-size:60%;vertical-align:sub}\n",
1341 : .f_styles_with_defaults = "sub,.ansi-sub{font-size:60%;vertical-align:sub}\n",
1342 : },
1343 :
1344 : // superscript + subscript are mutually exclusive
1345 : {
1346 : .f_input = "normal \033[73mthen superscript \033[74mthen subscript\033[75m and then not\033[m",
1347 : .f_plain_text = "normal then superscript then subscript and then not",
1348 : .f_html = "normal <span class=\"ansi-sup\">then superscript </span><span class=\"ansi-sub\">then subscript </span>and then not",
1349 : .f_optimized_html = "normal <sup>then superscript </sup><sub>then subscript </sub>and then not",
1350 : .f_styles = ".ansi-sup{font-size:60%;vertical-align:super}\n.ansi-sub{font-size:60%;vertical-align:sub}\n",
1351 : .f_styles_with_defaults = "sup,.ansi-sup{font-size:60%;vertical-align:super}\nsub,.ansi-sub{font-size:60%;vertical-align:sub}\n",
1352 : },
1353 :
1354 : // subscript + superscript are mutually exclusive
1355 : {
1356 : .f_input = "normal \033[74mthen subscript \033[73mthen superscript\033[75m and then not\033[m",
1357 : .f_plain_text = "normal then subscript then superscript and then not",
1358 : .f_html = "normal <span class=\"ansi-sub\">then subscript </span><span class=\"ansi-sup\">then superscript </span>and then not",
1359 : .f_optimized_html = "normal <sub>then subscript </sub><sup>then superscript </sup>and then not",
1360 : .f_styles = ".ansi-sup{font-size:60%;vertical-align:super}\n.ansi-sub{font-size:60%;vertical-align:sub}\n",
1361 : .f_styles_with_defaults = "sup,.ansi-sup{font-size:60%;vertical-align:super}\nsub,.ansi-sub{font-size:60%;vertical-align:sub}\n",
1362 : },
1363 :
1364 : // foreground gray color
1365 : {
1366 : .f_input = "foreground \033[90mgray\033[39m color\033[m",
1367 : .f_plain_text = "foreground gray color",
1368 : .f_html = "foreground <span style=\"color:#808080;background-color:#ffffff\">gray </span>color",
1369 : },
1370 :
1371 : // foreground bright red color
1372 : {
1373 : .f_input = "foreground \033[91mbright red\033[39m color\033[m",
1374 : .f_plain_text = "foreground bright red color",
1375 : .f_html = "foreground <span style=\"color:#ff0000;background-color:#ffffff\">bright red </span>color",
1376 : },
1377 :
1378 : // foreground bright green color
1379 : {
1380 : .f_input = "foreground \033[92mbright green\033[39m color\033[m",
1381 : .f_plain_text = "foreground bright green color",
1382 : .f_html = "foreground <span style=\"color:#00ff00;background-color:#ffffff\">bright green </span>color",
1383 : },
1384 :
1385 : // foreground bright yellow color
1386 : {
1387 : .f_input = "foreground \033[93mbright yellow\033[39m color\033[m",
1388 : .f_plain_text = "foreground bright yellow color",
1389 : .f_html = "foreground <span style=\"color:#ffff00;background-color:#ffffff\">bright yellow </span>color",
1390 : },
1391 :
1392 : // foreground bright blue color
1393 : {
1394 : .f_input = "foreground \033[94mbright blue\033[39m color\033[m",
1395 : .f_plain_text = "foreground bright blue color",
1396 : .f_html = "foreground <span style=\"color:#0000ff;background-color:#ffffff\">bright blue </span>color",
1397 : },
1398 :
1399 : // foreground bright magenta color
1400 : {
1401 : .f_input = "foreground \033[95mbright magenta\033[39m color\033[m",
1402 : .f_plain_text = "foreground bright magenta color",
1403 : .f_html = "foreground <span style=\"color:#ff00ff;background-color:#ffffff\">bright magenta </span>color",
1404 : },
1405 :
1406 : // foreground bright cyan color
1407 : {
1408 : .f_input = "foreground \033[96mbright cyan\033[39m color\033[m",
1409 : .f_plain_text = "foreground bright cyan color",
1410 : .f_html = "foreground <span style=\"color:#00ffff;background-color:#ffffff\">bright cyan </span>color",
1411 : },
1412 :
1413 : // foreground bright white color
1414 : {
1415 : .f_input = "foreground \033[97mbright white\033[39m color\033[m",
1416 : .f_plain_text = "foreground bright white color",
1417 : .f_html = "foreground <span style=\"color:#ffffff;background-color:#ffffff\">bright white </span>color",
1418 : },
1419 :
1420 : // background gray color
1421 : {
1422 : .f_input = "background \033[100mgray\033[49m color\033[m",
1423 : .f_plain_text = "background gray color",
1424 : .f_html = "background <span style=\"color:#000000;background-color:#808080\">gray </span>color",
1425 : },
1426 :
1427 : // background bright red color
1428 : {
1429 : .f_input = "background \033[101mbright red\033[49m color\033[m",
1430 : .f_plain_text = "background bright red color",
1431 : .f_html = "background <span style=\"color:#000000;background-color:#ff0000\">bright red </span>color",
1432 : },
1433 :
1434 : // background bright green color
1435 : {
1436 : .f_input = "background \033[102mbright green\033[49m color\033[m",
1437 : .f_plain_text = "background bright green color",
1438 : .f_html = "background <span style=\"color:#000000;background-color:#00ff00\">bright green </span>color",
1439 : },
1440 :
1441 : // background bright yellow color
1442 : {
1443 : .f_input = "background \033[103mbright yellow\033[49m color\033[m",
1444 : .f_plain_text = "background bright yellow color",
1445 : .f_html = "background <span style=\"color:#000000;background-color:#ffff00\">bright yellow </span>color",
1446 : },
1447 :
1448 : // background bright blue color
1449 : {
1450 : .f_input = "background \033[104mbright blue\033[49m color\033[m",
1451 : .f_plain_text = "background bright blue color",
1452 : .f_html = "background <span style=\"color:#000000;background-color:#0000ff\">bright blue </span>color",
1453 : },
1454 :
1455 : // background bright magenta color
1456 : {
1457 : .f_input = "background \033[105mbright magenta\033[49m color\033[m",
1458 : .f_plain_text = "background bright magenta color",
1459 : .f_html = "background <span style=\"color:#000000;background-color:#ff00ff\">bright magenta </span>color",
1460 : },
1461 :
1462 : // background bright cyan color
1463 : {
1464 : .f_input = "background \033[106mbright cyan\033[49m color\033[m",
1465 : .f_plain_text = "background bright cyan color",
1466 : .f_html = "background <span style=\"color:#000000;background-color:#00ffff\">bright cyan </span>color",
1467 : },
1468 :
1469 : // background bright white color
1470 : {
1471 : .f_input = "background \033[107mbright white\033[49m color\033[m",
1472 : .f_plain_text = "background bright white color",
1473 : .f_html = "background <span style=\"color:#000000;background-color:#ffffff\">bright white </span>color",
1474 : },
1475 :
1476 : // HTML special characters
1477 : {
1478 : .f_input = "quot - \", amp - &, apos - ', lt - <, and gt - >",
1479 : .f_plain_text = "quot - \", amp - &, apos - ', lt - <, and gt - >",
1480 : .f_html = "quot - ", amp - &, apos - ', lt - <, and gt - >",
1481 : .f_markdown = "quot \\- \", amp \\- &, apos \\- ', lt \\- \\<, and gt \\- \\>",
1482 : },
1483 :
1484 : // markdown special characters
1485 : {
1486 : .f_input = "++ * - # _ < > ` [ \\ ++",
1487 : .f_plain_text = "++ * - # _ < > ` [ \\ ++",
1488 : .f_html = "++ * - # _ < > ` [ \\ ++",
1489 : .f_markdown = "++ \\* \\- \\# \\_ \\< \\> \\` \\[ \\\\ ++",
1490 : },
1491 :
1492 : // multiple lines
1493 : {
1494 : .f_input = "this is line 1\nthen comes line 2\r\nand we got 3\rfinally line 4",
1495 : .f_plain_text = "this is line 1\nthen comes line 2\nand we got 3\nfinally line 4",
1496 : .f_html = "this is line 1<br/>\nthen comes line 2<br/>\nand we got 3<br/>\nfinally line 4",
1497 : },
1498 :
1499 : // unsupported system control
1500 : {
1501 : .f_input = "change title \033]0;This is the title\007",
1502 : .f_plain_text = "change title ]0;This is the title\007",
1503 : .f_html = "change title ]0;This is the title\007",
1504 : },
1505 :
1506 : // unsupported ST characters (for example the console can move the cursor)
1507 : {
1508 : .f_input = "A\033[AB\033[BC\033[CD\033[DE\033[EF\033[FG\033[GH\033[HJ\033[JK\033[KS\033[ST\033[Tf\033[fh\033[hi\033[il\033[ln\033[ns\033[su\033[u",
1509 : .f_plain_text = "ABCDEFGHJKSTfhilnsu",
1510 : .f_html = "ABCDEFGHJKSTfhilnsu",
1511 : },
1512 :
1513 : // fonts are ignored
1514 : {
1515 : .f_input = "\033[10mFon\033[11mt s\033[12mele\033[13mcti\033[14mons\033[15m ar\033[16me i\033[17mgno\033[18mred\033[19m Fr\033[20makt\033[mur.",
1516 : .f_plain_text = "Font selections are ignored Fraktur.",
1517 : .f_html = "Font selections are ignored Fraktur.",
1518 : },
1519 :
1520 : // frames are ignored
1521 : {
1522 : .f_input = "Normal \033[51mFramed \033[52mCircled \033[54mNormal",
1523 : .f_plain_text = "Normal Framed Circled Normal",
1524 : .f_html = "Normal Framed Circled Normal",
1525 : },
1526 :
1527 : // ideograms are ignored
1528 : {
1529 : .f_input = "Normal \033[60mIdeo0 \033[61mIdeo1 \033[62mIdeo2 \033[63mIdeo3 \033[64mIdeo4 \033[65mNormal",
1530 : .f_plain_text = "Normal Ideo0 Ideo1 Ideo2 Ideo3 Ideo4 Normal",
1531 : .f_html = "Normal Ideo0 Ideo1 Ideo2 Ideo3 Ideo4 Normal",
1532 : },
1533 : };
1534 :
1535 :
1536 :
1537 : }
1538 : // no name namespace
1539 :
1540 :
1541 1 : CATCH_TEST_CASE("convert_ansi", "[converter]")
1542 : {
1543 1 : CATCH_START_SECTION("convert_ansi: simple conversions")
1544 : {
1545 1 : snaplogger::convert_ansi::pointer_t plain_text_converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
1546 1 : snaplogger::convert_ansi::pointer_t html_converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_HTML));
1547 1 : snaplogger::convert_ansi::pointer_t markdown_converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_MARKDOWN));
1548 :
1549 1 : CATCH_REQUIRE(plain_text_converter->get_type() == snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT);
1550 1 : CATCH_REQUIRE(html_converter->get_type() == snaplogger::ansi_output_t::ANSI_OUTPUT_HTML);
1551 1 : CATCH_REQUIRE(markdown_converter->get_type() == snaplogger::ansi_output_t::ANSI_OUTPUT_MARKDOWN);
1552 :
1553 1 : CATCH_REQUIRE_FALSE(plain_text_converter->get_optimize());
1554 1 : CATCH_REQUIRE_FALSE(html_converter->get_optimize());
1555 1 : CATCH_REQUIRE_FALSE(markdown_converter->get_optimize());
1556 :
1557 1 : CATCH_REQUIRE(plain_text_converter->get_br());
1558 1 : CATCH_REQUIRE(html_converter->get_br());
1559 1 : CATCH_REQUIRE(markdown_converter->get_br());
1560 :
1561 : // save cursor; we assume that the longest string will wrap one line
1562 : //
1563 1 : std::cout << "\n\n\033[s";
1564 :
1565 106 : for(auto const & convert : g_convert_data)
1566 : {
1567 : // to avoid the reuse of the line, change the \033[u with \033[s
1568 : //
1569 2835 : std::cout << "\033[u\033[2A--- working on [" << snapdev::string_replace_many(std::string(convert.f_input), {
1570 : {"\r", "\\r"},
1571 : {"\n", "\\n"},
1572 : {"\033[A", "\\033[A"},
1573 : {"\033[B", "\\033[B"},
1574 : {"\033[C", "\\033[C"},
1575 : {"\033[D", "\\033[D"},
1576 : {"\033[E", "\\033[E"},
1577 : {"\033[F", "\\033[F"},
1578 : {"\033[G", "\\033[G"},
1579 : {"\033[H", "\\033[H"},
1580 : {"\033[J", "\\033[J"},
1581 : {"\033[K", "\\033[K"},
1582 : {"\033[S", "\\033[S"},
1583 : {"\033[T", "\\033[T"},
1584 : {"\033[f", "\\033[f"},
1585 : {"\033[h", "\\033[h"},
1586 : {"\033[i", "\\033[i"},
1587 : {"\033[l", "\\033[l"},
1588 : {"\033[n", "\\033[n"},
1589 : {"\033[s", "\\033[s"},
1590 : {"\033[u", "\\033[u"},
1591 210 : }) << "]\033[K\n";
1592 :
1593 : // plain text
1594 : //
1595 315 : plain_text_converter->write(convert.f_input);
1596 105 : std::string result(plain_text_converter->read());
1597 105 : CATCH_REQUIRE_FALSE(plain_text_converter->has_invalid_data());
1598 105 : CATCH_REQUIRE(convert.f_plain_text == result);
1599 105 : CATCH_REQUIRE(plain_text_converter->get_styles().empty());
1600 :
1601 : // html
1602 : //
1603 315 : html_converter->write(convert.f_input);
1604 105 : result = html_converter->read();
1605 105 : CATCH_REQUIRE_FALSE(html_converter->has_invalid_data());
1606 105 : CATCH_REQUIRE(convert.f_html == result);
1607 :
1608 : // no br html
1609 : //
1610 105 : html_converter->set_br(false);
1611 105 : CATCH_REQUIRE_FALSE(html_converter->get_br());
1612 :
1613 315 : html_converter->write(convert.f_input);
1614 105 : result = html_converter->read();
1615 105 : CATCH_REQUIRE_FALSE(html_converter->has_invalid_data());
1616 630 : std::string const html_without_br(snapdev::string_replace_many(std::string(convert.f_html), {{"<br/>", ""}}));
1617 105 : CATCH_REQUIRE(html_without_br == result);
1618 :
1619 105 : html_converter->set_br(true);
1620 105 : CATCH_REQUIRE(html_converter->get_br());
1621 :
1622 : // {
1623 : // snaplogger::convert_ansi::pointer_t clean_html_converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_HTML));
1624 : // clean_html_converter->write(convert.f_input);
1625 : // result = clean_html_converter->read();
1626 : // CATCH_REQUIRE_FALSE(clean_html_converter->has_invalid_data());
1627 : // CATCH_REQUIRE(convert.f_html == result);
1628 : // if(convert.f_styles != nullptr)
1629 : // {
1630 : ////std::cout << " >>> (1)T:[" << snapdev::string_replace_many(std::string(convert.f_styles), {
1631 : //// {"\r", "\\r"},
1632 : //// {"\n", "\\n"},
1633 : //// }) << " && " << snapdev::string_replace_many(std::string(convert.f_styles_with_defaults == nullptr ? convert.f_styles : convert.f_styles_with_defaults), {
1634 : //// {"\r", "\\r"},
1635 : //// {"\n", "\\n"},
1636 : //// }) << "]\n";
1637 : ////std::cout << " >>> (1)C:[" << snapdev::string_replace_many(clean_html_converter->get_styles(), {
1638 : //// {"\r", "\\r"},
1639 : //// {"\n", "\\n"},
1640 : //// }) << " && " << snapdev::string_replace_many(clean_html_converter->get_styles(true), {
1641 : //// {"\r", "\\r"},
1642 : //// {"\n", "\\n"},
1643 : //// }) << "]\n";
1644 : // CATCH_REQUIRE(convert.f_styles == clean_html_converter->get_styles());
1645 : // CATCH_REQUIRE(convert.f_styles == clean_html_converter->get_styles(true));
1646 : // //CATCH_REQUIRE((convert.f_styles_with_defaults == nullptr ? convert.f_styles : convert.f_styles_with_defaults) == clean_html_converter->get_styles(true));
1647 : // }
1648 : // else
1649 : // {
1650 : // if(!clean_html_converter->get_styles().empty())
1651 : // {
1652 : // std::cout << std::flush;
1653 : // std::cerr << "error: styles are not empty:\n "
1654 : // << snapdev::string_replace_many(clean_html_converter->get_styles(), {{"\n", "\n "}})
1655 : // << "\n";
1656 : // }
1657 : // CATCH_REQUIRE(clean_html_converter->get_styles().empty());
1658 : // }
1659 : // }
1660 :
1661 : // clean html (to verify styles)
1662 : //
1663 : {
1664 105 : snaplogger::convert_ansi::pointer_t clean_html_converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_HTML));
1665 315 : clean_html_converter->write(convert.f_input);
1666 105 : result = clean_html_converter->read();
1667 105 : CATCH_REQUIRE_FALSE(clean_html_converter->has_invalid_data());
1668 105 : CATCH_REQUIRE(convert.f_html == result);
1669 105 : if(convert.f_styles != nullptr)
1670 : {
1671 : //std::cout << " >>> (1)T:[" << snapdev::string_replace_many(std::string(convert.f_styles), {
1672 : // {"\r", "\\r"},
1673 : // {"\n", "\\n"},
1674 : // }) << " && " << snapdev::string_replace_many(std::string(convert.f_styles_with_defaults == nullptr ? convert.f_styles : convert.f_styles_with_defaults), {
1675 : // {"\r", "\\r"},
1676 : // {"\n", "\\n"},
1677 : // }) << "]\n";
1678 : //std::cout << " >>> (1)C:[" << snapdev::string_replace_many(clean_html_converter->get_styles(), {
1679 : // {"\r", "\\r"},
1680 : // {"\n", "\\n"},
1681 : // }) << " && " << snapdev::string_replace_many(clean_html_converter->get_styles(true), {
1682 : // {"\r", "\\r"},
1683 : // {"\n", "\\n"},
1684 : // }) << "]\n";
1685 48 : CATCH_REQUIRE(convert.f_styles == clean_html_converter->get_styles());
1686 48 : CATCH_REQUIRE(convert.f_styles == clean_html_converter->get_styles(true));
1687 : //CATCH_REQUIRE((convert.f_styles_with_defaults == nullptr ? convert.f_styles : convert.f_styles_with_defaults) == clean_html_converter->get_styles(true));
1688 : }
1689 : else
1690 : {
1691 57 : if(!clean_html_converter->get_styles().empty())
1692 : {
1693 0 : std::cout << std::flush;
1694 : std::cerr << "error: styles are not empty:\n "
1695 0 : << snapdev::string_replace_many(clean_html_converter->get_styles(), {{"\n", "\n "}})
1696 0 : << "\n";
1697 : }
1698 57 : CATCH_REQUIRE(clean_html_converter->get_styles().empty());
1699 : }
1700 105 : }
1701 :
1702 : // optimized html
1703 : //
1704 105 : html_converter->set_optimize(true);
1705 105 : CATCH_REQUIRE(html_converter->get_optimize());
1706 :
1707 315 : html_converter->write(convert.f_input);
1708 105 : result = html_converter->read();
1709 105 : CATCH_REQUIRE_FALSE(html_converter->has_invalid_data());
1710 105 : CATCH_REQUIRE((convert.f_optimized_html == nullptr ? convert.f_html : convert.f_optimized_html) == result);
1711 :
1712 105 : html_converter->set_optimize(false);
1713 105 : CATCH_REQUIRE_FALSE(html_converter->get_optimize());
1714 :
1715 : // clean optimized html
1716 : //
1717 : {
1718 105 : snaplogger::convert_ansi::pointer_t clean_html_converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_HTML));
1719 105 : clean_html_converter->set_optimize(true);
1720 105 : CATCH_REQUIRE(clean_html_converter->get_optimize());
1721 :
1722 315 : clean_html_converter->write(convert.f_input);
1723 105 : result = clean_html_converter->read();
1724 105 : CATCH_REQUIRE_FALSE(clean_html_converter->has_invalid_data());
1725 105 : CATCH_REQUIRE((convert.f_optimized_html == nullptr ? convert.f_html : convert.f_optimized_html) == result);
1726 105 : if(convert.f_styles != nullptr)
1727 : {
1728 : //std::cout << " >>> (2)T:[" << snapdev::string_replace_many(std::string(convert.f_styles), {
1729 : // {"\r", "\\r"},
1730 : // {"\n", "\\n"},
1731 : // }) << " && " << snapdev::string_replace_many(std::string(convert.f_styles_with_defaults == nullptr ? convert.f_styles : convert.f_styles_with_defaults), {
1732 : // {"\r", "\\r"},
1733 : // {"\n", "\\n"},
1734 : // }) << "]\n";
1735 : //std::cout << " >>> (2)C:[" << snapdev::string_replace_many(clean_html_converter->get_styles(), {
1736 : // {"\r", "\\r"},
1737 : // {"\n", "\\n"},
1738 : // }) << " && " << snapdev::string_replace_many(clean_html_converter->get_styles(true), {
1739 : // {"\r", "\\r"},
1740 : // {"\n", "\\n"},
1741 : // }) << "]\n";
1742 : //CATCH_REQUIRE(convert.f_styles == clean_html_converter->get_styles());
1743 48 : CATCH_REQUIRE((convert.f_styles_with_defaults == nullptr ? convert.f_styles : convert.f_styles_with_defaults) == clean_html_converter->get_styles(true));
1744 : }
1745 : else
1746 : {
1747 57 : if(!clean_html_converter->get_styles().empty())
1748 : {
1749 0 : std::cout << std::flush;
1750 : std::cerr << "error: styles are not empty:\n "
1751 0 : << snapdev::string_replace_many(clean_html_converter->get_styles(), {{"\n", "\n "}})
1752 0 : << "\n";
1753 : }
1754 57 : CATCH_REQUIRE(clean_html_converter->get_styles().empty());
1755 : }
1756 105 : }
1757 :
1758 : // markdown
1759 : //
1760 315 : markdown_converter->write(convert.f_input);
1761 105 : result = markdown_converter->read();
1762 105 : CATCH_REQUIRE_FALSE(markdown_converter->has_invalid_data());
1763 105 : CATCH_REQUIRE((convert.f_markdown == nullptr ? convert.f_plain_text : convert.f_markdown) == result);
1764 105 : CATCH_REQUIRE(markdown_converter->get_styles().empty());
1765 105 : }
1766 1 : std::cout << "\033[K";
1767 1 : }
1768 1 : CATCH_END_SECTION()
1769 211 : }
1770 :
1771 :
1772 5 : CATCH_TEST_CASE("convert_ansi_invalid", "[converter][error]")
1773 : {
1774 5 : CATCH_START_SECTION("convert_ansi_invalid: bad UTF-8 character")
1775 : {
1776 1 : snaplogger::convert_ansi::pointer_t converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
1777 3 : converter->write("\033[4mBad char: \x83\033[m");
1778 1 : std::string const result(converter->read());
1779 1 : CATCH_REQUIRE(converter->has_invalid_data());
1780 1 : CATCH_REQUIRE("Bad char: " == result);
1781 1 : }
1782 5 : CATCH_END_SECTION()
1783 :
1784 5 : CATCH_START_SECTION("convert_ansi_invalid: unsupported character closing CSI")
1785 : {
1786 1 : char buf[4] = {
1787 : '\033',
1788 : '[',
1789 : '@',
1790 : '\0',
1791 : };
1792 64 : for(; buf[2] <= '~'; ++buf[2])
1793 : {
1794 63 : switch(buf[2])
1795 : {
1796 20 : case 'm':
1797 : case 'A':
1798 : case 'B':
1799 : case 'C':
1800 : case 'D':
1801 : case 'E':
1802 : case 'F':
1803 : case 'G':
1804 : case 'H':
1805 : case 'J':
1806 : case 'K':
1807 : case 'S':
1808 : case 'T':
1809 : case 'f':
1810 : case 'h':
1811 : case 'i':
1812 : case 'l':
1813 : case 'n':
1814 : case 's':
1815 : case 'u':
1816 : // supported characters do not generate an invalid sequence
1817 : // (even if we do not support any of them except the 'm')
1818 : //
1819 20 : break;
1820 :
1821 43 : default:
1822 : {
1823 43 : snaplogger::convert_ansi::pointer_t converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
1824 129 : converter->write(buf);
1825 43 : std::string const result(converter->read());
1826 43 : CATCH_REQUIRE(converter->has_invalid_data());
1827 43 : CATCH_REQUIRE(result.empty());
1828 43 : }
1829 : break;
1830 :
1831 : }
1832 : }
1833 : }
1834 5 : CATCH_END_SECTION()
1835 :
1836 5 : CATCH_START_SECTION("convert_ansi_invalid: unsupported CSI value separator")
1837 : {
1838 1114112 : for(char32_t wc = 0x000001; wc <= 0x10FFFF; ++wc)
1839 : {
1840 : // skip invalid unicode (surrogates in char32_t are not valid)
1841 : //
1842 1114111 : if(wc >= 0xD800 && wc <= 0xDFFF)
1843 : {
1844 2048 : continue;
1845 : }
1846 :
1847 : // skip digits, those are understood
1848 : //
1849 1112063 : if(wc >= U'0' && wc <= U'9')
1850 : {
1851 10 : continue;
1852 : }
1853 :
1854 : // skip closing characters
1855 : //
1856 1112053 : if(wc >= U'@' && wc <= U'~')
1857 : {
1858 63 : continue;
1859 : }
1860 :
1861 : // skip valid separators
1862 : //
1863 1111990 : if(wc == ';' || wc == ':')
1864 : {
1865 2 : continue;
1866 : }
1867 : //std::cerr << "--- checking character 0x" << std::hex << std::setw(6) << std::setfill('0') << static_cast<std::uint32_t>(wc) << std::dec << "\n";
1868 :
1869 1111988 : snaplogger::convert_ansi::pointer_t converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
1870 3335964 : std::string sequence("\033[2");
1871 1111988 : sequence += libutf8::to_u8string(wc);
1872 1111988 : sequence += "3m";
1873 1111988 : converter->write(sequence);
1874 1111988 : std::string const result(converter->read());
1875 1111988 : CATCH_REQUIRE(converter->has_invalid_data());
1876 1111988 : CATCH_REQUIRE(result.empty());
1877 1111988 : }
1878 : }
1879 5 : CATCH_END_SECTION()
1880 :
1881 5 : CATCH_START_SECTION("convert_ansi_invalid: unsupported parameter numbers")
1882 : {
1883 1 : auto is_valid = [](int const value)
1884 : {
1885 100 : switch(value)
1886 : {
1887 0 : case 0:
1888 : case 1:
1889 : case 2:
1890 : case 3:
1891 : case 4:
1892 : case 5:
1893 : case 6:
1894 : case 7:
1895 : case 8:
1896 : case 9:
1897 : case 10:
1898 : case 11:
1899 : case 12:
1900 : case 13:
1901 : case 14:
1902 : case 15:
1903 : case 16:
1904 : case 17:
1905 : case 18:
1906 : case 19:
1907 : case 20:
1908 : case 21:
1909 : case 22:
1910 : case 23:
1911 : case 24:
1912 : case 25:
1913 : case 26:
1914 : case 27:
1915 : case 28:
1916 : case 29:
1917 : case 30:
1918 : case 31:
1919 : case 32:
1920 : case 33:
1921 : case 34:
1922 : case 35:
1923 : case 36:
1924 : case 37:
1925 : case 38:
1926 : case 39:
1927 : case 40:
1928 : case 41:
1929 : case 42:
1930 : case 43:
1931 : case 44:
1932 : case 45:
1933 : case 46:
1934 : case 47:
1935 : case 48:
1936 : case 49:
1937 : case 50:
1938 : case 51:
1939 : case 52:
1940 : case 53:
1941 : case 54:
1942 : case 55:
1943 : case 58:
1944 : case 59:
1945 : case 60:
1946 : case 61:
1947 : case 62:
1948 : case 63:
1949 : case 64:
1950 : case 65:
1951 : case 73:
1952 : case 74:
1953 : case 75:
1954 : case 90:
1955 : case 91:
1956 : case 92:
1957 : case 93:
1958 : case 94:
1959 : case 95:
1960 : case 96:
1961 : case 97:
1962 : case 100:
1963 : case 101:
1964 : case 102:
1965 : case 103:
1966 : case 104:
1967 : case 105:
1968 : case 106:
1969 : case 107:
1970 0 : return true;
1971 :
1972 100 : default:
1973 100 : return false;
1974 :
1975 : }
1976 : };
1977 :
1978 101 : for(int count(0); count < 100; ++count)
1979 : {
1980 100 : int value(0);
1981 : for(;;)
1982 : {
1983 100 : value = rand();
1984 100 : if(!is_valid(value))
1985 : {
1986 100 : break;
1987 : }
1988 : }
1989 :
1990 100 : snaplogger::convert_ansi::pointer_t converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
1991 300 : std::string sequence("\033[");
1992 100 : sequence += std::to_string(value);
1993 100 : sequence += "m";
1994 100 : converter->write(sequence);
1995 100 : std::string const result(converter->read());
1996 100 : CATCH_REQUIRE(converter->has_invalid_data());
1997 100 : CATCH_REQUIRE(result.empty());
1998 100 : }
1999 : }
2000 5 : CATCH_END_SECTION()
2001 :
2002 5 : CATCH_START_SECTION("convert_ansi_invalid: invalid color definitions")
2003 : {
2004 1 : constexpr char const * invalid_colors[] =
2005 : {
2006 : "\033[48;1m -> transparent not supported with backgrounds",
2007 : "\033[58;1m -> transparent not supported with underlines",
2008 : "\033[38;2m -> RGB missing for foreground color",
2009 : "\033[48;2;45m -> GB in RGB missing for background color",
2010 : "\033[58;2;45;78m -> B in RGB missing for underline color",
2011 : "\033[38;2;256;33;98m -> red value out of bound for foreground color",
2012 : "\033[48;2;45;256;11m -> green value out of bound for background color",
2013 : "\033[58;2;45;78;256m -> blue value out of bound for underline color",
2014 : "\033[38;3m -> CMY missing for foreground color",
2015 : "\033[48;3;45m -> MY in CMY missing for background color",
2016 : "\033[58;3;45;78m -> Y in CMY missing for underline color",
2017 : "\033[38;3;256;33;98m -> cyan value out of bound for foreground color",
2018 : "\033[48;3;45;256;11m -> magenta value out of bound for background color",
2019 : "\033[58;3;45;78;256m -> yellow value out of bound for underline color",
2020 : "\033[38;4m -> CMYK missing for foreground color",
2021 : "\033[48;4;45m -> MYK in CMYK missing for background color",
2022 : "\033[58;4;45;78m -> YK in CMYK missing for underline color",
2023 : "\033[38;4;45;78;14m -> K in CMYK missing for foreground color",
2024 : "\033[38;4;256;33;98;100m -> cyan value out of bound for foreground color",
2025 : "\033[48;4;45;256;11;200m -> magenta value out of bound for background color",
2026 : "\033[58;4;45;78;256;180m -> yellow value out of bound for underline color",
2027 : "\033[48;4;45;78;106;256m -> black value out of bound for background color",
2028 : "\033[38;5m -> index missing for foreground color",
2029 : "\033[48;5;256m -> index out of bound for background color",
2030 : };
2031 25 : for(auto const & bad_color : invalid_colors)
2032 : {
2033 24 : snaplogger::convert_ansi::pointer_t converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
2034 72 : converter->write(bad_color);
2035 24 : std::string const result(converter->read());
2036 24 : CATCH_REQUIRE(converter->has_invalid_data());
2037 24 : CATCH_REQUIRE_FALSE(result.empty()); // not super useful, but we include a changing comment
2038 24 : }
2039 : }
2040 5 : CATCH_END_SECTION()
2041 5 : }
2042 :
2043 :
2044 :
2045 : // vim: ts=4 sw=4 et
|