smarky 0.0.1
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 +7 -0
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +76 -0
- data/Rakefile +9 -0
- data/lib/smarky.rb +77 -0
- data/lib/smarky/element.rb +83 -0
- data/lib/smarky/markdown/kramdown.rb +11 -0
- data/lib/smarky/markdown/maruku.rb +11 -0
- data/lib/smarky/markdown/redcarpet.rb +15 -0
- data/lib/smarky/version.rb +3 -0
- data/smarky.gemspec +29 -0
- data/spec/element_spec.rb +68 -0
- data/spec/smarky_spec.rb +189 -0
- data/spec/spec_helper.rb +31 -0
- metadata +175 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 498ca46d8878825f6416da7310e082abbbac9d8b
|
4
|
+
data.tar.gz: fa44aac8e0ec3ce1abc7ea3cfafbfd4a9249a467
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5954494b1daa014a2d97df8f96cd279d1fbe021d12179f76c9576928a59b82f1c6ac3814660a0e3a496bac112f098dcee593cbc32607a347362032c6fcad63f0
|
7
|
+
data.tar.gz: cd208436b638fff4d9689debc1c4c66856fa1fa82a139440acd56e6276169ffd512554193c7ef4b6fe993368bc81398905fb6831b2559bc3fd430eb05d7f2ece
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Dan Tao
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
Smarky
|
2
|
+
======
|
3
|
+
|
4
|
+
Smarky takes [Markdown](http://daringfireball.net/projects/markdown/) and turns it into **structured** (as opposed to *flat*) HTML.
|
5
|
+
|
6
|
+
This is easier to show than to explain. Say we have this Markdown:
|
7
|
+
|
8
|
+
```markdown
|
9
|
+
# The Trial
|
10
|
+
|
11
|
+
## Chapter 1
|
12
|
+
|
13
|
+
Someone must have been telling lies about Josef K. [...]
|
14
|
+
|
15
|
+
## Chapter 2
|
16
|
+
|
17
|
+
K. was informed by telephone [...]
|
18
|
+
```
|
19
|
+
|
20
|
+
Traditional Markdown renderers will translate this to the following HTML:
|
21
|
+
|
22
|
+
```html
|
23
|
+
<h1>The Trial</h1>
|
24
|
+
<h2>Chapter 1</h2>
|
25
|
+
<p>Someone must have been telling lies about Joseph K. [...]</p>
|
26
|
+
<h2>Chapter 2</h2>
|
27
|
+
<p>K. was informed by telephone [...]</p>
|
28
|
+
```
|
29
|
+
|
30
|
+
This is *flat*. Smarky will produce this instead:
|
31
|
+
|
32
|
+
```html
|
33
|
+
<article>
|
34
|
+
<h1>The Trial</h1>
|
35
|
+
<section>
|
36
|
+
<h2>Chapter 1</h2>
|
37
|
+
<p>Someone must have been telling lies about Joseph K. [...]</p>
|
38
|
+
</section>
|
39
|
+
<section>
|
40
|
+
<h2>Chapter 2</h2>
|
41
|
+
<p>K. was informed by telephone [...]</p>
|
42
|
+
</section>
|
43
|
+
</article>
|
44
|
+
```
|
45
|
+
|
46
|
+
Usage
|
47
|
+
-----
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
article = Smarky.parse('This is some *sweet* Markdown.')
|
51
|
+
# => a Smarky::Element representing the top-level <article>
|
52
|
+
|
53
|
+
article.children
|
54
|
+
# => an array of Smarky::Element objects (w/ #to_html and #inner_html methods)
|
55
|
+
|
56
|
+
article.sections
|
57
|
+
# => an array of just the child sections (useful for, e.g., a table of contents)
|
58
|
+
|
59
|
+
article.to_html
|
60
|
+
# => the structured HTML
|
61
|
+
```
|
62
|
+
|
63
|
+
Choosing a Markdown renderer
|
64
|
+
----------------------------
|
65
|
+
|
66
|
+
Smarky lets you pick which Markdown renderer you want to use. Right now you have three options:
|
67
|
+
|
68
|
+
- [Redcarpet](https://github.com/vmg/redcarpet)
|
69
|
+
- [Maruku](https://github.com/bhollis/maruku)
|
70
|
+
- [Kramdown](https://github.com/gettalong/kramdown)
|
71
|
+
|
72
|
+
To specify a renderer, pass an options hash with `:markdown_renderer` to `Smarky.parse`:
|
73
|
+
|
74
|
+
Smarky.parse(markdown, :markdown_renderer => :kramdown)
|
75
|
+
|
76
|
+
Obviously, you'll need the appropriate gem installed in order to use it (Smarky doesn't eagerly specify a dependency on any of them). The default is currently Redcarpet.
|
data/Rakefile
ADDED
data/lib/smarky.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'smarky/element'
|
2
|
+
require 'smarky/version'
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
module Smarky
|
6
|
+
def self.parse(markdown, options={})
|
7
|
+
html = self.markdown_renderer(options).render(markdown)
|
8
|
+
fragment = Nokogiri::HTML.fragment(html)
|
9
|
+
|
10
|
+
article = Element.new('article')
|
11
|
+
section = article
|
12
|
+
current_level = nil
|
13
|
+
|
14
|
+
fragment.children.each do |node|
|
15
|
+
if (heading = node.name.match(/^h(\d)$/i))
|
16
|
+
new_section = Element.new('section', heading[0])
|
17
|
+
new_section.add_child(Element.new(node))
|
18
|
+
|
19
|
+
level = heading[1].to_i
|
20
|
+
if current_level.nil? || level > current_level
|
21
|
+
difference = level - (current_level || 1)
|
22
|
+
while difference > 1
|
23
|
+
wrapper_section = Element.new('section')
|
24
|
+
section.add_child(wrapper_section)
|
25
|
+
section = wrapper_section
|
26
|
+
difference -= 1
|
27
|
+
end
|
28
|
+
|
29
|
+
section.add_child(new_section)
|
30
|
+
section = new_section
|
31
|
+
|
32
|
+
elsif level == current_level
|
33
|
+
section.add_next_sibling(new_section)
|
34
|
+
section = new_section
|
35
|
+
|
36
|
+
else
|
37
|
+
difference = current_level - level
|
38
|
+
while difference > 0
|
39
|
+
section = section.parent
|
40
|
+
difference -= 1
|
41
|
+
end
|
42
|
+
|
43
|
+
section.add_next_sibling(new_section)
|
44
|
+
section = new_section
|
45
|
+
end
|
46
|
+
|
47
|
+
current_level = level
|
48
|
+
|
49
|
+
else
|
50
|
+
section.add_child(Element.new(node))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
article
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.markdown_renderer(options={})
|
58
|
+
case options[:markdown_renderer]
|
59
|
+
when :redcarpet
|
60
|
+
require 'smarky/markdown/redcarpet'
|
61
|
+
Smarky::Markdown::Redcarpet.new
|
62
|
+
|
63
|
+
when :maruku
|
64
|
+
require 'smarky/markdown/maruku'
|
65
|
+
Smarky::Markdown::Maruku.new
|
66
|
+
|
67
|
+
when :kramdown
|
68
|
+
require 'smarky/markdown/kramdown'
|
69
|
+
Smarky::Markdown::Kramdown.new
|
70
|
+
|
71
|
+
else
|
72
|
+
# Default to Redcarpet
|
73
|
+
require 'smarky/markdown/redcarpet'
|
74
|
+
Smarky::Markdown::Redcarpet.new
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Smarky
|
2
|
+
class Element
|
3
|
+
def initialize(*args)
|
4
|
+
node_or_name, @title = args
|
5
|
+
|
6
|
+
case node_or_name
|
7
|
+
when String
|
8
|
+
@document = Nokogiri::HTML::Document.new
|
9
|
+
@node = Nokogiri::XML::Node.new(node_or_name, @document)
|
10
|
+
|
11
|
+
else
|
12
|
+
@document = node_or_name.document
|
13
|
+
@node = node_or_name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def title
|
18
|
+
@title ||= begin
|
19
|
+
first_child = @node.children.first
|
20
|
+
first_child && first_child.name =~ /^h[1-6]$/ && first_child.content
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def parent
|
25
|
+
@parent ||= Element.new(@node.parent)
|
26
|
+
end
|
27
|
+
|
28
|
+
def name
|
29
|
+
@node.name
|
30
|
+
end
|
31
|
+
|
32
|
+
def content
|
33
|
+
@node.content
|
34
|
+
end
|
35
|
+
|
36
|
+
def children
|
37
|
+
@children ||= @node.children.map { |node| Element.new(node) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def sections
|
41
|
+
@sections ||= @node.css('> section').map { |node| Element.new(node) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_child(child)
|
45
|
+
@node.add_child(child.node)
|
46
|
+
dirty!
|
47
|
+
child
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_next_sibling(sibling)
|
51
|
+
@node.add_next_sibling(sibling.node)
|
52
|
+
dirty!
|
53
|
+
sibling
|
54
|
+
end
|
55
|
+
|
56
|
+
def add_section
|
57
|
+
add_child(Element.new('section'))
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_html
|
61
|
+
@node.to_html
|
62
|
+
end
|
63
|
+
|
64
|
+
def inner_html
|
65
|
+
@node.inner_html
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
def node
|
71
|
+
@node
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def dirty!
|
77
|
+
@title = nil
|
78
|
+
@parent = nil
|
79
|
+
@children = nil
|
80
|
+
@sections = nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/smarky.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'smarky/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "smarky"
|
8
|
+
spec.version = Smarky::VERSION
|
9
|
+
spec.authors = ["Dan Tao"]
|
10
|
+
spec.email = ["daniel.tao@gmail.com"]
|
11
|
+
spec.description = %q{Smarky creates structure from Markdown}
|
12
|
+
spec.summary = %q{Smarky creates structure from Markdown}
|
13
|
+
spec.homepage = "https://github.com/dtao/smarky"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "nokogiri"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "heredoc_unindent"
|
24
|
+
spec.add_development_dependency "kramdown"
|
25
|
+
spec.add_development_dependency "maruku"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "redcarpet"
|
28
|
+
spec.add_development_dependency "rspec"
|
29
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe Smarky::Element do
|
4
|
+
let(:result) { Smarky.parse(@input) }
|
5
|
+
|
6
|
+
let(:sections) { result.sections }
|
7
|
+
|
8
|
+
describe 'sections' do
|
9
|
+
before :each do
|
10
|
+
input <<-EOMARKDOWN
|
11
|
+
# Chapter 1
|
12
|
+
This is chapter 1.
|
13
|
+
|
14
|
+
## Chapter 1, Part 1
|
15
|
+
This is part 1 of chapter 1.
|
16
|
+
|
17
|
+
## Chapter 1, Part 2
|
18
|
+
This is part 2 of chapter 1.
|
19
|
+
|
20
|
+
# Chapter 2
|
21
|
+
This is chapter 2.
|
22
|
+
|
23
|
+
## Chapter 2, Part 1
|
24
|
+
This is part 1 of chapter 2.
|
25
|
+
|
26
|
+
## Chapter 2, Part 2
|
27
|
+
This is part 2 of chapter 2.
|
28
|
+
EOMARKDOWN
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'provides access to all of its child sections' do
|
32
|
+
sections.map(&:title).should == ['Chapter 1', 'Chapter 2']
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'every section also provides access to child sections' do
|
36
|
+
sections.map { |s| s.sections.map(&:title) }.should == [
|
37
|
+
['Chapter 1, Part 1', 'Chapter 1, Part 2'],
|
38
|
+
['Chapter 2, Part 1', 'Chapter 2, Part 2']
|
39
|
+
]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'title' do
|
44
|
+
it 'is set to the content of the first header element' do
|
45
|
+
input <<-EOMARKDOWN
|
46
|
+
This is a title
|
47
|
+
===============
|
48
|
+
|
49
|
+
Content content content.
|
50
|
+
EOMARKDOWN
|
51
|
+
|
52
|
+
sections.first.title.should == 'This is a title'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "doesn't have a title if its first child is not a heading" do
|
56
|
+
input <<-EOMARKDOWN
|
57
|
+
This is some content before the heading.
|
58
|
+
|
59
|
+
This is a heading
|
60
|
+
=================
|
61
|
+
|
62
|
+
This is some content after the heading.
|
63
|
+
EOMARKDOWN
|
64
|
+
|
65
|
+
result.title.should be_nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/spec/smarky_spec.rb
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe Smarky do
|
4
|
+
let(:result) { Smarky.parse(@input, @options || {}) }
|
5
|
+
|
6
|
+
describe 'parse' do
|
7
|
+
def verify_result(*args)
|
8
|
+
expected, @options = [args.pop, args.pop]
|
9
|
+
|
10
|
+
case expected
|
11
|
+
when Array
|
12
|
+
node_to_array(result)[1..-1].should == expected
|
13
|
+
when String
|
14
|
+
result.to_html.should == expected
|
15
|
+
else
|
16
|
+
raise 'Unable to verify against a #{expected.class}.'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns a Smarky::Element wrapper around an <article>' do
|
21
|
+
result.should be_a(Smarky::Element)
|
22
|
+
result.name.should == 'article'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'works in the simplest case: rendering a single paragraph' do
|
26
|
+
input 'Why *hello* there.'
|
27
|
+
verify_result '<article><p>Why <em>hello</em> there.</p></article>'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'uses RedCarpet for rendering Markdown by default' do
|
31
|
+
input <<-EOMARKDOWN
|
32
|
+
This should look weird.
|
33
|
+
{: .weird }
|
34
|
+
EOMARKDOWN
|
35
|
+
verify_result "<article><p>This should look weird.\n{: .weird }</p></article>"
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'can use Maruku, if specified' do
|
39
|
+
input <<-EOMARKDOWN
|
40
|
+
This should look normal.
|
41
|
+
{: .normal }
|
42
|
+
EOMARKDOWN
|
43
|
+
verify_result({ :markdown_renderer => :maruku }, '<article><p class="normal">This should look normal.</p></article>')
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'can also use Kramdown' do
|
47
|
+
# TODO: Test this properly.
|
48
|
+
input <<-EOMARKDOWN
|
49
|
+
This should also look normal.
|
50
|
+
{: .normal }
|
51
|
+
EOMARKDOWN
|
52
|
+
verify_result({ :markdown_renderer => :kramdown }, '<article><p class="normal">This should also look normal.</p></article>')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'renders sibling sections for progressive heading elements' do
|
56
|
+
input <<-EOMARKDOWN
|
57
|
+
Section 1
|
58
|
+
=========
|
59
|
+
|
60
|
+
This is section 1.
|
61
|
+
|
62
|
+
Section 2
|
63
|
+
=========
|
64
|
+
|
65
|
+
This is section 2.
|
66
|
+
EOMARKDOWN
|
67
|
+
|
68
|
+
verify_result [
|
69
|
+
[:section,
|
70
|
+
[:h1, 'Section 1'],
|
71
|
+
[:p, 'This is section 1.']
|
72
|
+
],
|
73
|
+
[:section,
|
74
|
+
[:h1, 'Section 2'],
|
75
|
+
[:p, 'This is section 2.']
|
76
|
+
]
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'renders nested sections for heading elements with descending rank' do
|
81
|
+
input <<-EOMARKDOWN
|
82
|
+
Section 1
|
83
|
+
=========
|
84
|
+
|
85
|
+
This is section 1.
|
86
|
+
|
87
|
+
Section 1.1
|
88
|
+
-----------
|
89
|
+
|
90
|
+
This is section 1.1.
|
91
|
+
|
92
|
+
### Section 1.1.1
|
93
|
+
|
94
|
+
This is section 1.1.1.
|
95
|
+
EOMARKDOWN
|
96
|
+
|
97
|
+
verify_result [
|
98
|
+
[:section,
|
99
|
+
[:h1, 'Section 1'],
|
100
|
+
[:p, 'This is section 1.'],
|
101
|
+
[:section,
|
102
|
+
[:h2, 'Section 1.1'],
|
103
|
+
[:p, 'This is section 1.1.'],
|
104
|
+
[:section,
|
105
|
+
[:h3, 'Section 1.1.1'],
|
106
|
+
[:p, 'This is section 1.1.1.']
|
107
|
+
]
|
108
|
+
]
|
109
|
+
]
|
110
|
+
]
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'works properly for multiple sections and subsections' do
|
114
|
+
input <<-EOMARKDOWN
|
115
|
+
Section 1
|
116
|
+
=========
|
117
|
+
|
118
|
+
This is section 1.
|
119
|
+
|
120
|
+
Section 1.1
|
121
|
+
-----------
|
122
|
+
|
123
|
+
This is section 1.1.
|
124
|
+
|
125
|
+
Section 2
|
126
|
+
=========
|
127
|
+
|
128
|
+
This is section 2.
|
129
|
+
|
130
|
+
Section 2.1
|
131
|
+
-----------
|
132
|
+
|
133
|
+
This is section 2.1.
|
134
|
+
EOMARKDOWN
|
135
|
+
|
136
|
+
verify_result [
|
137
|
+
[:section,
|
138
|
+
[:h1, 'Section 1'],
|
139
|
+
[:p, 'This is section 1.'],
|
140
|
+
[:section,
|
141
|
+
[:h2, 'Section 1.1'],
|
142
|
+
[:p, 'This is section 1.1.']
|
143
|
+
]
|
144
|
+
],
|
145
|
+
[:section,
|
146
|
+
[:h1, 'Section 2'],
|
147
|
+
[:p, 'This is section 2.'],
|
148
|
+
[:section,
|
149
|
+
[:h2, 'Section 2.1'],
|
150
|
+
[:p, 'This is section 2.1.']
|
151
|
+
]
|
152
|
+
]
|
153
|
+
]
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'handles diving down and then jumping back up by multiple levels' do
|
157
|
+
input <<-EOMARKDOWN
|
158
|
+
# Section 1
|
159
|
+
|
160
|
+
This is section 1.
|
161
|
+
|
162
|
+
### Section 1.1.1
|
163
|
+
|
164
|
+
This is section 1.1.1.
|
165
|
+
|
166
|
+
# Section 2
|
167
|
+
|
168
|
+
This is section 2.
|
169
|
+
EOMARKDOWN
|
170
|
+
|
171
|
+
verify_result [
|
172
|
+
[:section,
|
173
|
+
[:h1, 'Section 1'],
|
174
|
+
[:p, 'This is section 1.'],
|
175
|
+
[:section,
|
176
|
+
[:section,
|
177
|
+
[:h3, 'Section 1.1.1'],
|
178
|
+
[:p, 'This is section 1.1.1.']
|
179
|
+
]
|
180
|
+
]
|
181
|
+
],
|
182
|
+
[:section,
|
183
|
+
[:h1, 'Section 2'],
|
184
|
+
[:p, 'This is section 2.']
|
185
|
+
]
|
186
|
+
]
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'smarky'
|
2
|
+
require 'rspec'
|
3
|
+
require 'heredoc_unindent'
|
4
|
+
|
5
|
+
def input(markdown)
|
6
|
+
@input = markdown.unindent
|
7
|
+
end
|
8
|
+
|
9
|
+
def node_to_array(node)
|
10
|
+
array = [node.name.to_sym]
|
11
|
+
|
12
|
+
if node.children.empty?
|
13
|
+
array << node.content
|
14
|
+
|
15
|
+
elsif node.children.length == 1 && node.children[0].name == 'text'
|
16
|
+
array << node.children[0].content
|
17
|
+
|
18
|
+
else
|
19
|
+
node.children.each do |node|
|
20
|
+
array << node_to_array(node) unless node.name == 'text' && node.content =~ /^\s*$/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
array
|
25
|
+
end
|
26
|
+
|
27
|
+
RSpec.configure do |config|
|
28
|
+
config.before :each do
|
29
|
+
@input = ''
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smarky
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dan Tao
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: heredoc_unindent
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: kramdown
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: maruku
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: redcarpet
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: Smarky creates structure from Markdown
|
126
|
+
email:
|
127
|
+
- daniel.tao@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- .gitignore
|
133
|
+
- Gemfile
|
134
|
+
- LICENSE.txt
|
135
|
+
- README.md
|
136
|
+
- Rakefile
|
137
|
+
- lib/smarky.rb
|
138
|
+
- lib/smarky/element.rb
|
139
|
+
- lib/smarky/markdown/kramdown.rb
|
140
|
+
- lib/smarky/markdown/maruku.rb
|
141
|
+
- lib/smarky/markdown/redcarpet.rb
|
142
|
+
- lib/smarky/version.rb
|
143
|
+
- smarky.gemspec
|
144
|
+
- spec/element_spec.rb
|
145
|
+
- spec/smarky_spec.rb
|
146
|
+
- spec/spec_helper.rb
|
147
|
+
homepage: https://github.com/dtao/smarky
|
148
|
+
licenses:
|
149
|
+
- MIT
|
150
|
+
metadata: {}
|
151
|
+
post_install_message:
|
152
|
+
rdoc_options: []
|
153
|
+
require_paths:
|
154
|
+
- lib
|
155
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - '>='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
requirements: []
|
166
|
+
rubyforge_project:
|
167
|
+
rubygems_version: 2.0.3
|
168
|
+
signing_key:
|
169
|
+
specification_version: 4
|
170
|
+
summary: Smarky creates structure from Markdown
|
171
|
+
test_files:
|
172
|
+
- spec/element_spec.rb
|
173
|
+
- spec/smarky_spec.rb
|
174
|
+
- spec/spec_helper.rb
|
175
|
+
has_rdoc:
|