Class: MDOM::Builder

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

Overview

A builder (DSL) for constructing MDOM trees programmatically, as an alternative to parsing Markdown text.

Every method both appends the constructed node to the node currently being built and returns the builder itself, so calls chain. Blocks nest: while a block runs, the node it creates becomes the builder's current target, and the previous target is restored when the block returns.

doc = MDOM.build do |b|
b.h1 "Title"
b.p "A paragraph with *emphasis*."
b.list do
  b.item "one"
  b.item "two"
end
end
doc.to_markdown

String arguments to block- and inline-level methods are run through the inline parser, so emphasis, strong, code, links and images are recognised. Use the explicit inline methods (+em+, strong, code_span, link, image) when you need an exact structure; their string arguments are treated as literal text unless you nest an explicit method inside a block.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBuilder

Returns a new instance of Builder.



36
37
38
39
# File 'lib/mdom/builder.rb', line 36

def initialize
  @document = Document.new
  @stack = [@document]
end

Class Method Details

.build(builder = new, &block) ⇒ Object

Build a document with block (or a nested block passed to an explicit builder) and return it. See MDOM.build.



31
32
33
34
# File 'lib/mdom/builder.rb', line 31

def self.build(builder = new, &block)
  builder.document(&block)
  builder.to_document
end

Instance Method Details

#blockquote(*parts, &block) ⇒ Object Also known as: quote

A blockquote. +parts+/+block+ are parsed as block content.



114
115
116
117
118
# File 'lib/mdom/builder.rb', line 114

def blockquote(*parts, &block)
  node = Blockquote.new
  build_blocks(node, parts, &block)
  append(node)
end

#code_block(literal, lang: nil, fenced: true) ⇒ Object

A fenced code block. lang sets the info string.



122
123
124
# File 'lib/mdom/builder.rb', line 122

def code_block(literal, lang: nil, fenced: true)
  append(CodeBlock.new(literal.to_s, lang: lang, fenced: fenced))
end

#code_span(value) ⇒ Object

A code span (x). The argument is literal.



154
155
156
# File 'lib/mdom/builder.rb', line 154

def code_span(value)
  append(Code.new(value.to_s))
end

#document(&block) ⇒ Object

Build a document (the root node). With a block, the block is evaluated against this builder and its content is added to the root document. Returns the builder; use to_document / finish for the tree.



46
47
48
49
# File 'lib/mdom/builder.rb', line 46

def document(&block)
  push(@document) { instance_eval(&block) } if block
  self
end

#em(*parts, &block) ⇒ Object Also known as: emphasis

Emphasis (x). With a block, nested explicit inline methods are used; otherwise string arguments are parsed as inline content. Appends to the current target and returns the node.



137
138
139
140
141
142
# File 'lib/mdom/builder.rb', line 137

def em(*parts, &block)
  node = Emphasis.new
  build_inline(node, parts, &block)
  append(node)
  node
end

#h1(*parts, **attributes) ⇒ Object



58
# File 'lib/mdom/builder.rb', line 58

def h1(*parts, **attributes) = heading(1, *parts, **attributes)

#h2(*parts, **attributes) ⇒ Object



59
# File 'lib/mdom/builder.rb', line 59

def h2(*parts, **attributes) = heading(2, *parts, **attributes)

#h3(*parts, **attributes) ⇒ Object



60
# File 'lib/mdom/builder.rb', line 60

def h3(*parts, **attributes) = heading(3, *parts, **attributes)

#h4(*parts, **attributes) ⇒ Object



61
# File 'lib/mdom/builder.rb', line 61

def h4(*parts, **attributes) = heading(4, *parts, **attributes)

#h5(*parts, **attributes) ⇒ Object



62
# File 'lib/mdom/builder.rb', line 62

def h5(*parts, **attributes) = heading(5, *parts, **attributes)

#h6(*parts, **attributes) ⇒ Object



63
# File 'lib/mdom/builder.rb', line 63

def h6(*parts, **attributes) = heading(6, *parts, **attributes)

#hardbreakObject

A hard line break (two trailing spaces).



178
179
180
# File 'lib/mdom/builder.rb', line 178

def hardbreak
  append(Hardbreak.new)
end

#heading(level = 1, *parts, **attributes) ⇒ Object

