lookbook 1.2.1 → 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +47 -14
  4. data/app/assets/lookbook/css/themes/blue.css +4 -2
  5. data/app/assets/lookbook/css/themes/green.css +66 -0
  6. data/app/assets/lookbook/css/themes/indigo.css +4 -2
  7. data/app/assets/lookbook/css/themes/rose.css +66 -0
  8. data/app/assets/lookbook/css/themes/zinc.css +4 -2
  9. data/app/components/lookbook/base_component.rb +2 -2
  10. data/app/components/lookbook/code/component.css +2 -2
  11. data/app/components/lookbook/code/component.html.erb +3 -2
  12. data/app/components/lookbook/code/component.rb +13 -2
  13. data/app/components/lookbook/code/highlight_github.css +406 -0
  14. data/app/components/lookbook/header/component.html.erb +1 -1
  15. data/app/components/lookbook/inspector_panel/component.rb +4 -6
  16. data/app/components/lookbook/nav/component.rb +8 -15
  17. data/app/components/lookbook/nav/directory/component.html.erb +28 -0
  18. data/app/components/lookbook/nav/directory/component.rb +4 -0
  19. data/app/components/lookbook/nav/{item → entity}/component.html.erb +8 -8
  20. data/app/components/lookbook/nav/entity/component.rb +49 -0
  21. data/app/components/lookbook/nav/item/component.css +15 -0
  22. data/app/components/lookbook/nav/item/component.js +4 -0
  23. data/app/components/lookbook/nav/item/component.rb +13 -56
  24. data/app/components/lookbook/params/editor/component.html.erb +2 -2
  25. data/app/components/lookbook/params/editor/component.rb +3 -10
  26. data/app/components/lookbook/params/field/component.css +3 -3
  27. data/app/components/lookbook/params/field/component.html.erb +8 -8
  28. data/app/components/lookbook/params/field/component.rb +21 -72
  29. data/app/components/lookbook/split_layout/component.html.erb +1 -1
  30. data/app/components/lookbook/tabs/component.html.erb +1 -1
  31. data/app/components/lookbook/tabs/component.js +4 -0
  32. data/app/components/lookbook/tag_component.rb +1 -1
  33. data/app/components/lookbook/viewport/component.css +1 -1
  34. data/app/components/lookbook/viewport/component.html.erb +1 -1
  35. data/app/components/lookbook/viewport/component.rb +1 -1
  36. data/app/controllers/concerns/lookbook/targetable_concern.rb +131 -0
  37. data/app/controllers/concerns/lookbook/with_preview_controller_concern.rb +13 -0
  38. data/app/controllers/lookbook/application_controller.rb +21 -9
  39. data/app/controllers/lookbook/inspector_controller.rb +45 -0
  40. data/app/controllers/lookbook/page_controller.rb +13 -9
  41. data/app/controllers/lookbook/pages_controller.rb +9 -15
  42. data/app/controllers/lookbook/previews_controller.rb +4 -210
  43. data/app/helpers/lookbook/application_helper.rb +2 -2
  44. data/app/helpers/lookbook/output_helper.rb +5 -5
  45. data/app/helpers/lookbook/page_helper.rb +7 -4
  46. data/app/views/layouts/lookbook/application.html.erb +40 -38
  47. data/app/views/layouts/lookbook/page.html.erb +2 -2
  48. data/app/views/layouts/lookbook/shell.html.erb +3 -2
  49. data/app/views/layouts/lookbook/skeleton.html.erb +7 -7
  50. data/app/views/lookbook/index.html.erb +13 -2
  51. data/app/views/lookbook/{previews → inspector}/inputs/_color.html.erb +0 -0
  52. data/app/views/lookbook/{previews → inspector}/inputs/_range.html.erb +0 -0
  53. data/app/views/lookbook/{previews → inspector}/inputs/_select.html.erb +0 -0
  54. data/app/views/lookbook/{previews → inspector}/inputs/_text.html.erb +0 -0
  55. data/app/views/lookbook/{previews → inspector}/inputs/_textarea.html.erb +0 -0
  56. data/app/views/lookbook/{previews → inspector}/inputs/_toggle.html.erb +5 -5
  57. data/app/views/lookbook/{previews → inspector}/panels/_content.html.erb +0 -0
  58. data/app/views/lookbook/{previews → inspector}/panels/_notes.html.erb +2 -2
  59. data/app/views/lookbook/{previews → inspector}/panels/_output.html.erb +0 -0
  60. data/app/views/lookbook/inspector/panels/_params.html.erb +15 -0
  61. data/app/views/lookbook/{previews → inspector}/panels/_preview.html.erb +0 -0
  62. data/app/views/lookbook/{previews → inspector}/panels/_source.html.erb +0 -0
  63. data/app/views/lookbook/{previews → inspector}/show.html.erb +5 -2
  64. data/config/app.yml +11 -1
  65. data/config/inputs.yml +12 -12
  66. data/config/languages.yml +41 -0
  67. data/config/panels.yml +6 -6
  68. data/config/routes.rb +5 -5
  69. data/config/tags.yml +8 -1
  70. data/lib/lookbook/engine.rb +103 -130
  71. data/lib/lookbook/entities/collections/component_collection.rb +4 -0
  72. data/lib/lookbook/entities/collections/concerns/hierarchical_collection.rb +23 -0
  73. data/lib/lookbook/entities/collections/entity_collection.rb +61 -0
  74. data/lib/lookbook/entities/collections/page_collection.rb +30 -0
  75. data/lib/lookbook/entities/collections/preview_collection.rb +41 -0
  76. data/lib/lookbook/entities/collections/preview_example_collection.rb +4 -0
  77. data/lib/lookbook/entities/component.rb +31 -0
  78. data/lib/lookbook/entities/concerns/annotatable.rb +58 -0
  79. data/lib/lookbook/entities/concerns/inspectable.rb +44 -0
  80. data/lib/lookbook/entities/concerns/locatable.rb +73 -0
  81. data/lib/lookbook/entities/concerns/navigable.rb +43 -0
  82. data/lib/lookbook/entities/entity.rb +53 -0
  83. data/lib/lookbook/entities/page.rb +80 -0
  84. data/lib/lookbook/entities/page_section.rb +43 -0
  85. data/lib/lookbook/entities/preview.rb +87 -0
  86. data/lib/lookbook/entities/preview_example.rb +100 -0
  87. data/lib/lookbook/entities/preview_group.rb +48 -0
  88. data/lib/lookbook/file_watcher.rb +47 -0
  89. data/lib/lookbook/lang.rb +12 -35
  90. data/lib/lookbook/param.rb +99 -0
  91. data/lib/lookbook/{preview_controller.rb → preview_actions.rb} +14 -3
  92. data/lib/lookbook/preview_parser.rb +53 -0
  93. data/lib/lookbook/process.rb +21 -0
  94. data/lib/lookbook/rendered_example.rb +37 -0
  95. data/lib/lookbook/services/code/code_beautifier.rb +21 -0
  96. data/lib/lookbook/services/code/code_highlighter.rb +69 -0
  97. data/lib/lookbook/services/code/code_indenter.rb +14 -0
  98. data/lib/lookbook/services/data/parsers/data_parser.rb +22 -0
  99. data/lib/lookbook/services/data/parsers/json_parser.rb +7 -0
  100. data/lib/lookbook/services/data/parsers/yaml_parser.rb +7 -0
  101. data/lib/lookbook/services/data/resolvers/data_resolver.rb +70 -0
  102. data/lib/lookbook/services/data/resolvers/eval_resolver.rb +10 -0
  103. data/lib/lookbook/services/data/resolvers/file_resolver.rb +28 -0
  104. data/lib/lookbook/services/data/resolvers/method_resolver.rb +10 -0
  105. data/lib/lookbook/services/data/resolvers/yaml_resolver.rb +18 -0
  106. data/lib/lookbook/services/entities/entity_tree_builder.rb +45 -0
  107. data/lib/lookbook/services/markdown_renderer.rb +29 -0
  108. data/lib/lookbook/services/position_prefix_parser.rb +16 -0
  109. data/lib/lookbook/services/string_value_caster.rb +60 -0
  110. data/lib/lookbook/services/tags/tag_options_parser.rb +62 -0
  111. data/lib/lookbook/services/templates/action_view_annotations_handler.rb +21 -0
  112. data/lib/lookbook/services/templates/action_view_annotations_stripper.rb +15 -0
  113. data/lib/lookbook/services/templates/frontmatter_extractor.rb +28 -0
  114. data/lib/lookbook/services/templates/styles_extractor.rb +38 -0
  115. data/lib/lookbook/services/{search_param_builder.rb → urls/search_param_builder.rb} +1 -1
  116. data/lib/lookbook/services/{search_param_parser.rb → urls/search_param_parser.rb} +1 -1
  117. data/lib/lookbook/stores/config_store.rb +12 -9
  118. data/lib/lookbook/stores/input_store.rb +7 -3
  119. data/lib/lookbook/stores/panel_store.rb +2 -2
  120. data/lib/lookbook/stores/tag_store.rb +3 -5
  121. data/lib/lookbook/support/null_object.rb +10 -0
  122. data/lib/lookbook/support/service.rb +2 -2
  123. data/lib/lookbook/support/store.rb +2 -35
  124. data/lib/lookbook/support/tree_node.rb +87 -0
  125. data/lib/lookbook/support/utils/path_utils.rb +32 -5
  126. data/lib/lookbook/support/utils/utils.rb +24 -0
  127. data/lib/lookbook/tags/component_tag.rb +13 -0
  128. data/lib/lookbook/tags/custom_tag.rb +61 -0
  129. data/lib/lookbook/tags/display_tag.rb +15 -0
  130. data/lib/lookbook/tags/hidden_tag.rb +13 -0
  131. data/lib/lookbook/tags/id_tag.rb +7 -0
  132. data/lib/lookbook/tags/label_tag.rb +4 -0
  133. data/lib/lookbook/tags/logical_path_tag.rb +7 -0
  134. data/lib/lookbook/tags/param_tag.rb +63 -0
  135. data/lib/lookbook/tags/position_tag.rb +16 -0
  136. data/lib/lookbook/tags/source_tag.rb +7 -0
  137. data/lib/lookbook/tags/tag_provider.rb +18 -0
  138. data/lib/lookbook/tags/yard_tag.rb +90 -0
  139. data/lib/lookbook/theme.rb +8 -0
  140. data/lib/lookbook/version.rb +1 -1
  141. data/lib/lookbook/websocket.rb +60 -0
  142. data/lib/lookbook.rb +13 -8
  143. data/public/lookbook-assets/css/lookbook.css +487 -411
  144. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  145. data/public/lookbook-assets/css/themes/blue.css +3 -1
  146. data/public/lookbook-assets/css/themes/blue.css.map +1 -1
  147. data/public/lookbook-assets/css/themes/green.css +68 -0
  148. data/public/lookbook-assets/css/themes/green.css.map +1 -0
  149. data/public/lookbook-assets/css/themes/indigo.css +3 -1
  150. data/public/lookbook-assets/css/themes/indigo.css.map +1 -1
  151. data/public/lookbook-assets/css/themes/rose.css +68 -0
  152. data/public/lookbook-assets/css/themes/rose.css.map +1 -0
  153. data/public/lookbook-assets/css/themes/zinc.css +3 -1
  154. data/public/lookbook-assets/css/themes/zinc.css.map +1 -1
  155. data/public/lookbook-assets/js/embed.js +10 -1
  156. data/public/lookbook-assets/js/embed.js.map +1 -1
  157. data/public/lookbook-assets/js/lookbook.js +358 -629
  158. data/public/lookbook-assets/js/lookbook.js.map +1 -1
  159. metadata +96 -44
  160. data/app/components/lookbook/code/highlight_github_light.css +0 -217
  161. data/app/views/lookbook/previews/panels/_params.html.erb +0 -15
  162. data/lib/lookbook/code_formatter.rb +0 -68
  163. data/lib/lookbook/collection.rb +0 -161
  164. data/lib/lookbook/component.rb +0 -34
  165. data/lib/lookbook/entity.rb +0 -47
  166. data/lib/lookbook/markdown.rb +0 -22
  167. data/lib/lookbook/page.rb +0 -195
  168. data/lib/lookbook/page_collection.rb +0 -19
  169. data/lib/lookbook/page_section.rb +0 -29
  170. data/lib/lookbook/params.rb +0 -157
  171. data/lib/lookbook/parser.rb +0 -42
  172. data/lib/lookbook/preview.rb +0 -174
  173. data/lib/lookbook/preview_collection.rb +0 -23
  174. data/lib/lookbook/preview_example.rb +0 -93
  175. data/lib/lookbook/preview_group.rb +0 -62
  176. data/lib/lookbook/source_inspector.rb +0 -95
  177. data/lib/lookbook/support/utils/attribute_utils.rb +0 -9
  178. data/lib/lookbook/tag.rb +0 -122
  179. data/lib/lookbook/tag_options.rb +0 -111
  180. data/lib/lookbook/tags.rb +0 -17
  181. data/lib/lookbook/template_parser.rb +0 -72
  182. data/lib/lookbook/utils.rb +0 -105
