lookbook 1.2.1 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +47 -14
  4. data/app/components/lookbook/code/component.html.erb +1 -1
  5. data/app/components/lookbook/inspector_panel/component.rb +3 -5
  6. data/app/components/lookbook/nav/item/component.html.erb +1 -1
  7. data/app/components/lookbook/params/editor/component.rb +3 -10
  8. data/app/components/lookbook/params/field/component.html.erb +8 -8
  9. data/app/components/lookbook/params/field/component.rb +21 -72
  10. data/app/controllers/concerns/lookbook/targetable_concern.rb +156 -0
  11. data/app/controllers/concerns/lookbook/with_preview_controller_concern.rb +13 -0
  12. data/app/controllers/lookbook/application_controller.rb +13 -3
  13. data/app/controllers/lookbook/inspector_controller.rb +45 -0
  14. data/app/controllers/lookbook/page_controller.rb +11 -7
  15. data/app/controllers/lookbook/previews_controller.rb +4 -210
  16. data/app/helpers/lookbook/output_helper.rb +5 -5
  17. data/app/views/layouts/lookbook/skeleton.html.erb +3 -3
  18. data/app/views/lookbook/index.html.erb +12 -1
  19. data/app/views/lookbook/{previews → inspector}/inputs/_color.html.erb +0 -0
  20. data/app/views/lookbook/{previews → inspector}/inputs/_range.html.erb +0 -0
  21. data/app/views/lookbook/{previews → inspector}/inputs/_select.html.erb +0 -0
  22. data/app/views/lookbook/{previews → inspector}/inputs/_text.html.erb +0 -0
  23. data/app/views/lookbook/{previews → inspector}/inputs/_textarea.html.erb +0 -0
  24. data/app/views/lookbook/{previews → inspector}/inputs/_toggle.html.erb +3 -3
  25. data/app/views/lookbook/{previews → inspector}/panels/_content.html.erb +0 -0
  26. data/app/views/lookbook/{previews → inspector}/panels/_notes.html.erb +0 -0
  27. data/app/views/lookbook/{previews → inspector}/panels/_output.html.erb +0 -0
  28. data/app/views/lookbook/{previews → inspector}/panels/_params.html.erb +4 -4
  29. data/app/views/lookbook/{previews → inspector}/panels/_preview.html.erb +0 -0
  30. data/app/views/lookbook/{previews → inspector}/panels/_source.html.erb +0 -0
  31. data/app/views/lookbook/{previews → inspector}/show.html.erb +4 -1
  32. data/config/app.yml +8 -1
  33. data/config/inputs.yml +12 -12
  34. data/config/panels.yml +5 -5
  35. data/config/routes.rb +5 -5
  36. data/config/tags.yml +4 -1
  37. data/lib/lookbook/engine.rb +101 -150
  38. data/lib/lookbook/file_watcher.rb +47 -0
  39. data/lib/lookbook/page.rb +15 -16
  40. data/lib/lookbook/param.rb +99 -0
  41. data/lib/lookbook/preview.rb +8 -1
  42. data/lib/lookbook/{preview_controller.rb → preview_actions.rb} +14 -3
  43. data/lib/lookbook/preview_example.rb +1 -1
  44. data/lib/lookbook/preview_group.rb +0 -4
  45. data/lib/lookbook/preview_parser.rb +53 -0
  46. data/lib/lookbook/process.rb +21 -0
  47. data/lib/lookbook/services/code/code_beautifier.rb +21 -0
  48. data/lib/lookbook/services/code/code_highlighter.rb +69 -0
  49. data/lib/lookbook/services/data/parsers/data_parser.rb +22 -0
  50. data/lib/lookbook/services/data/parsers/json_parser.rb +7 -0
  51. data/lib/lookbook/services/data/parsers/yaml_parser.rb +7 -0
  52. data/lib/lookbook/services/data/resolvers/data_resolver.rb +70 -0
  53. data/lib/lookbook/services/data/resolvers/eval_resolver.rb +10 -0
  54. data/lib/lookbook/services/data/resolvers/file_resolver.rb +28 -0
  55. data/lib/lookbook/services/data/resolvers/method_resolver.rb +10 -0
  56. data/lib/lookbook/services/data/resolvers/yaml_resolver.rb +18 -0
  57. data/lib/lookbook/services/markdown_renderer.rb +29 -0
  58. data/lib/lookbook/services/string_value_caster.rb +60 -0
  59. data/lib/lookbook/services/tags/tag_options_parser.rb +62 -0
  60. data/lib/lookbook/services/templates/action_view_annotations_handler.rb +21 -0
  61. data/lib/lookbook/services/templates/action_view_annotations_stripper.rb +15 -0
  62. data/lib/lookbook/services/templates/frontmatter_extractor.rb +28 -0
  63. data/lib/lookbook/services/templates/styles_extractor.rb +38 -0
  64. data/lib/lookbook/services/{search_param_builder.rb → urls/search_param_builder.rb} +1 -1
  65. data/lib/lookbook/services/{search_param_parser.rb → urls/search_param_parser.rb} +1 -1
  66. data/lib/lookbook/source_inspector.rb +26 -45
  67. data/lib/lookbook/stores/config_store.rb +7 -8
  68. data/lib/lookbook/stores/input_store.rb +7 -3
  69. data/lib/lookbook/stores/tag_store.rb +3 -5
  70. data/lib/lookbook/support/null_object.rb +10 -0
  71. data/lib/lookbook/support/service.rb +2 -2
  72. data/lib/lookbook/support/store.rb +1 -1
  73. data/lib/lookbook/support/utils/attribute_utils.rb +6 -1
  74. data/lib/lookbook/support/utils/path_utils.rb +6 -3
  75. data/lib/lookbook/tags/component_tag.rb +7 -0
  76. data/lib/lookbook/tags/custom_tag.rb +59 -0
  77. data/lib/lookbook/tags/display_tag.rb +15 -0
  78. data/lib/lookbook/tags/hidden_tag.rb +13 -0
  79. data/lib/lookbook/tags/id_tag.rb +7 -0
  80. data/lib/lookbook/tags/label_tag.rb +4 -0
  81. data/lib/lookbook/tags/logical_path_tag.rb +4 -0
  82. data/lib/lookbook/tags/param_tag.rb +61 -0
  83. data/lib/lookbook/tags/position_tag.rb +16 -0
  84. data/lib/lookbook/tags/tag_provider.rb +18 -0
  85. data/lib/lookbook/tags/yard_tag.rb +62 -0
  86. data/lib/lookbook/utils.rb +0 -40
  87. data/lib/lookbook/version.rb +1 -1
  88. data/lib/lookbook/websocket.rb +60 -0
  89. data/lib/lookbook.rb +2 -1
  90. data/public/lookbook-assets/css/lookbook.css +30 -77
  91. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  92. data/public/lookbook-assets/js/lookbook.js +7 -2
  93. data/public/lookbook-assets/js/lookbook.js.map +1 -1
  94. metadata +55 -26
  95. data/lib/lookbook/code_formatter.rb +0 -68
  96. data/lib/lookbook/markdown.rb +0 -22
  97. data/lib/lookbook/params.rb +0 -157
  98. data/lib/lookbook/parser.rb +0 -42
  99. data/lib/lookbook/tag.rb +0 -122
  100. data/lib/lookbook/tag_options.rb +0 -111
  101. data/lib/lookbook/tags.rb +0 -17
  102. data/lib/lookbook/template_parser.rb +0 -72
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lookbook
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Perkins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-17 00:00:00.000000000 Z
11
+ date: 2022-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: css_parser
@@ -303,7 +303,10 @@ files:
303
303
  - app/components/lookbook/viewport/component.html.erb
