Class: MaRuKu::NokogiriHTMLFragment

Inherits:
Object
  • Object
show all
Defined in:
lib/maruku/html.rb

Overview

Nokogiri backend for HTML handling

Instance Method Summary collapse

Constructor Details

#initialize(raw_html) ⇒ NokogiriHTMLFragment



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/maruku/html.rb', line 49

def initialize(raw_html)
  # Wrap our HTML in a dummy document with a doctype (just
  # for the entity references)
  wrapped = '<!DOCTYPE html PUBLIC
  "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
  "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
<html>' + raw_html.strip + '</html>'

  d = Nokogiri::XML::Document.parse(wrapped) {|c| c.nonet }
  @fragment = d.root
end

Instance Method Details

#add_class(class_name) ⇒ Object

Add a class to the children of this fragment



68
69
70
71
72
# File 'lib/maruku/html.rb', line 68

def add_class(class_name)
  @fragment.children.each do |c|
    c['class'] = ((c['class']||'').split(' ') + [class_name]).join(' ')
  end
end

#first_node_nameObject



62
63
64
65
# File 'lib/maruku/html.rb', line 62

def first_node_name
  first_child = @fragment.children.first
  first_child ? first_child.name : nil
end

#process_markdown_inside_elements(doc) ⇒ Object

Process markdown within the contents of some elements and replace their contents with the processed version.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/maruku/html.rb', line 78

def process_markdown_inside_elements(doc)
  # find span elements or elements with 'markdown' attribute
  elts = @fragment.css("[markdown]")

  d = @fragment.children.first
  if d && HTML_INLINE_ELEMS.include?(d.name)
    elts << d unless d.attribute('markdown')
    elts += span_descendents(d)
  end

  elts.each do |e|
    how = e['markdown']
    e.remove_attribute('markdown')

    next if "0" == how # user requests no markdown parsing inside
    parse_blocks = (how == 'block') || BLOCK_TAGS.include?(e.name)

    # Select all text children of e
    e.xpath("./text()").each do |original_text|
      s = MaRuKu::Out::HTML.escapeHTML(original_text.text)
      unless s.strip.empty?
        parsed = parse_blocks ? doc.parse_text_as_markdown(s) : doc.parse_span(s)

        # restore leading and trailing spaces
        padding = /\A(\s*).*?(\s*)\z/.match(s)
        parsed = [padding[1]] + parsed + [padding[2]] if padding

        el = doc.md_el(:dummy, parsed)

        # Nokogiri collapses consecutive Text nodes, so replace it by a dummy element
        guard = Nokogiri::XML::Element.new('guard', @fragment)
        original_text.replace(guard)
        el.children_to_html.each do |x|
          guard.before(x.to_s)
        end
        guard.remove
      end
    end
  end
end

#to_htmlString

Convert this fragment to an HTML or XHTML string.



121
122
123
124
125
126
127
# File 'lib/maruku/html.rb', line 121

def to_html
  output_options = Nokogiri::XML::Node::SaveOptions::DEFAULT_XHTML ^
    Nokogiri::XML::Node::SaveOptions::FORMAT
  @fragment.children.inject("") do |out, child|
    out << child.serialize(:save_with => output_options, :encoding => 'UTF-8')
  end
end