class Node

Includes
Enumerable; Inspect: #inspect, #pretty_print

Represents a node in a parsed Markdown document tree.

Nested Classes and Modules

module Inspect

Provides concise pretty-printing for Markdown nodes.

Definitions

def dup

Duplicate the current node and all its children.

Signature

returns Markly::Node

The duplicated node tree.

Implementation

def dup
	# This is a bit crazy, but it's the best I can come up with right now:
	node = Markly.parse(self.to_markdown)
	
	# If we aren't duplicating a document, we return `first_child` as the root will be a document node:
	if self.type == :document
		return node
	else
		return node.first_child
	end
end

def walk(&block)

Walk the node tree recursively.

Signature

yields {|node| ...}

Each node in depth-first order, including this node.

parameter node Markly::Node

The current node.

returns Enumerator | Nil

An enumerator when no block is given.

Implementation

def walk(&block)
	return enum_for(:walk) unless block_given?
	
	yield self
	each do |child|
		child.walk(&block)
	end
end

def to_html(flags: DEFAULT, extensions: [])

Convert the node to an HTML string.

Signature

parameter flags Integer

The enabled rendering flags.

parameter extensions Array(Symbol)

The extensions to enable.

returns String

The rendered HTML.

Implementation

def to_html(flags: DEFAULT, extensions: [])
	_render_html(flags, extensions).force_encoding("utf-8")
end

def to_commonmark(flags: DEFAULT, width: 0)

Convert the node to a CommonMark string.

Signature

parameter flags Integer

The enabled rendering flags.

parameter width Integer

The column at which to wrap output, or 0 to disable wrapping.

returns String

The rendered CommonMark text.

Implementation

def to_commonmark(flags: DEFAULT, width: 0)
	_render_commonmark(flags, width).force_encoding("utf-8")
end

def code_language

Return the language identifier from the code info string.

Signature

returns String | Nil

The language identifier, or nil when none is present.

Implementation

def code_language
	code_info.split(/\s+/, 2).first
end

def to_plaintext(flags: DEFAULT, width: 0)

Convert the node to a plain-text string.

Signature

parameter flags Integer

The enabled rendering flags.

parameter width Integer

The column at which to wrap output, or 0 to disable wrapping.

returns String

The rendered plain text.

Implementation

def to_plaintext(flags: DEFAULT, width: 0)
	_render_plaintext(flags, width).force_encoding("utf-8")
end

def each

Iterate over the direct children of this node.

Signature

yields {|child| ...}

Each direct child of this node.

parameter child Markly::Node

The current child node.

returns Enumerator | Nil

An enumerator when no block is given.

Implementation

def each
	return enum_for(:each) unless block_given?
	
	child = first_child
	while child
		next_child = child.next
		yield child
		child = next_child
	end
end

def find_header(title)

Finds a direct child header with the given text.

Signature

parameter title String

The header text to match.

returns Markly::Node | Nil

The matching header, if present.

Implementation

def find_header(title)
	each do |child|
		if child.type == :header && child.first_child.string_content == title
			return child
		end
	end
end

def delete_until

Delete all nodes until the block returns true.

Signature

yields {|node| ...}

Each node before it is deleted.

parameter node Markly::Node

The current node.

returns Markly::Node | Nil

The node for which the block returned true, if any.

Implementation

def delete_until
	current = self
	while current
		return current if yield(current)
		next_node = current.next
		current.delete
		current = next_node
	end
end

def replace_section(new_node, replace_header: true, remove_subsections: true)

Replace a section (header + content) with a new node.

Signature

parameter new_node Markly::Node | Nil

The node with which to replace the section.

parameter replace_header Boolean

Whether to replace the header itself.

parameter remove_subsections Boolean

Whether to remove subsections.

Implementation

def replace_section(new_node, replace_header: true, remove_subsections: true)
	# Delete until the next heading:
	self.next&.delete_until do |node|
		node.type == :header && (!remove_subsections || node.header_level <= self.header_level)
	end
	
	self.append_after(new_node) if new_node
	self.delete if replace_header
end

def next_header

Finds the next sibling header.

Signature

returns Markly::Node | Nil

The next header, if present.

Implementation

def next_header
	current = self.next
	while current
		if current.type == :header
			return current
		end
		current = current.next
	end
end

alias next_heading next_header

An alias for Markly::Node#next_header.

def append_after(node)

Append the given node after the current node.

It's okay to provide a document node, its children will be appended.

Signature

parameter node Markly::Node

The node to append.

Implementation

def append_after(node)
	if node.type == :document
		node = node.first_child
	end
	
	current = self
	while node
		next_node = node.next
		current.insert_after(node)
		current = node
		node = next_node
	end
end

def append_before(node)

Append the given node before the current node.

It's okay to provide a document node, its children will be appended.

Signature

parameter node Markly::Node

The node to append.

Implementation

def append_before(node)
	if node.type == :document
		node = node.first_child
	end
	
	current = self
	while node
		next_node = node.next
		current.insert_before(node)
		node = next_node
	end
end

def extract_children

Extract the children as a fragment.

Signature

returns Markly::Node

The fragment.

Implementation

def extract_children
	fragment = Markly::Node.new(:custom_inline)
	
	while child = self.first_child
		fragment.append_child(child)
	end
	
	fragment
end