multimarkdown 4.5.0.r1

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 +1060 -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 +156 -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 +483 -0
  21. data/MultiMarkdown-4/odf.c +1201 -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 +15582 -0
  27. data/MultiMarkdown-4/parser.h +186 -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 +213 -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 +70 -0
  40. data/Rakefile +85 -0
  41. data/bin/ruby_multi_markdown +128 -0
  42. data/ext/extconf.h +3 -0
  43. data/ext/extconf.rb +17 -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/multimarkdown.rb +1 -0
  49. data/multi_markdown.gemspec +37 -0
  50. data/test/multi_markdown_test.rb +64 -0
  51. metadata +119 -0
@@ -0,0 +1,14 @@
1
+ #ifndef HTML_PARSER_H
2
+ #define HTML_PARSER_H
3
+
4
+ #include "parser.h"
5
+ #include "writer.h"
6
+
7
+
8
+ void print_html_node_tree(GString *out, node *list, scratch_pad *scratch);
9
+ void print_html_node(GString *out, node *n, scratch_pad *scratch);
10
+ void print_html_localized_typography(GString *out, int character, scratch_pad *scratch);
11
+ void print_html_string(GString *out, char *str, scratch_pad *scratch);
12
+ void print_html_endnotes(GString *out, scratch_pad *scratch);
13
+
14
+ #endif
@@ -0,0 +1,1137 @@
1
+ /*
2
+
3
+ latex.c -- LaTeX 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 "latex.h"
23
+
24
+ bool is_latex_complete_doc(node *meta);
25
+
26
+ /* find_latex_mode -- check for metadata to switch to beamer/memoir */
27
+ int find_latex_mode(int format, node *n) {
28
+ node *latex_mode;
29
+ char *key;
30
+ char *label;
31
+
32
+ if (format != LATEX_FORMAT)
33
+ return format;
34
+
35
+ if (tree_contains_key(n, METAKEY)) {
36
+ latex_mode = metadata_for_key("latexmode",n);
37
+ if (latex_mode != NULL) {
38
+ key = metavalue_for_key("latexmode",n);
39
+ label = label_from_string(key);
40
+ if (strcmp(label, "beamer") == 0) {
41
+ format = BEAMER_FORMAT;
42
+ } else if (strcmp(label, "memoir") == 0) {
43
+ format = MEMOIR_FORMAT;
44
+ }
45
+ free(label);
46
+ free(key);
47
+ }
48
+ }
49
+
50
+ return format;
51
+ }
52
+
53
+
54
+ /* print_latex_node_tree -- convert node tree to LaTeX */
55
+ void print_latex_node_tree(GString *out, node *list, scratch_pad *scratch) {
56
+ while (list != NULL) {
57
+ print_latex_node(out, list, scratch);
58
+ list = list->next;
59
+ }
60
+ }
61
+
62
+ /* print_latex_node -- convert given node to LaTeX and append */
63
+ void print_latex_node(GString *out, node *n, scratch_pad *scratch) {
64
+ node *temp_node;
65
+ char *temp;
66
+ int lev;
67
+ char *width = NULL;
68
+ char *height = NULL;
69
+ GString *temp_str;
70
+ GString *raw_str;
71
+ int i;
72
+ double temp_float;
73
+
74
+ if (n == NULL)
75
+ return;
76
+
77
+ /* debugging statement */
78
+ #ifdef DEBUG_ON
79
+ fprintf(stderr, "print_latex_node: %d\n",n->key);
80
+ #endif
81
+
82
+ /* If we are forcing a complete document, and METADATA isn't the first thing,
83
+ we need to close <head> */
84
+ if ((scratch->extensions & EXT_COMPLETE)
85
+ && !(scratch->extensions & EXT_HEAD_CLOSED) &&
86
+ !((n->key == FOOTER) || (n->key == METADATA))) {
87
+ pad(out, 2, scratch);
88
+ scratch->extensions = scratch->extensions | EXT_HEAD_CLOSED;
89
+ }
90
+ switch (n->key) {
91
+ case NO_TYPE:
92
+ break;
93
+ case LIST:
94
+ print_latex_node_tree(out,n->children,scratch);
95
+ break;
96
+ case STR:
97
+ print_latex_string(out,n->str, scratch);
98
+ break;
99
+ case SPACE:
100
+ g_string_append_printf(out,"%s",n->str);
101
+ break;
102
+ case PLAIN:
103
+ pad(out,1, scratch);
104
+ print_latex_node_tree(out,n->children, scratch);
105
+ scratch->padded = 0;
106
+ break;
107
+ case PARA:
108
+ pad(out, 2, scratch);
109
+ print_latex_node_tree(out,n->children,scratch);
110
+ scratch->padded = 0;
111
+ break;
112
+ case HRULE:
113
+ pad(out, 2, scratch);
114
+ g_string_append_printf(out, "\\begin{center}\\rule{3in}{0.4pt}\\end{center}\n");
115
+ scratch->padded = 0;
116
+ break;
117
+ case HTMLBLOCK:
118
+ /* don't print HTML block */
119
+ /* but do print HTML comments for raw LaTeX */
120
+ if (strncmp(n->str,"<!--",4) == 0) {
121
+ pad(out, 2, scratch);
122
+ /* trim "-->" from end */
123
+ n->str[strlen(n->str)-3] = '\0';
124
+ g_string_append_printf(out, "%s", &n->str[4]);
125
+ scratch->padded = 0;
126
+ }
127
+ break;
128
+ case VERBATIM:
129
+ pad(out, 2, scratch);
130
+ if ((n->children != NULL) && (n->children->key == VERBATIMTYPE)) {
131
+ trim_trailing_whitespace(n->children->str);
132
+ if (strlen(n->children->str) > 0) {
133
+ g_string_append_printf(out, "\\begin{lstlisting}[language=%s]\n%s\\end{lstlisting}", n->children->str,n->str);
134
+ scratch->padded = 0;
135
+ break;
136
+ }
137
+ }
138
+ g_string_append_printf(out, "\\begin{verbatim}\n%s\\end{verbatim}",n->str);
139
+ scratch->padded = 0;
140
+ break;
141
+ case BULLETLIST:
142
+ pad(out, 2, scratch);
143
+ g_string_append_printf(out, "\\begin{itemize}");
144
+ scratch->padded = 0;
145
+ print_latex_node_tree(out, n->children, scratch);
146
+ pad(out, 1, scratch);
147
+ g_string_append_printf(out, "\\end{itemize}");
148
+ scratch->padded = 0;
149
+ break;
150
+ case ORDEREDLIST:
151
+ pad(out, 2, scratch);
152
+ g_string_append_printf(out, "\\begin{enumerate}");
153
+ scratch->padded = 0;
154
+ print_latex_node_tree(out, n->children, scratch);
155
+ pad(out, 1, scratch);
156
+ g_string_append_printf(out, "\\end{enumerate}");
157
+ scratch->padded = 0;
158
+ break;
159
+ case LISTITEM:
160
+ pad(out, 1, scratch);
161
+ g_string_append_printf(out, "\\item ");
162
+ scratch->padded = 2;
163
+ print_latex_node_tree(out, n->children, scratch);
164
+ g_string_append_printf(out, "\n");
165
+ scratch->padded = 0;
166
+ break;
167
+ case METADATA:
168
+ /* print the metadata */
169
+ print_latex_node_tree(out,n->children, scratch);
170
+ if (!(scratch->extensions & EXT_SNIPPET) && (is_latex_complete_doc(n))) {
171
+ scratch->extensions = scratch->extensions | EXT_COMPLETE;
172
+ }
173
+ break;
174
+ case METAKEY:
175
+ /* reformat the key */
176
+ temp = n->str;
177
+ n->str = label_from_string(temp);
178
+ free(temp);
179
+
180
+ if (strcmp(n->str, "baseheaderlevel") == 0) {
181
+ scratch->baseheaderlevel = atoi(n->children->str);
182
+ break;
183
+ } else if (strcmp(n->str, "latexheaderlevel") == 0) {
184
+ scratch->baseheaderlevel = atoi(n->children->str);
185
+ break;
186
+ } else if (strcmp(n->str, "quoteslanguage") == 0) {
187
+ temp = label_from_node_tree(n->children);
188
+ if ((strcmp(temp, "nl") == 0) || (strcmp(temp, "dutch") == 0)) { scratch->language = DUTCH; } else
189
+ if ((strcmp(temp, "de") == 0) || (strcmp(temp, "german") == 0)) { scratch->language = GERMAN; } else
190
+ if (strcmp(temp, "germanguillemets") == 0) { scratch->language = GERMANGUILL; } else
191
+ if ((strcmp(temp, "fr") == 0) || (strcmp(temp, "french") == 0)) { scratch->language = FRENCH; } else
192
+ if ((strcmp(temp, "sv") == 0) || (strcmp(temp, "swedish") == 0)) { scratch->language = SWEDISH; }
193
+ break;
194
+ }
195
+
196
+ /* Don't handle remaining metadata if we're snippet only */
197
+
198
+ if (scratch->extensions & EXT_SNIPPET)
199
+ break;
200
+
201
+ if (strcmp(n->str, "title") == 0) {
202
+ g_string_append_printf(out, "\\def\\mytitle{");
203
+ print_latex_node(out, n->children, scratch);
204
+ g_string_append_printf(out, "}\n");
205
+ } else if (strcmp(n->str, "author") == 0) {
206
+ g_string_append_printf(out, "\\def\\myauthor{");
207
+ print_latex_node(out, n->children, scratch);
208
+ g_string_append_printf(out, "}\n");
209
+ } else if (strcmp(n->str, "date") == 0) {
210
+ g_string_append_printf(out, "\\def\\mydate{");
211
+ print_latex_node(out, n->children, scratch);
212
+ g_string_append_printf(out, "}\n");
213
+ } else if (strcmp(n->str, "copyright") == 0) {
214
+ g_string_append_printf(out, "\\def\\mycopyright{");
215
+ print_latex_node(out, n->children, scratch);
216
+ g_string_append_printf(out, "}\n");
217
+ } else if (strcmp(n->str, "css") == 0) {
218
+ } else if (strcmp(n->str, "xhtmlheader") == 0) {
219
+ } else if (strcmp(n->str, "htmlheader") == 0) {
220
+ } else if (strcmp(n->str, "latexinput") == 0) {
221
+ trim_trailing_whitespace(n->children->str);
222
+ g_string_append_printf(out, "\\input{%s}\n", n->children->str);
223
+ } else if (strcmp(n->str, "latexfooter") == 0) {
224
+ trim_trailing_whitespace(n->children->str);
225
+ scratch->latex_footer = strdup(n->children->str);
226
+ } else if (strcmp(n->str, "bibtex") == 0) {
227
+ trim_trailing_whitespace(n->children->str);
228
+ g_string_append_printf(out, "\\def\\bibliocommand{\\bibliography{%s}}\n",n->children->str);
229
+ } else {
230
+ g_string_append_printf(out, "\\def\\");
231
+ print_latex_string(out, n->str, scratch);
232
+ g_string_append_printf(out, "{");
233
+ print_latex_node_tree(out, n->children, scratch);
234
+ g_string_append_printf(out, "}\n");
235
+ }
236
+ break;
237
+ case METAVALUE:
238
+ trim_trailing_whitespace(n->str);
239
+ print_latex_string(out,n->str, scratch);
240
+ break;
241
+ case FOOTER:
242
+ print_latex_endnotes(out, scratch);
243
+ if (scratch->latex_footer != NULL) {
244
+ pad(out, 2, scratch);
245
+ g_string_append_printf(out,"\\input{%s}\n", scratch->latex_footer);
246
+ }
247
+ if (scratch->extensions & EXT_COMPLETE) {
248
+ g_string_append_printf(out, "\n\\end{document}");
249
+ }
250
+ break;
251
+ case HEADINGSECTION:
252
+ print_latex_node_tree(out,n->children,scratch);
253
+ break;
254
+ case H1: case H2: case H3: case H4: case H5: case H6:
255
+ lev = n->key - H1 + scratch->baseheaderlevel; /* assumes H1 ... H6 are in order */
256
+ if (lev > 7)
257
+ lev = 7; /* Max at level 7 */
258
+ pad(out, 2, scratch);
259
+ switch (lev) {
260
+ case 1:
261
+ g_string_append_printf(out, "\\part{");
262
+ break;
263
+ case 2:
264
+ g_string_append_printf(out, "\\chapter{");
265
+ break;
266
+ case 3:
267
+ g_string_append_printf(out, "\\section{");
268
+ break;
269
+ case 4:
270
+ g_string_append_printf(out, "\\subsection{");
271
+ break;
272
+ case 5:
273
+ g_string_append_printf(out, "\\subsubsection{");
274
+ break;
275
+ case 6:
276
+ g_string_append_printf(out, "\\paragraph{");
277
+ break;
278
+ case 7:
279
+ g_string_append_printf(out, "\\subparagraph{");
280
+ break;
281
+ }
282
+ /* Don't allow footnotes */
283
+ scratch->no_latex_footnote = TRUE;
284
+ if (n->children->key == AUTOLABEL) {
285
+ /* use label for header since one was specified (MMD)*/
286
+ temp = label_from_string(n->children->str);
287
+ print_latex_node_tree(out, n->children->next, scratch);
288
+ g_string_append_printf(out, "}\n\\label{%s}",temp);
289
+ free(temp);
290
+ } else {
291
+ /* generate a label by default for MMD */
292
+ temp = label_from_node_tree(n->children);
293
+ print_latex_node_tree(out, n->children, scratch);
294
+ g_string_append_printf(out, "}\n\\label{%s}",temp);
295
+ free(temp);
296
+ }
297
+ scratch->no_latex_footnote = FALSE;
298
+ scratch->padded = 0;
299
+ break;
300
+ case APOSTROPHE:
301
+ print_latex_localized_typography(out, APOS, scratch);
302
+ break;
303
+ case ELLIPSIS:
304
+ print_latex_localized_typography(out, ELLIP, scratch);
305
+ break;
306
+ case EMDASH:
307
+ print_latex_localized_typography(out, MDASH, scratch);
308
+ break;
309
+ case ENDASH:
310
+ print_latex_localized_typography(out, NDASH, scratch);
311
+ break;
312
+ case SINGLEQUOTED:
313
+ print_latex_localized_typography(out, LSQUOTE, scratch);
314
+ print_latex_node_tree(out, n->children, scratch);
315
+ print_latex_localized_typography(out, RSQUOTE, scratch);
316
+ break;
317
+ case DOUBLEQUOTED:
318
+ print_latex_localized_typography(out, LDQUOTE, scratch);
319
+ print_latex_node_tree(out, n->children, scratch);
320
+ print_latex_localized_typography(out, RDQUOTE, scratch);
321
+ break;
322
+ case LINEBREAK:
323
+ g_string_append_printf(out, "\\\\\n");
324
+ break;
325
+ case MATHSPAN:
326
+ if (n->str[0] == '$') {
327
+ if (n->str[1] == '$') {
328
+ if (strncmp(&n->str[2],"\\begin",5) == 0) {
329
+ n->str[strlen(n->str)-2] = '\0';
330
+ g_string_append_printf(out, "%s",&n->str[1]);
331
+ } else {
332
+ g_string_append_printf(out, "%s",n->str);
333
+ }
334
+ } else {
335
+ if (strncmp(&n->str[1],"\\begin",5) == 0) {
336
+ n->str[strlen(n->str)-1] = '\0';
337
+ g_string_append_printf(out, "%s",&n->str[1]);
338
+ } else {
339
+ g_string_append_printf(out, "%s",n->str);
340
+ }
341
+ }
342
+ } else if (strncmp(&n->str[2],"\\begin",5) == 0) {
343
+ /* trim */
344
+ n->str[strlen(n->str)-3] = '\0';
345
+ g_string_append_printf(out, "%s", &n->str[2]);
346
+ } else {
347
+ if (n->str[strlen(n->str)-1] == ']') {
348
+ n->str[strlen(n->str)-3] = '\0';
349
+ g_string_append_printf(out, "%s\\]", n->str);
350
+ } else {
351
+ n->str[strlen(n->str)-3] = '\0';
352
+ g_string_append_printf(out, "$%s$", &n->str[2]);
353
+ }
354
+ }
355
+ break;
356
+ case STRONG:
357
+ g_string_append_printf(out, "\\textbf{");
358
+ print_latex_node_tree(out,n->children,scratch);
359
+ g_string_append_printf(out, "}");
360
+ break;
361
+ case EMPH:
362
+ g_string_append_printf(out, "\\emph{");
363
+ print_latex_node_tree(out,n->children,scratch);
364
+ g_string_append_printf(out, "}");
365
+ break;
366
+ case LINKREFERENCE:
367
+ break;
368
+ case LINK:
369
+ #ifdef DEBUG_ON
370
+ fprintf(stderr, "print LaTeX link: '%s'\n",n->str);
371
+ #endif
372
+ /* Do we have proper info? */
373
+
374
+ if (n->link_data == NULL) {
375
+ /* NULL link_data could occur if we parsed this link before and it didn't
376
+ match anything */
377
+ n->link_data = mk_link_data(NULL, NULL, NULL, NULL);
378
+ }
379
+
380
+ if ((n->link_data->label == NULL) &&
381
+ (n->link_data->source == NULL)) {
382
+ #ifdef DEBUG_ON
383
+ fprintf(stderr, "print latex link: '%s'\n",n->str);
384
+ #endif
385
+ /* we seem to be a [foo][] style link */
386
+ /* so load a label */
387
+ temp_str = g_string_new("");
388
+ print_raw_node_tree(temp_str, n->children);
389
+ free(n->link_data->label);
390
+ n->link_data->label = temp_str->str;
391
+ g_string_free(temp_str, FALSE);
392
+ }
393
+ #ifdef DEBUG_ON
394
+ fprintf(stderr, "look for reference data for latex link: '%s'\n",n->str);
395
+ #endif
396
+ /* Load reference data */
397
+ if (n->link_data->label != NULL) {
398
+ #ifdef DEBUG_ON
399
+ fprintf(stderr, "have label for latex link: '%s'\n",n->str);
400
+ #endif
401
+ temp = strdup(n->link_data->label);
402
+ free_link_data(n->link_data);
403
+ n->link_data = extract_link_data(temp, scratch);
404
+ if (n->link_data == NULL) {
405
+ /* replace original text since no definition found */
406
+ g_string_append_printf(out, "[");
407
+ print_latex_node(out, n->children, scratch);
408
+ g_string_append_printf(out,"]");
409
+ if (n->children->next != NULL) {
410
+ g_string_append_printf(out, "[");
411
+ print_latex_node_tree(out, n->children->next, scratch);
412
+ g_string_append_printf(out,"]");
413
+ } else if (n->str != NULL) {
414
+ /* no title label, so see if we stashed str*/
415
+ g_string_append_printf(out, "%s", n->str);
416
+ } else {
417
+ g_string_append_printf(out, "[%s]",temp);
418
+ }
419
+ free(temp);
420
+ break;
421
+ }
422
+ free(temp);
423
+ }
424
+ temp_str = g_string_new("");
425
+ print_latex_node_tree(temp_str, n->children, scratch);
426
+ raw_str = g_string_new("");
427
+ print_raw_node_tree(raw_str, n->children);
428
+
429
+ if ((n->link_data->source != NULL) && (n->link_data->source[0] == '#' )) {
430
+ /* link to anchor within the document */
431
+ if (strlen(temp_str->str) > 0) {
432
+ /* We have text before the link */
433
+ g_string_append_printf(out, "%s (", temp_str->str);
434
+ }
435
+
436
+ if (n->link_data->label == NULL) {
437
+ if ((n->link_data->source != NULL) && (strncmp(n->link_data->source,"#",1) == 0)) {
438
+ /* This link was specified as [](#bar) */
439
+ g_string_append_printf(out, "\\autoref{%s}", n->link_data->source + 1);
440
+ } else {
441
+ g_string_append_printf(out, "\\href{%s}{}", n->link_data->source);
442
+ }
443
+ } else {
444
+ g_string_append_printf(out, "\\autoref{%s}", n->link_data->label);
445
+ }
446
+ if (strlen(temp_str->str) > 0) {
447
+ g_string_append_printf(out, ")", temp_str->str);
448
+ }
449
+ } else if (strcmp(raw_str->str, n->link_data->source) == 0){
450
+ /* This is a <link> */
451
+ g_string_append_printf(out, "\\href{%s}{%s}", n->link_data->source, temp_str->str);
452
+ } else if ((strlen(n->link_data->source) > 7) &&
453
+ (strcmp(raw_str->str,&n->link_data->source[7]) == 0)) {
454
+ /*This is a <mailto> */
455
+ g_string_append_printf(out, "\\href{%s}{%s}", n->link_data->source, temp_str->str);
456
+ } else {
457
+ /* this is a [text](link) */
458
+ g_string_append_printf(out, "\\href{%s}{", n->link_data->source);
459
+ print_latex_node_tree(out, n->children, scratch);
460
+ g_string_append_printf(out, "}");
461
+ if (scratch->no_latex_footnote == FALSE) {
462
+ g_string_append_printf(out, "\\footnote{\\href{");
463
+ print_latex_url(out, n->link_data->source, scratch);
464
+ g_string_append_printf(out, "}{", n->link_data->source);
465
+ print_latex_string(out, n->link_data->source, scratch);
466
+ g_string_append_printf(out, "}}");
467
+ }
468
+ }
469
+ g_string_free(temp_str, true);
470
+ g_string_free(raw_str, true);
471
+ n->link_data->attr = NULL;
472
+ break;
473
+ case ATTRKEY:
474
+ g_string_append_printf(out, " %s=\"%s\"", n->str,
475
+ n->children->str);
476
+ break;
477
+ case REFNAME:
478
+ case SOURCE:
479
+ case TITLE:
480
+ break;
481
+ case IMAGEBLOCK:
482
+ pad(out,2, scratch);
483
+ case IMAGE:
484
+ #ifdef DEBUG_ON
485
+ fprintf(stderr, "print image\n");
486
+ #endif
487
+ /* Do we have proper info? */
488
+ if ((n->link_data->label == NULL) &&
489
+ (n->link_data->source == NULL)) {
490
+ /* we seem to be a [foo][] style link */
491
+ /* so load a label */
492
+ temp_str = g_string_new("");
493
+ print_raw_node_tree(temp_str, n->children);
494
+ n->link_data->label = temp_str->str;
495
+ g_string_free(temp_str, FALSE);
496
+ }
497
+ /* Load reference data */
498
+ if (n->link_data->label != NULL) {
499
+ temp = strdup(n->link_data->label);
500
+ free_link_data(n->link_data);
501
+ n->link_data = extract_link_data(temp, scratch);
502
+ if (n->link_data == NULL) {
503
+ /* replace original text since no definition found */
504
+ g_string_append_printf(out, "![");
505
+ print_latex_node(out, n->children, scratch);
506
+ g_string_append_printf(out,"]");
507
+ if (n->children->next != NULL) {
508
+ g_string_append_printf(out, "[");
509
+ print_latex_node_tree(out, n->children->next, scratch);
510
+ g_string_append_printf(out,"]");
511
+ } else if (n->str != NULL) {
512
+ /* no title label, so see if we stashed str*/
513
+ g_string_append_printf(out, "%s", n->str);
514
+ } else {
515
+ g_string_append_printf(out, "[%s]",temp);
516
+ }
517
+ free(temp);
518
+ break;
519
+ }
520
+ free(temp);
521
+ }
522
+
523
+ if (n->key == IMAGEBLOCK)
524
+ g_string_append_printf(out, "\\begin{figure}[htbp]\n\\centering\n");
525
+
526
+ g_string_append_printf(out, "\\includegraphics[");
527
+
528
+ #ifdef DEBUG_ON
529
+ fprintf(stderr, "attributes\n");
530
+ #endif
531
+
532
+ if (n->link_data->attr != NULL) {
533
+ temp_node = node_for_attribute("height",n->link_data->attr);
534
+ if (temp_node != NULL)
535
+ height = correct_dimension_units(temp_node->children->str);
536
+ temp_node = node_for_attribute("width",n->link_data->attr);
537
+ if (temp_node != NULL)
538
+ width = correct_dimension_units(temp_node->children->str);
539
+ }
540
+
541
+ if ((height == NULL) && (width == NULL)) {
542
+ /* No dimensions used */
543
+ g_string_append_printf(out, "keepaspectratio,width=\\textwidth,height=0.75\\textheight");
544
+ } else {
545
+ /* At least one dimension given */
546
+ if (!((height != NULL) && (width != NULL))) {
547
+ /* we only have one */
548
+ g_string_append_printf(out, "keepaspectratio,");
549
+ }
550
+
551
+ if (width != NULL) {
552
+ if (width[strlen(width)-1] == '%') {
553
+ width[strlen(width)-1] = '\0';
554
+ temp_float = strtod(width, NULL);
555
+ temp_float = temp_float/100;
556
+ g_string_append_printf(out, "width=%.4f\\textwidth,", temp_float);
557
+ } else {
558
+ g_string_append_printf(out, "width=%s,",width);
559
+ }
560
+ } else {
561
+ g_string_append_printf(out, "width=\\textwidth,");
562
+ }
563
+
564
+ if (height != NULL) {
565
+ if (height[strlen(height)-1] == '%') {
566
+ height[strlen(height)-1] = '\0';
567
+ temp_float = strtod(height, NULL);
568
+ temp_float = temp_float/100;
569
+ g_string_append_printf(out, "height=%.4f\\textheight", temp_float);
570
+ } else {
571
+ g_string_append_printf(out, "height=%s",height);
572
+ }
573
+ } else {
574
+ g_string_append_printf(out, "height=0.75\\textheight");
575
+ }
576
+ }
577
+
578
+ g_string_append_printf(out, "]{%s}",n->link_data->source);
579
+
580
+ if (n->key == IMAGEBLOCK) {
581
+ if (n->children != NULL) {
582
+ g_string_append_printf(out, "\n\\caption{");
583
+ print_latex_node_tree(out, n->children, scratch);
584
+ g_string_append_printf(out, "}");
585
+ }
586
+ if (n->link_data->label != NULL) {
587
+ temp = label_from_string(n->link_data->label);
588
+ g_string_append_printf(out, "\n\\label{%s}",temp);
589
+ free(temp);
590
+ }
591
+ g_string_append_printf(out, "\n\\end{figure}");
592
+ scratch->padded = 0;
593
+ }
594
+
595
+ free(height);
596
+ free(width);
597
+ n->link_data->attr = NULL; /* We'll delete these elsewhere */
598
+ break;
599
+ #ifdef DEBUG_ON
600
+ fprintf(stderr, "finish image\n");
601
+ #endif
602
+ case NOTEREFERENCE:
603
+ lev = note_number_for_node(n, scratch);
604
+ temp_node = node_for_count(scratch->used_notes, lev);
605
+ scratch->padded = 2;
606
+ if (temp_node->key == GLOSSARYSOURCE) {
607
+ g_string_append_printf(out, "\\newglossaryentry{%s}{",temp_node->children->children->str);
608
+ print_latex_node_tree(out, temp_node->children, scratch);
609
+ g_string_append_printf(out, "}}\\glsadd{%s}",temp_node->children->children->str);
610
+ } else {
611
+ g_string_append_printf(out, "\\footnote{");
612
+ print_latex_node_tree(out, temp_node->children, scratch);
613
+ g_string_append_printf(out, "}");
614
+ }
615
+ scratch->padded = 0;
616
+ break;
617
+ case NOCITATION:
618
+ case CITATION:
619
+ #ifdef DEBUG_ON
620
+ fprintf(stderr, "\nprint cite\n");
621
+ #endif
622
+ if ((n->link_data != NULL) && (strncmp(n->link_data->label,"[#",2) == 0)) {
623
+ /* external citation (e.g. BibTeX) */
624
+ n->link_data->label[strlen(n->link_data->label)-1] = '\0';
625
+ if (n->key == NOCITATION) {
626
+ g_string_append_printf(out, "~\\nocite{%s}",&n->str[2]);
627
+ } else {
628
+ g_string_append_printf(out, "<FAKE span class=\"externalcitation\">");
629
+ g_string_append_printf(out, "</span>");
630
+ }
631
+ } else {
632
+ #ifdef DEBUG_ON
633
+ fprintf(stderr, "internal cite\n");
634
+ #endif
635
+ /* MMD citation, so output as footnote */
636
+ /* TODO: create separate stream from footnotes */
637
+ lev = note_number_for_label(n->link_data->label, scratch);
638
+ if (lev != 0) {
639
+ #ifdef DEBUG_ON
640
+ fprintf(stderr, "matching cite found\n");
641
+ #endif
642
+ temp_node = node_for_count(scratch->used_notes, lev);
643
+ /* flag that this is used as a citation */
644
+ temp_node->key = CITATIONSOURCE;
645
+ if (lev > scratch->max_footnote_num) {
646
+ scratch->max_footnote_num = lev;
647
+ }
648
+ if (n->key == NOCITATION) {
649
+ g_string_append_printf(out, "~\\nocite{%s}", n->link_data->label);
650
+ } else {
651
+ if (n->children != NULL) {
652
+ g_string_append_printf(out, "~\\citep[");
653
+ print_latex_node(out, n->children, scratch);
654
+ g_string_append_printf(out,"]{%s}",n->link_data->label);
655
+ } else {
656
+ g_string_append_printf(out, "~\\citep{%s}", n->link_data->label);
657
+ }
658
+ }
659
+ } else {
660
+ /* not located -- this is external cite */
661
+ #ifdef DEBUG_ON
662
+ fprintf(stderr, "no match for cite: '%s'\n",n->link_data->label);
663
+ #endif
664
+ temp = n->link_data->label;
665
+ if (n->key == NOCITATION) {
666
+ g_string_append_printf(out, "~\\nocite{%s}",n->link_data->label);
667
+ } else {
668
+ if (n->children != NULL) {
669
+ #ifdef DEBUG_ON
670
+ fprintf(stderr, "cite with children\n");
671
+ #endif
672
+ if (strcmp(&temp[strlen(temp) - 1],";") == 0) {
673
+ g_string_append_printf(out, " \\citet[");
674
+ temp[strlen(temp) - 1] = '\0';
675
+ } else {
676
+ g_string_append_printf(out, "~\\citep[");
677
+ }
678
+ print_latex_node(out, n->children, scratch);
679
+ g_string_append_printf(out, "]{%s}",temp);
680
+ } else {
681
+ #ifdef DEBUG_ON
682
+ fprintf(stderr, "cite without children. locat:'%s'\n",n->str);
683
+ #endif
684
+ if (strcmp(&temp[strlen(temp) - 1],";") == 0) {
685
+ temp[strlen(temp) - 1] = '\0';
686
+ g_string_append_printf(out, " \\citet{%s}",temp);
687
+ } else {
688
+ g_string_append_printf(out, "~\\citep{%s}",temp);
689
+ }
690
+ }
691
+ }
692
+ }
693
+ }
694
+ #ifdef DEBUG_ON
695
+ fprintf(stderr, "finish cite\n");
696
+ #endif
697
+ break;
698
+ case VARIABLE:
699
+ temp = metavalue_for_key(n->str,scratch->result_tree);
700
+ if (temp == NULL) {
701
+ g_string_append_printf(out, "[%%%s]",n->str);
702
+ } else {
703
+ g_string_append_printf(out, temp);
704
+ free(temp);
705
+ }
706
+ break;
707
+ case GLOSSARYTERM:
708
+ if ((n->next != NULL) && (n->next->key == GLOSSARYSORTKEY) ) {
709
+ g_string_append_printf(out, "sort={");
710
+ print_latex_string(out, n->next->str, scratch);
711
+ g_string_append_printf(out, "},");
712
+ }
713
+ g_string_append_printf(out,"name={");
714
+ print_latex_string(out, n->children->str, scratch);
715
+ g_string_append_printf(out, "},description={");
716
+ break;
717
+ case GLOSSARYSORTKEY:
718
+ break;
719
+ case CODE:
720
+ g_string_append_printf(out, "\\texttt{");
721
+ print_latex_string(out, n->str, scratch);
722
+ g_string_append_printf(out, "}");
723
+ break;
724
+ case BLOCKQUOTEMARKER:
725
+ print_latex_node_tree(out, n->children, scratch);
726
+ break;
727
+ case BLOCKQUOTE:
728
+ pad(out,2, scratch);
729
+ g_string_append_printf(out, "\\begin{quote}");
730
+ scratch->padded = 0;
731
+ print_latex_node_tree(out, n->children, scratch);
732
+ pad(out,1, scratch);
733
+ g_string_append_printf(out, "\\end{quote}");
734
+ scratch->padded = 0;
735
+ break;
736
+ case RAW:
737
+ /* This shouldn't happen */
738
+ g_string_append_printf(out, "RAW:");
739
+ g_string_append_printf(out,"%s",n->str);
740
+ break;
741
+ case HTML:
742
+ /* don't print HTML block */
743
+ /* but do print HTML comments for raw LaTeX */
744
+ if (strncmp(n->str,"<!--",4) == 0) {
745
+ /* trim "-->" from end */
746
+ n->str[strlen(n->str)-3] = '\0';
747
+ g_string_append_printf(out, "%s", &n->str[4]);
748
+ scratch->padded = 0;
749
+ }
750
+ break;
751
+ case DEFLIST:
752
+ pad(out,2, scratch);
753
+ g_string_append_printf(out, "\\begin{description}");
754
+ scratch->padded = 0;
755
+ print_latex_node_tree(out, n->children, scratch);
756
+ pad(out, 1, scratch);
757
+ g_string_append_printf(out, "\\end{description}");
758
+ scratch->padded = 0;
759
+ break;
760
+ case TERM:
761
+ pad(out,2, scratch);
762
+ g_string_append_printf(out, "\\item[");
763
+ print_latex_node_tree(out, n->children, scratch);
764
+ g_string_append_printf(out, "]");
765
+ scratch->padded = 0;
766
+ break;
767
+ case DEFINITION:
768
+ pad(out, 2, scratch);
769
+ scratch->padded = 2;
770
+ print_latex_node_tree(out, n->children, scratch);
771
+ scratch->padded = 0;
772
+ break;
773
+ case TABLE:
774
+ pad(out, 2, scratch);
775
+ g_string_append_printf(out, "\\begin{table}[htbp]\n\\begin{minipage}{\\linewidth}\n\\setlength{\\tymax}{0.5\\linewidth}\n\\centering\n\\small\n");
776
+ print_latex_node_tree(out, n->children, scratch);
777
+ g_string_append_printf(out, "\n\\end{tabulary}\n\\end{minipage}\n\\end{table}");
778
+ scratch->padded = 0;
779
+ break;
780
+ case TABLESEPARATOR:
781
+ temp_str = g_string_new("");
782
+ for (i = 0; n->str[i]; i++) {
783
+ if (n->str[i] != 'h')
784
+ g_string_append_printf(temp_str,"%c",toupper(n->str[i]));
785
+ }
786
+ g_string_append_printf(out, "\\begin{tabulary}{\\textwidth}{@{}%s@{}} \\toprule\n", temp_str->str);
787
+ g_string_free(temp_str, true);
788
+ break;
789
+ case TABLECAPTION:
790
+ if ((n->children != NULL) && (n->children->key == TABLELABEL)) {
791
+ temp = label_from_string(n->children->str);
792
+ } else {
793
+ temp = label_from_node_tree(n->children);
794
+ }
795
+ g_string_append_printf(out, "\\caption{");
796
+ print_latex_node_tree(out, n->children, scratch);
797
+ g_string_append_printf(out, "}\n\\label{%s}\n", temp);
798
+ free(temp);
799
+ break;
800
+ case TABLELABEL:
801
+ break;
802
+ case TABLEHEAD:
803
+ print_latex_node_tree(out, n->children, scratch);
804
+ g_string_append_printf(out, "\\midrule\n");
805
+ break;
806
+ case TABLEBODY:
807
+ print_latex_node_tree(out, n->children, scratch);
808
+ if ((n->next != NULL) && (n->next->key == TABLEBODY)) {
809
+ g_string_append_printf(out, "\n\\midrule\n");
810
+ } else {
811
+ g_string_append_printf(out, "\n\\bottomrule\n");
812
+ }
813
+ break;
814
+ case TABLEROW:
815
+ print_latex_node_tree(out, n->children, scratch);
816
+ g_string_append_printf(out, "\\\\\n");
817
+ break;
818
+ case TABLECELL:
819
+ scratch->padded = 2;
820
+ if ((n->children != NULL) && (n->children->key == CELLSPAN)) {
821
+ g_string_append_printf(out, "\\multicolumn{%d}{c}{",(int)strlen(n->children->str)+1);
822
+ }
823
+ print_latex_node_tree(out, n->children, scratch);
824
+ if ((n->children != NULL) && (n->children->key == CELLSPAN)) {
825
+ g_string_append_printf(out, "}");
826
+ }
827
+ if (n->next != NULL)
828
+ g_string_append_printf(out, "&");
829
+ break;
830
+ case CELLSPAN:
831
+ break;
832
+ case GLOSSARYSOURCE:
833
+ if (scratch->printing_notes)
834
+ print_latex_node_tree(out, n->children, scratch);
835
+ break;
836
+ case CITATIONSOURCE:
837
+ case NOTESOURCE:
838
+ if (scratch->printing_notes)
839
+ print_latex_node(out, n->children, scratch);
840
+ break;
841
+ case SOURCEBRANCH:
842
+ fprintf(stderr,"SOURCEBRANCH\n");
843
+ break;
844
+ case NOTELABEL:
845
+ break;
846
+ case SUPERSCRIPT:
847
+ g_string_append_printf(out, "\\textsuperscript{%s}",n->str);
848
+ break;
849
+ case SUBSCRIPT:
850
+ g_string_append_printf(out, "\\textsubscript{%s}",n->str);
851
+ break;
852
+ case KEY_COUNTER:
853
+ break;
854
+ default:
855
+ fprintf(stderr, "print_latex_node encountered unknown node key = %d\n",n->key);
856
+ exit(EXIT_FAILURE);
857
+ }
858
+ }
859
+
860
+ /* print_latex_endnotes */
861
+ void print_latex_endnotes(GString *out, scratch_pad *scratch) {
862
+ scratch->used_notes = reverse_list(scratch->used_notes);
863
+ scratch->printing_notes = 1;
864
+
865
+ node *note = scratch->used_notes;
866
+ #ifdef DEBUG_ON
867
+ fprintf(stderr, "start endnotes\n");
868
+ #endif
869
+
870
+ if ((note == NULL) || ((note->key == KEY_COUNTER) && (note->next == NULL)))
871
+ return;
872
+ while (note != NULL) {
873
+ if (note->key == CITATIONSOURCE)
874
+ break;
875
+ note = note->next;
876
+ }
877
+
878
+ if (note == NULL)
879
+ return;
880
+
881
+ note = scratch->used_notes;
882
+
883
+ /* TODO: need CITATIONSOURCE to print bibliography */
884
+ #ifdef DEBUG_ON
885
+ fprintf(stderr, "there are endnotes to print\n");
886
+ #endif
887
+
888
+ pad(out, 2, scratch);
889
+ g_string_append_printf(out, "\\begin{thebibliography}{0}");
890
+ while ( note != NULL) {
891
+ if (note->key == KEY_COUNTER) {
892
+ note = note->next;
893
+ continue;
894
+ }
895
+
896
+ pad(out, 1, scratch);
897
+
898
+ if (note->key == CITATIONSOURCE) {
899
+ g_string_append_printf(out, "\\bibitem{%s}\n", note->str);
900
+ scratch->padded = 2;
901
+
902
+ print_latex_node(out, note, scratch);
903
+ pad(out, 1, scratch);
904
+ scratch->padded = 1;
905
+ } else {
906
+ /* footnotes handled elsewhere */
907
+ }
908
+
909
+ note = note->next;
910
+ }
911
+ pad(out,2, scratch);
912
+ g_string_append_printf(out, "\\end{thebibliography}");
913
+ scratch->padded = 0;
914
+ #ifdef DEBUG_ON
915
+ fprintf(stderr, "finish endnotes\n");
916
+ #endif
917
+ }
918
+
919
+ /* Check metadata keys and determine if we need a complete document */
920
+ /* We also preconvert metadata keys to proper formatting -- lowercase with no spaces */
921
+ bool is_latex_complete_doc(node *meta) {
922
+ node *step;
923
+ char *temp;
924
+ step = meta->children;
925
+
926
+ while (step != NULL) {
927
+ /* process key to proper label */
928
+ temp = step->str; /* store pointer to original str */
929
+ step->str = label_from_string(step->str);
930
+ free(temp); /* free original since we don't need it */
931
+ step = step->next;
932
+ }
933
+
934
+ step = meta->children;
935
+ while (step != NULL) {
936
+ /* the following types of metadata do not require a complete document */
937
+ if ((strcmp(step->str, "baseheaderlevel") != 0) &&
938
+ (strcmp(step->str, "xhtmlheaderlevel") != 0) &&
939
+ (strcmp(step->str, "htmlheaderlevel") != 0) &&
940
+ (strcmp(step->str, "latexheaderlevel") != 0) &&
941
+ (strcmp(step->str, "odfheaderlevel") != 0) &&
942
+ (strcmp(step->str, "xhtmlheader") != 0) &&
943
+ (strcmp(step->str, "htmlheader") != 0) &&
944
+ (strcmp(step->str, "quoteslanguage") != 0))
945
+ { return TRUE;}
946
+ step = step->next;
947
+ }
948
+
949
+ return FALSE;
950
+ }
951
+
952
+ /* print_latex_localized_typography -- convert to "smart" typography */
953
+ void print_latex_localized_typography(GString *out, int character, scratch_pad *scratch) {
954
+ if (!extension(EXT_SMART, scratch->extensions)) {
955
+ g_string_append_c(out, character);
956
+ return;
957
+ }
958
+ switch (character) {
959
+ case LSQUOTE:
960
+ switch (scratch->language) {
961
+ case SWEDISH:
962
+ g_string_append_printf(out, "'");
963
+ break;
964
+ case FRENCH:
965
+ g_string_append_printf(out,"'");
966
+ break;
967
+ case GERMAN:
968
+ g_string_append_printf(out,"‚");
969
+ break;
970
+ case GERMANGUILL:
971
+ g_string_append_printf(out,"›");
972
+ break;
973
+ default:
974
+ g_string_append_printf(out,"`");
975
+ }
976
+ break;
977
+ case RSQUOTE:
978
+ switch (scratch->language) {
979
+ case GERMAN:
980
+ g_string_append_printf(out,"`");
981
+ break;
982
+ case GERMANGUILL:
983
+ g_string_append_printf(out,"‹");
984
+ break;
985
+ default:
986
+ g_string_append_printf(out,"'");
987
+ }
988
+ break;
989
+ case APOS:
990
+ g_string_append_printf(out,"'");
991
+ break;
992
+ case LDQUOTE:
993
+ switch (scratch->language) {
994
+ case DUTCH:
995
+ case GERMAN:
996
+ g_string_append_printf(out,"„");
997
+ break;
998
+ case GERMANGUILL:
999
+ g_string_append_printf(out,"»");
1000
+ break;
1001
+ case FRENCH:
1002
+ g_string_append_printf(out,"«");
1003
+ break;
1004
+ case SWEDISH:
1005
+ g_string_append_printf(out, "''");
1006
+ break;
1007
+ default:
1008
+ g_string_append_printf(out,"``");
1009
+ }
1010
+ break;
1011
+ case RDQUOTE:
1012
+ switch (scratch->language) {
1013
+ case SWEDISH:
1014
+ case DUTCH:
1015
+ g_string_append_printf(out,"''");
1016
+ break;
1017
+ case GERMAN:
1018
+ g_string_append_printf(out,"``");
1019
+ break;
1020
+ case GERMANGUILL:
1021
+ g_string_append_printf(out,"«");
1022
+ break;
1023
+ case FRENCH:
1024
+ g_string_append_printf(out,"»");
1025
+ break;
1026
+ default:
1027
+ g_string_append_printf(out,"''");
1028
+ }
1029
+ break;
1030
+ case NDASH:
1031
+ g_string_append_printf(out,"--");
1032
+ break;
1033
+ case MDASH:
1034
+ g_string_append_printf(out,"---");
1035
+ break;
1036
+ case ELLIP:
1037
+ g_string_append_printf(out,"{\\ldots}");
1038
+ break;
1039
+ default:;
1040
+ }
1041
+ }
1042
+
1043
+ /* print_latex_string - print string, escaping for LaTeX */
1044
+ void print_latex_string(GString *out, char *str, scratch_pad *scratch) {
1045
+ char *tmp;
1046
+ if (str == NULL)
1047
+ return;
1048
+ while (*str != '\0') {
1049
+ switch (*str) {
1050
+ case '{': case '}': case '$': case '%':
1051
+ case '&': case '_': case '#':
1052
+ g_string_append_printf(out, "\\%c", *str);
1053
+ break;
1054
+ case '^':
1055
+ g_string_append_printf(out, "\\^{}");
1056
+ break;
1057
+ case '\\':
1058
+ g_string_append_printf(out, "\\textbackslash{}");
1059
+ break;
1060
+ case '~':
1061
+ g_string_append_printf(out, "\\ensuremath{\\sim}");
1062
+ break;
1063
+ case '|':
1064
+ g_string_append_printf(out, "\\textbar{}");
1065
+ break;
1066
+ case '<':
1067
+ g_string_append_printf(out, "$<$");
1068
+ break;
1069
+ case '>':
1070
+ g_string_append_printf(out, "$>$");
1071
+ break;
1072
+ case '/':
1073
+ str++;
1074
+ while (*str == '/') {
1075
+ g_string_append_printf(out, "/");
1076
+ str++;
1077
+ }
1078
+ g_string_append_printf(out, "\\slash ");
1079
+ str--;
1080
+ break;
1081
+ case '\n':
1082
+ tmp = str;
1083
+ tmp--;
1084
+ if (*tmp == ' ') {
1085
+ tmp--;
1086
+ if (*tmp == ' ') {
1087
+ g_string_append_printf(out, "\\\\\n");
1088
+ } else {
1089
+ g_string_append_printf(out, "\n");
1090
+ }
1091
+ } else {
1092
+ g_string_append_printf(out, "\n");
1093
+ }
1094
+ break;
1095
+ default:
1096
+ g_string_append_c(out, *str);
1097
+ }
1098
+ str++;
1099
+ }
1100
+ }
1101
+
1102
+ /* print_latex_url - print url, escaping for LaTeX */
1103
+ void print_latex_url(GString *out, char *str, scratch_pad *scratch) {
1104
+ if (str == NULL)
1105
+ return;
1106
+ while (*str != '\0') {
1107
+ switch (*str) {
1108
+ case '$': case '%': case '!':
1109
+ case '&': case '_': case '#':
1110
+ g_string_append_printf(out, "\\%c", *str);
1111
+ break;
1112
+ case '^':
1113
+ g_string_append_printf(out, "\\^{}");
1114
+ break;
1115
+ default:
1116
+ g_string_append_c(out, *str);
1117
+ }
1118
+ str++;
1119
+ }
1120
+ }
1121
+
1122
+ char * correct_dimension_units(char *original) {
1123
+ char *result;
1124
+ int i;
1125
+
1126
+ result = strdup(original);
1127
+
1128
+ for (i = 0; result[i]; i++)
1129
+ result[i] = tolower(result[i]);
1130
+
1131
+ if (strstr(&result[strlen(result)-2],"px")) {
1132
+ result[strlen(result)-2] = '\0';
1133
+ strcat(result, "pt");
1134
+ }
1135
+
1136
+ return result;
1137
+ }