Class: Scrapetor::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/scrapetor/builder.rb

Overview

Pure-Ruby HTML construction DSL. No external dependency.

Two usage patterns:

# 1. Block with explicit receiver:
html = Scrapetor::Builder.build do |b|
  b.html do
    b.head { b.title "My Page" }
    b.body do
      b.h1 "Hello", class: "hdr"
      b.p "world", id: "lead"
      b.a("More", href: "/x")
    end
  end
end

# 2. Direct instance:
b = Scrapetor::Builder.new
b.div(class: "card") { b.h1 "Title" }
b.to_html

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&block) ⇒ Builder

Returns a new instance of Builder.



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/scrapetor/builder.rb', line 34

def initialize(&block)
  @stack = []
  @root  = []
  if block
    if block.arity == 1
      block.call(self)
    else
      instance_eval(&block)
    end
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object

Method-missing dispatch: any unknown method becomes a tag.

b.div("hi", class: "card") { b.span "x" }
  ->  <div class="card">hi<span>x</span></div>


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/scrapetor/builder.rb', line 74

def method_missing(name, *args, &block)
  content = nil
  attrs   = {}
  args.each do |a|
    case a
    when Hash   then attrs = attrs.merge(a)
    when String then content ||= a
    else             content ||= a.to_s
    end
  end
  element = Element.new(name.to_s, attrs, [])
  append(element)
  @stack.push(element)
  element.children << content unless content.nil?
  if block
    if block.arity == 1
      block.call(self)
    else
      instance_eval(&block)
    end
  end
  @stack.pop
  self
end

Class Method Details

.build(&block) ⇒ Object



30
31
32
# File 'lib/scrapetor/builder.rb', line 30

def self.build(&block)
  new(&block).to_html
end

Instance Method Details

#comment(s) ⇒ Object

Inject an HTML comment.



59
60
61
62
# File 'lib/scrapetor/builder.rb', line 59

def comment(s)
  append(Comment.new(s.to_s))
  self
end

#doctype(name = "html") ⇒ Object

Inject a doctype.



65
66
67
68
# File 'lib/scrapetor/builder.rb', line 65

def doctype(name = "html")
  append(Doctype.new(name.to_s))
  self
end

#raw(s) ⇒ Object

Inject pre-escaped raw HTML.



53
54
55
56
# File 'lib/scrapetor/builder.rb', line 53

def raw(s)
  append(RawHTML.new(s.to_s))
  self
end

#respond_to_missing?(_name, _include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/scrapetor/builder.rb', line 99

def respond_to_missing?(_name, _include_private = false)
  true
end

#text(s) ⇒ Object

Inject a raw text node at the current position.



47
48
49
50
# File 'lib/scrapetor/builder.rb', line 47

def text(s)
  append(s.to_s)
  self
end

#to_htmlObject Also known as: to_s



103
104
105
# File 'lib/scrapetor/builder.rb', line 103

def to_html
  @root.map { |n| serialize(n) }.join
end