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 |
import strutils type MMIOT* = int mkd_flag_t* = uint32 # line builder for markdown() # {.push importc, cdecl.} proc mkd_in*(a2: TFile; 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: TFile; 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: TFile; a4: cint; a5: cstring): cint proc markdown*(a2: ptr MMIOT; a3: TFile; 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: TFile): 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: TFile): cint proc mkd_generatetoc*(a2: ptr MMIOT; a3: TFile): cint proc mkd_generatexml*(a2: cstring; a3: cint; a4: TFile): cint proc mkd_generatecss*(a2: ptr MMIOT; a3: TFile): cint const mkd_style* = mkd_generatecss proc mkd_generateline*(a2: cstring; a3: cint; a4: TFile; 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: TFile; a3: ptr MMIOT; a4: cint) proc mkd_flags_are*(a2: TFile; a3: mkd_flag_t; a4: cint) proc mkd_ref_prefix*(a2: ptr MMIOT; a3: cstring) # special flags for markdown() and mkd_text() # {.pop.} const MKD_NOLINKS* = 0x00000001 # don't do link processing, block <a> tags MKD_NOIMAGE* = 0x00000002 # don't do image processing, block <img> MKD_NOPANTS* = 0x00000004 # don't run smartypants() MKD_NOHTML* = 0x00000008 # don't allow raw html through AT ALL MKD_STRICT* = 0x00000010 # disable SUPERSCRIPT, RELAXED_EMPHASIS MKD_TAGTEXT* = 0x00000020 # process text inside an html tag; no # <em>, no <bold>, no html or [] expansion MKD_NO_EXT* = 0x00000040 # don't allow pseudo-protocols #MKD_NOEXT* = MKD_NO_EXT # ^^^ (aliased for user convenience) MKD_CDATA* = 0x00000080 # generate code for xml ![CDATA[...]] MKD_NOSUPERSCRIPT* = 0x00000100 # no A^B MKD_NORELAXED* = 0x00000200 # emphasis happens /everywhere/ MKD_NOTABLES* = 0x00000400 # disallow tables MKD_NOSTRIKETHROUGH* = 0x00000800 # forbid ~~strikethrough~~ MKD_DOTOC* = 0x00001000 # do table-of-contents processing MKD_1_COMPAT* = 0x00002000 # compatibility with MarkdownTest_1.0 MKD_AUTOLINK* = 0x00004000 # make http://foo.com link even without <>s MKD_SAFELINK* = 0x00008000 # paranoid check for link protocol MKD_NOHEADER* = 0x00010000 # don't process header blocks MKD_TABSTOP* = 0x00020000 # expand tabs to 4 spaces MKD_NODIVQUOTE* = 0x00040000 # forbid >%class% blocks MKD_NOALPHALIST* = 0x00080000 # forbid alphabetic lists MKD_NODLIST* = 0x00100000 # forbid definition lists MKD_EXTRA_FOOTNOTE* = 0x00200000 # enable markdown extra-style footnotes MKD_NOSTYLE* = 0x00400000 # don't extract <style> blocks MKD_EMBED* = MKD_NOLINKS or MKD_NOIMAGE or MKD_TAGTEXT # special flags for mkd_in() and mkd_string() type TMDMetaData* = object of TObject title*: string author*: string date*: string toc*: string proc md*(s: string, f = 0): string = var 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(f) # Check if metadata is present var lns = s.splitLines var valid_metadata = false var offset = 0 if (lns[0][0] == '%') and (lns[1][0] == '%') and (lns[2][0] == '%'): valid_metadata = true else: valid_metadata = false if lns[0][0] == '%': offset = 2 if lns[1][0] == '%': offset = 3 var str = cstring(lns[offset..lns.len-1].join("\n")) 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) if (int(flags) and MKD_DOTOC) == MKD_DOTOC: var toc = allocCStringArray([""]) discard $mkd_toc(mmiot, toc) try: data.toc = cstringArrayToSeq(toc)[0] except: data.toc = "" var res = allocCStringArray([""]) discard mkd_document(mmiot, res) result = cstringArrayToSeq(res)[0] mkd_cleanup(mmiot) return |