hologram 0.5.9 → 0.6.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0e48a782a8a76b16ebd3ae5127bf1b331ae6d435
4
- data.tar.gz: 01448485dc3f2ed3a396ab0fd2bc699dd7d9438e
3
+ metadata.gz: 24abd28899897760d163bbf8dd975e4589436af0
4
+ data.tar.gz: ac2d7bf8b43b646802107f20284378c77bfa26f3
5
5
  SHA512:
6
- metadata.gz: 380bd924c01c63dd9b9dfba8fffee5acc19e48806da2157901fcda52ded6e30f5ee5b5d367111449188904fc17b0120c313171cd5db2f82dc26bd224f501a185
7
- data.tar.gz: 9837b618d0854234b1e85cc32ffb53bcaa41dfc09c0f3b029bb1b7ce74f83b405ffadb5ce93ac775bd32fc4b1ba28e3165fb3361d4e688f2a2fbd69457a353f7
6
+ metadata.gz: 9793211c0cf19e31fd8c5384ec17f149ebfec48ff596477a94b48507b6f467519d146962f32f8e2aa7196773e4c0d272bbc1555f0bf2be9cf3062d2be9915fdb
7
+ data.tar.gz: f9308f6c7136fcefd2bd7188c583d699355071ca6ffb24e2586a9d57156db8e56c4f2b9b42d62c64b632aa516c2b910bd26117a71ca0bbc6f3f982d9234ddce7
@@ -1,23 +1,25 @@
1
- Copyright (c) 2013, Trulia, Inc.
2
- All rights reserved.
1
+ Copyright (c) 2013, Trulia, Inc. All rights reserved.
3
2
 
4
3
  MIT License
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of the Trulia, Inc. nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
5
14
 
6
- Permission is hereby granted, free of charge, to any person obtaining
7
- a copy of this software and associated documentation files (the
8
- "Software"), to deal in the Software without restriction, including
9
- without limitation the rights to use, copy, modify, merge, publish,
10
- distribute, sublicense, and/or sell copies of the Software, and to
11
- permit persons to whom the Software is furnished to do so, subject to
12
- the following conditions:
13
-
14
- The above copyright notice and this permission notice shall be
15
- included in all copies or substantial portions of the Software.
16
-
17
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TRULIA, INC. BE
19
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md CHANGED
@@ -27,8 +27,8 @@ If you don't use bundler you can run `gem install hologram`.
27
27
  hologram init
