/* Copyright (C) 2020 C. McEnroe * * 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 . */ #include #include #include #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;", [IdentifierTag] = "color: inherit;", [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 htmlHeader(const char *opts[]) { if (!opts[Document]) goto body; printf("\n"); if (opts[Title]) htmlEscape(opts[Title]); printf("\n"); if (opts[CSS]) { printf("\n"); } else if (!opts[Inline]) { printf("\n"); } body: if (opts[Inline] && opts[Tab]) { printf("
");
	} else {
		printf("
");
	}
}

static void htmlFooter(const char *opts[]) {
	printf("
"); if (opts[Document]) printf("\n"); } static void htmlAnchor(const char *opts[], const char *text) { if (opts[Inline]) { printf(""); htmlEscape(text); printf(""); } static void htmlFormat(const char *opts[], enum Class class, const char *text) { if (opts[Anchor] && class == IdentifierTag) { htmlAnchor(opts, text); } else if (class == Normal) { htmlEscape(text); } else { if (opts[Inline]) { printf("", Style[class] ? Style[class] : ""); } else { printf("", Class[class]); } htmlEscape(text); printf(""); } } const struct Formatter FormatHTML = { htmlHeader, htmlFormat, htmlFooter };