rmultimarkdown 4.7.1.1 → 6.2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -2
  3. data/README.md +7 -9
  4. data/Rakefile +33 -18
  5. data/ext/Makefile +261 -0
  6. data/ext/extconf.rb +23 -3
  7. data/ext/mmd/aho-corasick.c +596 -0
  8. data/ext/mmd/aho-corasick.h +120 -0
  9. data/ext/mmd/beamer.c +344 -0
  10. data/ext/mmd/beamer.h +72 -0
  11. data/ext/mmd/char.c +156 -0
  12. data/ext/mmd/char.h +111 -0
  13. data/ext/mmd/char_lookup.c +212 -0
  14. data/ext/mmd/critic_markup.c +330 -0
  15. data/ext/mmd/critic_markup.h +94 -0
  16. data/ext/mmd/d_string.c +402 -0
  17. data/ext/mmd/epub.c +563 -0
  18. data/ext/mmd/epub.h +69 -0
  19. data/ext/mmd/fodt.c +2288 -0
  20. data/ext/mmd/fodt.h +81 -0
  21. data/ext/mmd/html.c +2460 -0
  22. data/ext/mmd/html.h +81 -0
  23. data/ext/mmd/i18n.h +170 -0
  24. data/ext/mmd/include/d_string.h +182 -0
  25. data/ext/mmd/include/libMultiMarkdown.h +548 -0
  26. data/ext/mmd/include/token.h +233 -0
  27. data/ext/mmd/latex.c +2435 -0
  28. data/ext/mmd/latex.h +83 -0
  29. data/ext/mmd/lexer.c +3001 -0
  30. data/ext/mmd/lexer.h +75 -0
  31. data/ext/mmd/memoir.c +138 -0
  32. data/ext/mmd/memoir.h +67 -0
  33. data/ext/mmd/miniz.c +7557 -0
  34. data/ext/mmd/miniz.h +1328 -0
  35. data/ext/mmd/mmd.c +2798 -0
  36. data/ext/mmd/mmd.h +120 -0
  37. data/ext/mmd/object_pool.c +141 -0
  38. data/ext/mmd/object_pool.h +101 -0
  39. data/ext/mmd/opendocument-content.c +2071 -0
  40. data/ext/mmd/opendocument-content.h +135 -0
  41. data/ext/mmd/opendocument.c +981 -0
  42. data/ext/mmd/opendocument.h +118 -0
  43. data/ext/mmd/parser.c +1760 -0
  44. data/ext/mmd/parser.h +39 -0
  45. data/{MultiMarkdown-4 → ext/mmd}/rng.c +90 -49
  46. data/ext/mmd/scanners.c +77512 -0
  47. data/ext/mmd/scanners.h +101 -0
  48. data/ext/mmd/stack.c +142 -0
  49. data/ext/mmd/stack.h +113 -0
  50. data/ext/mmd/textbundle.c +455 -0
  51. data/ext/mmd/textbundle.h +115 -0
  52. data/ext/mmd/token.c +773 -0
  53. data/ext/mmd/token_pairs.c +263 -0
  54. data/ext/mmd/token_pairs.h +123 -0
  55. data/ext/mmd/transclude.c +549 -0
  56. data/ext/mmd/transclude.h +87 -0
  57. data/ext/mmd/uthash.h +1074 -0
  58. data/ext/mmd/uuid.c +154 -0
  59. data/ext/mmd/uuid.h +77 -0
  60. data/ext/mmd/version.h +111 -0
  61. data/ext/mmd/writer.c +2652 -0
  62. data/ext/mmd/writer.h +260 -0
  63. data/ext/mmd/zip.c +210 -0
  64. data/ext/mmd/zip.h +120 -0
  65. data/ext/{multi_markdown.c → ruby_multi_markdown.c} +87 -18
  66. data/lib/multi_markdown.bundle +0 -0
  67. data/lib/multi_markdown.rb +5 -8
  68. data/lib/multi_markdown/version.rb +1 -1
  69. data/rmultimarkdown.gemspec +2 -2
  70. data/test/{extensions_test.rb.rb → extensions_test.rb} +10 -54
  71. data/test/multi_markdown_test.rb +13 -0
  72. metadata +67 -47
  73. data/MultiMarkdown-4/GLibFacade.c +0 -310
  74. data/MultiMarkdown-4/GLibFacade.h +0 -100
  75. data/MultiMarkdown-4/beamer.c +0 -182
  76. data/MultiMarkdown-4/beamer.h +0 -11
  77. data/MultiMarkdown-4/critic.c +0 -111
  78. data/MultiMarkdown-4/critic.h +0 -15
  79. data/MultiMarkdown-4/glib.h +0 -11
  80. data/MultiMarkdown-4/html.c +0 -1117
  81. data/MultiMarkdown-4/html.h +0 -14
  82. data/MultiMarkdown-4/latex.c +0 -1217
  83. data/MultiMarkdown-4/latex.h +0 -16
  84. data/MultiMarkdown-4/libMultiMarkdown.h +0 -177
  85. data/MultiMarkdown-4/lyx.c +0 -2265
  86. data/MultiMarkdown-4/lyx.h +0 -37
  87. data/MultiMarkdown-4/lyxbeamer.c +0 -265
  88. data/MultiMarkdown-4/lyxbeamer.h +0 -11
  89. data/MultiMarkdown-4/memoir.c +0 -80
  90. data/MultiMarkdown-4/memoir.h +0 -10
  91. data/MultiMarkdown-4/multimarkdown.c +0 -518
  92. data/MultiMarkdown-4/odf.c +0 -1222
  93. data/MultiMarkdown-4/odf.h +0 -18
  94. data/MultiMarkdown-4/opml.c +0 -189
  95. data/MultiMarkdown-4/opml.h +0 -15
  96. data/MultiMarkdown-4/parse_utilities.c +0 -884
  97. data/MultiMarkdown-4/parser.c +0 -16656
  98. data/MultiMarkdown-4/parser.h +0 -188
  99. data/MultiMarkdown-4/rtf.c +0 -665
  100. data/MultiMarkdown-4/rtf.h +0 -17
  101. data/MultiMarkdown-4/strtok.c +0 -56
  102. data/MultiMarkdown-4/strtok.h +0 -9
  103. data/MultiMarkdown-4/text.c +0 -53
  104. data/MultiMarkdown-4/text.h +0 -11
  105. data/MultiMarkdown-4/toc.c +0 -142
  106. data/MultiMarkdown-4/toc.h +0 -15
  107. data/MultiMarkdown-4/transclude.c +0 -307
  108. data/MultiMarkdown-4/transclude.h +0 -28
  109. data/MultiMarkdown-4/writer.c +0 -731
  110. data/MultiMarkdown-4/writer.h +0 -38
