lookbook 2.0.0.beta.2 → 2.0.0.beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/lookbook/css/fonts.css +33 -0
  3. data/app/assets/lookbook/css/lookbook.css +7 -0
  4. data/app/assets/lookbook/css/themes/blue.css +4 -1
  5. data/app/assets/lookbook/css/themes/green.css +4 -1
  6. data/app/assets/lookbook/css/themes/indigo.css +4 -1
  7. data/app/assets/lookbook/css/themes/rose.css +4 -1
  8. data/app/assets/lookbook/css/themes/zinc.css +4 -1
  9. data/app/assets/lookbook/fonts/Inter-italic.var.woff2 +0 -0
  10. data/app/assets/lookbook/fonts/Inter-roman.var.woff2 +0 -0
  11. data/app/assets/lookbook/fonts/SourceCodeVariable-Italic.ttf.woff2 +0 -0
  12. data/app/assets/lookbook/fonts/SourceCodeVariable-Roman.ttf.woff2 +0 -0
  13. data/app/assets/lookbook/img/lucide-sprite.svg +869 -869
  14. data/app/assets/lookbook/js/lib/lookbook.js +12 -2
  15. data/app/components/lookbook/code/highlight_github.css +16 -17
  16. data/app/components/lookbook/dimensions_display/component.js +4 -7
  17. data/app/components/lookbook/file_source/component.html.erb +9 -0
  18. data/app/components/lookbook/file_source/component.rb +73 -0
  19. data/app/components/lookbook/header/component.html.erb +11 -8
  20. data/app/components/lookbook/icon/component.css +1 -1
  21. data/app/components/lookbook/icon/component.html.erb +1 -1
  22. data/app/components/lookbook/icon/component.rb +4 -1
  23. data/app/components/lookbook/logo/component.html.erb +6 -0
  24. data/app/components/lookbook/logo/component.rb +15 -0
  25. data/app/components/lookbook/message/component.css +33 -0
  26. data/app/components/lookbook/message/component.html.erb +26 -0
  27. data/app/components/lookbook/message/component.rb +13 -0
  28. data/app/components/lookbook/nav/entity/component.html.erb +2 -2
  29. data/app/components/lookbook/nav/entity/component.rb +1 -1
  30. data/app/components/lookbook/page_tabs/component.html.erb +2 -2
  31. data/app/components/lookbook/params/field/component.css +3 -3
  32. data/app/components/lookbook/prose/component.css +8 -1
  33. data/app/components/lookbook/prose/component.html.erb +6 -1
  34. data/app/components/lookbook/prose/component.rb +2 -2
  35. data/app/controllers/concerns/lookbook/targetable_concern.rb +2 -16
  36. data/app/controllers/lookbook/application_controller.rb +38 -14
  37. data/app/controllers/lookbook/embeds_controller.rb +3 -4
  38. data/app/controllers/lookbook/inspector_controller.rb +4 -12
  39. data/app/controllers/lookbook/pages_controller.rb +15 -27
  40. data/app/controllers/lookbook/preview_controller.rb +30 -2
  41. data/app/controllers/lookbook/previews_controller.rb +13 -15
  42. data/app/views/layouts/lookbook/application.html.erb +1 -0
  43. data/app/views/layouts/lookbook/skeleton.html.erb +2 -2
  44. data/app/views/lookbook/errors/default.html.erb +40 -0
  45. data/app/views/lookbook/errors/not_found.html.erb +10 -0
  46. data/app/views/lookbook/index.html.erb +29 -24
  47. data/app/views/lookbook/pages/show.html.erb +9 -8
  48. data/app/views/lookbook/partials/_blank_slate.html.erb +7 -0
  49. data/config/app.yml +8 -0
  50. data/config/routes.rb +2 -0
  51. data/lib/lookbook/engine.rb +12 -5
  52. data/lib/lookbook/entities/concerns/annotatable_entity.rb +26 -1
  53. data/lib/lookbook/entities/concerns/inspectable_entity.rb +17 -2
  54. data/lib/lookbook/entities/concerns/locatable_entity.rb +51 -7
  55. data/lib/lookbook/entities/concerns/navigable_entity.rb +14 -1
  56. data/lib/lookbook/entities/entity.rb +34 -12
  57. data/lib/lookbook/entities/page_entity.rb +68 -10
  58. data/lib/lookbook/entities/page_section_entity.rb +4 -0
  59. data/lib/lookbook/entities/preview_entity.rb +107 -17
  60. data/lib/lookbook/entities/renderable_entity.rb +47 -9
  61. data/lib/lookbook/entities/rendered_scenario_entity.rb +17 -6
  62. data/lib/lookbook/entities/scenario_entity.rb +77 -16
  63. data/lib/lookbook/entities/scenario_group_entity.rb +82 -9
  64. data/lib/lookbook/helpers/page_helper.rb +26 -1
  65. data/lib/lookbook/helpers/ui_elements_helper.rb +0 -24
  66. data/lib/lookbook/param.rb +1 -1
  67. data/lib/lookbook/services/markdown_renderer.rb +2 -4
  68. data/lib/lookbook/stores/config_store.rb +0 -12
  69. data/lib/lookbook/support/errors/config_error.rb +1 -1
  70. data/lib/lookbook/support/errors/error.rb +64 -0
  71. data/lib/lookbook/support/errors/parser_error.rb +1 -1
  72. data/lib/lookbook/support/errors/preview_template_error.rb +1 -1
  73. data/lib/lookbook/support/errors/routing_error.rb +7 -0
  74. data/lib/lookbook/support/errors/template_error.rb +7 -0
  75. data/lib/lookbook/version.rb +1 -1
  76. data/public/lookbook-assets/Inter-italic.var.69eb0fe1.woff2 +0 -0
  77. data/public/lookbook-assets/Inter-italic.var.736a7044.woff2 +0 -0
  78. data/public/lookbook-assets/Inter-roman.var.b695afbe.woff2 +0 -0
  79. data/public/lookbook-assets/Inter-roman.var.fbdd51d0.woff2 +0 -0
  80. data/public/lookbook-assets/SourceCodeVariable-Italic.cad97b83.otf +0 -0
  81. data/public/lookbook-assets/SourceCodeVariable-Italic.ttf.09b4354a.woff2 +0 -0
  82. data/public/lookbook-assets/SourceCodeVariable-Italic.ttf.fcd7e9f4.woff2 +0 -0
  83. data/public/lookbook-assets/SourceCodeVariable-Roman.185ddb17.otf +0 -0
  84. data/public/lookbook-assets/SourceCodeVariable-Roman.ttf.118e9f22.woff2 +0 -0
  85. data/public/lookbook-assets/SourceCodeVariable-Roman.ttf.91043609.woff2 +0 -0
  86. data/public/lookbook-assets/css/lookbook.css +417 -58
  87. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  88. data/public/lookbook-assets/css/themes/blue.css +4 -1
  89. data/public/lookbook-assets/css/themes/blue.css.map +1 -1
  90. data/public/lookbook-assets/css/themes/green.css +4 -1
  91. data/public/lookbook-assets/css/themes/green.css.map +1 -1
  92. data/public/lookbook-assets/css/themes/indigo.css +4 -1
  93. data/public/lookbook-assets/css/themes/indigo.css.map +1 -1
  94. data/public/lookbook-assets/css/themes/rose.css +4 -1
  95. data/public/lookbook-assets/css/themes/rose.css.map +1 -1
  96. data/public/lookbook-assets/css/themes/zinc.css +4 -1
  97. data/public/lookbook-assets/css/themes/zinc.css.map +1 -1
  98. data/public/lookbook-assets/img/lucide-sprite.svg +869 -869
  99. data/public/lookbook-assets/js/index.js +173 -173
  100. data/public/lookbook-assets/js/index.js.map +1 -1
  101. data/public/lookbook-assets/js/lookbook-core.js +4 -2
  102. data/public/lookbook-assets/js/lookbook.js +4 -2
  103. metadata +31 -26
  104. data/app/views/layouts/lookbook/shell.html.erb +0 -25
  105. data/app/views/lookbook/404.html.erb +0 -15
  106. data/app/views/lookbook/error.html.erb +0 -46
  107. data/lib/lookbook/error.rb +0 -120
  108. data/lib/lookbook/support/errors/lookbook_error.rb +0 -21
  109. data/lib/tasks/lookbook_tasks.rake +0 -10
  110. data/public/lookbook-assets/css/app.css +0 -2341
  111. data/public/lookbook-assets/css/app.css.map +0 -11
  112. data/public/lookbook-assets/css/themes/zinc.css.map.91837.5 +0 -1
  113. data/public/lookbook-assets/feather-sprite.svg +0 -1
  114. data/public/lookbook-assets/js/app.js +0 -10862
  115. data/public/lookbook-assets/js/app.js.map +0 -2571
  116. data/public/lookbook-assets/js/embed.js +0 -1427
  117. data/public/lookbook-assets/js/embed.js.91837.6 +0 -0
  118. data/public/lookbook-assets/js/embed.js.map +0 -1
  119. data/public/lookbook-assets/js/lookbook-core.js.map +0 -1
  120. data/public/lookbook-assets/js/lookbook.js.map +0 -1
  121. data/public/lookbook-assets/lookbook-esm.js +0 -1427
  122. data/public/lookbook-assets/lookbook-esm.js.map +0 -1
  123. data/public/lookbook-assets/lookbook-global.js +0 -1427
  124. data/public/lookbook-assets/lookbook-global.js.map +0 -1
  125. data/public/lookbook-assets/lookbook.js +0 -1427
  126. data/public/lookbook-assets/lookbook.js.map +0 -1
