kramdown を使って Markdown をパースしてあれこれる

  • 9
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

一般人にMarkdownを書いてもらって、それをうまいことなんらかに使いたいなぁーと。

そもそも、HTMLに一発で変換してくれるステキなライブラリはあるけれど、パースした結果が欲しいってのはあるのかないのかピンとこなかったので、kramdownを調べてみた。

導入

gem install kramdown

コード

抜粋

main.rb

def own_inspect(node, deep)
  deep_puts(
    "TYPE:#{node.type} => VALUE:'#{node.value}' / ATTR:'#{node.attr}'",
    deep
  )
  node.children.each do |child|
    own_inspect(child, deep + 1)
  end
end

doc =  Kramdown::Document.new(text)
deep = 0
own_inspect(doc.root, deep)

textを読み込ませてパース。結果は、doc.rootを手繰っていけばよい。runできるコードは最下段参照。

まとめ

何にパースされたのか?は .type を見ればOKで、中身は .value で取ればOK。

子要素はchildrenで取れる。

リンクなどなどは、 .attr[] にある。基本 .type で分岐すればあれこれできるようだ。

しかし、がんばるより、htmlに置き換えたものをhtmlパーサに食わせて操作したり、置換したりしたほうが早い気がするね・・・。

動くものと動作ログ

main.rb
require 'kramdown'

def deep_puts(v, deep)
  deep.times { print '  ' }
  puts v
end

def own_inspect(node, deep)
  deep_puts(
    "TYPE:#{node.type} => VALUE:'#{node.value}' / ATTR:'#{node.attr}'",
    deep
  )
  node.children.each do |child|
    own_inspect(child, deep + 1)
  end
end


text = <<EOS
#aaa
e

#ccc

- h
- i
  - ii
  - iii

#inline
abc **def** ghi

# Image
![Qiita](http://qiita.com/icons/favicons/public/apple-touch-icon.png "Qiita")

# Link
[blog]('http://blog.phalanxware.com')

EOS

doc =  Kramdown::Document.new(text)
puts doc.to_html

deep = 0

own_inspect(doc.root, deep)

実行結果

$ ruby main.rb
<h1 id="aaa">aaa</h1>
<p>e</p>

<h1 id="ccc">ccc</h1>

<ul>
  <li>h</li>
  <li>i
    <ul>
      <li>ii</li>
      <li>iii</li>
    </ul>
  </li>
</ul>

<h1 id="inline">inline</h1>
<p>abc <strong>def</strong> ghi</p>

<h1 id="image">Image</h1>
<p><img src="http://qiita.com/icons/favicons/public/apple-touch-icon.png" alt="Qiita" title="Qiita" /></p>

<h1 id="link">Link</h1>
<p><a href="'http://blog.phalanxware.com'">blog</a></p>

TYPE:root => VALUE:'' / ATTR:'{}'
  TYPE:header => VALUE:'' / ATTR:'{}'
    TYPE:text => VALUE:'aaa' / ATTR:'{}'
  TYPE:p => VALUE:'' / ATTR:'{}'
    TYPE:text => VALUE:'e' / ATTR:'{}'
  TYPE:blank => VALUE:'
' / ATTR:'{}'
  TYPE:header => VALUE:'' / ATTR:'{}'
    TYPE:text => VALUE:'ccc' / ATTR:'{}'
  TYPE:blank => VALUE:'
' / ATTR:'{}'
  TYPE:ul => VALUE:'' / ATTR:'{}'
    TYPE:li => VALUE:'' / ATTR:'{}'
      TYPE:p => VALUE:'' / ATTR:'{}'
        TYPE:text => VALUE:'h' / ATTR:'{}'
    TYPE:li => VALUE:'' / ATTR:'{}'
      TYPE:p => VALUE:'' / ATTR:'{}'
        TYPE:text => VALUE:'i
' / ATTR:'{}'
      TYPE:ul => VALUE:'' / ATTR:'{}'
        TYPE:li => VALUE:'' / ATTR:'{}'
          TYPE:p => VALUE:'' / ATTR:'{}'
            TYPE:text => VALUE:'ii' / ATTR:'{}'
        TYPE:li => VALUE:'' / ATTR:'{}'
          TYPE:p => VALUE:'' / ATTR:'{}'
            TYPE:text => VALUE:'iii' / ATTR:'{}'
  TYPE:blank => VALUE:'
' / ATTR:'{}'
  TYPE:header => VALUE:'' / ATTR:'{}'
    TYPE:text => VALUE:'inline' / ATTR:'{}'
  TYPE:p => VALUE:'' / ATTR:'{}'
    TYPE:text => VALUE:'abc ' / ATTR:'{}'
    TYPE:strong => VALUE:'' / ATTR:'{}'
      TYPE:text => VALUE:'def' / ATTR:'{}'
    TYPE:text => VALUE:' ghi' / ATTR:'{}'
  TYPE:blank => VALUE:'
' / ATTR:'{}'
  TYPE:header => VALUE:'' / ATTR:'{}'
    TYPE:text => VALUE:'Image' / ATTR:'{}'
  TYPE:p => VALUE:'' / ATTR:'{}'
    TYPE:img => VALUE:'' / ATTR:'{"src"=>"http://qiita.com/icons/favicons/public/apple-touch-icon.png", "alt"=>"Qiita", "title"=>"Qiita"}'
  TYPE:blank => VALUE:'
' / ATTR:'{}'
  TYPE:header => VALUE:'' / ATTR:'{}'
    TYPE:text => VALUE:'Link' / ATTR:'{}'
  TYPE:p => VALUE:'' / ATTR:'{}'
    TYPE:a => VALUE:'' / ATTR:'{"href"=>"'http://blog.phalanxware.com'"}'
      TYPE:text => VALUE:'blog' / ATTR:'{}'
  TYPE:blank => VALUE:'
' / ATTR:'{}'