lookbook 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +47 -14
- data/app/components/lookbook/code/component.html.erb +1 -1
- data/app/components/lookbook/inspector_panel/component.rb +3 -5
- data/app/components/lookbook/nav/item/component.html.erb +1 -1
- data/app/components/lookbook/params/editor/component.rb +3 -10
- data/app/components/lookbook/params/field/component.html.erb +8 -8
- data/app/components/lookbook/params/field/component.rb +21 -72
- data/app/controllers/concerns/lookbook/targetable_concern.rb +156 -0
- data/app/controllers/concerns/lookbook/with_preview_controller_concern.rb +13 -0
- data/app/controllers/lookbook/application_controller.rb +13 -3
- data/app/controllers/lookbook/inspector_controller.rb +45 -0
- data/app/controllers/lookbook/page_controller.rb +11 -7
- data/app/controllers/lookbook/previews_controller.rb +4 -210
- data/app/helpers/lookbook/output_helper.rb +5 -5
- data/app/views/layouts/lookbook/skeleton.html.erb +3 -3
- data/app/views/lookbook/index.html.erb +12 -1
- data/app/views/lookbook/{previews → inspector}/inputs/_color.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/inputs/_range.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/inputs/_select.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/inputs/_text.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/inputs/_textarea.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/inputs/_toggle.html.erb +3 -3
- data/app/views/lookbook/{previews → inspector}/panels/_content.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/panels/_notes.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/panels/_output.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/panels/_params.html.erb +4 -4
- data/app/views/lookbook/{previews → inspector}/panels/_preview.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/panels/_source.html.erb +0 -0
- data/app/views/lookbook/{previews → inspector}/show.html.erb +4 -1
- data/config/app.yml +8 -1
- data/config/inputs.yml +12 -12
- data/config/panels.yml +5 -5
- data/config/routes.rb +5 -5
- data/config/tags.yml +4 -1
- data/lib/lookbook/engine.rb +101 -150
- data/lib/lookbook/file_watcher.rb +47 -0
- data/lib/lookbook/page.rb +15 -16
- data/lib/lookbook/param.rb +99 -0
- data/lib/lookbook/preview.rb +8 -1
- data/lib/lookbook/{preview_controller.rb → preview_actions.rb} +14 -3
- data/lib/lookbook/preview_example.rb +1 -1
- data/lib/lookbook/preview_group.rb +0 -4
- data/lib/lookbook/preview_parser.rb +53 -0
- data/lib/lookbook/process.rb +21 -0
- data/lib/lookbook/services/code/code_beautifier.rb +21 -0
- data/lib/lookbook/services/code/code_highlighter.rb +69 -0
- data/lib/lookbook/services/data/parsers/data_parser.rb +22 -0
- data/lib/lookbook/services/data/parsers/json_parser.rb +7 -0
- data/lib/lookbook/services/data/parsers/yaml_parser.rb +7 -0
- data/lib/lookbook/services/data/resolvers/data_resolver.rb +70 -0
- data/lib/lookbook/services/data/resolvers/eval_resolver.rb +10 -0
- data/lib/lookbook/services/data/resolvers/file_resolver.rb +28 -0
- data/lib/lookbook/services/data/resolvers/method_resolver.rb +10 -0
- data/lib/lookbook/services/data/resolvers/yaml_resolver.rb +18 -0
- data/lib/lookbook/services/markdown_renderer.rb +29 -0
- data/lib/lookbook/services/string_value_caster.rb +60 -0
- data/lib/lookbook/services/tags/tag_options_parser.rb +62 -0
- data/lib/lookbook/services/templates/action_view_annotations_handler.rb +21 -0
- data/lib/lookbook/services/templates/action_view_annotations_stripper.rb +15 -0
- data/lib/lookbook/services/templates/frontmatter_extractor.rb +28 -0
- data/lib/lookbook/services/templates/styles_extractor.rb +38 -0
- data/lib/lookbook/services/{search_param_builder.rb → urls/search_param_builder.rb} +1 -1
- data/lib/lookbook/services/{search_param_parser.rb → urls/search_param_parser.rb} +1 -1
- data/lib/lookbook/source_inspector.rb +26 -45
- data/lib/lookbook/stores/config_store.rb +7 -8
- data/lib/lookbook/stores/input_store.rb +7 -3
- data/lib/lookbook/stores/tag_store.rb +3 -5
- data/lib/lookbook/support/null_object.rb +10 -0
- data/lib/lookbook/support/service.rb +2 -2
- data/lib/lookbook/support/store.rb +1 -1
- data/lib/lookbook/support/utils/attribute_utils.rb +6 -1
- data/lib/lookbook/support/utils/path_utils.rb +6 -3
- data/lib/lookbook/tags/component_tag.rb +7 -0
- data/lib/lookbook/tags/custom_tag.rb +59 -0
- data/lib/lookbook/tags/display_tag.rb +15 -0
- data/lib/lookbook/tags/hidden_tag.rb +13 -0
- data/lib/lookbook/tags/id_tag.rb +7 -0
- data/lib/lookbook/tags/label_tag.rb +4 -0
- data/lib/lookbook/tags/logical_path.rb +4 -0
- data/lib/lookbook/tags/param_tag.rb +61 -0
- data/lib/lookbook/tags/position_tag.rb +16 -0
- data/lib/lookbook/tags/tag_provider.rb +18 -0
- data/lib/lookbook/tags/yard_tag.rb +62 -0
- data/lib/lookbook/utils.rb +0 -40
- data/lib/lookbook/version.rb +1 -1
- data/lib/lookbook/websocket.rb +60 -0
- data/lib/lookbook.rb +2 -1
- data/public/lookbook-assets/css/lookbook.css +30 -77
- data/public/lookbook-assets/css/lookbook.css.map +1 -1
- data/public/lookbook-assets/js/lookbook.js +7 -2
- data/public/lookbook-assets/js/lookbook.js.map +1 -1
- metadata +55 -26
- data/lib/lookbook/code_formatter.rb +0 -68
- data/lib/lookbook/markdown.rb +0 -22
- data/lib/lookbook/params.rb +0 -157
- data/lib/lookbook/parser.rb +0 -42
- data/lib/lookbook/tag.rb +0 -122
- data/lib/lookbook/tag_options.rb +0 -111
- data/lib/lookbook/tags.rb +0 -17
- 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.
|
4
|
+
version: 1.3.0
|
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-
|
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/
|
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/
|
367
|
-
- lib/lookbook/services/
|
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/
|
383
|
-
- lib/lookbook/
|
384
|
-
- lib/lookbook/tags.rb
|
385
|
-
- lib/lookbook/
|
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.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
|
data/lib/lookbook/markdown.rb
DELETED
@@ -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
|
data/lib/lookbook/params.rb
DELETED
@@ -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
|
data/lib/lookbook/parser.rb
DELETED
@@ -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
|
data/lib/lookbook/tag_options.rb
DELETED
@@ -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
|