markdown_record 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +225 -0
- data/Rakefile +9 -0
- data/app/assets/config/markdown_cms_manifest.js +1 -0
- data/app/assets/stylesheets/markdown_cms/application.css +15 -0
- data/app/controllers/markdown_record/application_controller.rb +11 -0
- data/app/controllers/markdown_record/content_controller.rb +19 -0
- data/app/controllers/markdown_record/html_controller.rb +11 -0
- data/app/controllers/markdown_record/json_controller.rb +11 -0
- data/app/helpers/markdown_record/application_helper.rb +4 -0
- data/app/helpers/markdown_record/controller_helpers.rb +39 -0
- data/app/helpers/markdown_record/view_helpers.rb +84 -0
- data/app/models/markdown_record/demo/dsl_command.rb +10 -0
- data/app/models/markdown_record/demo/section.rb +9 -0
- data/app/models/markdown_record/tests/child_model.rb +15 -0
- data/app/models/markdown_record/tests/fake_active_record_model.rb +13 -0
- data/app/models/markdown_record/tests/model.rb +15 -0
- data/app/models/markdown_record/tests/other_child_model.rb +15 -0
- data/config/routes.rb +13 -0
- data/lib/generators/markdown_record_generator.rb +44 -0
- data/lib/markdown_record/association.rb +131 -0
- data/lib/markdown_record/associations.rb +106 -0
- data/lib/markdown_record/base.rb +25 -0
- data/lib/markdown_record/cli.rb +54 -0
- data/lib/markdown_record/configuration.rb +66 -0
- data/lib/markdown_record/content_associations.rb +46 -0
- data/lib/markdown_record/content_dsl/attribute.rb +22 -0
- data/lib/markdown_record/content_dsl/directory_fragment.rb +22 -0
- data/lib/markdown_record/content_dsl/disable.rb +22 -0
- data/lib/markdown_record/content_dsl/enable.rb +22 -0
- data/lib/markdown_record/content_dsl/end_attribute.rb +22 -0
- data/lib/markdown_record/content_dsl/end_model.rb +22 -0
- data/lib/markdown_record/content_dsl/fragment.rb +22 -0
- data/lib/markdown_record/content_dsl/model.rb +23 -0
- data/lib/markdown_record/content_dsl/render_format.rb +22 -0
- data/lib/markdown_record/content_dsl/render_strategy.rb +22 -0
- data/lib/markdown_record/content_dsl/use_layout.rb +22 -0
- data/lib/markdown_record/content_dsl.rb +37 -0
- data/lib/markdown_record/content_fragment.rb +123 -0
- data/lib/markdown_record/engine.rb +13 -0
- data/lib/markdown_record/errors/base.rb +6 -0
- data/lib/markdown_record/errors/duplicate_filename_error.rb +21 -0
- data/lib/markdown_record/errors/duplicate_id_error.rb +11 -0
- data/lib/markdown_record/errors/missing_parent_error.rb +11 -0
- data/lib/markdown_record/file_saver.rb +39 -0
- data/lib/markdown_record/html_renderer.rb +194 -0
- data/lib/markdown_record/indexer.rb +34 -0
- data/lib/markdown_record/json_renderer.rb +270 -0
- data/lib/markdown_record/model_inflator.rb +107 -0
- data/lib/markdown_record/path_utilities.rb +86 -0
- data/lib/markdown_record/rendering.rb +57 -0
- data/lib/markdown_record/routes_renderer.rb +0 -0
- data/lib/markdown_record/validator.rb +59 -0
- data/lib/markdown_record/version.rb +3 -0
- data/lib/markdown_record.rb +28 -0
- data/templates/Thorfile +3 -0
- data/templates/base/content/example_content.md +3 -0
- data/templates/base/layouts/_concatenated_layout.html.erb +8 -0
- data/templates/base/layouts/_custom_layout.html.erb +7 -0
- data/templates/base/layouts/_file_layout.html.erb +8 -0
- data/templates/base/layouts/_global_layout.html.erb +8 -0
- data/templates/demo/assets/images/ruby-logo.png +0 -0
- data/templates/demo/content/10_custom_models_and_associations.md.erb +78 -0
- data/templates/demo/content/11_controller_helpers.md.erb +20 -0
- data/templates/demo/content/12_configuration.md.erb +26 -0
- data/templates/demo/content/13_sandbox/1_foo.md +12 -0
- data/templates/demo/content/13_sandbox/2_sandbox_nested/1_bar.md +18 -0
- data/templates/demo/content/1_home.md.erb +40 -0
- data/templates/demo/content/2_installation.md.erb +129 -0
- data/templates/demo/content/3_rendering_basics.md.erb +71 -0
- data/templates/demo/content/4_content_dsl.md.erb +104 -0
- data/templates/demo/content/5_routes.md.erb +43 -0
- data/templates/demo/content/6_model_basics.md.erb +105 -0
- data/templates/demo/content/7_content_frags.md.erb +78 -0
- data/templates/demo/content/8_erb_syntax_and_view_helpers.md.erb +88 -0
- data/templates/demo/content/9_layouts.md.erb +15 -0
- data/templates/demo/layouts/_concatenated_layout.html.erb +12 -0
- data/templates/demo/layouts/_custom_layout.html.erb +14 -0
- data/templates/demo/layouts/_file_layout.html.erb +15 -0
- data/templates/demo/layouts/_global_layout.html.erb +108 -0
- data/templates/markdown_record_initializer.rb +3 -0
- data/templates/render_content.thor +57 -0
- metadata +270 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
require "markdown_record/content_dsl/model"
|
2
|
+
require "markdown_record/content_dsl/attribute"
|
3
|
+
require "markdown_record/content_dsl/end_attribute"
|
4
|
+
require "markdown_record/content_dsl/end_model"
|
5
|
+
require "markdown_record/content_dsl/fragment"
|
6
|
+
require "markdown_record/content_dsl/directory_fragment"
|
7
|
+
require "markdown_record/content_dsl/use_layout"
|
8
|
+
require "markdown_record/content_dsl/disable"
|
9
|
+
require "markdown_record/content_dsl/enable"
|
10
|
+
|
11
|
+
module MarkdownRecord
|
12
|
+
module ContentDsl
|
13
|
+
include Model
|
14
|
+
include Attribute
|
15
|
+
include EndAttribute
|
16
|
+
include EndModel
|
17
|
+
include DirectoryFragment
|
18
|
+
include Fragment
|
19
|
+
include UseLayout
|
20
|
+
include Disable
|
21
|
+
include Enable
|
22
|
+
|
23
|
+
HTML_COMMENT_REGEX = /(<!--(?:(?:\s|.)(?!-->))*(?:.|\s)-->)/
|
24
|
+
|
25
|
+
def remove_dsl(text)
|
26
|
+
text = Model.remove_dsl(text)
|
27
|
+
text = Attribute.remove_dsl(text)
|
28
|
+
text = EndAttribute.remove_dsl(text)
|
29
|
+
text = EndModel.remove_dsl(text)
|
30
|
+
text = Fragment.remove_dsl(text)
|
31
|
+
text = UseLayout.remove_dsl(text)
|
32
|
+
text = Disable.remove_dsl(text)
|
33
|
+
text = Enable.remove_dsl(text)
|
34
|
+
text
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
class ContentFragment < MarkdownRecord::Base
|
3
|
+
include MarkdownRecord::PathUtilities
|
4
|
+
|
5
|
+
attribute :meta, :type => Object
|
6
|
+
attribute :concatenated, :type => Boolean
|
7
|
+
|
8
|
+
def initialize(attributes = nil, options = {})
|
9
|
+
super
|
10
|
+
|
11
|
+
if self.meta.class == Hash
|
12
|
+
self.meta = self.meta.with_indifferent_access
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Override the new_association method on MarkdownRecord::Base
|
17
|
+
# to force all association queries to only look for fragments
|
18
|
+
def self.new_association(base_filters = {}, search_filters = {})
|
19
|
+
MarkdownRecord::Association.new(base_filters, search_filters).fragmentize
|
20
|
+
end
|
21
|
+
|
22
|
+
def fragment_id
|
23
|
+
id
|
24
|
+
end
|
25
|
+
|
26
|
+
def name
|
27
|
+
meta[:name]
|
28
|
+
end
|
29
|
+
|
30
|
+
def exists?
|
31
|
+
json_exists? || html_exists?
|
32
|
+
end
|
33
|
+
|
34
|
+
def json_exists?
|
35
|
+
Pathname.new(json_path).exist?
|
36
|
+
end
|
37
|
+
|
38
|
+
def html_exists?
|
39
|
+
Pathname.new(html_path).exist?
|
40
|
+
end
|
41
|
+
|
42
|
+
def read_json
|
43
|
+
File.read(json_path) if json_exists?
|
44
|
+
end
|
45
|
+
|
46
|
+
def read_html
|
47
|
+
File.read(html_path) if html_exists?
|
48
|
+
end
|
49
|
+
|
50
|
+
def json_path
|
51
|
+
path("json")
|
52
|
+
end
|
53
|
+
|
54
|
+
def json_route
|
55
|
+
route("json", id)
|
56
|
+
end
|
57
|
+
|
58
|
+
def html_path
|
59
|
+
path("html")
|
60
|
+
end
|
61
|
+
|
62
|
+
def html_route
|
63
|
+
route("html", id)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Associations
|
67
|
+
def ancestors
|
68
|
+
ancestors_from(::MarkdownRecord.config.content_root.basename.to_s)
|
69
|
+
end
|
70
|
+
|
71
|
+
def parent
|
72
|
+
self.class.find(meta[:parent_id] || subdirectory)
|
73
|
+
end
|
74
|
+
|
75
|
+
def ancestors_from(ancestor)
|
76
|
+
ancestor = self.class.find(ancestor) if ancestor.is_a?(String)
|
77
|
+
|
78
|
+
parents = []
|
79
|
+
current_parent = self.class.find(subdirectory)
|
80
|
+
|
81
|
+
while current_parent
|
82
|
+
if current_parent.id == ancestor.id
|
83
|
+
parents.unshift(current_parent)
|
84
|
+
current_parent = nil
|
85
|
+
else
|
86
|
+
parents.unshift(current_parent)
|
87
|
+
current_parent = self.class.find(current_parent.subdirectory)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
parents
|
92
|
+
end
|
93
|
+
|
94
|
+
def parents_from(ancestor)
|
95
|
+
ancestor = self.class.find(ancestor) if ancestor.is_a?(String)
|
96
|
+
|
97
|
+
parents = []
|
98
|
+
current_parent = self
|
99
|
+
|
100
|
+
while current_parent
|
101
|
+
if current_parent.id == ancestor&.id
|
102
|
+
parents.unshift(current_parent)
|
103
|
+
current_parent = nil
|
104
|
+
else
|
105
|
+
parents.unshift(current_parent)
|
106
|
+
current_parent = current_parent.parent
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
parents
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def path(ext)
|
116
|
+
"#{::MarkdownRecord.config.rendered_content_root.join(id).to_s}.#{ext}"
|
117
|
+
end
|
118
|
+
|
119
|
+
def route(ext, path)
|
120
|
+
"#{ext}/#{path}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace MarkdownRecord
|
4
|
+
|
5
|
+
initializer "markdown_record.view_helpers" do
|
6
|
+
ActiveSupport.on_load(:action_view) { include MarkdownRecord::ViewHelpers }
|
7
|
+
end
|
8
|
+
|
9
|
+
initializer 'markdown_record.controller_helpers' do
|
10
|
+
ActiveSupport.on_load(:action_controller) { include ::MarkdownRecord::ControllerHelpers }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "markdown_record/errors/base"
|
2
|
+
|
3
|
+
module MarkdownRecord
|
4
|
+
module Errors
|
5
|
+
class DuplicateFilenameError < MarkdownRecord::Errors::Base
|
6
|
+
def initialize(filenames)
|
7
|
+
msgs = []
|
8
|
+
|
9
|
+
filenames.each do |f|
|
10
|
+
if MarkdownRecord.config.ignore_numeric_prefix
|
11
|
+
msgs << "There are multiple files that resolve to [#{f}] after numeric prefixes are ignored."
|
12
|
+
else
|
13
|
+
msgs << "There are multiple files that resolve to [#{f}]."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
super(msgs.join("\n"))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
class FileSaver
|
3
|
+
include ::MarkdownRecord::PathUtilities
|
4
|
+
|
5
|
+
attr_accessor :saved_files
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@saved_files = {:html => [], :json => []}
|
9
|
+
end
|
10
|
+
|
11
|
+
def save_to_file(content, rendered_subdirectory, options, fragments = false)
|
12
|
+
filename, subdirectory, extension = full_path_to_parts(rendered_subdirectory)
|
13
|
+
filename = file_name(filename, extension, fragments)
|
14
|
+
|
15
|
+
save_path = ::MarkdownRecord.config.rendered_content_root.join(subdirectory).join(filename)
|
16
|
+
relative_path = save_path.to_s.gsub(Rails.root.to_s, "")
|
17
|
+
|
18
|
+
@saved_files[extension.to_sym].unshift(relative_path)
|
19
|
+
|
20
|
+
if options[:save]
|
21
|
+
save_path.dirname.mkpath
|
22
|
+
|
23
|
+
save_path.open('wb') do |file|
|
24
|
+
file << content
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def base_content_name
|
30
|
+
::MarkdownRecord.config.content_root.basename
|
31
|
+
end
|
32
|
+
|
33
|
+
def file_name(subdirectory, extension, fragments)
|
34
|
+
base_name = ::MarkdownRecord.config.content_root.join(subdirectory).basename.to_s
|
35
|
+
base_name += "_fragments" if fragments
|
36
|
+
"#{base_name}.#{extension}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require "redcarpet"
|
2
|
+
require "htmlbeautifier"
|
3
|
+
|
4
|
+
module MarkdownRecord
|
5
|
+
class HtmlRenderer < ::Redcarpet::Render::HTML
|
6
|
+
include ::MarkdownRecord::PathUtilities
|
7
|
+
include ::MarkdownRecord::ContentDsl
|
8
|
+
|
9
|
+
HTML_SUBSTITUTIONS = {
|
10
|
+
/<!---/ => "<!--",
|
11
|
+
/<!---/ => "<!--"
|
12
|
+
}
|
13
|
+
|
14
|
+
def initialize(
|
15
|
+
file_saver: ::MarkdownRecord::FileSaver.new)
|
16
|
+
super(::MarkdownRecord.config.html_render_options)
|
17
|
+
@indexer = ::MarkdownRecord::Indexer.new
|
18
|
+
@markdown = ::Redcarpet::Markdown.new(self, ::MarkdownRecord.config.markdown_extensions)
|
19
|
+
@file_saver = file_saver
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_html_for_subdirectory(subdirectory: "", **options)
|
23
|
+
content = @indexer.index(subdirectory: subdirectory)
|
24
|
+
rendered_subdirectory = base_content_path.join(subdirectory)
|
25
|
+
|
26
|
+
html_content = render_html_recursively(content, rendered_subdirectory.to_s)
|
27
|
+
processed_html = process_html_recursively(html_content[rendered_subdirectory.to_s], rendered_subdirectory, options)
|
28
|
+
final_html = finalize_html_recursively(processed_html, rendered_subdirectory)
|
29
|
+
|
30
|
+
save_content_recursively(final_html, options, rendered_subdirectory)
|
31
|
+
{ :html_content => processed_html, :saved_files => @file_saver.saved_files }
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def render_html_recursively(file_or_directory, file_or_directory_name)
|
38
|
+
case file_or_directory.class.name
|
39
|
+
when Hash.name # if it is a directory
|
40
|
+
directory_hash = { file_or_directory_name => {} } # hash representing the directory and its contents
|
41
|
+
|
42
|
+
file_or_directory.each do |child_file_or_directory_name, child_file_or_directory|
|
43
|
+
child_content_hash = render_html_recursively(child_file_or_directory, child_file_or_directory_name)
|
44
|
+
directory_hash[file_or_directory_name].merge!(child_content_hash)
|
45
|
+
end
|
46
|
+
|
47
|
+
directory_hash
|
48
|
+
when String.name # if it is a file
|
49
|
+
{ file_or_directory_name => render_html(file_or_directory) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def render_html(html)
|
54
|
+
rendered_html = @markdown.render(html)
|
55
|
+
remove_dsl(rendered_html)
|
56
|
+
end
|
57
|
+
|
58
|
+
def process_html_recursively(file_or_directory, full_path, options)
|
59
|
+
case file_or_directory.class.name
|
60
|
+
when Hash.name
|
61
|
+
directory_hash = { full_path.to_s => {} } # hash representing the directory and its contents
|
62
|
+
|
63
|
+
file_or_directory.each do |child_file_or_directory_name, child_file_or_directory|
|
64
|
+
child_content_hash = process_html_recursively(child_file_or_directory, full_path.join(child_file_or_directory_name), options)
|
65
|
+
directory_hash[full_path.to_s].merge!(child_content_hash)
|
66
|
+
end
|
67
|
+
|
68
|
+
if options[:concat]
|
69
|
+
concatenated_html = concatenate_html_recursively(directory_hash[full_path.to_s], []).join("\r\n")
|
70
|
+
directory_hash["#{full_path.to_s}.concat"] = process_html(concatenated_html, full_path.to_s, concatenated_layout)
|
71
|
+
end
|
72
|
+
|
73
|
+
directory_hash.compact
|
74
|
+
when String.name # if it is a file
|
75
|
+
if options[:deep]
|
76
|
+
{ full_path.to_s => process_html(file_or_directory, full_path, custom_layout(file_or_directory) || file_layout) }
|
77
|
+
else
|
78
|
+
{ }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def process_html(html, full_path, layout = nil)
|
84
|
+
processed_html = html.gsub(/<p>(\<%(\S|\s)*?%\>)<\/p>/){ CGI.unescapeHTML($1) }
|
85
|
+
processed_html = processed_html.gsub(/(\<%(\S|\s)*?%\>)/){ CGI.unescapeHTML($1) }
|
86
|
+
locals = erb_locals_from_path(full_path.to_s)
|
87
|
+
processed_html = render_erb(processed_html, locals) if full_path.to_s.ends_with?(".md.erb")
|
88
|
+
processed_html = render_erb(layout, locals.merge(html: processed_html)) if layout
|
89
|
+
processed_html
|
90
|
+
end
|
91
|
+
|
92
|
+
def render_erb(html, locals)
|
93
|
+
render_controller = ::MarkdownRecord.config.render_controller || ::ApplicationController
|
94
|
+
rendered_html = render_controller.render(
|
95
|
+
inline: html,
|
96
|
+
locals: locals
|
97
|
+
).to_str
|
98
|
+
rendered_html
|
99
|
+
end
|
100
|
+
|
101
|
+
def concatenate_html_recursively(content, html)
|
102
|
+
case content.class.name
|
103
|
+
when Hash.name
|
104
|
+
sorted_hash_values(content).each do |v|
|
105
|
+
concatenate_html_recursively(v, html)
|
106
|
+
end
|
107
|
+
when String.name
|
108
|
+
html << content
|
109
|
+
end
|
110
|
+
html
|
111
|
+
end
|
112
|
+
|
113
|
+
def sorted_hash_values(hash)
|
114
|
+
values = []
|
115
|
+
keys = hash.keys.sort_by do |k|
|
116
|
+
basename = k.split("/").last
|
117
|
+
m = basename.match(/^(\d+)_/)
|
118
|
+
m.try(:[], 1).to_i || k
|
119
|
+
end
|
120
|
+
|
121
|
+
keys.each do |k|
|
122
|
+
values << hash[k] if !k.include?(".concat")
|
123
|
+
end
|
124
|
+
values
|
125
|
+
end
|
126
|
+
|
127
|
+
def custom_layout(html)
|
128
|
+
layout = use_layout_dsl(html)
|
129
|
+
return unless layout
|
130
|
+
|
131
|
+
File.read(::MarkdownRecord.config.layout_directory.join(layout))
|
132
|
+
end
|
133
|
+
|
134
|
+
def global_layout
|
135
|
+
global_layout_path = ::MarkdownRecord.config.global_layout_path
|
136
|
+
@global_layout ||= global_layout_path ? layout(global_layout_path) : nil
|
137
|
+
end
|
138
|
+
|
139
|
+
def concatenated_layout
|
140
|
+
concatenated_layout_path = ::MarkdownRecord.config.concatenated_layout_path
|
141
|
+
@concatenated_layout ||= concatenated_layout_path ? layout(concatenated_layout_path) : nil
|
142
|
+
end
|
143
|
+
|
144
|
+
def file_layout
|
145
|
+
file_layout_path = ::MarkdownRecord.config.file_layout_path
|
146
|
+
@file_layout ||= file_layout_path ? layout(file_layout_path) : nil
|
147
|
+
end
|
148
|
+
|
149
|
+
def layout(path)
|
150
|
+
File.read(::MarkdownRecord.config.layout_directory.join(path))
|
151
|
+
end
|
152
|
+
|
153
|
+
def finalize_html_recursively(content, rendered_subdirectory)
|
154
|
+
case content.class.name
|
155
|
+
when Hash.name
|
156
|
+
final_hash = {}
|
157
|
+
content.each do |key, value|
|
158
|
+
child_path = rendered_subdirectory.join(key)
|
159
|
+
final_hash[key] = finalize_html_recursively(value, child_path)
|
160
|
+
end
|
161
|
+
final_hash
|
162
|
+
when String.name
|
163
|
+
finalize_html(content, rendered_subdirectory)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def finalize_html(html, full_path)
|
168
|
+
locals = erb_locals_from_path(full_path)
|
169
|
+
final_html = html
|
170
|
+
final_html = render_erb(global_layout, locals.merge(html: final_html)) if global_layout
|
171
|
+
|
172
|
+
HTML_SUBSTITUTIONS.each do |find, replace|
|
173
|
+
final_html = final_html.gsub(find, replace)
|
174
|
+
end
|
175
|
+
|
176
|
+
final_html = final_html.squeeze("\n")
|
177
|
+
final_html = HtmlBeautifier.beautify(final_html)
|
178
|
+
final_html
|
179
|
+
end
|
180
|
+
|
181
|
+
def save_content_recursively(content, options, rendered_subdirectory)
|
182
|
+
case content.class.name
|
183
|
+
when Hash.name
|
184
|
+
content.each do |key, value|
|
185
|
+
child_path = rendered_subdirectory.join(key)
|
186
|
+
save_content_recursively(value, options, child_path)
|
187
|
+
end
|
188
|
+
when String.name
|
189
|
+
path = clean_path(rendered_subdirectory.to_s)
|
190
|
+
@file_saver.save_to_file(content, "#{path}.html", options)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
class Indexer
|
3
|
+
|
4
|
+
def index(subdirectory: "")
|
5
|
+
content_path = ::MarkdownRecord.config.content_root.join(subdirectory)
|
6
|
+
index = {}
|
7
|
+
recursive_index(content_path, index)
|
8
|
+
index
|
9
|
+
end
|
10
|
+
|
11
|
+
def file(path)
|
12
|
+
file_path = ::MarkdownRecord.config.content_root.join(path)
|
13
|
+
|
14
|
+
if Pathname.new(path).extname == ".md" && file_path.exist?
|
15
|
+
File.read(file_path)
|
16
|
+
else
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def recursive_index(parent_dir_path, index)
|
22
|
+
parent_root = Dir.new(parent_dir_path)
|
23
|
+
parent_root.children.each do |child|
|
24
|
+
pathname = Pathname.new("#{parent_dir_path}/#{child}")
|
25
|
+
if pathname.directory?
|
26
|
+
index[child] = {}
|
27
|
+
recursive_index(pathname, index[child])
|
28
|
+
else
|
29
|
+
index[child] = File.read(pathname) if (pathname.extname == ".md" || pathname.to_s =~ /\.md\.erb$/)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|