hologram 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +37 -0
- data/README.md +243 -5
- data/hologram.gemspec +2 -0
- data/lib/hologram.rb +2 -0
- data/lib/hologram/block_code_renderer.rb +45 -0
- data/lib/hologram/code_example_renderer.rb +73 -0
- data/lib/hologram/code_example_renderer/example.rb +27 -0
- data/lib/hologram/code_example_renderer/factory.rb +60 -0
- data/lib/hologram/code_example_renderer/renderers/haml_renderer.rb +17 -0
- data/lib/hologram/code_example_renderer/renderers/html_renderer.rb +6 -0
- data/lib/hologram/code_example_renderer/renderers/js_renderer.rb +5 -0
- data/lib/hologram/code_example_renderer/renderers/jsx_renderer.rb +4 -0
- data/lib/hologram/code_example_renderer/renderers/react_renderer.rb +21 -0
- data/lib/hologram/code_example_renderer/renderers/slim_renderer.rb +16 -0
- data/lib/hologram/code_example_renderer/template.rb +33 -0
- data/lib/hologram/display_message.rb +13 -0
- data/lib/hologram/doc_block_collection.rb +5 -1
- data/lib/hologram/doc_builder.rb +58 -7
- data/lib/hologram/doc_parser.rb +20 -4
- data/lib/hologram/document_block.rb +22 -4
- data/lib/hologram/link_helper.rb +18 -0
- data/lib/hologram/markdown_renderer.rb +56 -35
- data/lib/hologram/version.rb +1 -1
- data/lib/template/code_example_templates/js_example_template.html.erb +7 -0
- data/lib/template/code_example_templates/jsx_example_template.html.erb +7 -0
- data/lib/template/code_example_templates/markup_example_template.html.erb +10 -0
- data/lib/template/code_example_templates/markup_table_template.html.erb +23 -0
- data/lib/template/hologram_config.yml +23 -0
- data/spec/block_code_renderer_spec.rb +279 -0
- data/spec/code_example_renderer/example_spec.rb +26 -0
- data/spec/code_example_renderer/factory_spec.rb +102 -0
- data/spec/code_example_renderer/template_spec.rb +50 -0
- data/spec/display_message_spec.rb +18 -0
- data/spec/doc_block_collection_spec.rb +26 -1
- data/spec/doc_builder_spec.rb +28 -5
- data/spec/doc_parser_spec.rb +67 -7
- data/spec/document_block_spec.rb +33 -2
- data/spec/fixtures/source/components/button/buttons.css +8 -6
- data/spec/fixtures/source/components/button/skin/buttonSkins.css +17 -0
- data/spec/fixtures/styleguide/base_css.html +176 -52
- data/spec/fixtures/styleguide/index.html +6 -14
- data/spec/link_helper_spec.rb +57 -0
- data/spec/markdown_renderer_spec.rb +82 -0
- metadata +75 -19
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'hologram/code_example_renderer/example'
|
2
|
+
require 'hologram/code_example_renderer/template'
|
3
|
+
|
4
|
+
module Hologram
|
5
|
+
module CodeExampleRenderer
|
6
|
+
class << self
|
7
|
+
def register(example_type, args)
|
8
|
+
puts "Adding renderer for #{example_type} examples"
|
9
|
+
example_types[example_type] = {
|
10
|
+
example_class: args[:example_class],
|
11
|
+
example_template: args[:example_template],
|
12
|
+
table_template: args[:table_template]
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def unregister(example_type)
|
17
|
+
example_types.delete(example_type)
|
18
|
+
end
|
19
|
+
|
20
|
+
def example_class_for(example_type)
|
21
|
+
if example_types.has_key?(example_type)
|
22
|
+
example_types[example_type][:example_class]
|
23
|
+
else
|
24
|
+
Example
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def example_template_for(example_type)
|
29
|
+
if example_types.has_key?(example_type)
|
30
|
+
example_types[example_type][:example_template]
|
31
|
+
else
|
32
|
+
[
|
33
|
+
"<div class=\"codeBlock\">",
|
34
|
+
" <div class=\"highlight\">",
|
35
|
+
" <pre><%= code_example %></pre>",
|
36
|
+
" </div>",
|
37
|
+
"</div>",
|
38
|
+
].join("\n")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def table_template_for(example_type)
|
43
|
+
if example_types.has_key?(example_type)
|
44
|
+
example_types[example_type][:table_template]
|
45
|
+
else
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_renderers_and_templates
|
51
|
+
require 'hologram/code_example_renderer/factory'
|
52
|
+
|
53
|
+
Dir[File.join(File.dirname(__FILE__), 'code_example_renderer', 'renderers', '*.rb')].each do |file|
|
54
|
+
require file
|
55
|
+
end
|
56
|
+
|
57
|
+
if path_to_custom_example_renderers
|
58
|
+
Dir[File.join(path_to_custom_example_renderers, '*.rb')].each do |file|
|
59
|
+
require file
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
attr_accessor :path_to_custom_example_renderers
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def example_types
|
69
|
+
@example_types ||= Hash.new
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Hologram
|
2
|
+
module CodeExampleRenderer
|
3
|
+
class Example < Struct.new(:code)
|
4
|
+
def rendered_example
|
5
|
+
code
|
6
|
+
end
|
7
|
+
|
8
|
+
def code_example
|
9
|
+
formatter.format(lexer.lex(code)).strip
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_binding
|
13
|
+
binding
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def formatter
|
19
|
+
@_formatter ||= Rouge::Formatters::HTML.new(wrap: false)
|
20
|
+
end
|
21
|
+
|
22
|
+
def lexer
|
23
|
+
@_lexer ||= Rouge::Lexer.find_fancy('guess', code)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'hologram/code_example_renderer'
|
2
|
+
|
3
|
+
module Hologram
|
4
|
+
module CodeExampleRenderer
|
5
|
+
class Factory
|
6
|
+
def self.define(example_type, &block)
|
7
|
+
definition_proxy = DefinitionProxy.new
|
8
|
+
definition_proxy.instance_eval(&block)
|
9
|
+
|
10
|
+
example_class = Class.new(Example) do
|
11
|
+
if definition_proxy.rendered_example_block
|
12
|
+
define_method :rendered_example do
|
13
|
+
definition_proxy.rendered_example_block.call(code)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
if definition_proxy.lexer_block
|
20
|
+
define_method :lexer do
|
21
|
+
definition_proxy.lexer_block.call
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
CodeExampleRenderer.register(example_type,
|
27
|
+
example_class: example_class,
|
28
|
+
example_template: Template.new(definition_proxy.example_template_name).template,
|
29
|
+
table_template: Template.new(definition_proxy.table_template_name).template,
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class DefinitionProxy
|
35
|
+
attr_reader :example_template_name, :table_template_name,
|
36
|
+
:lexer_block, :rendered_example_block
|
37
|
+
|
38
|
+
def example_template(template_name)
|
39
|
+
self.example_template_name = template_name
|
40
|
+
end
|
41
|
+
|
42
|
+
def table_template(template_name)
|
43
|
+
self.table_template_name = template_name
|
44
|
+
end
|
45
|
+
|
46
|
+
def lexer(&block)
|
47
|
+
self.lexer_block = block
|
48
|
+
end
|
49
|
+
|
50
|
+
def rendered_example(&block)
|
51
|
+
self.rendered_example_block = block
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
attr_writer :example_template_name, :table_template_name,
|
57
|
+
:lexer_block, :rendered_example_block
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Hologram::CodeExampleRenderer::Factory.define 'haml' do
|
2
|
+
example_template 'markup_example_template'
|
3
|
+
table_template 'markup_table_template'
|
4
|
+
lexer { Rouge::Lexer.find('haml') }
|
5
|
+
|
6
|
+
rendered_example do |code|
|
7
|
+
begin
|
8
|
+
require 'haml'
|
9
|
+
rescue LoadError
|
10
|
+
raise "haml must be present for you to use haml"
|
11
|
+
end
|
12
|
+
|
13
|
+
haml_engine = Haml::Engine.new(code.strip)
|
14
|
+
haml_engine.render(Object.new, {})
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
Hologram::CodeExampleRenderer::Factory.define 'react' do
|
4
|
+
example_template 'markup_example_template'
|
5
|
+
table_template 'markup_table_template'
|
6
|
+
|
7
|
+
lexer { Rouge::Lexer.find(:html) }
|
8
|
+
|
9
|
+
rendered_example do |code|
|
10
|
+
div_id = SecureRandom.hex(10)
|
11
|
+
[
|
12
|
+
"<div id=\"#{div_id}\"></div>",
|
13
|
+
"<script type=\"text/jsx\">",
|
14
|
+
" React.render(",
|
15
|
+
" #{code.strip},",
|
16
|
+
" document.getElementById('#{div_id}')",
|
17
|
+
" );",
|
18
|
+
"</script>"
|
19
|
+
].join("\n")
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Hologram::CodeExampleRenderer::Factory.define 'slim' do
|
2
|
+
example_template 'markup_example_template'
|
3
|
+
table_template 'markup_table_template'
|
4
|
+
lexer { Rouge::Lexer.find('slim') }
|
5
|
+
|
6
|
+
rendered_example do |code|
|
7
|
+
begin
|
8
|
+
require 'slim'
|
9
|
+
rescue LoadError
|
10
|
+
raise "slim must be present for you to use slim"
|
11
|
+
end
|
12
|
+
|
13
|
+
slim_engine = Slim::Template.new { code.strip }
|
14
|
+
slim_engine.render(Object.new, {})
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Hologram
|
2
|
+
module CodeExampleRenderer
|
3
|
+
class Template < Struct.new(:template_name)
|
4
|
+
def template
|
5
|
+
return nil if !template_filename
|
6
|
+
File.read(template_filename)
|
7
|
+
end
|
8
|
+
|
9
|
+
class << self
|
10
|
+
attr_accessor :path_to_custom_example_templates
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def template_filename
|
16
|
+
return nil if !template_name
|
17
|
+
custom_file_exists? ? custom_file : default_file
|
18
|
+
end
|
19
|
+
|
20
|
+
def custom_file_exists?
|
21
|
+
!!self.class.path_to_custom_example_templates && File.file?(custom_file)
|
22
|
+
end
|
23
|
+
|
24
|
+
def custom_file
|
25
|
+
File.join(self.class.path_to_custom_example_templates, "#{template_name}.html.erb")
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_file
|
29
|
+
File.join(File.dirname(__FILE__), '..', '..', 'template', 'code_example_templates', "#{template_name}.html.erb")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Hologram
|
2
2
|
module DisplayMessage
|
3
3
|
@@quiet = false
|
4
|
+
@@exit_on_warnings = false
|
4
5
|
|
5
6
|
def self.quiet!
|
6
7
|
@@quiet = true
|
@@ -16,6 +17,14 @@ module Hologram
|
|
16
17
|
@@quiet
|
17
18
|
end
|
18
19
|
|
20
|
+
def self.exit_on_warnings!
|
21
|
+
@@exit_on_warnings = true
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.continue_on_warnings!
|
25
|
+
@@exit_on_warnings = false
|
26
|
+
end
|
27
|
+
|
19
28
|
def self.puts(str)
|
20
29
|
return if quiet?
|
21
30
|
super(str)
|
@@ -45,6 +54,10 @@ module Hologram
|
|
45
54
|
|
46
55
|
def self.warning(message)
|
47
56
|
puts yellow("Warning: #{message}")
|
57
|
+
if @@exit_on_warnings
|
58
|
+
puts red("Exiting due to warning")
|
59
|
+
exit 1
|
60
|
+
end
|
48
61
|
end
|
49
62
|
|
50
63
|
def self.success(message)
|
@@ -15,7 +15,11 @@ module Hologram
|
|
15
15
|
return
|
16
16
|
end
|
17
17
|
|
18
|
-
@doc_blocks
|
18
|
+
if @doc_blocks.has_key?(doc_block.name)
|
19
|
+
DisplayMessage.warning("Multiple Hologram comments with name: #{doc_block.name}.")
|
20
|
+
else
|
21
|
+
@doc_blocks[doc_block.name] = doc_block
|
22
|
+
end
|
19
23
|
return doc_block
|
20
24
|
end
|
21
25
|
|
data/lib/hologram/doc_builder.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'hologram/link_helper'
|
2
|
+
|
1
3
|
module Hologram
|
2
4
|
class DocBuilder
|
3
5
|
attr_accessor :source, :destination, :documentation_assets, :dependencies, :index, :base_path, :renderer, :doc_blocks, :pages, :config_yml
|
@@ -31,7 +33,17 @@ module Hologram
|
|
31
33
|
end
|
32
34
|
|
33
35
|
FileUtils.cp_r INIT_TEMPLATE_FILES, Dir.pwd
|
34
|
-
new_files = [
|
36
|
+
new_files = [
|
37
|
+
"hologram_config.yml",
|
38
|
+
"doc_assets/",
|
39
|
+
"doc_assets/_header.html",
|
40
|
+
"doc_assets/_footer.html",
|
41
|
+
"code_example_templates/",
|
42
|
+
"code_example_templates/markdown_example_template.html.erb",
|
43
|
+
"code_example_templates/markdown_table_template.html.erb",
|
44
|
+
"code_example_templates/js_example_template.html.erb",
|
45
|
+
"code_example_templates/jsx_example_template.html.erb",
|
46
|
+
]
|
35
47
|
DisplayMessage.created(new_files)
|
36
48
|
end
|
37
49
|
|
@@ -47,6 +59,14 @@ module Hologram
|
|
47
59
|
@documentation_assets = options['documentation_assets']
|
48
60
|
@config_yml = options['config_yml']
|
49
61
|
@plugins = Plugins.new(options.fetch('config_yml', {}), extra_args)
|
62
|
+
@nav_level = options['nav_level'] || 'page'
|
63
|
+
@exit_on_warnings = options['exit_on_warnings']
|
64
|
+
@code_example_templates = options['code_example_templates']
|
65
|
+
@code_example_renderers = options['code_example_renderers']
|
66
|
+
|
67
|
+
if @exit_on_warnings
|
68
|
+
DisplayMessage.exit_on_warnings!
|
69
|
+
end
|
50
70
|
end
|
51
71
|
|
52
72
|
def build
|
@@ -112,7 +132,7 @@ module Hologram
|
|
112
132
|
end
|
113
133
|
|
114
134
|
def build_docs
|
115
|
-
doc_parser = DocParser.new(input_dir, index, @plugins)
|
135
|
+
doc_parser = DocParser.new(input_dir, index, @plugins, nav_level: @nav_level)
|
116
136
|
@pages, @categories = doc_parser.parse
|
117
137
|
|
118
138
|
if index && !@pages.has_key?(index + '.html')
|
@@ -131,8 +151,8 @@ module Hologram
|
|
131
151
|
# ignore . and .. directories and files that start with
|
132
152
|
# underscore
|
133
153
|
next if item == '.' or item == '..' or item.start_with?('_')
|
134
|
-
|
135
|
-
|
154
|
+
FileUtils.rm "#{output_dir}/#{item}", :force => true
|
155
|
+
FileUtils.cp_r "#{doc_assets_dir}/#{item}", "#{output_dir}/#{item}"
|
136
156
|
end
|
137
157
|
end
|
138
158
|
|
@@ -141,8 +161,8 @@ module Hologram
|
|
141
161
|
begin
|
142
162
|
dirpath = Pathname.new(dir).realpath
|
143
163
|
if File.directory?("#{dir}")
|
144
|
-
|
145
|
-
|
164
|
+
FileUtils.rm "#{output_dir}/#{dirpath.basename}", :force => true
|
165
|
+
FileUtils.cp_r "#{dirpath}", "#{output_dir}/#{dirpath.basename}"
|
146
166
|
end
|
147
167
|
rescue
|
148
168
|
DisplayMessage.warning("Could not copy dependency: #{dir}")
|
@@ -151,7 +171,10 @@ module Hologram
|
|
151
171
|
end
|
152
172
|
|
153
173
|
def write_docs
|
154
|
-
|
174
|
+
load_code_example_templates_and_renderers
|
175
|
+
|
176
|
+
renderer_instance = renderer.new(link_helper: link_helper)
|
177
|
+
markdown = Redcarpet::Markdown.new(renderer_instance, { :fenced_code_blocks => true, :tables => true })
|
155
178
|
tpl_vars = TemplateVariables.new({:categories => @categories, :config => @config_yml, :pages => @pages})
|
156
179
|
#generate html from markdown
|
157
180
|
@pages.each do |file_name, page|
|
@@ -174,6 +197,34 @@ module Hologram
|
|
174
197
|
end
|
175
198
|
end
|
176
199
|
|
200
|
+
def load_code_example_templates_and_renderers
|
201
|
+
if @code_example_templates
|
202
|
+
CodeExampleRenderer::Template.path_to_custom_example_templates = real_path(@code_example_templates)
|
203
|
+
end
|
204
|
+
|
205
|
+
if @code_example_renderers
|
206
|
+
CodeExampleRenderer.path_to_custom_example_renderers = real_path(@code_example_renderers)
|
207
|
+
end
|
208
|
+
|
209
|
+
CodeExampleRenderer.load_renderers_and_templates
|
210
|
+
end
|
211
|
+
|
212
|
+
def link_helper
|
213
|
+
@_link_helper ||= LinkHelper.new(@pages.map { |page|
|
214
|
+
if not page[1][:blocks].nil?
|
215
|
+
{
|
216
|
+
name: page[0],
|
217
|
+
component_names: page[1][:blocks].map { |component| component[:name] }
|
218
|
+
}
|
219
|
+
else
|
220
|
+
{
|
221
|
+
name: page[0],
|
222
|
+
component_names: {}
|
223
|
+
}
|
224
|
+
end
|
225
|
+
})
|
226
|
+
end
|
227
|
+
|
177
228
|
def write_erb(file_name, content, binding)
|
178
229
|
fh = get_fh(output_dir, file_name)
|
179
230
|
erb = ERB.new(content)
|
data/lib/hologram/doc_parser.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module Hologram
|
2
2
|
class DocParser
|
3
3
|
SUPPORTED_EXTENSIONS = ['.css', '.scss', '.less', '.sass', '.styl', '.js', '.md', '.markdown', '.erb' ]
|
4
|
-
attr_accessor :source_path, :pages, :doc_blocks
|
4
|
+
attr_accessor :source_path, :pages, :doc_blocks, :nav_level
|
5
5
|
|
6
|
-
def initialize(source_path, index_name = nil, plugins)
|
6
|
+
def initialize(source_path, index_name = nil, plugins=[], opts={})
|
7
7
|
@plugins = plugins
|
8
8
|
@source_paths = Array(source_path)
|
9
9
|
@index_name = index_name
|
10
|
+
@nav_level = opts[:nav_level] || 'page'
|
10
11
|
@pages = {}
|
11
12
|
@output_files_by_category = {}
|
12
13
|
end
|
@@ -85,9 +86,16 @@ module Hologram
|
|
85
86
|
# .sass: //doc (follow by other lines proceeded by a space)
|
86
87
|
# other types: /*doc ... */
|
87
88
|
if file.end_with?('.sass')
|
88
|
-
|
89
|
+
#For sass strip out leading white spaces after we get the
|
90
|
+
#comment, this fixes haml when using this comment style
|
91
|
+
hologram_comments = file_str.scan(/\s*\/\/doc\s*((( [^\n]*\n)|\n)+)/).map{ |arr| [arr[0].gsub(/^[ \t]{2}/,'')] }
|
89
92
|
else
|
90
93
|
hologram_comments = file_str.scan(/^\s*\/\*doc(.*?)\*\//m)
|
94
|
+
|
95
|
+
#check if scss file has sass comments
|
96
|
+
if hologram_comments.length == 0 and file.end_with?('.scss')
|
97
|
+
hologram_comments = file_str.scan(/\s*\/\/doc\s*((( [^\n]*\n)|\n)+)/).map{ |arr| [arr[0].gsub(/^[ \t]{2}/,'')] }
|
98
|
+
end
|
91
99
|
end
|
92
100
|
return unless hologram_comments
|
93
101
|
|
@@ -133,8 +141,16 @@ module Hologram
|
|
133
141
|
@pages[output_file] = {:md => "", :blocks => []}
|
134
142
|
end
|
135
143
|
|
144
|
+
|
145
|
+
if (@nav_level == 'section' && depth == 1) || @nav_level == 'all'
|
146
|
+
include_sub_nav = true
|
147
|
+
else
|
148
|
+
include_sub_nav = false
|
149
|
+
end
|
150
|
+
|
136
151
|
@pages[output_file][:blocks].push(doc_block.get_hash)
|
137
|
-
@pages[output_file][:md] << doc_block.markdown_with_heading(depth)
|
152
|
+
@pages[output_file][:md] << doc_block.markdown_with_heading(depth, include_sub_nav: include_sub_nav)
|
138
153
|
end
|
154
|
+
|
139
155
|
end
|
140
156
|
end
|