1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/* Copyright (C) 2020 C. McEnroe <june@causal.agency>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hilex.h"
static void htmlEscape(const char *text) {
while (*text) {
switch (*text) {
break; case '"': text++; printf(""");
break; case '&': text++; printf("&");
break; case '<': text++; printf("<");
}
size_t len = strcspn(text, "\"&<");
if (len) fwrite(text, len, 1, stdout);
text += len;
}
}
static const char *Class[ClassCap] = {
#define X(class) [class] = #class,
ENUM_CLASS
#undef X
};
static const char *Styles[ClassCap] = {
[Keyword] = "color: dimgray;",
[Macro] = "color: green;",
[Comment] = "color: navy;",
[String] = "color: teal;",
[StringFormat] = "color: teal; font-weight: bold;",
[Interpolation] = "color: olive;",
};
static void styleTabSize(const char *tab) {
printf("-moz-tab-size: ");
htmlEscape(tab);
printf("; tab-size: ");
htmlEscape(tab);
printf(";");
}
static void (const char *opts[]) {
if (!opts[Document]) goto body;
printf("<!DOCTYPE html>\n<title>");
if (opts[Title]) htmlEscape(opts[Title]);
printf("</title>\n");
if (opts[Style]) {
printf("<link rel=\"stylesheet\" href=\"");
htmlEscape(opts[Style]);
printf("\">\n");
} else if (!opts[Inline]) {
printf("<style>\n");
if (opts[Tab]) {
printf("pre.hilex { ");
styleTabSize(opts[Tab]);
printf(" }\n");
}
for (enum Class class = 0; class < ClassCap; ++class) {
if (!Styles[class]) continue;
printf(".hilex.%s { %s }\n", Class[class], Styles[class]);
}
printf("</style>\n");
}
body:
if (opts[Inline] && opts[Tab]) {
printf("<pre class=\"hilex\" style=\"");
styleTabSize(opts[Tab]);
printf("\">");
} else {
printf("<pre class=\"hilex\">");
}
}
static void (const char *opts[]) {
printf("</pre>");
if (opts[Document]) printf("\n");
}
static void htmlFormat(const char *opts[], enum Class class, const char *text) {
if (class != Normal) {
if (opts[Inline]) {
printf("<span style=\"%s\">", Styles[class] ? Styles[class] : "");
} else {
printf("<span class=\"hilex %s\">", Class[class]);
}
htmlEscape(text);
printf("</span>");
} else {
htmlEscape(text);
}
}
const struct Formatter FormatHTML = { htmlHeader, htmlFormat, htmlFooter };
|