hologram 0.6.0 → 1.0.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 +7 -4
- data/Rakefile +5 -0
- data/hologram.gemspec +1 -1
- data/lib/hologram.rb +13 -445
- data/lib/hologram/display_message.rb +79 -0
- data/lib/hologram/doc_block_collection.rb +48 -0
- data/lib/hologram/doc_builder.rb +196 -0
- data/lib/hologram/doc_parser.rb +125 -0
- data/lib/hologram/document_block.rb +36 -0
- data/lib/hologram/template_variables.rb +21 -0
- data/lib/hologram/version.rb +1 -1
- data/lib/template/doc_assets/_header.html +7 -2
- data/lib/template/hologram_config.yml +3 -0
- data/spec/display_message_spec.rb +115 -0
- data/spec/doc_block_collection_spec.rb +80 -0
- data/spec/doc_builder_spec.rb +92 -0
- data/spec/doc_parser_spec.rb +89 -0
- data/spec/document_block_spec.rb +62 -0
- data/spec/fixtures/source/components/background/backgrounds.css +46 -0
- data/spec/fixtures/source/components/button/buttons.css +87 -0
- data/spec/fixtures/source/components/button/skin/buttonSkins.css +113 -0
- data/spec/fixtures/source/components/index.md +23 -0
- data/spec/fixtures/source/config.yml +17 -0
- data/spec/fixtures/source/extra/css/screen.css +1 -0
- data/spec/fixtures/source/templates/_footer.html +9 -0
- data/spec/fixtures/source/templates/_header.html +57 -0
- data/spec/fixtures/source/templates/static/css/doc.css +132 -0
- data/spec/fixtures/styleguide/base_css.html +170 -0
- data/spec/fixtures/styleguide/extra/css/screen.css +1 -0
- data/spec/fixtures/styleguide/index.html +84 -0
- data/spec/fixtures/styleguide/static/css/doc.css +132 -0
- data/spec/spec_helper.rb +7 -0
- metadata +66 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76d2ba97aebf57d28a1af14bb938face091b9f7a
|
4
|
+
data.tar.gz: 4c257fc06a73984a890d15d11e42f46ae5150203
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21c7f40342561dd6ea32edaf1e76390f08d0b7dfbb2c64fce8e60596227e2a562e90cde16478e052930a4205dbcae738385943da5eec8eeb23bdf06209f7a323
|
7
|
+
data.tar.gz: 56dc6706a6ff01a7bcbfbe874f27d6c5bd5723cd809c9fe976be6027b0f92a1fff4610f20f34280ffaf13f1c7fe001cafa3a725a0ce6fdcb9613ed6c61f8808f
|
data/README.md
CHANGED
@@ -66,13 +66,13 @@ Your config file needs to contain the following key/value pairs
|
|
66
66
|
(header/footer, etc), styleguide specific CSS, javascript and any
|
67
67
|
images. Hologram specifically looks for two files: `_header.html` and
|
68
68
|
`_footer.html`, these are used to start and end every html page
|
69
|
-
hologram generates.
|
69
|
+
hologram generates.
|
70
70
|
|
71
71
|
Hologram treats `_header.html` and `_footer.html`
|
72
72
|
as ERB files for each page that is generated you can access the
|
73
73
|
`title`, `file_name`, and `blocks`. `blocks` is a list of each
|
74
74
|
documenation block on the page. Each item in the list has a `title`,
|
75
|
-
`name`, `category`, and optionally a `parent`. This is useful for, say, building a menu that lists each component.
|
75
|
+
`name`, `category`, and optionally a `parent`. This is useful for, say, building a menu that lists each component.
|
76
76
|
**Nota Bene:** Filenames that begin with underscores will not be copied into the destination folder.
|
77
77
|
|
78
78
|
|
@@ -150,9 +150,9 @@ but it specifically looks for the following keys:
|
|
150
150
|
components in the same category will be written to the same page.
|
151
151
|
* **name**: This is used for grouping components, by assigning
|
152
152
|
a name a component can be referenced in another component as a parent.
|
153
|
-
* **parent**: (Optional.) This should be the **name** of another components. If this is set the current component will be displayed as a section within the **parent**'s documentation.
|
153
|
+
* **parent**: (Optional.) This should be the **name** of another components. If this is set the current component will be displayed as a section within the **parent**'s documentation.
|
154
154
|
|
155
|
-
For example, you might have a component with the **name** *buttons* and another component named *buttonSkins*. You could set the **parent** for the *buttonSkins* component to be *buttons*. It would then nest the *buttonSkins* documentation inside the *buttons* documentation.
|
155
|
+
For example, you might have a component with the **name** *buttons* and another component named *buttonSkins*. You could set the **parent** for the *buttonSkins* component to be *buttons*. It would then nest the *buttonSkins* documentation inside the *buttons* documentation.
|
156
156
|
|
157
157
|
Each level of nesting (components are infinitely nestable) will have a heading tag that represents its depth. In the above example *buttons* would have an `<h1>` and *buttonSkins* would have an `<h2>`. This you can [see this exact example in our demo repo](https://github.com/trulia/hologram-example/tree/master/components/button), and the output of this nesting [in our demo styleguide](http://trulia.github.io/hologram-example/base_css.html#Buttons).
|
158
158
|
|
@@ -183,6 +183,9 @@ The following preprocessors/file types are supported by Hologram:
|
|
183
183
|
- Javascript (.js)
|
184
184
|
- Markdown (.md, .markdown)
|
185
185
|
|
186
|
+
## Extensions and Plugins
|
187
|
+
- [Guard Hologram](https://github.com/kmayer/guard-hologram) is a sweet little gem that uses guard to monitor changes to your hologram project and rebuilds your styleguide on the fly as you make changes.
|
188
|
+
|
186
189
|
## Contributing
|
187
190
|
|
188
191
|
1. Fork it
|
data/Rakefile
CHANGED
data/hologram.gemspec
CHANGED
@@ -14,8 +14,8 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.add_dependency "redcarpet", "~> 2.2.2"
|
17
|
-
spec.add_dependency "sass", "~> 3.2.7"
|
18
17
|
spec.add_dependency "pygments.rb", "~> 0.4.2"
|
18
|
+
spec.add_dependency "rspec", "~> 2.14.1"
|
19
19
|
|
20
20
|
spec.files = `git ls-files`.split($/)
|
21
21
|
spec.executables = ['hologram']
|
data/lib/hologram.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require "hologram/version"
|
2
|
-
|
3
1
|
require 'redcarpet'
|
4
2
|
require 'yaml'
|
5
3
|
require 'pygments'
|
@@ -7,450 +5,20 @@ require 'fileutils'
|
|
7
5
|
require 'pathname'
|
8
6
|
require 'erb'
|
9
7
|
|
8
|
+
require 'hologram/version'
|
9
|
+
require 'hologram/document_block'
|
10
|
+
require 'hologram/doc_block_collection'
|
11
|
+
require 'hologram/doc_parser'
|
12
|
+
require 'hologram/doc_builder'
|
13
|
+
require 'hologram/template_variables'
|
14
|
+
require 'hologram/display_message'
|
15
|
+
|
10
16
|
require 'hologram_markdown_renderer'
|
11
17
|
|
12
18
|
module Hologram
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@children = {}
|
19
|
-
set_members(config, markdown) if config and markdown
|
20
|
-
end
|
21
|
-
|
22
|
-
def set_members(config, markdown)
|
23
|
-
@name = config['name']
|
24
|
-
@category = config['category']
|
25
|
-
@title = config['title']
|
26
|
-
@parent = config['parent']
|
27
|
-
@markdown = markdown
|
28
|
-
end
|
29
|
-
|
30
|
-
def get_hash
|
31
|
-
{:name => @name,
|
32
|
-
:parent => @parent,
|
33
|
-
:category => @category,
|
34
|
-
:title => @title
|
35
|
-
}
|
36
|
-
end
|
37
|
-
|
38
|
-
def is_valid?
|
39
|
-
@name && @markdown
|
40
|
-
end
|
41
|
-
|
42
|
-
# sets the header tag based on how deep your nesting is
|
43
|
-
def markdown_with_heading(heading = 1)
|
44
|
-
@markdown = "\n\n<h#{heading.to_s} id=\"#{@name}\">#{@title}</h#{heading.to_s}>" + @markdown
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
class DocBuilder
|
50
|
-
attr_accessor :doc_blocks, :config, :pages
|
51
|
-
|
52
|
-
INIT_TEMPLATE_PATH = File.expand_path('./template/', File.dirname(__FILE__)) + '/'
|
53
|
-
INIT_TEMPLATE_FILES = [
|
54
|
-
INIT_TEMPLATE_PATH + '/hologram_config.yml',
|
55
|
-
INIT_TEMPLATE_PATH + '/doc_assets',
|
56
|
-
]
|
57
|
-
|
58
|
-
def init(args)
|
59
|
-
@pages = {}
|
60
|
-
@supported_extensions = ['.css', '.scss', '.less', '.sass', '.styl', '.js', '.md', '.markdown' ]
|
61
|
-
|
62
|
-
begin
|
63
|
-
if args[0] == 'init' then
|
64
|
-
|
65
|
-
if File.exists?("hologram_config.yml")
|
66
|
-
puts "Cowardly refusing to overwrite existing hologram_config.yml".yellow
|
67
|
-
else
|
68
|
-
FileUtils.cp_r INIT_TEMPLATE_FILES, Dir.pwd
|
69
|
-
puts "Created the following files and directories:"
|
70
|
-
puts " hologram_config.yml"
|
71
|
-
puts " doc_assets/"
|
72
|
-
puts " doc_assets/_header.html"
|
73
|
-
puts " doc_assets/_footer.html"
|
74
|
-
end
|
75
|
-
else
|
76
|
-
begin
|
77
|
-
config_file = args[0] ? args[0] : 'hologram_config.yml'
|
78
|
-
|
79
|
-
begin
|
80
|
-
@config = YAML::load_file(config_file)
|
81
|
-
rescue
|
82
|
-
DisplayMessage.error("Could not load config file, try 'hologram init' to get started")
|
83
|
-
end
|
84
|
-
|
85
|
-
validate_config
|
86
|
-
|
87
|
-
current_path = Dir.pwd
|
88
|
-
base_path = Pathname.new(config_file)
|
89
|
-
Dir.chdir(base_path.dirname)
|
90
|
-
|
91
|
-
# the real work happens here.
|
92
|
-
build_docs
|
93
|
-
|
94
|
-
Dir.chdir(current_path)
|
95
|
-
puts "Build completed. (-: ".green
|
96
|
-
rescue RuntimeError => e
|
97
|
-
DisplayMessage.error("#{e}")
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
|
104
|
-
private
|
105
|
-
def build_docs
|
106
|
-
# Create the output directory if it doesn't exist
|
107
|
-
FileUtils.mkdir_p(config['destination']) unless File.directory?(config['destination'])
|
108
|
-
|
109
|
-
begin
|
110
|
-
input_directory = Pathname.new(config['source']).realpath
|
111
|
-
rescue
|
112
|
-
DisplayMessage.error("Can not read source directory, does it exist?")
|
113
|
-
end
|
114
|
-
|
115
|
-
output_directory = Pathname.new(config['destination']).realpath
|
116
|
-
doc_assets = Pathname.new(config['documentation_assets']).realpath unless !File.directory?(config['documentation_assets'])
|
117
|
-
|
118
|
-
if doc_assets.nil?
|
119
|
-
DisplayMessage.warning("Could not find documentation assets at #{config['documentation_assets']}")
|
120
|
-
end
|
121
|
-
|
122
|
-
# recursively traverse our directory structure looking for files that
|
123
|
-
# match our "parseable" file types. Open those files pulling out any
|
124
|
-
# comments matching the hologram doc style /*doc */ and create DocBlock
|
125
|
-
# objects from those comments, then add those to a collection object which
|
126
|
-
# is then returned.
|
127
|
-
doc_block_collection = process_dir(input_directory)
|
128
|
-
|
129
|
-
# doc blocks can define parent/child relationships that will nest their
|
130
|
-
# documentation appropriately. we can't put everything into that structure
|
131
|
-
# on our first pass through because there is no guarantee we'll parse files
|
132
|
-
# in the correct order. This step takes the full collection and creates the
|
133
|
-
# proper structure.
|
134
|
-
doc_block_collection.create_nested_structure
|
135
|
-
|
136
|
-
# hand off our properly nested collection to the output generator
|
137
|
-
build_pages_from_doc_blocks(doc_block_collection.doc_blocks)
|
138
|
-
|
139
|
-
# if we have an index category defined in our config copy that
|
140
|
-
# page to index.html
|
141
|
-
if config['index']
|
142
|
-
if @pages.has_key?(config['index'] + '.html')
|
143
|
-
@pages['index.html'] = @pages[config['index'] + '.html']
|
144
|
-
else
|
145
|
-
DisplayMessage.warning("Could not generate index.html, there was no content generated for the category #{config['index']}.")
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
write_docs(output_directory, doc_assets)
|
150
|
-
|
151
|
-
# Copy over dependencies
|
152
|
-
if config['dependencies']
|
153
|
-
config['dependencies'].each do |dir|
|
154
|
-
begin
|
155
|
-
dirpath = Pathname.new(dir).realpath
|
156
|
-
if File.directory?("#{dir}")
|
157
|
-
`rm -rf #{output_directory}/#{dirpath.basename}`
|
158
|
-
`cp -R #{dirpath} #{output_directory}/#{dirpath.basename}`
|
159
|
-
end
|
160
|
-
rescue
|
161
|
-
DisplayMessage.warning("Could not copy dependency: #{dir}")
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
if !doc_assets.nil?
|
167
|
-
Dir.foreach(doc_assets) do |item|
|
168
|
-
# ignore . and .. directories and files that start with
|
169
|
-
# underscore
|
170
|
-
next if item == '.' or item == '..' or item.start_with?('_')
|
171
|
-
`rm -rf #{output_directory}/#{item}`
|
172
|
-
`cp -R #{doc_assets}/#{item} #{output_directory}/#{item}`
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
|
178
|
-
def process_dir(base_directory)
|
179
|
-
#get all directories in our library folder
|
180
|
-
doc_block_collection = DocBlockCollection.new
|
181
|
-
directories = Dir.glob("#{base_directory}/**/*/")
|
182
|
-
directories.unshift(base_directory)
|
183
|
-
|
184
|
-
directories.each do |directory|
|
185
|
-
# filter and sort the files in our directory
|
186
|
-
files = []
|
187
|
-
Dir.foreach(directory).select{ |file| is_supported_file_type?(file) }.each do |file|
|
188
|
-
files << file
|
189
|
-
end
|
190
|
-
files.sort!
|
191
|
-
process_files(files, directory, doc_block_collection)
|
192
|
-
end
|
193
|
-
doc_block_collection
|
194
|
-
end
|
195
|
-
|
196
|
-
|
197
|
-
def process_files(files, directory, doc_block_collection)
|
198
|
-
files.each do |input_file|
|
199
|
-
if input_file.end_with?('md')
|
200
|
-
@pages[File.basename(input_file, '.md') + '.html'] = {:md => File.read("#{directory}/#{input_file}"), :blocks => []}
|
201
|
-
else
|
202
|
-
process_file("#{directory}/#{input_file}", doc_block_collection)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
|
208
|
-
def process_file(file, doc_block_collection)
|
209
|
-
file_str = File.read(file)
|
210
|
-
# get any comment blocks that match the patterns:
|
211
|
-
# .sass: //doc (follow by other lines proceeded by a space)
|
212
|
-
# other types: /*doc ... */
|
213
|
-
if file.end_with?('.sass')
|
214
|
-
hologram_comments = file_str.scan(/\s*\/\/doc\s*((( [^\n]*\n)|\n)+)/)
|
215
|
-
else
|
216
|
-
hologram_comments = file_str.scan(/^\s*\/\*doc(.*?)\*\//m)
|
217
|
-
end
|
218
|
-
return unless hologram_comments
|
219
|
-
|
220
|
-
hologram_comments.each do |comment_block|
|
221
|
-
doc_block_collection.add_doc_block(comment_block[0])
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
|
226
|
-
def build_pages_from_doc_blocks(doc_blocks, output_file = nil, depth = 1)
|
227
|
-
doc_blocks.sort.map do |key, doc_block|
|
228
|
-
|
229
|
-
# if the doc_block has a category set then use that, this will be
|
230
|
-
# true of all top level doc_blocks. The output file they set will then
|
231
|
-
# be passed into the recursive call for adding children to the output
|
232
|
-
output_file = get_file_name(doc_block.category) if doc_block.category
|
233
|
-
|
234
|
-
if !@pages.has_key?(output_file)
|
235
|
-
@pages[output_file] = {:md => "", :blocks => []}
|
236
|
-
end
|
237
|
-
|
238
|
-
@pages[output_file][:blocks].push(doc_block.get_hash)
|
239
|
-
@pages[output_file][:md] << doc_block.markdown_with_heading(depth)
|
240
|
-
|
241
|
-
if doc_block.children
|
242
|
-
depth += 1
|
243
|
-
build_pages_from_doc_blocks(doc_block.children, output_file, depth)
|
244
|
-
depth -= 1
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
|
250
|
-
def write_docs(output_directory, doc_assets)
|
251
|
-
# load the markdown renderer we are going to use
|
252
|
-
renderer = get_markdown_renderer
|
253
|
-
|
254
|
-
if File.exists?("#{doc_assets}/_header.html")
|
255
|
-
header_erb = ERB.new(File.read("#{doc_assets}/_header.html"))
|
256
|
-
elsif File.exists?("#{doc_assets}/header.html")
|
257
|
-
header_erb = ERB.new(File.read("#{doc_assets}/header.html"))
|
258
|
-
else
|
259
|
-
header_erb = nil
|
260
|
-
DisplayMessage.warning("No _header.html found in documentation assets. Without this your css/header will not be included on the generated pages.")
|
261
|
-
end
|
262
|
-
|
263
|
-
if File.exists?("#{doc_assets}/_footer.html")
|
264
|
-
footer_erb = ERB.new(File.read("#{doc_assets}/_footer.html"))
|
265
|
-
elsif File.exists?("#{doc_assets}/footer.html")
|
266
|
-
footer_erb = ERB.new(File.read("#{doc_assets}/footer.html"))
|
267
|
-
else
|
268
|
-
footer_erb = nil
|
269
|
-
DisplayMessage.warning("No _footer.html found in documentation assets. This might be okay to ignore...")
|
270
|
-
end
|
271
|
-
|
272
|
-
#generate html from markdown
|
273
|
-
@pages.each do |file_name, page|
|
274
|
-
fh = get_fh(output_directory, file_name)
|
275
|
-
|
276
|
-
title = page[:blocks].empty? ? "" : page[:blocks][0][:category]
|
277
|
-
|
278
|
-
tpl_vars = TemplateVariables.new(title, file_name, page[:blocks])
|
279
|
-
|
280
|
-
# generate doc nav html
|
281
|
-
unless header_erb.nil?
|
282
|
-
fh.write(header_erb.result(tpl_vars.get_binding))
|
283
|
-
end
|
284
|
-
|
285
|
-
# write the docs
|
286
|
-
begin
|
287
|
-
fh.write(renderer.render(page[:md]))
|
288
|
-
rescue Exception => e
|
289
|
-
DisplayMessage.error(e.message)
|
290
|
-
end
|
291
|
-
|
292
|
-
# write the footer
|
293
|
-
unless footer_erb.nil?
|
294
|
-
fh.write(footer_erb.result(tpl_vars.get_binding))
|
295
|
-
end
|
296
|
-
|
297
|
-
fh.close()
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
|
302
|
-
def get_markdown_renderer
|
303
|
-
if config['custom_markdown'].nil?
|
304
|
-
renderer = Redcarpet::Markdown.new(HologramMarkdownRenderer, { :fenced_code_blocks => true, :tables => true })
|
305
|
-
else
|
306
|
-
begin
|
307
|
-
load config['custom_markdown']
|
308
|
-
renderer_class = File.basename(config['custom_markdown'], '.rb').split(/_/).map(&:capitalize).join
|
309
|
-
puts "Custom markdown renderer #{renderer_class} loaded."
|
310
|
-
renderer = Redcarpet::Markdown.new(Module.const_get(renderer_class), { :fenced_code_blocks => true, :tables => true })
|
311
|
-
rescue LoadError => e
|
312
|
-
DisplayMessage.error("Could not load #{config['custom_markdown']}.")
|
313
|
-
rescue NameError => e
|
314
|
-
DisplayMessage.error("Class #{renderer_class} not found in #{config['custom_markdown']}.")
|
315
|
-
end
|
316
|
-
end
|
317
|
-
renderer
|
318
|
-
end
|
319
|
-
|
320
|
-
|
321
|
-
def validate_config
|
322
|
-
unless @config.key?('source')
|
323
|
-
DisplayMessage.error("No source directory specified in the config file")
|
324
|
-
end
|
325
|
-
|
326
|
-
unless @config.key?('destination')
|
327
|
-
DisplayMessage.error("No destination directory specified in the config")
|
328
|
-
end
|
329
|
-
|
330
|
-
unless @config.key?('documentation_assets')
|
331
|
-
DisplayMessage.error("No documentation assets directory specified")
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
|
336
|
-
def is_supported_file_type?(file)
|
337
|
-
@supported_extensions.include?(File.extname(file))
|
338
|
-
end
|
339
|
-
|
340
|
-
|
341
|
-
def get_file_name(str)
|
342
|
-
str = str.gsub(' ', '_').downcase + '.html'
|
343
|
-
end
|
344
|
-
|
345
|
-
|
346
|
-
def get_fh(output_directory, output_file)
|
347
|
-
File.open("#{output_directory}/#{output_file}", 'w')
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
|
352
|
-
#Helper class for binding things for ERB
|
353
|
-
class TemplateVariables
|
354
|
-
attr_accessor :title, :file_name, :blocks
|
355
|
-
|
356
|
-
def initialize(title, file_name, blocks)
|
357
|
-
@title = title
|
358
|
-
@file_name = file_name
|
359
|
-
@blocks = blocks
|
360
|
-
end
|
361
|
-
|
362
|
-
def get_binding
|
363
|
-
binding()
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
class DocBlockCollection
|
368
|
-
attr_accessor :doc_blocks
|
369
|
-
|
370
|
-
def initialize
|
371
|
-
@doc_blocks = {}
|
372
|
-
end
|
373
|
-
|
374
|
-
# this should throw an error if we have a match, but no yaml_match
|
375
|
-
def add_doc_block(comment_block)
|
376
|
-
yaml_match = /^\s*---\s(.*?)\s---$/m.match(comment_block)
|
377
|
-
return unless yaml_match
|
378
|
-
|
379
|
-
markdown = comment_block.sub(yaml_match[0], '')
|
380
|
-
|
381
|
-
begin
|
382
|
-
config = YAML::load(yaml_match[1])
|
383
|
-
rescue
|
384
|
-
DisplayMessage.error("Could not parse YAML:\n#{yaml_match[1]}")
|
385
|
-
end
|
386
|
-
|
387
|
-
if config['name'].nil?
|
388
|
-
DisplayMessage.warning("Missing required name config value. This hologram comment will be skipped. \n #{config.inspect}")
|
389
|
-
else
|
390
|
-
doc_block = DocumentBlock.new(config, markdown)
|
391
|
-
end
|
392
|
-
|
393
|
-
@doc_blocks[doc_block.name] = doc_block if doc_block.is_valid?
|
394
|
-
end
|
395
|
-
|
396
|
-
def create_nested_structure
|
397
|
-
blocks_to_remove_from_top_level = []
|
398
|
-
@doc_blocks.each do |key, doc_block|
|
399
|
-
# don't do anything to top level doc_blocks
|
400
|
-
next if !doc_block.parent
|
401
|
-
|
402
|
-
parent = @doc_blocks[doc_block.parent]
|
403
|
-
parent.children[doc_block.name] = doc_block
|
404
|
-
doc_block.parent = parent
|
405
|
-
blocks_to_remove_from_top_level << doc_block.name
|
406
|
-
end
|
407
|
-
|
408
|
-
blocks_to_remove_from_top_level.each do |key|
|
409
|
-
@doc_blocks.delete(key)
|
410
|
-
end
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
|
-
end
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
class DisplayMessage
|
419
|
-
def self.error(message)
|
420
|
-
if RUBY_VERSION.to_f > 1.8 then
|
421
|
-
puts "(\u{256F}\u{00B0}\u{25A1}\u{00B0}\u{FF09}\u{256F}".green + "\u{FE35} \u{253B}\u{2501}\u{253B} ".yellow + " Build not complete.".red
|
422
|
-
else
|
423
|
-
puts "Build not complete.".red
|
424
|
-
end
|
425
|
-
puts " #{message}"
|
426
|
-
exit 1
|
427
|
-
end
|
428
|
-
|
429
|
-
def self.warning(message)
|
430
|
-
puts "Warning: ".yellow + message
|
431
|
-
end
|
432
|
-
end
|
433
|
-
|
434
|
-
|
435
|
-
class String
|
436
|
-
# colorization
|
437
|
-
def colorize(color_code)
|
438
|
-
"\e[#{color_code}m#{self}\e[0m"
|
439
|
-
end
|
440
|
-
|
441
|
-
def red
|
442
|
-
colorize(31)
|
443
|
-
end
|
444
|
-
|
445
|
-
def green
|
446
|
-
colorize(32)
|
447
|
-
end
|
448
|
-
|
449
|
-
def yellow
|
450
|
-
colorize(33)
|
451
|
-
end
|
452
|
-
|
453
|
-
def pink
|
454
|
-
colorize(35)
|
455
|
-
end
|
19
|
+
INIT_TEMPLATE_PATH = File.expand_path('./template/', File.dirname(__FILE__)) + '/'
|
20
|
+
INIT_TEMPLATE_FILES = [
|
21
|
+
INIT_TEMPLATE_PATH + '/hologram_config.yml',
|
22
|
+
INIT_TEMPLATE_PATH + '/doc_assets',
|
23
|
+
]
|
456
24
|
end
|