-
Notifications
You must be signed in to change notification settings - Fork 59
/
toc.c
157 lines (137 loc) · 4.17 KB
/
toc.c
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
/*
toc.c -- Table of contents
(c) 2013-2015 Fletcher T. Penney (http://fletcherpenney.net/).
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License or the MIT
license. See LICENSE for details.
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 General Public License for more details.
*/
#include "toc.h"
/* print_toc_node_tree -- convert node tree to MultiMarkdown */
void print_toc_node_tree(GString *out, node *list, scratch_pad *scratch) {
#ifdef DEBUG_ON
fprintf(stderr, "print_toc_node_tree\n");
#endif
int lev;
while (list != NULL) {
if (list->key == HEADINGSECTION) {
lev = list->children->key;
print_toc_section_and_children(out, list, scratch);
while ((list->next != NULL) && (list->next->key == HEADINGSECTION)
&& (list->next->children->key > lev)) {
list = list->next;
}
} else {
print_toc_node(out, list, scratch);
}
list = list->next;
}
}
/* print_toc_section_and_children -- we want to stay inside the outline structure */
void print_toc_section_and_children(GString *out, node *list, scratch_pad *scratch) {
#ifdef DEBUG_ON
fprintf(stderr, "print_toc_section_and_children: %d\n",list->key);
#endif
int lev = list->children->key;
/* print current section (parent) */
print_toc_node(out, list, scratch);
scratch->toc_level ++;
/* check for child nodes */
while ((list->next != NULL) && (list->next->key == HEADINGSECTION) && (list->next->children->key > lev)) {
/* next item is also a HEADINGSECTION and is a child */
if (list->next->children->key - lev == 1)
print_toc_section_and_children(out, list->next, scratch);
list = list->next;
}
scratch->toc_level --;
}
/* print_toc_node -- convert given node to MultiMarkdown and append */
void print_toc_node(GString *out, node *n, scratch_pad *scratch) {
char *temp;
int i;
#ifdef DEBUG_ON
fprintf(stderr, "print_toc_node: %d\n",n->key);
#endif
switch (n->key) {
case HEADINGSECTION:
/* Need to handle "nesting" properly */
for (i = 0; i < scratch->toc_level; ++i)
{
g_string_append_printf(out, "\t");
}
g_string_append_printf(out, "* ");
/* Print header */
print_toc_node(out, n->children, scratch);
break;
case H1: case H2: case H3: case H4: case H5: case H6:
if ((n->children != NULL) && (n->children->key == AUTOLABEL)) {
temp = label_from_string(n->children->str);
/* use label for header since one was specified (MMD)*/
g_string_append_printf(out, "[");
print_toc_node_tree(out, n->children, scratch);
g_string_append_printf(out, "][%s]\n", temp);
} else {
temp = label_from_node_tree(n->children);
g_string_append_printf(out, "[");
print_toc_node_tree(out, n->children, scratch);
g_string_append_printf(out, "][%s]\n", temp);
}
free(temp);
break;
case STR:
print_toc_string(out, n->str);
break;
case EMPH:
g_string_append_printf(out, "*");
print_toc_node_tree(out, n->children, scratch);
g_string_append_printf(out, "*");
break;
case STRONG:
g_string_append_printf(out, "**");
print_toc_node_tree(out, n->children, scratch);
g_string_append_printf(out, "**");
break;
case SPACE:
g_string_append_printf(out, "%s", n->str);
break;
case LINK:
print_toc_node_tree(out, n->children, scratch);
break;
case HTML:
break;
case LINKREFERENCE:
break;
case AUTOLABEL:
break;
case VARIABLE:
g_string_append_printf(out, "[%%%s]",n->str);
break;
case LIST:
print_toc_node_tree(out, n->children, scratch);
break;
default: fprintf(stderr, "print_toc_node encountered unknown node key = %d\n",n->key);
break;
}
#ifdef DEBUG_ON
fprintf(stderr, "finish print_toc_node: %d\n", n->key);
#endif
}
/* print_toc_string - print string, escaping for MultiMarkdown */
void print_toc_string(GString *out, char *str) {
while (*str != '\0') {
switch (*str) {
case '[':
g_string_append_printf(out, "\\[");
break;
case ']':
g_string_append_printf(out, "\\]");
break;
default:
g_string_append_c(out, *str);
}
str++;
}
}