28
28
  ```
29
29
 
30
- This will create a config yml file, and also create a starter
31
- `_header.tpl` and `_footer.tpl` file for you. You can then tweak the
30
+ This will create a `hologram_config.yml` file (more on this below), and also create a starter
31
+ `_header.html` and `_footer.html` file for you. You can then tweak the
32
32
  config values and start documenting your css.
33
33
 
34
34
  Building the documentation is simply:
@@ -66,13 +66,14 @@ 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
- holgoram generates. Hologram treats `_header.html` and `_footer.html`
69
+ hologram generates.
70
+
71
+ Hologram treats `_header.html` and `_footer.html`
70
72
  as ERB files for each page that is generated you can access the
71
- `title`, `file_name`, and `blocks`. `blocks` is a list of each
73
+ `title`, `file_name`, and `blocks`. `blocks` is a list of each
72
74
  documenation block on the page. Each item in the list has a `title`,
73
- `name`, `category`, and optionally a `parent`. Additionaly, filenames
74
- that begin with underscores will not be copied into the destination
75
- folder.
75
+ `name`, `category`, and optionally a `parent`. This is useful for, say, building a menu that lists each component.
76
+ **Nota Bene:** Filenames that begin with underscores will not be copied into the destination folder.
76
77
 
77
78
 
78
79
  * **custom_markdown**: (optional) this is the filename of a class that
@@ -135,9 +136,11 @@ It will look for comments that match the following:
135
136
  */
136
137
 
137
138
  The first section of the comment is a yaml block that defines certain
138
- aspects of the this documentation block. The second part is simply
139
+ aspects of the this documentation block (more on that in the next section). The second part is simply
139
140
  markdown as defined by Redcarpet.
140
141
 
142
+ Notice the use of `html_example`. This tells the markdown renderer that it should treat the example as...well...html. If your project uses [haml](http://haml.info/) you can also use `haml_example`. In that case the output will be html for the example and the code block will show the haml used to generate the html. For components that require [javascript](https://www.destroyallsoftware.com/talks/wat) you can use `js_example` for your js. In addtion to outputing the js in a `<code>` block it will also wrap it in a `<script>` tag for execution.
143
+
141
144
  ####Document YAML section
142
145
  The yaml in the doc block can have any key value pair you deem important
143
146
  but it specifically looks for the following keys:
@@ -147,8 +150,11 @@ but it specifically looks for the following keys:
147
150
  components in the same category will be written to the same page.
148
151
  * **name**: This is used for grouping components, by assigning
149
152
  a name a component can be referenced in another component as a parent.
150
- * **parent**: Optional. If this is set the current component will be
151
- 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
+
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
+
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).
152
158
 
153
159
 
154
160
  ###Documentation Assets
@@ -1,29 +1,3 @@
1
- # Copyright (c) 2013, Trulia, Inc.
2
- # All rights reserved.
3
- #
4
- # Redistribution and use in source and binary forms, with or without
5
- # modification, are permitted provided that the following conditions are met:
6
- # * Redistributions of source code must retain the above copyright
7
- # notice, this list of conditions and the following disclaimer.
8
- # * Redistributions in binary form must reproduce the above copyright
9
- # notice, this list of conditions and the following disclaimer in the
10
- # documentation and/or other materials provided with the distribution.
11
- # * Neither the name of the Trulia, Inc. nor the
12
- # names of its contributors may be used to endorse or promote products
13
- # derived from this software without specific prior written permission.
14
- #
15
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16
- # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17
- # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18
- # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TRULIA, INC. BE
19
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22
- # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
- # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
- # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
- # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
-
27
1
  require "hologram/version"
28
2
 
29
3
  require 'redcarpet'
@@ -37,23 +11,8 @@ require 'hologram_markdown_renderer'
37
11
 
38
12
  module Hologram
39
13
 
40
- #Helper class for binding things for ERB
41
- class TemplateVariables
42
- attr_accessor :title, :file_name, :blocks
43
-
44
- def initialize(title, file_name, blocks)
45
- @title = title
46
- @file_name = file_name
47
- @blocks = blocks
48
- end
49
-
50
- def get_binding
51
- binding
52
- end
53
- end
54
-
55
14
  class DocumentBlock
56
- attr_accessor :name, :parent, :children, :title, :category, :markdown, :output_file, :config
15
+ attr_accessor :name, :parent, :children, :title, :category, :markdown, :config, :heading
57
16
 
58
17
  def initialize(config = nil, markdown = nil)
59
18
  @children = {}
@@ -62,9 +21,9 @@ module Hologram
62
21
 
63
22
  def set_members(config, markdown)
64
23
  @name = config['name']
65
- @parent = config['parent']
66
24
  @category = config['category']
67
25
  @title = config['title']
26
+ @parent = config['parent']
68
27
  @markdown = markdown
69
28
  end
70
29
 
@@ -79,10 +38,15 @@ module Hologram
79
38
  def is_valid?
80
39
  @name && @markdown
81
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
82
46
  end
83
47
 
84
48
 
85
- class Builder
49
+ class DocBuilder
86
50
  attr_accessor :doc_blocks, :config, :pages
87
51
 
88
52
  INIT_TEMPLATE_PATH = File.expand_path('./template/', File.dirname(__FILE__)) + '/'
@@ -92,14 +56,14 @@ module Hologram
92
56
  ]
93
57
 
94
58
  def init(args)
95
- @doc_blocks, @pages = {}, {}
59
+ @pages = {}
96
60
  @supported_extensions = ['.css', '.scss', '.less', '.sass', '.styl', '.js', '.md', '.markdown' ]
97
61
 
98
62
  begin
99
63
  if args[0] == 'init' then
100
64
 
101
65
  if File.exists?("hologram_config.yml")
102
- puts "Cowardly refusing to overwrite existing hologram_config.yml"
66
+ puts "Cowardly refusing to overwrite existing hologram_config.yml".yellow
103
67
  else
104
68
  FileUtils.cp_r INIT_TEMPLATE_FILES, Dir.pwd
105
69
  puts "Created the following files and directories:"
@@ -115,22 +79,22 @@ module Hologram
115
79
  begin
116
80
  @config = YAML::load_file(config_file)
117
81
  rescue
118
- display_error "Could not load config file, try hologram init to get started"
82
+ DisplayMessage.error("Could not load config file, try 'hologram init' to get started")
119
83
  end
120
84
 
121
85
  validate_config
122
86
 
123
- #TODO: maybe this should move into build_docs
124
87
  current_path = Dir.pwd
125
88
  base_path = Pathname.new(config_file)
126
89
  Dir.chdir(base_path.dirname)
127
90
 
91
+ # the real work happens here.
128
92
  build_docs
129
93
 
130
94
  Dir.chdir(current_path)
131
95
  puts "Build completed. (-: ".green
132
96
  rescue RuntimeError => e
133
- display_error("#{e}")
97
+ DisplayMessage.error("#{e}")
134
98
  end
135
99
  end
136
100
  end
@@ -145,19 +109,32 @@ module Hologram
145
109
  begin
146
110
  input_directory = Pathname.new(config['source']).realpath
147
111
  rescue
148
- display_error "Can not read source directory, does it exist?"
112
+ DisplayMessage.error("Can not read source directory, does it exist?")
149
113
  end
150
114
 
151
115
  output_directory = Pathname.new(config['destination']).realpath
152
116
  doc_assets = Pathname.new(config['documentation_assets']).realpath unless !File.directory?(config['documentation_assets'])
153
117
 
154
118
  if doc_assets.nil?
155
- display_warning "Could not find documentation assets at #{config['documentation_assets']}"
119
+ DisplayMessage.warning("Could not find documentation assets at #{config['documentation_assets']}")
156
120
  end
157
121
 
158
- process_dir(input_directory)
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
159
135
 
160
- build_pages_from_doc_blocks(@doc_blocks)
136
+ # hand off our properly nested collection to the output generator
137
+ build_pages_from_doc_blocks(doc_block_collection.doc_blocks)
161
138
 
162
139
  # if we have an index category defined in our config copy that
163
140
  # page to index.html
@@ -165,7 +142,7 @@ module Hologram
165
142
  if @pages.has_key?(config['index'] + '.html')
166
143
  @pages['index.html'] = @pages[config['index'] + '.html']
167
144
  else
168
- display_warning "Could not generate index.html, there was no content generated for the category #{config['index']}."
145
+ DisplayMessage.warning("Could not generate index.html, there was no content generated for the category #{config['index']}.")
169
146
  end
170
147
  end
171
148
 
@@ -181,7 +158,7 @@ module Hologram
181
158
  `cp -R #{dirpath} #{output_directory}/#{dirpath.basename}`