@@ -1,7 +1,6 @@
1
1
  module Lookbook
2
2
  # Represents a preview scenario method within a preview class
3
3
  #
4
- # @ignore methods
5
4
  # @api public
6
5
  class ScenarioEntity < Entity
7
6
  include InspectableEntity
@@ -10,8 +9,15 @@ module Lookbook
10
9
 
11
10
  delegate :group, to: :code_object
12
11
 
12
+ # The preview that this scenario belongs to.
13
+ #
14
+ # @return [PreviewEntity] The parent preview entity
13
15
  attr_reader :preview
14
16
 
17
+ # @api private
18
+ alias_method :parent, :preview
19
+
20
+ # @api private
15
21
  def initialize(code_object, preview, priority: nil)
16
22
  @code_object = code_object
17
23
  @preview = preview
@@ -19,61 +25,116 @@ module Lookbook
19
25
  @lookup_path = "#{parent.lookup_path}/#{name}"
20
26
  end
21
27
 
28
+ # @!group Identity
29
+
30
+ # Human-readable unique scenario ID
31
+ #
32
+ # @return [String] The ID
22
33
  def id
23
34
  @_id ||= Utils.id(fetch_config(:id) { "#{parent.id}-#{code_object.name}" })
24
35
  end
25
36
 
37
+ # Parameter-safe scenario name.
38
+ #
39
+ # @return [String] The name
26
40
  def name