304
304
  - app/components/lookbook/viewport/component.js
305
305
  - app/components/lookbook/viewport/component.rb
306
+ - app/controllers/concerns/lookbook/targetable_concern.rb
307
+ - app/controllers/concerns/lookbook/with_preview_controller_concern.rb
306
308
  - app/controllers/lookbook/application_controller.rb
309
+ - app/controllers/lookbook/inspector_controller.rb
307
310
  - app/controllers/lookbook/page_controller.rb
308
311
  - app/controllers/lookbook/pages_controller.rb
309
312
  - app/controllers/lookbook/previews_controller.rb
@@ -321,21 +324,21 @@ files:
321
324
  - app/views/lookbook/404.html.erb
322
325
  - app/views/lookbook/error.html.erb
323
326
  - app/views/lookbook/index.html.erb
327
+ - app/views/lookbook/inspector/inputs/_color.html.erb
328
+ - app/views/lookbook/inspector/inputs/_range.html.erb
329
+ - app/views/lookbook/inspector/inputs/_select.html.erb
330
+ - app/views/lookbook/inspector/inputs/_text.html.erb
331
+ - app/views/lookbook/inspector/inputs/_textarea.html.erb
332
+ - app/views/lookbook/inspector/inputs/_toggle.html.erb
333
+ - app/views/lookbook/inspector/panels/_content.html.erb
334
+ - app/views/lookbook/inspector/panels/_notes.html.erb
335
+ - app/views/lookbook/inspector/panels/_output.html.erb
336
+ - app/views/lookbook/inspector/panels/_params.html.erb
337
+ - app/views/lookbook/inspector/panels/_preview.html.erb
338
+ - app/views/lookbook/inspector/panels/_source.html.erb
339
+ - app/views/lookbook/inspector/show.html.erb
324
340
  - app/views/lookbook/pages/show.html.erb
