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

Returns a new instance of 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

Returns The name of the first child element in the fragment.

Returns:

  • The name of the first child element in the fragment.



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.

Parameters:



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 = CGI.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.

Returns:



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