1 /**
2 
3 	MultiMarkdown 6 -- Lightweight markup processor to produce HTML, LaTeX, and more.
4 
5 	@file writer.h
6 
7 	@brief Coordinate conversion of token tree to output formats.
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 WRITER_MULTIMARKDOWN_H
57 #define WRITER_MULTIMARKDOWN_H
58 
59 #ifdef TEST
60 	#include "CuTest.h"
61 #endif
62 
63 #include "libMultiMarkdown.h"
64 #include "uthash.h"
65 
66 /*
67  #include "d_string.h"
68 #include "mmd.h"
69 #include "stack.h"
70 #include "token.h"
71 #include "uthash.h"
72 */
73 
74 #define kMaxExportRecursiveDepth 1000		//!< Maximum recursion depth when exporting token tree -- to prevent stack overflow with "pathologic" input
75 
76 #define kMaxTableColumns 48					//!< Maximum number of table columns for specifying alignment
77 
78 typedef struct asset asset;
79 typedef struct stack stack;
80 
81 typedef struct {
82 	struct link 	*	link_hash;
83 	struct meta 	*	meta_hash;
84 
85 	unsigned long		extensions;
86 	short				output_format;
87 	short				padded;			//!< How many empty lines at end output buffer
88 	short				list_is_tight;
89 	short				close_para;
90 	short				skip_token;
91 
92 	short				footnote_para_counter;
93 	stack 		*		used_footnotes;
94 	stack 		*		inline_footnotes_to_free;
95 	struct fn_holder *	footnote_hash;
96 	short				footnote_being_printed;
97 
98 	int 				random_seed_base;
99 
100 	int 				random_seed_base_labels;
101 	int 				label_counter;
102 
103 	stack 		*		used_citations;
104 	stack 		*		inline_citations_to_free;
105 	struct fn_holder *	citation_hash;
106 	short				citation_being_printed;
107 	char 		*		bibtex_file;
108 
109 	stack 		*		used_glossaries;
110 	stack 		*		inline_glossaries_to_free;
111 	struct fn_holder *	glossary_hash;
112 	short				glossary_being_printed;
113 
114 	stack 		*		used_abbreviations;
115 	stack 		*		inline_abbreviations_to_free;
116 	struct fn_holder *	abbreviation_hash;
117 
118 	short				language;
119 	short				quotes_lang;
120 
121 	short				base_header_level;
122 
123 	stack 		*		header_stack;
124 
125 	stack 		*		outline_stack;
126 	short				opml_item_closed;
127 
128 	short				recurse_depth;
129 
130 	short				in_table_header;
131 	short				table_column_count;
132 	short				table_cell_count;
133 	char 				table_alignment[kMaxTableColumns];
134 
135 	short				odf_para_type;
136 
137 	struct asset 	*	asset_hash;
138 	short				store_assets;
139 	short				remember_assets;
140 
141 	stack 		*		critic_stack;
142 } scratch_pad;
143 
144 
145 struct attr {
146 	char 		*		key;
147 	char 		*		value;
148 	struct attr 	*	next;
149 };
150 
151 typedef struct attr attr;
152 
153 struct link {
154 	token 		*		label;
155 	char  	*			label_text;
156 	char 		*		clean_text;
157 	char 		*		url;
158 	char 		*		title;
159 	attr 		*		attributes;
160 	short				flags;
161 	UT_hash_handle		hh;
162 };
163 
164 enum link_flags {
165 	LINK_INLINE       = 1 << 0,			//!< Inline link, e.g. [foo](#bar)
166 	LINK_IMPLICIT     = 1 << 1,			//!< Implicit link, e.g. [foo]
167 	LINK_REFERENCE    = 1 << 2,			//!< Reference definition
168 	LINK_AUTO         = 1 << 3, 		//!< Automatically generated link (e.g. Headers, tables)
169 };
170 
171 typedef struct link link;
172 
173 struct footnote {
174 	token 		*		label;
175 	char 		*		label_text;
176 	char 		*		clean_text;
177 	token 		*		content;
178 	size_t				count;
179 	bool				free_para;
180 
181 	char 				_PADDING[7];	//!< pad struct for alignment
182 };
183 
184 typedef struct footnote footnote;
185 
186 struct fn_holder {
187 	footnote 	*		note;
188 	UT_hash_handle		hh;
189 };
190 
191 typedef struct fn_holder fn_holder;
192 
193 struct meta {
194 	char 		*		key;
195 	char 		*		value;
196 	size_t				start;
197 	UT_hash_handle		hh;
198 };
199 
200 typedef struct meta meta;
201 
202 struct abbr {
203 	char 		*		abbr;
204 	size_t				abbr_len;
205 	char 		*		expansion;
206 	size_t				expansion_len;
207 	UT_hash_handle		hh;
208 };
209 
210 typedef struct abbr abbr;
211 
212 
213 /// Temporary storage while exporting parse tree to output format
214 scratch_pad * scratch_pad_new(mmd_engine * e, short format);
215 
216 void scratch_pad_free(scratch_pad * scratch);
217 
218 
219 /// Ensure at least num newlines at end of output buffer
220 void pad(DString * d, short num, scratch_pad * scratch);
221 
222 link * explicit_link(scratch_pad * scratch, token * label, token * url, const char * source);
223 
224 /// Find link based on label
225 link * extract_link_from_stack(scratch_pad * scratch, const char * target);
226 
227 char * text_inside_pair(const char * source, token * pair);
228 char * clean_inside_pair(const char * source, token * t, bool lowercase);
229 
230 void link_free(link * l);
231 void footnote_free(footnote * f);
232 
233 char * label_from_token(const char * source, token * t);
234 char * label_from_header(const char * source, token * t, scratch_pad * scratch);
235 
236 void parse_brackets(const char * source, scratch_pad * scratch, token * bracket, link ** link, short * skip_token, bool * free_link);
237 
238 
239 void print_token_raw(DString * out, const char * source, token * t);
240 
241 void print_token_tree_raw(DString * out, const char * source, token * t);
242 
243 char * url_accept(const char * source, size_t start, size_t max_len, size_t * end_pos, bool validate);
244 
245 void abbreviation_from_bracket(const char * source, scratch_pad * scratch, token * t, short * num);
246 void citation_from_bracket(const char * source, scratch_pad * scratch, token * t, short * num);
247 void footnote_from_bracket(const char * source, scratch_pad * scratch, token * t, short * num);
248 void glossary_from_bracket(const char * source, scratch_pad * scratch, token * t, short * num);
249 
250 meta * meta_new(const char * source, size_t start, size_t len);
251 void meta_set_value(meta * m, const char * value);
252 void meta_free(meta * m);
253 char * extract_metadata(scratch_pad * scratch, const char * target);
254 meta * extract_meta_from_stack(scratch_pad * scratch, const char * target);
255 
256 void read_table_column_alignments(const char * source, token * table, scratch_pad * scratch);
257 
258 void strip_leading_whitespace(token * chain, const char * source);
259 
260 void trim_trailing_whitespace_d_string(DString * d);
261 
262 bool table_has_caption(token * table);
263 
264 char * get_fence_language_specifier(token * fence, const char * source);
265 
266 token * manual_label_from_header(token * h, const char * source);
267 
268 char * label_from_string(const char * str);
269 
270 char * clean_string(const char * str, bool lowercase);
271 
272 short raw_level_for_header(token * header);
273 
274 void store_asset(scratch_pad * scratch_pad, char * url);
275 asset * extract_asset(scratch_pad * scratch, char * url);
276 void asset_free(asset * a);
277 
278 bool raw_filter_text_matches(char * pattern, short format);
279 bool raw_filter_matches(token * filter, const char * source, short format);
280 
281 
282 #endif
283 
284