rmultimarkdown 6.2.2.1 → 6.4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Makefile +2 -2
  3. data/ext/mmd/aho-corasick.c +12 -8
  4. data/ext/mmd/beamer.c +29 -0
  5. data/ext/mmd/critic_markup.c +100 -4
  6. data/ext/mmd/critic_markup.h +7 -0
  7. data/ext/mmd/d_string.c +502 -119
  8. data/ext/mmd/epub.c +2 -4
  9. data/ext/mmd/file.c +436 -0
  10. data/ext/mmd/file.h +153 -0
  11. data/ext/mmd/html.c +130 -37
  12. data/ext/mmd/include/d_string.h +20 -19
  13. data/ext/mmd/include/libMultiMarkdown.h +42 -27
  14. data/ext/mmd/include/token.h +15 -15
  15. data/ext/mmd/latex.c +107 -30
  16. data/ext/mmd/lexer.c +19 -7
  17. data/ext/mmd/lexer.h +2 -2
  18. data/ext/mmd/memoir.c +29 -0
  19. data/ext/mmd/mmd.c +65 -39
  20. data/ext/mmd/object_pool.h +4 -4
  21. data/ext/mmd/opendocument-content.c +95 -13
  22. data/ext/mmd/opendocument.c +315 -313
  23. data/ext/mmd/opml-lexer.c +2183 -0
  24. data/ext/mmd/opml-lexer.h +157 -0
  25. data/ext/mmd/opml-parser.c +1193 -0
  26. data/ext/mmd/opml-parser.h +15 -0
  27. data/ext/mmd/opml-reader.c +435 -0
  28. data/ext/mmd/opml-reader.h +111 -0
  29. data/ext/mmd/opml.c +511 -0
  30. data/ext/mmd/opml.h +115 -0
  31. data/ext/mmd/parser.c +2 -0
  32. data/ext/mmd/rng.c +1 -1
  33. data/ext/mmd/scanners.c +51663 -24824
  34. data/ext/mmd/stack.c +4 -2
  35. data/ext/mmd/stack.h +8 -8
  36. data/ext/mmd/textbundle.c +2 -4
  37. data/ext/mmd/token.c +24 -12
  38. data/ext/mmd/token_pairs.c +2 -2
  39. data/ext/mmd/token_pairs.h +10 -10
  40. data/ext/mmd/transclude.c +1 -226
  41. data/ext/mmd/transclude.h +0 -8
  42. data/ext/mmd/uuid.c +3 -3
  43. data/ext/mmd/version.h +3 -3
  44. data/ext/mmd/writer.c +99 -30
  45. data/ext/mmd/writer.h +11 -0
  46. data/lib/multi_markdown.bundle +0 -0
  47. data/lib/multi_markdown/version.rb +1 -1
  48. metadata +13 -5
  49. data/ext/mmd/fodt.c +0 -2288
  50. data/ext/mmd/fodt.h +0 -81