27
41
  @_name ||= Utils.name(code_object.name)
28
42
  end
29
43
 
44
+ # Entity type identifier.
45
+ # Returns `:scenario` for scenarios.
46
+ #
47
+ # @return [Symbol] The entity type
48
+ def type
49
+ :scenario
50
+ end
51
+
52
+ # @!endgroup
53
+
54
+ # @!group Display options
55
+
56
+ # Display options hash.
57
+ #
58
+ # Contains all display options defined via the `@display` tag
59
+ # merged with any globally-defined options.
60
+ #
61
+ # @return [Hash] The resolved display options
30
62
  def display_options
31
63
  parent.display_options.merge(fetch_config(:display_options, {}))
32
64
  end
33
65
 
66
+ # @!endgroup
67
+
68
+ # @!group Render Targets
69
+
70
+ # @api private
34
71
  def render_targets
35
72
  @_render_targets ||= RenderTargetCollection.new(load_render_targets)
36
73
  end
37
74
 
75
+ # @api private
76
+ alias_method :components, :render_targets
77
+
78
+ # The item (component or partial) that the scenario renders.
79
+ #
80
+ # The render target is guessed where possible (based on the preview class name)
81
+ # but can also be manually specified using the `@renders` tag.
82
+ #
83
+ # @example :ruby
84
+ # "This scenario renders: #{scenario.render_target.label}"
85
+ #
86
+ # @return [RenderableEntity] The render target
38
87
  def render_target
