docrb-html 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +1 -1
- data/.rubocop.yml +32 -15
- data/Gemfile +11 -1
- data/Gemfile.lock +52 -2
- data/assets/breadcrumb.scss +0 -1
- data/assets/class_header.scss +1 -0
- data/assets/constant_display.scss +16 -0
- data/assets/doc_box.scss +34 -4
- data/assets/documentation_block.scss +29 -1
- data/assets/field_block.scss +46 -0
- data/assets/js/filtering.js +3 -3
- data/assets/links.scss +0 -2
- data/assets/method_argument.scss +2 -8
- data/assets/method_display.scss +4 -0
- data/assets/method_list.scss +40 -0
- data/assets/reference.scss +1 -1
- data/assets/style.scss +3 -0
- data/assets/svg.scss +37 -0
- data/assets/symbol.scss +1 -1
- data/assets/text_block.scss +9 -9
- data/bin/smoke +5 -0
- data/{renderer.gemspec → docrb-html.gemspec} +2 -0
- data/exe/docrb-html +1 -1
- data/lib/docrb-html.rb +165 -0
- data/lib/renderer/component/attribute.rb +9 -0
- data/lib/renderer/component/attribute_display.rb +17 -0
- data/lib/renderer/component/constant_display.rb +9 -0
- data/lib/renderer/component/doc_box.rb +26 -18
- data/lib/renderer/component/documentation_comment.rb +9 -0
- data/lib/renderer/component/field_block.rb +9 -0
- data/lib/renderer/component/method_argument.rb +19 -63
- data/lib/renderer/component/method_display.rb +1 -1
- data/lib/renderer/component/method_list.rb +1 -1
- data/lib/renderer/component/reference.rb +23 -12
- data/lib/renderer/component/text_block.rb +1 -7
- data/lib/renderer/component.rb +4 -4
- data/lib/renderer/core_extensions.rb +12 -1
- data/lib/renderer/entities/attribute.rb +17 -0
- data/lib/renderer/entities/attribute_definition.rb +23 -0
- data/lib/renderer/entities/base.rb +58 -0
- data/lib/renderer/entities/class.rb +17 -0
- data/lib/renderer/entities/container.rb +52 -0
- data/lib/renderer/entities/method.rb +18 -0
- data/lib/renderer/entities/method_argument.rb +27 -0
- data/lib/renderer/entities/method_definition.rb +25 -0
- data/lib/renderer/entities/module.rb +29 -0
- data/lib/renderer/entities/reference.rb +103 -0
- data/lib/renderer/entities/source_definition.rb +17 -0
- data/lib/renderer/entities.rb +30 -0
- data/lib/renderer/helpers.rb +77 -19
- data/lib/renderer/markdown.rb +62 -0
- data/lib/renderer/metadata.rb +10 -26
- data/lib/renderer/template.rb +4 -6
- data/lib/renderer/version.rb +1 -1
- data/script/makecomponent +1 -1
- data/templates/attribute.erb +10 -0
- data/templates/attribute_display.erb +22 -0
- data/templates/breadcrumb.erb +9 -9
- data/templates/class_header.erb +6 -7
- data/templates/component_list.erb +14 -8
- data/templates/constant_display.erb +13 -0
- data/templates/doc_box.erb +40 -31
- data/templates/documentation_block.erb +2 -11
- data/templates/documentation_comment.erb +23 -0
- data/templates/field_block.erb +15 -0
- data/templates/method_argument.erb +4 -4
- data/templates/method_display.erb +14 -21
- data/templates/method_list.erb +52 -8
- data/templates/reference.erb +10 -7
- data/templates/text_block.erb +13 -14
- metadata +60 -8
- data/lib/renderer/defs/specialized_object.rb +0 -172
- data/lib/renderer/defs/specialized_projection.rb +0 -31
- data/lib/renderer/defs.rb +0 -180
- data/lib/renderer.rb +0 -131
@@ -1,172 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Renderer
|
4
|
-
class Defs
|
5
|
-
class SpecializedObject
|
6
|
-
def initialize(obj, parent, provider)
|
7
|
-
@obj = obj
|
8
|
-
@provider = provider
|
9
|
-
prepare(parent)
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.specialize(obj, parent, provider)
|
13
|
-
return nil if obj.nil?
|
14
|
-
|
15
|
-
new(obj, parent, provider)
|
16
|
-
end
|
17
|
-
|
18
|
-
def [](key) = @obj[key]
|
19
|
-
def fetch(*, **, &) = @obj.fetch(*, **, &)
|
20
|
-
|
21
|
-
def resolve(name)
|
22
|
-
named = named_as(name)
|
23
|
-
modules.find(&named) \
|
24
|
-
|| classes.find(&named) \
|
25
|
-
|| attributes&.find(&named) \
|
26
|
-
|| defs.find(&named) \
|
27
|
-
|| sdefs.find(&named)
|
28
|
-
end
|
29
|
-
|
30
|
-
def resolve_inheritance(name)
|
31
|
-
named = named_as(name)
|
32
|
-
modules.find(&named) \
|
33
|
-
|| classes.find(&named) \
|
34
|
-
|| parent&.resolve_inheritance(name)
|
35
|
-
end
|
36
|
-
|
37
|
-
def resolve_parent(name)
|
38
|
-
parent = self[:parent]
|
39
|
-
return { type: "Unknown Ref", name: } unless parent
|
40
|
-
|
41
|
-
parent.resolve(name) || parent.resolve_parent(name)
|
42
|
-
end
|
43
|
-
|
44
|
-
def resolve_path(path)
|
45
|
-
p = path.dup
|
46
|
-
obj = self
|
47
|
-
until p.empty?
|
48
|
-
obj = obj.resolve(p[0])
|
49
|
-
return unless obj
|
50
|
-
|
51
|
-
p.shift
|
52
|
-
end
|
53
|
-
obj
|
54
|
-
end
|
55
|
-
|
56
|
-
def resolve_qualified(obj)
|
57
|
-
result = nil
|
58
|
-
query = nil
|
59
|
-
|
60
|
-
if obj[:class_path]&.length&.> 0
|
61
|
-
query = obj[:class_path] + [obj[:name]]
|
62
|
-
result = root.resolve_path(query)
|
63
|
-
else
|
64
|
-
query = obj[:name]
|
65
|
-
result = resolve(query)
|
66
|
-
result ||= resolve_inheritance(query)
|
67
|
-
end
|
68
|
-
|
69
|
-
puts "Qualified resolution of #{query.inspect} by #{name} failed." unless result
|
70
|
-
|
71
|
-
result
|
72
|
-
end
|
73
|
-
|
74
|
-
def method_missing(method_name, *args, **kwargs, &)
|
75
|
-
var = "@#{method_name}".to_sym
|
76
|
-
if instance_variables.include?(var)
|
77
|
-
instance_variable_get(var)
|
78
|
-
elsif @obj.key? method_name
|
79
|
-
@obj.fetch(method_name)
|
80
|
-
else
|
81
|
-
super
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def respond_to_missing?(method_name, include_private = false)
|
86
|
-
instance_variables.include?("@#{method_name}".to_sym) || @obj.key?(method_name) || super
|
87
|
-
end
|
88
|
-
|
89
|
-
def to_s
|
90
|
-
"<SpecializedObject for #{@provider.path_of(@obj).join("::")}>"
|
91
|
-
end
|
92
|
-
|
93
|
-
def inspect = to_s
|
94
|
-
|
95
|
-
def prepare_inheritance
|
96
|
-
@inheritance_prepared = true
|
97
|
-
@inherits = coerce_inheritance_data(@obj[:inherits])
|
98
|
-
@extends = @obj[:extends]&.map { resolve_qualified _1 }
|
99
|
-
@includes = @obj[:includes]&.map { resolve_qualified _1 }
|
100
|
-
@classes.each(&:prepare_inheritance)
|
101
|
-
@modules.each(&:prepare_inheritance)
|
102
|
-
end
|
103
|
-
|
104
|
-
private
|
105
|
-
|
106
|
-
def make_path
|
107
|
-
r = [name]
|
108
|
-
p = parent
|
109
|
-
while p
|
110
|
-
r << p.name
|
111
|
-
p = p.parent
|
112
|
-
end
|
113
|
-
|
114
|
-
r.reverse
|
115
|
-
end
|
116
|
-
|
117
|
-
def parent_of(parent)
|
118
|
-
return unless parent
|
119
|
-
|
120
|
-
p = parent
|
121
|
-
while p
|
122
|
-
return p unless p.parent
|
123
|
-
|
124
|
-
p = p.parent
|
125
|
-
end
|
126
|
-
|
127
|
-
p
|
128
|
-
end
|
129
|
-
|
130
|
-
def specialize_defs(defs, _parent)
|
131
|
-
defs.values.map do |i|
|
132
|
-
decoration = if i[:source] == "inheritance"
|
133
|
-
"inherited"
|
134
|
-
elsif i[:overriding]
|
135
|
-
"override"
|
136
|
-
else
|
137
|
-
""
|
138
|
-
end
|
139
|
-
|
140
|
-
origin = i[:source]
|
141
|
-
|
142
|
-
@provider.find_source(i)
|
143
|
-
.merge({ decoration:, origin: })
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def coerce_inheritance_data(obj)
|
148
|
-
return obj if obj.nil?
|
149
|
-
|
150
|
-
resolve_inheritance(obj) || obj
|
151
|
-
end
|
152
|
-
|
153
|
-
def prepare(parent)
|
154
|
-
@inheritance_prepared = true
|
155
|
-
@parent = parent
|
156
|
-
@defs = specialize_defs(@obj[:defs], self)
|
157
|
-
@sdefs = specialize_defs(@obj[:sdefs], self)
|
158
|
-
@attributes = (@obj[:attributes] || {}).values.map do |v|
|
159
|
-
@provider.prepare_attr(v)
|
160
|
-
end
|
161
|
-
|
162
|
-
@root = parent_of(parent)
|
163
|
-
@path = make_path
|
164
|
-
|
165
|
-
@classes = @obj[:classes].map { SpecializedObject.specialize(_1, self, @provider) }
|
166
|
-
@modules = @obj[:modules].map { SpecializedObject.specialize(_1, self, @provider) }
|
167
|
-
end
|
168
|
-
|
169
|
-
def named_as(n) = ->(o) { o.name == n }
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Renderer
|
4
|
-
class Defs
|
5
|
-
class SpecializedProjection < Array
|
6
|
-
def initialize(provider)
|
7
|
-
super()
|
8
|
-
@provider = provider
|
9
|
-
replace((provider.modules + provider.classes)
|
10
|
-
.map { provider.specialize_object _1 }
|
11
|
-
.each(&:prepare_inheritance))
|
12
|
-
end
|
13
|
-
|
14
|
-
def find_path(path)
|
15
|
-
path = @provider.path_of(path) unless path.is_a? Array
|
16
|
-
p = path.dup
|
17
|
-
obj = find { _1.name == p.first }
|
18
|
-
p.shift
|
19
|
-
return unless obj
|
20
|
-
|
21
|
-
until p.empty?
|
22
|
-
obj = obj.resolve(p.first)
|
23
|
-
p.shift
|
24
|
-
return unless obj
|
25
|
-
end
|
26
|
-
|
27
|
-
obj
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/lib/renderer/defs.rb
DELETED
@@ -1,180 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "defs/specialized_object"
|
4
|
-
require_relative "defs/specialized_projection"
|
5
|
-
|
6
|
-
class Renderer
|
7
|
-
class Defs
|
8
|
-
class << self
|
9
|
-
attr_reader :singleton
|
10
|
-
end
|
11
|
-
|
12
|
-
class << self
|
13
|
-
attr_writer :singleton
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize(base, metadata)
|
17
|
-
@data = JSON.parse(File.read("#{base}/data.json"), symbolize_names: true)
|
18
|
-
@meta = metadata
|
19
|
-
Defs.singleton = self
|
20
|
-
end
|
21
|
-
|
22
|
-
attr_reader :meta
|
23
|
-
|
24
|
-
def classes = @classes ||= make_paths(@data[:classes])
|
25
|
-
def modules = @modules ||= make_paths(@data[:modules])
|
26
|
-
|
27
|
-
def make_paths(obj)
|
28
|
-
return [] unless obj
|
29
|
-
|
30
|
-
obj.each { set_parent(_1, nil) }
|
31
|
-
end
|
32
|
-
|
33
|
-
def set_parent(obj, parent)
|
34
|
-
obj[:parent] = parent
|
35
|
-
obj[:classes].each { set_parent(_1, obj) }
|
36
|
-
obj[:modules].each { set_parent(_1, obj) }
|
37
|
-
end
|
38
|
-
|
39
|
-
def document_outline
|
40
|
-
(classes + modules).map { outline(_1) }
|
41
|
-
end
|
42
|
-
|
43
|
-
def outline(object, level = 0)
|
44
|
-
defs = object[:defs].values.map { map_method(_1) }.sort_by { _1[:name] }
|
45
|
-
sdefs = object[:sdefs].values.map { map_method(_1) }.sort_by { _1[:name] }
|
46
|
-
attributes = object[:attributes]&.values&.map { prepare_attr(_1) }&.sort_by { _1[:name] }
|
47
|
-
|
48
|
-
{
|
49
|
-
level:,
|
50
|
-
name: object[:name],
|
51
|
-
type: object[:type],
|
52
|
-
classes: object[:classes].map { outline(_1, level + 1) },
|
53
|
-
modules: object[:modules].map { outline(_1, level + 1) },
|
54
|
-
defs: defs + sdefs,
|
55
|
-
attributes:
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
def map_method(met)
|
60
|
-
decoration = if met[:source] == "inheritance"
|
61
|
-
"inherited"
|
62
|
-
elsif met[:overriding]
|
63
|
-
"override"
|
64
|
-
end
|
65
|
-
|
66
|
-
obj = find_source(met)
|
67
|
-
type = [].tap do |arr|
|
68
|
-
arr << "Class" if obj[:type] == "defs"
|
69
|
-
arr << "Method"
|
70
|
-
end.join(" ")
|
71
|
-
|
72
|
-
{
|
73
|
-
name: obj[:name],
|
74
|
-
visibility: obj[:visibility],
|
75
|
-
args: obj[:args],
|
76
|
-
type:,
|
77
|
-
short_type: obj[:type],
|
78
|
-
doc: obj[:doc],
|
79
|
-
decoration:
|
80
|
-
}
|
81
|
-
end
|
82
|
-
|
83
|
-
def find_source(met)
|
84
|
-
obj = met
|
85
|
-
obj = obj[:definition] while obj[:source] != "source"
|
86
|
-
obj[:definition]
|
87
|
-
end
|
88
|
-
|
89
|
-
def prepare_attr(met)
|
90
|
-
decoration = if met[:source] == "inheritance"
|
91
|
-
"inherited"
|
92
|
-
elsif met[:overriding]
|
93
|
-
"override"
|
94
|
-
end
|
95
|
-
origin = met[:source]
|
96
|
-
att = find_source(met)
|
97
|
-
visibility = if att[:reader_visibility] == "public" && att[:writer_visibility] == "public"
|
98
|
-
"read/write"
|
99
|
-
elsif att[:reader_visibility] == "public" && att[:writer_visibility] != "public"
|
100
|
-
"read-only"
|
101
|
-
else
|
102
|
-
"write-only"
|
103
|
-
end
|
104
|
-
|
105
|
-
{
|
106
|
-
name: att[:name],
|
107
|
-
type: "Attribute",
|
108
|
-
visibility:,
|
109
|
-
decoration:,
|
110
|
-
origin:,
|
111
|
-
doc: att[:doc]
|
112
|
-
}
|
113
|
-
end
|
114
|
-
|
115
|
-
def path_of(item)
|
116
|
-
p = []
|
117
|
-
parent = item
|
118
|
-
until parent.nil?
|
119
|
-
p << parent[:name]
|
120
|
-
parent = parent[:parent]
|
121
|
-
end
|
122
|
-
p.reverse
|
123
|
-
end
|
124
|
-
|
125
|
-
def definitions_of(item)
|
126
|
-
item[:defined_by]&.map do |d|
|
127
|
-
path_components = d[:filename].split("/")
|
128
|
-
{
|
129
|
-
name: path_components.last,
|
130
|
-
href: git_url(d)
|
131
|
-
}
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def git_url(definition)
|
136
|
-
"#{@meta.git_url}/blob/#{@meta.git_tip}#{definition[:filename].gsub(@meta.git_root,
|
137
|
-
"")}#L#{definition[:start_at]}"
|
138
|
-
end
|
139
|
-
|
140
|
-
def clean_file_path(definition) = definition[:filename].gsub(meta.git_root, "")
|
141
|
-
|
142
|
-
def specialized_projection
|
143
|
-
@specialized_projection ||= SpecializedProjection.new(self)
|
144
|
-
end
|
145
|
-
|
146
|
-
def specialize_data
|
147
|
-
@specialize_data ||= (data[:modules] + data[:classes])
|
148
|
-
.map { specialize_object _1 }
|
149
|
-
.each(&:prepare_inheritance)
|
150
|
-
end
|
151
|
-
|
152
|
-
def specialize_object(obj, parent = nil)
|
153
|
-
SpecializedObject.specialize(obj, parent, self)
|
154
|
-
end
|
155
|
-
|
156
|
-
def by_name(n) = ->(o) { o[:name] == n }
|
157
|
-
|
158
|
-
def doc_for(path)
|
159
|
-
path = path_of(path) if path.is_a? Hash
|
160
|
-
path = path.dup
|
161
|
-
named = by_name(path.shift)
|
162
|
-
root = classes.find(&named) || modules.find(&named)
|
163
|
-
|
164
|
-
return unless root
|
165
|
-
|
166
|
-
find_recursive(path, root)
|
167
|
-
end
|
168
|
-
|
169
|
-
def find_recursive(path, root)
|
170
|
-
return root if path.empty?
|
171
|
-
|
172
|
-
named = by_name(path.shift)
|
173
|
-
next_item = root.classes.find(&named) || root.modules.find(&named)
|
174
|
-
|
175
|
-
return nil unless next_item
|
176
|
-
|
177
|
-
find_recursive(path, next_item)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
data/lib/renderer.rb
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "json"
|
4
|
-
|
5
|
-
require "erb"
|
6
|
-
require "sassc"
|
7
|
-
require "nokogiri"
|
8
|
-
|
9
|
-
require_relative "renderer/version"
|
10
|
-
require_relative "renderer/core_extensions"
|
11
|
-
|
12
|
-
class Renderer
|
13
|
-
ASSETS_PATH = Pathname.new(__dir__).join("../assets")
|
14
|
-
TEMPLATES_PATH = Pathname.new(__dir__).join("../templates")
|
15
|
-
STYLE_BASE = SassC::Engine.new(File.read(ASSETS_PATH.join("style.scss")),
|
16
|
-
style: :compressed,
|
17
|
-
load_paths: [ASSETS_PATH]).render
|
18
|
-
|
19
|
-
def now = Time.now.strftime("%A, %-d %b %Y %H:%M:%S %Z")
|
20
|
-
|
21
|
-
def initialize(base, output)
|
22
|
-
@base = Pathname.new(base)
|
23
|
-
@output = Pathname.new(output)
|
24
|
-
end
|
25
|
-
|
26
|
-
def metadata = @metadata ||= Metadata.new(@base)
|
27
|
-
def defs = @defs ||= Defs.new(@base, metadata)
|
28
|
-
def footer = @footer ||= Component::Footer.new(version: VERSION, updated_at: now)
|
29
|
-
|
30
|
-
def render
|
31
|
-
project_header = Component::ProjectHeader.new(
|
32
|
-
name: metadata.name,
|
33
|
-
description: metadata.summary,
|
34
|
-
license: metadata.license,
|
35
|
-
owner: metadata.format_authors,
|
36
|
-
links: metadata.project_links
|
37
|
-
)
|
38
|
-
|
39
|
-
index = Page.new(title: "#{metadata.name} - Docrb") do
|
40
|
-
[
|
41
|
-
project_header,
|
42
|
-
Component::TabBar.new(
|
43
|
-
selected_index: 0,
|
44
|
-
items: [
|
45
|
-
{ name: "Readme", href: "/" },
|
46
|
-
{ name: "Components", href: "/components.html" }
|
47
|
-
]
|
48
|
-
),
|
49
|
-
Component::Markdown.new(source: File.read(@base.join("readme.html"))),
|
50
|
-
footer
|
51
|
-
]
|
52
|
-
end
|
53
|
-
|
54
|
-
components = Page.new(title: "Components - #{metadata.name} - Docrb") do
|
55
|
-
[
|
56
|
-
project_header,
|
57
|
-
Component::TabBar.new(
|
58
|
-
selected_index: 1,
|
59
|
-
items: [
|
60
|
-
{ name: "Readme", href: "/" },
|
61
|
-
{ name: "Components", href: "/components.html" }
|
62
|
-
]
|
63
|
-
),
|
64
|
-
Component::ComponentList.new(list: defs.document_outline),
|
65
|
-
footer
|
66
|
-
]
|
67
|
-
end
|
68
|
-
|
69
|
-
pages(defs.classes + defs.modules)
|
70
|
-
|
71
|
-
FileUtils.mkdir_p @output
|
72
|
-
|
73
|
-
index.render_to(@output.join("index.html"))
|
74
|
-
components.render_to(@output.join("components.html"))
|
75
|
-
File.write(@output.join("style.css"), STYLE_BASE)
|
76
|
-
|
77
|
-
copy_assets
|
78
|
-
end
|
79
|
-
|
80
|
-
def copy_assets
|
81
|
-
[
|
82
|
-
"js/filtering.js",
|
83
|
-
"favicon.ico"
|
84
|
-
].each do |file|
|
85
|
-
File.write(@output.join(Pathname.new(file).basename),
|
86
|
-
File.read(ASSETS_PATH.join(file)))
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def pages(comps, parents = [])
|
91
|
-
comps.each do |comp|
|
92
|
-
page = Page.new(
|
93
|
-
title: "#{comp[:name]} - #{metadata.name} - Docrb",
|
94
|
-
level: parents.count
|
95
|
-
) do
|
96
|
-
[
|
97
|
-
Component::ClassHeader.new(
|
98
|
-
type: comp[:type],
|
99
|
-
name: comp[:name],
|
100
|
-
definitions: defs.definitions_of(comp)
|
101
|
-
),
|
102
|
-
Component::Breadcrumb.new(
|
103
|
-
project_name: metadata.name,
|
104
|
-
items: (parents + [comp]).map.with_index do |p, idx|
|
105
|
-
{ name: p[:name], parents: parents[0...idx].map { _1[:name] } }
|
106
|
-
end
|
107
|
-
),
|
108
|
-
Component::DocBox.new(
|
109
|
-
item: comp,
|
110
|
-
meta: metadata,
|
111
|
-
defs:
|
112
|
-
),
|
113
|
-
footer
|
114
|
-
]
|
115
|
-
end
|
116
|
-
|
117
|
-
parent_dir = @output.join(parents.map { _1[:name] }.join("/"))
|
118
|
-
FileUtils.mkdir_p(parent_dir)
|
119
|
-
page.render_to(parent_dir.join("#{comp[:name]}.html"))
|
120
|
-
|
121
|
-
pages(comp.fetch(:classes, []) + comp.fetch(:modules, []), parents + [comp])
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
require_relative "renderer/template"
|
127
|
-
require_relative "renderer/component"
|
128
|
-
require_relative "renderer/helpers"
|
129
|
-
require_relative "renderer/page"
|
130
|
-
require_relative "renderer/metadata"
|
131
|
-
require_relative "renderer/defs"
|