An ATX heading. level defaults to 1; the remaining arguments are the heading's inline content.



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

def heading(level = 1, *parts, **attributes)
  node = Heading.new(level, children: inline_nodes(parts), attributes: attributes)
  append(node)
end

#hruleObject Also known as: hr

A horizontal rule.



127
128
129
# File 'lib/mdom/builder.rb', line 127

def hrule(*, **)
  append(Hrule.new)
end

#image(destination, alt: nil, title: nil) ⇒ Object

An image.



168
169
170
# File 'lib/mdom/builder.rb', line 168

def image(destination, alt: nil, title: nil)
  append(Image.new(destination, alt: alt, title: title))
end

#inspectObject

A human-readable tree rendering of the document built so far.



196
197
198
# File 'lib/mdom/builder.rb', line 196

def inspect
  to_document.inspect
end

#item(*parts, task: nil, checked: false, &block) ⇒ Object Also known as: li

A list item. Without a block, parts become a single paragraph.



93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/mdom/builder.rb', line 93

def item(*parts, task: nil, checked: false, &block)
  node = ListItem.new
  unless task.nil?
    node.attributes[:task] = true
    node.attributes[:checked] = checked ? true : false
  end
  if block
    push(node) { instance_eval(&block) }
  elsif !parts.empty?
    node.append(Paragraph.new(children: inline_nodes(parts)))
  end
  append(node)
end

A link. Without a block the label is the literal *label parts; with a block, nested explicit inline methods build the label.



160
161
162
163
164
165
# File 'lib/mdom/builder.rb', line 160

def link(destination, *label, title: nil, &block)
  node = Link.new(destination, title: title)
  build_inline(node, label, &block)
  append(node)
  node
end

#list(*items, ordered: false, tight: true, start: nil, &block) ⇒ Object

A list. ordered: true produces an ordered list; start: sets its first number. Without a block, items are wrapped into single-paragraph list items.



76
77
78
79
80
81
82
83
84
85
# File 'lib/mdom/builder.rb', line 76

def list(*items, ordered: false, tight: true, start: nil, &block)
  node = List.new(ordered: ordered, tight: tight, start: start)
  if block
    push(node) { instance_eval(&block) }
  else
    items.each { node.append(ListItem.new(children: [Paragraph.new])) }
    refill_items(node, items)
  end
  append(node)
end

#ol(*items, start: nil, &block) ⇒ Object

An ordered list, as a shorthand for list(ordered: true).



90
# File 'lib/mdom/builder.rb', line 90

def ol(*items, start: nil, &block) = list(*items, ordered: true, start: start, &block)

#paragraph(*parts, &block) ⇒ Object Also known as: p

A paragraph. With a block, the block's inline nodes become its children.



66
67
68
69
70
# File 'lib/mdom/builder.rb', line 66

def paragraph(*parts, &block)
  node = Paragraph.new
  build_inline(node, parts, &block)
  append(node)
end

#softbreakObject

A soft line break.



173
174
175
# File 'lib/mdom/builder.rb', line 173

def softbreak
  append(Softbreak.new)
end

#strong(*parts, &block) ⇒ Object

Strong (x).



146
147
148
149
150
151
# File 'lib/mdom/builder.rb', line 146

def strong(*parts, &block)
  node = Strong.new
  build_inline(node, parts, &block)
  append(node)
  node
end

#task(checked, *parts, &block) ⇒ Object

A task list item (+checked+ marks it done).



109
110
111
# File 'lib/mdom/builder.rb', line 109

def task(checked, *parts, &block)
  item(*parts, task: true, checked: checked, &block)
end

#to_documentObject Also known as: finish

The document built so far.



185
186
187
# File 'lib/mdom/builder.rb', line 185

def to_document
  @document
end

#to_markdownObject

Serialize the document built so far to Markdown.



191
192
193
# File 'lib/mdom/builder.rb', line 191

def to_markdown
  @document.to_markdown
end

#ul(*items, &block) ⇒ Object

An unordered list, as a shorthand for list(ordered: false).



88
89
# File 'lib/mdom/builder.rb', line 88

def ul(*items, &block) = list(*items, ordered: false, &block)
# An ordered list, as a shorthand for +list(ordered: true)+.