hologram 0.6.0 → 1.0.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/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
@@ -0,0 +1,36 @@
|
|
1
|
+
module Hologram
|
2
|
+
class DocumentBlock
|
3
|
+
attr_accessor :name, :parent, :children, :title, :category, :markdown, :config, :heading
|
4
|
+
|
5
|
+
def initialize(config = nil, markdown = nil)
|
6
|
+
@children = {}
|
7
|
+
set_members(config, markdown) if config and markdown
|
8
|
+
end
|
9
|
+
|
10
|
+
def set_members(config, markdown)
|
11
|
+
@name = config['name']
|
12
|
+
@category = config['category']
|
13
|
+
@title = config['title']
|
14
|
+
@parent = config['parent']
|
15
|
+
@markdown = markdown
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_hash
|
19
|
+
{:name => @name,
|
20
|
+
:parent => @parent,
|
21
|
+
:category => @category,
|
22
|
+
:title => @title
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_valid?
|
27
|
+
!!(@name && @markdown)
|
28
|
+
end
|
29
|
+
|
30
|
+
# sets the header tag based on how deep your nesting is
|
31
|
+
def markdown_with_heading(heading = 1)
|
32
|
+
@markdown = "\n\n<h#{heading.to_s} id=\"#{@name}\">#{@title}</h#{heading.to_s}>" + @markdown
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Hologram
|
2
|
+
|
3
|
+
#Helper class for binding things for ERB
|
4
|
+
class TemplateVariables
|
5
|
+
attr_accessor :title, :file_name, :blocks, :categories
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
set_args(args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def set_args(args)
|
12
|
+
args.each do |k,v|
|
13
|
+
instance_variable_set("@#{k}", v) unless v.nil?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_binding
|
18
|
+
binding()
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/hologram/version.rb
CHANGED
@@ -8,11 +8,16 @@
|
|
8
8
|
|
9
9
|
<nav>
|
10
10
|
<ul>
|
11
|
-
<%
|
12
|
-
<li><a href="
|
11
|
+
<% @categories.each do |category, file_name| %>
|
12
|
+
<li><a href="<%= file_name %>"><%= category %></a></li>
|
13
13
|
<% end %>
|
14
14
|
</ul>
|
15
15
|
</nav>
|
16
16
|
|
17
17
|
<h1>a brand new style guide, it's super effective</h1>
|
18
18
|
<section class="content">
|
19
|
+
<ul>
|
20
|
+
<% @blocks.each do |b| %>
|
21
|
+
<li><a href="#<%= b[:name] %>"><%= b[:title] %></a></li>
|
22
|
+
<% end %>
|
23
|
+
</ul>
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
describe Hologram::DisplayMessage do
|
5
|
+
subject(:display) { Hologram::DisplayMessage }
|
6
|
+
|
7
|
+
#Rails kernerl helper
|
8
|
+
def capture(stream)
|
9
|
+
stream = stream.to_s
|
10
|
+
captured_stream = Tempfile.new(stream)
|
11
|
+
stream_io = eval("$#{stream}")
|
12
|
+
origin_stream = stream_io.dup
|
13
|
+
stream_io.reopen(captured_stream)
|
14
|
+
|
15
|
+
yield
|
16
|
+
|
17
|
+
stream_io.rewind
|
18
|
+
return captured_stream.read
|
19
|
+
ensure
|
20
|
+
captured_stream.unlink
|
21
|
+
stream_io.reopen(origin_stream)
|
22
|
+
end
|
23
|
+
|
24
|
+
context '.quiet!' do
|
25
|
+
around do |example|
|
26
|
+
display.quiet!
|
27
|
+
example.run
|
28
|
+
display.show!
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'sets quiet to true' do
|
32
|
+
display.quiet!
|
33
|
+
expect(display.quiet?).to be_true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context '.puts' do
|
38
|
+
let(:message) { capture(:stdout) { display.puts('foo') } }
|
39
|
+
|
40
|
+
it 'puts to console' do
|
41
|
+
expect(message).to eql "foo\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when quiet' do
|
45
|
+
around do |example|
|
46
|
+
display.quiet!
|
47
|
+
example.run
|
48
|
+
display.show!
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'does nothing' do
|
52
|
+
expect(message).to be_empty
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context '.error' do
|
58
|
+
around do |example|
|
59
|
+
display.quiet!
|
60
|
+
example.run
|
61
|
+
display.show!
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'displays an error in red' do
|
65
|
+
expect(display).to receive(:puts).with("\e[32m(╯°□°)╯\e[0m\e[31m︵ ┻━┻ \e[0m\e[31m Build not complete.\e[0m")
|
66
|
+
expect(display).to receive(:puts).with(" foo")
|
67
|
+
|
68
|
+
begin
|
69
|
+
display.error('foo')
|
70
|
+
rescue SystemExit
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'exits' do
|
75
|
+
expect{ display.error('foo') }.to raise_error SystemExit
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context '.warning' do
|
80
|
+
it 'displays a warning message in yellow' do
|
81
|
+
expect(display).to receive(:puts).with("\e[33mWarning: foo\e[0m")
|
82
|
+
display.warning('foo')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context '.colorize' do
|
87
|
+
it 'returns a colorized string' do
|
88
|
+
expect(display.colorize(31, 'foo')).to eql "\e[31mfoo\e[0m"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context '.red' do
|
93
|
+
it 'returns a red colorized string' do
|
94
|
+
expect(display.red('foo')).to eql display.colorize(31, 'foo')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context '.green' do
|
99
|
+
it 'returns a green colorized string' do
|
100
|
+
expect(display.green('foo')).to eql display.colorize(32, 'foo')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context '.yellow' do
|
105
|
+
it 'returns a yellow colorized string' do
|
106
|
+
expect(display.yellow('foo')).to eql display.colorize(33, 'foo')
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context '.pink' do
|
111
|
+
it 'returns a pink colorized string' do
|
112
|
+
expect(display.pink('foo')).to eql display.colorize(35, 'foo')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hologram::DocBlockCollection do
|
4
|
+
let(:comment) do
|
5
|
+
comment = <<comment
|
6
|
+
/*doc
|
7
|
+
---
|
8
|
+
title: Buttons
|
9
|
+
name: button
|
10
|
+
category: Base CSS
|
11
|
+
---
|
12
|
+
|
13
|
+
Button styles can be applied to any element. Typically you'll want
|
14
|
+
to use either a `<button>` or an `<a>` element:
|
15
|
+
|
16
|
+
```html_example
|
17
|
+
<button class="btn btnDefault">Click</button>
|
18
|
+
<a class="btn btnDefault" href="trulia.com">Trulia!</a>
|
19
|
+
```
|
20
|
+
|
21
|
+
If your button is actually a link to another page, please use the
|
22
|
+
`<a>` element, while if your button performs an action, such as
|
23
|
+
submitting a form or triggering some javascript event, then use a
|
24
|
+
`<button>` element.
|
25
|
+
|
26
|
+
*/
|
27
|
+
comment
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:collection){ Hologram::DocBlockCollection.new }
|
31
|
+
|
32
|
+
context '#add_doc_block' do
|
33
|
+
context 'when the comment is valid' do
|
34
|
+
before do
|
35
|
+
collection.add_doc_block(comment)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'adds a doc block to the collection' do
|
39
|
+
expect(collection.doc_blocks.size).to eql 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when no yaml is provided' do
|
44
|
+
before do
|
45
|
+
collection.add_doc_block('')
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'does not add a new block' do
|
49
|
+
expect(collection.doc_blocks.size).to eql 0
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context '#create_nested_structure' do
|
55
|
+
context 'when the collection has blocks with parents' do
|
56
|
+
before do
|
57
|
+
collection.add_doc_block(comment)
|
58
|
+
collection.add_doc_block(%q{
|
59
|
+
/*doc
|
60
|
+
---
|
61
|
+
title: foo
|
62
|
+
name: bah
|
63
|
+
parent: button
|
64
|
+
---
|
65
|
+
some other button style
|
66
|
+
*/})
|
67
|
+
|
68
|
+
collection.create_nested_structure
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'removes the child block from the collection level' do
|
72
|
+
expect(collection.doc_blocks.size).to eql 1
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'nests the doc block as a child of the parent block' do
|
76
|
+
expect(collection.doc_blocks['button'].children.size).to eql 1
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hologram::DocBuilder do
|
4
|
+
subject(:builder) { Hologram::DocBuilder.new }
|
5
|
+
|
6
|
+
context '#init' do
|
7
|
+
around do |example|
|
8
|
+
Hologram::DisplayMessage.quiet!
|
9
|
+
example.run
|
10
|
+
Hologram::DisplayMessage.show!
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when passed an invalid config' do
|
14
|
+
before do
|
15
|
+
File.open('bad_config.yml', 'w'){ |io| io << '%' }
|
16
|
+
end
|
17
|
+
|
18
|
+
after do
|
19
|
+
FileUtils.rm('bad_config.yml')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'exits the process' do
|
23
|
+
expect { builder.init(['bad_config.yml']) }.to raise_error SystemExit
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when passed a config file' do
|
28
|
+
let(:style_files) { Dir[File.expand_path('../fixtures/styleguide/**/*.*', __FILE__)] }
|
29
|
+
let(:config_path) { File.join(Dir.pwd, 'spec/fixtures/source/config.yml') }
|
30
|
+
let(:config_copy_path) { File.join(Dir.pwd, 'spec/fixtures/source/config.yml.copy') }
|
31
|
+
|
32
|
+
around do |example|
|
33
|
+
Dir.mktmpdir do |tmpdir|
|
34
|
+
FileUtils.cp(config_path, config_copy_path)
|
35
|
+
File.open(config_copy_path, 'a'){ |io| io << "destination: #{tmpdir}" }
|
36
|
+
current_dir = Dir.pwd
|
37
|
+
Dir.chdir(tmpdir)
|
38
|
+
|
39
|
+
example.run
|
40
|
+
|
41
|
+
Dir.chdir(current_dir)
|
42
|
+
FileUtils.rm(config_copy_path)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
before do
|
47
|
+
builder.init([config_copy_path])
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'builds a styleguide' do
|
51
|
+
processed_files = Dir[File.join('.', '**/*.*')]
|
52
|
+
processed_files.each_with_index do |file, index|
|
53
|
+
expect(FileUtils.cmp(file, style_files[index])).to be_true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when passed "init" as arg' do
|
59
|
+
around do |example|
|
60
|
+
Dir.mktmpdir do |dir|
|
61
|
+
Dir.chdir(dir) do
|
62
|
+
example.run
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
before do
|
68
|
+
builder.init(['init'])
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'creates a config file' do
|
72
|
+
expect(File.exists?('hologram_config.yml')).to be_true
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'creates default assets' do
|
76
|
+
Dir.chdir('doc_assets') do
|
77
|
+
['_header.html', '_footer.html'].each do |asset|
|
78
|
+
expect(File.exists?(asset)).to be_true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when a hologram_config.yml already exists' do
|
84
|
+
it 'does nothing' do
|
85
|
+
open('hologram_config.yml', 'w') {|io|io << 'foo'}
|
86
|
+
builder.init(['init'])
|
87
|
+
expect(IO.read('hologram_config.yml')).to eql('foo')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hologram::DocParser do
|
4
|
+
|
5
|
+
let(:doc) do
|
6
|
+
<<-eos
|
7
|
+
/*doc
|
8
|
+
---
|
9
|
+
title: Some other style
|
10
|
+
name: otherStyle
|
11
|
+
category: Foo
|
12
|
+
---
|
13
|
+
Markdown stuff
|
14
|
+
*/
|
15
|
+
eos
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:child_doc) do
|
19
|
+
<<-eos
|
20
|
+
/*doc
|
21
|
+
---
|
22
|
+
parent: button
|
23
|
+
name: otherStyle
|
24
|
+
title: Some other style
|
25
|
+
---
|
26
|
+
Markdown stuff
|
27
|
+
*/
|
28
|
+
eos
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:source_path) { 'spec/fixtures/source' }
|
32
|
+
let(:temp_doc) { File.join(source_path, 'components', 'button', 'skin', 'testSkin.css') }
|
33
|
+
|
34
|
+
subject(:parser) { Hologram::DocParser.new('spec/fixtures/source') }
|
35
|
+
|
36
|
+
context '#parse' do
|
37
|
+
let(:result) { parser.parse }
|
38
|
+
|
39
|
+
it 'builds and returns a hash of pages' do
|
40
|
+
expect(result).to be_a Hash
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when an index page is specified' do
|
44
|
+
subject(:parser) { Hologram::DocParser.new('spec/fixtures/source', 'foo') }
|
45
|
+
|
46
|
+
around do |example|
|
47
|
+
File.open(temp_doc, 'a+'){ |io| io << doc }
|
48
|
+
example.run
|
49
|
+
FileUtils.rm(temp_doc)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'uses that page as the index' do
|
53
|
+
expect(result['index.html'][:md]).to include 'Markdown stuff'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when the source is a parent doc' do
|
58
|
+
around do |example|
|
59
|
+
File.open(temp_doc, 'a+'){ |io| io << doc }
|
60
|
+
example.run
|
61
|
+
FileUtils.rm(temp_doc)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'takes the category in a collection and treats them as the page names' do
|
65
|
+
expect(result.keys).to include 'foo.html'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'when a source doc is a child' do
|
70
|
+
around do |example|
|
71
|
+
File.open(temp_doc, 'a+'){ |io| io << child_doc }
|
72
|
+
example.run
|
73
|
+
FileUtils.rm(temp_doc)
|
74
|
+
end
|
75
|
+
|
76
|
+
before do
|
77
|
+
parser.parse
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'appends the child doc to the category page' do
|
81
|
+
expect(result['base_css.html'][:md]).to include 'Some other style'
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'assigns the child doc a deeper header' do
|
85
|
+
expect(result['base_css.html'][:md]).to include '<h2 id="otherStyle">Some other style</h2>'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|