325
341
  - app/views/lookbook/preview.html.erb
326
- - app/views/lookbook/previews/inputs/_color.html.erb
327
- - app/views/lookbook/previews/inputs/_range.html.erb
328
- - app/views/lookbook/previews/inputs/_select.html.erb
329
- - app/views/lookbook/previews/inputs/_text.html.erb
330
- - app/views/lookbook/previews/inputs/_textarea.html.erb
331
- - app/views/lookbook/previews/inputs/_toggle.html.erb
332
- - app/views/lookbook/previews/panels/_content.html.erb
333
- - app/views/lookbook/previews/panels/_notes.html.erb
334
- - app/views/lookbook/previews/panels/_output.html.erb
335
- - app/views/lookbook/previews/panels/_params.html.erb
336
- - app/views/lookbook/previews/panels/_preview.html.erb
337
- - app/views/lookbook/previews/panels/_source.html.erb
338
- - app/views/lookbook/previews/show.html.erb
339
342
  - config/app.yml
340
343
  - config/hooks.yml
341
344
  - config/inputs.yml
@@ -343,29 +346,46 @@ files:
343
346
  - config/routes.rb
344
347
  - config/tags.yml
345
348
  - lib/lookbook.rb
346
- - lib/lookbook/code_formatter.rb
347
349
  - lib/lookbook/collection.rb
348
350
  - lib/lookbook/component.rb
349
351
  - lib/lookbook/engine.rb
350
352
  - lib/lookbook/entity.rb
351
353
  - lib/lookbook/error.rb
352
354
  - lib/lookbook/features.rb
355
+ - lib/lookbook/file_watcher.rb
353
356
  - lib/lookbook/lang.rb
354
- - lib/lookbook/markdown.rb
355
357
  - lib/lookbook/page.rb
356
358
  - lib/lookbook/page_collection.rb
357
359
  - lib/lookbook/page_section.rb
358
- - lib/lookbook/params.rb
359
- - lib/lookbook/parser.rb
360
+ - lib/lookbook/param.rb
360
361
  - lib/lookbook/preview.rb
362
+ - lib/lookbook/preview_actions.rb
361
363
  - lib/lookbook/preview_collection.rb
362
- - lib/lookbook/preview_controller.rb
363
364
  - lib/lookbook/preview_example.rb
364
365
  - lib/lookbook/preview_group.rb
366
+ - lib/lookbook/preview_parser.rb
367
+ - lib/lookbook/process.rb
368
+ - lib/lookbook/services/code/code_beautifier.rb
369
+ - lib/lookbook/services/code/code_highlighter.rb
365
370
  - lib/lookbook/services/config_loader.rb