39
88
  render_targets.first
40
89
  end
41
90
 
91
+ alias_method :component, :render_target
92
+
93
+ # @!endgroup
94
+
95
+ # @!group URLs
96
+
97
+ # The inspector URL path for this preview
98
+ #
99
+ # @return [String] URL path
100
+ def inspect_path
101
+ lookbook_inspect_path(lookup_path)
102
+ end
103
+
104
+ # The standalone preview URL path for this preview
105
+ #
106
+ # @return [String] URL path
107
+ def preview_path
108
+ lookbook_preview_path(lookup_path)
109
+ end
110
+
111
+ # @!endgroup
112
+
113
+ # @api private
42
114
  def scenarios
43
115
  [self]
44
116
  end
45
117
 
118
+ # @api private
46
119
  def template_source(template_path)
47
120
  source_path = template_file_path(template_path)
48
121
  source_path ? File.read(source_path) : nil
49
122
  end
50
123
 
124
+ # @api private
51
125
  def template_lang(template_path)
52
126
  path = template_file_path(template_path)
53
127
  Lookbook::Lang.guess(path) || Lookbook::Lang.find(:html)
54
128
  end
55
129
 
130
+ # @api private
56
131
  def search_terms
57
132
  [parent.label, label]
58
133
  end
59
134
 
60
- def url_path
61
- lookbook_inspect_path(lookup_path)
62
- end
63
-
64
- def preview_path
65
- lookbook_preview_path(lookup_path)
66
- end
67
-
68
- def type
69
- :scenario
70
- end
71
-
72
- alias_method :parent, :preview
73
- alias_method :components, :render_targets
74
- alias_method :component, :render_target
75
135
  alias_method :lang, :source_lang
76
136
  alias_method :examples, :scenarios
137
+ alias_method :url_path, :inspect_path
77
138
 
78
139
  deprecate lang: :source_lang, deprecator: Deprecation
79
140
  deprecate examples: :scenarios, deprecator: Deprecation
@@ -1,13 +1,28 @@
1
1
  module Lookbook
2
2
  # Represents a group of preview scenarios within a preview class
3
3
  #
4
- # @ignore methods
5
4
  # @api public
6
5
  class ScenarioGroupEntity < Entity
7
6
  include NavigableEntity
8
7
 
9
- attr_reader :scenarios, :preview
8
+ # @!group Scenarios
10
9
 
10
+ # Returns all scenarios within the group.
11
+ #
12
+ # @return [Array<ScenarioEntity>] All scenarios
13
+ attr_reader :scenarios
14
+
15
+ # @!endgroup
16
+
17
+ # The preview that this scenario belongs to.
18
+ #
19
+ # @return [PreviewEntity] The parent preview entity
20
+ attr_reader :preview
21
+
22
+ # @api private
23
+ alias_method :parent, :preview
24
+
25
+ # @api private
11
26
  def initialize(name, scenarios, preview)