182
159
  end
183
160
  rescue
184
- display_warning "Could not copy dependency: #{dir}"
161
+ DisplayMessage.warning("Could not copy dependency: #{dir}")
185
162
  end
186
163
  end
187
164
  end
@@ -200,6 +177,7 @@ module Hologram
200
177
 
201
178
  def process_dir(base_directory)
202
179
  #get all directories in our library folder
180
+ doc_block_collection = DocBlockCollection.new
203
181
  directories = Dir.glob("#{base_directory}/**/*/")
204
182
  directories.unshift(base_directory)
205
183
 
@@ -210,23 +188,24 @@ module Hologram
210
188
  files << file
211
189
  end
212
190
  files.sort!
213
- process_files(files, directory)
191
+ process_files(files, directory, doc_block_collection)
214
192
  end
193
+ doc_block_collection
215
194
  end
216
195
 
217
196
 
218
- def process_files(files, directory)
197
+ def process_files(files, directory, doc_block_collection)
219
198
  files.each do |input_file|
220
199
  if input_file.end_with?('md')
221
200
  @pages[File.basename(input_file, '.md') + '.html'] = {:md => File.read("#{directory}/#{input_file}"), :blocks => []}
222
201
  else
223
- process_file("#{directory}/#{input_file}")
202
+ process_file("#{directory}/#{input_file}", doc_block_collection)
224
203
  end
225
204
  end
226
205
  end
227
206
 
228
207
 
229
- def process_file(file)
208
+ def process_file(file, doc_block_collection)
230
209
  file_str = File.read(file)
231
210
  # get any comment blocks that match the patterns:
232
211
  # .sass: //doc (follow by other lines proceeded by a space)
@@ -239,73 +218,30 @@ module Hologram
239
218
  return unless hologram_comments
240
219
 
241
220
  hologram_comments.each do |comment_block|
