From 8237abc0cbd821e17b6b9c5a8d5c5ad3014ba455 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Thu, 20 Nov 2014 13:58:37 -0800 Subject: Added commonmark.rb, steps towards a nice ruby wrapper of the parser. --- commonmark.rb | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 commonmark.rb diff --git a/commonmark.rb b/commonmark.rb new file mode 100644 index 0000000..0d7fa0e --- /dev/null +++ b/commonmark.rb @@ -0,0 +1,79 @@ +require 'ffi' + +module CMark + extend FFI::Library + ffi_lib ['libcmark', 'cmark'] + typedef :pointer, :node + enum :node_type, [:document, :blockquote, :list, :list_item, + :fenced_code, :indented_code, :html, :paragraph, + :atx_header, :setext_header, :hrule, :reference_def, + :str, :softbreak, :linebreak, :code, :inline_html, + :emph, :strong, :link, :image] + enum :node_type, [] + attach_function :cmark_markdown_to_html, [:string, :int], :string + attach_function :cmark_parse_document, [:string, :int], :node + attach_function :cmark_node_first_child, [:node], :node + attach_function :cmark_node_next, [:node], :node + attach_function :cmark_node_get_type, [:node], :node_type +end + +def pointer_to_block(pointer) + if pointer.null? + raise NullPointer + else + node_type = CMark::cmark_node_get_type(pointer) + if node_type == 0 # document + children = [] + b = CMark::cmark_node_first_child(pointer) + while !b.null? + children << pointer_to_block(b) + b = CMark::cmark_node_next(b) + end + return Document.new(children) + elsif node_type == 7 # paragraph + return Paragraph.new("TODO") + else + raise UnknownNodeType, node_type + end + end +end + +class Block + def initialize + end +end + +class Document < Block + attr_accessor :children + def initialize(children) + @children = children + end +end + +class Paragraph < Block + def initialize(inlines) + @contents = "inlines" # TODO + end + def to_html + "

" + @contents + "

" + end +end + +class Inline +end + +def parse_markdown(s) + len = s.bytes.length + pointer_to_block(CMark::cmark_parse_document(s, len)) +end + +def markdown_to_html(s) + len = s.bytes.length + CMark::cmark_markdown_to_html(s, len) +end + +doc = parse_markdown(STDIN.read()) +doc.children.each do |b| + print(b) +end +# print markdown_to_html(STDIN.read()) -- cgit v1.2.3