12
27
  @name = Utils.name(name)
13
28
  @scenarios = ScenarioCollection.new(scenarios)
@@ -15,6 +30,14 @@ module Lookbook
15
30
  @lookup_path = "#{parent.lookup_path}/#{@name}"
16
31
  end
17
32
 
33
+ # @!group Display options
34
+
35
+ # Display options hash.
36
+ #
37
+ # Contains all display options defined via the `@display` tag
38
+ # for each scenario in the group, merged with any globally-defined options.
39
+ #
40
+ # @return [Hash] The resolved display options
18
41
  def display_options
19
42
  merged = {}
20
43
  scenarios.to_a.reverse.map do |scenario|
@@ -23,35 +46,85 @@ module Lookbook
23
46
  merged
24
47
  end
25
48
 
49
+ # @!endgroup
50
+
51
+ # @!group Render Targets
52
+
53
+ # Collection of render targets (components or partials)
54
+ # from each of the scenarios in the group.
55
+ #
56
+ # Render targets are guessed where possible (based on the preview class name)
57
+ # but can also be manually specified using the `@renders` tag.
58
+ #
59
+ # @example :ruby
60
+ # "This group renders: #{group.render_targets.map(&:label).join(", ")}"
61
+ #
62
+ # @return [Array<RenderableEntity>] Render target entities
26
63
  def render_targets
27
64
  @_render_targets ||= RenderTargetCollection.new(scenarios.flat_map(&:render_targets).uniq(&:lookup_path))
28
65
  end
29
66
 
30
- def search_terms
31
- [parent.label, label]
32
- end
67
+ alias_method :components, :render_targets
68
+
69
+ # @!endgroup
33
70
 
71
+ # @!group Annotations
72
+
73
+ # Collection of tags from each of the scenarios in the group.
74
+ # Can be filtered by tag name by providing the name as an argument.
75
+ #
76
+ # @example :ruby
77
+ # all_tags = group.tags
78
+ # display_tags = group.tags(:display)
79
+ #
80
+ # @param tag_name [Symbol] Optional tag type to filter by
81
+ # @return [Array<YardTag>] Array of tags
34
82
  def tags(tag_name = nil)
35
83
  scenarios.flat_map { |scenario| scenario.tags(tag_name) }
36
84
  end
37
85
 
86
+ # @api private
38
87
  def tag(tag_name = nil)
39
88
  tags(tag_name).first
40
89
  end
41
90
 
42
- def url_path
91
+ # @!endgroup
92
+
93
+ # @!group URLs
94
+
95
+ # The inspector URL path for this scenario group
96
+ #
97
+ # @return [String] URL path
98
+ def inspect_path
43
99
  lookbook_inspect_path(lookup_path)
44
100
  end
45
101
 
102
+ # The standalone preview URL path for this scenario group
103
+ #
104
+ # @return [String] URL path
46
105
  def preview_path
47
106
  lookbook_preview_path(lookup_path)
48
107
  end
49
108
 
109
+ alias_method :url_path, :inspect_path
110
+
111
+ # @!endgroup
112
+
113
+ # @!group Identity
114
+
115
+ # Entity type identifier.
116
+ # Returns `:scenario_group` for scenario groups.
117
+ #
118
+ # @return [Symbol] The entity type
50
119
  def type
51
- :group
120
+ :scenario_group
52
121
  end
53
122
 
54
- alias_method :parent, :preview
55
- alias_method :components, :render_targets
123
+ # @!endgroup
124
+
125
+ # @api private
126
+ def search_terms
127
+ [parent.label, label]
128
+ end
56
129
  end
57
130
  end
@@ -5,14 +5,39 @@ module Lookbook
5
5
  module PageHelper
6
6
  # Returns the URL path to a page.
7
7
  #
8
+ # @api private
8
9
  # @param id [String, PageEntity] The id or PageEntity instance to generate a URL path for