242
- doc_block = build_doc_block(comment_block[0])
243
- add_doc_block_to_collection(doc_block) if doc_block
221
+ doc_block_collection.add_doc_block(comment_block[0])
244
222
  end
245
223
  end
246
224
 
247
225
 
248
- # this should throw an error if we have a match, but now yaml_match
249
- def build_doc_block(comment_block)
250
- yaml_match = /^\s*---\s(.*?)\s---$/m.match(comment_block)
251
- return unless yaml_match
252
- markdown = comment_block.sub(yaml_match[0], '')
253
-
254
- begin
255
- config = YAML::load(yaml_match[1])
256
- rescue
257
- display_error("Could not parse YAML:\n#{yaml_match[1]}")
258
- end
259
-
260
- if config['name'].nil?
261
- puts "Missing required name config value. This hologram comment will be skipped. \n #{config.inspect}"
262
- else
263
- doc_block = DocumentBlock.new(config, markdown)
264
- end
265
- end
266
-
267
-
268
- def add_doc_block_to_collection(doc_block)
269
- return unless doc_block.is_valid?
270
- if doc_block.parent.nil?
271
- #parent file
272
- begin
273
- doc_block.output_file = get_file_name(doc_block.category)
274
- rescue NoMethodError => e
275
- display_error("No output file specified. Missing category? \n #{doc_block.inspect}")
276
- end
277
-
278
- @doc_blocks[doc_block.name] = doc_block;
279
- doc_block.markdown = "\n\n<#{@config['parent_heading_tag']} id=\"#{doc_block.name}\">#{doc_block.title}</#{@config['parent_heading_tag']}>" + doc_block.markdown
280
- else
281
- # child file
282
- parent_doc_block = @doc_blocks[doc_block.parent]
283
- if parent_doc_block
284
- if doc_block.title.nil?
285
- doc_block.markdown = doc_block.markdown
286
- else
287
- doc_block.markdown = "\n\n<#{@config['child_heading_tag']} id=\"#{doc_block.name}\">#{doc_block.title}</#{@config['child_heading_tag']}>" + doc_block.markdown
288
- end
289
- parent_doc_block.children[doc_block.name] = doc_block
290
- else
291
- @doc_blocks[doc_block.parent] = DocumentBlock.new()
292
- end
293
- end
294
- end
295
-
296
-
297
- def build_pages_from_doc_blocks(doc_blocks, output_file = nil)
226
+ def build_pages_from_doc_blocks(doc_blocks, output_file = nil, depth = 1)
298
227
  doc_blocks.sort.map do |key, doc_block|
299
- output_file = doc_block.output_file || output_file
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
300
233
 
301
234
  if !@pages.has_key?(output_file)
302
235
  @pages[output_file] = {:md => "", :blocks => []}
303
236
  end
304
237
 
305
238
  @pages[output_file][:blocks].push(doc_block.get_hash)
306
- @pages[output_file][:md] << doc_block.markdown
239
+ @pages[output_file][:md] << doc_block.markdown_with_heading(depth)
240
+
307
241
  if doc_block.children
308
- build_pages_from_doc_blocks(doc_block.children, output_file)
242
+ depth += 1
243
+ build_pages_from_doc_blocks(doc_block.children, output_file, depth)
244
+ depth -= 1
309
245
  end
310
246
  end
311
247
  end
@@ -321,7 +257,7 @@ module Hologram
321
257
  header_erb = ERB.new(File.read("#{doc_assets}/header.html"))
322
258
  else
323
259
  header_erb = nil
324
- display_warning "No _header.html found in documentation assets. Without this your css/header will not be included on the generated pages."
260
+ DisplayMessage.warning("No _header.html found in documentation assets. Without this your css/header will not be included on the generated pages.")
325
261
  end
326
262
 
327
263
  if File.exists?("#{doc_assets}/_footer.html")
@@ -330,7 +266,7 @@ module Hologram
330
266
  footer_erb = ERB.new(File.read("#{doc_assets}/footer.html"))
331
267
  else
332
268
  footer_erb = nil
333
- display_warning "No _footer.html found in documentation assets. This might be okay to ignore..."
269
+ DisplayMessage.warning("No _footer.html found in documentation assets. This might be okay to ignore...")
334
270
  end
335
271
 
336
272
  #generate html from markdown
@@ -339,7 +275,7 @@ module Hologram
339
275
 
