all repos — hastyscribe @ 7bf9a351511cbb39a05d107306b5ab68636401d8

A professional markdown compiler.

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
import strutils

type 
  MMIOT* = int
  mkd_flag_t* = uint32

# line builder for markdown()
# 
{.push importc, cdecl.}
proc mkd_in*(a2: 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: 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: File; a4: cint; a5: cstring): cint
proc markdown*(a2: ptr MMIOT; a3: 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: 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: File): cint
proc mkd_generatetoc*(a2: ptr MMIOT; a3: File): cint
proc mkd_generatexml*(a2: cstring; a3: cint; a4: File): cint
proc mkd_generatecss*(a2: ptr MMIOT; a3: File): cint
const 
  mkd_style* = mkd_generatecss

proc mkd_generateline*(a2: cstring; a3: cint; a4: 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: File; a3: ptr MMIOT; a4: cint)
proc mkd_flags_are*(a2: File; 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 RootObj
  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

when defined(macosx):
  {.link: "vendor/libmarkdown_macosx_x86.a".}
when defined(windows):
  {.link: "vendor/libmarkdown_windows_x86.a".}
when defined(linux):
  when defined(arm):
    {.link: "vendor/libmarkdown_linux_arm.a".}
  when defined(i386) or defined(amd64):
    {.link: "vendor/libmarkdown_linux_x86.a".}