aboutsummaryrefslogtreecommitdiff
path: root/g2x.c
blob: 2cd46fe5a8bb10a71063336962933cb09da05ed3 (plain)
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
#include <stdio.h>
#include <string.h>

#define BUFSIZE 4096
#define html(s) fputs(s,stdout)
#define xmlput(n)\
	for(pos = n; buf[pos] != '\n'; pos++) {\
		switch(buf[pos]) {\
			default: putchar(buf[pos]); break;\
			case '>' : html("&gt;"); break;\
			case '<' : html("&lt;"); break;\
			case '&' : html("&amp;"); break;\
			case '\'': html("&apos;"); break;\
			case '"' : html("&quot;"); break;\
		}\
	}

int main(void)
{
	char buf[BUFSIZE];
	int pos, list_state = 0;

	html(
		"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
		"<!DOCTYPE html PUBLIC ""\"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
		"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
		"<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n"
		"<link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\"/>\n"
		"<title></title></head><body>\n"
	);

	// Reading a line from stdin into buf
	while (fgets(buf,BUFSIZE,stdin) != NULL)
	{
		if (!strncmp(buf,"# ",2))
		{// Match # for first header
			html("<h1>");
			xmlput(2);
			html("</h1>\n");
		}
		else if (!strncmp(buf,"## ",3))
		{// Match ## for second header
			html("<h2>");
			xmlput(3);
			html("</h2>\n");
		}
		else if (!strncmp(buf,"### ",4))
		{// Match ### for third header
			html("<h3>");
			xmlput(4);
			html("</h3>\n");
		}
		else if (!strncmp(buf,"> ",2))
		{// Match "> " for blockquote
			html("<p><blockquote>");
			xmlput(2);
			html("</blockquote></p>\n");
		}
		else if (!strncmp(buf,"* ",2))
		{// Match * for lists
			if (list_state == 0) html("<ul>\n");
			html("<li>"); xmlput(2); html("</li>\n");
			list_state = 1; // in a list
		}
		else if (list_state == 1)
		{// In a set of lists
			html("</ul>\n");
			list_state = 0; // out of a list
		}
		// FIXME "out of list" skips the reading of next line.
		else if (!strncmp(buf,"=>",2)) // Match links
		{// Match => for hyperlinks
			html("<p><a href=\"");
			for (pos = 3; buf[pos] != ' ';)
				putchar(buf[pos++]);
			// read entire URL, then check for "gmi" in URL.
			// TODO use strncmp instead of inline char match.
			// btw idk how to really use strncmp here at all.
			if (
				buf[pos-3] == 'g' &&
				buf[pos-2] == 'm' &&
				buf[pos-1] == 'i' // check for .gmi
			){
				fseek(stdout,-3,1); // move back 3 chars
				html("html"); // put .html
			}
			html("\">"); xmlput(pos+1); html("</a></p>\n");
		}
		else if (!strncmp(buf,"```",3))
		{// Match ``` codeblocks, ignore the block-name
		// TODO don't ignore the block-name
			fgets(buf,BUFSIZE,stdin); html("<pre><code>");
			while (strncmp(buf,"```",3))
			{
				xmlput(0);
				putchar('\n');
				fgets(buf,BUFSIZE,stdin);
			}
			html("</code></pre>\n");
		}
		else // Match paragraphs
		{
			html("<p>");
			xmlput(0);
			html("</p>\n");
		}
	} html("</body>"); html("</html>");
	// I love the gemini protocol!
}