340
276
  title = page[:blocks].empty? ? "" : page[:blocks][0][:category]
341
277
 
342
- tpl_vars = TemplateVariables.new title, file_name, page[:blocks]
278
+ tpl_vars = TemplateVariables.new(title, file_name, page[:blocks])
343
279
 
344
280
  # generate doc nav html
345
281
  unless header_erb.nil?
@@ -347,7 +283,11 @@ module Hologram
347
283
  end
348
284
 
349
285
  # write the docs
350
- fh.write(renderer.render(page[:md]))
286
+ begin
287
+ fh.write(renderer.render(page[:md]))
288
+ rescue Exception => e
289
+ DisplayMessage.error(e.message)
290
+ end
351
291
 
352
292
  # write the footer
353
293
  unless footer_erb.nil?
@@ -369,9 +309,9 @@ module Hologram
369
309
  puts "Custom markdown renderer #{renderer_class} loaded."
370
310
  renderer = Redcarpet::Markdown.new(Module.const_get(renderer_class), { :fenced_code_blocks => true, :tables => true })
371
311
  rescue LoadError => e
372
- display_error("Could not load #{config['custom_markdown']}.")
312
+ DisplayMessage.error("Could not load #{config['custom_markdown']}.")
373
313
  rescue NameError => e
374
- display_error("Class #{renderer_class} not found in #{config['custom_markdown']}.")
314
+ DisplayMessage.error("Class #{renderer_class} not found in #{config['custom_markdown']}.")
375
315
  end
376
316
  end
377
317
  renderer
@@ -380,24 +320,15 @@ module Hologram
380
320
 
381
321
  def validate_config
382
322
  unless @config.key?('source')
383
- display_error "No source directory specified in the config file"
323
+ DisplayMessage.error("No source directory specified in the config file")
384
324
  end
385
325
 
386
326
  unless @config.key?('destination')
387
- display_error "No destination directory specified in the config"
327
+ DisplayMessage.error("No destination directory specified in the config")
388
328
  end
389
329
 
390
330
  unless @config.key?('documentation_assets')
391
- display_error "No documentation assets directory specified"
392
- end
393
-
394
- #Setup some defaults for these guys
395
- unless @config.key?('parent_heading_tag')
396
- @config['parent_heading_tag'] = 'h1'
397
- end
398
-
399
- unless @config.key?('child_heading_tag')
400
- @config['child_heading_tag'] = 'h2'
331
+ DisplayMessage.error("No documentation assets directory specified")
401
332
  end
402
333
  end
403
334
 
@@ -406,31 +337,98 @@ module Hologram
406
337
  @supported_extensions.include?(File.extname(file))
407
338
  end
408
339
 
409
- def display_error(message)
410
- if RUBY_VERSION.to_f > 1.8 then
411
- 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
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}")
412
389
  else
413
- puts "Build not complete.".red
390
+ doc_block = DocumentBlock.new(config, markdown)
414
391
  end
415
- puts " #{message}"
416
- exit 1
417
- end
418
392
 
419
- def display_warning(message)
420
- puts "Warning: ".yellow + message
393
+ @doc_blocks[doc_block.name] = doc_block if doc_block.is_valid?
421
394
  end
422
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
423
401
 
424
- def get_file_name(str)
425
- str = str.gsub(' ', '_').downcase + '.html'
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
426
411
  end
412
+ end
427
413
 
414
+ end
428
415
 
429
- def get_fh(output_directory, output_file)
430
- File.open("#{output_directory}/#{output_file}", 'w')
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
431
424
  end
425
+ puts " #{message}"
426
+ exit 1
432
427
  end
433
428
 
429
+ def self.warning(message)
430
+ puts "Warning: ".yellow + message
431
+ end
434
432
  end
435
433
 
436
434
 
@@ -25,5 +25,5 @@
25
25
  # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
26
 
27
27
  module Hologram
28
- VERSION = "0.5.9"
28
+ VERSION = "0.6.0"
29
29
  end
