1 /*
2  * Copyright 2006-2016 Christian Stigen Larsen
3  * Copyright 2020 Christoph Raitzig
4  * Distributed under the GNU General Public License (GPL) v2.
5  */
6 
7 #include "config.h"
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include "html.h"
13 #include "options.h"
14 
print_html_document_start(const int fontsize,FILE * f)15 void print_html_document_start(const int fontsize, FILE *f) {
16 
17 	fputs("<!DOCTYPE html>\n"
18 		"<html>\n"
19 		" <head>\n"
20 		" <meta charset=\"utf-8\">\n", f);
21 	fprintf(f,
22 		" <title>%s</title>\n", html_title);
23 	fputs(
24 		"  <style>\n", f);
25 	print_css(fontsize, f);
26 	fputs(
27 		"  </style>\n"
28 		" </head>\n"
29 		"<body>\n", f);
30 }
31 
print_html_image_start(FILE * f)32 void print_html_image_start(FILE *f) {
33 	fputs("<div class='ascii'><pre>\n", f);
34 }
35 
print_html_document_end(FILE * f)36 void print_html_document_end(FILE *f) {
37 	fputs("</body>\n</html>\n", f);
38 }
39 
print_html_image_end(FILE * f)40 void print_html_image_end(FILE *f) {
41 	fputs("</pre>\n</div>\n", f);
42 }
43 
44 #if ASCII
print_html_char(FILE * f,const char ch,const int r_fg,const int g_fg,const int b_fg,const int r_bg,const int g_bg,const int b_bg)45 void print_html_char(FILE *f, const char ch,
46 	const int r_fg, const int g_fg, const int b_fg,
47 	const int r_bg, const int g_bg, const int b_bg)
48 #else
49 void print_html_char(FILE *f, const char* ch,
50 	const int r_fg, const int g_fg, const int b_fg,
51 	const int r_bg, const int g_bg, const int b_bg)
52 #endif
53 {
54 	if ( colorfill ) {
55 		fprintf(f, "<span style='color:#%02x%02x%02x; background-color:#%02x%02x%02x;'>%s</span>",
56 			r_fg, g_fg, b_fg,
57 			r_bg, g_bg, b_bg,
58 			html_entity(ch));
59 	} else
60 		fprintf(f, "<span style='color:#%02x%02x%02x;'>%s</span>",
61 			r_fg, g_fg, b_fg, html_entity(ch));
62 }
63 
print_html_newline(FILE * f)64 void print_html_newline(FILE *f) {
65 	fputs("<br>", f);
66 }
67 
print_xhtml_document_start(const int fontsize,FILE * f)68 void print_xhtml_document_start(const int fontsize, FILE *f) {
69 
70 	fputs(   "<?xml version='1.0' encoding='UTF-8' ?>\n"
71 		"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'"
72 		"  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>\n"
73 		"<html xmlns='http://www.w3.org/1999/xhtml' lang='en' xml:lang='en'>\n"
74 		"<head>\n", f);
75 	fprintf(f,
76 		"<title>%s</title>\n", html_title);
77 	fputs(
78 		"<style type='text/css'>\n", f);
79 	print_css(fontsize, f);
80 	fputs(
81 		"</style>\n"
82 		"</head>\n"
83 		"<body>\n", f);
84 }
85 
print_xhtml_image_start(FILE * f)86 void print_xhtml_image_start(FILE *f) {
87 	fputs("<div class='ascii'><pre>\n", f);
88 }
89 
print_xhtml_document_end(FILE * f)90 void print_xhtml_document_end(FILE *f) {
91 	fputs("</body>\n</html>\n", f);
92 }
93 
print_xhtml_image_end(FILE * f)94 void print_xhtml_image_end(FILE *f) {
95 	fputs("</pre>\n</div>\n", f);
96 }
97 
98 #if ASCII
print_xhtml_char(FILE * f,const char ch,const int r_fg,const int g_fg,const int b_fg,const int r_bg,const int g_bg,const int b_bg)99 void print_xhtml_char(FILE *f, const char ch,
100 	const int r_fg, const int g_fg, const int b_fg,
101 	const int r_bg, const int g_bg, const int b_bg)
102 #else
103 void print_xhtml_char(FILE *f, const char* ch,
104 	const int r_fg, const int g_fg, const int b_fg,
105 	const int r_bg, const int g_bg, const int b_bg)
106 #endif
107 {
108 	if ( colorfill ) {
109 		fprintf(f, "<span style='color:#%02x%02x%02x; background-color:#%02x%02x%02x;'>%s</span>",
110 			r_fg, g_fg, b_fg,
111 			r_bg, g_bg, b_bg,
112 			html_entity(ch));
113 	} else
114 		fprintf(f, "<span style='color:#%02x%02x%02x;'>%s</span>",
115 			r_fg, g_fg, b_fg, html_entity(ch));
116 }
117 
print_xhtml_newline(FILE * f)118 void print_xhtml_newline(FILE *f) {
119 	fputs("<br/>", f);
120 }
121 
print_css(const int fontsize,FILE * f)122 void print_css(const int fontsize, FILE *f) {
123 	fputs("body {\n", f);
124 	fputs(!invert?
125 		"   background-color: white;\n" : "background-color: black;\n", f);
126 	fputs(  "}\n"
127 		".ascii {\n"
128 		"   font-family: Courier;\n", f); // should be a monospaced font
129 	if ( !usecolors )
130 	fputs(!invert?
131 		"   color: black;\n" : "   color: white;\n", f);
132 	fprintf(f,
133 		"   font-size:%dpt;\n", fontsize);
134 	if ( html_bold )
135 	fputs( 	"   font-weight: bold;\n", f);
136 	else
137 	fputs(  "   font-weight: normal;\n", f);
138 	fputs(
139 		"}\n", f);
140 }
141 
142 #if ASCII
html_entity(const char ch)143 const char* html_entity(const char ch) { // if a html entity is larger than 6
144 		// chars, change escape_title accordingly
145 	static char s[2];
146 	switch ( ch ) {
147 #else
148 const char* html_entity(const char* ch) {
149 	switch ( ch[0] ) {
150 #endif
151 	case ' ': return "&nbsp;"; break;
152 	case '<': return "&lt;"; break;
153 	case '>': return "&gt;"; break;
154 	case '&': return "&amp;"; break;
155 	default:
156 #if ASCII
157 		s[0]=ch; s[1]=0; return s; break;
158 #else
159 		return ch;
160 #endif
161 	}
162 }
163 
164 int escape_title() {
165 	if ( strlen(html_title_raw)==0 ) {
166 		return 1;
167 	}
168 	html_title = calloc(strlen(html_title_raw)*6 +1, sizeof(char)); // at most
169 			// 6 characters are returned by html_entity for each character
170 	if ( html_title==NULL ) {
171 		return 0;
172 	}
173 	int j = 0;
174 	int sizeNew;
175 	char* newChar;
176 	for (int i = 0; i < strlen(html_title_raw); i++) {
177 		if ( html_title_raw[i]=='&' ) { // otherwise HTML entities could not be
178 			// used on purpose
179 			html_title[j++] = '&';
180 			continue;
181 		}
182 #if ASCII
183 		const char* newChar = html_entity(html_title_raw[i]);
184 #else
185 		char tempString[2];
186 		tempString[0] = html_title_raw[i];
187 		tempString[1] = '\0';
188 		const char* newChar = html_entity(tempString);
189 #endif
190 		sizeNew = strlen(newChar);
191 		for (int k = 0; k < sizeNew; k++) {
192 			html_title[j+k] = newChar[k];
193 		}
194 		j += sizeNew;
195 	}
196 	if ( realloc(html_title, (j+1) * sizeof(char))==NULL )
197 		return 0;
198 	return 1;
199 }
200