"Fossies" - the Fresh Open Source Software Archive 
Member "xterm-379/html.c" (19 Sep 2021, 8948 Bytes) of package /linux/misc/xterm-379.tgz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "html.c" see the
Fossies "Dox" file reference documentation.
1 /* $XTermId: html.c,v 1.23 2021/09/19 18:30:48 tom Exp $ */
2
3 /*
4 * Copyright 2018-2020,2021 Thomas E. Dickey
5 * Copyright 2015,2018 Jens Schweikhardt
6 *
7 * All Rights Reserved
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to
11 * deal in the Software without restriction, including without limitation the
12 * rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Except as contained in this notice, the name(s) of the above copyright
28 * holders shall not be used in advertising or otherwise to promote the sale,
29 * use or other dealings in this Software without prior written
30 * authorization.
31 */
32
33 #include <xterm.h>
34 #include <version.h>
35
36 #define MakeDim(color) \
37 color = (unsigned short) ((2 * (unsigned) color) / 3)
38
39 #define RGBPCT(c) \
40 ((double)c.red / 655.35), \
41 ((double)c.green / 655.35), \
42 ((double)c.blue / 655.35)
43
44 static void dumpHtmlHeader(XtermWidget xw, FILE *fp);
45 static void dumpHtmlScreen(XtermWidget xw, FILE *fp);
46 static void dumpHtmlLine(XtermWidget xw, int row, FILE *fp);
47 static void dumpHtmlFooter(XtermWidget, FILE *fp);
48 static void writeStyle(XtermWidget, FILE *fp);
49
50 void
51 xtermDumpHtml(XtermWidget xw)
52 {
53 char *saveLocale;
54 FILE *fp;
55
56 TRACE(("xtermDumpHtml...\n"));
57 saveLocale = xtermSetLocale(LC_NUMERIC, "C");
58 fp = create_printfile(xw, ".xhtml");
59 if (fp != 0) {
60 dumpHtmlHeader(xw, fp);
61 dumpHtmlScreen(xw, fp);
62 dumpHtmlFooter(xw, fp);
63 fclose(fp);
64 }
65 xtermResetLocale(LC_NUMERIC, saveLocale);
66 TRACE(("...xtermDumpHtml done\n"));
67 }
68
69 static void
70 dumpHtmlHeader(XtermWidget xw, FILE *fp)
71 {
72 fputs("<?xml version='1.0' encoding='UTF-8'?>\n", fp);
73 fputs("<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'\n", fp);
74 fputs(" 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>\n", fp);
75 fputs("<html xmlns='http://www.w3.org/1999/xhtml' lang='en' xml:lang='en'>\n", fp);
76 fputs(" <head>\n", fp);
77 fprintf(fp, " <meta name='generator' content='%s'/>\n", xtermVersion());
78 fputs(" <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>\n", fp);
79 fputs(" <link rel='Stylesheet' type='text/css' href='xterm.css'/>\n", fp);
80 fputs(" <title>Xterm</title>\n", fp);
81 writeStyle(xw, fp);
82 fputs(" </head>\n", fp);
83 fputs(" <body>\n", fp);
84 fputs(" <div id='vt100'>\n", fp);
85 fputs(" <pre>", fp);
86 xevents(xw);
87 }
88
89 static void
90 writeStyle(XtermWidget xw, FILE *fp)
91 {
92 TScreen *s = TScreenOf(xw);
93
94 fputs(" <style type='text/css'>\n", fp);
95 fputs(" body, pre { margin: 0 }\n", fp);
96 fputs(" #vt100 {\n", fp);
97 fputs(" float: left;\n", fp);
98 fprintf(fp, " font-size: 12pt;\n");
99 fprintf(fp, " border: %upx solid %s;\n", BorderWidth(xw),
100 PixelToCSSColor(xw, BorderPixel(xw)));
101 fprintf(fp, " padding: %dpx;\n", s->border);
102 fprintf(fp, " background: %s\n", PixelToCSSColor(xw, xw->old_background));
103 fprintf(fp, " }\n");
104 fputs(" .ul { text-decoration: underline }\n", fp);
105 fputs(" .bd { font-weight: bold }\n", fp);
106 fputs(" .it { font-style: italic }\n", fp);
107 fputs(" .st { text-decoration: line-through }\n", fp);
108 fputs(" .lu { text-decoration: line-through underline }\n", fp);
109 fputs(" </style>\n", fp);
110 xevents(xw);
111 }
112
113 static void
114 dumpHtmlScreen(XtermWidget xw, FILE *fp)
115 {
116 TScreen *s = TScreenOf(xw);
117 int row;
118
119 for (row = s->top_marg; row <= s->bot_marg; ++row) {
120 dumpHtmlLine(xw, row, fp);
121 }
122 }
123
124 /*
125 * Note: initial and final space around values of class and style
126 * attribute are deliberate. They make it easier for XPath
127 * to test whether a particular name is among the attributes.
128 * It allows expressions such as
129 * [contains(@class, ' ul ')]
130 * instead of the unwieldy
131 * [contains(concat(' ', @class, ' '), ' ul ')]
132 * The ev and od (for even and odd rows) values
133 * avoid empty values when going back to old fg/bg.
134 */
135 static void
136 dumpHtmlLine(XtermWidget xw, int row, FILE *fp)
137 {
138 TScreen *s = TScreenOf(xw);
139 char attrs[2][sizeof
140 "<span class=' ev ul bd it st du ' style='color: rgb(100.00%, 100.00%, 100.00%); background: rgb(100.00%, 100.00%, 100.00%)'>"];
141 int attr_index = 0;
142 char *attr = &attrs[attr_index][0];
143 int inx = ROW2INX(s, row);
144 LineData *ld = getLineData(s, inx);
145 int col;
146
147 if (ld == 0)
148 return;
149
150 for (col = 0; col < MaxCols(s); col++) {
151 XColor fgcolor, bgcolor;
152 IChar chr = ld->charData[col];
153 int slen = 0;
154
155 fgcolor.pixel = xw->old_foreground;
156 bgcolor.pixel = xw->old_background;
157 #if OPT_ISO_COLORS
158 if (ld->attribs[col] & FG_COLOR) {
159 Pixel fg = extract_fg(xw, ld->color[col], ld->attribs[col]);
160 #if OPT_DIRECT_COLOR
161 if (ld->attribs[col] & ATR_DIRECT_FG)
162 fgcolor.pixel = fg;
163 else
164 #endif
165 fgcolor.pixel = s->Acolors[fg].value;
166 }
167 if (ld->attribs[col] & BG_COLOR) {
168 Pixel bg = extract_bg(xw, ld->color[col], ld->attribs[col]);
169 #if OPT_DIRECT_COLOR
170 if (ld->attribs[col] & ATR_DIRECT_BG)
171 bgcolor.pixel = bg;
172 else
173 #endif
174 bgcolor.pixel = s->Acolors[bg].value;
175 }
176 #endif
177
178 (void) QueryOneColor(xw, &fgcolor);
179 (void) QueryOneColor(xw, &bgcolor);
180 xevents(xw);
181
182 if (ld->attribs[col] & BLINK) {
183 /* White on red. */
184 fgcolor.red = fgcolor.green = fgcolor.blue = MAX_U_COLOR;
185 bgcolor.red = MAX_U_COLOR;
186 bgcolor.green = bgcolor.blue = 0u;
187 }
188 #if OPT_WIDE_ATTRS
189 if (ld->attribs[col] & ATR_FAINT) {
190 MakeDim(fgcolor.red);
191 MakeDim(fgcolor.green);
192 MakeDim(fgcolor.blue);
193 }
194 #endif
195 if (ld->attribs[col] & INVERSE) {
196 XColor tmp = fgcolor;
197 fgcolor = bgcolor;
198 bgcolor = tmp;
199 }
200
201 slen = sprintf(attr + slen, "<span class=' %s",
202 ((row % 2) ? "ev" : "od"));
203 if (ld->attribs[col] & BOLD)
204 slen += sprintf(attr + slen, " bd");
205 #if OPT_WIDE_ATTRS
206 /*
207 * Handle multiple text-decoration properties.
208 * Treat ATR_DBL_UNDER the same as UNDERLINE since there is no
209 * official proper CSS 2.2 way to use double underlining. (E.g.
210 * using border-bottom does not work for successive lines and
211 * "text-decoration: underline double" is a browser extension).
212 */
213 if ((ld->attribs[col] & (UNDERLINE | ATR_DBL_UNDER)) &&
214 (ld->attribs[col] & ATR_STRIKEOUT))
215 slen += sprintf(attr + slen, " lu");
216 else if (ld->attribs[col] & (UNDERLINE | ATR_DBL_UNDER))
217 slen += sprintf(attr + slen, " ul");
218 else if (ld->attribs[col] & ATR_STRIKEOUT)
219 slen += sprintf(attr + slen, " st");
220
221 if (ld->attribs[col] & ATR_ITALIC)
222 slen += sprintf(attr + slen, " it");
223 #else
224 if (ld->attribs[col] & UNDERLINE)
225 slen += sprintf(attr + slen, " ul");
226 #endif
227 slen += sprintf(attr + slen,
228 " ' style='color: rgb(%.2f%%, %.2f%%, %.2f%%);",
229 RGBPCT(fgcolor));
230 (void) sprintf(attr + slen,
231 " background: rgb(%.2f%%, %.2f%%, %.2f%%)'>", RGBPCT(bgcolor));
232 if (col == 0) {
233 fputs(attr, fp);
234 attr = &attrs[attr_index ^= 1][0];
235 } else {
236 if (strcmp(&attrs[0][0], &attrs[1][0])) {
237 fputs("</span>", fp);
238 fputs(attr, fp);
239 attr = &attrs[attr_index ^= 1][0];
240 }
241 }
242
243 #if OPT_WIDE_CHARS
244 if (chr > 127) {
245 /* Ignore hidden characters. */
246 if (chr != HIDDEN_CHAR) {
247 Char temp[10];
248 *convertToUTF8(temp, chr) = 0;
249 fputs((char *) temp, fp);
250 }
251 } else
252 #endif
253 switch (chr) {
254 case 0:
255 fputc(' ', fp);
256 break;
257 case '&':
258 fputs("&", fp);
259 break;
260 case '<':
261 fputs("<", fp);
262 break;
263 case '>':
264 fputs(">", fp);
265 break;
266 case ' ':
267 fputs("\302\240", fp);
268 break;
269 default:
270 fputc((int) chr, fp);
271 }
272 xevents(xw);
273 }
274 fprintf(fp, "</span>\n");
275 xevents(xw);
276 }
277
278 static void
279 dumpHtmlFooter(XtermWidget xw, FILE *fp)
280 {
281 fputs("</pre>\n", fp);
282 fputs(" </div>\n", fp);
283 fputs(" </body>\n", fp);
284 fputs("</html>\n", fp);
285 xevents(xw);
286 }
287
288 char *
289 PixelToCSSColor(XtermWidget xw, Pixel p)
290 {
291 static char rgb[sizeof "rgb(100.00%, 100.00%, 100.00%)"];
292 XColor c;
293
294 (void) xw;
295 c.pixel = p;
296 (void) QueryOneColor(xw, &c);
297 sprintf(rgb, "rgb(%.2f%%, %.2f%%, %.2f%%)", RGBPCT(c));
298 return rgb;
299 }