@@ -1,29 +1,3 @@
1
- # Copyright (c) 2013, Trulia, Inc.
2
- # All rights reserved.
3
- #
4
- # Redistribution and use in source and binary forms, with or without
5
- # modification, are permitted provided that the following conditions are met:
6
- # * Redistributions of source code must retain the above copyright
7
- # notice, this list of conditions and the following disclaimer.
8
- # * Redistributions in binary form must reproduce the above copyright
9
- # notice, this list of conditions and the following disclaimer in the
10
- # documentation and/or other materials provided with the distribution.
11
- # * Neither the name of the Trulia, Inc. nor the
12
- # names of its contributors may be used to endorse or promote products
13
- # derived from this software without specific prior written permission.
14
- #
15
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16
- # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17
- # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18
- # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TRULIA, INC. BE
19
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22
- # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
- # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
- # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
- # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
-
27
1
  class HologramMarkdownRenderer < Redcarpet::Render::HTML
28
2
  def block_code(code, language)
29
3
  if language and language.include?('example')
@@ -32,10 +6,38 @@ class HologramMarkdownRenderer < Redcarpet::Render::HTML
32
6
  '<script>' + code + '</script>
33
7
  <div class="codeBlock jsExample">' + Pygments.highlight(code) + '</div>'
34
8
  else
35
- '<div class="codeExample">' + '<div class="exampleOutput">' + code + '</div>' + '<div class="codeBlock">' + Pygments.highlight(code) + '</div>' + '</div>'
9
+ '<div class="codeExample">' + '<div class="exampleOutput">' + render_html(code, language) + '</div>' + '<div class="codeBlock">' + Pygments.highlight(code, :lexer => get_lexer(language)) + '</div>' + '</div>'
36
10
  end
37
11
  else
38
12
  '<div class="codeBlock">' + Pygments.highlight(code) + '</div>'
39
- end
13
+ end
14
+ end
15
+
16
+ private
17
+ def render_html(code, language)
18
+ case language
19
+ when 'haml_example'
20
+ safe_require('haml', language)
21
+ return Haml::Engine.new(code.strip).render(Object.new, {})
22
+ else
23
+ code
24
+ end
25
+ end
26
+
27
+ def get_lexer(language)
28
+ case language
29
+ when 'haml_example'
30
+ 'haml'
31
+ else
32
+ 'html'
33
+ end
34
+ end
35
+
36
+ def safe_require(templating_library, language)
37
+ begin
38
+ require templating_library
39
+ rescue LoadError
40
+ raise "#{templating_library} must be present for you to use #{language}"
41
+ end
40
42
  end
41
43
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hologram
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.9
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - JD Cantrell
@@ -9,76 +9,76 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-05 00:00:00.000000000 Z
12
+ date: 2013-12-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redcarpet
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ~>
18
+ - - "~>"
19
19
  - !ruby/object:Gem::Version
20
20
  version: 2.2.2
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ~>
25
+ - - "~>"
26
26
  - !ruby/object:Gem::Version
27
27
  version: 2.2.2
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: sass
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ~>
32
+ - - "~>"
33
33
  - !ruby/object:Gem::Version
34
34
  version: 3.2.7
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ~>
39
+ - - "~>"
40
40
  - !ruby/object:Gem::Version
41
41
  version: 3.2.7
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: pygments.rb
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ~>
46
+ - - "~>"
47
47
  - !ruby/object:Gem::Version
48
48
  version: 0.4.2
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ~>
53
+ - - "~>"
54
54
  - !ruby/object:Gem::Version
55
55
  version: 0.4.2
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: bundler
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - ~>
60
+ - - "~>"
61
61
  - !ruby/object:Gem::Version
62
62
  version: '1.3'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ~>
67
+ - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '1.3'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rake
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - '>='
74
+ - - ">="
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - '>='
81
+ - - ">="
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
84
  description: Build doc type things
@@ -89,7 +89,7 @@ executables:
89
89
  extensions: []
90
90
  extra_rdoc_files: []
91
91
  files:
92
- - .gitignore
92
+ - ".gitignore"
93
93
  - Gemfile
94
94
  - LICENSE.txt
95
95
  - README.md
@@ -112,17 +112,17 @@ require_paths:
112
112
  - lib
113
113
  required_ruby_version: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '>='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  required_rubygems_version: !ruby/object:Gem::Requirement
119
119
  requirements:
120
- - - '>='
120
+ - - ">="
121
121
  - !ruby/object:Gem::Version
122
122
  version: '0'
123
123
  requirements: []
124
124
  rubyforge_project:
125
- rubygems_version: 2.0.14
125
+ rubygems_version: 2.0.3
126
126
  signing_key:
127
127
  specification_version: 4
128
128
  summary: Build document type things.