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,101 @@
1
+ /**
2
+
3
+ MultiMarkdown 6 -- Lightweight markup processor to produce HTML, LaTeX, and more.
4
+
5
+ @file scanners.h
6
+
7
+ @brief After text has been tokenized, there are still some constructs that are best
8
+ interpreted using regular expressions.
9
+
10
+
11
+ @author Fletcher T. Penney
12
+ @bug
13
+
14
+ **/
15
+
16
+ /*
17
+
18
+ Copyright © 2016 - 2017 Fletcher T. Penney.
19
+
20
+
21
+ The `MultiMarkdown 6` project is released under the MIT License..
22
+
23
+ GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project:
24
+
25
+ https://github.com/fletcher/MultiMarkdown-4/
26
+
27
+ MMD 4 is released under both the MIT License and GPL.
28
+
29
+
30
+ CuTest is released under the zlib/libpng license. See CuTest.c for the text
31
+ of the license.
32
+
33
+
34
+ ## The MIT License ##
35
+
36
+ Permission is hereby granted, free of charge, to any person obtaining a copy
37
+ of this software and associated documentation files (the "Software"), to deal
38
+ in the Software without restriction, including without limitation the rights
39
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
40
+ copies of the Software, and to permit persons to whom the Software is
41
+ furnished to do so, subject to the following conditions:
42
+
43
+ The above copyright notice and this permission notice shall be included in
44
+ all copies or substantial portions of the Software.
45
+
46
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
51
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
52
+ THE SOFTWARE.
53
+
54
+ */
55
+
56
+
57
+ #ifndef SCANNERS_MULTIMARKDOWN_H
58
+ #define SCANNERS_MULTIMARKDOWN_H
59
+
60
+ #ifdef TEST
61
+ #include "CuTest.h"
62
+ #endif
63
+
64
+ enum alignments {
65
+ ALIGN_LEFT = 1 << 0,
66
+ ALIGN_RIGHT = 1 << 1,
67
+ ALIGN_CENTER = 1 << 2,
68
+ ALIGN_WRAP = 1 << 3
69
+ };
70
+
71
+
72
+ size_t scan_alignment_string(const char * c);
73
+ size_t scan_attr(const char * c);
74
+ size_t scan_attributes(const char * c);
75
+ size_t scan_atx(const char * c);
76
+ size_t scan_definition(const char * c);
77
+ size_t scan_destination(const char * c);
78
+ size_t scan_email(const char * c);
79
+ size_t scan_fence_start(const char * c);
80
+ size_t scan_fence_end(const char * c);
81
+ size_t scan_html(const char * c);
82
+ size_t scan_html_block(const char * c);
83
+ size_t scan_html_comment(const char * c);
84
+ size_t scan_html_line(const char * c);
85
+ size_t scan_key(const char * c);
86
+ size_t scan_meta_key(const char * c);
87
+ size_t scan_meta_line(const char * c);
88
+ size_t scan_ref_abbreviation(const char * c);
89
+ size_t scan_ref_citation(const char * c);
90
+ size_t scan_ref_foot(const char * c);
91
+ size_t scan_ref_glossary(const char * c);
92
+ size_t scan_ref_link(const char * c);
93
+ size_t scan_ref_link_no_attributes(const char * c);
94
+ size_t scan_setext(const char * c);
95
+ size_t scan_spnl(const char * c);
96
+ size_t scan_table_separator(const char * c);
97
+ size_t scan_title(const char * c);
98
+ size_t scan_url(const char * c);
99
+ size_t scan_value(const char * c);
100
+
101
+ #endif
data/ext/mmd/stack.c ADDED
@@ -0,0 +1,142 @@
1
+ /**
2
+
3
+ MultiMarkdown 6 -- Lightweight markup processor to produce HTML, LaTeX, and more.
4
+
5
+ @file stack.c
6
+
7
+ @brief Create a dynamic array that stores pointers in a LIFO order.
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 text
30
+ of the license.
31
+
32
+
33
+ ## The MIT License ##
34
+
35
+ Permission is hereby granted, free of charge, to any person obtaining a copy
36
+ of this software and associated documentation files (the "Software"), to deal
37
+ in the Software without restriction, including without limitation the rights
38
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39
+ copies of the Software, and to permit persons to whom the Software is
40
+ furnished to do so, subject to the following conditions:
41
+
42
+ The above copyright notice and this permission notice shall be included in
43
+ all copies or substantial portions of the Software.
44
+
45
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51
+ THE SOFTWARE.
52
+
53
+ */
54
+
55
+ #include <stdlib.h>
56
+ #include <string.h>
57
+
58
+ #include "stack.h"
59
+
60
+ #define kStackStartingSize 64
61
+
62
+
63
+ /// Create a new stack with dynamic storage with an
64
+ /// initial capacity (0 to use default capacity)
65
+ stack * stack_new(int startingSize) {
66
+ stack * s = malloc(sizeof(stack));
67
+
68
+ if (s) {
69
+ if (startingSize <= 0) {
70
+ startingSize = kStackStartingSize;
71
+ }
72
+
73
+ s->element = malloc(sizeof(void *) * startingSize);
74
+
75
+ if (!s->element) {
76
+ free(s);
77
+ return NULL;
78
+ }
79
+
80
+ s->size = 0;
81
+ s->capacity = startingSize;
82
+ }
83
+
84
+ return s;
85
+ }
86
+
87
+
88
+ /// Free the stack
89
+ void stack_free(stack * s) {
90
+ free(s->element);
91
+ free(s);
92
+ }
93
+
94
+
95
+ /// Add a new pointer to the stack
96
+ void stack_push(stack * s, void * element) {
97
+ if (s->size == s->capacity) {
98
+ s->capacity *= 2;
99
+ s->element = realloc(s->element, s->capacity * sizeof(void *));
100
+ }
101
+
102
+ s->element[s->size++] = element;
103
+ }
104
+
105
+
106
+ /// Pop the top item off the stack
107
+ void * stack_pop(stack * s) {
108
+ void * last = stack_peek(s);
109
+
110
+ if (s->size != 0) {
111
+ s->size--;
112
+ }
113
+
114
+ return last;
115
+ }
116
+
117
+
118
+ /// Peek at the top item on the stack
119
+ void * stack_peek(stack * s) {
120
+ if (s->size == 0) {
121
+ return NULL;
122
+ }
123
+
124
+ return s->element[(s->size) - 1];
125
+ }
126
+
127
+
128
+ /// Peek at a specific index in the stack
129
+ void * stack_peek_index(stack * s, size_t index) {
130
+ if (index >= s->size) {
131
+ return NULL;
132
+ }
133
+
134
+ return s->element[index];
135
+ }
136
+
137
+
138
+ /// Sort array using specified compare_function
139
+ void stack_sort(stack * s, void * compare_function) {
140
+ qsort(s->element, s->size, sizeof(void *), compare_function);
141
+ }
142
+
data/ext/mmd/stack.h ADDED
@@ -0,0 +1,113 @@
1
+ /**
2
+
3
+ MultiMarkdown 6 -- Lightweight markup processor to produce HTML, LaTeX, and more.
4
+
5
+ @file stack.h
6
+
7
+ @brief Create a dynamic array that stores pointers in a LIFO order.
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 text
30
+ of the license.
31
+
32
+
33
+ ## The MIT License ##
34
+
35
+ Permission is hereby granted, free of charge, to any person obtaining a copy
36
+ of this software and associated documentation files (the "Software"), to deal
37
+ in the Software without restriction, including without limitation the rights
38
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39
+ copies of the Software, and to permit persons to whom the Software is
40
+ furnished to do so, subject to the following conditions:
41
+
42
+ The above copyright notice and this permission notice shall be included in
43
+ all copies or substantial portions of the Software.
44
+
45
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51
+ THE SOFTWARE.
52
+
53
+ */
54
+
55
+
56
+ #ifndef STACK_SMART_STRING_H
57
+ #define STACK_SMART_STRING_H
58
+
59
+ #include <stdlib.h>
60
+
61
+ /// Structure for a stack
62
+ struct stack {
63
+ size_t size; //!< Number of objects currently in stack
64
+ size_t capacity; //!< Total current capacity for stack
65
+ void ** element; //!< Array of pointers to objects in stack
66
+ };
67
+
68
+ typedef struct stack stack;
69
+
70
+
71
+ /// Create a new stack with dynamic storage with an
72
+ /// initial capacity (0 to use default capacity)
73
+ stack * stack_new(
74
+ int startingSize //!< Default capacity for stack
75
+ );
76
+
77
+
78
+ /// Free the stack
79
+ void stack_free(
80
+ stack * s //!< Stack to be freed
81
+ );
82
+
83
+
84
+ /// Add a new pointer to the stack
85
+ void stack_push(
86
+ stack * s, //!< Stack to use
87
+ void * element //!< Pointer to push onto stack
88
+ );
89
+
90
+
91
+ /// Pop the top pointer off the stack and return it
92
+ void * stack_pop(
93
+ stack * s //!< Stack to examine
94
+ );
95
+
96
+
97
+ /// Peek at the top pointer on the stack (but don't remove it from stack)
98
+ void * stack_peek(
99
+ stack * s //!< Stack to examine
100
+ );
101
+
102
+
103
+ /// Peek at a specific index in the stack
104
+ void * stack_peek_index(
105
+ stack * s, //!< Stack to examine
106
+ size_t index //!< Index to peek at (0 is first pointer on stack)
107
+ );
108
+
109
+
110
+ /// Sort stack based on sort_function
111
+ void stack_sort(stack * s, void * compare_function);
112
+
113
+ #endif
@@ -0,0 +1,455 @@
1
+ /**
2
+
3
+ MultiMarkdown -- Lightweight markup processor to produce HTML, LaTeX, and more.
4
+
5
+ @file textbundle.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
+ #include <stdio.h>
105
+ #include <stdlib.h>
106
+ #include <sys/stat.h>
107
+
108
+ #ifdef USE_CURL
109
+ #include <curl/curl.h>
110
+ #endif
111
+
112
+ #include "textbundle.h"
113
+ #include "miniz.h"
114
+ #include "transclude.h"
115
+ #include "writer.h"
116
+ #include "zip.h"
117
+
118
+
119
+ char * textbundle_info_json(void) {
120
+ DString * info = d_string_new("");
121
+
122
+ d_string_append(info, "{\n");
123
+ d_string_append(info, "\t\"version\": 2,\n");
124
+ d_string_append(info, "\t\"type\": \"net.daringfireball.markdown\",\n");
125
+ d_string_append(info, "\t\"transient\": false,\n");
126
+ d_string_append(info, "\t\"creatorIdentifier\": \"net.multimarkdown\"\n");
127
+ d_string_append(info, "}");
128
+
129
+ char * result = info->str;
130
+ d_string_free(info, false);
131
+ return result;
132
+ }
133
+
134
+
135
+ static bool add_asset_from_file(mz_zip_archive * pZip, asset * a, const char * destination, const char * directory) {
136
+ if (!directory) {
137
+ return false;
138
+ }
139
+
140
+ char * path = path_from_dir_base(directory, a->url);
141
+ mz_bool status;
142
+ bool result = false;
143
+
144
+ DString * buffer = scan_file(path);
145
+
146
+ if (buffer && buffer->currentStringLength > 0) {
147
+ status = mz_zip_writer_add_mem(pZip, destination, buffer->str, buffer->currentStringLength, MZ_BEST_COMPRESSION);
148
+
149
+ if (!status) {
150
+ fprintf(stderr, "Error adding asset '%s' to zip.\n", destination);
151
+ }
152
+
153
+ d_string_free(buffer, true);
154
+ result = true;
155
+ }
156
+
157
+ free(path);
158
+
159
+ return result;
160
+ }
161
+
162
+
163
+ #ifdef USE_CURL
164
+ // Dynamic buffer for downloading files in memory
165
+ // Based on https://curl.haxx.se/libcurl/c/getinmemory.html
166
+
167
+ struct MemoryStruct {
168
+ char * memory;
169
+ size_t size;
170
+ };
171
+
172
+
173
+ static size_t write_memory(void * contents, size_t size, size_t nmemb, void * userp) {
174
+ size_t realsize = size * nmemb;
175
+ struct MemoryStruct * mem = (struct MemoryStruct *)userp;
176
+
177
+ mem->memory = realloc(mem->memory, mem->size + realsize + 1);
178
+
179
+ if (mem->memory == NULL) {
180
+ // Out of memory
181
+ fprintf(stderr, "Out of memory\n");
182
+ return 0;
183
+ }
184
+
185
+ memcpy(&(mem->memory[mem->size]), contents, realsize);
186
+ mem->size += realsize;
187
+ mem->memory[mem->size] = 0;
188
+
189
+ return realsize;
190
+ }
191
+
192
+ // Add assets to zipfile using libcurl
193
+ static void add_assets(mz_zip_archive * pZip, mmd_engine * e, const char * directory) {
194
+ asset * a, * a_tmp;
195
+
196
+ if (e->asset_hash) {
197
+ CURL * curl;
198
+ CURLcode res;
199
+
200
+ struct MemoryStruct chunk;
201
+ chunk.memory = malloc(1);
202
+ chunk.size = 0;
203
+
204
+ char destination[100] = "assets/";
205
+ destination[43] = '\0';
206
+
207
+ mz_bool status;
208
+
209
+ curl_global_init(CURL_GLOBAL_ALL);
210
+ curl = curl_easy_init();
211
+
212
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_memory);
213
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
214
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
215
+
216
+ HASH_ITER(hh, e->asset_hash, a, a_tmp) {
217
+ curl_easy_setopt(curl, CURLOPT_URL, a->url);
218
+ res = curl_easy_perform(curl);
219
+
220
+ memcpy(&destination[7], a->asset_path, 36);
221
+
222
+ if (res != CURLE_OK) {
223
+ // Attempt to add asset from local file
224
+ if (!add_asset_from_file(pZip, a, destination, directory)) {
225
+ fprintf(stderr, "Unable to store '%s' in EPUB\n", a->url);
226
+ }
227
+ } else {
228
+ // Store downloaded file in zip
229
+ status = mz_zip_writer_add_mem(pZip, destination, chunk.memory, chunk.size, MZ_BEST_COMPRESSION);
230
+
231
+ if (!status) {
232
+ fprintf(stderr, "Error adding asset '%s' to zip as '%s'.\n", a->asset_path, destination);
233
+ }
234
+ }
235
+ }
236
+ }
237
+ }
238
+
239
+ #else
240
+ // Add local assets only (libcurl not available)
241
+ static void add_assets(mz_zip_archive * pZip, mmd_engine * e, const char * directory) {
242
+ asset * a, * a_tmp;
243
+
244
+ if (e->asset_hash) {
245
+
246
+ char destination[100] = "assets/";
247
+ destination[43] = '\0';
248
+
249
+ mz_bool status;
250
+
251
+ HASH_ITER(hh, e->asset_hash, a, a_tmp) {
252
+
253
+ memcpy(&destination[7], a->asset_path, 36);
254
+
255
+ // Attempt to add asset from local file
256
+ if (!add_asset_from_file(pZip, a, destination, directory)) {
257
+ fprintf(stderr, "Unable to store '%s' in EPUB\n", a->url);
258
+ }
259
+ }
260
+ }
261
+ }
262
+ #endif
263
+
264
+
265
+ void traverse_for_images(token * t, DString * text, mmd_engine * e, long * offset, char * destination, char * url) {
266
+ asset * a;
267
+ char * clean;
268
+ link * l;
269
+
270
+ while (t) {
271
+ switch (t->type) {
272
+ case PAIR_BRACKET_IMAGE:
273
+ if (t->next && t->next->type == PAIR_PAREN) {
274
+ t = t->next;
275
+
276
+ memcpy(url, &text->str[t->start + *offset + 1], t->len - 2);
277
+ url[t->len - 2] = '\0';
278
+ clean = clean_string(url, false);
279
+
280
+ HASH_FIND_STR(e->asset_hash, clean, a);
281
+
282
+ if (a) {
283
+ // Replace url with asset path
284
+ memcpy(&destination[7], a->asset_path, 36);
285
+ * offset += d_string_replace_text_in_range(text, t->start + *offset, t->len, clean, destination);
286
+ }
287
+
288
+ free(clean);
289
+ }
290
+
291
+ break;
292
+
293
+ case BLOCK_EMPTY:
294
+
295
+ // Is this a link definition?
296
+ for (int i = 0; i < e->definition_stack->size; ++i) {
297
+ if (t == stack_peek_index(e->definition_stack, i)) {
298
+ // Find matching link
299
+ for (int j = 0; j < e->link_stack->size; ++j) {
300
+ l = stack_peek_index(e->link_stack, j);
301
+
302
+ if (l->label->start == t->child->start) {
303
+ // This is a match
304
+ HASH_FIND_STR(e->asset_hash, l->url, a);
305
+
306
+ if (a) {
307
+ memcpy(&destination[7], a->asset_path, 36);
308
+ * offset += d_string_replace_text_in_range(text, t->start + *offset, t->len, l->url, destination);
309
+ }
310
+ }
311
+ }
312
+ }
313
+ }
314
+
315
+ break;
316
+
317
+ default:
318
+ if (t->child) {
319
+ traverse_for_images(t->child, text, e, offset, destination, url);
320
+ }
321
+
322
+ break;
323
+ }
324
+
325
+ t = t->next;
326
+ }
327
+ }
328
+
329
+
330
+ void sub_asset_paths(DString * text, mmd_engine * e) {
331
+ long offset = 0;
332
+ asset * a;
333
+ token * t = e->root->child;
334
+
335
+ char destination[100] = "assets/";
336
+ destination[43] = '\0';
337
+
338
+ // Is there CSS metadata?
339
+ if (e->metadata_stack) {
340
+ if (e->metadata_stack->size > 0) {
341
+ meta * m;
342
+
343
+ for (int i = 0; i < e->metadata_stack->size; ++i) {
344
+ m = stack_peek_index(e->metadata_stack, i);
345
+
346
+ if (strcmp("css", m->key) == 0) {
347
+ // Get METADATA range
348
+ t = e->root->child;
349
+ token_skip_until_type(&t, BLOCK_META);
350
+
351
+ // Substitute inside metadata block
352
+ HASH_FIND_STR(e->asset_hash, m->value, a);
353
+
354
+ if (a) {
355
+ memcpy(&destination[7], a->asset_path, 36);
356
+ offset += d_string_replace_text_in_range(text, t->start, t->len, m->value, destination);
357
+ }
358
+ }
359
+ }
360
+ }
361
+ }
362
+
363
+
364
+ // Find images
365
+ char url[1000] = "";
366
+
367
+ // Travel parse tree for images and image reference definitions
368
+ traverse_for_images(t, text, e, &offset, &destination[0], &url[0]);
369
+ }
370
+
371
+
372
+ DString * textbundle_create(const char * body, mmd_engine * e, const char * directory) {
373
+ DString * result = d_string_new("");
374
+ scratch_pad * scratch = scratch_pad_new(e, FORMAT_TEXTBUNDLE_COMPRESSED);
375
+
376
+ mz_bool status;
377
+ char * data;
378
+ size_t len;
379
+
380
+ mz_zip_archive zip;
381
+ zip_new_archive(&zip);
382
+
383
+
384
+ // Add info json
385
+ data = textbundle_info_json();
386
+ len = strlen(data);
387
+ status = mz_zip_writer_add_mem(&zip, "info.json", data, len, MZ_BEST_COMPRESSION);
388
+ free(data);
389
+
390
+ if (!status) {
391
+ fprintf(stderr, "Error adding JSON info to zip.\n");
392
+ }
393
+
394
+ // Create directories
395
+ status = mz_zip_writer_add_mem(&zip, "assets/", NULL, 0, MZ_NO_COMPRESSION);
396
+
397
+ if (!status) {
398
+ fprintf(stderr, "Error adding assets directory to zip.\n");
399
+ }
400
+
401
+ // Add main document
402
+ DString * temp = d_string_new(e->dstr->str);
403
+
404
+ sub_asset_paths(temp, e);
405
+
406
+ len = temp->currentStringLength;
407
+ status = mz_zip_writer_add_mem(&zip, "text.markdown", temp->str, len, MZ_BEST_COMPRESSION);
408
+
409
+ if (!status) {
410
+ fprintf(stderr, "Error adding content to zip.\n");
411
+ }
412
+
413
+ // Add html version document
414
+ len = strlen(body);
415
+ status = mz_zip_writer_add_mem(&zip, "text.html", body, len, MZ_BEST_COMPRESSION);
416
+
417
+ if (!status) {
418
+ fprintf(stderr, "Error adding content to zip.\n");
419
+ }
420
+
421
+ // Add assets
422
+ add_assets(&zip, e, directory);
423
+
424
+ scratch_pad_free(scratch);
425
+
426
+ // Finalize zip archive and extract data
427
+ free(result->str);
428
+
429
+ status = mz_zip_writer_finalize_heap_archive(&zip, (void **) & (result->str), (size_t *) & (result->currentStringLength));
430
+
431
+ if (!status) {
432
+ fprintf(stderr, "Error finalizing zip.\n");
433
+ }
434
+
435
+ return result;
436
+ }
437
+
438
+
439
+
440
+ // Use the miniz library to create a zip archive for the TEXTBUNDLE_COMPRESSED document
441
+ void textbundle_write_wrapper(const char * filepath, const char * body, mmd_engine * e, const char * directory) {
442
+ FILE * output_stream;
443
+
444
+ DString * result = textbundle_create(body, e, directory);
445
+
446
+ if (!(output_stream = fopen(filepath, "w"))) {
447
+ // Failed to open file
448
+ perror(filepath);
449
+ } else {
450
+ fwrite(&(result->str), result->currentStringLength, 1, output_stream);
451
+ fclose(output_stream);
452
+ }
453
+
454
+ d_string_free(result, true);
455
+ }