class Paru::PandocFilter::Node

Every node in a Pandoc AST is mapped to Node. Filters are all about manipulating Nodes.

@!attribute parent

@return [Node] the parent node, if any.

Attributes

parent[RW]

Public Class Methods

from_markdown(markdown_string) click to toggle source

Create a new node from a markdown string. This is always a block level node. If more than one new node is created, a {Div} is created as a parent for the newly created block nodes..

@param markdown_string [String] the markdown string to convert

to a AST node

@return [Block|Div] The {Block} node created by converting

markdown_string with pandoc; A {Div} node if this conversion
holds more than one {Block} node.
# File lib/paru/filter/node.rb, line 148
def self.from_markdown(markdown_string)
    node = Node.new []
    node.outer_markdown = markdown_string

    if node.children.size == 1
        node = node.children.first
    else
        container = from_markdown "<div></div>"
        container.children = node.children
        node = container
    end

    return node 
end
new(contents = [], inline_children = false) click to toggle source

Create a new Node with contents. Also indicate if this node has inline children or block children.

@param contents [Array<pandoc node in JSON> = []] the contents of

this node

@param inline_children [Boolean] does this node have

inline children (true) or block children (false).
# File lib/paru/filter/node.rb, line 115
def initialize(contents = [], inline_children = false)
    @children = []
    @parent = nil

    if contents.is_a? Array
        contents.each do |elt|
            if PandocFilter.const_defined? elt["t"]
                child = PandocFilter.const_get(elt["t"]).new elt["c"]
            else
                if inline_children
                    child = PandocFilter::Inline.new elt["c"]
                else
                    child = PandocFilter::Plain.new elt["c"]
                end
            end

            child.parent = self
            @children.push child
        end
    end
end

Public Instance Methods

ast_contents() click to toggle source

An AST representation of the contents of this node

@return [Array]

# File lib/paru/filter/node.rb, line 330
def ast_contents()
    if has_children?
        @children.map {|child| child.to_ast}
    else
        []
    end
end
ast_type() click to toggle source

The AST type of this Node

@return [String]

# File lib/paru/filter/node.rb, line 323
def ast_type()
    self.class.name.split("::").last
end
can_act_as_both_block_and_inline?() click to toggle source

Can this node act both as a block and inline node? Some nodes are hybrids in this regard, like Math or Image

@return [Boolean]

# File lib/paru/filter/node.rb, line 265
def can_act_as_both_block_and_inline?()
    false
end
children() click to toggle source

Get this node’s children,

@return [Array<Node>] this node’s children as an Array.

# File lib/paru/filter/node.rb, line 183
def children()
    if has_children?
        @children
    else
        []
    end
end
children=(list) click to toggle source

Set this node’s children

@param list [Array<Node>] a list with nodes

# File lib/paru/filter/node.rb, line 194
def children=(list)
    @children = list
end
each() { |child| ... } click to toggle source

For each child of this Node, yield the child

@yield [Node]

# File lib/paru/filter/node.rb, line 166
def each()
    @children.each do |child|
        yield child
    end
end
get_replacement() click to toggle source

Get this node’s replacemnt. Nil if it has not been replaced by the {markdown} method

@return [Node] This node’s replacement or nil if there is none.

# File lib/paru/filter/node.rb, line 427
def get_replacement
    @replacement
end
has_been_replaced?() click to toggle source

Has this node been replaced by using the {markdown} method? If so, return true.

@return [Boolean]

# File lib/paru/filter/node.rb, line 419
def has_been_replaced?
    not @replacement.nil?
end
has_block?() click to toggle source

Does this node have Block contents?

@return [Boolean] true if this node has Block contents, false

otherwise
# File lib/paru/filter/node.rb, line 249
def has_block?()
    false
end
has_children?() click to toggle source

Does this node have any children?

@return [Boolean] True if this node has any children, false

otherwise.
# File lib/paru/filter/node.rb, line 176
def has_children?()
    defined? @children and not @children.nil? and @children.size > 0
end
has_class?(name) click to toggle source

If this node has attributes with classes, is name among them?

@param name [String] the class name to search for

@return [Boolean] true if this node has attributes with classes

and name is among them, false otherwise
# File lib/paru/filter/node.rb, line 298
def has_class?(name)
    if not @attr.nil?
        @attr.has_class? name
    else
        false
    end
end
has_inline?() click to toggle source

Does this node have Inline contents?

@return [Boolean] true if this node has Inline contents, false

otherwise
# File lib/paru/filter/node.rb, line 241
def has_inline?()
    false
end
has_parent?() click to toggle source