9
10
  def page_path(id)
10
11
  page = id.is_a?(PageEntity) ? id : Engine.pages.find_by_id(id)
11
12
  if page.present?
12
- lookbook_page_path page.lookup_path
13
+ page.docs_path
13
14
  else
14
15
  Lookbook.logger.warn "Could not find page with id ':#{id}'"
15
16
  end
16
17
  end
18
+
19
+ # Render a 'live' embed of a component preview.
20
+ #
21
+ # If no scenario name is provided then the default (first) preview
22
+ # scenario will be rendered in the embed.
23
+ #
24
+ # @param preview [String] Name of the preview class to embed
25
+ # @param scenario [String] Example method name
26
+ # @param opts [Hash] Options hash
27
+ def embed(preview, scenario = nil, **opts)
28
+ preview_entity = if preview.is_a?(Symbol)
29
+ Engine.previews.find_by_path(preview)
30
+ else
31
+ Engine.previews.find_by_preview_class(preview)
32
+ end
33
+ scenario_entity = scenario ? preview_entity&.scenario(scenario) : preview_entity&.default_scenario
34
+ opts[:actions] ||= ["inspect", "open"]
35
+
36
+ lookbook_render Embed::Component.new(
37
+ scenario: scenario_entity,
38
+ params: opts.fetch(:params, {}),
39
+ options: opts.except(:params)
40
+ )
41
+ end
17
42
  end
18
43
  end
@@ -34,30 +34,6 @@ module Lookbook
34
34
  lookbook_render :code, **opts, &block
35
35
  end
36
36
 
37
- # Render a 'live' embed of a component preview.
38
- #
39
- # If no scenario name is provided then the default (first) preview
40
- # scenario will be rendered in the embed.
41
- #
42
- # @param preview [String] Name of the preview class to embed
43
- # @param scenario [String] Example method name
44
- # @param opts [Hash] Options hash
45
- def embed(preview, scenario = nil, **opts)
46
- preview_entity = if preview.is_a?(Symbol)
47
- Engine.previews.find_by_path(preview)
48
- else
49
- Engine.previews.find_by_preview_class(preview)
50
- end
51
- scenario_entity = scenario ? preview_entity&.scenario(scenario) : preview_entity&.default_scenario
52
- opts[:actions] ||= ["inspect", "open"]
53
-
54
- lookbook_render Embed::Component.new(
55
- scenario: scenario_entity,
56
- params: opts.fetch(:params, {}),
57
- options: opts.except(:params)
58
- )
59
- end
60
-
61
37
  # @api private
62
38
  def prose(**opts, &block)
63
39
  lookbook_render :prose, **opts, &block
@@ -65,7 +65,7 @@ module Lookbook
65
65
 
66
66
  def input_config
67
67
  config = Lookbook::Engine.inputs.get_input(input)
68
- config || raise(LookbookError.new("Unknown input type '#{input}'"))
68
+ config || raise(Lookbook::Error.new("Unknown input type '#{input}'"))
69
69
  end
70
70
 
71
71
  def guess_input
@@ -18,11 +18,9 @@ module Lookbook
18
18
  class LookbookMarkdownRenderer < Redcarpet::Render::HTML
19
19
  def block_code(code, language = "ruby")
20
20
  line_numbers = language.to_s.end_with? "-numbered"
21
- ApplicationController.render(Lookbook::Code::Component.new(**{
22
- source: code,
21
+ ApplicationController.render(Lookbook::Code::Component.new(source: code,
23
22
  language: language.to_s.chomp("-numbered"),
24
- line_numbers: line_numbers
25
- }), layout: nil)
23
+ line_numbers: line_numbers), layout: nil)
26
24
  end
27
25
 
28
26
  def postprocess(full_document)
@@ -27,22 +27,10 @@ module Lookbook
27
27
  store[:project_name] = (name == false) ? nil : name
28
28
  end
29
29
 
