diff options
author | June McEnroe <june@causal.agency> | 2020-12-29 00:55:47 -0500 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2020-12-29 00:55:47 -0500 |
commit | 1e284c0b01081e731be45d1b29b49d4540ae3c2c (patch) | |
tree | 8e637d4fb2bcdcd31925ce383442e6f119d28691 /bin/hilex/html.c | |
parent | Add hilex manual page (diff) | |
download | src-1e284c0b01081e731be45d1b29b49d4540ae3c2c.tar.gz src-1e284c0b01081e731be45d1b29b49d4540ae3c2c.zip |
Add hilex HTML output
Diffstat (limited to 'bin/hilex/html.c')
-rw-r--r-- | bin/hilex/html.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/bin/hilex/html.c b/bin/hilex/html.c new file mode 100644 index 00000000..cfa42770 --- /dev/null +++ b/bin/hilex/html.c @@ -0,0 +1,135 @@ +/* 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 *Style[ClassCap] = { + [Keyword] = "color: dimgray;", + [Tag] = "color: inherit;", + [Macro] = "color: green;", + [Comment] = "color: navy;", + [String] = "color: teal;", + [StringFormat] = "color: teal; font-weight: bold;", +}; + +static void styleTabSize(const char *tab) { + printf("-moz-tab-size: "); + htmlEscape(tab); + printf("; tab-size: "); + htmlEscape(tab); + printf(";"); +} + +static void htmlHeader(const char *opts[]) { + if (!opts[Document]) goto body; + + printf("<!DOCTYPE html>\n<title>"); + if (opts[Title]) htmlEscape(opts[Title]); + printf("</title>\n"); + + if (opts[CSS]) { + printf("<link rel=\"stylesheet\" href=\""); + htmlEscape(opts[CSS]); + printf("\">\n"); + } else if (!opts[Inline]) { + printf("<style>\n"); + if (opts[Tab]) { + printf("pre.hi { "); + styleTabSize(opts[Tab]); + printf(" }\n"); + } + for (enum Class class = 0; class < ClassCap; ++class) { + if (!Style[class]) continue; + printf(".hi.%s { %s }\n", Class[class], Style[class]); + } + if (opts[Anchor]) { + printf( + ".hi.%s:target { color: goldenrod; outline: none; }\n", + Class[Tag] + ); + } + printf("</style>\n"); + } + +body: + if (opts[Inline] && opts[Tab]) { + printf("<pre class=\"hi\" style=\""); + styleTabSize(opts[Tab]); + printf("\">"); + } else { + printf("<pre class=\"hi\">"); + } +} + +static void htmlFooter(const char *opts[]) { + printf("</pre>"); + if (opts[Document]) printf("\n"); +} + +static void htmlAnchor(const char *opts[], const char *text) { + if (opts[Inline]) { + printf("<a style=\"%s\" id=\"", Style[Tag]); + } else { + printf("<a class=\"hi %s\" id=\"", Class[Tag]); + } + htmlEscape(text); + printf("\" href=\"#"); + htmlEscape(text); + printf("\">"); + htmlEscape(text); + printf("</a>"); +} + +static void htmlFormat(const char *opts[], enum Class class, const char *text) { + if (opts[Anchor] && class == Tag) { + htmlAnchor(opts, text); + } else if (class == Normal) { + htmlEscape(text); + } else { + if (opts[Inline]) { + printf("<span style=\"%s\">", Style[class] ? Style[class] : ""); + } else { + printf("<span class=\"hi %s\">", Class[class]); + } + htmlEscape(text); + printf("</span>"); + } +} + +const struct Formatter FormatHTML = { htmlHeader, htmlFormat, htmlFooter }; |