hologram 1.2.0 → 1.3.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 +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
|