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