lookbook 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +233 -5
- data/app/assets/lookbook/css/app.css +15 -3
- data/app/assets/lookbook/js/app.js +8 -0
- data/app/assets/lookbook/js/components/app.js +55 -0
- data/app/assets/lookbook/js/components/embed.js +89 -0
- data/app/assets/lookbook/js/components/filter.js +13 -2
- data/app/assets/lookbook/js/components/nav-group.js +3 -6
- data/app/assets/lookbook/js/components/nav-item.js +3 -1
- data/app/assets/lookbook/js/components/nav.js +8 -15
- data/app/assets/lookbook/js/components/page.js +19 -41
- data/app/assets/lookbook/js/components/sidebar.js +16 -1
- data/app/assets/lookbook/js/components/splitter.js +1 -1
- data/app/assets/lookbook/js/components/tabs.js +3 -1
- data/app/assets/lookbook/js/embed.js +1 -0
- data/app/assets/lookbook/js/lib/split.js +0 -6
- data/app/assets/lookbook/js/stores/layout.js +3 -0
- data/app/assets/lookbook/js/stores/pages.js +5 -0
- data/app/assets/lookbook/js/stores/sidebar.js +2 -1
- data/app/controllers/lookbook/application_controller.rb +28 -0
- data/app/controllers/lookbook/page_controller.rb +20 -0
- data/app/controllers/lookbook/pages_controller.rb +40 -0
- data/app/controllers/lookbook/{app_controller.rb → previews_controller.rb} +39 -67
- data/app/helpers/lookbook/application_helper.rb +8 -61
- data/app/helpers/lookbook/component_helper.rb +40 -0
- data/app/helpers/lookbook/output_helper.rb +15 -0
- data/app/helpers/lookbook/page_helper.rb +46 -0
- data/app/helpers/lookbook/preview_helper.rb +1 -1
- data/app/views/layouts/lookbook/application.html.erb +30 -0
- data/app/views/layouts/lookbook/basic.html.erb +7 -0
- data/app/views/layouts/lookbook/preview.html.erb +5 -1
- data/app/views/layouts/lookbook/skeleton.html.erb +28 -0
- data/app/views/lookbook/components/_branding.html.erb +8 -0
- data/app/views/lookbook/components/_code.html.erb +2 -2
- data/app/views/lookbook/components/_copy_button.html.erb +11 -0
- data/app/views/lookbook/components/_drawer.html.erb +4 -16
- data/app/views/lookbook/components/_embed.html.erb +39 -0
- data/app/views/lookbook/components/_filter.html.erb +8 -5
- data/app/views/lookbook/components/_header.html.erb +2 -4
- data/app/views/lookbook/components/_icon.html.erb +2 -2
- data/app/views/lookbook/components/_nav.html.erb +7 -8
- data/app/views/lookbook/components/_nav_group.html.erb +1 -1
- data/app/views/lookbook/components/_nav_item.html.erb +4 -3
- data/app/views/lookbook/components/_nav_page.html.erb +22 -0
- data/app/views/lookbook/components/_nav_preview.html.erb +1 -1
- data/app/views/lookbook/components/_not_found.html.erb +11 -0
- data/app/views/lookbook/components/_param.html.erb +1 -1
- data/app/views/lookbook/components/_preview.html.erb +16 -10
- data/app/views/lookbook/components/_sidebar.html.erb +55 -0
- data/app/views/lookbook/pages/not_found.html.erb +15 -0
- data/app/views/lookbook/pages/show.html.erb +71 -0
- data/app/views/lookbook/previews/error.html.erb +1 -0
- data/app/views/lookbook/{inputs → previews/inputs}/_select.html.erb +0 -0
- data/app/views/lookbook/{inputs → previews/inputs}/_text.html.erb +0 -0
- data/app/views/lookbook/{inputs → previews/inputs}/_textarea.html.erb +0 -0
- data/app/views/lookbook/{inputs → previews/inputs}/_toggle.html.erb +0 -0
- data/app/views/lookbook/{not_found.html.erb → previews/not_found.html.erb} +2 -2
- data/app/views/lookbook/{panels → previews/panels}/_notes.html.erb +2 -2
- data/app/views/lookbook/{panels → previews/panels}/_output.html.erb +0 -0
- data/app/views/lookbook/{panels → previews/panels}/_params.html.erb +0 -0
- data/app/views/lookbook/{panels → previews/panels}/_preview.html.erb +0 -0
- data/app/views/lookbook/{panels → previews/panels}/_source.html.erb +0 -0
- data/app/views/lookbook/{show.html.erb → previews/show.html.erb} +0 -0
- data/config/routes.rb +9 -4
- data/lib/lookbook/code_formatter.rb +22 -1
- data/lib/lookbook/code_inspector.rb +73 -0
- data/lib/lookbook/collection.rb +110 -8
- data/lib/lookbook/engine.rb +59 -32
- data/lib/lookbook/features.rb +1 -1
- data/lib/lookbook/markdown.rb +31 -0
- data/lib/lookbook/page.rb +146 -0
- data/lib/lookbook/page_collection.rb +11 -0
- data/lib/lookbook/parser.rb +2 -0
- data/lib/lookbook/preview.rb +52 -56
- data/lib/lookbook/preview_collection.rb +15 -0
- data/lib/lookbook/preview_example.rb +27 -29
- data/lib/lookbook/preview_group.rb +12 -6
- data/lib/lookbook/utils.rb +74 -0
- data/lib/lookbook/version.rb +1 -1
- data/lib/lookbook.rb +18 -1
- data/public/lookbook-assets/css/app.css +1 -1
- data/public/lookbook-assets/css/app.css.map +1 -1
- data/public/lookbook-assets/js/app.js +1 -1
- data/public/lookbook-assets/js/app.js.map +1 -1
- data/public/lookbook-assets/js/embed.js +2 -0
- data/public/lookbook-assets/js/embed.js.map +1 -0
- metadata +44 -18
- data/app/assets/lookbook/js/lib/utils.js +0 -3
- data/app/views/layouts/lookbook/app.html.erb +0 -60
- data/app/views/lookbook/error.html.erb +0 -1
- data/lib/lookbook/taggable.rb +0 -46
@@ -0,0 +1,73 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class CodeInspector
|
3
|
+
include Utils
|
4
|
+
|
5
|
+
attr_reader :code_object
|
6
|
+
delegate :groups, :source, to: :@code_object, allow_nil: true
|
7
|
+
|
8
|
+
def initialize(taggable_object_path)
|
9
|
+
@code_object = Lookbook::Engine.parser.get_code_object(taggable_object_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def hidden?
|
13
|
+
if code_object&.tag(:hidden)
|
14
|
+
code_object.tag(:hidden).text.strip != "false"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def id
|
19
|
+
if code_object&.tag(:id)&.text&.present?
|
20
|
+
generate_id(code_object&.tag(:id)&.text)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def label
|
25
|
+
code_object&.tag(:label)&.text
|
26
|
+
end
|
27
|
+
|
28
|
+
def notes
|
29
|
+
if code_object&.docstring
|
30
|
+
code_object.docstring.to_s.strip
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def group
|
35
|
+
code_object&.group
|
36
|
+
end
|
37
|
+
|
38
|
+
def position
|
39
|
+
code_object&.tag(:position)&.text&.to_i || 10000
|
40
|
+
end
|
41
|
+
|
42
|
+
def display_params
|
43
|
+
display_params = {}.with_indifferent_access
|
44
|
+
if code_object&.tags(:display).present?
|
45
|
+
code_object.tags(:display).each do |tag|
|
46
|
+
parts = tag.text.strip.match(/^([^\s]*)\s?(.*)$/)
|
47
|
+
if parts.present?
|
48
|
+
begin
|
49
|
+
display_params[parts[1]] = YAML.safe_load(parts[2] || "~")
|
50
|
+
rescue SyntaxError => err
|
51
|
+
Lookbook.logger.error("\n👀 [Lookbook] Invalid JSON in @display tag.\n👀 [Lookbook] (#{err})\n")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
display_params
|
57
|
+
end
|
58
|
+
|
59
|
+
def parameter_defaults
|
60
|
+
code_object&.parameters&.map { |str| Params.parse_method_param_str(str) }&.compact&.to_h
|
61
|
+
end
|
62
|
+
|
63
|
+
def params
|
64
|
+
code_object&.tags("param")&.map do |param|
|
65
|
+
Lookbook::Params.build_param(param, parameter_defaults[param.name])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def methods
|
70
|
+
code_object&.meths
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/lookbook/collection.rb
CHANGED
@@ -1,33 +1,56 @@
|
|
1
1
|
module Lookbook
|
2
2
|
class Collection
|
3
|
+
include Utils
|
4
|
+
include Enumerable
|
5
|
+
|
3
6
|
attr_reader :path
|
7
|
+
delegate :size, :each, to: :items
|
4
8
|
|
5
|
-
def initialize(path = "")
|
9
|
+
def initialize(path = "", items = [])
|
10
|
+
if path.is_a?(Array)
|
11
|
+
@items = path
|
12
|
+
path = ""
|
13
|
+
else
|
14
|
+
@items = items
|
15
|
+
end
|
6
16
|
@path = path.delete_prefix("/").delete_suffix("/")
|
7
|
-
@items = []
|
8
17
|
end
|
9
18
|
|
10
19
|
def id
|
11
|
-
(
|
20
|
+
generate_id(lookup_path || "root")
|
12
21
|
end
|
13
22
|
|
14
23
|
def name
|
15
|
-
@
|
24
|
+
@name ||= remove_position_prefix(basename)
|
16
25
|
end
|
17
26
|
|
18
27
|
def label
|
19
28
|
name&.titleize
|
20
29
|
end
|
21
30
|
|
31
|
+
def lookup_path
|
32
|
+
@lookup_path ||= to_lookup_path(@path)
|
33
|
+
end
|
34
|
+
|
35
|
+
def position
|
36
|
+
@position ||= parse_position_prefix(basename).first
|
37
|
+
end
|
38
|
+
|
22
39
|
def hierarchy_depth
|
23
40
|
@path ? @path.split("/").size : 0
|
24
41
|
end
|
25
42
|
|
26
|
-
def items
|
27
|
-
|
43
|
+
def items
|
44
|
+
@items.sort_by { |item| [item.hierarchy_depth, item.position, item.label] }
|
45
|
+
end
|
46
|
+
|
47
|
+
def visible_items
|
48
|
+
reject { |i| i.hidden? }
|
28
49
|
end
|
29
50
|
|
30
51
|
def add(item)
|
52
|
+
@ordered_entities = nil
|
53
|
+
@tree = nil
|
31
54
|
if item.is_a?(String)
|
32
55
|
item = Collection.new([@path, item].join("/"))
|
33
56
|
end
|
@@ -37,15 +60,94 @@ module Lookbook
|
|
37
60
|
|
38
61
|
def get(name)
|
39
62
|
name = name.underscore
|
40
|
-
|
63
|
+
items.find { |item| item.name.underscore == name }
|
41
64
|
end
|
42
65
|
|
43
66
|
def get_or_create(name)
|
44
|
-
get(name).presence || add(name)
|
67
|
+
get(remove_position_prefix(name)).presence || add(name)
|
68
|
+
end
|
69
|
+
|
70
|
+
def find(lookup = nil, &block)
|
71
|
+
if lookup
|
72
|
+
lookup.is_a?(Symbol) ? find_by_id(lookup.to_s.tr("_", "-")) : find_by_path(lookup)
|
73
|
+
elsif block
|
74
|
+
items.find(&block)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def find_by_id(id)
|
79
|
+
items.find { |i| i.id == id }
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_by_path(path)
|
83
|
+
items.find { |i| i.lookup_path == path }
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_parent(child)
|
87
|
+
parent_path = child.lookup_path.split("/").pop.join("/")
|
88
|
+
find_by_path(parent_path)
|
89
|
+
end
|
90
|
+
|
91
|
+
def ordered_entities
|
92
|
+
return @ordered_entities if @ordered_entities.present?
|
93
|
+
entities = []
|
94
|
+
as_tree.items.each do |item|
|
95
|
+
entities.append(item.is_a?(Collection) ? item.ordered_entities : item)
|
96
|
+
end
|
97
|
+
@ordered_entities ||= entities.flatten
|
98
|
+
end
|
99
|
+
|
100
|
+
def find_first
|
101
|
+
ordered_entities.first
|
102
|
+
end
|
103
|
+
|
104
|
+
def find_next(item)
|
105
|
+
index = ordered_entities.find_index { |i| i.lookup_path == item.lookup_path }
|
106
|
+
ordered_entities[index + 1] unless index.nil?
|
107
|
+
end
|
108
|
+
|
109
|
+
def find_previous(item)
|
110
|
+
index = ordered_entities.find_index { |i| i.lookup_path == item.lookup_path }
|
111
|
+
ordered_entities[index - 1] if !index.nil? && index > 0
|
112
|
+
end
|
113
|
+
|
114
|
+
def as_tree(filter_hidden: true)
|
115
|
+
return self if hierarchy_depth > 0
|
116
|
+
return @tree if @tree.present?
|
117
|
+
@tree = self.class.new
|
118
|
+
candidates = filter_hidden ? visible_items : items
|
119
|
+
candidates.each do |item|
|
120
|
+
current = @tree
|
121
|
+
if item.hierarchy_depth == 1
|
122
|
+
current.add(item)
|
123
|
+
else
|
124
|
+
item.parent_collections_names.each.with_index(1) do |name, i|
|
125
|
+
target = current.get_or_create(name)
|
126
|
+
if item.hierarchy_depth == i + 1
|
127
|
+
target.add(item)
|
128
|
+
else
|
129
|
+
current = target
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
@tree
|
45
135
|
end
|
46
136
|
|
47
137
|
def type
|
48
138
|
:collection
|
49
139
|
end
|
140
|
+
|
141
|
+
protected
|
142
|
+
|
143
|
+
def basename
|
144
|
+
@path.present? ? @path.split("/").last : ""
|
145
|
+
end
|
146
|
+
|
147
|
+
class << self
|
148
|
+
def describe_as
|
149
|
+
"items"
|
150
|
+
end
|
151
|
+
end
|
50
152
|
end
|
51
153
|
end
|
data/lib/lookbook/engine.rb
CHANGED
@@ -24,11 +24,13 @@ module Lookbook
|
|
24
24
|
config.lookbook = ActiveSupport::OrderedOptions.new
|
25
25
|
config.lookbook.listen_paths ||= []
|
26
26
|
config.lookbook.preview_paths ||= []
|
27
|
+
config.lookbook.page_paths ||= ["test/components/docs"]
|
27
28
|
|
28
|
-
initializer "view_component.set_configs" do
|
29
|
-
options =
|
30
|
-
vc_options =
|
29
|
+
initializer "view_component.set_configs" do
|
30
|
+
options = config.lookbook
|
31
|
+
vc_options = config.view_component
|
31
32
|
|
33
|
+
options.project_name ||= options.project_name == false ? nil : options.project_name || "Lookbook"
|
32
34
|
options.auto_refresh = true if options.auto_refresh.nil?
|
33
35
|
options.sort_examples = false if options.sort_examples.nil?
|
34
36
|
options.debug = false unless options.debug == true
|
@@ -36,6 +38,13 @@ module Lookbook
|
|
36
38
|
options.preview_paths = options.preview_paths.map(&:to_s)
|
37
39
|
options.preview_paths += vc_options.preview_paths
|
38
40
|
|
41
|
+
options.page_paths = options.page_paths.map(&:to_s)
|
42
|
+
options.page_controller = "Lookbook::PageController" if options.page_controller.nil?
|
43
|
+
options.page_route ||= "pages"
|
44
|
+
options.page_options ||= {}.with_indifferent_access
|
45
|
+
|
46
|
+
options.markdown_options = Markdown::DEFAULT_OPTIONS.merge(options.markdown_options || {})
|
47
|
+
|
39
48
|
options.preview_controller = vc_options.preview_controller if options.preview_controller.nil?
|
40
49
|
options.preview_srcdoc = false if options.preview_srcdoc.nil?
|
41
50
|
options.preview_display_params ||= {}.with_indifferent_access
|
@@ -43,16 +52,14 @@ module Lookbook
|
|
43
52
|
options.listen_paths = options.listen_paths.map(&:to_s)
|
44
53
|
options.listen_paths += options.preview_paths
|
45
54
|
options.listen_paths << (vc_options.view_component_path || Rails.root.join("app/components"))
|
55
|
+
options.listen_paths.filter! { |path| Dir.exist? path }
|
46
56
|
|
47
|
-
options.
|
48
|
-
|
57
|
+
options.cable = ActionCable::Server::Configuration.new
|
58
|
+
options.cable.cable = {adapter: "async"}.with_indifferent_access
|
59
|
+
options.cable.mount_path ||= "/lookbook-cable"
|
60
|
+
options.cable.connection_class = -> { Lookbook::Connection }
|
49
61
|
|
50
|
-
|
51
|
-
if app.config.lookbook.auto_refresh
|
52
|
-
Lookbook::Engine.cable.cable = {adapter: "async"}.with_indifferent_access
|
53
|
-
Lookbook::Engine.cable.mount_path = "/cable"
|
54
|
-
Lookbook::Engine.cable.connection_class = -> { Lookbook::Connection }
|
55
|
-
end
|
62
|
+
options.experimental_features = false unless options.experimental_features.present?
|
56
63
|
end
|
57
64
|
|
58
65
|
initializer "lookbook.parser.tags" do
|
@@ -68,23 +75,25 @@ module Lookbook
|
|
68
75
|
|
69
76
|
initializer "lookbook.logging" do
|
70
77
|
if config.lookbook.debug == true
|
71
|
-
|
78
|
+
config.lookbook.cable.logger ||= Rails.logger
|
72
79
|
else
|
73
|
-
|
80
|
+
config.lookbook.cable.logger = Lookbook::NullLogger.new
|
74
81
|
config.action_view.logger = Lookbook::NullLogger.new
|
75
82
|
end
|
76
83
|
end
|
77
84
|
|
78
|
-
initializer "lookbook.
|
79
|
-
|
80
|
-
ViewComponent::Preview.extend Lookbook::Preview
|
81
|
-
end
|
85
|
+
initializer "lookbook.helpers" do
|
86
|
+
config.action_controller.include_all_helpers = false
|
82
87
|
end
|
83
88
|
|
84
|
-
config.after_initialize do
|
85
|
-
|
89
|
+
config.after_initialize do
|
90
|
+
Array(config.view_component.preview_paths).each do |preview_path|
|
91
|
+
Dir["#{preview_path}/**/*_preview.rb"].sort.each { |file| require_dependency file }
|
92
|
+
end
|
93
|
+
|
94
|
+
@preview_listener = Listen.to(*config.lookbook.listen_paths, only: /\.(rb|html.*)$/) do |modified, added, removed|
|
86
95
|
parser.parse
|
87
|
-
if
|
96
|
+
if Lookbook::Engine.websocket
|
88
97
|
if (modified.any? || removed.any?) && added.none?
|
89
98
|
Lookbook::Engine.websocket.broadcast("reload", {
|
90
99
|
modified: modified,
|
@@ -93,32 +102,50 @@ module Lookbook
|
|
93
102
|
end
|
94
103
|
end
|
95
104
|
end
|
96
|
-
@
|
105
|
+
@preview_listener.start
|
106
|
+
|
107
|
+
if Lookbook::Features.enabled?(:pages)
|
108
|
+
@page_listener = Listen.to(*config.lookbook.page_paths.filter { |dir| Dir.exist? dir }, only: /\.(html.*|md.*)$/) do |modified, added, removed|
|
109
|
+
if Lookbook::Engine.websocket
|
110
|
+
if modified.any? || removed.any? || added.any?
|
111
|
+
Lookbook::Engine.websocket.broadcast("reload", {
|
112
|
+
modified: modified,
|
113
|
+
removed: removed,
|
114
|
+
added: added
|
115
|
+
})
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
@page_listener.start
|
120
|
+
end
|
121
|
+
|
97
122
|
parser.parse
|
98
123
|
end
|
99
124
|
|
100
125
|
at_exit do
|
101
|
-
@
|
126
|
+
@preview_listener&.stop
|
127
|
+
@page_listener&.stop
|
102
128
|
end
|
103
129
|
|
104
130
|
class << self
|
105
131
|
def websocket
|
106
|
-
if
|
107
|
-
@websocket ||=
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
132
|
+
if config.lookbook.auto_refresh
|
133
|
+
@websocket ||= if Rails.version.to_f >= 6.0
|
134
|
+
ActionCable::Server::Base.new(config: config.lookbook.cable)
|
135
|
+
else
|
136
|
+
websocket ||= ActionCable::Server::Base.new
|
137
|
+
websocket.config = config.lookbook.cable
|
138
|
+
websocket
|
139
|
+
end
|
113
140
|
end
|
114
141
|
end
|
115
142
|
|
116
143
|
def websocket_mount_path
|
117
|
-
"#{
|
144
|
+
"#{mounted_path}#{config.lookbook.cable.mount_path}" if websocket
|
118
145
|
end
|
119
146
|
|
120
|
-
def
|
121
|
-
|
147
|
+
def mounted_path
|
148
|
+
Lookbook::Engine.routes.find_script_name({})
|
122
149
|
end
|
123
150
|
|
124
151
|
def parser
|
data/lib/lookbook/features.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "redcarpet"
|
2
|
+
|
3
|
+
module Lookbook
|
4
|
+
class Markdown
|
5
|
+
DEFAULT_OPTIONS = {
|
6
|
+
tables: true,
|
7
|
+
fenced_code_blocks: true,
|
8
|
+
disable_indented_code_blocks: true,
|
9
|
+
strikethrough: true,
|
10
|
+
highlight: true,
|
11
|
+
with_toc_data: true
|
12
|
+
}
|
13
|
+
|
14
|
+
def self.render(text)
|
15
|
+
markdown = Redcarpet::Markdown.new(Renderer, Lookbook.config.markdown_options)
|
16
|
+
markdown.render(text).html_safe
|
17
|
+
end
|
18
|
+
|
19
|
+
class Renderer < Redcarpet::Render::HTML
|
20
|
+
def block_code(code, language = "ruby")
|
21
|
+
line_numbers = language.to_s.end_with? "-numbered"
|
22
|
+
ApplicationController.render "lookbook/components/_code", locals: {
|
23
|
+
code: code,
|
24
|
+
language: language.to_s.chomp("-numbered"),
|
25
|
+
line_numbers: line_numbers
|
26
|
+
},
|
27
|
+
layout: nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module Lookbook
|
2
|
+
class Page
|
3
|
+
include Utils
|
4
|
+
|
5
|
+
FRONTMATTER_FIELDS = [
|
6
|
+
:id,
|
7
|
+
:label,
|
8
|
+
:title,
|
9
|
+
:hidden,
|
10
|
+
:landing,
|
11
|
+
:position,
|
12
|
+
:markdown,
|
13
|
+
:header,
|
14
|
+
:footer,
|
15
|
+
:data
|
16
|
+
]
|
17
|
+
|
18
|
+
def initialize(path, base_path)
|
19
|
+
@pathname = Pathname.new path
|
20
|
+
@base_path = base_path
|
21
|
+
end
|
22
|
+
|
23
|
+
def path
|
24
|
+
rel_path = @pathname.relative_path_from(@base_path)
|
25
|
+
(rel_path.dirname.to_s == "." ? name : "#{rel_path.dirname}/#{name}")
|
26
|
+
end
|
27
|
+
|
28
|
+
def lookup_path
|
29
|
+
@lookup_path ||= to_lookup_path(path)
|
30
|
+
end
|
31
|
+
|
32
|
+
def full_path
|
33
|
+
Rails.root.join(@pathname.to_s)
|
34
|
+
end
|
35
|
+
|
36
|
+
def name
|
37
|
+
remove_position_prefix(path_name)
|
38
|
+
end
|
39
|
+
|
40
|
+
def hidden?
|
41
|
+
options[:hidden] == true
|
42
|
+
end
|
43
|
+
|
44
|
+
def markdown?
|
45
|
+
options[:markdown] == true
|
46
|
+
end
|
47
|
+
|
48
|
+
def header?
|
49
|
+
options[:header] == true
|
50
|
+
end
|
51
|
+
|
52
|
+
def footer?
|
53
|
+
options[:footer] == true
|
54
|
+
end
|
55
|
+
|
56
|
+
def get(key)
|
57
|
+
options[key]
|
58
|
+
end
|
59
|
+
|
60
|
+
def content
|
61
|
+
@content ||= strip_frontmatter(file_contents)
|
62
|
+
end
|
63
|
+
|
64
|
+
def matchers
|
65
|
+
normalize_matchers(label)
|
66
|
+
end
|
67
|
+
|
68
|
+
def hierarchy_depth
|
69
|
+
path.split("/").size
|
70
|
+
end
|
71
|
+
|
72
|
+
def parent_collections_names
|
73
|
+
File.dirname(path).split("/")
|
74
|
+
end
|
75
|
+
|
76
|
+
def type
|
77
|
+
:page
|
78
|
+
end
|
79
|
+
|
80
|
+
def method_missing(method_name, *args, &block)
|
81
|
+
if args.none? && !block
|
82
|
+
options[method_name]
|
83
|
+
else
|
84
|
+
super
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def respond_to_missing?(method_name, include_private = false)
|
89
|
+
FRONTMATTER_FIELDS.include? method_name
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
|
94
|
+
def file_contents
|
95
|
+
File.read(full_path)
|
96
|
+
end
|
97
|
+
|
98
|
+
def options
|
99
|
+
return @options if @options
|
100
|
+
frontmatter = (get_frontmatter(file_contents) || {}).deep_symbolize_keys
|
101
|
+
options = Lookbook.config.page_options.deep_merge(frontmatter).with_indifferent_access
|
102
|
+
options[:id] = options[:id] ? generate_id(options[:id]) : generate_id(lookup_path)
|
103
|
+
options[:label] ||= name.titleize
|
104
|
+
options[:title] ||= options[:label]
|
105
|
+
options[:hidden] ||= false
|
106
|
+
options[:landing] ||= false
|
107
|
+
options[:position] = options[:position] ? options[:position].to_i : get_position_prefix(path_name)
|
108
|
+
options[:markdown] ||= markdown_file?
|
109
|
+
options[:header] = true unless options.key? :header
|
110
|
+
options[:footer] = true unless options.key? :footer
|
111
|
+
@options ||= options
|
112
|
+
end
|
113
|
+
|
114
|
+
def path_name
|
115
|
+
@pathname.basename(@pathname.extname).to_s.gsub(/\.(html|md)$/, "")
|
116
|
+
end
|
117
|
+
|
118
|
+
def markdown_file?
|
119
|
+
@pathname.basename(@pathname.extname).to_s.end_with?(".md")
|
120
|
+
end
|
121
|
+
|
122
|
+
class << self
|
123
|
+
def find(path)
|
124
|
+
all.find { |p| p.lookup_path == path }
|
125
|
+
end
|
126
|
+
|
127
|
+
def exists?(path)
|
128
|
+
!!find(path)
|
129
|
+
end
|
130
|
+
|
131
|
+
def all
|
132
|
+
pages = Array(page_paths).map do |dir|
|
133
|
+
Dir["#{dir}/**/*.html.*", "#{dir}/**/*.md.*"].sort.map do |page|
|
134
|
+
Lookbook::Page.new(page, dir)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
sorted_pages = pages.flatten.uniq { |p| p.path }.sort_by { |page| [page.position, page.label] }
|
138
|
+
PageCollection.new(sorted_pages)
|
139
|
+
end
|
140
|
+
|
141
|
+
def page_paths
|
142
|
+
Lookbook.config.page_paths.filter { |dir| Dir.exist? dir }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
data/lib/lookbook/parser.rb
CHANGED
@@ -28,6 +28,8 @@ module Lookbook
|
|
28
28
|
YARD::Tags::Library.define_tag("Hidden status", :hidden)
|
29
29
|
YARD::Tags::Library.define_tag("Label", :label)
|
30
30
|
YARD::Tags::Library.define_tag("Display", :display)
|
31
|
+
YARD::Tags::Library.define_tag("Position", :position)
|
32
|
+
YARD::Tags::Library.define_tag("ID", :id)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|