366
- - lib/lookbook/services/search_param_builder.rb
367
- - lib/lookbook/services/search_param_parser.rb
371
+ - lib/lookbook/services/data/parsers/data_parser.rb
372
+ - lib/lookbook/services/data/parsers/json_parser.rb
373
+ - lib/lookbook/services/data/parsers/yaml_parser.rb
374
+ - lib/lookbook/services/data/resolvers/data_resolver.rb
375
+ - lib/lookbook/services/data/resolvers/eval_resolver.rb
376
+ - lib/lookbook/services/data/resolvers/file_resolver.rb
377
+ - lib/lookbook/services/data/resolvers/method_resolver.rb
378
+ - lib/lookbook/services/data/resolvers/yaml_resolver.rb
379
+ - lib/lookbook/services/markdown_renderer.rb
380
+ - lib/lookbook/services/string_value_caster.rb
368
381
  - lib/lookbook/services/tags/key_value_tag_parser.rb
382
+ - lib/lookbook/services/tags/tag_options_parser.rb
383
+ - lib/lookbook/services/templates/action_view_annotations_handler.rb
384
+ - lib/lookbook/services/templates/action_view_annotations_stripper.rb
385
+ - lib/lookbook/services/templates/frontmatter_extractor.rb
386
+ - lib/lookbook/services/templates/styles_extractor.rb
387
+ - lib/lookbook/services/urls/search_param_builder.rb
388
+ - lib/lookbook/services/urls/search_param_parser.rb
369
389
  - lib/lookbook/source_inspector.rb
370
390
  - lib/lookbook/stores/config_store.rb
371
391
  - lib/lookbook/stores/hook_store.rb
@@ -375,17 +395,26 @@ files:
375
395
  - lib/lookbook/support/errors/config_error.rb
376
396
  - lib/lookbook/support/errors/lookbook_error.rb
377
397
  - lib/lookbook/support/errors/parser_error.rb
398
+ - lib/lookbook/support/null_object.rb
378
399
  - lib/lookbook/support/service.rb
379
400
  - lib/lookbook/support/store.rb
380
401
  - lib/lookbook/support/utils/attribute_utils.rb
381
402
  - lib/lookbook/support/utils/path_utils.rb
382
- - lib/lookbook/tag.rb
383
- - lib/lookbook/tag_options.rb
384
- - lib/lookbook/tags.rb
385
- - lib/lookbook/template_parser.rb
403
+ - lib/lookbook/tags/component_tag.rb
404
+ - lib/lookbook/tags/custom_tag.rb
405
+ - lib/lookbook/tags/display_tag.rb
406
+ - lib/lookbook/tags/hidden_tag.rb
407
+ - lib/lookbook/tags/id_tag.rb
408
+ - lib/lookbook/tags/label_tag.rb
409
+ - lib/lookbook/tags/logical_path_tag.rb
410
+ - lib/lookbook/tags/param_tag.rb
411
+ - lib/lookbook/tags/position_tag.rb
412
+ - lib/lookbook/tags/tag_provider.rb
413
+ - lib/lookbook/tags/yard_tag.rb
386
414
  - lib/lookbook/theme.rb
387
415
  - lib/lookbook/utils.rb
388
416
  - lib/lookbook/version.rb
417
+ - lib/lookbook/websocket.rb
389
418
  - lib/tasks/lookbook_tasks.rake
390
419
  - public/lookbook-assets/css/app.css
391
420
  - public/lookbook-assets/css/app.css.map
