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