Does this node have a parent?

@return [Boolean] True if this node has a parent, false

otherwise.
# File lib/paru/filter/node.rb, line 202
def has_parent?()
    not @parent.nil?
end
has_string?() click to toggle source

Does this node has a string value?

@return [Boolean] true if this node has a string value, false

otherwise
# File lib/paru/filter/node.rb, line 233
def has_string?()
    false
end
is_block?() click to toggle source

Is this node a Block level node?

@return [Boolean] true if this node is a block level node, false

otherwise
# File lib/paru/filter/node.rb, line 257
def is_block?()
    false
end
is_inline?() click to toggle source

Is this an Inline level node?

@return [Boolean] true if this node is an inline level node,

false otherwise
# File lib/paru/filter/node.rb, line 273
def is_inline?()
    false
end
is_leaf?() click to toggle source

Is this Node a leaf? See also is_node?

@return [Boolean] A node is a leaf when it has no children

false otherwise
# File lib/paru/filter/node.rb, line 225
def is_leaf?()
    not has_children?
end
is_node?() click to toggle source

Is this Node a Node or a leaf? See is_leaf?

@return [Boolean] A node is a node if it is not a leaf.

# File lib/paru/filter/node.rb, line 217
def is_node?()
    not is_leaf
end
is_root?() click to toggle source

Is this a root node?

@return [Boolean] True if this node has a no parent, false

otherwise
# File lib/paru/filter/node.rb, line 210
def is_root?()
    not has_parent?
end
markdown() click to toggle source

Get the markdown representation of this Node, including the Node itself.

@return [String] the outer markdown representation of this Node

# File lib/paru/filter/node.rb, line 352
def markdown()
    temp_doc = PandocFilter::Document.fragment [self]
    markdown = AST2MARKDOWN << temp_doc.to_JSON
    markdown
end
Also aliased as: outer_markdown
markdown=(markdown) click to toggle source

Set the markdown representation of this Node: replace this Node by the Node represented by the markdown string. If an inline node is being replaced and the replacement has more than one paragraph, only the contents of the first paragraph is used

@param markdown [String] the markdown string to replace this

Node

@example Replacing all horizontal lines by a Plain node saying “hi”

Paru::Filter.run do
    with "HorizontalLine" do |line|
        line.markdown = "hi"
    end
end
# File lib/paru/filter/node.rb, line 375
def markdown=(markdown)
    json = MARKDOWN2JSON << markdown
    temp_doc = PandocFilter::Document.from_JSON json

    if not has_parent? or is_root?
        @children = temp_doc.children
    else
        # replace current node by new nodes
        # There is a difference between inline and block nodes
        current_index = parent.find_index self

        # By default, pandoc creates a Block level node when
        # converting a string. However, if the original is a
        # inline level node, so should its replacement node(s) be.
        # Only using first block node (paragraph?)
        if is_inline?
            temp_doc = temp_doc.children.first

            if not temp_doc.children.all? {|node| node.is_inline?}
                raise Error.new "Cannot replace the inline level node represented by '#{self.markdown}' with markdown that converts to block level nodes: '#{markdown}'."
            end
        else
            replacement = temp_doc.children.first
            @replacement = replacement unless replacement.nil? or to_ast == replacement.to_ast
        end

        index = current_index
        temp_doc.each do |child|
            index += 1
            parent.insert index, child
        end
            

        # Remove the original node
        parent.remove_at current_index
    end
end
Also aliased as: outer_markdown=
outer_markdown()
Alias for: markdown
outer_markdown=(markdown)
Alias for: markdown=
toMetadata() click to toggle source

Convert this Node to a metadata value. If this Node {is_inline?}, it is converted to {MetaInlines} if it is {is_block?}, it is converted to {MetaBlocks}.

@return [MetaInlines|MetaBlocks]

# File lib/paru/filter/node.rb, line 282
def toMetadata()
    if is_inline? then
        MetaInlines.new to_ast, true
    elsif is_blocks? then
        MetaBlocks.new to_ast, false
    else
        # ?
    end
end
to_ast() click to toggle source

Create an AST representation of this Node

@return [Hash]

# File lib/paru/filter/node.rb, line 341
def to_ast()
    {
        "t" => ast_type,
        "c" => ast_contents
    }
end
to_s() click to toggle source

A String representation of this Node

@return [String]

# File lib/paru/filter/node.rb, line 309
def to_s()
    self.class.name
end
type() click to toggle source

The pandoc type of this Node

@return [String]

# File lib/paru/filter/node.rb, line 316
def type()
    ast_type
end