@@ -1,68 +0,0 @@
1
- require "rouge"
2
- require "htmlbeautifier"
3
- require "htmlentities"
4
-
5
- module Lookbook
6
- module CodeFormatter
7
- class << self
8
- def highlight(source, **opts)
9
- coder = HTMLEntities.new
10
- source = coder.decode source
11
- language = opts[:language] || "ruby"
12
- formatter = Formatter.new(**opts)
13
- lexer = Rouge::Lexer.find(language.to_s) || Rouge::Lexer.find("plaintext")
14
- formatter.format(lexer.lex(source)).html_safe
15
- end
16
-
17
- def beautify(source, **opts)
18
- language = opts[:language] || "html"
19
- source = source.strip
20
- result = language.downcase == "html" ? HtmlBeautifier.beautify(source) : source
21
- result.strip.html_safe
22
- end
23
- end
24
- end
25
-
26
- class Formatter < Rouge::Formatters::HTML
27
- def initialize(**opts)
28
- @opts = opts
29
- @highlight_lines = opts[:highlight_lines].to_a || []
30
- @start_line = opts[:start_line] || 1
31
- @language = opts[:language]
32
- end
33
-
34
- def stream(tokens, &block)
35
- lines = token_lines(tokens)
36
-
37
- yield "<div class='wrapper'>"
38
-
39
- if @opts[:line_numbers]
40
- yield "<div class='line-numbers'>"
41
- lines.each.with_index do |line, i|
42
- yield "<div class='line #{"highlighted" if highlighted?(i)}'><span class='line-number'>#{line_number(i)}</span></div>"
43
- end
44
- yield "</div>"
45
- end
46
-
47
- yield "<pre class='code highlight' data-lang='#{@language}'><code>"
48
- lines.each.with_index do |line_tokens, i|
49
- yield "<div class='line#{" highlighted" if highlighted?(i)}'>"
50
- line_tokens.each do |token, value|
51
- yield span(token, value)
52
- end
53
- yield "</div>"
54
- end
55
- yield "</code></pre>"
56
-
57
- yield "</div>"
58
- end
59
-
60
- def highlighted?(i)
61
- @highlight_lines.include?(i + 1)
62
- end
63
-
64
- def line_number(i)
65
- @start_line + i
66
- end
67
- end
68
- end
@@ -1,22 +0,0 @@
1
- require "redcarpet"
2
-
3
- module Lookbook
4
- class Markdown
5
- def self.render(text)
6
- Utils.strip_action_view_annotations!(text)
7
- markdown = Redcarpet::Markdown.new(Renderer, Lookbook.config.markdown_options.to_h)
8
- markdown.render(text).html_safe
9
- end
10
-
11
- class Renderer < Redcarpet::Render::HTML
12
- def block_code(code, language = "ruby")
13
- line_numbers = language.to_s.end_with? "-numbered"
14
- ApplicationController.render(Lookbook::Code::Component.new(**{
15
- source: code,
16
- language: language.to_s.chomp("-numbered"),
17
- line_numbers: line_numbers
18
- }), layout: nil)
19
- end
20
- end
21
- end
22
- end
@@ -1,157 +0,0 @@
1
- require "active_model"
2
-
3
- module Lookbook
4
- module Params
5
- VALUE_TYPE_MATCH_REGEXP = /^(\[\s?([A-Z]{1}\w+)\s?\])/
6
- DESCRIPTION_MATCH_REGEXP = /"(.*[^\\])"$/
7
-
8
- PARAM_OPTION_KEYS = %i[name input label hint description value_type value_default].freeze
9
-
10
- class << self
11
- def build_param(param, default: nil, eval_scope: nil)
12
- input, value_type, options_str, description = parse_param_tag_text(param.text)
13
-
14
- tag_options = Lookbook::TagOptions.new(options_str,
15
- base_dir: (File.dirname(param.object.files.first[0]) if param.object.files.any?),
16
- eval_scope: eval_scope).options
17
-
18
- if tag_options.is_a? Array
19
- # handle special case legacy situation for selects where
20
- # options are an array of choices rather than a Hash
21
- tag_options = {choices: tag_options}
22
- end
23
-
24
- param_options = tag_options.select { |key| PARAM_OPTION_KEYS.include? key }
25
- input_options = tag_options.except(*PARAM_OPTION_KEYS)
26
-
27
- value_type ||= param_options[:value_type]
28
- input ||= param_options[:input] || guess_input(value_type, default)
29
- name = param.name.to_s
30
-
31
- {
32
- name: name,
33
- label: param_options[:label] || name.titleize,
34
- hint: param_options[:hint],
35
- description: description || param_options[:description],
36
- input: input.to_s.tr("_", "-"),
37
- input_options: input_options,
38
- value: nil,
39
- value_type: value_type || guess_value_type(input, default),
40
- value_default: default
41
- }
42
- end
43
-
44
- # Parses param tag strings with the format: `[<value_type>] <input> <description?> <opts?>`
45
- def parse_param_tag_text(text)
46
- text = (text.presence || "").strip
47
-
48
- value_type = nil
49
- text.match(VALUE_TYPE_MATCH_REGEXP) do |m|
50
- value_type = m[2]
51
- text.gsub!(VALUE_TYPE_MATCH_REGEXP, "").strip!
52
- end
53
-
54
- text, options_str = Lookbook::TagOptions.extract_options(text)
55
-
56
- description = nil
57
- text.match(DESCRIPTION_MATCH_REGEXP) do |m|
58
- description = m[1]
59
- text.gsub!(DESCRIPTION_MATCH_REGEXP, "").strip!
60
- end
61
-
62
- input, rest = text.split(" ", 2)
63
-
64
- [input, value_type, options_str, description, rest]
65
- end
66
-
67
- def parse_method_param_str(param_str)
68
- return nil if param_str[0].nil? || param_str[1].nil?
69
- name = param_str[0].chomp(":")
70
- value = param_str[1]&.strip
71
- value = case value
72
- when "nil"
73
- nil
74
- else
75
- if value&.first == ":"
76
- value.delete_prefix(":").to_sym
77
- else
78
- YAML.safe_load(value)
79
- end
80
- end
81
- [name, value]
82
- end
83
-
84
- def cast(value, type = "String")
85
- case type.downcase
86
- when "symbol"
87
- value.presence&.delete_prefix(":")&.to_sym
88
- when "hash"
89
- result = safe_parse_yaml(value, {})
90
- unless result.is_a? Hash
91
- Lookbook.logger.debug "Failed to parse '#{value}' into a Hash"
92
- result = {}
93
- end
94
- result
95
- when "array"
96
- result = safe_parse_yaml(value, [])
97
- unless result.is_a? Array
98
- Lookbook.logger.debug "Failed to parse '#{value}' into an Array"
99
- result = []
100
- end
101
- result
102
- when "datetime"
103
- begin
104
- result = DateTime.parse(value)
105
- rescue Date::Error
106
- Lookbook.logger.debug "Failed to parse '#{value}' into a DateTime"
107
- result = DateTime.now
108
- end
109
- result
110
- else
111
- begin
112
- type_class = "ActiveModel::Type::#{type}".constantize
113
- type_class.new.cast(value)
114
- rescue NameError
115
- raise ArgumentError, "'#{type}' is not a valid param type to cast to."
116
- end
117
- end
118
- end
119
-
120
- private
121
-
122
- def guess_input(value_type, default)
123
- if value_type&.downcase == "boolean" || (value_type.blank? && boolean?(default))
124
- "toggle"
125
- else
126
- "text"
127
- end
128
- end
129
-
130
- def guess_value_type(input, default)
131
- if input&.downcase == "toggle"
132
- "Boolean"
133
- elsif input&.downcase == "number"
134
- "Integer"
135
- elsif boolean?(default)
136
- "Boolean"
137
- elsif default.is_a? Symbol
138
- "Symbol"
139
- elsif ["date", "datetime-local"].include?(input&.downcase) || default.is_a?(DateTime)
140
- "DateTime"
141
- else
142
- "String"
143
- end
144
- end
145
-
146
- def safe_parse_yaml(value, fallback)
147
- value.present? ? YAML.safe_load(value) : fallback
148
- rescue Psych::SyntaxError
149
- fallback
150
- end
151
-
152
- def boolean?(value)
153
- value == true || value == false
154
- end
155
- end
156
- end
157
- end
@@ -1,42 +0,0 @@
1
- require "yard"
2
-
3
- module Lookbook
4
- class Parser
5
- attr_reader :registry_path
6
- def initialize(paths)
7
- @paths = paths.map { |p| "#{p}/**/*preview.rb" }
8
- @after_parse_callbacks = []
9
- @after_parse_once_callbacks = []
10
- @parsing = false
11
-
12
- YARD::Parser::SourceParser.after_parse_list do
13
- [*@after_parse_callbacks, *@after_parse_once_callbacks].each do |callback|
14
- callback.call(YARD::Registry)
15
- end
16
- @after_parse_once_callbacks = []
17
- @parsing = false
18
- end
19
- end
20
-
21
- def parse(&block)
22
- unless @parsing
23
- @parsing = true
24
- @after_parse_once_callbacks << block if block
25
- YARD::Registry.clear
26
- YARD.parse(@paths)
27
- end
28
- end
29
-
30
- def after_parse(&block)
31
- @after_parse_callbacks << block
32
- end
33
-
34
- class << self
35
- def define_tags(tags = nil)
36
- tags.to_h.each do |name, tag|
37
- YARD::Tags::Library.define_tag(tag[:label], name, tag[:yard_parser])
38
- end
39
- end
40
- end
41
- end
42
- 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