lib/commonmarker.rb in commonmarker-0.1.3 vs lib/commonmarker.rb in commonmarker-0.2.0
- old
+ new
@@ -1,281 +1,63 @@
#!/usr/bin/env ruby
require 'commonmarker/commonmarker'
require 'commonmarker/config'
require 'commonmarker/renderer'
require 'commonmarker/renderer/html_renderer'
+require 'commonmarker/version'
begin
require 'awesome_print'
rescue LoadError; end
-NODE_TYPES = %i(none document blockquote list list_item
- code_block html paragraph
- header hrule text softbreak
- linebreak code inline_html
- emph strong link image)
-
-LIST_TYPES = %i(no_list bullet_list ordered_list)
-
-NONE_TYPE = 'NONE'
-
module CommonMarker
- class NodeError < StandardError
+ # Public: Parses a Markdown string into an HTML string.
+ #
+ # text - A {String} of text
+ # option - Either a {Symbol} or {Array of Symbol}s indicating the parse options
+ #
+ # Returns a {String} of converted HTML.
+ def self.render_html(text, option = :default)
+ fail TypeError, 'text must be a string!' unless text.is_a?(String)
+ Node.markdown_to_html(text, Config.process_options(option))
end
- class Node
- attr_reader :pointer
+ # Public: Parses a Markdown string into a `document` node.
+ #
+ # string - {String} to be parsed
+ # option - A {Symbol} or {Array of Symbol}s indicating the parse options
+ #
+ # Returns the `document` node.
+ def self.render_doc(text, option = :default)
+ fail TypeError, 'text must be a string!' unless text.is_a?(String)
+ Node.parse_document(text, text.bytesize, Config.process_options(option))
+ end
- # Creates a Node. Either +type+ or +pointer+ should be provided; the
- # other should be nil. If +type+ is provided, a new node with that
- # type is created. If +pointer+ is provided, a node is created from the
- # C node at +pointer+.
- # Params:
- # +type+:: +node_type+ of the node to be created (nil if +pointer+ is used).
- # +pointer+:: pointer to C node (nil if +type+ is used).
- def initialize(type = nil, pointer = nil)
- if pointer
- @pointer = pointer
- else
- idx = NODE_TYPES.index(type)
- fail NodeError, "node type does not exist #{type}" unless idx
- @pointer = CMark.node_new(type)
- end
-
- fail NodeError, "could not create node of type #{type}" if @pointer.nil?
- end
-
- # Parses a string into a :document Node.
- # Params:
- # +s+:: +String+ to be parsed.
- def self.parse_string(s, option = :default)
- Config.option_exists?(option)
- Node.new(nil, CMark.parse_document(s, s.bytesize, Config.to_h[option]))
- end
-
- # Parses a file into a :document Node.
- # Params:
- # +f+:: +File+ to be parsed (caller must open and close).
- def self.parse_file(f)
- s = f.read()
- self.parse_string(s)
- end
-
- def first_child
- Node.new(nil, CMark.node_first_child(@pointer))
- end
-
- def last_child
- Node.new(nil, CMark.node_last_child(@pointer))
- end
-
- def parent
- Node.new(nil, CMark.node_parent(@pointer))
- end
-
- def previous
- Node.new(nil, CMark.node_previous(@pointer))
- end
-
- def next
- Node.new(nil, CMark.node_next(@pointer))
- end
-
- # Iterator over the children (if any) of this Node.
- def each_child
- childptr = CMark.node_first_child(@pointer)
- until CMark.node_get_type_string(childptr) == NONE_TYPE
- nextptr = CMark.node_next(childptr)
- yield Node.new(nil, childptr)
- childptr = nextptr
- end
- end
-
- # Deletes the node and unlinks it (fixing pointers in
- # parents and siblings appropriately). Note: this method
- # does not free the node.
- def delete
- CMark.node_unlink(@pointer)
- end
-
- # Insert a node before this Node.
- # Params:
- # +sibling+:: Sibling node to insert.
- def insert_before(sibling)
- res = CMark.node_insert_before(@pointer, sibling.pointer)
- fail NodeError, 'could not insert before' if res == 0
- end
-
- # Insert a node after this Node.
- # Params:
- # +sibling+:: Sibling Node to insert.
- def insert_after(sibling)
- res = CMark.node_insert_before(@pointer, sibling.pointer)
- fail NodeError, 'could not insert after' if res == 0
- end
-
- # Prepend a child to this Node.
- # Params:
- # +child+:: Child Node to prepend.
- def prepend_child(child)
- res = CMark.node_prepend_child(@pointer, child.pointer)
- fail NodeError, 'could not prepend child' if res == 0
- end
-
- # Returns string content of this Node.
- def string_content
- CMark.node_get_string_content(@pointer)
- end
-
- # Sets string content of this Node.
- # Params:
- # +s+:: +String+ containing new content.
- def string_content=(s)
- res = CMark.node_set_string_content(@pointer, s)
- fail NodeError, 'could not set string content' if res == 0
- end
-
- # Returns header level of this Node (must be a :header).
- def header_level
- fail NodeError, 'can\'t get header_level for non-header' unless type == :header
- CMark.node_get_header_level(@pointer)
- end
-
- # Sets header level of this Node (must be a :header).
- # Params:
- # +level+:: New header level (+Integer+).
- def header_level=(level)
- fail NodeError, 'can\'t set header_level for non-header' unless type == :header
- if !level.is_a?(Integer) || level < 0 || level > 6
- fail NodeError, 'level must be between 1-6'
- end
- res = CMark.node_set_header_level(@pointer, level)
- fail NodeError, 'could not set header level' if res == 0
- end
-
- # Returns list type of this Node (must be a :list).
- def list_type
- fail NodeError, 'can\'t get list_type for non-list' unless type == :list
- LIST_TYPES[CMark.node_get_list_type(@pointer)]
- end
-
- # Sets list type of this Node (must be a :list).
- # Params:
- # +list_type+:: New list type (+:list_type+), either
- # :ordered_list or :bullet_list.
- def list_type=(list_type)
- fail NodeError, 'can\'t set list_type for non-list' unless type == :list
- res = CMark.node_set_list_type(@pointer, list_type)
- fail NodeError, 'could not set list_type' if res == 0
- end
-
- # Returns start number of this Node (must be a :list of
- # list_type :ordered_list).
- def list_start
- if type != :list || list_type != :ordered_list
- fail NodeError, 'can\'t get list_start for non-ordered list'
- end
- CMark.node_get_list_start(@pointer)
- end
-
- # Sets start number of this Node (must be a :list of
- # list_type :ordered_list).
- # Params:
- # +start+:: New start number (+Integer+).
- def list_start=(start)
- if type != :list || list_type != :ordered_list
- fail NodeError, 'can\'t set list_start for non-ordered list'
- end
- fail NodeError, 'start must be Integer' unless start.is_a?(Integer)
- res = CMark.node_set_list_start(@pointer, start)
- fail NodeError, 'could not set list_start' if res == 0
- end
-
- # Returns tight status of this Node (must be a :list).
- def list_tight
- fail NodeError, 'can\'t get list_tight for non-list' unless type == :list
- CMark.node_get_list_tight(@pointer)
- end
-
- # Sets tight status of this Node (must be a :list).
- # Params:
- # +tight+:: New tight status (boolean).
- def list_tight=(tight)
- fail NodeError, 'can\'t set list_tight for non-list' unless type == :list
- res = CMark.node_set_list_tight(@pointer, tight)
- fail NodeError, 'could not set list_tight' if res == 0
- end
-
- # Returns URL of this Node (must be a :link or :image).
- def url
- fail NodeError, 'can\'t get URL for non-link or image' if !(type == :link || type == :image)
- CMark.node_get_url(@pointer)
- end
-
- # Sets URL of this Node (must be a :link or :image).
- # Params:
- # +URL+:: New URL (+String+).
- def url=(url)
- fail NodeError, 'can\'t set URL for non-link or image' if !(type == :link || type == :image)
- fail NodeError, 'url must be a String' unless url.is_a?(String)
- res = CMark.node_set_url(@pointer, url)
- fail NodeError, 'could not set header level' if res == 0
- end
-
- # Returns title of this Node (must be a :link or :image).
- def title
- fail NodeError, 'can\'t get title for non-link or image' if !(type == :link || type == :image)
- CMark.node_get_title(@pointer)
- end
-
- # Sets title of this Node (must be a :link or :image).
- # Params:
- # +title+:: New title (+String+).
- def title=(title)
- fail NodeError, 'can\'t set title for non-link or image' if !(type == :link || type == :image)
- fail NodeError, 'title must be a String' unless title.is_a?(String)
- res = CMark.node_set_title(@pointer, title)
- fail NodeError, 'could not set header level' if res == 0
- end
-
- # Returns fence info of this Node (must be a :code_block).
- def fence_info
- fail NodeError, 'can\'t get fence_info for non code_block' unless type == :code_block
- CMark.node_get_fence_info(@pointer)
- end
-
- # Sets fence_info of this Node (must be a :code_block).
- # Params:
- # +info+:: New info (+String+).
- def fence_info=(info)
- fail NodeError, 'can\'t set fence_info for non code_block' unless type == :code_block
- fail NodeError, 'info must be a String' unless info.is_a?(String)
- res = CMark.node_set_fence_info(@pointer, info)
- fail NodeError, 'could not set info' if res == 0
- end
-
- # An iterator that "walks the tree," descending into children
- # recursively.
+ class Node
+ # Public: An iterator that "walks the tree," descending into children recursively.
+ #
+ # blk - A {Proc} representing the action to take for each child
def walk(&blk)
yield self
each_child do |child|
child.walk(&blk)
end
end
- # Returns the type of this Node.
- def type
- NODE_TYPES[CMark.node_get_type(@pointer)]
- end
-
- def type_string
- CMark.node_get_type_string(@pointer)
- end
-
- # Convert to HTML using libcmark's fast (but uncustomizable) renderer.
+ # Public: Convert the node to an HTML string.
+ #
+ # Returns a {String}.
def to_html(option = :default)
- Config.option_exists?(option)
- CMark.render_html(@pointer, Config.to_h[option]).force_encoding('utf-8')
+ _render_html(Config.process_options(option)).force_encoding('utf-8')
end
+ # Internal: Iterate over the children (if any) of the current pointer.
+ def each_child
+ child = first_child
+ while child
+ nextchild = child.next
+ yield child
+ child = nextchild
+ end
+ end
end
end