rmultimarkdown 4.5.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/LICENSE +75 -0
  2. data/MultiMarkdown-4/GLibFacade.c +294 -0
  3. data/MultiMarkdown-4/GLibFacade.h +95 -0
  4. data/MultiMarkdown-4/beamer.c +179 -0
  5. data/MultiMarkdown-4/beamer.h +11 -0
  6. data/MultiMarkdown-4/critic.c +111 -0
  7. data/MultiMarkdown-4/critic.h +15 -0
  8. data/MultiMarkdown-4/glib.h +11 -0
  9. data/MultiMarkdown-4/html.c +1062 -0
  10. data/MultiMarkdown-4/html.h +14 -0
  11. data/MultiMarkdown-4/latex.c +1137 -0
  12. data/MultiMarkdown-4/latex.h +16 -0
  13. data/MultiMarkdown-4/libMultiMarkdown.h +157 -0
  14. data/MultiMarkdown-4/lyx.c +2163 -0
  15. data/MultiMarkdown-4/lyx.h +36 -0
  16. data/MultiMarkdown-4/lyxbeamer.c +267 -0
  17. data/MultiMarkdown-4/lyxbeamer.h +11 -0
  18. data/MultiMarkdown-4/memoir.c +79 -0
  19. data/MultiMarkdown-4/memoir.h +10 -0
  20. data/MultiMarkdown-4/multimarkdown.c +469 -0
  21. data/MultiMarkdown-4/odf.c +1202 -0
  22. data/MultiMarkdown-4/odf.h +18 -0
  23. data/MultiMarkdown-4/opml.c +188 -0
  24. data/MultiMarkdown-4/opml.h +15 -0
  25. data/MultiMarkdown-4/parse_utilities.c +752 -0
  26. data/MultiMarkdown-4/parser.c +15679 -0
  27. data/MultiMarkdown-4/parser.h +188 -0
  28. data/MultiMarkdown-4/rng.c +117 -0
  29. data/MultiMarkdown-4/rtf.c +648 -0
  30. data/MultiMarkdown-4/rtf.h +17 -0
  31. data/MultiMarkdown-4/strtok.c +56 -0
  32. data/MultiMarkdown-4/strtok.h +9 -0
  33. data/MultiMarkdown-4/text.c +53 -0
  34. data/MultiMarkdown-4/text.h +11 -0
  35. data/MultiMarkdown-4/transclude.c +218 -0
  36. data/MultiMarkdown-4/transclude.h +26 -0
  37. data/MultiMarkdown-4/writer.c +576 -0
  38. data/MultiMarkdown-4/writer.h +34 -0
  39. data/README.md +75 -0
  40. data/Rakefile +85 -0
  41. data/bin/rmultimarkdown +128 -0
  42. data/ext/extconf.h +3 -0
  43. data/ext/extconf.rb +10 -0
  44. data/ext/multi_markdown.c +100 -0
  45. data/lib/multi_markdown.bundle +0 -0
  46. data/lib/multi_markdown.rb +88 -0
  47. data/lib/multi_markdown/version.rb +6 -0
  48. data/lib/rmultimarkdown.rb +1 -0
  49. data/rmultimarkdown.gemspec +37 -0
  50. data/test/multi_markdown_test.rb +64 -0
  51. metadata +122 -0