30
- def page_paths=(paths = nil)
31
- store[:page_paths].push(*paths.to_a)
32
- end
33
-
34
30
  def page_extensions=(extensions = nil)
35
31
  store[:page_extensions].push(*extensions.to_a).uniq!
36
32
  end
37
33
 
38
- def preview_paths=(paths = nil)
39
- store[:preview_paths].push(*paths.to_a)
40
- end
41
-
42
- def component_paths=(paths = nil)
43
- store[:component_paths].push(*paths.to_a)
44
- end
45
-
46
34
  def listen_extensions=(extensions = nil)
47
35
  store[:listen_extensions].push(*extensions.to_a).uniq!
48
36
  end
@@ -1,5 +1,5 @@
1
1
  module Lookbook
2
- class ConfigError < LookbookError
2
+ class ConfigError < Error
3
3
  def initialize(msg = nil, scope: "config", **kwargs)
4
4
  super(msg, scope: scope, **kwargs)
5
5
  end
@@ -0,0 +1,64 @@
1
+ module Lookbook
2
+ class Error < StandardError
3
+ attr_reader :scope, :original, :status, :detail, :source
4
+
5
+ def initialize(message = nil,
6
+ scope: nil, original: nil, status: nil, detail: nil,
7
+ file_path: nil, source: nil, line_number: nil, **kwargs)
8
+ @scope = scope
9
+ @original = original
10
+ @message = message
11
+ @status = status
12
+ @detail = detail
13
+ @file_path = file_path
14
+ @source = source
15
+ @line_number = line_number
16
+ super(message)
17
+ end
18
+
19
+ def message
20
+ @message || original&.message
21
+ end
22
+
23
+ def backtrace
24
+ original&.backtrace || super
25
+ end
26
+
27
+ def type
28
+ (original.presence || self).class.to_s
29
+ end
30
+
31
+ def file_path
32
+ return @file_path.to_s if @file_path.present?
33
+
34
+ parsed_backtrace[0][0] if parsed_backtrace.any?
35
+ end
36
+
37
+ def relative_file_path
38
+ file_path&.delete_prefix("#{Rails.root}/")
39
+ end
40
+
41
+ def line_number
42
+ return @line_number.to_i if @line_number.present?
43
+
44
+ if parsed_backtrace.any?
45
+ number = parsed_backtrace[0][1]
46
+ number.to_i if number.present?
47
+ end
48
+ end
49
+
50
+ def backtrace_lines
51
+ root = Rails.root.to_s
52
+ backtrace.map { |line| line.gsub(root, "") }
53
+ end
54
+
55
+ protected
56
+
57
+ def parsed_backtrace
58
+ backtrace.map do |line|
59
+ line =~ /^(.+?):(\d+)(|:in `(.+)')$/
60
+ [$1, $2, $4]
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,5 +1,5 @@
1
1
  module Lookbook
2
- class ParserError < LookbookError
2
+ class ParserError < Error
3
3
  def initialize(msg = nil, scope: "parser", **kwargs)
4
4
  super(msg, scope: scope, **kwargs)
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Lookbook
2
- class PreviewTemplateError < LookbookError
2
+ class PreviewTemplateError < Error
3
3
  def initialize(msg = nil, scope: "preview", **kwargs)
4
4
  super(msg, scope: scope, **kwargs)
5
5
  end
@@ -0,0 +1,7 @@
1
+ module Lookbook
2
+ class RoutingError < Error
3
+ def initialize(msg = nil, scope: "request", **kwargs)
4
+ super(msg, scope: scope, status: :not_found, **kwargs)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Lookbook
2
+ class TemplateError < Error
3
+ def initialize(msg = nil, scope: "template", **kwargs)
4
+ super(msg, scope: scope, **kwargs)
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module Lookbook
2
- VERSION = "2.0.0.beta.2"
2
+ VERSION = "2.0.0.beta.4"
3
3
  end