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
@@ -0,0 +1,135 @@
1
+ /**
2
+
3
+ MultiMarkdown -- Lightweight markup processor to produce HTML, LaTeX, and more.
4
+
5
+ @file opendocument-content.h
6
+
7
+ @brief
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
+ uthash library:
33
+ Copyright (c) 2005-2016, Troy D. Hanson
34
+
35
+ Licensed under Revised BSD license
36
+
37
+ miniz library:
38
+ Copyright 2013-2014 RAD Game Tools and Valve Software
39
+ Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
40
+
41
+ Licensed under the MIT license
42
+
43
+ argtable3 library:
44
+ Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann
45
+ <sheitmann@users.sourceforge.net>
46
+ All rights reserved.
47
+
48
+ Licensed under the Revised BSD License
49
+
50
+
51
+ ## The MIT License ##
52
+
53
+ Permission is hereby granted, free of charge, to any person obtaining
54
+ a copy of this software and associated documentation files (the
55
+ "Software"), to deal in the Software without restriction, including
56
+ without limitation the rights to use, copy, modify, merge, publish,
57
+ distribute, sublicense, and/or sell copies of the Software, and to
58
+ permit persons to whom the Software is furnished to do so, subject to
59
+ the following conditions:
60
+
61
+ The above copyright notice and this permission notice shall be
62
+ included in all copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
65
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
66
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
67
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
68
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
69
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
70
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
71
+
72
+
73
+ ## Revised BSD License ##
74
+
75
+ Redistribution and use in source and binary forms, with or without
76
+ modification, are permitted provided that the following conditions are
77
+ met:
78
+ * Redistributions of source code must retain the above copyright
79
+ notice, this list of conditions and the following disclaimer.
80
+ * Redistributions in binary form must reproduce the above
81
+ copyright notice, this list of conditions and the following
82
+ disclaimer in the documentation and/or other materials provided
83
+ with the distribution.
84
+ * Neither the name of the <organization> nor the
85
+ names of its contributors may be used to endorse or promote
86
+ products derived from this software without specific prior
87
+ written permission.
88
+
89
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
90
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
91
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
92
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT
93
+ HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
94
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
95
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR
96
+ PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
97
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
98
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100
+
101
+
102
+ */
103
+
104
+
105
+ #ifndef OPENDOCUMENT_CONTENT_MULTIMARKDOWN_H
106
+ #define OPENDOCUMENT_CONTENT_MULTIMARKDOWN_H
107
+
108
+ #include "writer.h"
109
+
110
+ void mmd_print_char_opendocument(DString * out, char c);
111
+ void mmd_print_string_opendocument(DString * out, const char * str);
112
+ void mmd_print_localized_char_opendocument(DString * out, unsigned short type, scratch_pad * scratch);
113
+
114
+ void mmd_export_token_opendocument_raw(DString * out, const char * source, token * t, scratch_pad * scratch);
115
+ void mmd_export_token_opendocument_math(DString * out, const char * source, token * t, scratch_pad * scratch);
116
+
117
+ void mmd_export_link_opendocument(DString * out, const char * source, token * text, link * link, scratch_pad * scratch);
118
+ void mmd_export_image_opendocument(DString * out, const char * source, token * text, link * link, scratch_pad * scratch, bool is_figure);
119
+
120
+
121
+ void mmd_export_token_opendocument(DString * out, const char * source, token * t, scratch_pad * scratch);
122
+ void mmd_export_token_tree_opendocument(DString * out, const char * source, token * t, scratch_pad * scratch);
123
+
124
+ void mmd_export_token_opendocument_raw(DString * out, const char * source, token * t, scratch_pad * scratch);
125
+ void mmd_export_token_tree_opendocument_raw(DString * out, const char * source, token * t, scratch_pad * scratch);
126
+
127
+ void mmd_export_citation_list_opendocument(DString * out, const char * source, scratch_pad * scratch);
128
+ void mmd_export_footnote_list_opendocument(DString * out, const char * source, scratch_pad * scratch);
129
+
130
+ void mmd_start_complete_opendocument(DString * out, const char * source, scratch_pad * scratch);
131
+ void mmd_end_complete_opendocument(DString * out, const char * source, scratch_pad * scratch);
132
+
133
+ void mmd_export_citation_list_opendocument(DString * out, const char * source, scratch_pad * scratch);
134
+
135
+ #endif
@@ -0,0 +1,981 @@
1
+ /**
2
+
3
+ MultiMarkdown -- Lightweight markup processor to produce HTML, LaTeX, and more.
4
+
5
+ @file opendocument.c
6
+
7
+ @brief
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
+ uthash library:
33
+ Copyright (c) 2005-2016, Troy D. Hanson
34
+
35
+ Licensed under Revised BSD license
36
+
37
+ miniz library:
38
+ Copyright 2013-2014 RAD Game Tools and Valve Software
39
+ Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
40
+
41
+ Licensed under the MIT license
42
+
43
+ argtable3 library:
44
+ Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann
45
+ <sheitmann@users.sourceforge.net>
46
+ All rights reserved.
47
+
48
+ Licensed under the Revised BSD License
49
+
50
+
51
+ ## The MIT License ##
52
+
53
+ Permission is hereby granted, free of charge, to any person obtaining
54
+ a copy of this software and associated documentation files (the
55
+ "Software"), to deal in the Software without restriction, including
56
+ without limitation the rights to use, copy, modify, merge, publish,
57
+ distribute, sublicense, and/or sell copies of the Software, and to
58
+ permit persons to whom the Software is furnished to do so, subject to
59
+ the following conditions:
60
+
61
+ The above copyright notice and this permission notice shall be
62
+ included in all copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
65
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
66
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
67
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
68
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
69
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
70
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
71
+
72
+
73
+ ## Revised BSD License ##
74
+
75
+ Redistribution and use in source and binary forms, with or without
76
+ modification, are permitted provided that the following conditions are
77
+ met:
78
+ * Redistributions of source code must retain the above copyright
79
+ notice, this list of conditions and the following disclaimer.
80
+ * Redistributions in binary form must reproduce the above
81
+ copyright notice, this list of conditions and the following
82
+ disclaimer in the documentation and/or other materials provided
83
+ with the distribution.
84
+ * Neither the name of the <organization> nor the
85
+ names of its contributors may be used to endorse or promote
86
+ products derived from this software without specific prior
87
+ written permission.
88
+
89
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
90
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
91
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
92
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT
93
+ HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
94
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
95
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR
96
+ PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
97
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
98
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100
+
101
+
102
+ */
103
+
104
+ #ifdef USE_CURL
105
+ #include <curl/curl.h>
106
+ #endif
107
+
108
+ #include "miniz.h"
109
+ #include "opendocument.h"
110
+ #include "opendocument-content.h"
111
+ #include "transclude.h"
112
+ #include "writer.h"
113
+ #include "zip.h"
114
+
115
+ #define print(x) d_string_append(out, x)
116
+ #define print_const(x) d_string_append_c_array(out, x, sizeof(x) - 1)
117
+ #define print_char(x) d_string_append_c(out, x)
118
+ #define printf(...) d_string_append_printf(out, __VA_ARGS__)
119
+ #define print_token(t) d_string_append_c_array(out, &(source[t->start]), t->len)
120
+ #define print_localized(x) mmd_print_localized_char_html(out, x, scratch)
121
+
122
+
123
+ /// strdup() not available on all platforms
124
+ static char * my_strdup(const char * source) {
125
+ if (source == NULL) {
126
+ return NULL;
127
+ }
128
+
129
+ char * result = malloc(strlen(source) + 1);
130
+
131
+ if (result) {
132
+ strcpy(result, source);
133
+ }
134
+
135
+ return result;
136
+ }
137
+
138
+
139
+ static bool add_asset_from_file(mz_zip_archive * pZip, asset * a, const char * destination, const char * directory) {
140
+ if (!directory) {
141
+ return false;
142
+ }
143
+
144
+ char * path = path_from_dir_base(directory, a->url);
145
+ mz_bool status;
146
+ bool result = false;
147
+
148
+ DString * buffer = scan_file(path);
149
+
150
+ if (buffer && buffer->currentStringLength > 0) {
151
+ status = mz_zip_writer_add_mem(pZip, destination, buffer->str, buffer->currentStringLength, MZ_BEST_COMPRESSION);
152
+
153
+ if (!status) {
154
+ fprintf(stderr, "Error adding asset '%s' to zip.\n", destination);
155
+ }
156
+
157
+ d_string_free(buffer, true);
158
+ result = true;
159
+ }
160
+
161
+ free(path);
162
+
163
+ return result;
164
+ }
165
+
166
+
167
+ /// Create metadata for OpenDocument
168
+ char * opendocument_metadata(mmd_engine * e, scratch_pad * scratch) {
169
+ DString * out = d_string_new("");
170
+ meta * m;
171
+
172
+ d_string_append(out, "<office:meta>\n");
173
+
174
+ // Iterate through metadata keys
175
+ for (m = scratch->meta_hash; m != NULL; m = m->hh.next) {
176
+ if (strcmp(m->key, "author") == 0) {
177
+ print_const("\t<dc:creator>");
178
+ mmd_print_string_opendocument(out, m->value);
179
+ print_const("</dc:creator>\n");
180
+ } else if (strcmp(m->key, "baseheaderlevel") == 0) {
181
+ } else if (strcmp(m->key, "bibliostyle") == 0) {
182
+ } else if (strcmp(m->key, "bibtex") == 0) {
183
+ } else if (strcmp(m->key, "css") == 0) {
184
+ } else if (strcmp(m->key, "htmlfooter") == 0) {
185
+ } else if (strcmp(m->key, "htmlheader") == 0) {
186
+ } else if (strcmp(m->key, "htmlheaderlevel") == 0) {
187
+ } else if (strcmp(m->key, "language") == 0) {
188
+ } else if (strcmp(m->key, "latexbegin") == 0) {
189
+ } else if (strcmp(m->key, "latexconfig") == 0) {
190
+ } else if (strcmp(m->key, "latexfooter") == 0) {
191
+ } else if (strcmp(m->key, "latexheaderlevel") == 0) {
192
+ } else if (strcmp(m->key, "latexinput") == 0) {
193
+ } else if (strcmp(m->key, "latexleader") == 0) {
194
+ } else if (strcmp(m->key, "latexmode") == 0) {
195
+ } else if (strcmp(m->key, "mmdfooter") == 0) {
196
+ } else if (strcmp(m->key, "mmdheader") == 0) {
197
+ } else if (strcmp(m->key, "quoteslanguage") == 0) {
198
+ } else if (strcmp(m->key, "title") == 0) {
199
+ print_const("\t<dc:title>");
200
+ mmd_print_string_opendocument(out, m->value);
201
+ print_const("</dc:title>\n");
202
+ } else if (strcmp(m->key, "transcludebase") == 0) {
203
+ } else if (strcmp(m->key, "xhtmlheader") == 0) {
204
+ } else if (strcmp(m->key, "xhtmlheaderlevel") == 0) {
205
+ } else {
206
+ print_const("\t<meta:user-defined meta:name=\"");
207
+ mmd_print_string_opendocument(out, m->key);
208
+ print_const("\">");
209
+ mmd_print_string_opendocument(out, m->value);
210
+ print_const("</meta:user-defined>\n");
211
+ }
212
+ }
213
+
214
+ d_string_append(out, "</office:meta>");
215
+
216
+ char * result = out->str;
217
+ d_string_free(out, false);
218
+ return result;
219
+ }
220
+
221
+
222
+ /// Create full metadata file for OpenDocument
223
+ char * opendocument_metadata_file(mmd_engine * e, scratch_pad * scratch) {
224
+ DString * out = d_string_new("");
225
+
226
+ char * meta = opendocument_metadata(e, scratch);
227
+
228
+ // Open
229
+ d_string_append(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
230
+ d_string_append(out, "<office:document-meta xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\" xmlns:ooo=\"http://openoffice.org/2004/office\" xmlns:grddl=\"http://www.w3.org/2003/g/data-view#\" office:version=\"1.2\">\n");
231
+
232
+ // Metadata
233
+ d_string_append(out, meta);
234
+
235
+ // Close
236
+ d_string_append(out, "\n</office:document-meta>");
237
+
238
+ // Cleanup
239
+ free(meta);
240
+ char * result = out->str;
241
+ d_string_free(out, false);
242
+ return result;
243
+ }
244
+
245
+
246
+ /// Create default style information for OpenDocument
247
+ char * opendocument_style(int format) {
248
+ DString * out = d_string_new("");
249
+
250
+ /* Font Declarations */
251
+ print_const("<office:font-face-decls>\n" \
252
+ " <style:font-face style:name=\"Courier New\" svg:font-family=\"'Courier New'\"\n" \
253
+ " style:font-adornments=\"Regular\"\n" \
254
+ " style:font-family-generic=\"modern\"\n" \
255
+ " style:font-pitch=\"fixed\"/>\n" \
256
+ "</office:font-face-decls>\n");
257
+
258
+ /* Append basic style information */
259
+ print_const("<office:styles>\n" \
260
+ "<style:style style:name=\"Standard\" style:family=\"paragraph\" style:class=\"text\">\n" \
261
+ " <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0.15in\"" \
262
+ " fo:text-align=\"justify\" style:justify-single-word=\"false\"/>\n" \
263
+ " </style:style>\n" \
264
+ "<style:style style:name=\"Preformatted_20_Text\" style:display-name=\"Preformatted Text\"\n" \
265
+ " style:family=\"paragraph\"\n" \
266
+ " style:parent-style-name=\"Standard\"\n" \
267
+ " style:class=\"html\">\n" \
268
+ " <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0in\" fo:text-align=\"start\"\n" \
269
+ " style:justify-single-word=\"false\"/>\n" \
270
+ " <style:text-properties style:font-name=\"Courier New\" fo:font-size=\"11pt\"\n" \
271
+ " style:font-name-asian=\"Courier New\"\n" \
272
+ " style:font-size-asian=\"11pt\"\n" \
273
+ " style:font-name-complex=\"Courier New\"\n" \
274
+ " style:font-size-complex=\"11pt\"/>\n" \
275
+ "</style:style>\n" \
276
+ "<style:style style:name=\"Source_20_Text\" style:display-name=\"Source Text\"\n" \
277
+ " style:family=\"text\">\n" \
278
+ " <style:text-properties style:font-name=\"Courier New\" style:font-name-asian=\"Courier New\"\n" \
279
+ " style:font-name-complex=\"Courier New\"\n" \
280
+ " fo:font-size=\"11pt\"/>\n" \
281
+ "</style:style>\n" \
282
+ "<style:style style:name=\"List\" style:family=\"paragraph\"\n" \
283
+ " style:parent-style-name=\"Standard\"\n" \
284
+ " style:class=\"list\">\n" \
285
+ " <style:paragraph-properties fo:text-align=\"start\" style:justify-single-word=\"false\"/>\n" \
286
+ " <style:text-properties style:font-size-asian=\"12pt\"/>\n" \
287
+ "</style:style>\n" \
288
+ "<style:style style:name=\"Quotations\" style:family=\"paragraph\"\n" \
289
+ " style:parent-style-name=\"Standard\"\n" \
290
+ " style:class=\"html\">\n" \
291
+ " <style:paragraph-properties fo:margin-left=\"0.3937in\" fo:margin-right=\"0.3937in\" fo:margin-top=\"0in\"\n" \
292
+ " fo:margin-bottom=\"0.1965in\"\n" \
293
+ " fo:text-align=\"justify\"" \
294
+ " style:justify-single-word=\"false\"" \
295
+ " fo:text-indent=\"0in\"\n" \
296
+ " style:auto-text-indent=\"false\"/>\n" \
297
+ "</style:style>\n" \
298
+ "<style:style style:name=\"Table_20_Heading\" style:display-name=\"Table Heading\"\n" \
299
+ " style:family=\"paragraph\"\n" \
300
+ " style:parent-style-name=\"Table_20_Contents\"\n" \
301
+ " style:class=\"extra\">\n" \
302
+ " <style:paragraph-properties fo:text-align=\"center\" style:justify-single-word=\"false\"\n" \
303
+ " text:number-lines=\"false\"\n" \
304
+ " text:line-number=\"0\"/>\n" \
305
+ " <style:text-properties fo:font-weight=\"bold\" style:font-weight-asian=\"bold\"\n" \
306
+ " style:font-weight-complex=\"bold\"/>\n" \
307
+ "</style:style>\n" \
308
+ "<style:style style:name=\"Horizontal_20_Line\" style:display-name=\"Horizontal Line\"\n" \
309
+ " style:family=\"paragraph\"\n" \
310
+ " style:parent-style-name=\"Standard\"\n" \
311
+ " style:class=\"html\">\n" \
312
+ " <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0.1965in\"\n" \
313
+ " style:border-line-width-bottom=\"0.0008in 0.0138in 0.0008in\"\n" \
314
+ " fo:padding=\"0in\"\n" \
315
+ " fo:border-left=\"none\"\n" \
316
+ " fo:border-right=\"none\"\n" \
317
+ " fo:border-top=\"none\"\n" \
318
+ " fo:border-bottom=\"0.0154in double #808080\"\n" \
319
+ " text:number-lines=\"false\"\n" \
320
+ " text:line-number=\"0\"\n" \
321
+ " style:join-border=\"false\"/>\n" \
322
+ " <style:text-properties fo:font-size=\"6pt\" style:font-size-asian=\"6pt\" style:font-size-complex=\"6pt\"/>\n" \
323
+ "</style:style>\n" \
324
+ "<style:style style:name=\"Footnote_20_anchor\" style:display-name=\"Footnote anchor\"" \
325
+ " style:family=\"text\">" \
326
+ " <style:text-properties style:text-position=\"super 58%\"/>" \
327
+ " </style:style>\n" \
328
+ "<style:style style:name=\"TOC_Item\" style:family=\"paragraph\" style:parent-style-name=\"Standard\">\n" \
329
+ " <style:paragraph-properties>\n" \
330
+ " <style:tab-stops>\n" \
331
+ " <style:tab-stop style:position=\"6.7283in\" style:type=\"right\" style:leader-style=\"dotted\" style:leader-text=\".\"/>\n" \
332
+ " </style:tab-stops>\n" \
333
+ " </style:paragraph-properties>\n" \
334
+ "</style:style>\n" \
335
+ " <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" \
336
+ " <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" \
337
+ "</office:styles>\n");
338
+
339
+ /* Automatic style information */
340
+ print_const("<office:automatic-styles>" \
341
+ " <style:style style:name=\"MMD-Italic\" style:family=\"text\">\n" \
342
+ " <style:text-properties fo:font-style=\"italic\" style:font-style-asian=\"italic\"\n" \
343
+ " style:font-style-complex=\"italic\"/>\n" \
344
+ " </style:style>\n" \
345
+ " <style:style style:name=\"MMD-Bold\" style:family=\"text\">\n" \
346
+ " <style:text-properties fo:font-weight=\"bold\" style:font-weight-asian=\"bold\"\n" \
347
+ " style:font-weight-complex=\"bold\"/>\n" \
348
+ " </style:style>\n" \
349
+ " <style:style style:name=\"MMD-Superscript\" style:family=\"text\">\n" \
350
+ " <style:text-properties style:text-position=\"super 58%\"/>\n" \
351
+ " </style:style>\n" \
352
+ " <style:style style:name=\"MMD-Subscript\" style:family=\"text\">\n" \
353
+ " <style:text-properties style:text-position=\"sub 58%\"/>\n" \
354
+ " </style:style>\n" \
355
+ " <style:style style:name=\"Strike\" style:family=\"text\">\n" \
356
+ " <style:text-properties style:text-line-through-style=\"solid\" />\n" \
357
+ " </style:style>\n" \
358
+ " <style:style style:name=\"Underline\" style:family=\"text\">\n" \
359
+ " <style:text-properties style:text-underline-style=\"solid\" style:text-underline-color=\"font-color\"/>\n" \
360
+ " </style:style>\n" \
361
+ " <style:style style:name=\"Highlight\" style:family=\"text\">\n" \
362
+ " <style:text-properties fo:background-color=\"#FFFF00\" />\n" \
363
+ " </style:style>\n" \
364
+ " <style:style style:name=\"Comment\" style:family=\"text\">\n" \
365
+ " <style:text-properties fo:color=\"#0000BB\" />\n" \
366
+ " </style:style>\n" \
367
+ "<style:style style:name=\"MMD-Table\" style:family=\"paragraph\" style:parent-style-name=\"Standard\">\n" \
368
+ " <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0.05in\"/>\n" \
369
+ "</style:style>\n" \
370
+ "<style:style style:name=\"MMD-Table-Center\" style:family=\"paragraph\" style:parent-style-name=\"MMD-Table\">\n" \
371
+ " <style:paragraph-properties fo:text-align=\"center\" style:justify-single-word=\"false\"/>\n" \
372
+ "</style:style>\n" \
373
+ "<style:style style:name=\"MMD-Table-Right\" style:family=\"paragraph\" style:parent-style-name=\"MMD-Table\">\n" \
374
+ " <style:paragraph-properties fo:text-align=\"right\" style:justify-single-word=\"false\"/>\n" \
375
+ "</style:style>\n" \
376
+ "<style:style style:name=\"P2\" style:family=\"paragraph\" style:parent-style-name=\"Standard\"\n" \
377
+ " style:list-style-name=\"L2\">\n" \
378
+ "<style:paragraph-properties fo:text-align=\"start\" style:justify-single-word=\"false\"/>\n" \
379
+ "</style:style>\n" \
380
+ "<style:style style:name=\"fr1\" style:family=\"graphic\" style:parent-style-name=\"Frame\">\n" \
381
+ " <style:graphic-properties style:print-content=\"true\" style:vertical-pos=\"top\"\n" \
382
+ " style:vertical-rel=\"baseline\"\n" \
383
+ " fo:padding=\"0in\"\n" \
384
+ " fo:border=\"none\"\n" \
385
+ " style:shadow=\"none\"/>\n" \
386
+ "</style:style>\n" \
387
+ "<style:style style:name=\"P1\" style:family=\"paragraph\" style:parent-style-name=\"Standard\"\n" \
388
+ " style:list-style-name=\"L1\"/>\n" \
389
+ "<text:list-style style:name=\"L1\">\n" \
390
+ " <text:list-level-style-bullet text:level=\"1\" text:style-name=\"Numbering_20_Symbols\" style:num-suffix=\".\" text:bullet-char=\"•\">\n" \
391
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
392
+ " <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" \
393
+ " </style:list-level-properties>\n" \
394
+ " </text:list-level-style-bullet>\n" \
395
+ " <text:list-level-style-bullet text:level=\"2\" text:style-name=\"Numbering_20_Symbols\" style:num-suffix=\".\" text:bullet-char=\"◦\">\n" \
396
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
397
+ " <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" \
398
+ " </style:list-level-properties>\n" \
399
+ " </text:list-level-style-bullet>\n" \
400
+ " <text:list-level-style-bullet text:level=\"3\" text:style-name=\"Numbering_20_Symbols\" style:num-suffix=\".\" text:bullet-char=\"▪\">\n" \
401
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
402
+ " <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" \
403
+ " </style:list-level-properties>\n" \
404
+ " </text:list-level-style-bullet>\n" \
405
+ " <text:list-level-style-number text:level=\"4\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
406
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
407
+ " <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" \
408
+ " </style:list-level-properties>\n" \
409
+ " </text:list-level-style-number>\n" \
410
+ " <text:list-level-style-number text:level=\"5\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
411
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
412
+ " <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" \
413
+ " </style:list-level-properties>\n" \
414
+ " </text:list-level-style-number>\n" \
415
+ " <text:list-level-style-number text:level=\"6\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
416
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
417
+ " <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" \
418
+ " </style:list-level-properties>\n" \
419
+ " </text:list-level-style-number>\n" \
420
+ " <text:list-level-style-number text:level=\"7\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
421
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
422
+ " <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" \
423
+ " </style:list-level-properties>\n" \
424
+ " </text:list-level-style-number>\n" \
425
+ " <text:list-level-style-number text:level=\"8\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
426
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
427
+ " <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" \
428
+ " </style:list-level-properties>\n" \
429
+ " </text:list-level-style-number>\n" \
430
+ " <text:list-level-style-number text:level=\"9\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
431
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
432
+ " <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" \
433
+ " </style:list-level-properties>\n" \
434
+ " </text:list-level-style-number>\n" \
435
+ " <text:list-level-style-number text:level=\"10\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
436
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
437
+ " <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" \
438
+ " </style:list-level-properties>\n" \
439
+ " </text:list-level-style-number>\n" \
440
+ "</text:list-style>\n" \
441
+ "<text:list-style style:name=\"L2\">\n" \
442
+ " <text:list-level-style-number text:level=\"1\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
443
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
444
+ " <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" \
445
+ " </style:list-level-properties>\n" \
446
+ " </text:list-level-style-number>\n" \
447
+ " <text:list-level-style-number text:level=\"2\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
448
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
449
+ " <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" \
450
+ " </style:list-level-properties>\n" \
451
+ " </text:list-level-style-number>\n" \
452
+ " <text:list-level-style-number text:level=\"3\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
453
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
454
+ " <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" \
455
+ " </style:list-level-properties>\n" \
456
+ " </text:list-level-style-number>\n" \
457
+ " <text:list-level-style-number text:level=\"4\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
458
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
459
+ " <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" \
460
+ " </style:list-level-properties>\n" \
461
+ " </text:list-level-style-number>\n" \
462
+ " <text:list-level-style-number text:level=\"5\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
463
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
464
+ " <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" \
465
+ " </style:list-level-properties>\n" \
466
+ " </text:list-level-style-number>\n" \
467
+ " <text:list-level-style-number text:level=\"6\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
468
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
469
+ " <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" \
470
+ " </style:list-level-properties>\n" \
471
+ " </text:list-level-style-number>\n" \
472
+ " <text:list-level-style-number text:level=\"7\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
473
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
474
+ " <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" \
475
+ " </style:list-level-properties>\n" \
476
+ " </text:list-level-style-number>\n" \
477
+ " <text:list-level-style-number text:level=\"8\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
478
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
479
+ " <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" \
480
+ " </style:list-level-properties>\n" \
481
+ " </text:list-level-style-number>\n" \
482
+ " <text:list-level-style-number text:level=\"9\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
483
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
484
+ " <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" \
485
+ " </style:list-level-properties>\n" \
486
+ " </text:list-level-style-number>\n" \
487
+ " <text:list-level-style-number text:level=\"10\" text:style-name=\"Standard\" style:num-suffix=\".\" style:num-format=\"1\">\n" \
488
+ " <style:list-level-properties text:list-level-position-and-space-mode=\"label-alignment\">\n" \
489
+ " <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" \
490
+ " </style:list-level-properties>\n" \
491
+ " </text:list-level-style-number>\n" \
492
+ "</text:list-style>\n" \
493
+ "</office:automatic-styles>\n" \
494
+ " <office:master-styles>\n" \
495
+ " <style:master-page style:name=\"Endnote\" >\n" \
496
+ " <style:header><text:h text:outline-level=\"2\">Bibliography</text:h></style:header></style:master-page>\n" \
497
+ " <style:master-page style:name=\"Footnote\" style:page-layout-name=\"pm2\"/>\n" \
498
+ " </office:master-styles>\n");
499
+
500
+ char * result = out->str;
501
+ d_string_free(out, false);
502
+ return result;
503
+ }
504
+
505
+
506
+ /// Create full style file for OpenDocument
507
+ char * opendocument_style_file(int format) {
508
+ DString * out = d_string_new("");
509
+
510
+ char * style = opendocument_style(format);
511
+
512
+ // Open
513
+ d_string_append(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
514
+
515
+ print_const("<office:document-styles xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"\n" \
516
+ "xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\"\n" \
517
+ "xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\"\n" \
518
+ "xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\"\n" \
519
+ "xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\"\n" \
520
+ "xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\"\n" \
521
+ "xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" \
522
+ "xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" \
523
+ "xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"\n" \
524
+ "xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\"\n" \
525
+ "xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\"\n" \
526
+ "xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\"\n" \
527
+ "xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\"\n" \
528
+ "xmlns:math=\"http://www.w3.org/1998/Math/MathML\"\n" \
529
+ "xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\"\n" \
530
+ "xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\"\n" \
531
+ "xmlns:ooo=\"http://openoffice.org/2004/office\"\n" \
532
+ "xmlns:ooow=\"http://openoffice.org/2004/writer\"\n" \
533
+ "xmlns:oooc=\"http://openoffice.org/2004/calc\"\n" \
534
+ "xmlns:dom=\"http://www.w3.org/2001/xml-events\"\n" \
535
+ "xmlns:xforms=\"http://www.w3.org/2002/xforms\"\n" \
536
+ "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" \
537
+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" \
538
+ "xmlns:rpt=\"http://openoffice.org/2005/report\"\n" \
539
+ "xmlns:of=\"urn:oasis:names:tc:opendocument:xmlns:of:1.2\"\n" \
540
+ "xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"\n" \
541
+ "xmlns:grddl=\"http://www.w3.org/2003/g/data-view#\"\n" \
542
+ "xmlns:officeooo=\"http://openoffice.org/2009/office\"\n" \
543
+ "xmlns:tableooo=\"http://openoffice.org/2009/table\"\n" \
544
+ "xmlns:drawooo=\"http://openoffice.org/2010/draw\"\n" \
545
+ "xmlns:calcext=\"urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0\"\n" \
546
+ "xmlns:loext=\"urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0\"\n" \
547
+ "xmlns:field=\"urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0\"\n" \
548
+ "xmlns:formx=\"urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0\"\n" \
549
+ "xmlns:css3t=\"http://www.w3.org/TR/css3-text/\"\n" \
550
+ "office:version=\"1.2\">\n");
551
+
552
+ // Styles
553
+ d_string_append(out, style);
554
+
555
+ // Close
556
+ d_string_append(out, "\n</office:document-styles>");
557
+
558
+ // Cleanup
559
+ free(style);
560
+ char * result = out->str;
561
+ d_string_free(out, false);
562
+ return result;
563
+ }
564
+
565
+
566
+ /// Create full settings file for OpenDocument
567
+ char * opendocument_settings_file(int format) {
568
+ return my_strdup("<?xml version=\"1.0\" encoding=\"utf-8\"?> <office:document-settings xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\" xmlns:ooo=\"http://openoffice.org/2004/office\" office:version=\"1.2\"> <office:settings></office:settings></office:document-settings>");
569
+ }
570
+
571
+
572
+ #ifdef USE_CURL
573
+ // Dynamic buffer for downloading files in memory
574
+ // Based on https://curl.haxx.se/libcurl/c/getinmemory.html
575
+
576
+ struct MemoryStruct {
577
+ char * memory;
578
+ size_t size;
579
+ };
580
+
581
+
582
+ static size_t write_memory(void * contents, size_t size, size_t nmemb, void * userp) {
583
+ size_t realsize = size * nmemb;
584
+ struct MemoryStruct * mem = (struct MemoryStruct *)userp;
585
+
586
+ mem->memory = realloc(mem->memory, mem->size + realsize + 1);
587
+
588
+ if (mem->memory == NULL) {
589
+ // Out of memory
590
+ fprintf(stderr, "Out of memory\n");
591
+ return 0;
592
+ }
593
+
594
+ memcpy(&(mem->memory[mem->size]), contents, realsize);
595
+ mem->size += realsize;
596
+ mem->memory[mem->size] = 0;
597
+
598
+ return realsize;
599
+ }
600
+
601
+ // Add assets to zipfile using libcurl
602
+ static void add_assets(mz_zip_archive * pZip, mmd_engine * e, const char * directory) {
603
+ asset * a, * a_tmp;
604
+
605
+ if (e->asset_hash) {
606
+ CURL * curl;
607
+ CURLcode res;
608
+
609
+ struct MemoryStruct chunk;
610
+ chunk.memory = malloc(1);
611
+ chunk.size = 0;
612
+
613
+ char destination[100] = "Pictures/";
614
+ destination[45] = '\0';
615
+
616
+ mz_bool status;
617
+
618
+ curl_global_init(CURL_GLOBAL_ALL);
619
+ curl = curl_easy_init();
620
+
621
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_memory);
622
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
623
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
624
+
625
+ HASH_ITER(hh, e->asset_hash, a, a_tmp) {
626
+ curl_easy_setopt(curl, CURLOPT_URL, a->url);
627
+ res = curl_easy_perform(curl);
628
+
629
+ memcpy(&destination[9], a->asset_path, 36);
630
+
631
+ if (res != CURLE_OK) {
632
+ // Attempt to add asset from local file
633
+ if (!add_asset_from_file(pZip, a, destination, directory)) {
634
+ fprintf(stderr, "Unable to store '%s' in EPUB\n", a->url);
635
+ }
636
+ } else {
637
+ // Store downloaded file in zip
638
+ status = mz_zip_writer_add_mem(pZip, destination, chunk.memory, chunk.size, MZ_BEST_COMPRESSION);
639
+
640
+ if (!status) {
641
+ fprintf(stderr, "Error adding asset '%s' to zip as '%s'.\n", a->asset_path, destination);
642
+ }
643
+ }
644
+ }
645
+ }
646
+ }
647
+
648
+ #else
649
+ // Add local assets only (libcurl not available)
650
+ static void add_assets(mz_zip_archive * pZip, mmd_engine * e, const char * directory) {
651
+ asset * a, * a_tmp;
652
+
653
+ if (e->asset_hash) {
654
+
655
+ char destination[100] = "Pictures/";
656
+ destination[45] = '\0';
657
+
658
+ mz_bool status;
659
+
660
+ HASH_ITER(hh, e->asset_hash, a, a_tmp) {
661
+
662
+ memcpy(&destination[9], a->asset_path, 36);
663
+
664
+ // Attempt to add asset from local file
665
+ if (!add_asset_from_file(pZip, a, destination, directory)) {
666
+ fprintf(stderr, "Unable to store '%s' in EPUB\n", a->url);
667
+ }
668
+ }
669
+ }
670
+ }
671
+ #endif
672
+
673
+
674
+ /// Create manifest file for OpenDocument
675
+ char * opendocument_manifest_file(mmd_engine * e, int format) {
676
+ DString * out = d_string_new("");
677
+
678
+ char * style = opendocument_style(format);
679
+
680
+ // Open
681
+ print_const("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
682
+ print_const("<manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\" manifest:version=\"1.2\">\n");
683
+
684
+ // Files
685
+ switch (format) {
686
+ case FORMAT_ODT:
687
+ print_const("\t<manifest:file-entry manifest:full-path=\"/\" manifest:version=\"1.2\" manifest:media-type=\"application/vnd.oasis.opendocument.text\"/>\n");
688
+ break;
689
+ }
690
+
691
+ print_const("\t<manifest:file-entry manifest:full-path=\"content.xml\" manifest:media-type=\"text/xml\"/>\n");
692
+ print_const("\t<manifest:file-entry manifest:full-path=\"styles.xml\" manifest:media-type=\"text/xml\"/>\n");
693
+ print_const("\t<manifest:file-entry manifest:full-path=\"settings.xml\" manifest:media-type=\"text/xml\"/>\n");
694
+ print_const("\t<manifest:file-entry manifest:full-path=\"meta.xml\" manifest:media-type=\"text/xml\"/>\n");
695
+
696
+ // Add assets
697
+ if (e->asset_hash) {
698
+ asset * a, * a_tmp;
699
+
700
+ print_const("\t<manifest:file-entry manifest:full-path=\"Pictures/\" manifest:media-type=\"\"/>\n");
701
+
702
+ HASH_ITER(hh, e->asset_hash, a, a_tmp) {
703
+ printf("\t<manifest:file-entry manifest:full-path=\"Pictures/%s\" manifest:media-type=\"image/png\"/>\n", a->asset_path);
704
+ }
705
+ }
706
+
707
+ // Close
708
+ print_const("\n</manifest:manifest>");
709
+
710
+ // Cleanup
711
+ free(style);
712
+ char * result = out->str;
713
+ d_string_free(out, false);
714
+ return result;
715
+ }
716
+
717
+
718
+ /// Create common elements of an OpenDocument zip file
719
+ mz_zip_archive * opendocument_core_zip(mmd_engine * e, int format) {
720
+ // Initialize zip archive
721
+ mz_zip_archive * zip = malloc(sizeof(mz_zip_archive));
722
+ zip_new_archive(zip);
723
+
724
+ mz_bool status;
725
+ char * data;
726
+ size_t len;
727
+
728
+ scratch_pad * scratch = scratch_pad_new(e, format);
729
+
730
+
731
+ // Add mimetype
732
+ char mime[100];
733
+
734
+ switch (format) {
735
+ case FORMAT_ODT:
736
+ strcpy(mime, "application/vnd.oasis.opendocument.text");
737
+ break;
738
+ }
739
+
740
+ len = strlen(mime);
741
+ status = mz_zip_writer_add_mem(zip, "mimetype", mime, len, MZ_NO_COMPRESSION);
742
+
743
+ if (!status) {
744
+ fprintf(stderr, "Error adding mimetype to zip.\n");
745
+ }
746
+
747
+
748
+ // Create metadata file
749
+ data = opendocument_metadata_file(e, scratch);
750
+ len = strlen(data);
751
+ status = mz_zip_writer_add_mem(zip, "meta.xml", data, len, MZ_BEST_COMPRESSION);
752
+ free(data);
753
+
754
+ if (!status) {
755
+ fprintf(stderr, "Error adding metadata to zip.\n");
756
+ }
757
+
758
+
759
+ // Create styles file
760
+ data = opendocument_style_file(format);
761
+ len = strlen(data);
762
+ status = mz_zip_writer_add_mem(zip, "styles.xml", data, len, MZ_BEST_COMPRESSION);
763
+ free(data);
764
+
765
+ if (!status) {
766
+ fprintf(stderr, "Error adding styles to zip.\n");
767
+ }
768
+
769
+
770
+ // Create settings file
771
+ data = opendocument_settings_file(format);
772
+ len = strlen(data);
773
+ status = mz_zip_writer_add_mem(zip, "settings.xml", data, len, MZ_BEST_COMPRESSION);
774
+ free(data);
775
+
776
+ if (!status) {
777
+ fprintf(stderr, "Error adding settings to zip.\n");
778
+ }
779
+
780
+
781
+ // Create directories
782
+ status = mz_zip_writer_add_mem(zip, "META-INF/", NULL, 0, MZ_NO_COMPRESSION);
783
+
784
+ if (!status) {
785
+ fprintf(stderr, "Error adding directory to zip.\n");
786
+ }
787
+
788
+ status = mz_zip_writer_add_mem(zip, "Pictures/", NULL, 0, MZ_NO_COMPRESSION);
789
+
790
+ if (!status) {
791
+ fprintf(stderr, "Error adding directory to zip.\n");
792
+ }
793
+
794
+
795
+ // Create manifest file
796
+ data = opendocument_manifest_file(e, format);
797
+ len = strlen(data);
798
+ status = mz_zip_writer_add_mem(zip, "META-INF/manifest.xml", data, len, MZ_BEST_COMPRESSION);
799
+ free(data);
800
+
801
+ if (!status) {
802
+ fprintf(stderr, "Error adding manifest to zip.\n");
803
+ }
804
+
805
+
806
+ // Clean up
807
+ scratch_pad_free(scratch);
808
+
809
+ return zip;
810
+ }
811
+
812
+
813
+ /// Add shared office:document config
814
+ void opendocument_document_attr(DString * out) {
815
+ print_const("xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"\n" \
816
+ "xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\"\n" \
817
+ "xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\"\n" \
818
+ "xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\"\n" \
819
+ "xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\"\n" \
820
+ "xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\"\n" \
821
+ "xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" \
822
+ "xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" \
823
+ "xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"\n" \
824
+ "xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\"\n" \
825
+ "xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\"\n" \
826
+ "xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\"\n" \
827
+ "xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\"\n" \
828
+ "xmlns:math=\"http://www.w3.org/1998/Math/MathML\"\n" \
829
+ "xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\"\n" \
830
+ "xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\"\n" \
831
+ "xmlns:ooo=\"http://openoffice.org/2004/office\"\n" \
832
+ "xmlns:ooow=\"http://openoffice.org/2004/writer\"\n" \
833
+ "xmlns:oooc=\"http://openoffice.org/2004/calc\"\n" \
834
+ "xmlns:dom=\"http://www.w3.org/2001/xml-events\"\n" \
835
+ "xmlns:xforms=\"http://www.w3.org/2002/xforms\"\n" \
836
+ "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" \
837
+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" \
838
+ "xmlns:rpt=\"http://openoffice.org/2005/report\"\n" \
839
+ "xmlns:of=\"urn:oasis:names:tc:opendocument:xmlns:of:1.2\"\n" \
840
+ "xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"\n" \
841
+ "xmlns:grddl=\"http://www.w3.org/2003/g/data-view#\"\n" \
842
+ "xmlns:officeooo=\"http://openoffice.org/2009/office\"\n" \
843
+ "xmlns:tableooo=\"http://openoffice.org/2009/table\"\n" \
844
+ "xmlns:drawooo=\"http://openoffice.org/2010/draw\"\n" \
845
+ "xmlns:calcext=\"urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0\"\n" \
846
+ "xmlns:loext=\"urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0\"\n" \
847
+ "xmlns:field=\"urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0\"\n" \
848
+ "xmlns:formx=\"urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0\"\n" \
849
+ "xmlns:css3t=\"http://www.w3.org/TR/css3-text/\"\n" \
850
+ "office:version=\"1.2\"");
851
+ }
852
+
853
+
854
+ /// Create full content file
855
+ char * opendocument_content_file(const char * body, int format) {
856
+ DString * out = d_string_new("");
857
+
858
+ // Open
859
+ print_const("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
860
+ print_const("<office:document-content ");
861
+ opendocument_document_attr(out);
862
+ print_const(">\n<office:body>\n");
863
+
864
+ switch (format) {
865
+ case FORMAT_ODT:
866
+ print_const("<office:text>\n");
867
+ break;
868
+ }
869
+
870
+ // Body
871
+ d_string_append(out, body);
872
+
873
+ // Close
874
+ switch (format) {
875
+ case FORMAT_ODT:
876
+ print_const("\n</office:text>");
877
+ break;
878
+ }
879
+
880
+ d_string_append(out, "\n</office:body>\n</office:document-content>\n");
881
+
882
+ // Cleanup
883
+ char * result = out->str;
884
+ d_string_free(out, false);
885
+ return result;
886
+ }
887
+
888
+
889
+ /// Create OpenDocument text file
890
+ DString * opendocument_core_flat_create(const char * body, mmd_engine * e, int format) {
891
+ DString * out = d_string_new("");
892
+ char * text;
893
+
894
+ print_const("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
895
+ print_const("<office:document ");
896
+ opendocument_document_attr(out);
897
+
898
+ // Add mimetype
899
+ switch (format) {
900
+ case FORMAT_FODT:
901
+ print_const("\noffice:mimetype=\"application/vnd.oasis.opendocument.text\">\n");
902
+ break;
903
+ }
904
+
905
+ scratch_pad * scratch = scratch_pad_new(e, format);
906
+
907
+ // Add styles
908
+ text = opendocument_style(format);
909
+ d_string_append(out, text);
910
+ free(text);
911
+
912
+ // Add metadata
913
+ text = opendocument_metadata(e, scratch);
914
+ d_string_append(out, text);
915
+ free(text);
916
+
917
+
918
+ // Add body
919
+ print_const("\n<office:body>\n<office:text>\n");
920
+ d_string_append(out, body);
921
+ print_const("\n</office:text>\n</office:body>\n</office:document>\n");
922
+
923
+
924
+ // Cleanup
925
+ scratch_pad_free(scratch);
926
+
927
+ return out;
928
+ }
929
+
930
+
931
+ /// Create OpenDocument zip file version
932
+ DString * opendocument_core_file_create(const char * body, mmd_engine * e, const char * directory, int format) {
933
+ DString * result = d_string_new("");
934
+
935
+ // Add common core elements
936
+ mz_zip_archive * zip = opendocument_core_zip(e, format);
937
+
938
+ mz_bool status;
939
+ char * data;
940
+ size_t len;
941
+
942
+
943
+ // Create content file
944
+ data = opendocument_content_file(body, format);
945
+ len = strlen(data);
946
+ status = mz_zip_writer_add_mem(zip, "content.xml", data, len, MZ_BEST_COMPRESSION);
947
+ free(data);
948
+
949
+ if (!status) {
950
+ fprintf(stderr, "Error adding content.xml to zip.\n");
951
+ }
952
+
953
+
954
+ // Add image assets
955
+ add_assets(zip, e, directory);
956
+
957
+
958
+ // Clean up
959
+ free(result->str);
960
+
961
+ status = mz_zip_writer_finalize_heap_archive(zip, (void **) & (result->str), (size_t *) & (result->currentStringLength));
962
+
963
+ if (!status) {
964
+ fprintf(stderr, "Error finalizing zip archive.\n");
965
+ }
966
+
967
+ return result;
968
+ }
969
+
970
+
971
+ /// Create OpenDocument flat text file (single xml file)
972
+ DString * opendocument_flat_text_create(const char * body, mmd_engine * e, const char * directory) {
973
+ return opendocument_core_flat_create(body, e, FORMAT_FODT);
974
+ }
975
+
976
+
977
+ /// Create OpenDocument text file (zipped package)
978
+ DString * opendocument_text_create(const char * body, mmd_engine * e, const char * directory) {
979
+ return opendocument_core_file_create(body, e, directory, FORMAT_ODT);
980
+ }
981
+