Class: MaRuKu::REXMLHTMLFragment

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

Overview

An HTMLFragment implementation using REXML

Instance Method Summary collapse

Constructor Details

#initialize(raw_html) ⇒ REXMLHTMLFragment

Returns a new instance of REXMLHTMLFragment.


150
151
152
153
154
155
156
157
# File 'lib/maruku/html.rb', line 150

def initialize(raw_html)
  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>'

  @fragment = REXML::Document.new(wrapped).root
end

Instance Method Details

#add_class(class_name) ⇒ Object

Add a class to the children of this fragment


166
167
168
169
170
# File 'lib/maruku/html.rb', line 166

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

#first_node_nameObject

The name of the first element in the fragment


160
161
162
163
# File 'lib/maruku/html.rb', line 160

def first_node_name
  first_child = @fragment.children.first
  (first_child && first_child.respond_to?(:name)) ? 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.


174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/maruku/html.rb', line 174

def process_markdown_inside_elements(doc)
  elts = []
  @fragment.each_element('//*[@markdown]') do |e|
    elts << e
  end

  d = @fragment.children.first
  if d && HTML_INLINE_ELEMS.include?(first_node_name)
    elts << d unless d.attributes['markdown']
    elts += span_descendents(d)
  end

  # find span elements or elements with 'markdown' attribute
  elts.each do |e|
    # should we parse block-level or span-level?
    how = e.attributes['markdown']
    e.attributes.delete('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.texts.each do |original_text|
      s = MaRuKu::Out::HTML.escapeHTML(original_text.value)
      unless s.strip.empty?
        # TODO extract common functionality
        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)

        new_html = "<dummy>"
        el.children_to_html.each do |x|
          new_html << x.to_s
        end
        new_html << "</dummy>"

        newdoc = REXML::Document.new(new_html).root

        p = original_text.parent
        newdoc.children.each do |c|
          p.insert_before(original_text, c)
        end

        p.delete(original_text)
      end
    end
  end
end

#to_htmlObject


226
227
228
229
230
231
# File 'lib/maruku/html.rb', line 226

def to_html
  formatter = REXML::Formatters::Default.new(true)
  @fragment.children.inject("") do |out, child|
    out << formatter.write(child, '')
  end
end