cmark

My personal build of CMark ✏️

cmark.py (2305B)

 1 #!/usr/bin/env python3
 2 # -*- coding: utf-8 -*-
 3 
 4 from ctypes import CDLL, c_char_p, c_size_t, c_int, c_void_p
 5 from subprocess import *
 6 import platform
 7 import os
 8 
 9 def pipe_through_prog(prog, text):
10     p1 = Popen(prog.split(), stdout=PIPE, stdin=PIPE, stderr=PIPE)
11     [result, err] = p1.communicate(input=text.encode('utf-8'))
12     return [p1.returncode, result.decode('utf-8'), err]
13 
14 def to_html(lib, text):
15     markdown = lib.cmark_markdown_to_html
16     markdown.restype = c_char_p
17     markdown.argtypes = [c_char_p, c_size_t, c_int]
18     textbytes = text.encode('utf-8')
19     textlen = len(textbytes)
20     # 1 << 17 == CMARK_OPT_UNSAFE
21     result = markdown(textbytes, textlen, 1 << 17).decode('utf-8')
22     return [0, result, '']
23 
24 def to_commonmark(lib, text):
25     textbytes = text.encode('utf-8')
26     textlen = len(textbytes)
27     parse_document = lib.cmark_parse_document
28     parse_document.restype = c_void_p
29     parse_document.argtypes = [c_char_p, c_size_t, c_int]
30     render_commonmark = lib.cmark_render_commonmark
31     render_commonmark.restype = c_char_p
32     render_commonmark.argtypes = [c_void_p, c_int, c_int]
33     node = parse_document(textbytes, textlen, 0)
34     result = render_commonmark(node, 0, 0).decode('utf-8')
35     return [0, result, '']
36 
37 class CMark:
38     def __init__(self, prog=None, library_dir=None):
39         self.prog = prog
40         if prog:
41             prog += ' --unsafe'
42             self.to_html = lambda x: pipe_through_prog(prog, x)
43             self.to_commonmark = lambda x: pipe_through_prog(prog + ' -t commonmark', x)
44         else:
45             sysname = platform.system()
46             if sysname == 'Darwin':
47                 libnames = [ "libcmark.dylib" ]
48             elif sysname == 'Windows':
49                 libnames = [ "cmark.dll", "libcmark.dll" ]
50             else:
51                 libnames = [ "libcmark.so" ]
52             if not library_dir:
53                 library_dir = os.path.join("build", "src")
54             for libname in libnames:
55                 candidate = os.path.join(library_dir, libname)
56                 if os.path.isfile(candidate):
57                     libpath = candidate
58                     break
59             cmark = CDLL(libpath)
60             self.to_html = lambda x: to_html(cmark, x)
61             self.to_commonmark = lambda x: to_commonmark(cmark, x)
62