src/hastyscribepkg/markdown.nim
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
const MKDIO_D* = true type MMIOT* = int mkd_flag_t* = cuint {.push importc, cdecl.} # line builder for markdown() # proc mkd_in*(a2: ptr FILE; a3: mkd_flag_t): ptr MMIOT # assemble input from a file proc mkd_string*(a2: cstring; a3: cint; a4: mkd_flag_t): ptr MMIOT # assemble input from a buffer # line builder for github flavoured markdown # proc gfm_in*(a2: ptr FILE; a3: mkd_flag_t): ptr MMIOT # assemble input from a file proc gfm_string*(a2: cstring; a3: cint; a4: mkd_flag_t): ptr MMIOT # assemble input from a buffer proc mkd_basename*(a2: ptr MMIOT; a3: cstring) proc mkd_initialize*() proc mkd_with_html5_tags*() proc mkd_shlib_destructor*() # compilation, debugging, cleanup # proc mkd_compile*(a2: ptr MMIOT; a3: mkd_flag_t): cint proc mkd_cleanup*(a2: ptr MMIOT) # markup functions # proc mkd_dump*(a2: ptr MMIOT; a3: ptr FILE; a4: cint; a5: cstring): cint proc markdown*(a2: ptr MMIOT; a3: ptr FILE; a4: mkd_flag_t): cint proc mkd_line*(a2: cstring; a3: cint; a4: cstringArray; a5: mkd_flag_t): cint type mkd_sta_function_t* = proc (a2: cint; a3: pointer): cint proc mkd_string_to_anchor*(a2: cstring; a3: cint; a4: mkd_sta_function_t; a5: pointer; a6: cint) proc mkd_xhtmlpage*(a2: ptr MMIOT; a3: cint; a4: ptr FILE): cint # header block access # proc mkd_doc_title*(a2: ptr MMIOT): cstring proc mkd_doc_author*(a2: ptr MMIOT): cstring proc mkd_doc_date*(a2: ptr MMIOT): cstring # compiled data access # proc mkd_document*(a2: ptr MMIOT; a3: cstringArray): cint proc mkd_toc*(a2: ptr MMIOT; a3: cstringArray): cint proc mkd_css*(a2: ptr MMIOT; a3: cstringArray): cint proc mkd_xml*(a2: cstring; a3: cint; a4: cstringArray): cint # write-to-file functions # proc mkd_generatehtml*(a2: ptr MMIOT; a3: ptr FILE): cint proc mkd_generatetoc*(a2: ptr MMIOT; a3: ptr FILE): cint proc mkd_generatexml*(a2: cstring; a3: cint; a4: ptr FILE): cint proc mkd_generatecss*(a2: ptr MMIOT; a3: ptr FILE): cint const mkd_style* = mkd_generatecss proc mkd_generateline*(a2: cstring; a3: cint; a4: ptr FILE; a5: mkd_flag_t): cint const mkd_text* = mkd_generateline # url generator callbacks # type mkd_callback_t* = proc (a2: cstring; a3: cint; a4: pointer): cstring mkd_free_t* = proc (a2: cstring; a3: pointer) proc mkd_e_url*(a2: pointer; a3: mkd_callback_t) proc mkd_e_flags*(a2: pointer; a3: mkd_callback_t) proc mkd_e_free*(a2: pointer; a3: mkd_free_t) proc mkd_e_data*(a2: pointer; a3: pointer) # version#. # var markdown_version*: ptr char proc mkd_mmiot_flags*(a2: ptr FILE; a3: ptr MMIOT; a4: cint) proc mkd_flags_are*(a2: ptr FILE; a3: mkd_flag_t; a4: cint) proc mkd_ref_prefix*(a2: ptr MMIOT; a3: cstring) {.pop.} # special flags for markdown() and mkd_text() # const MKD_NOLINKS* = 0x00000001 MKD_NOIMAGE* = 0x00000002 MKD_NOPANTS* = 0x00000004 MKD_NOHTML* = 0x00000008 MKD_STRICT* = 0x00000010 MKD_TAGTEXT* = 0x00000020 MKD_NO_EXT* = 0x00000040 MKD_CDATA* = 0x00000080 MKD_NOSUPERSCRIPT* = 0x00000100 MKD_NORELAXED* = 0x00000200 MKD_NOTABLES* = 0x00000400 MKD_NOSTRIKETHROUGH* = 0x00000800 MKD_TOC* = 0x00001000 MKD_1_COMPAT* = 0x00002000 MKD_AUTOLINK* = 0x00004000 MKD_SAFELINK* = 0x00008000 MKD_NOHEADER* = 0x00010000 MKD_TABSTOP* = 0x00020000 MKD_NODIVQUOTE* = 0x00040000 MKD_NOALPHALIST* = 0x00080000 MKD_NODLIST* = 0x00100000 MKD_EXTRA_FOOTNOTE* = 0x00200000 MKD_NOSTYLE* = 0x00400000 MKD_NODLDISCOUNT* = 0x00800000 MKD_DLEXTRA* = 0x01000000 MKD_FENCEDCODE* = 0x02000000 MKD_IDANCHOR* = 0x04000000 MKD_GITHUBTAGS* = 0x08000000 MKD_URLENCODEDANCHOR* = 0x10000000 MKD_HTML5ANCHOR* = 0x10000000 MKD_LATEX* = 0x40000000 MKD_EMBED* = MKD_NOLINKS or MKD_NOIMAGE or MKD_TAGTEXT ## High Level API import strutils, pegs const DefaultFlags = MKD_TOC or MKD_1_COMPAT or MKD_EXTRA_FOOTNOTE or MKD_DLEXTRA or MKD_FENCEDCODE or MKD_GITHUBTAGS or MKD_HTML5ANCHOR or MKD_LATEX type TMDMetaData* = object title*: string author*: string date*: string toc*: string css*: string proc md*(s: string, f = 0): string = var flags: uint32 if (f == 0): flags = DefaultFlags else: flags = uint32(f) var str = cstring(s&" ") var mmiot = mkd_string(str, cint(str.len-1), flags) discard mkd_compile(mmiot, flags) var res = allocCStringArray([""]) discard mkd_document(mmiot, res) result = cstringArrayToSeq(res)[0] mkd_cleanup(mmiot) return proc md*(s: string, f = 0, data: var TMDMetadata): string = var flags: uint32 if (f == 0): flags = DefaultFlags else: flags = uint32(f) # Check if Pandoc style metadata is present var valid_metadata = false var contents = s let peg_pandoc = peg""" definition <- ^{line} {line}? {line}? line <- '\%' @ \n """ var matches: array[0..2, string] let (s, e) = contents.findBounds(peg_pandoc, matches) # the pattern must start at the beginning of the file if s == 0: if matches[0] != "" and matches[1] != "" and matches[2] != "": valid_metadata = true else: # incomplete metadata, remove the whole pandoc section to not confuse discount contents = contents[e-1 .. ^1] var str = cstring(contents) var mmiot = mkd_string(str, cint(str.len-1), flags) if valid_metadata: data.title = $mkd_doc_title(mmiot) data.author = $mkd_doc_author(mmiot) data.date = $mkd_doc_date(mmiot) discard mkd_compile(mmiot, flags) # Process TOC if (int(flags) and MKD_TOC) == MKD_TOC: var toc = allocCStringArray(@[""]) if mkd_toc(mmiot, toc) > 0: data.toc = cstringArrayToSeq(toc)[0] else: data.toc = "" # Process CSS var css = allocCStringArray(newSeq[string](10)) if mkd_css(mmiot, css) > 0: data.css = cstringArrayToSeq(css)[0] else: data.css = "" # Generate HTML var res = allocCStringArray([""]) if mkd_document(mmiot, res) > 0: result = cstringArrayToSeq(res)[0] else: result = "" mkd_cleanup(mmiot) |