Add builder pattern for paragraph, lists, tables
This commit is contained in:
114
lib/ezdoc/builder.rb
Normal file
114
lib/ezdoc/builder.rb
Normal file
@@ -0,0 +1,114 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Ezdoc
|
||||
module Builder
|
||||
def p(text = nil, &block)
|
||||
para = Nodes::Paragraph.new
|
||||
if block
|
||||
with_target(para, &block)
|
||||
elsif text
|
||||
para.add_run(Nodes::Run.new(text, **current_formatting))
|
||||
end
|
||||
@nodes << para
|
||||
end
|
||||
|
||||
def text(value)
|
||||
@current_target.add_run(Nodes::Run.new(value, **current_formatting))
|
||||
end
|
||||
|
||||
def b(&block)
|
||||
with_format(:bold, &block)
|
||||
end
|
||||
|
||||
def i(&block)
|
||||
with_format(:italic, &block)
|
||||
end
|
||||
|
||||
def u(&block)
|
||||
with_format(:underline, &block)
|
||||
end
|
||||
|
||||
def ul(&block)
|
||||
list(:bullet, &block)
|
||||
end
|
||||
|
||||
def ol(&block)
|
||||
list(:number, &block)
|
||||
end
|
||||
|
||||
def li(text = nil, &block)
|
||||
item = Nodes::ListItem.new([], list_type: @current_list.type, num_id: @current_list.num_id)
|
||||
if block
|
||||
with_target(item, &block)
|
||||
elsif text
|
||||
item.add_run(Nodes::Run.new(text, **current_formatting))
|
||||
end
|
||||
@current_list.add_item(item)
|
||||
end
|
||||
|
||||
def table(&block)
|
||||
tbl = Nodes::Table.new
|
||||
previous_table = @current_table
|
||||
@current_table = tbl
|
||||
block.call
|
||||
@current_table = previous_table
|
||||
@nodes << tbl
|
||||
end
|
||||
|
||||
def tr(&block)
|
||||
row = Nodes::TableRow.new
|
||||
previous_row = @current_row
|
||||
@current_row = row
|
||||
block.call
|
||||
@current_row = previous_row
|
||||
@current_table.add_row(row)
|
||||
end
|
||||
|
||||
def td(text = nil, &block)
|
||||
cell = Nodes::TableCell.new
|
||||
if block
|
||||
with_target(cell, &block)
|
||||
elsif text
|
||||
cell.add_run(Nodes::Run.new(text, **current_formatting))
|
||||
end
|
||||
@current_row.add_cell(cell)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def list(type, &block)
|
||||
@num_id_counter ||= 0
|
||||
@num_id_counter += 1
|
||||
|
||||
list_node = Nodes::List.new(type: type, num_id: @num_id_counter)
|
||||
previous_list = @current_list
|
||||
@current_list = list_node
|
||||
block.call
|
||||
@current_list = previous_list
|
||||
@nodes << list_node
|
||||
end
|
||||
|
||||
def with_format(format, &block)
|
||||
@format_stack ||= []
|
||||
@format_stack.push(format)
|
||||
block.call
|
||||
@format_stack.pop
|
||||
end
|
||||
|
||||
def with_target(target, &block)
|
||||
previous_target = @current_target
|
||||
@current_target = target
|
||||
block.call
|
||||
@current_target = previous_target
|
||||
end
|
||||
|
||||
def current_formatting
|
||||
@format_stack ||= []
|
||||
{
|
||||
bold: @format_stack.include?(:bold),
|
||||
italic: @format_stack.include?(:italic),
|
||||
underline: @format_stack.include?(:underline)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user