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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
#include "../includes/compiler.h"
#include <stdio.h>
#include <string.h>
int find_string(string src, string query, size_t sz_src, size_t sz_query)
{
int j = 0;
while ((j < (sz_src - sz_query)) && (strncmp(query, src + j, sz_query))) ++j;
return j;
}
void compile_inner_text(string dest, string src, size_t sz_src,
string line_or_source)
{
/* cursor is the current index on the dest pointer
* lower represents the last tag character before content
* upper represents the first tag character after content
*
* size_of_content is self explanatory (size of content in tags)
* tag_size is the compiled size of a tag
* md_tag_size is the precompiled size of a tag
*
* tag is the string for the open HTML tag
* close_tag is the string for the close HTML tag
*
* i and j are iterator variables
*/
int cursor, lower, upper;
size_t size_of_content, tag_size, md_tag_size;
string tag, close_tag;
int i, j;
lower = 0;
upper = 0;
cursor = 0;
for (i = 0; i < size_of_line; ++i)
{
// Asterisk routine
if (src[i] == '*')
{
j = i + 1;
// Twin asterisks
if (src[i + 1] == '*')
{
tag = "<strong>";
close_tag = "</strong>";
tag_size = 8;
md_tag_size = 2;
// Make j the cursor seeking for the matching asterisk pair
while ((j < size_of_line - 1) && (src[j] != '*' || src[j + 1] != '*'))
++j;
// if found
if (src[j] == '*')
{
lower = i + 1;
upper = j;
}
else
{
// ERROR
fprintf(stderr, "No matching asterisk for %s:%d\n", line_or_source,
i);
exit(-1);
}
}
// one asterisk
else
{
tag = "<i>";
close_tag = "</i>";
tag_size = 3;
md_tag_size = 1;
while ((j < size_of_line) && (src[j] != '*')) ++j;
if (src[j] == '*')
{
lower = i;
upper = j;
}
else
{
// error, no matching asterisk
fprintf(stderr, "No matching asterisk for %s:%d\n", line_or_source,
i);
exit(-1);
}
}
/*
* Copy all
*/
size_of_content = upper - lower - 1;
strncpy(dest + cursor, tag, tag_size);
strncpy(dest + cursor + tag_size, src + lower + 1, size_of_content);
strncpy(dest + cursor + tag_size + size_of_content, close_tag,
tag_size + 1);
cursor +=
tag_size + size_of_content + tag_size + 1; // shift after operation
i += size_of_content + (2 * md_tag_size) - 1;
}
else
{
strncpy(dest + cursor, &src[i], 1);
cursor += 1;
}
}
}
string compile_line(string line, size_t size_of_line, string line_or_source)
{
string compiled_line;
size_t size_of_content;
if (line[0] == '#') // Compile a header
{
// Get the level of header (h1, h2, etc)
int depth;
for (depth = 1; line[depth] == '#'; ++depth) continue;
size_of_content = size_of_line - depth; // remove hashes
// Generate the header tags based on depth
const int tag_size = 4;
const int close_tag_size = 5;
string tag = malloc(sizeof(*tag) * 5);
string close_tag = malloc(sizeof(*close_tag) * 6);
sprintf(tag, "<h%d>", depth);
sprintf(close_tag, "</h%d>", depth);
// allocate buffer with extra 9 characters for the tags
compiled_line = malloc(sizeof(*compiled_line) *
(size_of_line + tag_size + close_tag_size + 1));
// write h1 to start of compiled_line
strncpy(compiled_line, tag, tag_size);
// write the rest of the line to the compiled_line
strncpy(compiled_line + tag_size, line + depth, size_of_line);
// write the end tags
strncpy(compiled_line + size_of_content + tag_size, close_tag,
close_tag_size);
compiled_line[size_of_content + tag_size + close_tag_size] = '\0';
}
else if (line[0] == '-') // Compile a list item
{
string tag = "<li>";
string close_tag = "</li>";
size_of_content = size_of_line - 1;
compiled_line = malloc(sizeof(*compiled_line) * (size_of_content + 10));
strncpy(compiled_line, tag, 4);
strncpy(compiled_line + 4, line + 1, size_of_line);
strncpy(compiled_line + size_of_content + 4, close_tag, 5);
compiled_line[size_of_content + 9] = '\0'; // terminate string
}
else // Compile a standard piece of text
{
compiled_line = malloc(sizeof(*compiled_line) * size_of_line * 2);
compile_inner_text(compiled_line, line, size_of_line, line_or_source);
}
return compiled_line;
}
|