diff options
| author | John MacFarlane <jgm@berkeley.edu> | 2014-11-22 16:55:56 -0800 | 
|---|---|---|
| committer | John MacFarlane <jgm@berkeley.edu> | 2014-11-22 16:55:56 -0800 | 
| commit | 641bbf1f3b7c0f693f58119614404b107742e31c (patch) | |
| tree | c4d4ed30996efa607618baf305c8e55d4f66de59 | |
| parent | d2aadf673344a0841e91430f1239994ffbad61f1 (diff) | |
commonmark.rb:  Added 'transform' and demos.
| -rwxr-xr-x | commonmark.rb | 49 | 
1 files changed, 43 insertions, 6 deletions
| diff --git a/commonmark.rb b/commonmark.rb index b41b8fe..0140c1b 100755 --- a/commonmark.rb +++ b/commonmark.rb @@ -74,6 +74,7 @@ class Node      end    end +  # An iterator that "walks the tree," returning each node    def walk(&blk)      yield self      self.children.each do |child| @@ -81,6 +82,35 @@ class Node      end    end +  # Walk the tree and transform it.  blk should take one argument, +  # a node.  If its value is a node, that node replaces the node being +  # visited. If its value is an array of nodes, those nodes are spliced +  # in place of the node being visited (so, to delete a node, use an +  # empty array).  Otherwise the node is left as it is. +  def transform(&blk) +    self.walk do |node| +      skip = false +      res = blk.call(node) +      if res.kind_of?(Array) +        splice = res +      elsif res.kind_of?(Node) +        splice = [res] +      else +        skip = true +      end +      unless skip +        parent = node.parent +        if parent +          siblings = node.parent.children +          index = siblings.index(node) +          siblings.replace(siblings.slice(0,index) + splice + +                           siblings.slice(index + 1, siblings.length)) +        else # at the document root, just skip +        end +      end +    end +  end +    def self.parse_string(s)      Node.new(CMark::cmark_parse_document(s, s.bytesize))    end @@ -343,14 +373,21 @@ doc.walk do |node|    end  end -# Walk tree and transform links to regular text +# Capitalize strings in headers  doc.walk do |node| +  if node.type == :setext_header or node.type == :atx_header +    node.walk do |subnode| +      if subnode.type == :str +        subnode.string_content = subnode.string_content.upcase +      end +    end +  end +end + +# Walk tree and transform links to regular text +doc.transform do |node|    if node.type == :link -    parent = node.parent -    index = parent.children.index(node) -    len = parent.children.length -    parent.children.replace(parent.children.slice(0,index) + node.children + -                            parent.children.slice(index + 1, len)) +    node.children    end  end | 
