dato_dast 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.projections.json +4 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +6 -0
- data/CODE_OF_CONDUCT.md +128 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +58 -0
- data/README.md +1082 -0
- data/Rakefile +8 -0
- data/TODO.md +0 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/dato_dast.gemspec +29 -0
- data/lib/dato_dast/configuration.rb +121 -0
- data/lib/dato_dast/errors/block_field_missing.rb +15 -0
- data/lib/dato_dast/errors/block_node_missing_render_function.rb +15 -0
- data/lib/dato_dast/errors/invalid_block_structure_type.rb +6 -0
- data/lib/dato_dast/errors/invalid_blocks_configuration.rb +18 -0
- data/lib/dato_dast/errors/invalid_marks_configuration.rb +15 -0
- data/lib/dato_dast/errors/invalid_nodes.rb +15 -0
- data/lib/dato_dast/errors/invalid_types_configuration.rb +15 -0
- data/lib/dato_dast/errors/missing_render_value_function.rb +15 -0
- data/lib/dato_dast/errors.rb +8 -0
- data/lib/dato_dast/extensions/middleman.rb +35 -0
- data/lib/dato_dast/html_tag.rb +74 -0
- data/lib/dato_dast/marks.rb +12 -0
- data/lib/dato_dast/nodes/attributed_quote.rb +20 -0
- data/lib/dato_dast/nodes/base.rb +113 -0
- data/lib/dato_dast/nodes/block.rb +124 -0
- data/lib/dato_dast/nodes/blockquote.rb +6 -0
- data/lib/dato_dast/nodes/code.rb +35 -0
- data/lib/dato_dast/nodes/generic.rb +21 -0
- data/lib/dato_dast/nodes/heading.rb +14 -0
- data/lib/dato_dast/nodes/inline_item.rb +14 -0
- data/lib/dato_dast/nodes/item_link.rb +29 -0
- data/lib/dato_dast/nodes/link.rb +57 -0
- data/lib/dato_dast/nodes/list.rb +9 -0
- data/lib/dato_dast/nodes/list_item.rb +6 -0
- data/lib/dato_dast/nodes/paragraph.rb +6 -0
- data/lib/dato_dast/nodes/root.rb +6 -0
- data/lib/dato_dast/nodes/span.rb +21 -0
- data/lib/dato_dast/nodes/thematic_break.rb +9 -0
- data/lib/dato_dast/nodes.rb +29 -0
- data/lib/dato_dast/version.rb +5 -0
- data/lib/dato_dast.rb +39 -0
- metadata +119 -0
data/Rakefile
ADDED
data/TODO.md
ADDED
File without changes
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "dato_dast"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/dato_dast.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/dato_dast/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "dato_dast"
|
7
|
+
spec.version = DatoDast::VERSION
|
8
|
+
spec.authors = ["John DeWyze"]
|
9
|
+
spec.email = ["john@dewyze.dev"]
|
10
|
+
|
11
|
+
spec.summary = "Gem for converting DatoCMS Structured Text to Html"
|
12
|
+
spec.description = "This gem provides a way to convert DatoCMS structured text to Html, as well as an extension for Middleman."
|
13
|
+
spec.homepage = "https://github.com/dewyze/dato_dast"
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
15
|
+
|
16
|
+
spec.metadata["homepage_uri"] = "https://github.com/dewyze/dato_dast"
|
17
|
+
spec.metadata["source_code_uri"] = "https://github.com/dewyze/dato_dast"
|
18
|
+
spec.metadata["changelog_uri"] = "https://github.com/dewyze/dato_dast/blob/main/CHANGELOG.md."
|
19
|
+
|
20
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
21
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
22
|
+
end
|
23
|
+
spec.bindir = "exe"
|
24
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
25
|
+
spec.require_paths = ["lib"]
|
26
|
+
|
27
|
+
spec.add_dependency "activesupport"
|
28
|
+
spec.add_development_dependency "pry-byebug"
|
29
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DatoDast
|
4
|
+
class Configuration
|
5
|
+
TYPE_CONFIG = {
|
6
|
+
Nodes::Block.type => { "node" => Nodes::Block },
|
7
|
+
Nodes::Blockquote.type => { "tag" => "blockquote", "node" => Nodes::AttributedQuote },
|
8
|
+
Nodes::Code.type => { "tag" => "code", "node" => Nodes::Code, "wrappers" => ["pre"] },
|
9
|
+
Nodes::Generic.type => { "node" => Nodes::Generic },
|
10
|
+
Nodes::Heading.type => { "tag" => ->(node) { "h#{node.level}" }, "node" => Nodes::Heading },
|
11
|
+
Nodes::ItemLink.type => { "tag" => "a", "node" => Nodes::ItemLink, "url_key" => :slug },
|
12
|
+
Nodes::Link.type => { "tag" => "a", "node" => Nodes::Link },
|
13
|
+
Nodes::List.type => { "tag" => ->(node) { node.style == "bulleted" ? "ul" : "ol" }, "node" => Nodes::List },
|
14
|
+
Nodes::ListItem.type => { "tag" => "li", "node" => Nodes::ListItem },
|
15
|
+
Nodes::Paragraph.type => { "tag" => "p", "node" => Nodes::Paragraph },
|
16
|
+
Nodes::Root.type => { "tag" => "div", "node" => Nodes::Root },
|
17
|
+
Nodes::Span.type => { "node" => Nodes::Span },
|
18
|
+
Nodes::ThematicBreak.type => { "tag" => "hr", "node" => Nodes::ThematicBreak },
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
MARK_CONFIG = {
|
22
|
+
Marks::CODE => { "tag" => "code" },
|
23
|
+
Marks::EMPHASIS => { "tag" => "em" },
|
24
|
+
Marks::HIGHLIGHT => { "tag" => "mark" },
|
25
|
+
Marks::STRIKETHROUGH => { "tag" => "strike" },
|
26
|
+
Marks::STRONG => { "tag" => "strong" },
|
27
|
+
Marks::UNDERLINE => { "tag" => "u" },
|
28
|
+
}.freeze
|
29
|
+
|
30
|
+
BLOCK_RENDER_KEYS = ["node", "render_value", "structure"].freeze
|
31
|
+
|
32
|
+
attr_reader :blocks, :host, :marks, :types
|
33
|
+
attr_accessor :highlight, :item_links, :smart_links
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
@blocks = {}
|
37
|
+
@highlight = true
|
38
|
+
@host = nil
|
39
|
+
@item_links = {}
|
40
|
+
@marks = MARK_CONFIG.transform_values { |value| value.dup }
|
41
|
+
@smart_links = true
|
42
|
+
@types = TYPE_CONFIG.transform_values { |value| value.dup }
|
43
|
+
end
|
44
|
+
|
45
|
+
def host=(new_host)
|
46
|
+
uri = URI(new_host)
|
47
|
+
|
48
|
+
if uri.host.present?
|
49
|
+
@host = uri.host
|
50
|
+
else
|
51
|
+
@host = uri.to_s
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def blocks=(new_blocks)
|
56
|
+
validate_blocks_configuration(new_blocks)
|
57
|
+
|
58
|
+
@blocks = new_blocks
|
59
|
+
end
|
60
|
+
|
61
|
+
def marks=(new_marks)
|
62
|
+
validate_marks_configuration(new_marks)
|
63
|
+
|
64
|
+
@marks.merge!(new_marks)
|
65
|
+
end
|
66
|
+
|
67
|
+
def types=(new_types)
|
68
|
+
validate_types(new_types)
|
69
|
+
|
70
|
+
@types.merge!(new_types)
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_wrapper(type, wrapper)
|
74
|
+
wrappers = Array.wrap(@types[type]["wrappers"])
|
75
|
+
wrappers << wrapper
|
76
|
+
@types[type]["wrappers"] = wrappers
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def validate_blocks_configuration(blocks_config)
|
82
|
+
invalid_blocks = []
|
83
|
+
|
84
|
+
blocks_config.each do |block, block_config|
|
85
|
+
next if block_config.is_a?(Proc)
|
86
|
+
|
87
|
+
intersection = block_config.keys & BLOCK_RENDER_KEYS
|
88
|
+
invalid_blocks << block unless intersection.length == 1
|
89
|
+
end
|
90
|
+
|
91
|
+
raise Errors::InvalidBlocksConfiguration.new(invalid_blocks) if invalid_blocks.present?
|
92
|
+
end
|
93
|
+
|
94
|
+
def validate_types(types_config)
|
95
|
+
invalid_configs = []
|
96
|
+
invalid_nodes = []
|
97
|
+
|
98
|
+
types_config.each do |type, type_config|
|
99
|
+
node = type_config["node"]
|
100
|
+
if node
|
101
|
+
invalid_nodes << type unless node.instance_methods.include?(:render)
|
102
|
+
else
|
103
|
+
invalid_configs << type
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
raise Errors::InvalidTypesConfiguration.new(invalid_configs) if invalid_configs.present?
|
108
|
+
raise Errors::InvalidNodes.new(invalid_nodes) if invalid_nodes.present?
|
109
|
+
end
|
110
|
+
|
111
|
+
def validate_marks_configuration(marks_config)
|
112
|
+
invalid_marks = []
|
113
|
+
|
114
|
+
marks_config.each do |mark, mark_config|
|
115
|
+
invalid_marks << mark unless mark_config.keys.include?("tag")
|
116
|
+
end
|
117
|
+
|
118
|
+
raise Errors::InvalidMarksConfiguration.new(invalid_marks) if invalid_marks.present?
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DatoDast
|
2
|
+
module Errors
|
3
|
+
class BlockFieldMissing < StandardError
|
4
|
+
MESSAGE = <<~MSG.strip
|
5
|
+
A structure type of 'field' requires the block to have the specified field.
|
6
|
+
|
7
|
+
The following block configuration is invalid:
|
8
|
+
MSG
|
9
|
+
|
10
|
+
def initialize(item_type)
|
11
|
+
super(MESSAGE + " " + item_type)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DatoDast
|
2
|
+
module Errors
|
3
|
+
class BlockNodeMissingRenderFunction < StandardError
|
4
|
+
MESSAGE = <<~MSG.strip
|
5
|
+
A node class provided for a block must have a 'render' method.
|
6
|
+
|
7
|
+
The node object for the following block item type is invalid:
|
8
|
+
MSG
|
9
|
+
|
10
|
+
def initialize(keys)
|
11
|
+
super(MESSAGE + " " + keys.join(", "))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module DatoDast
|
2
|
+
module Errors
|
3
|
+
class InvalidBlocksConfiguration < StandardError
|
4
|
+
MESSAGE = <<~MSG.strip
|
5
|
+
A block configuration requires exactly one of the following keys:
|
6
|
+
- "node"
|
7
|
+
- "render_value"
|
8
|
+
- "structure"
|
9
|
+
|
10
|
+
The following block configurations are invalid:
|
11
|
+
MSG
|
12
|
+
|
13
|
+
def initialize(keys)
|
14
|
+
super(MESSAGE + " " + keys.join(", "))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DatoDast
|
2
|
+
module Errors
|
3
|
+
class InvalidMarksConfiguration < StandardError
|
4
|
+
MESSAGE = <<~MSG.strip
|
5
|
+
A mark configuration requires only the "tag" key.
|
6
|
+
|
7
|
+
The following mark configurations are invalid:
|
8
|
+
MSG
|
9
|
+
|
10
|
+
def initialize(keys)
|
11
|
+
super(MESSAGE + " " + keys.join(", "))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DatoDast
|
2
|
+
module Errors
|
3
|
+
class InvalidNodes < StandardError
|
4
|
+
MESSAGE = <<~MSG.strip
|
5
|
+
A node class must have a 'render' instance method.
|
6
|
+
|
7
|
+
The node objects for the following types are invalid:
|
8
|
+
MSG
|
9
|
+
|
10
|
+
def initialize(keys)
|
11
|
+
super(MESSAGE + " " + keys.join(", "))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DatoDast
|
2
|
+
module Errors
|
3
|
+
class InvalidTypesConfiguration < StandardError
|
4
|
+
MESSAGE = <<~MSG.strip
|
5
|
+
A type configuration requires the "node" key.
|
6
|
+
|
7
|
+
The following type configurations are invalid:
|
8
|
+
MSG
|
9
|
+
|
10
|
+
def initialize(keys)
|
11
|
+
super(MESSAGE + " " + keys.join(", "))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DatoDast
|
2
|
+
module Errors
|
3
|
+
class MissingRenderValueFunction < StandardError
|
4
|
+
MESSAGE = <<~MSG.strip
|
5
|
+
A structure type of 'value' requires a render value function.
|
6
|
+
|
7
|
+
The following block configuration is invalid:
|
8
|
+
MSG
|
9
|
+
|
10
|
+
def initialize(item_type)
|
11
|
+
super(MESSAGE + " " + item_type)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require "dato_dast/errors/block_field_missing"
|
2
|
+
require "dato_dast/errors/block_node_missing_render_function"
|
3
|
+
require "dato_dast/errors/invalid_block_structure_type"
|
4
|
+
require "dato_dast/errors/invalid_blocks_configuration"
|
5
|
+
require "dato_dast/errors/invalid_marks_configuration"
|
6
|
+
require "dato_dast/errors/invalid_nodes"
|
7
|
+
require "dato_dast/errors/invalid_types_configuration"
|
8
|
+
require "dato_dast/errors/missing_render_value_function"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "middleman-core"
|
2
|
+
|
3
|
+
module DatoDast
|
4
|
+
module Extensions
|
5
|
+
class Middleman < Middleman::Extension
|
6
|
+
option :blocks, {}, "Configuration hash for blocks"
|
7
|
+
option :host, nil, "Host for your site, used in conjunction with 'smart_links' option"
|
8
|
+
option :highlight, true, "Toggle whether to attempt to higlight code blocks"
|
9
|
+
option :item_links, {}, "Configuration hash item links types and the url field"
|
10
|
+
option :marks, {}, "Configuration hash for a given mark"
|
11
|
+
option :smart_links, true, "Open Link items in new windows and ItemLinks in the same window"
|
12
|
+
option :types, {}, "Configuration hash for a given block node type"
|
13
|
+
|
14
|
+
def after_configuration
|
15
|
+
DatoDast.configure do |config|
|
16
|
+
config.blocks = options[:blocks]
|
17
|
+
config.highlight = options[:highlight]
|
18
|
+
config.host = options[:host]
|
19
|
+
config.item_links = options[:item_links]
|
20
|
+
config.marks = options[:marks]
|
21
|
+
config.smart_links = options[:smart_links]
|
22
|
+
config.types = options[:types]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
helpers do
|
27
|
+
def structured_text(object, config = nil)
|
28
|
+
DatoDast.structured_text(object, config)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
::Middleman::Extensions.register(:dato_dast, DatoDast::Extensions::Middleman)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module DatoDast
|
2
|
+
class HtmlTag
|
3
|
+
EMPTY = ""
|
4
|
+
NEWLINE = "\n"
|
5
|
+
|
6
|
+
def self.parse(tag, object = nil)
|
7
|
+
case tag
|
8
|
+
when String
|
9
|
+
new(tag)
|
10
|
+
when Hash
|
11
|
+
html_tag = tag["tag"]
|
12
|
+
css_class = tag["css_class"]
|
13
|
+
meta = tag["meta"]
|
14
|
+
|
15
|
+
HtmlTag.new(html_tag, { "css_class" => css_class, "meta" => meta, "object" => object })
|
16
|
+
when HtmlTag
|
17
|
+
tag
|
18
|
+
when nil
|
19
|
+
HtmlTag.new(nil)
|
20
|
+
else
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(tag, options = {})
|
26
|
+
@tag = tag
|
27
|
+
@css_class = options["css_class"] || ""
|
28
|
+
@meta = options["meta"] || {}
|
29
|
+
@object = options["object"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def open
|
33
|
+
return EMPTY unless tag
|
34
|
+
|
35
|
+
"<#{tag}#{css_class}#{meta}>" + NEWLINE
|
36
|
+
end
|
37
|
+
|
38
|
+
def close
|
39
|
+
return EMPTY unless tag
|
40
|
+
|
41
|
+
NEWLINE + "</#{tag}>"
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def tag
|
47
|
+
if @tag.is_a?(Proc)
|
48
|
+
@tag.call(@object)
|
49
|
+
else
|
50
|
+
@tag
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def css_class
|
55
|
+
return "" if @css_class.blank?
|
56
|
+
|
57
|
+
klass = @css_class.is_a?(Proc) ? @css_class.call(@object) : @css_class
|
58
|
+
|
59
|
+
" class=\"#{klass}\""
|
60
|
+
end
|
61
|
+
|
62
|
+
def meta
|
63
|
+
return "" if @meta.blank?
|
64
|
+
|
65
|
+
if @meta.is_a?(Proc)
|
66
|
+
" " + @meta.call(@object)
|
67
|
+
else
|
68
|
+
@meta.reduce("") do |html, pair|
|
69
|
+
html + " #{pair["id"]}=\"#{pair["value"]}\""
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module DatoDast
|
2
|
+
module Nodes
|
3
|
+
class AttributedQuote < Base
|
4
|
+
def attribution
|
5
|
+
@node["attribution"]
|
6
|
+
end
|
7
|
+
|
8
|
+
def render
|
9
|
+
<<~HTML
|
10
|
+
<figure>
|
11
|
+
#{super}
|
12
|
+
<figcaption>
|
13
|
+
#{attribution}
|
14
|
+
</figcaption>
|
15
|
+
</figure>
|
16
|
+
HTML
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module DatoDast
|
2
|
+
module Nodes
|
3
|
+
class Base
|
4
|
+
EMPTY = ""
|
5
|
+
NEWLINE = "\n"
|
6
|
+
|
7
|
+
def self.type
|
8
|
+
name.demodulize.camelize(:lower)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(node, links = [], blocks = [], config = nil)
|
12
|
+
@node = node
|
13
|
+
@links = links
|
14
|
+
@blocks = blocks
|
15
|
+
@config = config
|
16
|
+
end
|
17
|
+
|
18
|
+
def config
|
19
|
+
@config ||= DatoDast.configuration
|
20
|
+
end
|
21
|
+
|
22
|
+
def type
|
23
|
+
@node["type"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def children
|
27
|
+
@node["children"]
|
28
|
+
end
|
29
|
+
|
30
|
+
def wrappers
|
31
|
+
@node["wrappers"] || Array.wrap(node_config["wrappers"])
|
32
|
+
end
|
33
|
+
|
34
|
+
def tag
|
35
|
+
if node_config && node_config["tag"].is_a?(Proc)
|
36
|
+
node_config["tag"].call(proc_object)
|
37
|
+
else
|
38
|
+
@node["tag"] || node_config["tag"]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def css_class
|
43
|
+
if node_config && node_config["css_class"].is_a?(Proc)
|
44
|
+
node_config["css_class"].call(proc_object)
|
45
|
+
else
|
46
|
+
@node["css_class"] || node_config["css_class"]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def meta
|
51
|
+
if node_config && node_config["meta"].is_a?(Proc)
|
52
|
+
node_config["meta"].call(proc_object)
|
53
|
+
else
|
54
|
+
@node["meta"] || node_config["meta"]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def node_config
|
59
|
+
@node_config ||= config.types[type]
|
60
|
+
end
|
61
|
+
|
62
|
+
def tag_info
|
63
|
+
{
|
64
|
+
"tag" => tag,
|
65
|
+
"css_class" => css_class,
|
66
|
+
"meta" => meta,
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def render
|
71
|
+
open_wrappers +
|
72
|
+
html_tag.open +
|
73
|
+
render_value +
|
74
|
+
html_tag.close +
|
75
|
+
close_wrappers
|
76
|
+
end
|
77
|
+
|
78
|
+
def render_value
|
79
|
+
render_children
|
80
|
+
end
|
81
|
+
|
82
|
+
def render_children
|
83
|
+
return EMPTY unless children.present?
|
84
|
+
|
85
|
+
children.map do |child|
|
86
|
+
Nodes.wrap(child, @links, @blocks, config).render
|
87
|
+
end.join("\n").gsub(/\n+/, "\n")
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def html_tag
|
93
|
+
@html_tag ||= HtmlTag.parse(tag_info)
|
94
|
+
end
|
95
|
+
|
96
|
+
def open_wrappers
|
97
|
+
wrapper_tags.map(&:open).join("")
|
98
|
+
end
|
99
|
+
|
100
|
+
def close_wrappers
|
101
|
+
wrapper_tags.reverse.map(&:close).join("")
|
102
|
+
end
|
103
|
+
|
104
|
+
def wrapper_tags
|
105
|
+
@wrapper_tags ||= wrappers.map { |wrappers| HtmlTag.parse(wrappers, proc_object) }
|
106
|
+
end
|
107
|
+
|
108
|
+
def proc_object
|
109
|
+
self
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|