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
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Renderer
|
4
|
+
module Entities
|
5
|
+
class Container < Base
|
6
|
+
attr_accessor :classes, :modules, :extends, :includes, :defs, :sdefs, :defined_by, :doc, :constants
|
7
|
+
|
8
|
+
def initialize(parent, model)
|
9
|
+
super(parent, model[:name])
|
10
|
+
@classes = init_entities(model, :classes, as: Class)
|
11
|
+
@modules = init_entities(model, :modules, as: Module)
|
12
|
+
@extends = init_references!(model, :extends)
|
13
|
+
@includes = init_references!(model, :includes)
|
14
|
+
@constants = model[:constants] || {}
|
15
|
+
@defs = model.fetch(:defs, {}).map { |k, v| Method.new(self, :def, k.to_s, v) }
|
16
|
+
@sdefs = model.fetch(:sdefs, {}).map { |k, v| Method.new(self, :sdef, k.to_s, v) }
|
17
|
+
@defined_by = init_entities(model, :defined_by, as: SourceDefinition)
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_nested_container(named)
|
21
|
+
@modules.find { _1.name == named } || @classes.find { _1.name == named }
|
22
|
+
end
|
23
|
+
|
24
|
+
def resolve_class_path(path)
|
25
|
+
path.shift if path.first == "::"
|
26
|
+
obj = find_nested_container(path.shift)
|
27
|
+
return if obj.nil?
|
28
|
+
|
29
|
+
until path.empty?
|
30
|
+
obj = obj.find_nested_container(path.shift)
|
31
|
+
return if obj.nil?
|
32
|
+
end
|
33
|
+
|
34
|
+
obj
|
35
|
+
end
|
36
|
+
|
37
|
+
def init_entities(model, key, as:) = model.fetch(key, []).map { as.new(self, _1) }
|
38
|
+
|
39
|
+
def init_reference!(model, attr) = Reference.new(self, model, attr)
|
40
|
+
|
41
|
+
def init_references!(model, key, attr: nil)
|
42
|
+
model.fetch(key, []).map { init_reference!(_1, attr || key) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def init_reference(model, attr)
|
46
|
+
return if model.nil?
|
47
|
+
|
48
|
+
Reference.new(self, model, attr)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Renderer
|
4
|
+
module Entities
|
5
|
+
class Method < Base
|
6
|
+
attr_accessor :overriding, :source, :definition
|
7
|
+
|
8
|
+
def initialize(parent, type, name, model)
|
9
|
+
super(parent, name)
|
10
|
+
@overriding = model[:overriding] # TODO
|
11
|
+
@type = type
|
12
|
+
@definition = MethodDefinition.new(self, model)
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :type
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Renderer
|
4
|
+
module Entities
|
5
|
+
class MethodArgument
|
6
|
+
attr_accessor :name, :type, :value, :value_type, :parent
|
7
|
+
|
8
|
+
def initialize(parent, arg)
|
9
|
+
@parent = parent
|
10
|
+
@name = arg[:name]
|
11
|
+
@type = arg[:type].to_sym
|
12
|
+
@value = arg[:value]
|
13
|
+
@value_type = arg[:value_type]
|
14
|
+
end
|
15
|
+
|
16
|
+
def positional? = type == :arg || type == :optarg
|
17
|
+
|
18
|
+
def optional? = type == :optarg || type == :kwoptarg
|
19
|
+
|
20
|
+
def kwarg? = type == :kwarg || type == :kwoptarg
|
21
|
+
|
22
|
+
def rest? = type == :restarg || type == :kwrestarg
|
23
|
+
|
24
|
+
def block? = type == :blockarg
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Renderer
|
4
|
+
module Entities
|
5
|
+
class MethodDefinition
|
6
|
+
attr_accessor :args, :defined_by, :doc, :name, :overridden_by, :visibility, :parent
|
7
|
+
|
8
|
+
def initialize(parent, model)
|
9
|
+
@parent = parent
|
10
|
+
@args = model[:definition][:args].map { MethodArgument.new(self, _1) }
|
11
|
+
@defined_by = SourceDefinition.new(nil, model[:definition][:defined_by])
|
12
|
+
@doc = model[:definition][:doc]
|
13
|
+
@name = model[:definition][:name]
|
14
|
+
@overridden_by = model[:definition][:overridden_by] # TODO
|
15
|
+
@visibility = model[:definition][:visibility].to_sym
|
16
|
+
end
|
17
|
+
|
18
|
+
def protected? = visibility == :protected?
|
19
|
+
|
20
|
+
def public? = visibility == :public?
|
21
|
+
|
22
|
+
def private? = visibility == :private?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Renderer
|
4
|
+
module Entities
|
5
|
+
class Module < Container
|
6
|
+
def type = :module
|
7
|
+
|
8
|
+
def initialize(parent, model)
|
9
|
+
if parent.nil?
|
10
|
+
as_root { super }
|
11
|
+
else
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def resolve_references! = @references.each(&:resolve!)
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def as_root
|
21
|
+
old_root = Entities.current_root
|
22
|
+
Entities.current_root = self
|
23
|
+
yield
|
24
|
+
ensure
|
25
|
+
Entities.current_root = old_root
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Renderer
|
4
|
+
module Entities
|
5
|
+
class Reference
|
6
|
+
def initialize(parent, model, field)
|
7
|
+
@parent = parent
|
8
|
+
@root = Entities.current_root
|
9
|
+
@root.register_reference(self)
|
10
|
+
|
11
|
+
if model.is_a? String
|
12
|
+
@name = model
|
13
|
+
@class_path = []
|
14
|
+
else
|
15
|
+
@name = model[:name]
|
16
|
+
@class_path = model[:class_path]
|
17
|
+
end
|
18
|
+
@field = field
|
19
|
+
@target = nil
|
20
|
+
@broken = false
|
21
|
+
end
|
22
|
+
|
23
|
+
def resolved? = !@target.nil? || @broken
|
24
|
+
|
25
|
+
def broken? = @broken
|
26
|
+
|
27
|
+
def resolve!
|
28
|
+
return __resolve_from_root__ if @class_path.first == "::"
|
29
|
+
return __resolve_from_class_path__ unless @class_path.empty?
|
30
|
+
|
31
|
+
location = __location__.dup
|
32
|
+
until location.empty?
|
33
|
+
container = location.shift.find_nested_container(@name)
|
34
|
+
return __assign__(container) if container
|
35
|
+
end
|
36
|
+
|
37
|
+
__assign__ @root.find_nested_container(@name)
|
38
|
+
end
|
39
|
+
|
40
|
+
def method_missing(name, *)
|
41
|
+
return @target.send(name, *) if @target.respond_to?(name)
|
42
|
+
|
43
|
+
return @name if name == :name
|
44
|
+
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
48
|
+
def respond_to_missing?(name, include_private = false)
|
49
|
+
@target&.respond_to_missing?(name, include_private) || super
|
50
|
+
end
|
51
|
+
|
52
|
+
def inspect
|
53
|
+
full_name = [@class_path, @name].flatten.join("::")
|
54
|
+
"#<#{self.class.name}:#{object_id_hex} #{broken? ? "broken" : "valid"} reference to #{full_name}>"
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_s = inspect
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def __location__
|
62
|
+
return @location if @location
|
63
|
+
|
64
|
+
parents = []
|
65
|
+
current = @parent.parent
|
66
|
+
|
67
|
+
while current&.parent
|
68
|
+
parents << current
|
69
|
+
current = current.parent
|
70
|
+
end
|
71
|
+
|
72
|
+
@location = parents
|
73
|
+
end
|
74
|
+
|
75
|
+
def __broken__
|
76
|
+
@broken = true
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
|
80
|
+
def __assign__(target)
|
81
|
+
(@target = target) or __broken__
|
82
|
+
end
|
83
|
+
|
84
|
+
def __resolve_from_root__
|
85
|
+
container = @root.resolve_class_path(@class_path.dup) or return __broken__
|
86
|
+
__assign__ container.find_nested_container(@name)
|
87
|
+
end
|
88
|
+
|
89
|
+
def __resolve_from_class_path__
|
90
|
+
location = __location__.dup
|
91
|
+
container = nil
|
92
|
+
|
93
|
+
while !container && !location.empty? && !@class_path.empty?
|
94
|
+
container = location.shift&.find_nested_container(@class_path.first)
|
95
|
+
end
|
96
|
+
return __broken__ if container.nil?
|
97
|
+
|
98
|
+
container = container.resolve_class_path(@class_path[1..].dup) or return __broken__
|
99
|
+
__assign__ container.find_nested_container(@name)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Renderer
|
4
|
+
module Entities
|
5
|
+
class SourceDefinition
|
6
|
+
attr_accessor :end_at, :start_at, :source, :markdown_source, :filename
|
7
|
+
|
8
|
+
def initialize(_parent, model)
|
9
|
+
@end_at = model[:end_at]
|
10
|
+
@start_at = model[:start_at]
|
11
|
+
@source = model[:source]
|
12
|
+
@markdown_source = model[:markdown_source]
|
13
|
+
@filename = model[:filename]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "entities/base"
|
4
|
+
require_relative "entities/container"
|
5
|
+
|
6
|
+
require_relative "entities/method"
|
7
|
+
require_relative "entities/method_argument"
|
8
|
+
require_relative "entities/method_definition"
|
9
|
+
require_relative "entities/module"
|
10
|
+
require_relative "entities/class"
|
11
|
+
require_relative "entities/source_definition"
|
12
|
+
require_relative "entities/attribute"
|
13
|
+
require_relative "entities/attribute_definition"
|
14
|
+
require_relative "entities/reference"
|
15
|
+
|
16
|
+
class Renderer
|
17
|
+
module Entities
|
18
|
+
def self.current_root = Thread.current[:current_root]
|
19
|
+
|
20
|
+
def self.current_root=(val)
|
21
|
+
Thread.current[:current_root] = val
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.load_from(path)
|
25
|
+
model = JSON.load_file(path, symbolize_names: true)
|
26
|
+
Module.new(nil, model)
|
27
|
+
.tap(&:resolve_references!)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/renderer/helpers.rb
CHANGED
@@ -1,26 +1,43 @@
|
|
1
1
|
class Renderer
|
2
2
|
class Helpers
|
3
|
+
class << self
|
4
|
+
attr_reader :current_renderer
|
5
|
+
end
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_writer :current_renderer
|
9
|
+
end
|
10
|
+
|
3
11
|
def svg(name, **kwargs)
|
4
12
|
attrs = {}
|
5
13
|
cls = kwargs.delete(:class_name)
|
6
|
-
|
14
|
+
title = kwargs.delete(:title)
|
15
|
+
attrs["class"] = cls if cls && !title
|
7
16
|
kwargs.each { |k, v| attrs[k.to_s] = v.to_s }
|
8
17
|
|
9
18
|
svg = File.read(Renderer::ASSETS_PATH.join("images/#{name}.svg"))
|
10
|
-
return svg if attrs.empty?
|
19
|
+
return svg if attrs.empty? && title.nil?
|
11
20
|
|
12
21
|
doc = Nokogiri::XML svg
|
13
22
|
attrs.each do |k, v|
|
14
23
|
doc.css("svg")[0][k] = v
|
15
24
|
end
|
16
|
-
doc.to_xml.split("\n").tap(&:shift).join("\n")
|
25
|
+
doc = doc.to_xml.split("\n").tap(&:shift).join("\n")
|
26
|
+
return doc if title.nil?
|
27
|
+
|
28
|
+
<<~HTML
|
29
|
+
<div class="svg-container #{cls}">
|
30
|
+
<div class="svg-title">#{title}</div>
|
31
|
+
#{doc}
|
32
|
+
</div>
|
33
|
+
HTML
|
17
34
|
end
|
18
35
|
|
19
36
|
def div(class_name, **kwargs, &block)
|
20
37
|
classes = [class_name, kwargs.delete(:class_name)].flatten.compact
|
21
38
|
args = kwargs
|
22
|
-
|
23
|
-
|
39
|
+
.compact
|
40
|
+
.map { |k, v| "#{k}=\"#{v.gsub('"', "\\\"")}\"" }
|
24
41
|
|
25
42
|
start_tag = "<div class=\"#{classes.join(" ")}\" #{args.join(" ")}>"
|
26
43
|
end_tag = "</div>"
|
@@ -31,10 +48,10 @@ class Renderer
|
|
31
48
|
raw = block.call
|
32
49
|
|
33
50
|
captured = if fake_buffer.empty?
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
51
|
+
raw
|
52
|
+
else
|
53
|
+
fake_buffer
|
54
|
+
end
|
38
55
|
ensure
|
39
56
|
block.binding.local_variable_set(:_erbout, "#{start_tag}#{captured}#{end_tag}")
|
40
57
|
end
|
@@ -46,21 +63,21 @@ class Renderer
|
|
46
63
|
raw = block.call
|
47
64
|
|
48
65
|
captured = if fake_buffer.empty?
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
66
|
+
raw
|
67
|
+
else
|
68
|
+
fake_buffer
|
69
|
+
end
|
53
70
|
ensure
|
54
71
|
block.binding.local_variable_set(:_erbout, old_buffer)
|
55
72
|
end
|
56
73
|
|
57
|
-
def git_url(source) =
|
74
|
+
def git_url(source) = self.class.current_renderer.git_url(source)
|
58
75
|
|
59
|
-
def clean_file_path(source) =
|
76
|
+
def clean_file_path(source) = self.class.current_renderer.clean_file_path(source)
|
60
77
|
|
61
78
|
def line_range(source)
|
62
|
-
from = source
|
63
|
-
to = source
|
79
|
+
from = source.line_start
|
80
|
+
to = source.line_end
|
64
81
|
|
65
82
|
if from == to
|
66
83
|
"line #{from}"
|
@@ -68,11 +85,52 @@ class Renderer
|
|
68
85
|
"lines #{from} to #{to}"
|
69
86
|
end
|
70
87
|
end
|
88
|
+
|
89
|
+
def source_of(obj, parent = nil)
|
90
|
+
parent ||= obj.parent
|
91
|
+
|
92
|
+
case (v = parent.source_of(obj))
|
93
|
+
when :inherited, :included, :extended then v.to_s
|
94
|
+
when :self then ("override" if obj.try(:overriding))
|
95
|
+
else raise "WTF? Source of #{obj} is #{v.inspect}!"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def path_of(object, root: true)
|
100
|
+
return [] if object.nil? && !root
|
101
|
+
return [object.name] + path_of(object.parent, root: false) unless root
|
102
|
+
|
103
|
+
path = ["#{object.name}.html"] + path_of(object.parent, root: false)
|
104
|
+
path << ""
|
105
|
+
path.reverse.join("/")
|
106
|
+
end
|
107
|
+
|
108
|
+
def link_for(object)
|
109
|
+
case object
|
110
|
+
when Docrb::Parser::Attribute, Docrb::Parser::Method, Docrb::Parser::Constant
|
111
|
+
"#{path_of(object.parent)}##{anchor_for(object)}"
|
112
|
+
when Docrb::Parser::Class, Docrb::Parser::Module
|
113
|
+
path_of(object)
|
114
|
+
else
|
115
|
+
raise ArgumentError, "#link_for cannot link #{object.class.name}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def anchor_for(object)
|
120
|
+
case object
|
121
|
+
when Docrb::Parser::Attribute then "#{object.type}-attr-#{object.name}"
|
122
|
+
when Docrb::Parser::Method then "#{object.type}-method-#{object.name}"
|
123
|
+
when Docrb::Parser::Constant then "const-#{object.name}"
|
124
|
+
when Docrb::Parser::Class, Docrb::Parser::Module then ""
|
125
|
+
else
|
126
|
+
raise ArgumentError, "#anchor_for cannot process #{object.class.name}"
|
127
|
+
end
|
128
|
+
end
|
71
129
|
end
|
72
130
|
|
73
131
|
Component.constants
|
74
|
-
|
75
|
-
|
132
|
+
.reject { _1 == :HELPERS }
|
133
|
+
.each do |cls|
|
76
134
|
Helpers.define_method(cls.to_s.snakify) do |**kwargs|
|
77
135
|
Component.const_get(cls).new(**kwargs).render
|
78
136
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Renderer
|
4
|
+
# Renderer provides a Redcarpet renderer with Rouge extensions
|
5
|
+
class MarkdownRenderer < Redcarpet::Render::HTML
|
6
|
+
def initialize(extensions = {})
|
7
|
+
super extensions.merge(link_attributes: { target: "_blank" })
|
8
|
+
end
|
9
|
+
include Rouge::Plugins::Redcarpet
|
10
|
+
end
|
11
|
+
|
12
|
+
# InlineRenderer provides a renderer for inline contents. This renderer
|
13
|
+
# does not emit paragraph tags.
|
14
|
+
class InlineRenderer < MarkdownRenderer
|
15
|
+
def paragraph(text)
|
16
|
+
text
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Markdown provides utilities for generating HTML from markdown contents
|
21
|
+
class Markdown
|
22
|
+
# Internal: Creates a new renderer based on a provided type by setting
|
23
|
+
# sensible defaults.
|
24
|
+
#
|
25
|
+
# type - Type of the renderer to be initialised. Use Renderer or
|
26
|
+
# InlineRenderer
|
27
|
+
def self.make_render(type)
|
28
|
+
Redcarpet::Markdown.new(
|
29
|
+
type,
|
30
|
+
fenced_code_blocks: true,
|
31
|
+
autolink: true
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Renders a given input using the default renderer.
|
36
|
+
#
|
37
|
+
# input - Markdown content to be rendered
|
38
|
+
#
|
39
|
+
# Returns an HTML string containing the rendered Markdown content
|
40
|
+
def self.render(input)
|
41
|
+
make_render(MarkdownRenderer).render(input)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Renders a given input using the inline renderer.
|
45
|
+
#
|
46
|
+
# input - Markdown content to be rendered
|
47
|
+
#
|
48
|
+
# Returns an HTML string containing the rendered Markdown content
|
49
|
+
def self.inline(input)
|
50
|
+
make_render(InlineRenderer).render(input)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Renders a given Ruby source code into HTML
|
54
|
+
#
|
55
|
+
# source - Source code to be rendered
|
56
|
+
#
|
57
|
+
# Returns an HTML string containing the rendered source code
|
58
|
+
def self.render_source(source)
|
59
|
+
render("```ruby\n#{source}\n```")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/renderer/metadata.rb
CHANGED
@@ -2,11 +2,7 @@
|
|
2
2
|
|
3
3
|
class Renderer
|
4
4
|
class Metadata
|
5
|
-
def
|
6
|
-
@data = JSON.parse(File.read("#{base}/metadata.json"))
|
7
|
-
end
|
8
|
-
|
9
|
-
def format_authors
|
5
|
+
def self.format_authors(authors)
|
10
6
|
return nil if authors.nil? || authors.count.zero?
|
11
7
|
return authors.first if authors.length == 1
|
12
8
|
|
@@ -14,31 +10,19 @@ class Renderer
|
|
14
10
|
"#{authors.first}, and #{others} other#{others > 1 ? "s" : ""}"
|
15
11
|
end
|
16
12
|
|
17
|
-
def project_links
|
13
|
+
def self.project_links(meta)
|
18
14
|
links = []
|
19
|
-
links << { kind: "rubygems", href: host_url } if host_url
|
20
|
-
|
21
|
-
if git_url
|
22
|
-
links << if git_url.index("github.com/")
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
15
|
+
links << { kind: "rubygems", href: meta[:host_url] } if meta.key? :host_url
|
16
|
+
|
17
|
+
if meta.key? :git_url
|
18
|
+
links << if meta[:git_url].index("github.com/")
|
19
|
+
{ kind: "github", href: meta[:git_url] }
|
20
|
+
else
|
21
|
+
{ kind: "git", href: meta[:git_url] }
|
22
|
+
end
|
27
23
|
end
|
28
24
|
|
29
25
|
links
|
30
26
|
end
|
31
|
-
|
32
|
-
def method_missing(method_name, *arguments, &)
|
33
|
-
if @data.include? method_name.to_s
|
34
|
-
@data[method_name.to_s]
|
35
|
-
else
|
36
|
-
super
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def respond_to_missing?(method_name, include_private = false)
|
41
|
-
@data.key?(method_name.to_s) || super
|
42
|
-
end
|
43
27
|
end
|
44
28
|
end
|
data/lib/renderer/template.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
class Renderer
|
4
2
|
class Template
|
5
3
|
class Bind
|
@@ -8,11 +6,11 @@ class Renderer
|
|
8
6
|
@keys = keys
|
9
7
|
end
|
10
8
|
|
11
|
-
def method_missing(method_name,
|
9
|
+
def method_missing(method_name, ...)
|
12
10
|
if @keys.include? method_name
|
13
11
|
@keys[method_name]
|
14
12
|
else
|
15
|
-
@obj.send(method_name,
|
13
|
+
@obj.send(method_name, ...)
|
16
14
|
end
|
17
15
|
end
|
18
16
|
|
@@ -30,8 +28,8 @@ class Renderer
|
|
30
28
|
@template.filename = path.to_s
|
31
29
|
end
|
32
30
|
|
33
|
-
def render(
|
34
|
-
bind = Bind.new(
|
31
|
+
def render(bin, *, **)
|
32
|
+
bind = Bind.new(bin, *, **)
|
35
33
|
@template.result(bind.make_binding)
|
36
34
|
end
|
37
35
|
end
|
data/lib/renderer/version.rb
CHANGED
data/script/makecomponent
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
require_relative "../lib/renderer/core_extensions"
|
5
5
|
name = ARGV.first.snakify
|
6
6
|
real_name = ARGV.first
|
7
|
-
dashed_name = name.gsub(
|
7
|
+
dashed_name = name.gsub("_", "-")
|
8
8
|
File.write("assets/#{name}.scss", "div.#{dashed_name}-base {\n\n}\n")
|
9
9
|
styles = File.read("assets/style.scss")
|
10
10
|
File.write("assets/style.scss", "#{styles}@import './#{name}';\n")
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<div class="attribute-container"
|
2
|
+
data-origin="<%= source_of(item) %>"
|
3
|
+
data-type="attribute"
|
4
|
+
id="<%= kind %>-attr-<%= item.name %>"
|
5
|
+
>
|
6
|
+
<%= attribute_display(item: item, kind:, omit_type:) %>
|
7
|
+
<div class="doc-block">
|
8
|
+
<%= documentation_block(doc: item.doc) %>
|
9
|
+
</div>
|
10
|
+
</div>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<% div("method-display-base", id:) do %>
|
2
|
+
<% if (dec = source_of(item)) %>
|
3
|
+
<%= svg(dec.to_s.downcase, class_name: "decoration", title: dec.to_s.capitalize) %>
|
4
|
+
<% end %>
|
5
|
+
<% if kind && !omit_type %>
|
6
|
+
<%= typedef(name: "#{kind.capitalize} Attribute") %>
|
7
|
+
<% end %>
|
8
|
+
<% name = capture do %>
|
9
|
+
<div class="container">
|
10
|
+
<div class="method-name"><%= item.name %></div>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
<% if omit_link %>
|
14
|
+
<%= name %>
|
15
|
+
<% else %>
|
16
|
+
<a class="dashed" href="<%= link_for(item) %>"><%= name %></a>
|
17
|
+
<% end %>
|
18
|
+
<div class="label"><%= attr_type %></div>
|
19
|
+
<% if (visibility = item.doc&.dig(:meta, :visibility_annotation)) %>
|
20
|
+
<div class="label"><%= visibility %></div>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|