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 945 : 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", "\\033"},
1573 210 : }) << "]\033[K\n";
1574 :
1575 : // plain text
1576 : //
1577 315 : plain_text_converter->write(convert.f_input);
1578 105 : std::string result(plain_text_converter->read());
1579 105 : CATCH_REQUIRE_FALSE(plain_text_converter->has_invalid_data());
1580 105 : CATCH_REQUIRE(convert.f_plain_text == result);
1581 105 : CATCH_REQUIRE(plain_text_converter->get_styles().empty());
1582 :
1583 : // html
1584 : //
1585 315 : html_converter->write(convert.f_input);
1586 105 : result = html_converter->read();
1587 105 : CATCH_REQUIRE_FALSE(html_converter->has_invalid_data());
1588 105 : CATCH_REQUIRE(convert.f_html == result);
1589 :
1590 : // no br html
1591 : //
1592 105 : html_converter->set_br(false);
1593 105 : CATCH_REQUIRE_FALSE(html_converter->get_br());
1594 :
1595 315 : html_converter->write(convert.f_input);
1596 105 : result = html_converter->read();
1597 105 : CATCH_REQUIRE_FALSE(html_converter->has_invalid_data());
1598 630 : std::string const html_without_br(snapdev::string_replace_many(std::string(convert.f_html), {{"<br/>", ""}}));
1599 105 : CATCH_REQUIRE(html_without_br == result);
1600 :
1601 105 : html_converter->set_br(true);
1602 105 : CATCH_REQUIRE(html_converter->get_br());
1603 :
1604 : // clean html (to verify styles)
1605 : //
1606 : {
1607 105 : snaplogger::convert_ansi::pointer_t clean_html_converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_HTML));
1608 315 : clean_html_converter->write(convert.f_input);
1609 105 : result = clean_html_converter->read();
1610 105 : CATCH_REQUIRE_FALSE(clean_html_converter->has_invalid_data());
1611 105 : CATCH_REQUIRE(convert.f_html == result);
1612 105 : if(convert.f_styles != nullptr)
1613 : {
1614 : //std::cout << " >>> (1)T:[" << snapdev::string_replace_many(std::string(convert.f_styles), {
1615 : // {"\r", "\\r"},
1616 : // {"\n", "\\n"},
1617 : // }) << " && " << snapdev::string_replace_many(std::string(convert.f_styles_with_defaults == nullptr ? convert.f_styles : convert.f_styles_with_defaults), {
1618 : // {"\r", "\\r"},
1619 : // {"\n", "\\n"},
1620 : // }) << "]\n";
1621 : //std::cout << " >>> (1)C:[" << snapdev::string_replace_many(clean_html_converter->get_styles(), {
1622 : // {"\r", "\\r"},
1623 : // {"\n", "\\n"},
1624 : // }) << " && " << snapdev::string_replace_many(clean_html_converter->get_styles(true), {
1625 : // {"\r", "\\r"},
1626 : // {"\n", "\\n"},
1627 : // }) << "]\n";
1628 48 : CATCH_REQUIRE(convert.f_styles == clean_html_converter->get_styles());
1629 48 : CATCH_REQUIRE(convert.f_styles == clean_html_converter->get_styles(true));
1630 : //CATCH_REQUIRE((convert.f_styles_with_defaults == nullptr ? convert.f_styles : convert.f_styles_with_defaults) == clean_html_converter->get_styles(true));
1631 : }
1632 : else
1633 : {
1634 57 : if(!clean_html_converter->get_styles().empty())
1635 : {
1636 0 : std::cout << std::flush;
1637 : std::cerr << "error: styles are not empty:\n "
1638 0 : << snapdev::string_replace_many(clean_html_converter->get_styles(), {{"\n", "\n "}})
1639 0 : << "\n";
1640 : }
1641 57 : CATCH_REQUIRE(clean_html_converter->get_styles().empty());
1642 : }
1643 105 : }
1644 :
1645 : // optimized html
1646 : //
1647 105 : html_converter->set_optimize(true);
1648 105 : CATCH_REQUIRE(html_converter->get_optimize());
1649 :
1650 315 : html_converter->write(convert.f_input);
1651 105 : result = html_converter->read();
1652 105 : CATCH_REQUIRE_FALSE(html_converter->has_invalid_data());
1653 105 : CATCH_REQUIRE((convert.f_optimized_html == nullptr ? convert.f_html : convert.f_optimized_html) == result);
1654 :
1655 105 : html_converter->set_optimize(false);
1656 105 : CATCH_REQUIRE_FALSE(html_converter->get_optimize());
1657 :
1658 : // clean optimized html
1659 : //
1660 : {
1661 105 : snaplogger::convert_ansi::pointer_t clean_html_converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_HTML));
1662 105 : clean_html_converter->set_optimize(true);
1663 105 : CATCH_REQUIRE(clean_html_converter->get_optimize());
1664 :
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_optimized_html == nullptr ? convert.f_html : convert.f_optimized_html) == result);
1669 105 : if(convert.f_styles != nullptr)
1670 : {
1671 : //std::cout << " >>> (2)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 << " >>> (2)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 : //CATCH_REQUIRE(convert.f_styles == clean_html_converter->get_styles());
1686 48 : CATCH_REQUIRE((convert.f_styles_with_defaults == nullptr ? convert.f_styles : convert.f_styles_with_defaults) == clean_html_converter->get_styles(true));
1687 : }
1688 : else
1689 : {
1690 57 : if(!clean_html_converter->get_styles().empty())
1691 : {
1692 0 : std::cout << std::flush;
1693 : std::cerr << "error: styles are not empty:\n "
1694 0 : << snapdev::string_replace_many(clean_html_converter->get_styles(), {{"\n", "\n "}})
1695 0 : << "\n";
1696 : }
1697 57 : CATCH_REQUIRE(clean_html_converter->get_styles().empty());
1698 : }
1699 105 : }
1700 :
1701 : // markdown
1702 : //
1703 315 : markdown_converter->write(convert.f_input);
1704 105 : result = markdown_converter->read();
1705 105 : CATCH_REQUIRE_FALSE(markdown_converter->has_invalid_data());
1706 105 : CATCH_REQUIRE((convert.f_markdown == nullptr ? convert.f_plain_text : convert.f_markdown) == result);
1707 105 : CATCH_REQUIRE(markdown_converter->get_styles().empty());
1708 105 : }
1709 1 : std::cout << "\033[K";
1710 1 : }
1711 1 : CATCH_END_SECTION()
1712 211 : }
1713 :
1714 :
1715 5 : CATCH_TEST_CASE("convert_ansi_invalid", "[converter][error]")
1716 : {
1717 5 : CATCH_START_SECTION("convert_ansi_invalid: bad UTF-8 character")
1718 : {
1719 1 : snaplogger::convert_ansi::pointer_t converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
1720 3 : converter->write("\033[4mBad char: \x83\033[m");
1721 1 : std::string const result(converter->read());
1722 1 : CATCH_REQUIRE(converter->has_invalid_data());
1723 1 : CATCH_REQUIRE("Bad char: " == result);
1724 1 : }
1725 5 : CATCH_END_SECTION()
1726 :
1727 5 : CATCH_START_SECTION("convert_ansi_invalid: unsupported character closing CSI")
1728 : {
1729 1 : char buf[4] = {
1730 : '\033',
1731 : '[',
1732 : '@',
1733 : '\0',
1734 : };
1735 64 : for(; buf[2] <= '~'; ++buf[2])
1736 : {
1737 63 : switch(buf[2])
1738 : {
1739 20 : case 'm':
1740 : case 'A':
1741 : case 'B':
1742 : case 'C':
1743 : case 'D':
1744 : case 'E':
1745 : case 'F':
1746 : case 'G':
1747 : case 'H':
1748 : case 'J':
1749 : case 'K':
1750 : case 'S':
1751 : case 'T':
1752 : case 'f':
1753 : case 'h':
1754 : case 'i':
1755 : case 'l':
1756 : case 'n':
1757 : case 's':
1758 : case 'u':
1759 : // supported characters do not generate an invalid sequence
1760 : // (even if we do not support any of them except the 'm')
1761 : //
1762 20 : break;
1763 :
1764 43 : default:
1765 : {
1766 43 : snaplogger::convert_ansi::pointer_t converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
1767 129 : converter->write(buf);
1768 43 : std::string const result(converter->read());
1769 43 : CATCH_REQUIRE(converter->has_invalid_data());
1770 43 : CATCH_REQUIRE(result.empty());
1771 43 : }
1772 : break;
1773 :
1774 : }
1775 : }
1776 : }
1777 5 : CATCH_END_SECTION()
1778 :
1779 5 : CATCH_START_SECTION("convert_ansi_invalid: unsupported CSI value separator")
1780 : {
1781 1114112 : for(char32_t wc = 0x000001; wc <= 0x10FFFF; ++wc)
1782 : {
1783 : // skip invalid unicode (surrogates in char32_t are not valid)
1784 : //
1785 1114111 : if(wc >= 0xD800 && wc <= 0xDFFF)
1786 : {
1787 2048 : continue;
1788 : }
1789 :
1790 : // skip digits, those are understood
1791 : //
1792 1112063 : if(wc >= U'0' && wc <= U'9')
1793 : {
1794 10 : continue;
1795 : }
1796 :
1797 : // skip closing characters
1798 : //
1799 1112053 : if(wc >= U'@' && wc <= U'~')
1800 : {
1801 63 : continue;
1802 : }
1803 :
1804 : // skip valid separators
1805 : //
1806 1111990 : if(wc == ';' || wc == ':')
1807 : {
1808 2 : continue;
1809 : }
1810 : //std::cerr << "--- checking character 0x" << std::hex << std::setw(6) << std::setfill('0') << static_cast<std::uint32_t>(wc) << std::dec << "\n";
1811 :
1812 1111988 : snaplogger::convert_ansi::pointer_t converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
1813 3335964 : std::string sequence("\033[2");
1814 1111988 : sequence += libutf8::to_u8string(wc);
1815 1111988 : sequence += "3m";
1816 1111988 : converter->write(sequence);
1817 1111988 : std::string const result(converter->read());
1818 1111988 : CATCH_REQUIRE(converter->has_invalid_data());
1819 1111988 : CATCH_REQUIRE(result.empty());
1820 1111988 : }
1821 : }
1822 5 : CATCH_END_SECTION()
1823 :
1824 5 : CATCH_START_SECTION("convert_ansi_invalid: unsupported parameter numbers")
1825 : {
1826 1 : auto is_valid = [](int const value)
1827 : {
1828 100 : switch(value)
1829 : {
1830 0 : case 0:
1831 : case 1:
1832 : case 2:
1833 : case 3:
1834 : case 4:
1835 : case 5:
1836 : case 6:
1837 : case 7:
1838 : case 8:
1839 : case 9:
1840 : case 10:
1841 : case 11:
1842 : case 12:
1843 : case 13:
1844 : case 14:
1845 : case 15:
1846 : case 16:
1847 : case 17:
1848 : case 18:
1849 : case 19:
1850 : case 20:
1851 : case 21:
1852 : case 22:
1853 : case 23:
1854 : case 24:
1855 : case 25:
1856 : case 26:
1857 : case 27:
1858 : case 28:
1859 : case 29:
1860 : case 30:
1861 : case 31:
1862 : case 32:
1863 : case 33:
1864 : case 34:
1865 : case 35:
1866 : case 36:
1867 : case 37:
1868 : case 38:
1869 : case 39:
1870 : case 40:
1871 : case 41:
1872 : case 42:
1873 : case 43:
1874 : case 44:
1875 : case 45:
1876 : case 46:
1877 : case 47:
1878 : case 48:
1879 : case 49:
1880 : case 50:
1881 : case 51:
1882 : case 52:
1883 : case 53:
1884 : case 54:
1885 : case 55:
1886 : case 58:
1887 : case 59:
1888 : case 60:
1889 : case 61:
1890 : case 62:
1891 : case 63:
1892 : case 64:
1893 : case 65:
1894 : case 73:
1895 : case 74:
1896 : case 75:
1897 : case 90:
1898 : case 91:
1899 : case 92:
1900 : case 93:
1901 : case 94:
1902 : case 95:
1903 : case 96:
1904 : case 97:
1905 : case 100:
1906 : case 101:
1907 : case 102:
1908 : case 103:
1909 : case 104:
1910 : case 105:
1911 : case 106:
1912 : case 107:
1913 0 : return true;
1914 :
1915 100 : default:
1916 100 : return false;
1917 :
1918 : }
1919 : };
1920 :
1921 101 : for(int count(0); count < 100; ++count)
1922 : {
1923 100 : int value(0);
1924 : for(;;)
1925 : {
1926 100 : value = rand();
1927 100 : if(!is_valid(value))
1928 : {
1929 100 : break;
1930 : }
1931 : }
1932 :
1933 100 : snaplogger::convert_ansi::pointer_t converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
1934 300 : std::string sequence("\033[");
1935 100 : sequence += std::to_string(value);
1936 100 : sequence += "m";
1937 100 : converter->write(sequence);
1938 100 : std::string const result(converter->read());
1939 100 : CATCH_REQUIRE(converter->has_invalid_data());
1940 100 : CATCH_REQUIRE(result.empty());
1941 100 : }
1942 : }
1943 5 : CATCH_END_SECTION()
1944 :
1945 5 : CATCH_START_SECTION("convert_ansi_invalid: invalid color definitions")
1946 : {
1947 1 : constexpr char const * invalid_colors[] =
1948 : {
1949 : "\033[48;1m -> transparent not supported with backgrounds",
1950 : "\033[58;1m -> transparent not supported with underlines",
1951 : "\033[38;2m -> RGB missing for foreground color",
1952 : "\033[48;2;45m -> GB in RGB missing for background color",
1953 : "\033[58;2;45;78m -> B in RGB missing for underline color",
1954 : "\033[38;2;256;33;98m -> red value out of bound for foreground color",
1955 : "\033[48;2;45;256;11m -> green value out of bound for background color",
1956 : "\033[58;2;45;78;256m -> blue value out of bound for underline color",
1957 : "\033[38;3m -> CMY missing for foreground color",
1958 : "\033[48;3;45m -> MY in CMY missing for background color",
1959 : "\033[58;3;45;78m -> Y in CMY missing for underline color",
1960 : "\033[38;3;256;33;98m -> cyan value out of bound for foreground color",
1961 : "\033[48;3;45;256;11m -> magenta value out of bound for background color",
1962 : "\033[58;3;45;78;256m -> yellow value out of bound for underline color",
1963 : "\033[38;4m -> CMYK missing for foreground color",
1964 : "\033[48;4;45m -> MYK in CMYK missing for background color",
1965 : "\033[58;4;45;78m -> YK in CMYK missing for underline color",
1966 : "\033[38;4;45;78;14m -> K in CMYK missing for foreground color",
1967 : "\033[38;4;256;33;98;100m -> cyan value out of bound for foreground color",
1968 : "\033[48;4;45;256;11;200m -> magenta value out of bound for background color",
1969 : "\033[58;4;45;78;256;180m -> yellow value out of bound for underline color",
1970 : "\033[48;4;45;78;106;256m -> black value out of bound for background color",
1971 : "\033[38;5m -> index missing for foreground color",
1972 : "\033[48;5;256m -> index out of bound for background color",
1973 : };
1974 25 : for(auto const & bad_color : invalid_colors)
1975 : {
1976 24 : snaplogger::convert_ansi::pointer_t converter(std::make_shared<snaplogger::convert_ansi>(snaplogger::ansi_output_t::ANSI_OUTPUT_PLAIN_TEXT));
1977 72 : converter->write(bad_color);
1978 24 : std::string const result(converter->read());
1979 24 : CATCH_REQUIRE(converter->has_invalid_data());
1980 24 : CATCH_REQUIRE_FALSE(result.empty()); // not super useful, but we include a changing comment
1981 24 : }
1982 : }
1983 5 : CATCH_END_SECTION()
1984 5 : }
1985 :
1986 :
1987 :
1988 : // vim: ts=4 sw=4 et
|