@@ -1,28 +0,0 @@
1
- /*
2
-
3
- transclude.h -- miscellaneous support functions
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 <stdio.h>
19
- #include <string.h>
20
- #include <stdlib.h>
21
- #include <stdbool.h>
22
- #include <libgen.h>
23
- #include "GLibFacade.h"
24
-
25
- char * source_without_metadata(char * source, unsigned long extensions);
26
- void transclude_source(GString *source, char *basedir, char *stack, int format, GString *manifest);
27
- void append_mmd_footer(GString *source);
28
- void prepend_mmd_header(GString *source);
@@ -1,731 +0,0 @@
1
- /*
2
-
3
- writer.c -- General routines for converting parse structure to various
4
- output formats.
5
-
6
- (c) 2013-2015 Fletcher T. Penney (http://fletcherpenney.net/).
7
-
8
- Derived from peg-multimarkdown, which was forked from peg-markdown,
9
- which is (c) 2008 John MacFarlane (jgm at berkeley dot edu), and
10
- licensed under GNU GPL or MIT.
11
-
12
- This program is free software; you can redistribute it and/or modify
13
- it under the terms of the GNU General Public License or the MIT
14
- license. See LICENSE for details.
15
-
16
- This program is distributed in the hope that it will be useful,
17
- but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- GNU General Public License for more details.
20
-
21
- */
22
-
23
- #include "writer.h"
24
-
25
- /* export_node_tree -- given a tree, export as specified format */
26
- char * export_node_tree(node *list, int format, unsigned long extensions) {
27
- char *output;
28
- GString *out = g_string_new("");
29
- scratch_pad *scratch = mk_scratch_pad(extensions);
30
- scratch->result_tree = list; /* Pointer to result tree to use later */
31
-
32
- #ifdef DEBUG_ON
33
- fprintf(stderr, "export_node_tree\n");
34
- #endif
35
-
36
- #ifdef DEBUG_ON
37
- fprintf(stderr, "extract_references\n");
38
- #endif
39
-
40
- if ((format != OPML_FORMAT) &&
41
- (format != CRITIC_ACCEPT_FORMAT) &&
42
- (format != CRITIC_REJECT_FORMAT) &&
43
- (format != CRITIC_HTML_HIGHLIGHT_FORMAT)) {
44
- /* Find defined abbreviations */
45
- extract_abbreviations(list, scratch);
46
- /* Apply those abbreviations to source text */
47
- find_abbreviations(list, scratch);
48
-
49
- /* Parse for link, images, etc reference definitions */
50
- extract_references(list, scratch);
51
- }
52
-
53
- /* Change our desired format based on metadata */
54
- if (format == LATEX_FORMAT)
55
- format = find_latex_mode(format, list);
56
-
57
- switch (format) {
58
- case TEXT_FORMAT:
59
- print_text_node_tree(out, list, scratch);
60
- break;
61
- case HTML_FORMAT:
62
- if (scratch->extensions & EXT_COMPLETE) {
63
- g_string_append_printf(out,
64
- "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\"/>\n");
65
- }
66
- #ifdef DEBUG_ON
67
- fprintf(stderr, "print_html output\n");
68
- #endif
69
- print_html_node_tree(out, list, scratch);
70
- #ifdef DEBUG_ON
71
- fprintf(stderr, "print html endnotes\n");
72
- #endif
73
- print_html_endnotes(out, scratch);
74
- #ifdef DEBUG_ON
75
- fprintf(stderr, "finished printing html endnotes\n");
76
- #endif
77
- if (scratch->extensions & EXT_COMPLETE) {
78
- pad(out,2, scratch);
79
- g_string_append_printf(out, "</body>\n</html>");
80
- }
81
- #ifdef DEBUG_ON
82
- fprintf(stderr, "closed HTML document\n");
83
- #endif
84
- break;
85
- case LATEX_FORMAT:
86
- if ((list != NULL) && (list->key != METADATA)) {
87
- print_latex_node_tree(out, scratch->abbreviations, scratch);
88
- }
89
- print_latex_node_tree(out, list, scratch);
90
- break;
91
- case MEMOIR_FORMAT:
92
- if ((list != NULL) && (list->key != METADATA)) {
93
- print_memoir_node_tree(out, scratch->abbreviations, scratch);
94
- }
95
- print_memoir_node_tree(out, list, scratch);
96
- break;
97
- case BEAMER_FORMAT:
98
- if ((list != NULL) && (list->key != METADATA)) {
99
- print_beamer_node_tree(out, scratch->abbreviations, scratch);
100
- }
101
- print_beamer_node_tree(out, list, scratch);
102
- break;
103
- case LYX_FORMAT:
104
- perform_lyx_output(out,list,scratch);
105
- break;
106
- case OPML_FORMAT:
107
- #ifdef DEBUG_ON
108
- fprintf(stderr, "export OPML\n");
109
- #endif
110
- begin_opml_output(out, list, scratch);
111
- print_opml_node_tree(out, list, scratch);
112
- end_opml_output(out, list, scratch);
113
- break;
114
- case ODF_FORMAT:
115
- #ifdef DEBUG_ON
116
- fprintf(stderr, "export ODF\n");
117
- #endif
118
- begin_odf_output(out, list, scratch);
119
- print_odf_node_tree(out, list, scratch);
120
- end_odf_output(out, list, scratch);
121
- break;
122
- case RTF_FORMAT:
123
- #ifdef DEBUG_ON
124
- fprintf(stderr, "export RTF\n");
125
- #endif
126
- if (!(scratch->extensions & EXT_SNIPPET))
127
- begin_rtf_output(out, list, scratch);
128
- print_rtf_node_tree(out, list, scratch);
129
- if (!(scratch->extensions & EXT_SNIPPET))
130
- end_rtf_output(out, list, scratch);
131
- break;
132
- case CRITIC_ACCEPT_FORMAT:
133
- print_critic_accept_node_tree(out, list, scratch);
134
- break;
135
- case CRITIC_REJECT_FORMAT:
136
- print_critic_reject_node_tree(out, list, scratch);
137
- break;
138
- case CRITIC_HTML_HIGHLIGHT_FORMAT:
139
- print_critic_html_highlight_node_tree(out, list, scratch);
140
- break;
141
- case TOC_FORMAT:
142
- scratch->toc_level = 0;
143
- print_toc_node_tree(out,list,scratch);
144
- break;
145
- default:
146
- fprintf(stderr, "Unknown export format = %d\n",format);
147
- exit(EXIT_FAILURE);
148
- }
149
-
150
- output = out->str;
151
- g_string_free(out, false);
152
- free_scratch_pad(scratch);
153
-
154
- #ifdef DEBUG_ON
155
- fprintf(stderr, "finish export_node_tree\n");
156
- #endif
157
- return output;
158
- }
159
-
160
- /* extract_references -- go through node tree and find elements we need to reference;
161
- e.g. links, images, citations, footnotes
162
- Copy them from main parse tree */
163
- void extract_references(node *list, scratch_pad *scratch) {
164
- node *temp;
165
- link_data *l;
166
-
167
- while (list != NULL) {
168
- switch (list->key) {
169
- case LINKREFERENCE:
170
- l = list->link_data;
171
- temp = mk_link(list->children, l->label, l->source, l->title, NULL);
172
- temp->link_data->attr = copy_node_tree(l->attr);
173
-
174
- /* store copy of link reference */
175
- scratch->links = cons(temp, scratch->links);
176
-
177
- break;
178
- case NOTESOURCE:
179
- case GLOSSARYSOURCE:
180
- temp = copy_node(list);
181
- scratch->notes = cons(temp, scratch->notes);
182
- break;
183
- case H1: case H2: case H3: case H4: case H5: case H6:
184
- if ((list->children->key != AUTOLABEL) && !(scratch->extensions & EXT_NO_LABELS)
185
- && !(scratch->extensions & EXT_COMPATIBILITY)) {
186
- char *label = label_from_node_tree(list->children);
187
-
188
- /* create a label from header */
189
- temp = mk_autolink(label);
190
- scratch->links = cons(temp, scratch->links);
191
- free(label);
192
- }
193
- break;
194
- case TABLE:
195
- if (list->children->key != TABLELABEL) {
196
- char *label = label_from_node(list->children);
197
-
198
- /* create a label from header */
199
- temp = mk_autolink(label);
200
- scratch->links = cons(temp, scratch->links);
201
- free(label);
202
- }
203
-
204
- break;
205
- case HEADINGSECTION:
206
- case RAW:
207
- case LIST:
208
- extract_references(list->children, scratch);
209
- break;
210
- default:
211
- break;
212
- }
213
- list = list->next;
214
- }
215
- }
216
-
217
- /* extract_abbreviations -- traverse node tree and find abbreviation definitions */
218
- void extract_abbreviations(node *list, scratch_pad *scratch) {
219
- node *temp;
220
-
221
- while (list != NULL) {
222
- switch (list->key) {
223
- case ABBREVIATION:
224
- temp = copy_node(list);
225
- list->key = KEY_COUNTER; /* Mark this as dead; we will use it elsewhere */
226
- trim_trailing_whitespace(temp->str);
227
- scratch->abbreviations = cons(temp, scratch->abbreviations);
228
- break;
229
- case HEADINGSECTION:
230
- case RAW:
231
- case LIST:
232
- case BLOCKQUOTEMARKER:
233
- case BLOCKQUOTE:
234
- extract_abbreviations(list->children, scratch);
235
- break;
236
- default:
237
- /* Try to boost performance by skipping dead ends */
238
- break;
239
- }
240
- list = list->next;
241
- }
242
- }
243
-
244
-
245
- /* find_abbreviations -- use abbreviations to look for matching strings */
246
- void find_abbreviations(node *list, scratch_pad *scratch) {
247
- node *abbr = scratch->abbreviations;
248
- node *temp, *target, *end = NULL;
249
- bool ismatch;
250
-
251
- // Don't look if we didn't define any abbreviations */
252
- if (abbr->key == KEY_COUNTER)
253
- return;
254
-
255
- while (list != NULL) {
256
- switch (list->key) {
257
- case STR:
258
- /* Look for matching abbrevation */
259
- /*fprintf(stderr, "Check '%s' for matching abbr\n", list->str); */
260
- abbr = scratch->abbreviations;
261
- while (abbr != NULL) {
262
- if (abbr->key != KEY_COUNTER) {
263
- ismatch = true;
264
- temp = abbr->children->children;
265
- target = list;
266
-
267
- while((ismatch) && (temp != NULL) && (target != NULL)) {
268
- switch (temp->key) {
269
- case STR:
270
- if (strcmp(temp->str, target->str) != 0) {
271
- ismatch = false;
272
- }
273
- case SPACE:
274
- case KEY_COUNTER:
275
- break;
276
- default:
277
- if (temp->key != target->key)
278
- ismatch = false;
279
- break;
280
- }
281
- temp = temp->next;
282
- end = target;
283
- target = target->next;
284
- }
285
- if ((ismatch) && (temp == NULL)) {
286
- temp = copy_node(abbr);
287
- temp->next = NULL;
288
- list->children = temp;
289
- if (list != end) {
290
- list->key = ABBRSTART;
291
- if (end != NULL)
292
- end->key = ABBRSTOP;
293
- } else {
294
- list->key = ABBR;
295
- }
296
- }
297
- }
298
- abbr = abbr->next;
299
- }
300
- break;
301
- case LIST:
302
- case ORDEREDLIST:
303
- case BULLETLIST:
304
- case LISTITEM:
305
- case HEADINGSECTION:
306
- case PARA:
307
- case PLAIN:
308
- case LINK:
309
- case LINKREFERENCE:
310
- case NOTEREFERENCE:
311
- case NOTESOURCE:
312
- case GLOSSARYSOURCE:
313
- case BLOCKQUOTEMARKER:
314
- case BLOCKQUOTE:
315
- /* Check children of these elements */
316
- find_abbreviations(list->children, scratch);
317
- break;
318
- default:
319
- /* Everything else we skip */
320
- break;
321
- }
322
- list = list->next;
323
- }
324
- }
325
-
326
-
327
- /* extract_link_data -- given a label, parse the link data and return */
328
- link_data * extract_link_data(char *label, scratch_pad *scratch) {
329
- char *temp;
330
- link_data *d;
331
- node *ref = scratch->links;
332
- bool debug = 0;
333
-
334
- if (debug)
335
- fprintf(stderr, "try to extract link for '%s'\n",label);
336
-
337
- if ((label == NULL) || (strlen(label) == 0))
338
- return NULL;
339
-
340
- temp = clean_string(label);
341
-
342
- /* look for label string as is */
343
- while (ref != NULL) {
344
- if (ref->key == KEY_COUNTER) {
345
- ref = ref->next;
346
-
347
- continue;
348
- }
349
- if (strcmp(ref->link_data->label, temp) == 0) {
350
- if (debug)
351
- fprintf(stderr,"a:matched %s to %s\n",ref->link_data->label, label);
352
- /* matched */
353
- d = ref->link_data;
354
- d = mk_link_data(d->label, d->source, d->title, d->attr);
355
- free(temp);
356
- return d;
357
- } else {
358
- if (debug)
359
- fprintf(stderr,"a:did not match %s to %s\n",ref->link_data->label, label);
360
- }
361
- ref = ref->next;
362
- }
363
- free(temp);
364
-
365
- /* No match. Check for label()version */
366
-
367
- if (scratch->extensions & EXT_COMPATIBILITY) {
368
- /* not in compat mode */
369
- return NULL;
370
- }
371
- temp = label_from_string(label);
372
-
373
- ref = scratch->links;
374
-
375
- while (ref != NULL) {
376
- if (ref->key == KEY_COUNTER) {
377
- ref = ref->next;
378
-
379
- continue;
380
- }
381
- if (strcmp(ref->link_data->label, temp) == 0) {
382
- if (debug)
383
- fprintf(stderr,"b:matched %s to %s\n",ref->link_data->label, label);
384
- /* matched */
385
- d = ref->link_data;
386
- d = mk_link_data(d->label, d->source, d->title, d->attr);
387
- free(temp);
388
- return d;
389
- } else {
390
- if (debug)
391
- fprintf(stderr,"b:did not match %s to %s\n",ref->link_data->label, label);
392
- }
393
- ref = ref->next;
394
- }
395
- free(temp);
396
-
397
- if (debug)
398
- fprintf(stderr, "finish extract\n");
399
- return NULL;
400
- }
401
-
402
- /* pad -- ensure that at least 'x' newlines are at end of output */
403
- void pad(GString *out, int num, scratch_pad *scratch) {
404
- while (num-- > scratch->padded)
405
- g_string_append_c(out, '\n');
406
-
407
- scratch->padded = num;
408
- }
409
-
410
- /* note_number_for_label -- given a label to match, determine number to be used*/
411
- int note_number_for_label(char *text, scratch_pad *scratch) {
412
- node *n = NULL;
413
- char *clean;
414
- char *label;
415
- #ifdef DEBUG_ON
416
- fprintf(stderr, "find note number for: %s\n",text);
417
- #endif
418
-
419
- if ((text == NULL) || (strlen(text) == 0))
420
- return 0; /* Nothing to find */
421
-
422
- clean = clean_string(text);
423
- label = label_from_string(clean);
424
-
425
- /* have we used this note already? */
426
-
427
- /* look for label string as is */
428
- n = node_matching_label(clean, scratch->used_notes);
429
-
430
- /* if not, look in reserve queue */
431
- if (n == NULL) {
432
- n = node_matching_label(clean, scratch->notes);
433
-
434
- if (n != NULL) {
435
- /* move to used queue */
436
- move_note_to_used(n, scratch);
437
- #ifdef DEBUG_ON
438
- fprintf(stderr, "note has not already been used for: %s\n",text);
439
- #endif
440
- }
441
- } else {
442
- #ifdef DEBUG_ON
443
- fprintf(stderr, "note has already been used for: %s\n",text);
444
- #endif
445
- }
446
-
447
- /* Check label version */
448
- if (n == NULL)
449
- n = node_matching_label(label, scratch->used_notes);
450
-
451
- if (n == NULL) {
452
- n = node_matching_label(label, scratch->notes);
453
-
454
- if (n != NULL) {
455
- /* move to used queue */
456
- move_note_to_used(n, scratch);
457
- #ifdef DEBUG_ON
458
- fprintf(stderr, "note has not already been used for: %s\n",label);
459
- #endif
460
- }
461
- } else {
462
- #ifdef DEBUG_ON
463
- fprintf(stderr, "note has already been used for: %s\n",label);
464
- #endif
465
-
466
- }
467
-
468
- /* CAN recursively drill down to start counter at 0 and ++ */
469
- /* if found, move to used queue and return the number */
470
-
471
- free(label);
472
- free(clean);
473
- if (n != NULL) {
474
- #ifdef DEBUG_ON
475
- fprintf(stderr, "note number is: %d\n",count_node_from_end(n));
476
- #endif
477
- return count_node_from_end(n);
478
- }
479
- else
480
- return 0;
481
- }
482
-
483
- /* note_number_for_node -- given a note reference to match, determine number to be used*/
484
- int note_number_for_node(node *ref, scratch_pad *scratch) {
485
- char *label = ref->str;
486
- node *n = NULL;
487
- int num = 0;
488
-
489
- num = note_number_for_label(label, scratch);
490
-
491
- if (num > 0)
492
- return num;
493
-
494
- /* None found, so treat as inline note */
495
- n = ref->children;
496
- use_inline_footnote(ref, scratch);
497
-
498
- return count_node_from_end(n);
499
- }
500
-
501
-
502
- /* node_matching_label -- given a string, return the node matching the string */
503
- node * node_matching_label(char *label, node *n) {
504
- while (n != NULL) {
505
- if (n->key == KEY_COUNTER) {
506
- n = n->next;
507
- continue;
508
- }
509
- if (strcmp(n->str, label) == 0) {
510
- return n;
511
- }
512
- n = n->next;
513
- }
514
-
515
- return NULL;
516
- }
517
-
518
- /* since lists are stored in reverse order, need to count from end */
519
- int count_node_from_end(node *n) {
520
- if (n->next == NULL) {
521
- if (n->key == KEY_COUNTER)
522
- return 0;
523
- #ifdef DEBUG_ON
524
- fprintf(stderr, "note %d: '%s'\n",1,n->str);
525
- #endif
526
- return 1; /* reserve 0 for not found */
527
- }
528
- #ifdef DEBUG_ON
529
- fprintf(stderr, "note %d: '%s'\n",count_node_from_end(n->next) +1,n->str);
530
- #endif
531
- return (count_node_from_end(n->next) + 1);
532
- }
533
-
534
- /* since lists are stored in reverse order, need to count from end
535
- Only count cites (not footnotes) */
536
- int cite_count_node_from_end(node *n) {
537
- if (n->next == NULL) {
538
- /* we're the last node */
539
- if (n->key == CITATIONSOURCE)
540
- return 1;
541
- return 0; /* reserve 0 for not found */
542
- }
543
- if (n->key == CITATIONSOURCE) {
544
- return (cite_count_node_from_end(n->next) + 1);
545
- } else {
546
- return (cite_count_node_from_end(n->next));
547
- }
548
- }
549
-
550
- /* node_for_count -- given a number, get that node */
551
- node * node_for_count(node *n, int count) {
552
- if (n == NULL)
553
- return NULL;
554
-
555
- int total = count_node_from_end(n);
556
-
557
- if (count > total)
558
- return NULL;
559
-
560
- if (count == total)
561
- return n;
562
-
563
- while (total > count) {
564
- n = n->next;
565
- if (n == NULL)
566
- return NULL;
567
- total--;
568
- }
569
-
570
- return n;
571
- }
572
-
573
- /* move_note_to_used -- snip note from ->notes and move to used_notes */
574
- void move_note_to_used(node *list, scratch_pad *scratch) {
575
- node * n = scratch->notes;
576
- node * last = NULL;
577
-
578
- while (n != NULL) {
579
- if (n == list) {
580
- if (last != NULL) {
581
- last->next = n->next;
582
- } else {
583
- scratch->notes = n->next;
584
- }
585
- scratch->used_notes = cons(n, scratch->used_notes);
586
- return;
587
- }
588
- last = n;
589
- n = n->next;
590
- }
591
- }
592
-
593
- /* use_inline_footnote -- create a new note definition from inline footnote */
594
- void use_inline_footnote(node *ref, scratch_pad *scratch) {
595
- scratch->used_notes = cons(ref->children, scratch->used_notes);
596
- ref->children = NULL;
597
- }
598
-
599
- /* find attribute, if present */
600
- node * node_for_attribute(char *querystring, node *list) {
601
- #ifdef DEBUG_ON
602
- fprintf(stderr, "start node_for_attribute\n");
603
- #endif
604
- node *step = NULL;
605
- step = list;
606
- char *query;
607
-
608
- if (querystring == NULL)
609
- return NULL;
610
-
611
- query = label_from_string(querystring);
612
- #ifdef DEBUG_ON
613
- fprintf(stderr, "node_for_attribute 2: '%s'\n",query);
614
- #endif
615
-
616
- while (step != NULL) {
617
- if ((step->str != NULL) && (strcmp(step->str,query) == 0)) {
618
- free(query);
619
- #ifdef DEBUG_ON
620
- fprintf(stderr, "matched node_for_attribute\n");
621
- #endif
622
- return step;
623
- }
624
- #ifdef DEBUG_ON
625
- fprintf(stderr, "'%s' doesn't match '%s'\n",query,step->str);
626
- if (step->next == NULL)
627
- fprintf(stderr, "no next node\n");
628
- #endif
629
- step = step->next;
630
- }
631
- free(query);
632
- #ifdef DEBUG_ON
633
- fprintf(stderr, "stop node_for_attribute\n");
634
- #endif
635
- return NULL;
636
- }
637
-
638
-
639
- /* convert attribute to dimensions suitable for LaTeX or ODF */
640
- /* returns c string that needs to be freed */
641
- char * dimension_for_attribute(char *querystring, node *list) {
642
- #ifdef DEBUG_ON
643
- fprintf(stderr, "start dimension_for_attribute\n");
644
- #endif
645
- node *attribute;
646
- char *dimension;
647
- char *ptr;
648
- int i;
649
- char *upper;
650
- GString *result;
651
-
652
- attribute = node_for_attribute(querystring, list);
653
- if (attribute == NULL) return NULL;
654
- #ifdef DEBUG_ON
655
- fprintf(stderr, "a\n");
656
- #endif
657
-
658
- dimension = strdup(attribute->children->str);
659
- upper = strdup(attribute->children->str);
660
-
661
- for(i = 0; dimension[ i ]; i++)
662
- dimension[i] = tolower(dimension[ i ]);
663
-
664
- for(i = 0; upper[ i ]; i++)
665
- upper[i] = toupper(upper[ i ]);
666
- #ifdef DEBUG_ON
667
- fprintf(stderr, "b\n");
668
- #endif
669
-
670
- if (strstr(dimension, "px")) {
671
- ptr = strstr(dimension,"px");
672
- ptr[0] = '\0';
673
- strcat(ptr,"pt");
674
- }
675
-
676
- result = g_string_new(dimension);
677
-
678
- if ((strcmp(dimension,upper) == 0) && (dimension[strlen(dimension) -1] != '%')) {
679
- /* no units */
680
- g_string_append_printf(result, "pt");
681
- }
682
-
683
- free(upper);
684
- free(dimension);
685
-
686
- dimension = result->str;
687
- g_string_free(result, false);
688
- #ifdef DEBUG_ON
689
- fprintf(stderr, "finish dimension_for_attribute\n");
690
- #endif
691
- return(dimension);
692
- }
693
-
694
-
695
- /* Load available info for a link */
696
- link_data * load_link_data(node *n, scratch_pad *scratch) {
697
- link_data *r = NULL;
698
- GString *temp_str = NULL;
699
- char *temp;
700
-
701
- r = mk_link_data(n->link_data->label, n->link_data->source, n->link_data->title, n->link_data->attr);
702
-
703
- /* Do we have proper info? */
704
- if ((r->label == NULL) &&
705
- (r->source == NULL)) {
706
- /* we seem to be a [foo][] style link */
707
- /* so load a label */
708
- temp_str = g_string_new("");
709
- print_raw_node_tree(temp_str, n->children);
710
- r->label = temp_str->str;
711
- g_string_free(temp_str, FALSE);
712
- }
713
- /* Load data by reference */
714
- if (r->label != NULL) {
715
- temp = strdup(r->label);
716
-
717
- r->attr = NULL;
718
- free_link_data(r);
719
-
720
- r = extract_link_data(temp, scratch);
721
- if (r == NULL) {
722
- /* return NULL since no definition found */
723
-
724
- free(temp);
725
- return NULL;
726
- }
727
- free(temp);
728
- }
729
-
730
- return r;
731
- }