Custom renderer works.
This commit is contained in:
parent
26d7bf0c8e
commit
259dc0acaa
|
@ -6,3 +6,4 @@ dist
|
|||
*.egg-info
|
||||
*.sublime-*
|
||||
*.pyc
|
||||
*.so
|
||||
|
|
193
misaka/api.py
193
misaka/api.py
|
@ -18,6 +18,12 @@ OUNIT = 64
|
|||
MAX_NESTING = 16
|
||||
|
||||
|
||||
def to_string(buffer):
|
||||
if buffer == ffi.NULL or buffer.size == 0:
|
||||
return ''
|
||||
return ffi.string(buffer.data, buffer.size).decode('utf-8')
|
||||
|
||||
|
||||
def html(text, extensions=0, render_flags=0):
|
||||
ib = lib.hoedown_buffer_new(IUNIT)
|
||||
ob = lib.hoedown_buffer_new(OUNIT)
|
||||
|
@ -38,7 +44,7 @@ def html(text, extensions=0, render_flags=0):
|
|||
|
||||
class Markdown:
|
||||
def __init__(self, renderer, extensions=0):
|
||||
# NOTE: Prevent the renderer from being garbage collected
|
||||
# NOTE: Prevent the renderer from being garbage collected.
|
||||
self.renderer = renderer
|
||||
self.extensions = extensions
|
||||
|
||||
|
@ -50,8 +56,8 @@ class Markdown:
|
|||
document = lib.hoedown_document_new(self.renderer.renderer, self.extensions, MAX_NESTING);
|
||||
lib.hoedown_document_render(document, ob, ib.data, ib.size);
|
||||
|
||||
lib.hoedown_buffer_free(ib);
|
||||
lib.hoedown_document_free(document);
|
||||
lib.hoedown_buffer_free(ib)
|
||||
lib.hoedown_document_free(document)
|
||||
|
||||
try:
|
||||
return ffi.string(ob.data, ob.size).decode('utf-8')
|
||||
|
@ -61,89 +67,82 @@ class Markdown:
|
|||
|
||||
_callback_signatures = {
|
||||
# block level callbacks - NULL skips the block
|
||||
'blockcode': 'void (*blockcode)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, const hoedown_renderer_data *data)',
|
||||
'blockquote': 'void (*blockquote)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'header': 'void (*header)(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data)',
|
||||
'hrule': 'void (*hrule)(hoedown_buffer *ob, const hoedown_renderer_data *data)',
|
||||
'list': 'void (*list)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data)',
|
||||
'listitem': 'void (*listitem)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data)',
|
||||
'paragraph': 'void (*paragraph)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'table': 'void (*table)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'table_header': 'void (*table_header)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'table_body': 'void (*table_body)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'table_row': 'void (*table_row)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'table_cell': 'void (*table_cell)(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_table_flags flags, const hoedown_renderer_data *data)',
|
||||
'footnotes': 'void (*footnotes)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'footnote_def': 'void (*footnote_def)(hoedown_buffer *ob, const hoedown_buffer *content, unsigned int num, const hoedown_renderer_data *data)',
|
||||
'blockhtml': 'void (*blockhtml)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)',
|
||||
'blockcode': 'void(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_buffer *lang, const hoedown_renderer_data *data)',
|
||||
'blockquote': 'void(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'header': 'void(hoedown_buffer *ob, const hoedown_buffer *content, int level, const hoedown_renderer_data *data)',
|
||||
'hrule': 'void(hoedown_buffer *ob, const hoedown_renderer_data *data)',
|
||||
'list': 'void(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data)',
|
||||
'listitem': 'void(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_list_flags flags, const hoedown_renderer_data *data)',
|
||||
'paragraph': 'void(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'table': 'void(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'table_header': 'void(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'table_body': 'void(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'table_row': 'void(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'table_cell': 'void(hoedown_buffer *ob, const hoedown_buffer *content, hoedown_table_flags flags, const hoedown_renderer_data *data)',
|
||||
'footnotes': 'void(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'footnote_def': 'void(hoedown_buffer *ob, const hoedown_buffer *content, unsigned int num, const hoedown_renderer_data *data)',
|
||||
'blockhtml': 'void(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)',
|
||||
|
||||
# span level callbacks - NULL or return 0 prints the span verbatim
|
||||
'autolink': 'int (*autolink)(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, const hoedown_renderer_data *data)',
|
||||
'codespan': 'int (*codespan)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)',
|
||||
'double_emphasis': 'int (*double_emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'emphasis': 'int (*emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'underline': 'int (*underline)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'highlight': 'int (*highlight)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'quote': 'int (*quote)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'image': 'int (*image)(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, const hoedown_renderer_data *data)',
|
||||
'linebreak': 'int (*linebreak)(hoedown_buffer *ob, const hoedown_renderer_data *data)',
|
||||
'link': 'int (*link)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data)',
|
||||
'triple_emphasis': 'int (*triple_emphasis)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'strikethrough': 'int (*strikethrough)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'superscript': 'int (*superscript)(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'footnote_ref': 'int (*footnote_ref)(hoedown_buffer *ob, unsigned int num, const hoedown_renderer_data *data)',
|
||||
'math': 'int (*math)(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, const hoedown_renderer_data *data)',
|
||||
'raw_html': 'int (*raw_html)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)',
|
||||
'autolink': 'int(hoedown_buffer *ob, const hoedown_buffer *link, hoedown_autolink_type type, const hoedown_renderer_data *data)',
|
||||
'codespan': 'int(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)',
|
||||
'double_emphasis': 'int(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'emphasis': 'int(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'underline': 'int(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'highlight': 'int(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'quote': 'int(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'image': 'int(hoedown_buffer *ob, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_buffer *alt, const hoedown_renderer_data *data)',
|
||||
'linebreak': 'int(hoedown_buffer *ob, const hoedown_renderer_data *data)',
|
||||
'link': 'int(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_buffer *link, const hoedown_buffer *title, const hoedown_renderer_data *data)',
|
||||
'triple_emphasis': 'int(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'strikethrough': 'int(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'superscript': 'int(hoedown_buffer *ob, const hoedown_buffer *content, const hoedown_renderer_data *data)',
|
||||
'footnote_ref': 'int(hoedown_buffer *ob, unsigned int num, const hoedown_renderer_data *data)',
|
||||
'math': 'int(hoedown_buffer *ob, const hoedown_buffer *text, int displaymode, const hoedown_renderer_data *data)',
|
||||
'raw_html': 'int(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)',
|
||||
|
||||
# low level callbacks - NULL copies input directly into the output
|
||||
'entity': 'void (*entity)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);',
|
||||
'normal_text': 'void (*normal_text)(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data);',
|
||||
'entity': 'void(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)',
|
||||
'normal_text': 'void(hoedown_buffer *ob, const hoedown_buffer *text, const hoedown_renderer_data *data)',
|
||||
|
||||
# miscellaneous callbacks
|
||||
'doc_header': 'void (*doc_header)(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data);',
|
||||
'doc_footer': 'void (*doc_footer)(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data);',
|
||||
'doc_header': 'void(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data)',
|
||||
'doc_footer': 'void(hoedown_buffer *ob, int inline_render, const hoedown_renderer_data *data)',
|
||||
}
|
||||
|
||||
|
||||
class BaseRenderer:
|
||||
def __init__(self):
|
||||
self.renderer = lib.null_renderer_new()
|
||||
self.set_callbacks()
|
||||
# Use a noop method as a placeholder for render methods that are
|
||||
# implemented so there's no need to check if a render method exists
|
||||
# in a callback.
|
||||
for attr in _callback_signatures.keys():
|
||||
if not hasattr(self, attr):
|
||||
setattr(self, attr, self.noop)
|
||||
|
||||
def __del__(self):
|
||||
lib.null_renderer_free(self.renderer)
|
||||
self._callbacks = {k: ffi.callback(v, getattr(self, '_w_' + k))
|
||||
for k, v in _callback_signatures.items()}
|
||||
self.renderer = ffi.new('hoedown_renderer *', self._callbacks)
|
||||
|
||||
def set_callbacks(self):
|
||||
callbacks = []
|
||||
|
||||
for name, func in getmembers(self, predicate=ismethod):
|
||||
signature = _callback_signatures.get(name)
|
||||
if signature is None:
|
||||
continue
|
||||
|
||||
wrapper = getattr(self, '_w_' + name)
|
||||
callback = ffi.callback(signature, wrapper)
|
||||
callbacks.append(callback)
|
||||
setattr(self.renderer, name, callback)
|
||||
|
||||
# Prevent callbacks from being garbage collected.
|
||||
self._callbacks = callbacks
|
||||
def noop(self, *args, **kwargs):
|
||||
return None
|
||||
|
||||
def _w_blockcode(self, ob, text, lang, data):
|
||||
text = ffi.string(text.data, text.size).decode('utf-8')
|
||||
lang = ffi.string(lang.data, lang.size).decode('utf-8')
|
||||
text = to_string(text)
|
||||
lang = to_string(lang)
|
||||
|
||||
result = self.blockcode(text, lang)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_blockquote(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.blockquote(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_header(self, ob, content, level, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
level = int(level)
|
||||
result = self.header(content, level)
|
||||
if result:
|
||||
|
@ -156,7 +155,7 @@ class BaseRenderer:
|
|||
|
||||
# flags: LIST_ORDERED, LI_BLOCK.
|
||||
def _w_list(self, ob, content, flags, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
flags = int(flags)
|
||||
result = self.list(content, flags)
|
||||
if result:
|
||||
|
@ -164,57 +163,57 @@ class BaseRenderer:
|
|||
|
||||
# flags: LIST_ORDERED, LI_BLOCK.
|
||||
def _w_listitem(self, ob, content, flags, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
flags = int(flags)
|
||||
result = self.listitem(content, flags)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_paragraph(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.paragraph(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_table(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.table(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_table_header(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.table_header(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_table_body(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.table_body(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_table_row(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.table_row(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_table_cell(self, ob, content, flags, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
flags = int(flags)
|
||||
result = self.table_row(content, flags)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_footnotes(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.footnotes(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_footnote_def(self, ob, content, num, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
num = int(num)
|
||||
result = self.footnote_def(content, num)
|
||||
if result:
|
||||
|
@ -244,7 +243,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_double_emphasis(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.double_emphasis(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -252,7 +251,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_emphasis(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.emphasis(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -260,7 +259,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_underline(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.underline(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -268,7 +267,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_highlight(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.highlight(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -276,7 +275,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_quote(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.quote(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -284,9 +283,9 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_image(self, ob, link, title, alt, data):
|
||||
link = ffi.string(link.data, link.size).decode('utf-8')
|
||||
title = ffi.string(title.data, title.size).decode('utf-8')
|
||||
alt = ffi.string(alt.data, alt.size).decode('utf-8')
|
||||
link = to_string(link)
|
||||
title = to_string(title)
|
||||
alt = to_string(alt)
|
||||
result = self.image(link, title, alt)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -294,7 +293,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_quote(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.quote(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -309,9 +308,9 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_link(self, ob, content, link, title, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
link = ffi.string(link.data, link.size).decode('utf-8')
|
||||
title = ffi.string(title.data, title.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
link = to_string(link)
|
||||
title = to_string(title)
|
||||
result = self.link(content, link, title)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -319,7 +318,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_triple_emphasis(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.triple_emphasis(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -327,7 +326,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_strikethrough(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.strikethrough(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -335,7 +334,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_superscript(self, ob, content, data):
|
||||
content = ffi.string(content.data, content.size).decode('utf-8')
|
||||
content = to_string(content)
|
||||
result = self.superscript(content)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -351,7 +350,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_math(self, ob, text, displaymode, data):
|
||||
text = ffi.string(text.data, text.size).decode('utf-8')
|
||||
text = to_string(text)
|
||||
displaymode = int(displaymode)
|
||||
result = self.math(text, displaymode)
|
||||
if result:
|
||||
|
@ -360,7 +359,7 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_raw_html(self, ob, text, data):
|
||||
text = ffi.string(text.data, text.size).decode('utf-8')
|
||||
text = to_string(text)
|
||||
result = self.raw_html(text)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -368,13 +367,13 @@ class BaseRenderer:
|
|||
return 0
|
||||
|
||||
def _w_entity(self, ob, text, data):
|
||||
text = ffi.string(text.data, text.size).decode('utf-8')
|
||||
text = to_string(text)
|
||||
result = self.entity(text)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
||||
def _w_normal_text(self, ob, text, data):
|
||||
text = ffi.string(text.data, text.size).decode('utf-8')
|
||||
text = to_string(text)
|
||||
result = self.normal_text(text)
|
||||
if result:
|
||||
lib.hoedown_buffer_puts(ob, result.encode('utf-8'))
|
||||
|
@ -395,7 +394,19 @@ class BaseRenderer:
|
|||
class HtmlRenderer(BaseRenderer):
|
||||
def __init__(self, flags=0):
|
||||
self.renderer = lib.hoedown_html_renderer_new(flags, 0)
|
||||
self.set_callbacks()
|
||||
callbacks = []
|
||||
|
||||
for name, signature in _callback_signatures.items():
|
||||
if not hasattr(self, name):
|
||||
continue
|
||||
|
||||
wrapper = getattr(self, '_w_' + name)
|
||||
callback = ffi.callback(signature, wrapper)
|
||||
callbacks.append(callback)
|
||||
setattr(self.renderer, name, callback)
|
||||
|
||||
# Prevent garbage collection of callbacks.
|
||||
self._callbacks = callbacks
|
||||
|
||||
def __del__(self):
|
||||
lib.hoedown_html_renderer_free(self.renderer)
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from chibitest import runner
|
||||
|
||||
from test_markdown import MarkdownConformanceTest_10, MarkdownConformanceTest_103
|
||||
from test_renderer import CustomRendererTest
|
||||
|
||||
|
||||
def run_tests():
|
||||
runner([
|
||||
MarkdownConformanceTest_10,
|
||||
MarkdownConformanceTest_103,
|
||||
# MarkdownConformanceTest_10,
|
||||
# MarkdownConformanceTest_103,
|
||||
CustomRendererTest,
|
||||
])
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
import codecs
|
||||
from os import path
|
||||
from glob import glob
|
||||
|
||||
import misaka as m
|
||||
from chibitest import TestCase, ok
|
||||
from test_utils import clean_html
|
||||
|
||||
|
||||
class TestRenderer(m.BaseRenderer):
|
||||
def blockcode(self, text, language):
|
||||
return '[BLOCK_CODE language={1}] {0}'.format(text, language)
|
||||
|
||||
def paragraph(self, text):
|
||||
return '[PARAGRAPH] {0}\n'.format(text)
|
||||
|
||||
def normal_text(self, text):
|
||||
return text
|
||||
|
||||
|
||||
class CustomRendererTest(TestCase):
|
||||
name = 'Custom Renderer'
|
||||
|
||||
def setup(self):
|
||||
self.renderer = TestRenderer()
|
||||
self.render = m.Markdown(TestRenderer(), m.EXT_FENCED_CODE).render
|
||||
|
||||
def md(self, md, renderer):
|
||||
return m.Markdown(getattr(self, renderer)).render(md)
|
||||
|
||||
def test_block_code(self):
|
||||
supplied = '```bash\n$ :(){ :|:& };:\n```'
|
||||
expected = '[BLOCK_CODE language=bash] $ :(){ :|:& };:\n'
|
||||
|
||||
ok(self.render(supplied)).diff(expected)
|
Loading…
Reference in New Issue