Module: Smarky

Defined in:
lib/smarky.rb,
lib/smarky/element.rb,
lib/smarky/version.rb,
lib/smarky/markdown/maruku.rb,
lib/smarky/markdown/kramdown.rb,
lib/smarky/markdown/redcarpet.rb

Defined Under Namespace

Modules: Markdown Classes: Element

Constant Summary collapse

VERSION =
"0.0.4"

Class Method Summary collapse

Class Method Details

.markdown_renderer(options = {}) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/smarky.rb', line 67

def self.markdown_renderer(options={})
  case options[:markdown_renderer]
  when :redcarpet
    require 'smarky/markdown/redcarpet'
    Smarky::Markdown::Redcarpet.new

  when :maruku
    require 'smarky/markdown/maruku'
    Smarky::Markdown::Maruku.new

  when :kramdown
    require 'smarky/markdown/kramdown'
    Smarky::Markdown::Kramdown.new

  else
    # Just use whatever's available.
    if defined?(::Redcarpet)
      require 'smarky/markdown/redcarpet'
      Smarky::Markdown::Redcarpet.new

    elsif defined?(::Kramdown)
    require 'smarky/markdown/kramdown'
      Smarky::Markdown::Kramdown.new

    elsif defined?(::Maruku)
    require 'smarky/markdown/maruku'
      Smarky::Markdown::Maruku.new

    else
      raise "Smarky currently requires Redcarpet, Kramdown, or Maruku!"
    end
  end
end

.parse(markdown, options = {}) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/smarky.rb', line 6

def self.parse(markdown, options={})
  html     = self.markdown_renderer(options).render(markdown)
  fragment = Nokogiri::HTML.fragment(html)

  article  = Element.new('article')
  section  = article
  current_level = nil

  fragment.children.each do |node|
    if (heading = node.name.match(/^h(\d)$/i))
      title = node.content

      new_section = Element.new('section', title)
      new_section.add_child(Element.new(node))
      new_section['id'] = title.downcase.gsub(/[^0-9A-Z]/i, '-')

      level = heading[1].to_i
      if current_level.nil? || level > current_level
        difference = level - (current_level || 1)
        while difference > 1
          wrapper_section = Element.new('section')
          section.add_child(wrapper_section)
          section = wrapper_section
          difference -= 1
        end

        section.add_child(new_section)
        section = new_section

      elsif level == current_level
        section.add_next_sibling(new_section)
        section = new_section

      else
        difference = current_level - level
        while difference > 0
          section = section.parent
          difference -= 1
        end

        section.add_next_sibling(new_section)
        section = new_section
      end

      current_level = level

    else
      section.add_child(Element.new(node))
    end
  end

  # Special case: when an <article> contains exactly one <section> and nothing more.
  if article.children.length == 1 && article.sections.length == 1
    only_section = article.sections.first
    only_section.name = 'article'
    return only_section
  end

  article
end