Skip to content
This repository has been archived by the owner on Jul 29, 2020. It is now read-only.

Wrap C library #2

Closed
wants to merge 15 commits into from
Prev Previous commit
Next Next commit
Start creating nodes and documents
  • Loading branch information
gjtorikian committed May 7, 2015
commit 1858c19b065e7b8047f247168bb541863876b17c
2 changes: 1 addition & 1 deletion commonmarker.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Gem::Specification.new do |s|
s.executables = ["commonmarker"]
s.require_paths = %w(lib ext)


s.add_dependency 'ruby-enum', '~> 0.4'
s.add_development_dependency "rake-compiler", "~> 0.9"
s.add_development_dependency "bundler", "~> 1.9"
s.add_development_dependency "json", "~> 1.8.1"
Expand Down
38 changes: 37 additions & 1 deletion ext/commonmarker/commonmarker.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,53 @@
#include "commonmarker.h"
#include "cmark.h"
#include "node.h"

VALUE rb_mCommonMark;
cmark_node *node;

static VALUE
rb_markdown_to_html(VALUE text)
{
return rb_str_new2((char *)cmark_markdown_to_html((char *)RSTRING_PTR(text), RSTRING_LEN(text), 0));
}

static VALUE
rb_node_new(VALUE self, VALUE rb_type)
{
Check_Type(rb_type, T_FIXNUM);
cmark_node_type node_type = (cmark_node_type) FIX2INT(rb_type);

return cmark_node_new(node_type);
}

static VALUE
rb_parse_document(VALUE self, VALUE rb_text, VALUE rb_len, VALUE rb_options)
{
Check_Type(rb_text, T_STRING);
Check_Type(rb_len, T_FIXNUM);
Check_Type(rb_options, T_FIXNUM);

char *text = (char *)RSTRING_PTR(rb_text);
int len = FIX2INT(rb_len);
int options = FIX2INT(rb_options);

node = cmark_parse_document(text, len, CMARK_OPT_DEFAULT);

return Data_Wrap_Struct(self, NULL, cmark_node_free, node);
}

static VALUE
rb_node_get_string_content(VALUE self)
{
return Data_Wrap_Struct(self, NULL, cmark_strbuf_free, &node->string_content);
}

__attribute__((visibility("default")))
void Init_commonmarker()
{
rb_mCommonMark = rb_define_module("CommonMark");
rb_mCommonMark = rb_define_class("CMark", rb_cObject);
rb_define_singleton_method(rb_mCommonMark, "markdown_to_html", rb_markdown_to_html, 1);
rb_define_singleton_method(rb_mCommonMark, "node_new", rb_node_new, 1);
rb_define_singleton_method(rb_mCommonMark, "parse_document", rb_parse_document, 3);
rb_define_singleton_method(rb_mCommonMark, "node_get_string_content", rb_node_get_string_content, 1);
}
2 changes: 1 addition & 1 deletion ext/commonmarker/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@

CMARK_DIR = File.expand_path(File.join(File.dirname(__FILE__), 'cmark'))
CMARK_BUILD_DIR = File.join(CMARK_DIR, 'build')
FileUtils.rm_rf(CMARK_BUILD_DIR) if File.exist?(CMARK_BUILD_DIR)
FileUtils.mkdir_p(CMARK_BUILD_DIR)

Dir.chdir(CMARK_BUILD_DIR) do
system 'cmake ..'
system 'make'
end

$CFLAGS << " -I#{CMARK_DIR}/src -I#{CMARK_BUILD_DIR}/src"
$LOCAL_LIBS << "#{CMARK_BUILD_DIR}/src/libcmark.a"

create_makefile('commonmarker/commonmarker')
25 changes: 19 additions & 6 deletions lib/commonmarker.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
#!/usr/bin/env ruby
require 'commonmarker/commonmarker'
require 'commonmarker/config'
require 'stringio'
require 'cgi'
require 'set'
require 'uri'

NODE_TYPES = [:document, :blockquote, :list, :list_item,
:code_block, :html, :paragraph,
:header, :hrule, :reference_def,
:text, :softbreak, :linebreak, :code, :inline_html,
:emph, :strong, :link, :image]
LIST_TYPES = [:no_list, :bullet_list, :ordered_list]

# module CMark

# attach_function :cmark_node_new, [:node_type], :node
Expand Down Expand Up @@ -41,8 +50,6 @@
# end

module CommonMarker
VERSION = 0.1

class NodeError < StandardError
end

Expand All @@ -60,10 +67,13 @@ def initialize(type=nil, pointer=nil)
if pointer
@pointer = pointer
else
unless NODE_TYPES.include?(type)
raise NodeError, "node type does not exist #{type}"
end
@pointer = CMark.node_new(type)
end
if @pointer.null?
raise NodeError, "could not create node of type " + type.to_s
if @pointer.nil?
raise NodeError, "could not create node of type #{type}"
end
end

Expand All @@ -72,8 +82,11 @@ def initialize(type=nil, pointer=nil)
# memory when it is no longer needed.
# Params:
# +s+:: +String+ to be parsed.
def self.parse_string(s)
Node.new(nil, CMark.parse_document(s, s.bytesize))
def self.parse_string(s, option=:default)
unless Config.keys.include?(option)
raise StandardError, "option type does not exist #{option}"
end
Node.new(nil, CMark.parse_document(s, s.bytesize, Config.to_h[option]))
end

# Parses a file into a :document Node. The
Expand Down
14 changes: 14 additions & 0 deletions lib/commonmarker/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'ruby-enum'

module CommonMarker
class Config
include Ruby::Enum

define :default, 0
define :sourcepos, 1
define :hardbreaks, 2
define :normalize, 4
define :smart, 8

end
end
9 changes: 9 additions & 0 deletions test/test_maliciousness.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require 'test_helper'

class CommonMarker::TestMaliciousness < Minitest::Unit::TestCase
def test_init
assert_raises NodeError do
render = Node.new(99999)
end
end
end