#include "markdown_renderer.h" #include "core/object/class_db.h" #include "core/error/error_macros.h" #include "core/log/logger.h" #include "./libs/hoedown/html.h" #include "core/object/object.h" MarkdownRenderer::RenderType MarkdownRenderer::get_render_type() { return _render_type; } void MarkdownRenderer::set_render_type(const MarkdownRenderer::RenderType val) { _render_type = val; } int MarkdownRenderer::get_html_flags() { return _html_flags; } void MarkdownRenderer::set_html_flags(const int val) { _html_flags = val; } int MarkdownRenderer::get_markdown_extensions() { return _markdown_extensions; } void MarkdownRenderer::set_markdown_extensions(const int val) { _markdown_extensions = val; } int MarkdownRenderer::get_max_nesting() { return _max_nesting; } void MarkdownRenderer::set_max_nesting(const int val) { _max_nesting = val; } bool MarkdownRenderer::get_use_smartypants() { return _use_smartypants; } void MarkdownRenderer::set_use_smartypants(const bool val) { _use_smartypants = val; } int MarkdownRenderer::get_toc_level() { return _toc_level; } void MarkdownRenderer::set_toc_level(const int val) { _toc_level = val; } String MarkdownRenderer::render_to_html(const String &markdown) { hoedown_renderer *renderer; switch (_render_type) { case RENDER_TYPE_HTML: { renderer = hoedown_html_renderer_new(static_cast(_html_flags), _toc_level); } break; case RENDER_TYPE_HTML_TOC: { renderer = hoedown_html_toc_renderer_new(_toc_level); } break; default: { renderer = hoedown_html_renderer_new(static_cast(_html_flags), _toc_level); } break; } int hoedown_ext_flags = 0; if ((_markdown_extensions & EXTENSION_TABLES) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_TABLES; } if ((_markdown_extensions & EXTENSION_FENCED_CODE) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_FENCED_CODE; } if ((_markdown_extensions & EXTENSION_FOOTNOTES) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_FOOTNOTES; } if ((_markdown_extensions & EXTENSION_AUTOLINK) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_AUTOLINK; } if ((_markdown_extensions & EXTENSION_STRKIETHROUGH) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_STRIKETHROUGH; } if ((_markdown_extensions & EXTENSION_UNDERLINE) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_UNDERLINE; } if ((_markdown_extensions & EXTENSION_HIGHLIGHT) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_HIGHLIGHT; } if ((_markdown_extensions & EXTENSION_QUOTE) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_QUOTE; } if ((_markdown_extensions & EXTENSION_SUPERSCRIPT) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_SUPERSCRIPT; } if ((_markdown_extensions & EXTENSION_MATH) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_MATH; } if ((_markdown_extensions & EXTENSION_NO_INTRA_EMPHASIS) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_NO_INTRA_EMPHASIS; } if ((_markdown_extensions & EXTENSION_SPACE_HEADERS) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_SPACE_HEADERS; } if ((_markdown_extensions & EXTENSION_MATH_EXPLICIT) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_MATH_EXPLICIT; } if ((_markdown_extensions & EXTENSION_DISABLE_INDENTED_CODE) != 0) { hoedown_ext_flags |= HOEDOWN_EXT_DISABLE_INDENTED_CODE; } hoedown_document *document = hoedown_document_new(renderer, static_cast(hoedown_ext_flags), _max_nesting); //#define DEF_IUNIT 1024 hoedown_buffer *html = hoedown_buffer_new(1024); CharString csmd = markdown.utf8(); hoedown_document_render(document, html, reinterpret_cast(csmd.get_data()), csmd.length()); String html_str = String::utf8(reinterpret_cast(html->data)); if (_use_smartypants) { CharString cshtml = html_str.utf8(); hoedown_html_smartypants(html, reinterpret_cast(cshtml.get_data()), cshtml.length()); html_str = String::utf8(reinterpret_cast(html->data)); } hoedown_buffer_free(html); hoedown_document_free(document); hoedown_html_renderer_free(renderer); return html_str; } MarkdownRenderer::MarkdownRenderer() { _render_type = RENDER_TYPE_HTML; _html_flags = 0; //https://github.com/hoedown/hoedown/wiki/Popular-presets _markdown_extensions = EXTENSION_TABLES | EXTENSION_FENCED_CODE | EXTENSION_AUTOLINK | EXTENSION_STRKIETHROUGH | EXTENSION_NO_INTRA_EMPHASIS; _max_nesting = 16; _toc_level = 0; _use_smartypants = false; } MarkdownRenderer::~MarkdownRenderer() { } void MarkdownRenderer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_render_type"), &MarkdownRenderer::get_render_type); ClassDB::bind_method(D_METHOD("set_render_type", "val"), &MarkdownRenderer::set_render_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_type", PROPERTY_HINT_ENUM, "HTML,HTML TOC"), "set_render_type", "get_render_type"); ClassDB::bind_method(D_METHOD("get_html_flags"), &MarkdownRenderer::get_html_flags); ClassDB::bind_method(D_METHOD("set_html_flags", "val"), &MarkdownRenderer::set_html_flags); ADD_PROPERTY(PropertyInfo(Variant::INT, "html_flags", PROPERTY_HINT_FLAGS, "Skip HTML,Escape,Hard Wrap,Use XHTML"), "set_html_flags", "get_html_flags"); ClassDB::bind_method(D_METHOD("get_markdown_extensions"), &MarkdownRenderer::get_markdown_extensions); ClassDB::bind_method(D_METHOD("set_markdown_extensions", "val"), &MarkdownRenderer::set_markdown_extensions); ADD_PROPERTY(PropertyInfo(Variant::INT, "markdown_extensions", PROPERTY_HINT_FLAGS, "Tables,Fenced Code,Footnotes,Autolink,Strikethrough,Underline,Highlight,Quote,Superscript,Math,No Intra Emphasis,Space Headers,Math Explicit,Disable Indented Code"), "set_markdown_extensions", "get_markdown_extensions"); ClassDB::bind_method(D_METHOD("get_max_nesting"), &MarkdownRenderer::get_max_nesting); ClassDB::bind_method(D_METHOD("set_max_nesting", "val"), &MarkdownRenderer::set_max_nesting); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_nesting"), "set_max_nesting", "get_max_nesting"); ClassDB::bind_method(D_METHOD("get_use_smartypants"), &MarkdownRenderer::get_use_smartypants); ClassDB::bind_method(D_METHOD("set_use_smartypants", "val"), &MarkdownRenderer::set_use_smartypants); ADD_PROPERTY(PropertyInfo(Variant::INT, "use_smartypants"), "set_use_smartypants", "get_use_smartypants"); ClassDB::bind_method(D_METHOD("get_toc_level"), &MarkdownRenderer::get_toc_level); ClassDB::bind_method(D_METHOD("set_toc_level", "val"), &MarkdownRenderer::set_toc_level); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toc_level"), "set_toc_level", "get_toc_level"); ClassDB::bind_method(D_METHOD("render_to_html", "markdown"), &MarkdownRenderer::render_to_html); BIND_ENUM_CONSTANT(RENDER_TYPE_HTML); BIND_ENUM_CONSTANT(RENDER_TYPE_HTML_TOC); BIND_ENUM_CONSTANT(HTML_FLAG_SKIP_HTML); BIND_ENUM_CONSTANT(HTML_FLAG_ESCAPE); BIND_ENUM_CONSTANT(HTML_FLAG_HARD_WRAP); BIND_ENUM_CONSTANT(HTML_FLAG_USE_XHTML); BIND_ENUM_CONSTANT(EXTENSION_TABLES); BIND_ENUM_CONSTANT(EXTENSION_FENCED_CODE); BIND_ENUM_CONSTANT(EXTENSION_FOOTNOTES); BIND_ENUM_CONSTANT(EXTENSION_AUTOLINK); BIND_ENUM_CONSTANT(EXTENSION_STRKIETHROUGH); BIND_ENUM_CONSTANT(EXTENSION_UNDERLINE); BIND_ENUM_CONSTANT(EXTENSION_HIGHLIGHT); BIND_ENUM_CONSTANT(EXTENSION_QUOTE); BIND_ENUM_CONSTANT(EXTENSION_SUPERSCRIPT); BIND_ENUM_CONSTANT(EXTENSION_MATH); BIND_ENUM_CONSTANT(EXTENSION_NO_INTRA_EMPHASIS); BIND_ENUM_CONSTANT(EXTENSION_SPACE_HEADERS); BIND_ENUM_CONSTANT(EXTENSION_MATH_EXPLICIT); BIND_ENUM_CONSTANT(EXTENSION_DISABLE_INDENTED_CODE); };