@@ -0,0 +1,179 @@
1
+ /*
2
+
3
+ beamer.c -- Beamer add-on to LaTeX writer
4
+
5
+ (c) 2013 Fletcher T. Penney (http://fletcherpenney.net/).
6
+
7
+ This program is free software; you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License or the MIT
9
+ license. See LICENSE for details.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ */
17
+
18
+ #include "beamer.h"
19
+
20
+ /* print_beamer_node_tree -- convert node tree to LaTeX */
21
+ void print_beamer_node_tree(GString *out, node *list, scratch_pad *scratch) {
22
+ while (list != NULL) {
23
+ print_beamer_node(out, list, scratch);
24
+ list = list->next;
25
+ }
26
+ }
27
+
28
+ /* print_beamer_node -- convert given node to LaTeX and append */
29
+ void print_beamer_node(GString *out, node *n, scratch_pad *scratch) {
30
+ int lev;
31
+ char *temp;
32
+
33
+ /* If we are forcing a complete document, and METADATA isn't the first thing,
34
+ we need to close <head> */
35
+ if ((scratch->extensions & EXT_COMPLETE)
36
+ && !(scratch->extensions & EXT_HEAD_CLOSED) &&
37
+ !((n->key == FOOTER) || (n->key == METADATA))) {
38
+ pad(out, 2, scratch);
39
+ scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED;
40
+ }
41
+ switch (n->key) {
42
+ case FOOTER:
43
+ print_beamer_endnotes(out, scratch);
44
+ g_string_append_printf(out, "\\mode<all>\n");
45
+ if (scratch->latex_footer != NULL) {
46
+ pad(out, 2, scratch);
47
+ g_string_append_printf(out,"\\input{%s}\n", scratch->latex_footer);
48
+ }
49
+ if (scratch->extensions & EXT_COMPLETE) {
50
+ g_string_append_printf(out, "\n\\end{document}");
51
+ }
52
+ g_string_append_printf(out, "\\mode*\n");
53
+ break;
54
+ case LISTITEM:
55
+ pad(out, 1, scratch);
56
+ g_string_append_printf(out, "\\item<+-> ");
57
+ scratch->padded = 2;
58
+ print_latex_node_tree(out, n->children, scratch);
59
+ g_string_append_printf(out, "\n");
60
+ break;
61
+ case HEADINGSECTION:
62
+ if (n->children->key -H1 + scratch->baseheaderlevel == 3) {
63
+ pad(out, 2, scratch);
64
+ g_string_append_printf(out, "\\begin{frame}");
65
+ /* TODO: Fix this */
66
+ if (tree_contains_key(n->children,VERBATIM)) {
67
+ g_string_append_printf(out, "[fragile]");
68
+ }
69
+ scratch->padded = 0;
70
+ print_beamer_node_tree(out, n->children, scratch);
71
+ g_string_append_printf(out, "\n\n\\end{frame}\n\n");
72
+ scratch->padded = 2;
73
+ } else if (n->children->key -H1 + scratch->baseheaderlevel == 4) {
74
+ pad(out, 1, scratch);
75
+ g_string_append_printf(out, "\\mode<article>{\n");
76
+ scratch->padded = 0;
77
+ print_beamer_node_tree(out, n->children->next, scratch);
78
+ g_string_append_printf(out, "\n\n}\n\n");
79
+ scratch->padded = 2;
80
+ } else {
81
+ print_beamer_node_tree(out, n->children, scratch);
82
+ }
83
+ break;
84
+ case H1: case H2: case H3: case H4: case H5: case H6:
85
+ pad(out, 2, scratch);
86
+ lev = n->key - H1 + scratch->baseheaderlevel; /* assumes H1 ... H6 are in order */
87
+ switch (lev) {
88
+ case 1:
89
+ g_string_append_printf(out, "\\part{");
90
+ break;
91
+ case 2:
92
+ g_string_append_printf(out, "\\section{");
93
+ break;
94
+ case 3:
95
+ g_string_append_printf(out, "\\frametitle{");
96
+ break;
97
+ default:
98
+ g_string_append_printf(out, "\\emph{");
99
+ break;
100
+ }
101
+ /* generate a label for each header (MMD);
102
+ don't allow footnotes since invalid here */
103
+ scratch->no_latex_footnote = TRUE;
104
+ if (n->children->key == AUTOLABEL) {
105
+ temp = label_from_string(n->children->str);
106
+ print_latex_node_tree(out, n->children->next, scratch);
107
+ g_string_append_printf(out, "}\n\\label{%s}", temp);
108
+ free(temp);
109
+ } else {
110
+ print_latex_node_tree(out, n->children, scratch);
111
+ temp = label_from_node_tree(n->children);
112
+ g_string_append_printf(out, "}\n\\label{%s}", temp);
113
+ free(temp);
114
+ }
115
+ scratch->no_latex_footnote = FALSE;
116
+ scratch->padded = 0;
117
+ break;
118
+ default:
119
+ /* most things are not changed for memoir output */
120
+ print_latex_node(out, n, scratch);
121
+ }
122
+ }
123
+
124
+ /* print_beamer_endnotes */
125
+ void print_beamer_endnotes(GString *out, scratch_pad *scratch) {
126
+ scratch->used_notes = reverse_list(scratch->used_notes);
127
+ node *note = scratch->used_notes;
128
+ #ifdef DEBUG_ON
129
+ fprintf(stderr, "start endnotes\n");
130
+ #endif
131
+
132
+ if ((note == NULL) || ((note->key == KEY_COUNTER) && (note->next == NULL)))
133
+ return;
134
+ while (note != NULL) {
135
+ if (note->key == CITATIONSOURCE)
136
+ break;
137
+ note = note->next;
138
+ }
139
+
140
+ if (note == NULL)
141
+ return;
142
+
143
+ note = scratch->used_notes;
144
+
145
+ /* TODO: need CITATIONSOURCE to print bibliography */
146
+ #ifdef DEBUG_ON
147
+ fprintf(stderr, "there are endnotes to print\n");
148
+ #endif
149
+
150
+ pad(out, 2, scratch);
151
+ g_string_append_printf(out, "\\part{Bibliography}\n\\begin{frame}[allowframebreaks]\n\\frametitle{Bibliography}\n\\def\\newblock{}\n\\begin{thebibliography}{0}\n");
152
+ while ( note != NULL) {
153
+ if (note->key == KEY_COUNTER) {
154
+ note = note->next;
155
+ continue;
156
+ }
157
+
158
+ pad(out, 1, scratch);
159
+
160
+ if (note->key == CITATIONSOURCE) {
161
+ g_string_append_printf(out, "\\bibitem{%s}\n", note->str);
162
+ scratch->padded = 2;
163
+
164
+ print_latex_node(out, note, scratch);
165
+ pad(out, 1, scratch);
166
+ scratch->padded = 1;
167
+ } else {
168
+ /* footnotes handled elsewhere */
169
+ }
170
+
171
+ note = note->next;
172
+ }
173
+ pad(out,2, scratch);
174
+ g_string_append_printf(out, "\\end{thebibliography}\n\\end{frame}\n\n");
175
+ scratch->padded = 0;
176
+ #ifdef DEBUG_ON
177
+ fprintf(stderr, "finish endnotes\n");
178
+ #endif
179
+ }
@@ -0,0 +1,11 @@
1
+ #ifndef BEAMER_PARSER_H
2
+ #define BEAMER_PARSER_H
3
+
4
+ #include "parser.h"
5
+ #include "latex.h"
6
+
7
+ void print_beamer_node_tree(GString *out, node *list, scratch_pad *scratch);
8
+ void print_beamer_node(GString *out, node *n, scratch_pad *scratch);
9
+ void print_beamer_endnotes(GString *out, scratch_pad *scratch);
10
+
11
+ #endif
@@ -0,0 +1,111 @@
1
+ /*
2
+
3
+ critic.c -- CriticMarkup preprocessor
4
+
5
+ <http://criticmarkup.com>
6
+
7
+ (c) 2013 Fletcher T. Penney (http://fletcherpenney.net/).
8
+
9
+ This program is free software; you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License or the MIT
11
+ license. See LICENSE for details.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ */
19
+
20
+ #include "critic.h"
21
+
22
+ void print_critic_accept_node_tree(GString *out, node *list, scratch_pad *scratch) {
23
+ while (list != NULL) {
24
+ print_critic_accept_node(out, list, scratch);
25
+ list = list->next;
26
+ }
27
+ }
28
+
29
+ void print_critic_reject_node_tree(GString *out, node *list, scratch_pad *scratch) {
30
+ while (list != NULL) {
31
+ print_critic_reject_node(out, list, scratch);
32
+ list = list->next;
33
+ }
34
+ }
35
+
36
+ void print_critic_html_highlight_node_tree(GString *out, node *list, scratch_pad *scratch) {
37
+ while (list != NULL) {
38
+ print_critic_html_highlight_node(out, list, scratch);
39
+ list = list->next;
40
+ }
41
+ }
42
+
43
+ void print_critic_accept_node(GString *out, node *n, scratch_pad *scratch) {
44
+ if (n == NULL)
45
+ return;
46
+
47
+ switch (n->key) {
48
+ case LIST:
49
+ case CRITICSUBSTITUTION:
50
+ print_critic_accept_node_tree(out, n->children, scratch);
51
+ break;
52
+ case CRITICDELETION:
53
+ case CRITICCOMMENT:
54
+ break;
55
+ case CRITICHIGHLIGHT:
56
+ case CRITICADDITION:
57
+ default:
58
+ g_string_append_printf(out,"%s",n->str);
59
+ break;
60
+ }
61
+ }
62
+
63
+ void print_critic_reject_node(GString *out, node *n, scratch_pad *scratch) {
64
+ if (n == NULL)
65
+ return;
66
+
67
+ switch (n->key) {
68
+ case LIST:
69
+ case CRITICSUBSTITUTION:
70
+ print_critic_reject_node_tree(out, n->children, scratch);
71
+ break;
72
+ case CRITICADDITION:
73
+ case CRITICCOMMENT:
74
+ break;
75
+ case CRITICHIGHLIGHT:
76
+ case CRITICDELETION:
77
+ default:
78
+ g_string_append_printf(out,"%s",n->str);
79
+ break;
80
+ }
81
+ }
82
+
83
+ void print_critic_html_highlight_node(GString *out, node *n, scratch_pad *scratch) {
84
+ if (n == NULL)
85
+ return;
86
+
87
+ switch (n->key) {
88
+ case LIST:
89
+ print_critic_html_highlight_node_tree(out, n->children, scratch);
90
+ break;
91
+ case CRITICSUBSTITUTION:
92
+ print_critic_html_highlight_node_tree(out, n->children, scratch);
93
+ break;
94
+ case CRITICADDITION:
95
+ g_string_append_printf(out,"<ins>%s</ins>",n->str);
96
+ break;
97
+ case CRITICCOMMENT:
98
+ /* Hide comments for now */
99
+ /* g_string_append_printf(out, "<span class=\"critic comment\">%s</span>", n->str); */
100
+ break;
101
+ case CRITICHIGHLIGHT:
102
+ g_string_append_printf(out,"<mark>%s</mark>",n->str);
103
+ break;
104
+ case CRITICDELETION:
105
+ g_string_append_printf(out,"<del>%s</del>",n->str);
106
+ break;
107
+ default:
108
+ g_string_append_printf(out,"%s",n->str);
109
+ break;
110
+ }
111
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef CRITIC_PARSER_H
2
+ #define CRITIC_PARSER_H
3
+
4
+ #include "parser.h"
5
+ #include "writer.h"
6
+
7
+
8
+ void print_critic_accept_node_tree(GString *out, node *list, scratch_pad *scratch);
9
+ void print_critic_reject_node_tree(GString *out, node *list, scratch_pad *scratch);
10
+ void print_critic_html_highlight_node_tree(GString *out, node *list, scratch_pad *scratch);
11
+ void print_critic_accept_node(GString *out, node *list, scratch_pad *scratch);
12
+ void print_critic_reject_node(GString *out, node *list, scratch_pad *scratch);
13
+ void print_critic_html_highlight_node(GString *out, node *list, scratch_pad *scratch);
14
+
15
+ #endif
@@ -0,0 +1,11 @@
1
+ /*
2
+ * glib.h
3
+ * MultiMarkdown
4
+ *
5
+ * Created by Daniel Jalkut on 7/26/11.
6
+ * Copyright 2011 __MyCompanyName__. All rights reserved.
7
+ *
8
+ */
9
+
10
+ /* Just a dummy file to keep the glib-dependent sources compiling as we would hope */
11
+ #include "GLibFacade.h"
@@ -0,0 +1,1062 @@
1
+ /*
2
+
3
+ html.c -- HTML writer
4
+
5
+ (c) 2013 Fletcher T. Penney (http://fletcherpenney.net/).
6
+
7
+ Derived from peg-multimarkdown, which was forked from peg-markdown,
8
+ which is (c) 2008 John MacFarlane (jgm at berkeley dot edu), and
9
+ licensed under GNU GPL or MIT.
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of the GNU General Public License or the MIT
13
+ license. See LICENSE for details.
14
+
15
+ This program is distributed in the hope that it will be useful,
16
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ GNU General Public License for more details.
19
+
20
+ */
21
+
22
+ #include "html.h"
23
+
24
+ bool is_html_complete_doc(node *meta);
25
+ void print_col_group(GString *out,scratch_pad *scratch);
26
+
27
+
28
+ /* print_html_node_tree -- convert node tree to HTML */
29
+ void print_html_node_tree(GString *out, node *list, scratch_pad *scratch) {
30
+ while (list != NULL) {
31
+ print_html_node(out, list, scratch);
32
+ list = list->next;
33
+ }
34
+ }
35
+
36
+ /* print_html_node -- convert given node to HTML and append */
37
+ void print_html_node(GString *out, node *n, scratch_pad *scratch) {
38
+ node *temp_node;
39
+ link_data *temp_link_data = NULL;
40
+ char *temp;
41
+ int lev;
42
+ int random;
43
+ char temp_type;
44
+ char *width = NULL;
45
+ char *height = NULL;
46
+ GString *temp_str;
47
+
48
+ if (n == NULL)
49
+ return;
50
+
51
+ /* debugging statement */
52
+ #ifdef DEBUG_ON
53
+ fprintf(stderr, "print_html_node: %d\n",n->key);
54
+ #endif
55
+
56
+ /* If we are forcing a complete document, and METADATA isn't the first thing,
57
+ we need to close <head> */
58
+ if ((scratch->extensions & EXT_COMPLETE)
59
+ && !(scratch->extensions & EXT_HEAD_CLOSED) &&
60
+ !((n->key == FOOTER) || (n->key == METADATA))) {
61
+ g_string_append_printf(out, "</head>\n<body>\n");
62
+ scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED;
63
+ }
64
+ switch (n->key) {
65
+ case NO_TYPE:
66
+ break;
67
+ case LIST:
68
+ print_html_node_tree(out,n->children,scratch);
69
+ break;
70
+ case STR:
71
+ print_html_string(out,n->str, scratch);
72
+ break;
73
+ case SPACE:
74
+ g_string_append_printf(out,"%s",n->str);
75
+ break;
76
+ case PLAIN:
77
+ pad(out,1, scratch);
78
+ print_html_node_tree(out,n->children, scratch);
79
+ scratch->padded = 0;
80
+ break;
81
+ case PARA:
82
+ pad(out, 2, scratch);
83
+ g_string_append_printf(out, "<p>");
84
+ print_html_node_tree(out,n->children,scratch);
85
+ if (scratch->footnote_to_print != 0){
86
+ scratch->footnote_para_counter --;
87
+ if (scratch->footnote_para_counter == 0) {
88
+ if (scratch->extensions & EXT_RANDOM_FOOT) {
89
+ srand(scratch->random_seed_base + scratch->footnote_to_print);
90
+ random = rand() % 99999 + 1;
91
+ } else {
92
+ random = scratch->footnote_to_print;
93
+ }
94
+
95
+ g_string_append_printf(out, " <a href=\"#fnref:%d\" title=\"return to article\" class=\"reversefootnote\">&#160;&#8617;</a>", random);
96
+ scratch->footnote_to_print = 0;
97
+ }
98
+ }
99
+ g_string_append_printf(out, "</p>");
100
+ scratch->padded = 0;
101
+ break;
102
+ case HRULE:
103
+ pad(out, 2, scratch);
104
+ g_string_append_printf(out, "<hr />");
105
+ scratch->padded = 0;
106
+ break;
107
+ case HTMLBLOCK:
108
+ pad(out, 2, scratch);
109
+ g_string_append_printf(out, "%s", n->str);
110
+ scratch->padded = 0;
111
+ break;
112
+ case VERBATIM:
113
+ pad(out, 2, scratch);
114
+ if ((n->children != NULL) && (n->children->key == VERBATIMTYPE)) {
115
+ trim_trailing_whitespace(n->children->str);
116
+ if (strlen(n->children->str) > 0)
117
+ g_string_append_printf(out, "<pre><code class=\"%s\">", n->children->str);
118
+ else
119
+ g_string_append_printf(out, "%s", "<pre><code>");
120
+ } else {
121
+ g_string_append_printf(out, "%s", "<pre><code>");
122
+ }
123
+ print_html_string(out, n->str, scratch);
124
+ g_string_append_printf(out, "%s", "</code></pre>");
125
+ scratch->padded = 0;
126
+ break;
127
+ case BULLETLIST:
128
+ pad(out, 2, scratch);
129
+ g_string_append_printf(out, "%s", "<ul>");
130
+ scratch->padded = 0;
131
+ print_html_node_tree(out, n->children, scratch);
132
+ pad(out, 1, scratch);
133
+ g_string_append_printf(out, "%s", "</ul>");
134
+ scratch->padded = 0;
135
+ break;
136
+ case ORDEREDLIST:
137
+ pad(out, 2, scratch);
138
+ g_string_append_printf(out, "%s", "<ol>");
139
+ scratch->padded = 0;
140
+ print_html_node_tree(out, n->children, scratch);
141
+ pad(out, 1, scratch);
142
+ g_string_append_printf(out, "</ol>");
143
+ scratch->padded = 0;
144
+ break;
145
+ case LISTITEM:
146
+ pad(out, 1, scratch);
147
+ g_string_append_printf(out, "<li>");
148
+ scratch->padded = 2;
149
+ print_html_node_tree(out, n->children, scratch);
150
+ g_string_append_printf(out, "</li>");
151
+ scratch->padded = 0;
152
+ break;
153
+ case METADATA:
154
+ /* Not if snippet only */
155
+ if (scratch->extensions & EXT_SNIPPET) {
156
+ is_html_complete_doc(n);
157
+ print_html_node_tree(out,n->children, scratch);
158
+ break;
159
+ }
160
+
161
+ if (!(scratch->extensions & EXT_COMPLETE) && (is_html_complete_doc(n))) {
162
+ /* We have metadata to include, and didn't already force complete */
163
+ g_string_append_printf(out,
164
+ "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\"/>\n");
165
+ /* either way, now we need to be a complete doc */
166
+ scratch->extensions = scratch->extensions | EXT_COMPLETE;
167
+ } else {
168
+ /* Ensure we lowercase metadata */
169
+ is_html_complete_doc(n);
170
+ }
171
+ /* print the metadata */
172
+ scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED;
173
+ print_html_node_tree(out,n->children, scratch);
174
+ if (scratch->extensions & EXT_COMPLETE) {
175
+ /* need to close head and open body */
176
+ g_string_append_printf(out, "</head>\n<body>\n\n");
177
+ }
178
+ break;
179
+ case METAKEY:
180
+ if (strcmp(n->str, "baseheaderlevel") == 0) {
181
+ scratch->baseheaderlevel = atoi(n->children->str);
182
+ break;
183
+ } else if (strcmp(n->str, "xhtmlheaderlevel") == 0) {
184
+ scratch->baseheaderlevel = atoi(n->children->str);
185
+ break;
186
+ } else if (strcmp(n->str, "htmlheaderlevel") == 0) {
187
+ scratch->baseheaderlevel = atoi(n->children->str);
188
+ break;
189
+ } else if (strcmp(n->str, "quoteslanguage") == 0) {
190
+ temp = label_from_node_tree(n->children);
191
+ if ((strcmp(temp, "nl") == 0) || (strcmp(temp, "dutch") == 0)) { scratch->language = DUTCH; } else
192
+ if ((strcmp(temp, "de") == 0) || (strcmp(temp, "german") == 0)) { scratch->language = GERMAN; } else
193
+ if (strcmp(temp, "germanguillemets") == 0) { scratch->language = GERMANGUILL; } else
194
+ if ((strcmp(temp, "fr") == 0) || (strcmp(temp, "french") == 0)) { scratch->language = FRENCH; } else
195
+ if ((strcmp(temp, "sv") == 0) || (strcmp(temp, "swedish") == 0)) { scratch->language = SWEDISH; }
196
+ free(temp);
197
+ break;
198
+ }
199
+
200
+ /* Don't handle other metadata if we're snippet only */
201
+ if (scratch->extensions & EXT_SNIPPET)
202
+ break;
203
+
204
+ if (strcmp(n->str, "title") == 0) {
205
+ g_string_append_printf(out, "\t<title>");
206
+ print_html_node(out, n->children, scratch);
207
+ g_string_append_printf(out, "</title>\n");
208
+ } else if (strcmp(n->str, "css") == 0) {
209
+ g_string_append_printf(out, "\t<link type=\"text/css\" rel=\"stylesheet\" href=\"");
210
+ print_html_node(out, n->children, scratch);
211
+ g_string_append_printf(out, "\"/>\n");
212
+ } else if (strcmp(n->str, "xhtmlheader") == 0) {
213
+ trim_trailing_whitespace(n->children->str);
214
+ print_raw_node(out, n->children);
215
+ g_string_append_printf(out, "\n");
216
+ } else if (strcmp(n->str, "htmlheader") == 0) {
217
+ trim_trailing_whitespace(n->children->str);
218
+ print_raw_node(out, n->children);
219
+ g_string_append_printf(out, "\n");
220
+ } else {
221
+ g_string_append_printf(out,"\t<meta name=\"%s\" content=\"",n->str);
222
+ print_html_node(out,n->children,scratch);
223
+ g_string_append_printf(out,"\"/>\n");
224
+ }
225
+ break;
226
+ case METAVALUE:
227
+ trim_trailing_whitespace(n->str);
228
+ print_html_string(out,n->str, scratch);
229
+ break;
230
+ case FOOTER:
231
+ break;
232
+ case HEADINGSECTION:
233
+ print_html_node_tree(out,n->children,scratch);
234
+ break;
235
+ case H1: case H2: case H3: case H4: case H5: case H6:
236
+ lev = n->key - H1 + scratch->baseheaderlevel; /* assumes H1 ... H6 are in order */
237
+ if (lev > 6)
238
+ lev = 6; /* Max at level 6 */
239
+ pad(out, 2, scratch);
240
+ if ( scratch->extensions & EXT_COMPATIBILITY ) {
241
+ /* Use regular Markdown header format */
242
+ g_string_append_printf(out, "<h%1d>", lev);
243
+ print_html_node_tree(out, n->children, scratch);
244
+ } else if (n->children->key == AUTOLABEL) {
245
+ temp = label_from_string(n->children->str);
246
+ /* use label for header since one was specified (MMD)*/
247
+ g_string_append_printf(out, "<h%d id=\"%s\">", lev,temp);
248
+ print_html_node_tree(out, n->children->next, scratch);
249
+ free(temp);
250
+ } else if ( scratch->extensions & EXT_NO_LABELS ) {
251
+ /* Don't generate a label */
252
+ g_string_append_printf(out, "<h%1d>", lev);
253
+ print_html_node_tree(out, n->children, scratch);
254
+ } else {
255
+ /* generate a label by default for MMD */
256
+ temp = label_from_node_tree(n->children);
257
+ g_string_append_printf(out, "<h%d id=\"%s\">", lev, temp);
258
+ print_html_node_tree(out, n->children, scratch);
259
+ free(temp);
260
+ }
261
+ g_string_append_printf(out, "</h%1d>", lev);
262
+ scratch->padded = 0;
263
+ break;
264
+ case APOSTROPHE:
265
+ print_html_localized_typography(out, APOS, scratch);
266
+ break;
267
+ case ELLIPSIS:
268
+ print_html_localized_typography(out, ELLIP, scratch);
269
+ break;
270
+ case EMDASH:
271
+ print_html_localized_typography(out, MDASH, scratch);
272
+ break;
273
+ case ENDASH:
274
+ print_html_localized_typography(out, NDASH, scratch);
275
+ break;
276
+ case SINGLEQUOTED:
277
+ print_html_localized_typography(out, LSQUOTE, scratch);
278
+ print_html_node_tree(out, n->children, scratch);
279
+ print_html_localized_typography(out, RSQUOTE, scratch);
280
+ break;
281
+ case DOUBLEQUOTED:
282
+ print_html_localized_typography(out, LDQUOTE, scratch);
283
+ print_html_node_tree(out, n->children, scratch);
284
+ print_html_localized_typography(out, RDQUOTE, scratch);
285
+ break;
286
+ case LINEBREAK:
287
+ g_string_append_printf(out, "<br/>\n");
288
+ break;
289
+ case MATHSPAN:
290
+ if (n->str[0] == '$') {
291
+ n->str[strlen(n->str)-1] = '\0';
292
+ if (n->str[1] == '$') {
293
+ n->str[strlen(n->str)-1] = '\0';
294
+ g_string_append_printf(out, "<span class=\"math\">\\[%s\\]</span>",&n->str[2]);
295
+ } else {
296
+ g_string_append_printf(out, "<span class=\"math\">\\(%s\\)</span>",&n->str[1]);
297
+ }
298
+ } else if (n->str[strlen(n->str) - 1] == ']') {
299
+ n->str[strlen(n->str) - 3] = '\0';
300
+ g_string_append_printf(out, "<span class=\"math\">%s\\]</span>",n->str);
301
+ } else {
302
+ n->str[strlen(n->str) - 3] = '\0';
303
+ g_string_append_printf(out, "<span class=\"math\">%s\\)</span>",n->str);
304
+ }
305
+ break;
306
+ case STRONG:
307
+ g_string_append_printf(out, "<strong>");
308
+ print_html_node_tree(out,n->children,scratch);
309
+ g_string_append_printf(out, "</strong>");
310
+ break;
311
+ case EMPH:
312
+ g_string_append_printf(out, "<em>");
313
+ print_html_node_tree(out,n->children,scratch);
314
+ g_string_append_printf(out, "</em>");
315
+ break;
316
+ case LINKREFERENCE:
317
+ break;
318
+ case LINK:
319
+ #ifdef DEBUG_ON
320
+ fprintf(stderr, "print html link: '%s'\n",n->str);
321
+ #endif
322
+ /* Stash a copy of the link data */
323
+ if (n->link_data != NULL)
324
+ temp_link_data = mk_link_data(n->link_data->label, n->link_data->source, n->link_data->title, n->link_data->attr);
325
+
326
+ /* Do we have proper info? */
327
+ if ((n->link_data->label == NULL) &&
328
+ (n->link_data->source == NULL)) {
329
+ /* we seem to be a [foo][] style link */
330
+ /* so load a label */
331
+ temp_str = g_string_new("");
332
+ print_raw_node_tree(temp_str, n->children);
333
+ n->link_data->label = temp_str->str;
334
+ g_string_free(temp_str, FALSE);
335
+ }
336
+ /* Load reference data */
337
+ if (n->link_data->label != NULL) {
338
+ temp = strdup(n->link_data->label);
339
+
340
+ n->link_data->attr = NULL;
341
+ free_link_data(n->link_data);
342
+
343
+ n->link_data = extract_link_data(temp, scratch);
344
+ if (n->link_data == NULL) {
345
+ /* replace original text since no definition found */
346
+ g_string_append_printf(out, "[");
347
+ print_html_node(out, n->children, scratch);
348
+ g_string_append_printf(out,"]");
349
+ if (n->children->next != NULL) {
350
+ g_string_append_printf(out, "[");
351
+ print_html_node_tree(out, n->children->next, scratch);
352
+ g_string_append_printf(out,"]");
353
+ } else if (n->str != NULL) {
354
+ /* no title label, so see if we stashed str*/
355
+ g_string_append_printf(out, "%s", n->str);
356
+ } else {
357
+ g_string_append_printf(out, "[%s]",temp);
358
+ }
359
+
360
+ free(temp);
361
+
362
+ /* Restore stashed copy */
363
+ n->link_data = temp_link_data;
364
+
365
+ break;
366
+ }
367
+ free(temp);
368
+ }
369
+ g_string_append_printf(out, "<a");
370
+ if (n->link_data->source != NULL) {
371
+ g_string_append_printf(out, " href=\"");
372
+ if (strncmp(n->link_data->source,"mailto:", 6) == 0) {
373
+ scratch->obfuscate = 1; /* flag obfuscated */
374
+ }
375
+ print_html_string(out,n->link_data->source, scratch);
376
+ g_string_append_printf(out, "\"");
377
+ }
378
+ if ((n->link_data->title != NULL) && (strlen(n->link_data->title) > 0)) {
379
+ g_string_append_printf(out, " title=\"");
380
+ print_html_string(out, n->link_data->title, scratch);
381
+ g_string_append_printf(out, "\"");
382
+ }
383
+ print_html_node_tree(out, n->link_data->attr, scratch);
384
+ g_string_append_printf(out, ">");
385
+ if (n->children != NULL)
386
+ print_html_node_tree(out,n->children,scratch);
387
+ g_string_append_printf(out, "</a>");
388
+ scratch->obfuscate = 0;
389
+
390
+ /* Restore stashed copy */
391
+ n->link_data->attr = NULL;
392
+ free_link_data(n->link_data);
393
+ n->link_data = temp_link_data;
394
+
395
+ break;
396
+ case ATTRKEY:
397
+ if ( (strcmp(n->str,"height") == 0) || (strcmp(n->str, "width") == 0)) {
398
+ } else {
399
+ g_string_append_printf(out, " %s=\"%s\"", n->str,
400
+ n->children->str);
401
+ }
402
+ break;
403
+ case REFNAME:
404
+ case SOURCE:
405
+ case TITLE:
406
+ break;
407
+ case IMAGEBLOCK:
408
+ pad(out,2, scratch);
409
+ case IMAGE:
410
+ #ifdef DEBUG_ON
411
+ fprintf(stderr, "print image\n");
412
+ #endif
413
+ /* Stash a copy of the link data */
414
+ if (n->link_data != NULL)
415
+ temp_link_data = mk_link_data(n->link_data->label, n->link_data->source, n->link_data->title, n->link_data->attr);
416
+
417
+ if (n->key == IMAGEBLOCK)
418
+ g_string_append_printf(out, "<figure>\n");
419
+ /* Do we have proper info? */
420
+ if ((n->link_data->label == NULL) &&
421
+ (n->link_data->source == NULL)) {
422
+ /* we seem to be a [foo][] style link */
423
+ /* so load a label */
424
+ temp_str = g_string_new("");
425
+ print_raw_node_tree(temp_str, n->children);
426
+ n->link_data->label = temp_str->str;
427
+ g_string_free(temp_str, FALSE);
428
+ }
429
+ #ifdef DEBUG_ON
430
+ fprintf(stderr, "load reference data\n");
431
+ #endif
432
+ /* Load reference data */
433
+ if (n->link_data->label != NULL) {
434
+ temp = strdup(n->link_data->label);
435
+
436
+ n->link_data->attr = NULL;
437
+ free_link_data(n->link_data);
438
+
439
+ n->link_data = extract_link_data(temp, scratch);
440
+
441
+ if (n->link_data == NULL) {
442
+ g_string_append_printf(out, "![");
443
+ print_html_node_tree(out, n->children, scratch);
444
+ g_string_append_printf(out,"][%s]",temp);
445
+
446
+ /* Restore stashed copy */
447
+ n->link_data = temp_link_data;
448
+
449
+ free(temp);
450
+
451
+ break;
452
+ }
453
+ free(temp);
454
+ }
455
+ #ifdef DEBUG_ON
456
+ fprintf(stderr, "create img\n");
457
+ #endif
458
+ g_string_append_printf(out, "<img");
459
+ if (n->link_data->source != NULL)
460
+ g_string_append_printf(out, " src=\"%s\"",n->link_data->source);
461
+ if (n->children != NULL) {
462
+ g_string_append_printf(out, " alt=\"");
463
+ temp_str = g_string_new("");
464
+ print_raw_node_tree(temp_str, n->children);
465
+ print_html_string(out, temp_str->str, scratch);
466
+ g_string_free(temp_str, true);
467
+ g_string_append_printf(out, "\"");
468
+ } else {
469
+ g_string_append_printf(out, " alt=\"%s\"",n->link_data->title);
470
+ }
471
+ if (!(scratch->extensions & EXT_COMPATIBILITY)) {
472
+ if (n->link_data->label != NULL) {
473
+ temp = label_from_string(n->link_data->label);
474
+ g_string_append_printf(out, " id=\"%s\"",temp);
475
+ free(temp);
476
+ }
477
+ }
478
+ if ((n->link_data->title != NULL) && (strlen(n->link_data->title) > 0)) {
479
+ g_string_append_printf(out, " title=\"");
480
+ print_html_string(out, n->link_data->title, scratch);
481
+ g_string_append_printf(out, "\"");
482
+ }
483
+ #ifdef DEBUG_ON
484
+ fprintf(stderr, "attributes\n");
485
+ #endif
486
+ if (n->link_data->attr != NULL) {
487
+ temp_node = node_for_attribute("height",n->link_data->attr);
488
+ if (temp_node != NULL)
489
+ height = strdup(temp_node->children->str);
490
+ temp_node = node_for_attribute("width",n->link_data->attr);
491
+ if (temp_node != NULL)
492
+ width = strdup(temp_node->children->str);
493
+ if ((height != NULL) || (width != NULL)) {
494
+ #ifdef DEBUG_ON
495
+ fprintf(stderr, "width/height\n");
496
+ #endif
497
+ g_string_append_printf(out, " style=\"");
498
+ if (height != NULL)
499
+ g_string_append_printf(out, "height:%s;", height);
500
+ if (width != NULL)
501
+ g_string_append_printf(out, "width:%s;", width);
502
+ g_string_append_printf(out, "\"");
503
+ }
504
+ #ifdef DEBUG_ON
505
+ fprintf(stderr, "other attributes\n");
506
+ #endif
507
+ print_html_node_tree(out, n->link_data->attr, scratch);
508
+ free(height);
509
+ free(width);
510
+ }
511
+ g_string_append_printf(out, " />");
512
+ if (n->key == IMAGEBLOCK) {
513
+ if ((n->children != NULL) && (n->children->children != NULL) && (n->children->children->str != NULL)) {
514
+ g_string_append_printf(out, "\n<figcaption>");
515
+ print_html_node(out,n->children,scratch);
516
+ g_string_append_printf(out, "</figcaption>");
517
+ }
518
+ g_string_append_printf(out,"\n</figure>");
519
+ scratch->padded = 0;
520
+ }
521
+
522
+ /* Restore stashed copy */
523
+ n->link_data->attr = NULL;
524
+ free_link_data(n->link_data);
525
+ n->link_data = temp_link_data;
526
+
527
+ break;
528
+ #ifdef DEBUG_ON
529
+ fprintf(stderr, "finish image\n");
530
+ #endif
531
+ case NOTEREFERENCE:
532
+ lev = note_number_for_node(n, scratch);
533
+ temp_node = node_for_count(scratch->used_notes, lev);
534
+
535
+ if (scratch->extensions & EXT_RANDOM_FOOT) {
536
+ srand(scratch->random_seed_base + lev);
537
+ random = rand() % 99999 + 1;
538
+ } else {
539
+ random = lev;
540
+ }
541
+
542
+ if (temp_node->key == GLOSSARYSOURCE) {
543
+ if (lev > scratch->max_footnote_num) {
544
+ g_string_append_printf(out, "<a href=\"#fn:%d\" id=\"fnref:%d\" title=\"see footnote\" class=\"footnote glossary\">[%d]</a>",
545
+ random, random, lev);
546
+ scratch->max_footnote_num = lev;
547
+ } else {
548
+ g_string_append_printf(out, "<a href=\"#fn:%d\" title=\"see footnote\" class=\"footnote glossary\">[%d]</a>",
549
+ random, lev);
550
+ }
551
+ } else {
552
+ if (lev > scratch->max_footnote_num) {
553
+ g_string_append_printf(out, "<a href=\"#fn:%d\" id=\"fnref:%d\" title=\"see footnote\" class=\"footnote\">[%d]</a>",
554
+ random, random, lev);
555
+ scratch->max_footnote_num = lev;
556
+ } else {
557
+ g_string_append_printf(out, "<a href=\"#fn:%d\" title=\"see footnote\" class=\"footnote\">[%d]</a>",
558
+ random, lev);
559
+ }
560
+ }
561
+ break;
562
+ case NOCITATION:
563
+ case CITATION:
564
+ #ifdef DEBUG_ON
565
+ fprintf(stderr, "print cite\n");
566
+ #endif
567
+ if ((n->link_data != NULL) && (strncmp(n->link_data->label,"[#",2) == 0)) {
568
+ fprintf(stderr, "external cite\n");
569
+ /* external citation (e.g. BibTeX) */
570
+ if (n->key == NOCITATION) {
571
+ g_string_append_printf(out, "<span class=\"notcited\" id=\"%s\"/>",n->str);
572
+ } else {
573
+ g_string_append_printf(out, "<span class=\"externalcitation\">");
574
+ g_string_append_printf(out, "</span>");
575
+ }
576
+ } else {
577
+ #ifdef DEBUG_ON
578
+ fprintf(stderr, "internal cite\n");
579
+ #endif
580
+ /* MMD citation, so output as footnote */
581
+ /* TODO: create separate stream from footnotes */
582
+ lev = 0;
583
+ if (n->link_data != NULL)
584
+ lev = note_number_for_label(n->link_data->label, scratch);
585
+ if (lev != 0) {
586
+ #ifdef DEBUG_ON
587
+ fprintf(stderr, "matching cite found\n");
588
+ #endif
589
+ if (scratch->extensions & EXT_RANDOM_FOOT) {
590
+ srand(scratch->random_seed_base + lev);
591
+ random = rand() % 99999 + 1;
592
+ } else {
593
+ random = lev;
594
+ }
595
+
596
+ temp_node = node_for_count(scratch->used_notes, lev);
597
+ /* flag that this is used as a citation */
598
+ temp_node->key = CITATIONSOURCE;
599
+ if (lev > scratch->max_footnote_num) {
600
+ scratch->max_footnote_num = lev;
601
+ }
602
+ if (n->key == NOCITATION) {
603
+ g_string_append_printf(out, "<span class=\"notcited\" id=\"%d\">",random);
604
+ } else {
605
+ g_string_append_printf(out, "<a class=\"citation\" href=\"#fn:%d\" title=\"Jump to citation\">[",
606
+ random);
607
+ if (n->children != NULL) {
608
+ g_string_append_printf(out, "<span class=\"locator\">");
609
+ print_html_node(out, n->children, scratch);
610
+ g_string_append_printf(out, "</span>, %d]", lev);
611
+ } else {
612
+ g_string_append_printf(out, "%d]", lev);
613
+ }
614
+ }
615
+ g_string_append_printf(out, "<span class=\"citekey\" style=\"display:none\">%s</span>", n->link_data->label);
616
+ if (n->key == NOCITATION) {
617
+ g_string_append_printf(out, "</span>");
618
+ } else {
619
+ g_string_append_printf(out, "</a>");
620
+ }
621
+ } else {
622
+ /* not located -- this is external cite */
623
+ #ifdef DEBUG_ON
624
+ fprintf(stderr, "no match for cite: '%s'\n",n->link_data->label);
625
+ #endif
626
+ if ((n->link_data != NULL) && (n->key == NOCITATION)) {
627
+ g_string_append_printf(out, "<span class=\"notcited\" id=\"%s\"/>",n->link_data->label);
628
+ } else if (n->link_data != NULL) {
629
+ g_string_append_printf(out, "<span class=\"externalcitation\">[");
630
+ if (n->children != NULL) {
631
+ print_html_node(out, n->children, scratch);
632
+ g_string_append_printf(out, "][");
633
+ }
634
+ g_string_append_printf(out, "#%s]</span>",n->link_data->label);
635
+ }
636
+ }
637
+ }
638
+ #ifdef DEBUG_ON
639
+ fprintf(stderr, "finish cite\n");
640
+ #endif
641
+ break;
642
+ case VARIABLE:
643
+ temp = metavalue_for_key(n->str,scratch->result_tree);
644
+ if (temp == NULL) {
645
+ g_string_append_printf(out, "[%%%s]",n->str);
646
+ } else {
647
+ g_string_append_printf(out, temp);
648
+ free(temp);
649
+ }
650
+ break;
651
+ case GLOSSARYTERM:
652
+ g_string_append_printf(out,"<span class=\"glossary name\">");
653
+ print_html_string(out, n->children->str, scratch);
654
+ g_string_append_printf(out, "</span>");
655
+ if ((n->next != NULL) && (n->next->key == GLOSSARYSORTKEY) ) {
656
+ g_string_append_printf(out, "<span class=\"glossary sort\" style=\"display:none\">");
657
+ print_html_string(out, n->next->str, scratch);
658
+ g_string_append_printf(out, "</span>");
659
+ }
660
+ g_string_append_printf(out, ": ");
661
+ break;
662
+ case GLOSSARYSORTKEY:
663
+ break;
664
+ case CODE:
665
+ g_string_append_printf(out, "<code>");
666
+ print_html_string(out, n->str, scratch);
667
+ g_string_append_printf(out, "</code>");
668
+ break;
669
+ case BLOCKQUOTEMARKER:
670
+ print_html_node_tree(out, n->children, scratch);
671
+ break;
672
+ case BLOCKQUOTE:
673
+ pad(out,2, scratch);
674
+ g_string_append_printf(out, "<blockquote>\n");
675
+ scratch->padded = 2;
676
+ print_html_node_tree(out, n->children, scratch);
677
+ pad(out,1, scratch);
678
+ g_string_append_printf(out, "</blockquote>");
679
+ scratch->padded = 0;
680
+ break;
681
+ case RAW:
682
+ g_string_append_printf(out, "RAW:");
683
+ g_string_append_printf(out,"%s",n->str);
684
+ break;
685
+ case HTML:
686
+ g_string_append_printf(out, "%s", n->str);
687
+ break;
688
+ case DEFLIST:
689
+ pad(out,2, scratch);
690
+ scratch->padded = 1;
691
+ g_string_append_printf(out, "<dl>\n");
692
+ print_html_node_tree(out, n->children, scratch);
693
+ g_string_append_printf(out, "</dl>");
694
+ scratch->padded = 0;
695
+ break;
696
+ case TERM:
697
+ pad(out,1, scratch);
698
+ g_string_append_printf(out, "<dt>");
699
+ print_html_node_tree(out, n->children, scratch);
700
+ g_string_append_printf(out, "</dt>\n");
701
+ scratch->padded = 1;
702
+ break;
703
+ case DEFINITION:
704
+ pad(out,1, scratch);
705
+ scratch->padded = 1;
706
+ g_string_append_printf(out, "<dd>");
707
+ print_html_node_tree(out, n->children, scratch);
708
+ g_string_append_printf(out, "</dd>\n");
709
+ scratch->padded = 0;
710
+ break;
711
+ case TABLE:
712
+ pad(out,2, scratch);
713
+ g_string_append_printf(out, "<table>\n");
714
+ print_html_node_tree(out, n->children, scratch);
715
+ g_string_append_printf(out, "</table>\n");
716
+ scratch->cell_type = 0;
717
+ scratch->padded = 1;
718
+ break;
719
+ case TABLESEPARATOR:
720
+ scratch->table_alignment = n->str;
721
+ if (scratch->cell_type == 0)
722
+ print_col_group(out, scratch);
723
+ scratch->cell_type = 'd';
724
+ break;
725
+ case TABLECAPTION:
726
+ if ((n->children != NULL) && (n->children->key == TABLELABEL)) {
727
+ temp = label_from_string(n->children->str);
728
+ } else {
729
+ temp = label_from_node_tree(n->children);
730
+ }
731
+ g_string_append_printf(out, "<caption id=\"%s\">", temp);
732
+ print_html_node_tree(out, n->children, scratch);
733
+ g_string_append_printf(out, "</caption>\n");
734
+ free(temp);
735
+ break;
736
+ case TABLELABEL:
737
+ break;
738
+ case TABLEHEAD:
739
+ /* print column alignment for XSLT processing if needed */
740
+ if (scratch->cell_type == 0)
741
+ print_col_group(out, scratch);
742
+ scratch->cell_type = 'h';
743
+ g_string_append_printf(out, "\n<thead>\n");
744
+ print_html_node_tree(out, n->children, scratch);
745
+ g_string_append_printf(out, "</thead>\n");
746
+ scratch->cell_type = 'd';
747
+ break;
748
+ case TABLEBODY:
749
+ g_string_append_printf(out, "\n<tbody>\n");
750
+ print_html_node_tree(out, n->children, scratch);
751
+ g_string_append_printf(out, "</tbody>\n");
752
+ break;
753
+ case TABLEROW:
754
+ g_string_append_printf(out, "<tr>\n");
755
+ scratch->table_column = 0;
756
+ print_html_node_tree(out, n->children, scratch);
757
+ g_string_append_printf(out, "</tr>\n");
758
+ break;
759
+ case TABLECELL:
760
+ temp = scratch->table_alignment;
761
+ if (strncmp(&temp[scratch->table_column],"h",1) == 0) {
762
+ temp_type = 'h';
763
+ scratch->table_column++;
764
+ } else {
765
+ temp_type = scratch->cell_type;
766
+ }
767
+ lev = scratch->table_column;
768
+ if ( strncmp(&temp[lev],"r",1) == 0) {
769
+ g_string_append_printf(out, "\t<t%c style=\"text-align:right;\"", temp_type);
770
+ } else if ( strncmp(&temp[lev],"R",1) == 0) {
771
+ g_string_append_printf(out, "\t<t%c style=\"text-align:right;\"", temp_type);
772
+ } else if ( strncmp(&temp[lev],"c",1) == 0) {
773
+ g_string_append_printf(out, "\t<t%c style=\"text-align:center;\"", temp_type);
774
+ } else if ( strncmp(&temp[lev],"C",1) == 0) {
775
+ g_string_append_printf(out, "\t<t%c style=\"text-align:center;\"", temp_type);
776
+ } else {
777
+ g_string_append_printf(out, "\t<t%c style=\"text-align:left;\"", temp_type);
778
+ }
779
+ if ((n->children != NULL) && (n->children->key == CELLSPAN)) {
780
+ g_string_append_printf(out, " colspan=\"%d\"",(int)strlen(n->children->str)+1);
781
+ scratch->table_column += (int)strlen(n->children->str);
782
+ }
783
+ g_string_append_printf(out, ">");
784
+ scratch->padded = 2;
785
+ print_html_node_tree(out, n->children, scratch);
786
+ g_string_append_printf(out, "</t%c>\n", temp_type);
787
+ scratch->table_column++;
788
+ break;
789
+ case CELLSPAN:
790
+ break;
791
+ case GLOSSARYSOURCE:
792
+ if (scratch->printing_notes)
793
+ print_html_node_tree(out, n->children, scratch);
794
+ break;
795
+ case CITATIONSOURCE:
796
+ case NOTESOURCE:
797
+ if (scratch->printing_notes)
798
+ print_html_node_tree(out, n->children, scratch);
799
+ break;
800
+ case SOURCEBRANCH:
801
+ fprintf(stderr,"SOURCEBRANCH\n");
802
+ break;
803
+ case NOTELABEL:
804
+ break;
805
+ case SUPERSCRIPT:
806
+ g_string_append_printf(out, "<sup>%s</sup>",n->str);
807
+ break;
808
+ case SUBSCRIPT:
809
+ g_string_append_printf(out, "<sub>%s</sub>",n->str);
810
+ break;
811
+ case KEY_COUNTER:
812
+ break;
813
+ default:
814
+ fprintf(stderr, "print_html_node encountered unknown node key = %d\n",n->key);
815
+ exit(EXIT_FAILURE);
816
+ }
817
+ }
818
+
819
+ /* print_html_endnotes */
820
+ void print_html_endnotes(GString *out, scratch_pad *scratch) {
821
+ int counter = 0;
822
+ int random;
823
+
824
+ scratch->used_notes = reverse_list(scratch->used_notes);
825
+ scratch->printing_notes = 1;
826
+
827
+ node *note = scratch->used_notes;
828
+ #ifdef DEBUG_ON
829
+ fprintf(stderr, "start endnotes\n");
830
+ #endif
831
+
832
+ if ((note == NULL) || ((note->key == KEY_COUNTER) && (note->next == NULL)))
833
+ return;
834
+
835
+ #ifdef DEBUG_ON
836
+ fprintf(stderr, "there are endnotes to print\n");
837
+ #endif
838
+
839
+ pad(out,2, scratch);
840
+ g_string_append_printf(out, "<div class=\"footnotes\">\n<hr />\n<ol>");
841
+ while ( note != NULL) {
842
+ if (note->key == KEY_COUNTER) {
843
+ note = note->next;
844
+ continue;
845
+ }
846
+
847
+ counter++;
848
+ pad(out, 1, scratch);
849
+
850
+ if (scratch->extensions & EXT_RANDOM_FOOT) {
851
+ srand(scratch->random_seed_base + counter);
852
+ random = rand() % 99999 + 1;
853
+ } else {
854
+ random = counter;
855
+ }
856
+
857
+ if (note->key == CITATIONSOURCE) {
858
+ g_string_append_printf(out, "<li id=\"fn:%d\" class=\"citation\"><span class=\"citekey\" style=\"display:none\">%s</span>",
859
+ random, note->str);
860
+ } else {
861
+ g_string_append_printf(out, "<li id=\"fn:%d\">\n", random);
862
+ }
863
+
864
+
865
+ scratch->padded = 2;
866
+ if ((note->key == NOTESOURCE) || (note->key == GLOSSARYSOURCE))
867
+ scratch->footnote_to_print = counter;
868
+ scratch->footnote_para_counter = tree_contains_key_count(note->children,PARA);
869
+ print_html_node(out, note, scratch);
870
+ pad(out, 1, scratch);
871
+ g_string_append_printf(out, "</li>");
872
+
873
+ note = note->next;
874
+ }
875
+ pad(out,1, scratch);
876
+ g_string_append_printf(out, "</ol>\n</div>\n");
877
+ scratch->padded = 0;
878
+ #ifdef DEBUG_ON
879
+ fprintf(stderr, "finish endnotes\n");
880
+ #endif
881
+ }
882
+
883
+ /* Check metadata keys and determine if we need a complete document */
884
+ /* We also preconvert metadata keys to proper formatting -- lowercase with no spaces */
885
+ bool is_html_complete_doc(node *meta) {
886
+ node *step;
887
+ char *temp;
888
+ step = meta->children;
889
+
890
+ while (step != NULL) {
891
+ /* process key to proper label */
892
+ temp = step->str; /* store pointer to original str */
893
+ step->str = label_from_string(step->str);
894
+ free(temp); /* free original since we don't need it */
895
+ step = step->next;
896
+ }
897
+
898
+ step = meta->children;
899
+ while (step != NULL) {
900
+ /* the following types of metadata do not require a complete document */
901
+ if ((strcmp(step->str, "baseheaderlevel") != 0) &&
902
+ (strcmp(step->str, "xhtmlheaderlevel") != 0) &&
903
+ (strcmp(step->str, "htmlheaderlevel") != 0) &&
904
+ (strcmp(step->str, "latexheaderlevel") != 0) &&
905
+ (strcmp(step->str, "odfheaderlevel") != 0) &&
906
+ (strcmp(step->str, "quoteslanguage") != 0))
907
+ { return TRUE;}
908
+ step = step->next;
909
+ }
910
+
911
+ return FALSE;
912
+ }
913
+
914
+ /* print_html_localized_typography -- convert to "smart" typography */
915
+ void print_html_localized_typography(GString *out, int character, scratch_pad *scratch) {
916
+ if (!extension(EXT_SMART, scratch->extensions)) {
917
+ g_string_append_c(out, character);
918
+ return;
919
+ }
920
+ switch (character) {
921
+ case LSQUOTE:
922
+ switch (scratch->language) {
923
+ case SWEDISH:
924
+ g_string_append_printf(out, "&#8217;");
925
+ break;
926
+ case FRENCH:
927
+ g_string_append_printf(out,"&#39;");
928
+ break;
929
+ case GERMAN:
930
+ g_string_append_printf(out,"&#8218;");
931
+ break;
932
+ case GERMANGUILL:
933
+ g_string_append_printf(out,"&#8250;");
934
+ break;
935
+ default:
936
+ g_string_append_printf(out,"&#8216;");
937
+ }
938
+ break;
939
+ case RSQUOTE:
940
+ switch (scratch->language) {
941
+ case GERMAN:
942
+ g_string_append_printf(out,"&#8216;");
943
+ break;
944
+ case GERMANGUILL:
945
+ g_string_append_printf(out,"&#8249;");
946
+ break;
947
+ default:
948
+ g_string_append_printf(out,"&#8217;");
949
+ }
950
+ break;
951
+ case APOS:
952
+ g_string_append_printf(out,"&#8217;");
953
+ break;
954
+ case LDQUOTE:
955
+ switch (scratch->language) {
956
+ case DUTCH:
957
+ case GERMAN:
958
+ g_string_append_printf(out,"&#8222;");
959
+ break;
960
+ case GERMANGUILL:
961
+ g_string_append_printf(out,"&#187;");
962
+ break;
963
+ case FRENCH:
964
+ g_string_append_printf(out,"&#171;");
965
+ break;
966
+ case SWEDISH:
967
+ g_string_append_printf(out, "&#8221;");
968
+ break;
969
+ default:
970
+ g_string_append_printf(out,"&#8220;");
971
+ }
972
+ break;
973
+ case RDQUOTE:
974
+ switch (scratch->language) {
975
+ case SWEDISH:
976
+ case DUTCH:
977
+ g_string_append_printf(out,"&#8221;");
978
+ break;
979
+ case GERMAN:
980
+ g_string_append_printf(out,"&#8220;");
981
+ break;
982
+ case GERMANGUILL:
983
+ g_string_append_printf(out,"&#171;");
984
+ break;
985
+ case FRENCH:
986
+ g_string_append_printf(out,"&#187;");
987
+ break;
988
+ default:
989
+ g_string_append_printf(out,"&#8221;");
990
+ }
991
+ break;
992
+ case NDASH:
993
+ g_string_append_printf(out,"&#8211;");
994
+ break;
995
+ case MDASH:
996
+ g_string_append_printf(out,"&#8212;");
997
+ break;
998
+ case ELLIP:
999
+ g_string_append_printf(out,"&#8230;");
1000
+ break;
1001
+ default:;
1002
+ }
1003
+ }
1004
+
1005
+ /* print_html_string - print string, escaping for HTML */
1006
+ long ran_num_next(); /* Use Knuth's pseudo random generator */
1007
+
1008
+ void print_html_string(GString *out, char *str, scratch_pad *scratch) {
1009
+ if (str == NULL)
1010
+ return;
1011
+ while (*str != '\0') {
1012
+ switch (*str) {
1013
+ case '&':
1014
+ g_string_append_printf(out, "&amp;");
1015
+ break;
1016
+ case '<':
1017
+ g_string_append_printf(out, "&lt;");
1018
+ break;
1019
+ case '>':
1020
+ g_string_append_printf(out, "&gt;");
1021
+ break;
1022
+ case '"':
1023
+ g_string_append_printf(out, "&quot;");
1024
+ break;
1025
+ default:
1026
+ if ((scratch->obfuscate == true) && (extension(EXT_OBFUSCATE, scratch->extensions))
1027
+ && ((int) *str == (((int) *str) & 127))) {
1028
+ if (ran_num_next() % 2 == 0)
1029
+ g_string_append_printf(out, "&#%d;", (int) *str);
1030
+ else
1031
+ g_string_append_printf(out, "&#x%x;", (unsigned int) *str);
1032
+ } else {
1033
+ g_string_append_c(out, *str);
1034
+ }
1035
+ }
1036
+ str++;
1037
+ }
1038
+ }
1039
+
1040
+ /* print_col_group - print column alignment config (used in XSLT processing) */
1041
+ void print_col_group(GString *out,scratch_pad *scratch) {
1042
+ char *temp;
1043
+ int lev;
1044
+ g_string_append_printf(out, "<colgroup>\n");
1045
+ temp = scratch->table_alignment;
1046
+ for (lev=0;lev<strlen(temp);lev++) {
1047
+ if ( strncmp(&temp[lev],"r",1) == 0) {
1048
+ g_string_append_printf(out, "<col style=\"text-align:right;\"/>\n");
1049
+ } else if ( strncmp(&temp[lev],"R",1) == 0) {
1050
+ g_string_append_printf(out, "<col style=\"text-align:right;\" class=\"extended\"/>\n");
1051
+ } else if ( strncmp(&temp[lev],"c",1) == 0) {
1052
+ g_string_append_printf(out, "<col style=\"text-align:center;\"/>\n");
1053
+ } else if ( strncmp(&temp[lev],"C",1) == 0) {
1054
+ g_string_append_printf(out, "<col style=\"text-align:center;\" class=\"extended\"/>\n");
1055
+ } else if ( strncmp(&temp[lev],"L",1) == 0) {
1056
+ g_string_append_printf(out, "<col style=\"text-align:left;\" class=\"extended\"/>\n");
1057
+ } else {
1058
+ g_string_append_printf(out, "<col style=\"text-align:left;\"/>\n");
1059
+ }
1060
+ }
1061
+ g_string_append_printf(out, "</colgroup>\n");
1062
+ }