@@ -1,2288 +0,0 @@
1
- /**
2
-
3
- MultiMarkdown -- Lightweight markup processor to produce HTML, LaTeX, and more.
4
-
5
- @file fodt.c
6
-
7
- @brief Convert token tree to Flat OpenDocument (ODF/FODT) output
8
-
9
-
10
- @author Fletcher T. Penney
11
- @bug
12
-
13
- **/
14
-
15
- /*
16
-
17
- Copyright © 2016 - 2017 Fletcher T. Penney.
18
-
19
-
20
- The `MultiMarkdown 6` project is released under the MIT License..
21
-
22
- GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project:
23
-
24
- https://github.com/fletcher/MultiMarkdown-4/
25
-
26
- MMD 4 is released under both the MIT License and GPL.
27
-
28
-
29
- CuTest is released under the zlib/libpng license. See CuTest.c for the
30
- text of the license.
31
-
32
-
33
- ## The MIT License ##
34
-
35
- Permission is hereby granted, free of charge, to any person obtaining
36
- a copy of this software and associated documentation files (the
37
- "Software"), to deal in the Software without restriction, including
38
- without limitation the rights to use, copy, modify, merge, publish,
39
- distribute, sublicense, and/or sell copies of the Software, and to
40
- permit persons to whom the Software is furnished to do so, subject to
41
- the following conditions:
42
-
43
- The above copyright notice and this permission notice shall be
44
- included in all copies or substantial portions of the Software.
45
-
46
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
47
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
48
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
49
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
50
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
51
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
52
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
53
-
54
-
55
- */
56
-
57
-
58
- #include <ctype.h>
59
- #include <stdio.h>
60
- #include <stdlib.h>
61
- #include <string.h>
62
-
63
- #include "char.h"
64
- #include "i18n.h"
65
- #include "fodt.h"
66
- #include "parser.h"
67
- #include "scanners.h"
68
-
69
- #define print(x) d_string_append(out, x)
70
- #define print_const(x) d_string_append_c_array(out, x, sizeof(x) - 1)
71
- #define print_char(x) d_string_append_c(out, x)
72
- #define printf(...) d_string_append_printf(out, __VA_ARGS__)
73
- #define print_token(t) d_string_append_c_array(out, &(source[t->start]), t->len)
74
- #define print_localized(x) mmd_print_localized_char_odf(out, x, scratch)
75
-
76
-
77
- /// strdup() not available on all platforms
78
- static char * my_strdup(const char * source) {
79
- if (source == NULL) {
80
- return NULL;
81
- }
82
-
83
- char * result = malloc(strlen(source) + 1);
84
-
85
- if (result) {
86
- strcpy(result, source);
87
- }
88
-
89
- return result;
90
- }
91
-
92
-
93
- void mmd_print_char_odf(DString * out, char c) {
94
- switch (c) {
95
- case '"':
96
- print_const("&quot;");
97
- break;
98
-
99
- case '&':
100
- print_const("&amp;");
101
- break;
102
-
103
- case '<':
104
- print_const("&lt;");
105
- break;
106
-
107
- case '>':
108
- print_const("&gt;");
109
- break;
110
-
111
- case '\t':
112
- print_const("<text:tab/>");
113
-
114
- default:
115
- print_char(c);
116
- break;
117
- }
118
- }
119
-
120
-
121
- void mmd_print_string_odf(DString * out, const char * str) {
122
- if (str == NULL) {
123
- return;
124
- }
125
-
126
- while (*str != '\0') {
127
- mmd_print_char_odf(out, *str);
128
- str++;
129
- }
130
- }
131
-
132
-
133
- void mmd_print_localized_char_odf(DString * out, unsigned short type, scratch_pad * scratch) {
134
- switch (type) {
135
- case DASH_N:
136
- print_const("&#8211;");
137
- break;
138
-
139
- case DASH_M:
140
- print_const("&#8212;");
141
- break;
142
-
143
- case ELLIPSIS:
144
- print_const("&#8230;");
145
- break;
146
-
147
- case APOSTROPHE:
148
- print_const("&#8217;");
149
- break;
150
-
151
- case QUOTE_LEFT_SINGLE:
152
- switch (scratch->quotes_lang) {
153
- case SWEDISH:
154
- print( "&#8217;");
155
- break;
156
-
157
- case FRENCH:
158
- print_const("&#39;");
159
- break;
160
-
161
- case GERMAN:
162
- print_const("&#8218;");
163
- break;
164
-
165
- case GERMANGUILL:
166
- print_const("&#8250;");
167
- break;
168
-
169
- default:
170
- print_const("&#8216;");
171
- }
172
-
173
- break;
174
-
175
- case QUOTE_RIGHT_SINGLE:
176
- switch (scratch->quotes_lang) {
177
- case GERMAN:
178
- print_const("&#8216;");
179
- break;
180
-
181
- case GERMANGUILL:
182
- print_const("&#8249;");
183
- break;
184
-
185
- default:
186
- print_const("&#8217;");
187
- }
188
-
189
- break;
190
-
191
- case QUOTE_LEFT_DOUBLE:
192
- switch (scratch->quotes_lang) {
193
- case DUTCH:
194
- case GERMAN:
195
- print_const("&#8222;");
196
- break;
197
-
198
- case GERMANGUILL:
199
- print_const("&#187;");
200
- break;
201
-
202
- case FRENCH:
203
- print_const("&#171;");
204
- break;
205
-
206
- case SWEDISH:
207
- print( "&#8221;");
208
- break;
209
-
210
- default:
211
- print_const("&#8220;");
212
- }
213
-
214
- break;
215
-
216
- case QUOTE_RIGHT_DOUBLE:
217
- switch (scratch->quotes_lang) {
218
- case GERMAN:
219
- print_const("&#8220;");
220
- break;
221
-
222
- case GERMANGUILL:
223
- print_const("&#171;");
224
- break;
225
-
226
- case FRENCH:
227
- print_const("&#187;");
228
- break;
229
-
230
- case SWEDISH:
231
- case DUTCH:
232
- default:
233
- print_const("&#8221;");
234
- }
235
-
236
- break;
237
- }
238
- }
239
-
240
-
241
- void mmd_export_link_odf(DString * out, const char * source, token * text, link * link, scratch_pad * scratch) {
242
- if (link->url) {
243
- print_const("<text:a xlink:type=\"simple\" xlink:href=\"");
244
- mmd_print_string_odf(out, link->url);
245
- print_const("\"");
246
- } else {
247
- print_const("<a xlink:type=\"simple\" xlink:href=\"\"");
248
- }
249
-
250
- if (link->title && link->title[0] != '\0') {
251
- print_const(" office:name=\"");
252
- mmd_print_string_odf(out, link->title);
253
- print_const("\"");
254
- }
255
-
256
- print_const(">");
257
-
258
- // If we're printing contents of bracket as text, then ensure we include it all
259
- if (text && text->child && text->child->len > 1) {
260
- text->child->next->start--;
261
- text->child->next->len++;
262
- }
263
-
264
- mmd_export_token_tree_odf(out, source, text->child, scratch);
265
-
266
- print_const("</text:a>");
267
- }
268
-
269
-
270
- static char * correct_dimension_units(char *original) {
271
- char *result;
272
- int i;
273
-
274
- result = my_strdup(original);
275
-
276
- for (i = 0; result[i]; i++) {
277
- result[i] = tolower(result[i]);
278
- }
279
-
280
- if (strstr(&result[strlen(result) - 2], "px")) {
281
- result[strlen(result) - 2] = '\0';
282
- strcat(result, "pt");
283
- }
284
-
285
- return result;
286
- }
287
-
288
-
289
- void mmd_export_image_odf(DString * out, const char * source, token * text, link * link, scratch_pad * scratch, bool is_figure) {
290
- attr * a = link->attributes;
291
- char * height = NULL;
292
- char * width = NULL;
293
-
294
- print_const("<draw:frame text:anchor-type=\"as-char\"\ndraw:z-index=\"0\" draw:style-name=\"fr1\"");
295
-
296
- // Check attributes for dimensions
297
- while (a) {
298
- if (strcmp("height", a->key) == 0) {
299
- height = correct_dimension_units(a->value);
300
- } else if (strcmp("width", a->key) == 0) {
301
- width = correct_dimension_units(a->value);
302
- }
303
-
304
- a = a->next;
305
- }
306
-
307
- if (width) {
308
- printf(" svg:width=\"%s\">\n", width);
309
- } else {
310
- print_const(" svg:width=\"95%\">\n");
311
- }
312
-
313
- print_const("<draw:text-box><text:p><draw:frame text:anchor-type=\"as-char\" draw:z-index=\"1\" ");
314
-
315
- if (height && width) {
316
- printf("svg:height=\"%s\" ", height);
317
- printf("svg:width=\"%s\" ", width);
318
- }
319
-
320
- if (height) {
321
- free(height);
322
- }
323
-
324
- if (width) {
325
- free(width);
326
- }
327
-
328
- if (link->url) {
329
- printf(">\n<draw:image xlink:href=\"%s\"", link->url);
330
- }
331
-
332
- print_const(" xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\" draw:filter-name=\"&lt;All formats&gt;\"/>\n</draw:frame></text:p>");
333
-
334
- if (is_figure) {
335
- if (text) {
336
- print_const("\n<text:p>Figure <text:sequence text:name=\"Figure\" text:formula=\"ooow:Figure+1\" style:num-format=\"1\"> Update Fields to calculate numbers</text:sequence>: ");
337
- mmd_export_token_tree_odf(out, source, text->child, scratch);
338
- print_const("</text:p>");
339
- }
340
- }
341
-
342
- print_const("\n</draw:text-box></draw:frame>\n");
343
-
344
- scratch->padded = 1;
345
- }
346
-
347
-
348
-
349
- void mmd_export_toc_entry_odf(DString * out, const char * source, scratch_pad * scratch, size_t * counter, short level) {
350
- token * entry, * next;
351
- short entry_level, next_level;
352
- char * temp_char;
353
-
354
- // Iterate over tokens
355
- while (*counter < scratch->header_stack->size) {
356
- // Get token for header
357
- entry = stack_peek_index(scratch->header_stack, *counter);
358
- entry_level = raw_level_for_header(entry);
359
-
360
- if (entry_level >= level) {
361
- // This entry is a direct descendant of the parent
362
- temp_char = label_from_header(source, entry);
363
- printf("<text:p text:style-name=\"TOC_Item\"><text:a xlink:type=\"simple\" xlink:href=\"#%s\" text:style-name=\"Index_20_Link\" text:visited-style-name=\"Index_20_Link\">", temp_char);
364
- mmd_export_token_tree_odf(out, source, entry->child, scratch);
365
- print_const(" <text:tab/>1</text:a></text:p>\n");
366
-
367
- if (*counter < scratch->header_stack->size - 1) {
368
- next = stack_peek_index(scratch->header_stack, *counter + 1);
369
- next_level = next->type - BLOCK_H1 + 1;
370
-
371
- if (next_level > entry_level) {
372
- // This entry has children
373
- (*counter)++;
374
- mmd_export_toc_entry_odf(out, source, scratch, counter, entry_level + 1);
375
- }
376
- }
377
-
378
- free(temp_char);
379
- } else if (entry_level < level ) {
380
- // If entry < level, exit this level
381
- // Decrement counter first, so that we can test it again later
382
- (*counter)--;
383
- break;
384
- }
385
-
386
- // Increment counter
387
- (*counter)++;
388
- }
389
- }
390
-
391
- void mmd_export_toc_odf(DString * out, const char * source, scratch_pad * scratch) {
392
- size_t counter = 0;
393
-
394
- // TODO: Could use LC to internationalize this
395
- print_const("<text:table-of-content text:style-name=\"Sect1\" text:protected=\"true\" text:name=\"Table of Contents1\">\n");
396
- print_const("<text:table-of-content-source text:outline-level=\"10\">\n");
397
- print_const("<text:index-title-template text:style-name=\"Contents_20_Heading\">Table of Contents</text:index-title-template>\n");
398
- print_const("</text:table-of-content-source>\n<text:index-body>\n");
399
- print_const("<text:index-title text:style-name=\"Sect1\" text:name=\"Table of Contents1_Head\">\n");
400
- print_const("<text:p text:style-name=\"Contents_20_Heading\">Table of Contents</text:p>\n");
401
- print_const("</text:index-title>\n");
402
-
403
- mmd_export_toc_entry_odf(out, source, scratch, &counter, 0);
404
-
405
- print_const("</text:index-body>\n</text:table-of-content>\n\n");
406
- }
407
-
408
-
409
- void mmd_export_token_odf(DString * out, const char * source, token * t, scratch_pad * scratch) {
410
- if (t == NULL) {
411
- return;
412
- }
413
-
414
- short temp_short;
415
- short temp_short2;
416
- short temp_short3;
417
- link * temp_link = NULL;
418
- char * temp_char = NULL;
419
- char * temp_char2 = NULL;
420
- bool temp_bool = 0;
421
- token * temp_token = NULL;
422
- footnote * temp_note = NULL;
423
-
424
- switch (t->type) {
425
- case DOC_START_TOKEN:
426
- mmd_export_token_tree_odf(out, source, t->child, scratch);
427
- break;
428
-
429
- case AMPERSAND:
430
- case AMPERSAND_LONG:
431
- print_const("&amp;");
432
- break;
433
-
434
- case ANGLE_LEFT:
435
- print_const("&lt;");
436
- break;
437
-
438
- case ANGLE_RIGHT:
439
- print_const("&gt;");
440
- break;
441
-
442
- case APOSTROPHE:
443
- if (!(scratch->extensions & EXT_SMART)) {
444
- print_token(t);
445
- } else {
446
- print_localized(APOSTROPHE);
447
- }
448
-
449
- break;
450
-
451
- case BACKTICK:
452
- if (t->mate == NULL) {
453
- print_token(t);
454
- } else if (t->mate->type == QUOTE_RIGHT_ALT)
455
- if (!(scratch->extensions & EXT_SMART)) {
456
- print_token(t);
457
- } else {
458
- print_localized(QUOTE_LEFT_DOUBLE);
459
- } else if (t->start < t->mate->start) {
460
- print_const("<text:span text:style-name=\"Source_20_Text\">");
461
- } else {
462
- print_const("</text:span>");
463
- }
464
-
465
- break;
466
-
467
- case BLOCK_BLOCKQUOTE:
468
- pad(out, 2, scratch);
469
- scratch->padded = 2;
470
- temp_short2 = scratch->odf_para_type;
471
-
472
- scratch->odf_para_type = BLOCK_BLOCKQUOTE;
473
-
474
- mmd_export_token_tree_odf(out, source, t->child, scratch);
475
- scratch->padded = 0;
476
- scratch->odf_para_type = temp_short2;
477
- break;
478
-
479
- case BLOCK_CODE_FENCED:
480
- pad(out, 2, scratch);
481
-
482
- temp_char = get_fence_language_specifier(t->child->child, source);
483
-
484
- if (temp_char) {
485
- if (strncmp("{=", temp_char, 2) == 0) {
486
- // Raw source
487
- if (raw_filter_text_matches(temp_char, FORMAT_ODT)) {
488
- switch (t->child->tail->type) {
489
- case LINE_FENCE_BACKTICK_3:
490
- case LINE_FENCE_BACKTICK_4:
491
- case LINE_FENCE_BACKTICK_5:
492
- temp_token = t->child->tail;
493
- break;
494
-
495
- default:
496
- temp_token = NULL;
497
- }
498
-
499
- if (temp_token) {
500
- d_string_append_c_array(out, &source[t->child->next->start], temp_token->start - t->child->next->start);
501
- scratch->padded = 1;
502
- } else {
503
- d_string_append_c_array(out, &source[t->child->start + t->child->len], t->start + t->len - t->child->next->start);
504
- scratch->padded = 0;
505
- }
506
- }
507
-
508
- free(temp_char);
509
- break;
510
- }
511
- }
512
-
513
- free(temp_char);
514
-
515
- print_const("<text:p text:style-name=\"Preformatted Text\">");
516
- mmd_export_token_tree_odf_raw(out, source, t->child->next, scratch);
517
- print_const("</text:p>");
518
- scratch->padded = 0;
519
- break;
520
-
521
- case BLOCK_CODE_INDENTED:
522
- pad(out, 2, scratch);
523
- print_const("<text:p text:style-name=\"Preformatted Text\">");
524
- mmd_export_token_tree_odf_raw(out, source, t->child, scratch);
525
- print_const("</text:p>");
526
- scratch->padded = 0;
527
- break;
528
-
529
- case BLOCK_DEFINITION:
530
- pad(out, 2, scratch);
531
- temp_short2 = scratch->odf_para_type;
532
- scratch->odf_para_type = BLOCK_DEFINITION;
533
-
534
- temp_short = scratch->list_is_tight;
535
-
536
- if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next)) {
537
- scratch->list_is_tight = true;
538
- }
539
-
540
- if (t->child && t->child->type != BLOCK_PARA) {
541
- print_const("<text:p text:style-name=\"Quotations\">");
542
- mmd_export_token_tree_odf(out, source, t->child, scratch);
543
- print_const("</text:p>");
544
- } else {
545
- mmd_export_token_tree_odf(out, source, t->child, scratch);
546
- }
547
-
548
- scratch->padded = 0;
549
-
550
- scratch->list_is_tight = temp_short;
551
- scratch->odf_para_type = temp_short2;
552
- break;
553
-
554
- case BLOCK_DEFLIST:
555
- pad(out, 2, scratch);
556
-
557
- // Group consecutive definition lists into a single list.
558
- // lemon's LALR(1) parser can't properly handle this (to my understanding).
559
-
560
- // if (!(t->prev && (t->prev->type == BLOCK_DEFLIST)))
561
- // print_const("<dl>\n");
562
-
563
- scratch->padded = 2;
564
-
565
- mmd_export_token_tree_odf(out, source, t->child, scratch);
566
- pad(out, 1, scratch);
567
-
568
- // if (!(t->next && (t->next->type == BLOCK_DEFLIST)))
569
- // print_const("</dl>\n");
570
-
571
- scratch->padded = 1;
572
- break;
573
-
574
- case BLOCK_EMPTY:
575
- break;
576
-
577
- case BLOCK_H1:
578
- case BLOCK_H2:
579
- case BLOCK_H3:
580
- case BLOCK_H4:
581
- case BLOCK_H5:
582
- case BLOCK_H6:
583
- case BLOCK_SETEXT_1:
584
- case BLOCK_SETEXT_2:
585
- pad(out, 2, scratch);
586
-
587
- switch (t->type) {
588
- case BLOCK_SETEXT_1:
589
- temp_short = 1;
590
- break;
591
-
592
- case BLOCK_SETEXT_2:
593
- temp_short = 2;
594
- break;
595
-
596
- default:
597
- temp_short = t->type - BLOCK_H1 + 1;
598
- }
599
-
600
- printf("<text:h text:outline-level=\"%d\">", temp_short + scratch->base_header_level - 1);
601
-
602
- if (scratch->extensions & EXT_NO_LABELS) {
603
- mmd_export_token_tree_odf(out, source, t->child, scratch);
604
- } else {
605
- temp_char = label_from_header(source, t);
606
- printf("<text:bookmark text:name=\"%s\"/>", temp_char);
607
- mmd_export_token_tree_odf(out, source, t->child, scratch);
608
- //printf("<text:bookmark-end text:name=\"%s\"/>", temp_char);
609
- free(temp_char);
610
- }
611
-
612
- print_const("</text:h>");
613
- scratch->padded = 0;
614
- break;
615
-
616
- case BLOCK_HR:
617
- pad(out, 2, scratch);
618
- print_const("<text:p text:style-name=\"Horizontal_20_Line\"/>");
619
- scratch->padded = 0;
620
- break;
621
-
622
- case BLOCK_HTML:
623
- // Don't print HTML
624
- break;
625
-
626
- case BLOCK_LIST_BULLETED_LOOSE:
627
- case BLOCK_LIST_BULLETED:
628
- temp_short = scratch->list_is_tight;
629
-
630
- switch (t->type) {
631
- case BLOCK_LIST_BULLETED_LOOSE:
632
- scratch->list_is_tight = false;
633
- break;
634
-
635
- case BLOCK_LIST_BULLETED:
636
- scratch->list_is_tight = true;
637
- break;
638
- }
639
-
640
- pad(out, 2, scratch);
641
- print_const("<text:list text:style-name=\"L1\">");
642
- scratch->padded = 1;
643
- mmd_export_token_tree_odf(out, source, t->child, scratch);
644
- pad(out, 2, scratch);
645
- print_const("</text:list>");
646
- scratch->padded = 0;
647
- scratch->list_is_tight = temp_short;
648
- break;
649
-
650
- case BLOCK_LIST_ENUMERATED_LOOSE:
651
- case BLOCK_LIST_ENUMERATED:
652
- temp_short = scratch->list_is_tight;
653
-
654
- switch (t->type) {
655
- case BLOCK_LIST_ENUMERATED_LOOSE:
656
- scratch->list_is_tight = false;
657
- break;
658
-
659
- case BLOCK_LIST_ENUMERATED:
660
- scratch->list_is_tight = true;
661
- break;
662
- }
663
-
664
- pad(out, 2, scratch);
665
- print_const("<text:list text:style-name=\"L2\">");
666
- scratch->padded = 1;
667
- mmd_export_token_tree_odf(out, source, t->child, scratch);
668
- pad(out, 2, scratch);
669
- print_const("</text:list>");
670
- scratch->padded = 0;
671
- scratch->list_is_tight = temp_short;
672
- break;
673
-
674
- case BLOCK_LIST_ITEM:
675
- pad(out, 2, scratch);
676
- print_const("<text:list-item>\n");
677
- scratch->padded = 2;
678
- mmd_export_token_tree_odf(out, source, t->child, scratch);
679
- print_const("</text:list-item>");
680
- scratch->padded = 0;
681
- break;
682
-
683
- case BLOCK_LIST_ITEM_TIGHT:
684
- pad(out, 2, scratch);
685
- print_const("<text:list-item>\n");
686
-
687
- if (t->child && t->child->type != BLOCK_PARA) {
688
- print_const("<text:p text:style-name=\"P1\">\n");
689
- }
690
-
691
- scratch->padded = 2;
692
- mmd_export_token_tree_odf(out, source, t->child, scratch);
693
-
694
- if (t->child && t->child->type != BLOCK_PARA) {
695
- print_const("</text:p>");
696
- }
697
-
698
- print_const("</text:list-item>");
699
- scratch->padded = 0;
700
- break;
701
-
702
- case BLOCK_META:
703
- break;
704
-
705
- case BLOCK_PARA:
706
- pad(out, 2, scratch);
707
- print_const("<text:p");
708
-
709
- switch (scratch->odf_para_type) {
710
- case BLOCK_BLOCKQUOTE:
711
- case BLOCK_DEFINITION:
712
- print_const(" text:style-name=\"Quotations\">");
713
- break;
714
-
715
- case PAIR_BRACKET_ABBREVIATION:
716
- case PAIR_BRACKET_CITATION:
717
- case PAIR_BRACKET_FOOTNOTE:
718
- case PAIR_BRACKET_GLOSSARY:
719
- print_const(" text:style-name=\"Footnote\">");
720
- break;
721
-
722
- default:
723
- print_const(" text:style-name=\"Standard\">");
724
- break;
725
- }
726
-
727
- mmd_export_token_tree_odf(out, source, t->child, scratch);
728
-
729
- print_const("</text:p>");
730
- scratch->padded = 0;
731
- break;
732
-
733
- case BLOCK_TABLE:
734
- pad(out, 2, scratch);
735
- print_const("<table:table>\n");
736
-
737
- scratch->padded = 2;
738
- read_table_column_alignments(source, t, scratch);
739
-
740
- for (int i = 0; i < scratch->table_column_count; ++i) {
741
- print_const("<table:table-column/>\n");
742
- // switch (scratch->table_alignment[i]) {
743
- // case 'l':
744
- // print_const("<col style=\"text-align:left;\"/>\n");
745
- // break;
746
- // case 'L':
747
- // print_const("<col style=\"text-align:left;\" class=\"extended\"/>\n");
748
- // break;
749
- // case 'r':
750
- // print_const("<col style=\"text-align:right;\"/>\n");
751
- // break;
752
- // case 'R':
753
- // print_const("<col style=\"text-align:right;\" class=\"extended\"/>\n");
754
- // break;
755
- // case 'c':
756
- // print_const("<col style=\"text-align:center;\"/>\n");
757
- // break;
758
- // case 'C':
759
- // print_const("<col style=\"text-align:center;\" class=\"extended\"/>\n");
760
- // break;
761
- // default:
762
- // print_const("<col />\n");
763
- // break;
764
- // }
765
- }
766
-
767
- scratch->padded = 1;
768
-
769
- mmd_export_token_tree_odf(out, source, t->child, scratch);
770
- pad(out, 1, scratch);
771
- print_const("</table:table>\n");
772
-
773
- // Are we followed by a caption?
774
- if (table_has_caption(t)) {
775
- temp_token = t->next->child;
776
-
777
- if (temp_token->next &&
778
- temp_token->next->type == PAIR_BRACKET) {
779
- temp_token = temp_token->next;
780
- }
781
-
782
- temp_char = label_from_token(source, temp_token);
783
- printf("<text:p><text:bookmark text:name=\"%s\"/>Table <text:sequence text:name=\"Table\" text:formula=\"ooow:Table+1\" style:num-format=\"1\"> Update Fields to calculate numbers</text:sequence>:", temp_char);
784
-
785
- t->next->child->child->type = TEXT_EMPTY;
786
- t->next->child->child->mate->type = TEXT_EMPTY;
787
- mmd_export_token_tree_odf(out, source, t->next->child->child, scratch);
788
-
789
- printf("<text:bookmark-end text:name=\"%s\"/></text:p>\n", temp_char);
790
-
791
- free(temp_char);
792
- temp_short = 1;
793
- } else {
794
- temp_short = 0;
795
- }
796
-
797
- scratch->padded = 0;
798
- scratch->skip_token = temp_short;
799
-
800
- break;
801
-
802
- case BLOCK_TABLE_HEADER:
803
- pad(out, 2, scratch);
804
- scratch->in_table_header = 1;
805
- mmd_export_token_tree_odf(out, source, t->child, scratch);
806
- scratch->in_table_header = 0;
807
- scratch->padded = 1;
808
- break;
809
-
810
- case BLOCK_TABLE_SECTION:
811
- pad(out, 2, scratch);
812
- scratch->padded = 2;
813
- mmd_export_token_tree_odf(out, source, t->child, scratch);
814
- scratch->padded = 0;
815
- break;
816
-
817
- case BLOCK_TOC:
818
- pad(out, 2, scratch);
819
-
820
- mmd_export_toc_odf(out, source, scratch);
821
-
822
- scratch->padded = 1;
823
- break;
824
-
825
- case BLOCK_TERM:
826
- pad(out, 2, scratch);
827
- print_const("<text:p><text:span text:style-name=\"MMD-Bold\">");
828
- mmd_export_token_tree_odf(out, source, t->child, scratch);
829
- print_const("</text:span></text:p>\n");
830
- scratch->padded = 2;
831
- break;
832
-
833
- case BRACE_DOUBLE_LEFT:
834
- print_const("{{");
835
- break;
836
-
837
- case BRACE_DOUBLE_RIGHT:
838
- print_const("}}");
839
- break;
840
-
841
- case BRACKET_ABBREVIATION_LEFT:
842
- print_const("[>");
843
- break;
844
-
845
- case BRACKET_CITATION_LEFT:
846
- print_const("[#");
847
- break;
848
-
849
- case BRACKET_LEFT:
850
- print_const("[");
851
- break;
852
-
853
- case BRACKET_RIGHT:
854
- print_const("]");
855
- break;
856
-
857
- case BRACKET_VARIABLE_LEFT:
858
- print_const("[\%");
859
- break;
860
-
861
- case COLON:
862
- print_char(':');
863
- break;
864
-
865
- case CRITIC_ADD_OPEN:
866
- print_const("{++");
867
- break;
868
-
869
- case CRITIC_ADD_CLOSE:
870
- print_const("++}");
871
- break;
872
-
873
- case CRITIC_COM_OPEN:
874
- print_const("{&gt;&gt;");
875
- break;
876
-
877
- case CRITIC_COM_CLOSE:
878
- print_const("&lt;&lt;}");
879
- break;
880
-
881
- case CRITIC_DEL_OPEN:
882
- print_const("{--");
883
- break;
884
-
885
- case CRITIC_DEL_CLOSE:
886
- print_const("--}");
887
- break;
888
-
889
- case CRITIC_HI_OPEN:
890
- print_const("{==");
891
- break;
892
-
893
- case CRITIC_HI_CLOSE:
894
- print_const("==}");
895
- break;
896
-
897
- case CRITIC_SUB_OPEN:
898
- print_const("{~~");
899
- break;
900
-
901
- case CRITIC_SUB_DIV:
902
- print_const("~&gt;");
903
- break;
904
-
905
- case CRITIC_SUB_CLOSE:
906
- print_const("~~}");
907
- break;
908
-
909
- case DASH_M:
910
- if (!(scratch->extensions & EXT_SMART)) {
911
- print_token(t);
912
- } else {
913
- print_localized(DASH_M);
914
- }
915
-
916
- break;
917
-
918
- case DASH_N:
919
- if (!(scratch->extensions & EXT_SMART)) {
920
- print_token(t);
921
- } else {
922
- print_localized(DASH_N);
923
- }
924
-
925
- break;
926
-
927
- case ELLIPSIS:
928
- if (!(scratch->extensions & EXT_SMART)) {
929
- print_token(t);
930
- } else {
931
- print_localized(ELLIPSIS);
932
- }
933
-
934
- break;
935
-
936
- case EMPH_START:
937
- print_const("<text:span text:style-name=\"MMD-Italic\">");
938
- break;
939
-
940
- case EMPH_STOP:
941
- print_const("</text:span>");
942
- break;
943
-
944
- case EQUAL:
945
- print_char('=');
946
- break;
947
-
948
- case ESCAPED_CHARACTER:
949
- if (!(scratch->extensions & EXT_COMPATIBILITY) &&
950
- (source[t->start + 1] == ' ')) {
951
- print_const(" "); // This is a non-breaking space character
952
- } else {
953
- mmd_print_char_odf(out, source[t->start + 1]);
954
- }
955
-
956
- break;
957
-
958
- case HASH1:
959
- case HASH2:
960
- case HASH3:
961
- case HASH4:
962
- case HASH5:
963
- case HASH6:
964
- print_token(t);
965
- break;
966
-
967
- case HTML_ENTITY:
968
- print_const("&amp;");
969
- d_string_append_c_array(out, &(source[t->start + 1]), t->len - 1);
970
- break;
971
-
972
- case HTML_COMMENT_START:
973
- if (!(scratch->extensions & EXT_SMART)) {
974
- print_const("&lt;!--");
975
- } else {
976
- print_const("&lt;!");
977
- print_localized(DASH_N);
978
- }
979
-
980
- break;
981
-
982
- case HTML_COMMENT_STOP:
983
- if (!(scratch->extensions & EXT_SMART)) {
984
- print_const("--&gt;");
985
- } else {
986
- print_localized(DASH_N);
987
- print_const("&gt;");
988
- }
989
-
990
- break;
991
-
992
- case INDENT_SPACE:
993
- print_char(' ');
994
- break;
995
-
996
- case INDENT_TAB:
997
- print_const("<text:tab/>");
998
- break;
999
-
1000
- case LINE_LIST_BULLETED:
1001
- case LINE_LIST_ENUMERATED:
1002
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1003
- break;
1004
-
1005
- case LINE_SETEXT_2:
1006
- case MANUAL_LABEL:
1007
- case MARKER_BLOCKQUOTE:
1008
- case MARKER_H1:
1009
- case MARKER_H2:
1010
- case MARKER_H3:
1011
- case MARKER_H4:
1012
- case MARKER_H5:
1013
- case MARKER_H6:
1014
- case MARKER_LIST_BULLET:
1015
- case MARKER_LIST_ENUMERATOR:
1016
- break;
1017
-
1018
- case MATH_BRACKET_OPEN:
1019
- if (t->mate) {
1020
- print_const("<text:span text:style-name=\"math\">\\[");
1021
- } else {
1022
- print_const("\\[");
1023
- }
1024
-
1025
- break;
1026
-
1027
- case MATH_BRACKET_CLOSE:
1028
- if (t->mate) {
1029
- print_const("\\]</text:span>");
1030
- } else {
1031
- print_const("\\]");
1032
- }
1033
-
1034
- break;
1035
-
1036
- case MATH_DOLLAR_SINGLE:
1037
- if (t->mate) {
1038
- (t->start < t->mate->start) ? ( print_const("<text:span text:style-name=\"math\">\\(") ) : ( print_const("\\)</text:span>") );
1039
- } else {
1040
- print_const("$");
1041
- }
1042
-
1043
- break;
1044
-
1045
- case MATH_DOLLAR_DOUBLE:
1046
- if (t->mate) {
1047
- (t->start < t->mate->start) ? ( print_const("<text:span text:style-name=\"math\">\\[") ) : ( print_const("\\]</text:span>") );
1048
- } else {
1049
- print_const("$$");
1050
- }
1051
-
1052
- break;
1053
-
1054
- case MATH_PAREN_OPEN:
1055
- if (t->mate) {
1056
- print_const("<text:span text:style-name=\"math\">\\(");
1057
- } else {
1058
- print_const("\\(");
1059
- }
1060
-
1061
- break;
1062
-
1063
- case MATH_PAREN_CLOSE:
1064
- if (t->mate) {
1065
- print_const("\\)</text:span>");
1066
- } else {
1067
- print_const("\\)");
1068
- }
1069
-
1070
- break;
1071
-
1072
- case NON_INDENT_SPACE:
1073
- print_char(' ');
1074
- break;
1075
-
1076
- case PAIR_ANGLE:
1077
- temp_char = url_accept(source, t->start + 1, t->len - 2, NULL, true);
1078
-
1079
- if (temp_char) {
1080
- print_const("<text:a xlink:type=\"simple\" xlink:href=\"");
1081
-
1082
- if (scan_email(temp_char)) {
1083
- temp_bool = true;
1084
-
1085
- if (strncmp("mailto:", temp_char, 7) != 0) {
1086
- print_const("mailto:");
1087
- }
1088
- } else {
1089
- temp_bool = false;
1090
- }
1091
-
1092
- mmd_print_string_odf(out, temp_char);
1093
- print_const("\">");
1094
- mmd_print_string_odf(out, temp_char);
1095
- print_const("</text:a>");
1096
- } else if (scan_html(&source[t->start])) {
1097
- // We ignore HTML blocks
1098
- if (scan_html_comment(&source[t->start])) {
1099
- // But allow HTML comments as raw LaTeX
1100
- d_string_append_c_array(out, &source[t->start + 4], t->len - 4 - 3);
1101
- }
1102
- } else {
1103
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1104
- }
1105
-
1106
- free(temp_char);
1107
- break;
1108
-
1109
- case PAIR_BACKTICK:
1110
-
1111
- // Strip leading whitespace
1112
- switch (t->child->next->type) {
1113
- case TEXT_NL:
1114
- case INDENT_TAB:
1115
- case INDENT_SPACE:
1116
- case NON_INDENT_SPACE:
1117
- t->child->next->type = TEXT_EMPTY;
1118
- break;
1119
-
1120
- case TEXT_PLAIN:
1121
- while (t->child->next->len && char_is_whitespace(source[t->child->next->start])) {
1122
- t->child->next->start++;
1123
- t->child->next->len--;
1124
- }
1125
-
1126
- break;
1127
- }
1128
-
1129
- // Strip trailing whitespace
1130
- switch (t->child->mate->prev->type) {
1131
- case TEXT_NL:
1132
- case INDENT_TAB:
1133
- case INDENT_SPACE:
1134
- case NON_INDENT_SPACE:
1135
- t->child->mate->prev->type = TEXT_EMPTY;
1136
- break;
1137
-
1138
- case TEXT_PLAIN:
1139
- while (t->child->mate->prev->len && char_is_whitespace(source[t->child->mate->prev->start + t->child->mate->prev->len - 1])) {
1140
- t->child->mate->prev->len--;
1141
- }
1142
-
1143
- break;
1144
- }
1145
-
1146
- t->child->type = TEXT_EMPTY;
1147
- t->child->mate->type = TEXT_EMPTY;
1148
-
1149
- if (t->next && t->next->type == PAIR_RAW_FILTER) {
1150
- // Raw text?
1151
- if (raw_filter_matches(t->next, source, FORMAT_FODT)) {
1152
- d_string_append_c_array(out, &(source[t->child->start + t->child->len]), t->child->mate->start - t->child->start - t->child->len);
1153
- }
1154
-
1155
- // Skip over PAIR_RAW_FILTER
1156
- scratch->skip_token = 1;
1157
- break;
1158
- }
1159
-
1160
- print_const("<text:span text:style-name=\"Source_20_Text\">");
1161
- mmd_export_token_tree_odf_raw(out, source, t->child, scratch);
1162
- print_const("</text:span>");
1163
- break;
1164
-
1165
- case PAIR_BRACE:
1166
- case PAIR_BRACES:
1167
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1168
- break;
1169
-
1170
- case PAIR_BRACKET:
1171
- if ((scratch->extensions & EXT_NOTES) &&
1172
- (t->next && t->next->type == PAIR_BRACKET_CITATION)) {
1173
- goto parse_citation;
1174
- }
1175
-
1176
- case PAIR_BRACKET_IMAGE:
1177
- parse_brackets(source, scratch, t, &temp_link, &temp_short, &temp_bool);
1178
-
1179
- if (temp_link) {
1180
- if (t->type == PAIR_BRACKET) {
1181
- // Link
1182
- mmd_export_link_odf(out, source, t, temp_link, scratch);
1183
- } else {
1184
- // Image -- should it be a figure (e.g. image is only thing in paragraph)?
1185
- temp_token = t->next;
1186
-
1187
- if (temp_token &&
1188
- ((temp_token->type == PAIR_BRACKET) ||
1189
- (temp_token->type == PAIR_PAREN))) {
1190
- temp_token = temp_token->next;
1191
- }
1192
-
1193
- if (temp_token && temp_token->type == TEXT_NL) {
1194
- temp_token = temp_token->next;
1195
- }
1196
-
1197
- if (temp_token && temp_token->type == TEXT_LINEBREAK) {
1198
- temp_token = temp_token->next;
1199
- }
1200
-
1201
- if (t->prev || temp_token) {
1202
- mmd_export_image_odf(out, source, t, temp_link, scratch, false);
1203
- } else {
1204
- mmd_export_image_odf(out, source, t, temp_link, scratch, true);
1205
- }
1206
- }
1207
-
1208
- if (temp_bool) {
1209
- link_free(temp_link);
1210
- }
1211
-
1212
- scratch->skip_token = temp_short;
1213
-
1214
- return;
1215
- }
1216
-
1217
- // No links exist, so treat as normal
1218
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1219
- break;
1220
-
1221
- case PAIR_BRACKET_CITATION:
1222
- parse_citation:
1223
- temp_bool = true; // Track whether this is regular vs 'not cited'
1224
- temp_token = t; // Remember whether we need to skip ahead
1225
-
1226
- if (scratch->extensions & EXT_NOTES) {
1227
- // Note-based syntax enabled
1228
-
1229
- if (t->type == PAIR_BRACKET) {
1230
- // This is a locator for a subsequent citation (e.g. `[foo][#bar]`)
1231
- temp_char = text_inside_pair(source, t);
1232
- temp_char2 = label_from_string(temp_char);
1233
-
1234
- if (strcmp(temp_char2, "notcited") == 0) {
1235
- free(temp_char);
1236
- temp_char = my_strdup("");
1237
- temp_bool = false;
1238
- }
1239
-
1240
- free(temp_char2);
1241
-
1242
- // Move ahead to actual citation
1243
- t = t->next;
1244
- } else {
1245
- // This is the actual citation (e.g. `[#foo]`)
1246
- // No locator
1247
- temp_char = my_strdup("");
1248
- }
1249
-
1250
- // Classify this use
1251
- temp_short2 = scratch->used_citations->size;
1252
- citation_from_bracket(source, scratch, t, &temp_short);
1253
-
1254
- if (temp_short == -1) {
1255
- // This instance is not properly formed
1256
- print_const("[#");
1257
- mmd_export_token_tree_odf(out, source, t->child->next, scratch);
1258
- print_const("]");
1259
-
1260
- free(temp_char);
1261
- break;
1262
- }
1263
-
1264
-
1265
- temp_short3 = scratch->odf_para_type;
1266
- scratch->odf_para_type = PAIR_BRACKET_FOOTNOTE;
1267
-
1268
- if (temp_bool) {
1269
- // This is a regular citation
1270
-
1271
- if (temp_char[0] == '\0') {
1272
- // No locator
1273
-
1274
- if (temp_short2 == scratch->used_citations->size) {
1275
- // This is a re-use of a previously used note
1276
- print_const("<text:span text:style-name=\"Footnote_20_anchor\"><text:note-ref text:note-class=\"endnote\" text:reference-format=\"text\" ");
1277
- printf("text:ref-name=\"cite%d\">%d</text:note-ref></text:span>", temp_short, temp_short);
1278
- } else {
1279
- // This is the first time this note was used
1280
- printf("<text:note text:id=\"cite%d\" text:note-class=\"endnote\"><text:note-body>", temp_short);
1281
- temp_note = stack_peek_index(scratch->used_citations, temp_short - 1);
1282
-
1283
- mmd_export_token_tree_odf(out, source, temp_note->content, scratch);
1284
- print_const("</text:note-body></text:note>");
1285
- }
1286
- } else {
1287
- // Locator present
1288
-
1289
- if (temp_short2 == scratch->used_citations->size) {
1290
- // This is a re-use of a previously used note
1291
- print_const("<text:span text:style-name=\"Footnote_20_anchor\"><text:note-ref text:note-class=\"endnote\" text:reference-format=\"text\" ");
1292
- printf("text:ref-name=\"cite%d\">%d</text:note-ref></text:span>", temp_short, temp_short);
1293
- } else {
1294
- // This is the first time this note was used
1295
- printf("<text:note text:id=\"cite%d\" text:note-class=\"endnote\"><text:note-body>", temp_short);
1296
- temp_note = stack_peek_index(scratch->used_citations, temp_short - 1);
1297
-
1298
- mmd_export_token_tree_odf(out, source, temp_note->content, scratch);
1299
- print_const("</text:note-body></text:note>");
1300
- }
1301
- }
1302
- } else {
1303
- if (temp_short2 == scratch->used_citations->size) {
1304
- // This is a re-use of a previously used note
1305
- } else {
1306
- // This is the first time this note was used
1307
- // TODO: Not sure how to add an endnote without inserting a marker in the text
1308
- printf("<text:note text:id=\"cite%d\" text:note-class=\"endnote\"><text:note-body>", temp_short);
1309
- temp_note = stack_peek_index(scratch->used_citations, temp_short - 1);
1310
-
1311
- mmd_export_token_tree_odf(out, source, temp_note->content, scratch);
1312
- print_const("</text:note-body></text:note>");
1313
- }
1314
- }
1315
-
1316
- if (temp_token != t) {
1317
- // Skip citation on next pass
1318
- scratch->skip_token = 1;
1319
- }
1320
-
1321
- scratch->odf_para_type = temp_short3;
1322
-
1323
- free(temp_char);
1324
- } else {
1325
- // Note-based syntax disabled
1326
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1327
- }
1328
-
1329
- break;
1330
-
1331
- case PAIR_BRACKET_FOOTNOTE:
1332
- if (scratch->extensions & EXT_NOTES) {
1333
- // Note-based syntax enabled
1334
-
1335
- // Classify this use
1336
- temp_short2 = scratch->used_footnotes->size;
1337
- footnote_from_bracket(source, scratch, t, &temp_short);
1338
-
1339
- if (temp_short == -1) {
1340
- // This instance is not properly formed
1341
- print_const("[?");
1342
- mmd_export_token_tree_odf(out, source, t->child->next, scratch);
1343
- print_const("]");
1344
- break;
1345
- }
1346
-
1347
- temp_short3 = scratch->odf_para_type;
1348
- scratch->odf_para_type = PAIR_BRACKET_FOOTNOTE;
1349
-
1350
- if (temp_short2 == scratch->used_footnotes->size) {
1351
- // This is a re-use of a previously used note
1352
-
1353
- printf("<text:note text:id=\"fn%d\" text:note-class=\"footnote\"><text:note-body>", temp_short);
1354
- temp_note = stack_peek_index(scratch->used_footnotes, temp_short - 1);
1355
-
1356
- mmd_export_token_tree_odf(out, source, temp_note->content, scratch);
1357
- print_const("</text:note-body></text:note>");
1358
- } else {
1359
- // This is the first time this note was used
1360
-
1361
- // This is a new footnote
1362
- printf("<text:note text:id=\"fn%d\" text:note-class=\"footnote\"><text:note-body>", temp_short);
1363
- temp_note = stack_peek_index(scratch->used_footnotes, temp_short - 1);
1364
-
1365
- mmd_export_token_tree_odf(out, source, temp_note->content, scratch);
1366
- print_const("</text:note-body></text:note>");
1367
- }
1368
-
1369
- scratch->odf_para_type = temp_short3;
1370
- } else {
1371
- // Note-based syntax disabled
1372
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1373
- }
1374
-
1375
- break;
1376
-
1377
- case PAIR_BRACKET_ABBREVIATION:
1378
-
1379
- // Which might also be an "auto-tagged" abbreviation
1380
- if (scratch->extensions & EXT_NOTES) {
1381
- // Note-based syntax enabled
1382
-
1383
- // Classify this use
1384
- temp_short2 = scratch->used_abbreviations->size;
1385
- temp_short3 = scratch->inline_abbreviations_to_free->size;
1386
- abbreviation_from_bracket(source, scratch, t, &temp_short);
1387
-
1388
- if (temp_short == -1) {
1389
- // This instance is not properly formed
1390
- print_const("[>");
1391
- mmd_export_token_tree_odf(out, source, t->child->next, scratch);
1392
- print_const("]");
1393
- break;
1394
- }
1395
-
1396
- // Get instance of the note used
1397
- temp_note = stack_peek_index(scratch->used_abbreviations, temp_short - 1);
1398
-
1399
- if (t->child) {
1400
- t->child->type = TEXT_EMPTY;
1401
- t->child->mate->type = TEXT_EMPTY;
1402
- }
1403
-
1404
- if (temp_short2 == scratch->used_abbreviations->size) {
1405
- // This is a re-use of a previously used note
1406
-
1407
- if (temp_short3 == scratch->inline_abbreviations_to_free->size) {
1408
- // This is a reference definition
1409
- mmd_print_string_odf(out, temp_note->label_text);
1410
- // mmd_export_token_tree_odf(out, source, t->child, scratch);
1411
- } else {
1412
- // This is an inline definition
1413
- mmd_print_string_odf(out, temp_note->label_text);
1414
- // mmd_export_token_tree_odf(out, source, t->child, scratch);
1415
- }
1416
- } else {
1417
- // This is the first time this note was used
1418
- temp_short2 = scratch->odf_para_type;
1419
- scratch->odf_para_type = PAIR_BRACKET_ABBREVIATION;
1420
-
1421
- if (temp_short3 == scratch->inline_abbreviations_to_free->size) {
1422
- // This is a reference definition
1423
- mmd_print_string_odf(out, temp_note->clean_text);
1424
- print_const(" (");
1425
- mmd_print_string_odf(out, temp_note->label_text);
1426
- print_const(")");
1427
- } else {
1428
- // This is an inline definition
1429
- mmd_print_string_odf(out, temp_note->clean_text);
1430
- print_const(" (");
1431
- mmd_print_string_odf(out, temp_note->label_text);
1432
- print_const(")");
1433
- }
1434
-
1435
- scratch->odf_para_type = temp_short2;
1436
- }
1437
- } else {
1438
- // Note-based syntax disabled
1439
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1440
- }
1441
-
1442
- break;
1443
-
1444
- case PAIR_BRACKET_GLOSSARY:
1445
-
1446
- // Which might also be an "auto-tagged" glossary
1447
- if (scratch->extensions & EXT_NOTES) {
1448
- // Note-based syntax enabled
1449
-
1450
- // Classify this use
1451
- temp_short2 = scratch->used_glossaries->size;
1452
- glossary_from_bracket(source, scratch, t, &temp_short);
1453
-
1454
- if (temp_short == -1) {
1455
- // This instance is not properly formed
1456
- print_const("[?");
1457
- mmd_export_token_tree_odf(out, source, t->child->next, scratch);
1458
- print_const("]");
1459
- break;
1460
- }
1461
-
1462
- // Get instance of the note used
1463
- temp_note = stack_peek_index(scratch->used_glossaries, temp_short - 1);
1464
-
1465
- temp_short3 = scratch->odf_para_type;
1466
- scratch->odf_para_type = PAIR_BRACKET_GLOSSARY;
1467
-
1468
- if (temp_short2 == scratch->used_glossaries->size) {
1469
- // This is a re-use of a previously used note
1470
-
1471
- mmd_print_string_odf(out, temp_note->clean_text);
1472
- } else {
1473
- // This is the first time this note was used
1474
-
1475
- mmd_print_string_odf(out, temp_note->clean_text);
1476
-
1477
- printf("<text:note text:id=\"gn%d\" text:note-class=\"glossary\"><text:note-body>", temp_short);
1478
- mmd_export_token_tree_odf(out, source, temp_note->content, scratch);
1479
- print_const("</text:note-body></text:note>");
1480
- }
1481
-
1482
- scratch->odf_para_type = temp_short3;
1483
- } else {
1484
- // Note-based syntax disabled
1485
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1486
- }
1487
-
1488
- break;
1489
-
1490
- case PAIR_BRACKET_VARIABLE:
1491
- temp_char = text_inside_pair(source, t);
1492
- temp_char2 = extract_metadata(scratch, temp_char);
1493
-
1494
- if (temp_char2) {
1495
- mmd_print_string_odf(out, temp_char2);
1496
- } else {
1497
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1498
- }
1499
-
1500
- // Don't free temp_char2 (it belongs to meta *)
1501
- free(temp_char);
1502
- break;
1503
-
1504
- case PAIR_CRITIC_ADD:
1505
-
1506
- // Ignore if we're rejecting
1507
- if (scratch->extensions & EXT_CRITIC_REJECT) {
1508
- break;
1509
- }
1510
-
1511
- if (scratch->extensions & EXT_CRITIC) {
1512
- t->child->type = TEXT_EMPTY;
1513
- t->child->mate->type = TEXT_EMPTY;
1514
-
1515
- if (scratch->extensions & EXT_CRITIC_ACCEPT) {
1516
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1517
- } else {
1518
- print_const("<text:span text:style-name=\"Underline\">");
1519
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1520
- print_const("</text:span>");
1521
- }
1522
- } else {
1523
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1524
- }
1525
-
1526
- break;
1527
-
1528
- case PAIR_CRITIC_DEL:
1529
-
1530
- // Ignore if we're accepting
1531
- if (scratch->extensions & EXT_CRITIC_ACCEPT) {
1532
- break;
1533
- }
1534
-
1535
- if (scratch->extensions & EXT_CRITIC) {
1536
- t->child->type = TEXT_EMPTY;
1537
- t->child->mate->type = TEXT_EMPTY;
1538
-
1539
- if (scratch->extensions & EXT_CRITIC_REJECT) {
1540
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1541
- } else {
1542
- print_const("<text:span text:style-name=\"Strike\">");
1543
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1544
- print_const("</text:span>");
1545
- }
1546
- } else {
1547
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1548
- }
1549
-
1550
- break;
1551
-
1552
- case PAIR_CRITIC_COM:
1553
-
1554
- // Ignore if we're rejecting or accepting
1555
- if ((scratch->extensions & EXT_CRITIC_REJECT) ||
1556
- (scratch->extensions & EXT_CRITIC_ACCEPT)) {
1557
- break;
1558
- }
1559
-
1560
- if (scratch->extensions & EXT_CRITIC) {
1561
- t->child->type = TEXT_EMPTY;
1562
- t->child->mate->type = TEXT_EMPTY;
1563
- print_const("<text:span text:style-name=\"Comment\">");
1564
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1565
- print_const("</text:span>");
1566
- } else {
1567
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1568
- }
1569
-
1570
- break;
1571
-
1572
- case PAIR_CRITIC_HI:
1573
-
1574
- // Ignore if we're rejecting or accepting
1575
- if ((scratch->extensions & EXT_CRITIC_REJECT) ||
1576
- (scratch->extensions & EXT_CRITIC_ACCEPT)) {
1577
- t->child->type = TEXT_EMPTY;
1578
- t->child->mate->type = TEXT_EMPTY;
1579
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1580
- break;
1581
- }
1582
-
1583
- if (scratch->extensions & EXT_CRITIC) {
1584
- t->child->type = TEXT_EMPTY;
1585
- t->child->mate->type = TEXT_EMPTY;
1586
- print_const("<text:span text:style-name=\"Highlight\">");
1587
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1588
- print_const("</text:span>");
1589
- } else {
1590
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1591
- }
1592
-
1593
- break;
1594
-
1595
- case CRITIC_SUB_DIV_A:
1596
- print_const("~");
1597
- break;
1598
-
1599
- case CRITIC_SUB_DIV_B:
1600
- print_const("&gt;");
1601
- break;
1602
-
1603
- case PAIR_CRITIC_SUB_DEL:
1604
- if ((scratch->extensions & EXT_CRITIC) &&
1605
- (t->next) &&
1606
- (t->next->type == PAIR_CRITIC_SUB_ADD)) {
1607
- t->child->type = TEXT_EMPTY;
1608
- t->child->mate->type = TEXT_EMPTY;
1609
-
1610
- if (scratch->extensions & EXT_CRITIC_ACCEPT) {
1611
-
1612
- } else if (scratch->extensions & EXT_CRITIC_REJECT) {
1613
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1614
- } else {
1615
- print_const("<text:span text:style-name=\"Strike\">");
1616
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1617
- print_const("</text:span>");
1618
- }
1619
- } else {
1620
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1621
- }
1622
-
1623
- break;
1624
-
1625
- case PAIR_CRITIC_SUB_ADD:
1626
- if ((scratch->extensions & EXT_CRITIC) &&
1627
- (t->prev) &&
1628
- (t->prev->type == PAIR_CRITIC_SUB_DEL)) {
1629
- t->child->type = TEXT_EMPTY;
1630
- t->child->mate->type = TEXT_EMPTY;
1631
-
1632
- if (scratch->extensions & EXT_CRITIC_REJECT) {
1633
-
1634
- } else if (scratch->extensions & EXT_CRITIC_ACCEPT) {
1635
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1636
- } else {
1637
- print_const("<text:span text:style-name=\"Underline\">");
1638
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1639
- print_const("</text:span>");
1640
- }
1641
- } else {
1642
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1643
- }
1644
-
1645
- break;
1646
-
1647
- case PAIR_HTML_COMMENT:
1648
- break;
1649
-
1650
- case PAIR_EMPH:
1651
- case PAIR_MATH:
1652
- case PAIR_PAREN:
1653
- case PAIR_QUOTE_DOUBLE:
1654
- case PAIR_QUOTE_SINGLE:
1655
- case PAIR_STAR:
1656
- case PAIR_STRONG:
1657
- case PAIR_SUBSCRIPT:
1658
- case PAIR_SUPERSCRIPT:
1659
- case PAIR_UL:
1660
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1661
- break;
1662
-
1663
- case PAREN_LEFT:
1664
- print_char('(');
1665
- break;
1666
-
1667
- case PAREN_RIGHT:
1668
- print_char(')');
1669
- break;
1670
-
1671
- case PIPE:
1672
- print_token(t);
1673
- break;
1674
-
1675
- case PLUS:
1676
- print_char('+');
1677
- break;
1678
-
1679
- case QUOTE_SINGLE:
1680
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
1681
- print_const("'");
1682
- } else {
1683
- (t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_SINGLE) ) : ( print_localized(QUOTE_RIGHT_SINGLE) );
1684
- }
1685
-
1686
- break;
1687
-
1688
- case QUOTE_DOUBLE:
1689
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
1690
- print_const("&quot;");
1691
- } else {
1692
- (t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_DOUBLE) ) : ( print_localized(QUOTE_RIGHT_DOUBLE) );
1693
- }
1694
-
1695
- break;
1696
-
1697
- case QUOTE_RIGHT_ALT:
1698
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
1699
- print_const("''");
1700
- } else {
1701
- print_localized(QUOTE_RIGHT_DOUBLE);
1702
- }
1703
-
1704
- break;
1705
-
1706
- case SLASH:
1707
- print_char('/');
1708
- break;
1709
-
1710
- case STAR:
1711
- print_char('*');
1712
- break;
1713
-
1714
- case STRONG_START:
1715
- print_const("<text:span text:style-name=\"MMD-Bold\">");
1716
- break;
1717
-
1718
- case STRONG_STOP:
1719
- print_const("</text:span>");
1720
- break;
1721
-
1722
- case SUBSCRIPT:
1723
- if (t->mate) {
1724
- (t->start < t->mate->start) ? (print_const("<text:span text:style-name=\"MMD-Subscript\">")) : (print_const("</text:span>"));
1725
- } else if (t->len != 1) {
1726
- print_const("<text:span text:style-name=\"MMD-Subscript\">");
1727
- mmd_export_token_odf(out, source, t->child, scratch);
1728
- print_const("</text:span>");
1729
- } else {
1730
- print_const("~");
1731
- }
1732
-
1733
- break;
1734
-
1735
- case SUPERSCRIPT:
1736
- if (t->mate) {
1737
- (t->start < t->mate->start) ? (print_const("<text:span text:style-name=\"MMD-Superscript\">")) : (print_const("</text:span>"));
1738
- } else if (t->len != 1) {
1739
- print_const("<text:span text:style-name=\"MMD-Superscript\">");
1740
- mmd_export_token_odf(out, source, t->child, scratch);
1741
- print_const("</text:span>");
1742
- } else {
1743
- print_const("^");
1744
- }
1745
-
1746
- break;
1747
-
1748
- case TABLE_CELL:
1749
- print_const("<table:table-cell");
1750
-
1751
- if (t->next && t->next->type == TABLE_DIVIDER) {
1752
- if (t->next->len > 1) {
1753
- printf(" table:number-columns-spanned=\"%d\"", t->next->len);
1754
- }
1755
- }
1756
-
1757
- if (scratch->in_table_header) {
1758
- print_const(">\n<text:p text:style-name=\"Table_20_Heading\"");
1759
- } else {
1760
- print_const(">\n<text:p");
1761
-
1762
- switch (scratch->table_alignment[scratch->table_cell_count]) {
1763
- case 'l':
1764
- case 'L':
1765
- default:
1766
- print_const(" text:style-name=\"MMD-Table\"");
1767
- break;
1768
-
1769
- case 'r':
1770
- case 'R':
1771
- print_const(" text:style-name=\"MMD-Table-Right\"");
1772
- break;
1773
-
1774
- case 'c':
1775
- case 'C':
1776
- print_const(" text:style-name=\"MMD-Table-Center\"");
1777
- break;
1778
- }
1779
- }
1780
-
1781
- print_const(">");
1782
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1783
-
1784
- print_const("</text:p>\n</table:table-cell>\n");
1785
-
1786
- if (t->next) {
1787
- scratch->table_cell_count += t->next->len;
1788
- } else {
1789
- scratch->table_cell_count++;
1790
- }
1791
-
1792
- break;
1793
-
1794
- case TABLE_DIVIDER:
1795
- break;
1796
-
1797
- case TABLE_ROW:
1798
- print_const("<table:table-row>\n");
1799
- scratch->table_cell_count = 0;
1800
- mmd_export_token_tree_odf(out, source, t->child, scratch);
1801
- print_const("</table:table-row>\n");
1802
- break;
1803
-
1804
- case TEXT_EMPTY:
1805
- break;
1806
-
1807
- case TEXT_LINEBREAK:
1808
- if (t->next) {
1809
- print_const("<text:line-break/>\n");
1810
- scratch->padded = 0;
1811
- }
1812
-
1813
- break;
1814
-
1815
- case TEXT_NL:
1816
- if (t->next) {
1817
- print_char('\n');
1818
- }
1819
-
1820
- break;
1821
-
1822
- case RAW_FILTER_LEFT:
1823
- case TEXT_BACKSLASH:
1824
- case TEXT_BRACE_LEFT:
1825
- case TEXT_BRACE_RIGHT:
1826
- case TEXT_HASH:
1827
- case TEXT_NUMBER_POSS_LIST:
1828
- case TEXT_PERCENT:
1829
- case TEXT_PERIOD:
1830
- case TEXT_PLAIN:
1831
- case TOC:
1832
- case UL:
1833
- print_token(t);
1834
- break;
1835
-
1836
- default:
1837
- fprintf(stderr, "Unknown token type: %d\n", t->type);
1838
- token_describe(t, source);
1839
- break;
1840
- }
1841
- }
1842
-
1843
-
1844
- void mmd_export_token_tree_odf(DString * out, const char * source, token * t, scratch_pad * scratch) {
1845
-
1846
- // Prevent stack overflow with "dangerous" input causing extreme recursion
1847
- if (scratch->recurse_depth == kMaxExportRecursiveDepth) {
1848
- return;
1849
- }
1850
-
1851
- scratch->recurse_depth++;
1852
-
1853
- while (t != NULL) {
1854
- if (scratch->skip_token) {
1855
- scratch->skip_token--;
1856
- } else {
1857
- mmd_export_token_odf(out, source, t, scratch);
1858
- }
1859
-
1860
- t = t->next;
1861
- }
1862
-
1863
- scratch->recurse_depth--;
1864
- }
1865
-
1866
-
1867
- void mmd_export_token_odf_raw(DString * out, const char * source, token * t, scratch_pad * scratch) {
1868
- if (t == NULL) {
1869
- return;
1870
- }
1871
-
1872
- switch (t->type) {
1873
- case AMPERSAND:
1874
- print_const("&amp;");
1875
- break;
1876
-
1877
- case AMPERSAND_LONG:
1878
- print_const("&amp;amp;");
1879
- break;
1880
-
1881
- case ANGLE_RIGHT:
1882
- print_const("&gt;");
1883
- break;
1884
-
1885
- case ANGLE_LEFT:
1886
- print_const("&lt;");
1887
- break;
1888
-
1889
- case ESCAPED_CHARACTER:
1890
- print_const("\\");
1891
- mmd_print_char_odf(out, source[t->start + 1]);
1892
- break;
1893
-
1894
- case HTML_ENTITY:
1895
- print_const("&amp;");
1896
- d_string_append_c_array(out, &(source[t->start + 1]), t->len - 1);
1897
- break;
1898
-
1899
- case INDENT_TAB:
1900
- print_const("<text:tab/>");
1901
- break;
1902
-
1903
- case QUOTE_DOUBLE:
1904
- print_const("&quot;");
1905
- break;
1906
-
1907
- case CODE_FENCE:
1908
- if (t->next) {
1909
- t->next->type = TEXT_EMPTY;
1910
- }
1911
-
1912
- case TEXT_EMPTY:
1913
- break;
1914
-
1915
- case TEXT_NL:
1916
- print_const("<text:line-break/>");
1917
- break;
1918
-
1919
- default:
1920
- if (t->child) {
1921
- mmd_export_token_tree_odf_raw(out, source, t->child, scratch);
1922
- } else {
1923
- print_token(t);
1924
- }
1925
-
1926
- break;
1927
- }
1928
- }
1929
-
1930
-
1931
- void mmd_export_token_tree_odf_raw(DString * out, const char * source, token * t, scratch_pad * scratch) {
1932
- while (t != NULL) {
1933
- if (scratch->skip_token) {
1934
- scratch->skip_token--;
1935
- } else {
1936
- mmd_export_token_odf_raw(out, source, t, scratch);
1937
- }
1938
-
1939
- t = t->next;
1940
- }
1941
- }
1942
-
1943
-
1944
- void mmd_start_complete_odf(DString * out, const char * source, scratch_pad * scratch) {
1945
- print_const("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
1946
- "<office:document xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"\n" \
1947
- " xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\"\n" \
1948
- " xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\"\n" \
1949
- " xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\"\n" \
1950
- " xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\"\n" \
1951
- " xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\"\n" \
1952
- " xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" \
1953
- " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" \
1954
- " xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"\n" \
1955
- " xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\"\n" \
1956
- " xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\"\n" \
1957
- " xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\"\n" \
1958
- " xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\"\n" \
1959
- " xmlns:math=\"http://www.w3.org/1998/Math/MathML\"\n" \
1960
- " xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\"\n" \
1961
- " xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\"\n" \
1962
- " xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\"\n" \
1963
- " xmlns:ooo=\"http://openoffice.org/2004/office\"\n" \
1964
- " xmlns:ooow=\"http://openoffice.org/2004/writer\"\n" \
1965
- " xmlns:oooc=\"http://openoffice.org/2004/calc\"\n" \
1966
- " xmlns:dom=\"http://www.w3.org/2001/xml-events\"\n" \
1967
- " xmlns:xforms=\"http://www.w3.org/2002/xforms\"\n" \
1968
- " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" \
1969
- " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" \
1970
- " xmlns:rpt=\"http://openoffice.org/2005/report\"\n" \
1971
- " xmlns:of=\"urn:oasis:names:tc:opendocument:xmlns:of:1.2\"\n" \
1972
- " xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"\n" \
1973
- " xmlns:grddl=\"http://www.w3.org/2003/g/data-view#\"\n" \
1974
- " xmlns:tableooo=\"http://openoffice.org/2009/table\"\n" \
1975
- " xmlns:field=\"urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0\"\n" \
1976
- " xmlns:formx=\"urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0\"\n" \
1977
- " xmlns:css3t=\"http://www.w3.org/TR/css3-text/\"\n" \
1978
- " office:version=\"1.2\"\n" \
1979
- " grddl:transformation=\"http://docs.oasis-open.org/office/1.2/xslt/odf2rdf.xsl\"\n" \
1980
- " office:mimetype=\"application/vnd.oasis.opendocument.text\">\n");
1981
-
1982
- /* Font Declarations */
1983
- print_const("<office:font-face-decls>\n" \
1984
- " <style:font-face style:name=\"Courier New\" svg:font-family=\"'Courier New'\"\n" \
1985
- " style:font-adornments=\"Regular\"\n" \
1986
- " style:font-family-generic=\"modern\"\n" \
1987
- " style:font-pitch=\"fixed\"/>\n" \
1988
- "</office:font-face-decls>\n");
1989
-
1990
- /* Append basic style information */
1991
- print_const("<office:styles>\n" \
1992
- "<style:style style:name=\"Standard\" style:family=\"paragraph\" style:class=\"text\">\n" \
1993
- " <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0.15in\"" \
1994
- " fo:text-align=\"justify\" style:justify-single-word=\"false\"/>\n" \
1995
- " </style:style>\n" \
1996
- "<style:style style:name=\"Preformatted_20_Text\" style:display-name=\"Preformatted Text\"\n" \
1997
- " style:family=\"paragraph\"\n" \
1998
- " style:parent-style-name=\"Standard\"\n" \
1999
- " style:class=\"html\">\n" \
2000
- " <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0in\" fo:text-align=\"start\"\n" \
2001
- " style:justify-single-word=\"false\"/>\n" \
2002
- " <style:text-properties style:font-name=\"Courier New\" fo:font-size=\"11pt\"\n" \
2003
- " style:font-name-asian=\"Courier New\"\n" \
2004
- " style:font-size-asian=\"11pt\"\n" \
2005
- " style:font-name-complex=\"Courier New\"\n" \
2006
- " style:font-size-complex=\"11pt\"/>\n" \
2007
- "</style:style>\n" \
2008
- "<style:style style:name=\"Source_20_Text\" style:display-name=\"Source Text\"\n" \
2009
- " style:family=\"text\">\n" \
2010
- " <style:text-properties style:font-name=\"Courier New\" style:font-name-asian=\"Courier New\"\n" \
2011
- " style:font-name-complex=\"Courier New\"\n" \
2012
- " fo:font-size=\"11pt\"/>\n" \
2013
- "</style:style>\n" \
2014
- "<style:style style:name=\"List\" style:family=\"paragraph\"\n" \
2015
- " style:parent-style-name=\"Standard\"\n" \
2016
- " style:class=\"list\">\n" \
2017
- " <style:paragraph-properties fo:text-align=\"start\" style:justify-single-word=\"false\"/>\n" \
2018
- " <style:text-properties style:font-size-asian=\"12pt\"/>\n" \
2019
- "</style:style>\n" \
2020
- "<style:style style:name=\"Quotations\" style:family=\"paragraph\"\n" \
2021
- " style:parent-style-name=\"Standard\"\n" \
2022
- " style:class=\"html\">\n" \
2023
- " <style:paragraph-properties fo:margin-left=\"0.3937in\" fo:margin-right=\"0.3937in\" fo:margin-top=\"0in\"\n" \
2024
- " fo:margin-bottom=\"0.1965in\"\n" \
2025
- " fo:text-align=\"justify\"" \
2026
- " style:justify-single-word=\"false\"" \
2027
- " fo:text-indent=\"0in\"\n" \
2028
- " style:auto-text-indent=\"false\"/>\n" \
2029
- "</style:style>\n" \
2030
- "<style:style style:name=\"Table_20_Heading\" style:display-name=\"Table Heading\"\n" \
2031
- " style:family=\"paragraph\"\n" \
2032
- " style:parent-style-name=\"Table_20_Contents\"\n" \
2033
- " style:class=\"extra\">\n" \
2034
- " <style:paragraph-properties fo:text-align=\"center\" style:justify-single-word=\"false\"\n" \
2035
- " text:number-lines=\"false\"\n" \
2036
- " text:line-number=\"0\"/>\n" \
2037
- " <style:text-properties fo:font-weight=\"bold\" style:font-weight-asian=\"bold\"\n" \
2038
- " style:font-weight-complex=\"bold\"/>\n" \
2039
- "</style:style>\n" \
2040
- "<style:style style:name=\"Horizontal_20_Line\" style:display-name=\"Horizontal Line\"\n" \
2041
- " style:family=\"paragraph\"\n" \
2042
- " style:parent-style-name=\"Standard\"\n" \
2043
- " style:class=\"html\">\n" \
2044
- " <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0.1965in\"\n" \
2045
- " style:border-line-width-bottom=\"0.0008in 0.0138in 0.0008in\"\n" \
2046
- " fo:padding=\"0in\"\n" \
2047
- " fo:border-left=\"none\"\n" \
2048
- " fo:border-right=\"none\"\n" \
2049
- " fo:border-top=\"none\"\n" \
2050
- " fo:border-bottom=\"0.0154in double #808080\"\n" \
2051
- " text:number-lines=\"false\"\n" \
2052
- " text:line-number=\"0\"\n" \
2053
- " style:join-border=\"false\"/>\n" \
2054
- " <style:text-properties fo:font-size=\"6pt\" style:font-size-asian=\"6pt\" style:font-size-complex=\"6pt\"/>\n" \
2055
- "</style:style>\n" \
2056
- "<style:style style:name=\"Footnote_20_anchor\" style:display-name=\"Footnote anchor\"" \
2057
- " style:family=\"text\">" \
2058
- " <style:text-properties style:text-position=\"super 58%\"/>" \
2059
- " </style:style>\n" \
2060
- "<style:style style:name=\"TOC_Item\" style:family=\"paragraph\" style:parent-style-name=\"Standard\">\n" \
2061
- " <style:paragraph-properties>\n" \
2062
- " <style:tab-stops>\n" \
2063
- " <style:tab-stop style:position=\"6.7283in\" style:type=\"right\" style:leader-style=\"dotted\" style:leader-text=\".\"/>\n" \
2064
- " </style:tab-stops>\n" \
2065
- " </style:paragraph-properties>\n" \
2066
- "</style:style>\n" \
2067
- " <text:notes-configuration text:note-class=\"footnote\" text:default-style-name=\"Footnote\" text:citation-style-name=\"Footnote_20_Symbol\" text:citation-body-style-name=\"Footnote_20_anchor\" text:master-page-name=\"Footnote\" style:num-format=\"a\" text:start-value=\"0\" text:footnotes-position=\"page\" text:start-numbering-at=\"page\"/>\n" \
2068
- " <text:notes-configuration text:note-class=\"endnote\" text:default-style-name=\"Endnote\" text:citation-style-name=\"Endnote_20_Symbol\" text:citation-body-style-name=\"Endnote_20_anchor\" text:master-page-name=\"Endnote\" style:num-format=\"1\" text:start-value=\"0\"/>\n" \
2069
- "</office:styles>\n");
2070
-
2071
- /* Automatic style information */
2072
- print_const("<office:automatic-styles>" \
2073
- " <style:style style:name=\"MMD-Italic\" style:family=\"text\">\n" \
2074
- " <style:text-properties fo:font-style=\"italic\" style:font-style-asian=\"italic\"\n" \
2075
- " style:font-style-complex=\"italic\"/>\n" \
2076
- " </style:style>\n" \
2077
- " <style:style style:name=\"MMD-Bold\" style:family=\"text\">\n" \
2078
- " <style:text-properties fo:font-weight=\"bold\" style:font-weight-asian=\"bold\"\n" \
2079
- " style:font-weight-complex=\"bold\"/>\n" \
2080
- " </style:style>\n" \
2081
- " <style:style style:name=\"MMD-Superscript\" style:family=\"text\">\n" \
2082
- " <style:text-properties style:text-position=\"super 58%\"/>\n" \
2083
- " </style:style>\n" \
2084
- " <style:style style:name=\"MMD-Subscript\" style:family=\"text\">\n" \
2085
- " <style:text-properties style:text-position=\"sub 58%\"/>\n" \
2086
- " </style:style>\n" \
2087
- " <style:style style:name=\"Strike\" style:family=\"text\">\n" \
2088
- " <style:text-properties style:text-line-through-style=\"solid\" />\n" \
2089
- " </style:style>\n" \
2090
- " <style:style style:name=\"Underline\" style:family=\"text\">\n" \
2091
- " <style:text-properties style:text-underline-style=\"solid\" style:text-underline-color=\"font-color\"/>\n" \
2092
- " </style:style>\n" \
2093
- " <style:style style:name=\"Highlight\" style:family=\"text\">\n" \
2094
- " <style:text-properties fo:background-color=\"#FFFF00\" />\n" \
2095
- " </style:style>\n" \
2096
- " <style:style style:name=\"Comment\" style:family=\"text\">\n" \
2097
- " <style:text-properties fo:color=\"#0000BB\" />\n" \
2098
- " </style:style>\n" \
2099
- "<style:style style:name=\"MMD-Table\" style:family=\"paragraph\" style:parent-style-name=\"Standard\">\n" \
2100
- " <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0.05in\"/>\n" \
2101
- "</style:style>\n" \
2102
- "<style:style style:name=\"MMD-Table-Center\" style:family=\"paragraph\" style:parent-style-name=\"MMD-Table\">\n" \
2103
- " <style:paragraph-properties fo:text-align=\"center\" style:justify-single-word=\"false\"/>\n" \
2104
- "</style:style>\n" \
2105
- "<style:style style:name=\"MMD-Table-Right\" style:family=\"paragraph\" style:parent-style-name=\"MMD-Table\">\n" \
2106
- " <style:paragraph-properties fo:text-align=\"right\" style:justify-single-word=\"false\"/>\n" \
2107
- "</style:style>\n" \
2108
- "<style:style style:name=\"P2\" style:family=\"paragraph\" style:parent-style-name=\"Standard\"\n" \
2109
- " style:list-style-name=\"L2\">\n" \
2110
- "<style:paragraph-properties fo:text-align=\"start\" style:justify-single-word=\"false\"/>\n" \
2111
- "</style:style>\n" \
2112
- "<style:style style:name=\"fr1\" style:family=\"graphic\" style:parent-style-name=\"Frame\">\n" \
2113
- " <style:graphic-properties style:print-content=\"true\" style:vertical-pos=\"top\"\n" \
2114
- " style:vertical-rel=\"baseline\"\n" \
2115
- " fo:padding=\"0in\"\n" \
2116
- " fo:border=\"none\"\n" \
2117
- " style:shadow=\"none\"/>\n" \
2118
- "</style:style>\n" \
2119
- "<style:style style:name=\"P1\" style:family=\"paragraph\" style:parent-style-name=\"Standard\"\n" \
2120
- " style:list-style-name=\"L1\"/>\n" \
2121
- "<text:list-style style:name=\"L1\">\n" \
2122
- " <text:list-level-style-bullet text:level=\"1\" text:style-name=\"Numbering_20_Symbols\" style:num-suffix=\".\" text:bullet-char=\"•\">\n" \
2123
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2124
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"0.5in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"0.5in\"/>\n" \
2125
- " </style:list-level-properties>\n" \
2126
- " </text:list-level-style-bullet>\n" \
2127
- " <text:list-level-style-bullet text:level=\"2\" text:style-name=\"Numbering_20_Symbols\" style:num-suffix=\".\" text:bullet-char=\"◦\">\n" \
2128
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2129
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"0.75in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"0.75in\"/>\n" \
2130
- " </style:list-level-properties>\n" \
2131
- " </text:list-level-style-bullet>\n" \
2132
- " <text:list-level-style-bullet text:level=\"3\" text:style-name=\"Numbering_20_Symbols\" style:num-suffix=\".\" text:bullet-char=\"▪\">\n" \
2133
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2134
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"1in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"1in\"/>\n" \
2135
- " </style:list-level-properties>\n" \
2136
- " </text:list-level-style-bullet>\n" \
2137
- " <text:list-level-style-number text:level=\"4\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2138
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2139
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"1.25in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"1.25in\"/>\n" \
2140
- " </style:list-level-properties>\n" \
2141
- " </text:list-level-style-number>\n" \
2142
- " <text:list-level-style-number text:level=\"5\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2143
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2144
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"1.5in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"1.5in\"/>\n" \
2145
- " </style:list-level-properties>\n" \
2146
- " </text:list-level-style-number>\n" \
2147
- " <text:list-level-style-number text:level=\"6\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2148
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2149
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"1.75in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"1.75in\"/>\n" \
2150
- " </style:list-level-properties>\n" \
2151
- " </text:list-level-style-number>\n" \
2152
- " <text:list-level-style-number text:level=\"7\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2153
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2154
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"2in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"2in\"/>\n" \
2155
- " </style:list-level-properties>\n" \
2156
- " </text:list-level-style-number>\n" \
2157
- " <text:list-level-style-number text:level=\"8\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2158
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2159
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"2.25in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"2.25in\"/>\n" \
2160
- " </style:list-level-properties>\n" \
2161
- " </text:list-level-style-number>\n" \
2162
- " <text:list-level-style-number text:level=\"9\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2163
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2164
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"2.5in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"2.5in\"/>\n" \
2165
- " </style:list-level-properties>\n" \
2166
- " </text:list-level-style-number>\n" \
2167
- " <text:list-level-style-number text:level=\"10\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2168
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2169
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"2.75in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"2.75in\"/>\n" \
2170
- " </style:list-level-properties>\n" \
2171
- " </text:list-level-style-number>\n" \
2172
- "</text:list-style>\n" \
2173
- "<text:list-style style:name=\"L2\">\n" \
2174
- " <text:list-level-style-number text:level=\"1\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2175
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2176
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"0.5in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"0.5in\"/>\n" \
2177
- " </style:list-level-properties>\n" \
2178
- " </text:list-level-style-number>\n" \
2179
- " <text:list-level-style-number text:level=\"2\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2180
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2181
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"0.75in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"0.75in\"/>\n" \
2182
- " </style:list-level-properties>\n" \
2183
- " </text:list-level-style-number>\n" \
2184
- " <text:list-level-style-number text:level=\"3\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2185
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2186
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"1in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"1in\"/>\n" \
2187
- " </style:list-level-properties>\n" \
2188
- " </text:list-level-style-number>\n" \
2189
- " <text:list-level-style-number text:level=\"4\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2190
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2191
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"1.25in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"1.25in\"/>\n" \
2192
- " </style:list-level-properties>\n" \
2193
- " </text:list-level-style-number>\n" \
2194
- " <text:list-level-style-number text:level=\"5\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2195
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2196
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"1.5in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"1.5in\"/>\n" \
2197
- " </style:list-level-properties>\n" \
2198
- " </text:list-level-style-number>\n" \
2199
- " <text:list-level-style-number text:level=\"6\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2200
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2201
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"1.75in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"1.75in\"/>\n" \
2202
- " </style:list-level-properties>\n" \
2203
- " </text:list-level-style-number>\n" \
2204
- " <text:list-level-style-number text:level=\"7\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2205
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2206
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"2in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"2in\"/>\n" \
2207
- " </style:list-level-properties>\n" \
2208
- " </text:list-level-style-number>\n" \
2209
- " <text:list-level-style-number text:level=\"8\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2210
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2211
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"2.25in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"2.25in\"/>\n" \
2212
- " </style:list-level-properties>\n" \
2213
- " </text:list-level-style-number>\n" \
2214
- " <text:list-level-style-number text:level=\"9\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2215
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2216
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"2.5in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"2.5in\"/>\n" \
2217
- " </style:list-level-properties>\n" \
2218
- " </text:list-level-style-number>\n" \
2219
- " <text:list-level-style-number text:level=\"10\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
2220
- " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
2221
- " <style:list-level-label-alignment text:label-followed-by=\"listtab\" text:list-tab-stop-position=\"2.75in\" fo:text-indent=\"-0.25in\" fo:margin-left=\"2.75in\"/>\n" \
2222
- " </style:list-level-properties>\n" \
2223
- " </text:list-level-style-number>\n" \
2224
- "</text:list-style>\n" \
2225
- "</office:automatic-styles>\n" \
2226
- " <office:master-styles>\n" \
2227
- " <style:master-page style:name=\"Endnote\" >\n" \
2228
- " <style:header><text:h text:outline-level=\"2\">Bibliography</text:h></style:header></style:master-page>\n" \
2229
- " <style:master-page style:name=\"Footnote\" style:page-layout-name=\"pm2\"/>\n" \
2230
- " </office:master-styles>\n");
2231
-
2232
- // Iterate over metadata keys
2233
- meta * m;
2234
-
2235
- if (scratch->meta_hash) {
2236
- print_const("<office:meta>\n");
2237
- }
2238
-
2239
- for (m = scratch->meta_hash; m != NULL; m = m->hh.next) {
2240
- if (strcmp(m->key, "baseheaderlevel") == 0) {
2241
- } else if (strcmp(m->key, "bibliostyle") == 0) {
2242
- } else if (strcmp(m->key, "bibtex") == 0) {
2243
- } else if (strcmp(m->key, "css") == 0) {
2244
- } else if (strcmp(m->key, "htmlfooter") == 0) {
2245
- } else if (strcmp(m->key, "htmlheader") == 0) {
2246
- } else if (strcmp(m->key, "htmlheaderlevel") == 0) {
2247
- } else if (strcmp(m->key, "language") == 0) {
2248
- } else if (strcmp(m->key, "latexbegin") == 0) {
2249
- } else if (strcmp(m->key, "latexconfig") == 0) {
2250
- } else if (strcmp(m->key, "latexfooter") == 0) {
2251
- } else if (strcmp(m->key, "latexheaderlevel") == 0) {
2252
- } else if (strcmp(m->key, "latexinput") == 0) {
2253
- } else if (strcmp(m->key, "latexleader") == 0) {
2254
- } else if (strcmp(m->key, "latexmode") == 0) {
2255
- } else if (strcmp(m->key, "mmdfooter") == 0) {
2256
- } else if (strcmp(m->key, "mmdheader") == 0) {
2257
- } else if (strcmp(m->key, "quoteslanguage") == 0) {
2258
- } else if (strcmp(m->key, "title") == 0) {
2259
- print_const("\t<dc:title>");
2260
- mmd_print_string_odf(out, m->value);
2261
- print_const("</dc:title>\n");
2262
- } else if (strcmp(m->key, "transcludebase") == 0) {
2263
- } else if (strcmp(m->key, "xhtmlheader") == 0) {
2264
- print(m->value);
2265
- print_char('\n');
2266
- } else if (strcmp(m->key, "xhtmlheaderlevel") == 0) {
2267
- } else {
2268
- print_const("\t<meta:user-defined meta:name=\"");
2269
- mmd_print_string_odf(out, m->key);
2270
- print_const("\">");
2271
- mmd_print_string_odf(out, m->value);
2272
- print_const("</meta:user-defined>\n");
2273
- }
2274
- }
2275
-
2276
- if (scratch->meta_hash) {
2277
- print_const("</office:meta>\n");
2278
- }
2279
-
2280
- print_const("<office:body>\n<office:text>\n");
2281
- }
2282
-
2283
-
2284
- void mmd_end_complete_odf(DString * out, const char * source, scratch_pad * scratch) {
2285
- pad(out, 1, scratch);
2286
- print_const("</office:text>\n</office:body>\n</office:document>");
2287
- }
2288
-