@@ -1,174 +0,0 @@
1
- module Lookbook
2
- class Preview < Collection
3
- include Utils
4
-
5
- delegate :name, :render_args, to: :@preview
6
- delegate :position, :group, :notes, :hidden?, :tags, :tag, to: :@preview_inspector
7
-
8
- def initialize(preview, code_object)
9
- @preview = preview
10
- @preview_inspector = SourceInspector.new(code_object, eval_scope: preview_class.new)
11
- super(preview_class_path(@preview.name))
12
- end
13
-
14
- def id
15
- @preview_inspector&.id || generate_id(lookup_path)
16
- end
17
-
18
- def preview_class_name
19
- @preview.name
20
- end
21
-
22
- def preview_class
23
- @preview
24
- end
25
-
26
- def label
27
- @preview_inspector&.label&.presence || lookup_path.split("/").last.titleize
28
- end
29
-
30
- def type
31
- :preview
32
- end
33
-
34
- def example(example_name)
35
- examples.find { |m| m.name == example_name.to_s }
36
- end
37
-
38
- def examples
39
- return @examples if @examples.present?
40
- public_methods = @preview.public_instance_methods(false)
41
- public_method_objects = @preview_inspector&.methods&.select { |m| public_methods.include?(m.name) }
42
- examples = (public_method_objects || []).map { |m| PreviewExample.new(m.name.to_s, self, m) }
43
- sorted = Lookbook.config.sort_examples ? examples.sort_by(&:label) : examples
44
- @examples = []
45
- if @preview_inspector&.groups&.any?
46
- sorted.group_by { |m| m.group }.each do |name, examples|
47
- if name.nil?
48
- @examples += examples
49
- else
50
- name = label if name.strip == ""
51
- @examples << PreviewGroup.new(name.underscore, self, examples)
52
- end
53
- end
54
- else
55
- @examples = sorted
56
- end
57
- @examples = @examples.compact
58
- end
59
-
60
- def items
61
- examples.reject { |i| i.hidden? }
62
- end
63
-
64
- def default_example
65
- examples.first
66
- end
67
-
68
- def rel_path
69
- "#{name.underscore}.rb"
70
- end
71
-
72
- def full_path
73
- base_path = preview_paths.detect do |preview_path|
74
- Dir["#{preview_path}/#{rel_path}"].first
75
- end
76
- Pathname.new(Dir["#{base_path}/#{rel_path}"].first)
77
- end
78
-
79
- def url_path
80
- lookbook_inspect_path lookup_path
81
- end
82
-
83
- def parent_collections_names
84
- File.dirname(path).split("/")
85
- end
86
-
87
- def hierarchy_depth
88
- path.split("/").size
89
- end
90
-
91
- def layout
92
- @preview.instance_variable_get(:@layout)
93
- end
94
-
95
- def display_options
96
- Lookbook.config.preview_display_options.deep_merge(@preview_inspector&.display_options)
97
- end
98
-
99
- def collapsible?
100
- true
101
- end
102
-
103
- def component
104
- components.first
105
- end
106
-
107
- def components
108
- component_classes = @preview_inspector&.components&.any? ? @preview_inspector&.components : [guess_component]
109
- component_classes.map do |class_name|
110
- Component.new(class_name.to_s)
111
- end
112
- end
113
-
114
- def preview_paths
115
- PathUtils.normalize_all(Lookbook.config.preview_paths)
116
- end
117
-
118
- protected
119
-
120
- @preview_objects = nil
121
- @previews = nil
122
-
123
- def guess_component
124
- name.chomp("Preview").constantize
125
- rescue
126
- nil
127
- end
128
-
129
- class << self
130
- def find(path)
131
- all.find { |p| p.lookup_path == path }
132
- end
133
-
134
- def exists?(path)
135
- !!find(path)
136
- end
137
-
138
- def any?
139
- all.any?
140
- end
141
-
142
- def all
143
- if @previews.nil? && @preview_objects.present?
144
- previews = @preview_objects.map do |code_object|
145
- klass = code_object.path.constantize
146
- new(klass, code_object) if klass.ancestors.include?(ViewComponent::Preview)
147
- rescue => exception
148
- Lookbook.logger.error Lookbook::Error.new(exception)
149
- nil
150
- end.compact
151
-
152
- sorted_previews = previews.compact.sort_by { |preview| [preview.position, preview.label] }
153
- @previews = PreviewCollection.new(sorted_previews)
154
- @previews
155
- elsif !@preview_objects.present?
156
- PreviewCollection.new([])
157
- else
158
- @previews
159
- end
160
- end
161
-
162
- def errors
163
- @errors ||= []
164
- end
165
-
166
- def load!(preview_objects)
167
- @preview_objects = preview_objects
168
- @previews = nil
169
- end
170
- end
171
-
172
- alias_method :lookup_path, :path
173
- end
174
- end
@@ -1,23 +0,0 @@
1
- module Lookbook
2
- class PreviewCollection < Collection
3
- def id
4
- generate_id("preview-collection", lookup_path || "root")
5
- end
6
-
7
- def label
8
- "Previews"
9
- end
10
-
11
- def find_example(path)
12
- Lookbook::PreviewExample.all.find { |e| e.lookup_path == path }
13
- end
14
-
15
- def type
16
- :preview_collection
17
- end
18
-
19
- def self.describe_as
20
- "previews"
21
- end
22
- end
23
- end
@@ -1,93 +0,0 @@
1
- module Lookbook
2
- class PreviewExample < Entity
3
- attr_reader :name, :preview
4
- delegate :params, :position, :group, :notes, :hidden?, :source, :tags, :tag, to: :@example_inspector
5
-
6
- def initialize(name, preview, code_object)
7
- @name = name
8
- @preview = preview
9
- @example_inspector = SourceInspector.new(code_object, eval_scope: @preview.preview_class.new)
10
- super("#{@preview.path}/#{name}")
11
- end
12
-
13
- def id
14
- @example_inspector&.id || generate_id(@preview.id, name)
15
- end
16
-
17
- def url_path
18
- lookbook_inspect_path lookup_path
19
- end
20
-
21
- def label
22
- @example_inspector.label.presence || name.titleize
23
- end
24
-
25
- def display_options
26
- @preview.display_options.merge(@example_inspector.display_options)
27
- end
28
-
29
- def method_source
30
- @example_inspector.source.sub(/^def \w+\s?(\([^)]+\))?/m, "").split("\n")[0..-2].join("\n").strip_heredoc.strip
31
- end
32
-
33
- def lang
34
- Lookbook::Lang.find(:ruby)
35
- end
36
-
37
- def template_source(template_path)
38
- source_path = full_template_path(template_path)
39
- source_path ? File.read(source_path) : nil
40
- end
41
-
42
- def template_lang(template_path)
43
- Lookbook::Lang.guess(full_template_path(template_path)) || Lookbook::Lang.find(:html)
44
- end
45
-
46
- def type
47
- :example
48
- end
49
-
50
- def matchers
51
- normalize_matchers(@preview.label, label)
52
- end
53
-
54
- def hierarchy_depth
55
- @preview.hierarchy_depth + 1
56
- end
57
-
58
- protected
59
-
60
- def strip_ext(path)
61
- path.sub(/\..*$/, "")
62
- end
63
-
64
- def full_template_path(template_path)
65
- template_path = strip_ext template_path
66
- base_path = preview_paths.detect do |p|
67
- Dir["#{p}/#{template_path}.html.*"].first
68
- end
69
- path = Dir["#{base_path}/#{template_path}.html.*"].first
70
- path ? Pathname.new(path) : nil
71
- end
72
-
73
- def preview_paths
74
- PathUtils.normalize_all(Lookbook.config.preview_paths)
75
- end
76
-
77
- class << self
78
- def all
79
- Preview.all.map { |preview| preview.examples }.flatten
80
- end
81
-
82
- def find(path)
83
- all.find { |p| p.lookup_path == path }
84
- end
85
-
86
- def exists?(path)
87
- !!find(path)
88
- end
89
- end
90
-
91
- alias_method :lookup_path, :path
92
- end
93
- end
@@ -1,62 +0,0 @@
1
- module Lookbook
2
- class PreviewGroup < Entity
3
- attr_reader :name, :examples, :preview
4
-
5
- def initialize(name, preview, examples)
6
- @name = name
7
- @preview = preview
8
- @examples = examples
9
- super("#{@preview.path}/#{name}")
10
- end
11
-
12
- def url_path
13
- lookbook_inspect_path lookup_path
14
- end
15
-
16
- def label
17
- name.titleize
18
- end
19
-
20
- def type
21
- :group
22
- end
23
-
24
- def params
25
- examples.map(&:params).flatten.uniq { |param| param[:name] }
26
- end
27
-
28
- def display_options
29
- merged = {}
30
- examples.reverse.map do |example|
31
- merged.merge! example.display_options
32
- end
33
- merged
34
- end
35
-
36
- def hidden?
37
- false
38
- end
39
-
40
- def position
41
- 10000
42
- end
43
-
44
- def matchers
45
- normalize_matchers(@preview.label, label)
46
- end
47
-
48
- def hierarchy_depth
49
- @preview.hierarchy_depth + 1
50
- end
51
-
52
- def tags(name = nil)
53
- examples.map { |example| example.tags(name) }.flatten
54
- end
55
-
56
- def tag(name = nil)
57
- tags(name).first
58
- end
59
-
60
- alias_method :lookup_path, :path
61
- end
62
- end
@@ -1,95 +0,0 @@
1
- module Lookbook
2
- class SourceInspector
3
- include Utils
4
-
5
- attr_reader :code_object
6
- delegate :groups, :source, to: :@code_object, allow_nil: true
7
-
8
- def initialize(code_object, eval_scope: nil)
9
- @code_object = code_object
10
- @eval_scope = eval_scope
11
- end
12
-
13
- def hidden?
14
- @hidden ||= if code_object&.tag(:hidden)
15
- code_object.tag(:hidden).text.strip != "false"
16
- else
17
- false
18
- end
19
- end
20
-
21
- def id
22
- @id ||= if code_object&.tag(:id)&.text&.present?
23
- generate_id(code_object&.tag(:id)&.text)
24
- end
25
- end
26
-
27
- def label
28
- @label ||= code_object&.tag(:label)&.text
29
- end
30
-
31
- def notes
32
- @notes ||= if code_object&.docstring
33
- code_object.docstring.to_s.strip
34
- end
35
- end
36
-
37
- def group
38
- @group ||= code_object&.group
39
- end
40
-
41
- def position
42
- @position ||= code_object&.tag(:position)&.text&.to_i || 10000
43
- end
44
-
45
- def components
46
- @components ||= if code_object&.tags(:component).present?
47
- code_object.tags(:component).map do |component|
48
- component.text.constantize
49
- end
50
- else
51
- []
52
- end
53
- end
54
-
55
- def display_options
56
- return @display_options unless @display_options.nil?
57
- tags = code_object.tags(:display).to_a
58
- pairs = tags.map { KeyValueTagParser.call(_1.text) }
59
-
60
- # dynamic params set at the entity level are
61
- # not (yet) supported so filter them out.
62
- pairs.select! { |pair| !pair[1].is_a?(Array) && !pair[1].is_a?(Hash) }
63
-
64
- pairs.to_h.symbolize_keys
65
- end
66
-
67
- def parameter_defaults
68
- @param_defaults ||= code_object&.parameters&.map { |str| Params.parse_method_param_str(str) }&.compact&.to_h
69
- end
70
-
71
- def params
72
- @params ||= {}
73
- @params[:param] ||= code_object&.tags("param")&.map do |param|
74
- Lookbook::Params.build_param(param,
75
- default: parameter_defaults[param.name],
76
- eval_scope: @eval_scope)
77
- end
78
- end
79
-
80
- def methods
81
- @methods ||= code_object&.meths
82
- end
83
-
84
- def tags(name = nil)
85
- tag_objects = code_object&.tags(name).presence || []
86
- Lookbook::Tags.process_tags(tag_objects,
87
- eval_scope: @eval_scope,
88
- file: (code_object.files.first[0] if code_object.files.any?))
89
- end
90
-
91
- def tag(name = nil)
92
- tags(name).first
93
- end
94
- end
95
- end
@@ -1,9 +0,0 @@
1
- module Lookbook
2
- module AttributeUtils
3
- class << self
4
- def dom_id(*args)
5
- ["lookbook", *args].join("-").parameterize.dasherize
6
- end
7
- end
8
- end
9
- end
data/lib/lookbook/tag.rb DELETED
@@ -1,122 +0,0 @@
1
- require "shellwords"
2
-
3
- module Lookbook
4
- class Tag
5
- attr_reader :data, :arg_names
6
- attr_accessor :args, :opts
7
-
8
- def initialize(tag_object, arg_names = nil, parser: nil, eval_scope: nil, file: nil, **options)
9
- @tag_object = tag_object
10
- @arg_names = arg_names
11
- @args = {}
12
- @opts = {}
13
- @options = options
14
- @parser = parser
15
- @eval_scope = eval_scope
16
- @file = file
17
- @data = Store.new
18
- run_parser
19
- end
20
-
21
- def tag_name
22
- @name ||= @tag_object.tag_name.to_sym
23
- end
24
-
25
- def tag_body
26
- @tag_object.text
27
- end
28
-
29
- def get_opt(key, fallback = nil)
30
- opts[key] || fallback
31
- end
32
-
33
- def opts_str
34
- @opts_str ||= text_tokens.size > args_count ? text_tokens.slice(args_count, text_tokens.size).join(" ") : ""
35
- end
36
-
37
- protected
38
-
39
- def parse_args
40
- unless arg_names.nil?
41
- values = text_tokens.slice(0, args_count)
42
- @args = build_args(values)
43
- end
44
- end
45
-
46
- def parse_opts
47
- return @opts if @options[:parse_options] == false
48
- tag_opts = Lookbook::TagOptions.new(opts_str,
49
- eval_scope: @eval_scope,
50
- base_dir: File.dirname(@file))
51
- options = tag_opts.resolve || {}
52
- @opts = if options.is_a?(Hash)
53
- options.with_indifferent_access
54
- else
55
- Lookbook.logger.warn "'@#{tag_name}' tag options should resolve to a Hash"
56
- options
57
- end
58
- end
59
-
60
- def run_parser
61
- parse_args
62
- parse_opts
63
- @parser.call(self) if @parser.respond_to?(:call)
64
- end
65
-
66
- def arg_options
67
- return [] if arg_names.nil?
68
- @arg_options ||= arg_names.map do |arg|
69
- unless arg.is_a? Hash
70
- name = arg
71
- arg = {
72
- name: name.to_sym
73
- }
74
- end
75
- arg[:parse] = false unless arg.key? :parse
76
- arg
77
- end
78
- end
79
-
80
- def validate_arg_names
81
- if arg_names.present?
82
- arg_names.each do |name|
83
- if methods.include? name.to_sym
84
- raise ArgumentError, "'#{name}' is a reserved word and cannot be used as an argument name."
85
- end
86
- end
87
- end
88
- end
89
-
90
- def args_count
91
- arg_options.size
92
- end
93
-
94
- def parse_yaml(str, fallback = "~")
95
- YAML.safe_load(str || fallback)
96
- end
97
-
98
- def text_tokens
99
- @tokens ||= Shellwords.split(@tag_object.text)
100
- end
101
-
102
- def build_args(values)
103
- arg_options.map.with_index do |arg, i|
104
- value = values[i]
105
- value = parse_arg(value) if arg[:parse] == true && value.present?
106
- [arg[:name].to_sym, value]
107
- end.to_h
108
- end
109
-
110
- def method_missing(name, *method_args)
111
- if name.end_with? "="
112
- data[name.to_s.chomp("=").to_sym] = method_args.first
113
- else
114
- data[name] || args[name]
115
- end
116
- end
117
-
118
- def respond_to_missing?(name, *)
119
- data.key?(name) || args.key?(name)
120
- end
121
- end
122
- end
@@ -1,111 +0,0 @@
1
- module Lookbook
2
- class TagOptions
3
- SYMBOL_MATCH = /(:([a-zA-Z_\d]+))$/
4
- EVAL_OPTION_MATCH = /(\{\{\s?(.*)\s?\}\})$/
5
- YAML_HASH_MATCH = /(\{(.*?)\})$/m
6
- YAML_ARRAY_MATCH = /(\[(.*?)\])$/m
7
- FILE_PATH_MATCH = /(\S+\.(json|yml))$/
8
-
9
- MATCHERS = [YAML_ARRAY_MATCH, YAML_HASH_MATCH, SYMBOL_MATCH, EVAL_OPTION_MATCH, FILE_PATH_MATCH]
10
-
11
- def initialize(options_str, eval_scope: nil, base_dir: nil)
12
- @options_str = options_str.is_a?(String) ? options_str.strip : ""
13
- @eval_scope = eval_scope
14
- @base_dir = base_dir
15
- end
16
-
17
- def options
18
- resolve.is_a?(Hash) ? resolve.symbolize_keys : resolve
19
- end
20
-
21
- def resolve
22
- @resolved_options ||= begin
23
- if @options_str.present?
24
- if @options_str.end_with?(".json", ".yml")
25
- file_path = resolve_file_path
26
- if file_path
27
- options_file_content = File.read(file_path)
28
- else
29
- raise "Tag options data file not found"
30
- end
31
- end
32
- if file_path&.extname == ".json"
33
- JSON.parse(options_file_content)
34
- elsif file_path&.extname == ".yml"
35
- YAML.safe_load(options_file_content)
36
- elsif evaluatable?
37
- evaluate
38
- else
39
- YAML.safe_load(@options_str || "{}")
40
- end
41
- else
42
- {}
43
- end
44
- rescue => exception
45
- Lookbook.logger.warn Lookbook::Error.new(exception)
46
- {}
47
- end
48
- end
49
-
50
- def resolve_file_path
51
- path = if @options_str.start_with?(".") && @base_dir.present?
52
- File.expand_path(@options_str, @base_dir)
53
- else
54
- Rails.root.join(@options_str)
55
- end
56
- Pathname.new path
57
- end
58
-
59
- def evaluate
60
- if Lookbook.config.preview_params_options_eval == true
61
- if @eval_scope.nil?
62
- raise "Preview params eval must be scoped to an object"
63
- else
64
- @eval_scope.instance_eval(statement)
65
- end
66
- else
67
- raise "The config option `preview_params_options_eval` must be set to `true` before param options can be evaluated at runtime"
68
- end
69
- end
70
-
71
- def self.extract_options(str)
72
- str ||= ""
73
- str.strip!
74
- opts_str = ""
75
-
76
- MATCHERS.each do |regexp|
77
- match_data = str.match(regexp)
78
- unless match_data.nil?
79
- str.gsub!(regexp, "").strip!
80
- opts_str = match_data[1]
81
- break
82
- end
83
- end
84
-
85
- [str, opts_str]
86
- end
87
-
88
- def self.resolveable?(str)
89
- return unless str.is_a?(String)
90
- str.strip!
91
- MATCHERS.each do |regexp|
92
- return true if str.match?(regexp)
93
- end
94
- false
95
- end
96
-
97
- private
98
-
99
- def statement
100
- evaluatable? ? eval_match_data[2].strip : "{}"
101
- end
102
-
103
- def evaluatable?
104
- eval_match_data.present?
105
- end
106
-
107
- def eval_match_data
108
- @eval_match_data ||= @options_str.match(EVAL_OPTION_MATCH) || @options_str.match(SYMBOL_MATCH)
109
- end
110
- end
111
- end
data/lib/lookbook/tags.rb DELETED
@@ -1,17 +0,0 @@
1
- module Lookbook
2
- module Tags
3
- def self.process_tags(tag_objects, file: nil, eval_scope: nil)
4
- return [] if tag_objects.none?
5
- tag_objects.map do |tag_object|
6
- tag_config = Engine.tags.get_tag(tag_object.tag_name).to_h
7
- tag_opts = tag_config[:opts].to_h
8
- Lookbook::Tag.new(tag_object,
9
- tag_opts[:named_args],
10
- parser: tag_opts[:args_parser],
11
- **tag_opts.except(:named_args, :args_parser),
12
- file: file,
13
- eval_scope: eval_scope)
14
- end.compact
15
- end
16
- end
17
- end