chordpro 0.0.1 → 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 +5 -5
- data/Gemfile +3 -2
- data/Guardfile +3 -3
- data/README.md +32 -2
- data/Rakefile +2 -2
- data/chordpro.gemspec +17 -17
- data/lib/chordpro/chord.rb +27 -0
- data/lib/chordpro/directive.rb +37 -0
- data/lib/chordpro/html.rb +36 -34
- data/lib/chordpro/line.rb +18 -0
- data/lib/chordpro/linebreak.rb +11 -0
- data/lib/chordpro/lyric.rb +11 -0
- data/lib/chordpro/metadata.rb +29 -0
- data/lib/chordpro/parser.rb +14 -13
- data/lib/chordpro/setup.rb +63 -0
- data/lib/chordpro/song.rb +26 -0
- data/lib/chordpro/transform.rb +17 -0
- data/lib/chordpro/version.rb +1 -1
- data/lib/chordpro.rb +17 -3
- data/spec/chordpro/chord_spec.rb +37 -0
- data/spec/chordpro/directive_spec.rb +53 -0
- data/spec/chordpro/html_spec.rb +23 -6
- data/spec/chordpro/line_spec.rb +17 -0
- data/spec/chordpro/parser_spec.rb +61 -55
- data/spec/chordpro/song_spec.rb +56 -0
- data/spec/chordpro/transform_spec.rb +65 -0
- data/spec/example_spec.rb +14 -9
- data/spec/fixtures/sunshine.crd +1 -0
- data/spec/fixtures/sunshine.html +1 -27
- data/spec/spec_helper.rb +2 -1
- metadata +52 -20
data/spec/chordpro/html_spec.rb
CHANGED
@@ -1,27 +1,44 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Chordpro::HTML do
|
4
4
|
def html(string)
|
5
|
-
Chordpro
|
5
|
+
Chordpro.html(string)
|
6
6
|
end
|
7
7
|
|
8
|
-
%w
|
8
|
+
%w[title t].each do |name|
|
9
9
|
it "renders h1 for #{name}" do
|
10
10
|
expect(html("{#{name}: Blackbird}").to_s).to eq('<h1 class="title">Blackbird</h1>')
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
it "guards against xss in the title" do
|
15
|
+
expect(html('{title: <script>alert("oops");</script>}').to_s).to_not include("<script>")
|
16
|
+
end
|
17
|
+
|
18
|
+
%w[subtitle st su].each do |name|
|
15
19
|
it "renders h2 for #{name}" do
|
16
20
|
expect(html("{#{name}:The Beatles}").to_s).to eq('<h2 class="subtitle">The Beatles</h2>')
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
24
|
+
it "guards against xss in the subtitle" do
|
25
|
+
expect(html('{subtitle: <script>alert("oops");</script>}').to_s).to_not include("<script>")
|
26
|
+
end
|
27
|
+
|
20
28
|
it "renders line" do
|
21
29
|
expect(html("[G7]I dreamed I [C]held you in my [G]arms").to_s).to eq(
|
22
|
-
'<table><tr class="chords"><td>
|
23
|
-
|
30
|
+
'<table><tr class="chords"><td>G⁷</td><td>C</td><td>G</td></tr>' \
|
31
|
+
"<tr><td>I dreamed I </td><td>held you in my </td><td>arms</td></tr></table>"
|
24
32
|
)
|
25
33
|
end
|
26
34
|
|
35
|
+
it "guards against xss in chords and lyrics" do
|
36
|
+
expect(html('[<script>alert("oops");</script>]<script>alert("oops");</script>').to_s).to_not include("<script>")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "does not blow up with multiple chords in a row" do
|
40
|
+
expect(html("[G][C][D]")).to eq(
|
41
|
+
'<table><tr class="chords"><td>G</td><td>C</td><td>D</td></tr></table>'
|
42
|
+
)
|
43
|
+
end
|
27
44
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Chordpro::Line do
|
4
|
+
describe "accept" do
|
5
|
+
let(:visitor) { double(:visitor) }
|
6
|
+
let(:line) { Chordpro::Line.new([]) }
|
7
|
+
|
8
|
+
it "calls method on visitor" do
|
9
|
+
expect(visitor).to receive(:line).and_return("line")
|
10
|
+
expect(line.accept(visitor)).to eq("line")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns line when visitor does not respond to method" do
|
14
|
+
expect(line.accept(visitor)).to be_instance_of(Chordpro::Line)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,109 +1,115 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "spec_helper"
|
2
|
+
require "parslet/rig/rspec"
|
3
3
|
|
4
4
|
describe Chordpro::Parser do
|
5
5
|
let(:parser) { Chordpro::Parser.new }
|
6
6
|
|
7
7
|
subject { parser.send self.class.description }
|
8
8
|
|
9
|
-
describe
|
10
|
-
it { should parse(
|
11
|
-
it { should parse(
|
12
|
-
it { should parse(
|
13
|
-
it { should_not parse(
|
9
|
+
describe "space" do
|
10
|
+
it { should parse(" ") }
|
11
|
+
it { should parse(" ") }
|
12
|
+
it { should parse("") }
|
13
|
+
it { should_not parse("x") }
|
14
14
|
end
|
15
15
|
|
16
|
-
describe
|
17
|
-
it { should parse(
|
18
|
-
it { should_not parse(
|
16
|
+
describe "colon" do
|
17
|
+
it { should parse(":") }
|
18
|
+
it { should_not parse("x") }
|
19
19
|
end
|
20
20
|
|
21
|
-
describe
|
21
|
+
describe "newline" do
|
22
22
|
it { should parse("\n") }
|
23
23
|
it { should_not parse("x") }
|
24
24
|
end
|
25
25
|
|
26
|
-
describe
|
26
|
+
describe "lbrace" do
|
27
27
|
it { should parse("{") }
|
28
28
|
it { should_not parse("[") }
|
29
29
|
end
|
30
30
|
|
31
|
-
describe
|
31
|
+
describe "rbrace" do
|
32
32
|
it { should parse("}") }
|
33
33
|
it { should_not parse("]") }
|
34
34
|
end
|
35
35
|
|
36
|
-
describe
|
36
|
+
describe "lbracket" do
|
37
37
|
it { should parse("[") }
|
38
38
|
it { should_not parse("{") }
|
39
39
|
end
|
40
40
|
|
41
|
-
describe
|
41
|
+
describe "rbracket" do
|
42
42
|
it { should parse("]") }
|
43
43
|
it { should_not parse("}") }
|
44
44
|
end
|
45
45
|
|
46
|
-
describe
|
47
|
-
it { should parse(
|
48
|
-
it { should parse(
|
49
|
-
it { should_not parse(
|
50
|
-
it { should_not parse(
|
51
|
-
it { should_not parse(
|
46
|
+
describe "identifier" do
|
47
|
+
it { should parse("title") }
|
48
|
+
it { should parse("t") }
|
49
|
+
it { should_not parse(" abcdef") }
|
50
|
+
it { should_not parse(" ") }
|
51
|
+
it { should_not parse("") }
|
52
52
|
end
|
53
53
|
|
54
|
-
describe
|
55
|
-
it { should parse(
|
56
|
-
it { should parse(
|
57
|
-
it { should_not parse(
|
54
|
+
describe "value" do
|
55
|
+
it { should parse("some value") }
|
56
|
+
it { should parse(" ahoy ").as(" ahoy ") }
|
57
|
+
it { should_not parse("oops}") }
|
58
58
|
end
|
59
59
|
|
60
|
-
describe
|
61
|
-
it { should parse(
|
60
|
+
describe "comment" do
|
61
|
+
it { should parse("# ignore this") }
|
62
|
+
it { should_not parse("but you can't # ignore this") }
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "directive" do
|
66
|
+
it { should parse("{title:Royals}").as(directive: {name: "title", value: "Royals"}) }
|
62
67
|
# FIXME: remove trailing space from value
|
63
|
-
it { should parse(
|
64
|
-
it { should parse(
|
65
|
-
it { should_not parse(
|
68
|
+
it { should parse("{ title : Get Lucky }").as(directive: {name: "title", value: "Get Lucky "}) }
|
69
|
+
it { should parse("{soc}").as(directive: {name: "soc"}) }
|
70
|
+
it { should_not parse("{st:oops") }
|
66
71
|
end
|
67
72
|
|
68
|
-
describe
|
69
|
-
%w
|
70
|
-
it { should parse("[#{chord}]").as(:
|
73
|
+
describe "chord" do
|
74
|
+
%w[A Bb C# Dm Edim Fmaj Gsus2 A/C#].each do |chord|
|
75
|
+
it { should parse("[#{chord}]").as(chord: chord) }
|
71
76
|
end
|
72
77
|
|
73
|
-
it { should_not parse(
|
78
|
+
it { should_not parse("[G") }
|
74
79
|
end
|
75
80
|
|
76
|
-
describe
|
81
|
+
describe "lyric" do
|
77
82
|
it { should parse("I've never seen") }
|
78
|
-
it { should parse(" a diamond in the ")}
|
83
|
+
it { should parse(" a diamond in the ") }
|
79
84
|
it { should_not parse("in the[") }
|
80
85
|
it { should_not parse("in the\n") }
|
81
86
|
end
|
82
87
|
|
83
|
-
describe
|
84
|
-
it { should parse("[G]You are my sunshine").as(:
|
85
|
-
it {
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
88
|
+
describe "line" do
|
89
|
+
it { should parse("[G]You are my sunshine").as(line: [{chord: "G"}, {lyric: "You are my sunshine"}]) }
|
90
|
+
it {
|
91
|
+
should parse("You make me [C]happy when skies are [G]gray").as(line: [
|
92
|
+
{lyric: "You make me "},
|
93
|
+
{chord: "C"},
|
94
|
+
{lyric: "happy when skies are "},
|
95
|
+
{chord: "G"},
|
96
|
+
{lyric: "gray"}
|
97
|
+
])
|
98
|
+
}
|
99
|
+
|
100
|
+
it { should parse("words with a newline\n").as(line: [{lyric: "words with a newline"}]) }
|
94
101
|
it { should_not parse("foo\nbar") }
|
95
102
|
end
|
96
103
|
|
97
|
-
describe
|
104
|
+
describe "song" do
|
98
105
|
it do
|
99
|
-
song = "{title: I'll Fly Away}\n\n[C]I'll fly away, [C7]oh, glory\n[F]I'll fly [C]away\n"
|
100
|
-
should parse(song).as({:
|
101
|
-
{:
|
102
|
-
{:
|
103
|
-
{:
|
104
|
-
{:
|
106
|
+
song = "# A song\n{title: I'll Fly Away}\n\n[C]I'll fly away, [C7]oh, glory\n[F]I'll fly [C]away\n"
|
107
|
+
should parse(song).as({song: [
|
108
|
+
{directive: {name: "title", value: "I'll Fly Away"}},
|
109
|
+
{linebreak: "\n"},
|
110
|
+
{line: [{chord: "C"}, {lyric: "I'll fly away, "}, {chord: "C7"}, {lyric: "oh, glory"}]},
|
111
|
+
{line: [{chord: "F"}, {lyric: "I'll fly "}, {chord: "C"}, {lyric: "away"}]}
|
105
112
|
]})
|
106
|
-
|
107
113
|
end
|
108
114
|
end
|
109
115
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Chordpro
|
4
|
+
describe Song do
|
5
|
+
describe "metadata" do
|
6
|
+
let(:song) { Chordpro.parse("{title: Africa}\n{artist: Justin Timberlake}\n{artist: Jimmy Fallon}") }
|
7
|
+
|
8
|
+
it "returns nil if missing" do
|
9
|
+
expect(song.metadata["capo"]).to be(nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns single value" do
|
13
|
+
expect(song.metadata["title"]).to eq("Africa")
|
14
|
+
expect(song.metadata[:title]).to eq("Africa")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns array for multiple values" do
|
18
|
+
expect(song.metadata["artist"]).to eq(["Justin Timberlake", "Jimmy Fallon"])
|
19
|
+
expect(song.metadata[:artist]).to eq(song.metadata["artist"])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns nil for unknown directive" do
|
23
|
+
song = Chordpro.parse("{foo: bar}")
|
24
|
+
expect(song.metadata["foo"]).to eq(nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns hash with to_h" do
|
28
|
+
expect(song.metadata.to_h).to eq({
|
29
|
+
"title" => "Africa",
|
30
|
+
"artist" => ["Justin Timberlake", "Jimmy Fallon"]
|
31
|
+
})
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "method_missing" do
|
36
|
+
let(:song) { Chordpro.parse("{title: The Title}\n{st: The Subtitle}") }
|
37
|
+
|
38
|
+
it "responds to method for directives" do
|
39
|
+
expect(song.respond_to?(:title)).to be(true)
|
40
|
+
expect(song.respond_to?(:subtitle)).to be(true)
|
41
|
+
expect(song.title).to eq("The Title")
|
42
|
+
expect(song.subtitle).to eq("The Subtitle")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "responds to method for directive aliases" do
|
46
|
+
expect(song.respond_to?(:t)).to be(true)
|
47
|
+
expect(song.respond_to?(:st)).to be(true)
|
48
|
+
expect(song.t).to eq("The Title")
|
49
|
+
expect(song.st).to eq("The Subtitle")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "does not respond to unknown directive" do
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Chordpro::Transform do
|
4
|
+
let(:transform) { Chordpro::Transform.new }
|
5
|
+
|
6
|
+
describe "directive" do
|
7
|
+
subject { transform.apply(directive: {name: "title", value: "Two of Us"}) }
|
8
|
+
|
9
|
+
it { should be_kind_of(Chordpro::Directive) }
|
10
|
+
it { expect(subject.name).to eq("title") }
|
11
|
+
it { expect(subject.value).to eq("Two of Us") }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "directive without a value" do
|
15
|
+
subject { transform.apply(directive: {name: "soc"}) }
|
16
|
+
|
17
|
+
it { should be_kind_of(Chordpro::Directive) }
|
18
|
+
it { expect(subject.name).to eq("soc") }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "chord" do
|
22
|
+
subject { transform.apply(chord: "G") }
|
23
|
+
|
24
|
+
it { should be_kind_of(Chordpro::Chord) }
|
25
|
+
it { expect(subject.name).to eq("G") }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "chord" do
|
29
|
+
subject { transform.apply(chord: "G") }
|
30
|
+
|
31
|
+
it { should be_kind_of(Chordpro::Chord) }
|
32
|
+
it { expect(subject.name).to eq("G") }
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "linebreak" do
|
36
|
+
subject { transform.apply(linebreak: "\n") }
|
37
|
+
|
38
|
+
it { should be_kind_of(Chordpro::Linebreak) }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "line" do
|
42
|
+
subject do
|
43
|
+
transform.apply(line: [
|
44
|
+
{chord: "G"},
|
45
|
+
{lyric: "You are my sunshine"}
|
46
|
+
])
|
47
|
+
end
|
48
|
+
|
49
|
+
it { should be_kind_of(Chordpro::Line) }
|
50
|
+
it { expect(subject.parts.length).to eq(2) }
|
51
|
+
it { expect(subject.parts[0]).to be_instance_of(Chordpro::Chord) }
|
52
|
+
it { expect(subject.parts[1]).to be_instance_of(Chordpro::Lyric) }
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "song" do
|
56
|
+
subject do
|
57
|
+
transform.apply(song: [
|
58
|
+
{directive: {name: "title", value: "You Are My Sunshine"}},
|
59
|
+
{line: [{chord: "G"}, {lyric: "You are my sunshine"}]}
|
60
|
+
])
|
61
|
+
end
|
62
|
+
|
63
|
+
it { should be_kind_of(Chordpro::Song) }
|
64
|
+
end
|
65
|
+
end
|
data/spec/example_spec.rb
CHANGED
@@ -1,17 +1,22 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
describe
|
4
|
-
Dir[File.expand_path(
|
3
|
+
describe "Examples" do
|
4
|
+
Dir[File.expand_path("../fixtures/*.crd", __FILE__)].each do |file|
|
5
5
|
name = File.basename(file)
|
6
6
|
|
7
|
-
describe name, :
|
8
|
-
it
|
9
|
-
|
10
|
-
actual = File.read(file
|
7
|
+
describe name, example: name do
|
8
|
+
it "matches the example" do
|
9
|
+
html_file = file.gsub(/\.crd$/, ".html")
|
10
|
+
actual = Chordpro.html(File.read(file))
|
11
11
|
|
12
|
-
|
12
|
+
# Allow overwriting the HTML fixture with the actual output. This is
|
13
|
+
# useful when the desired output format changes.
|
14
|
+
File.open(html_file, "w") { |f| f << actual } if ENV["OVERWRITE"]
|
15
|
+
|
16
|
+
expected = File.read(html_file)
|
17
|
+
|
18
|
+
expect(actual).to eq(expected)
|
13
19
|
end
|
14
20
|
end
|
15
|
-
|
16
21
|
end
|
17
22
|
end
|
data/spec/fixtures/sunshine.crd
CHANGED
data/spec/fixtures/sunshine.html
CHANGED
@@ -1,27 +1 @@
|
|
1
|
-
<h1 class="title">You Are My Sunshine</h1>
|
2
|
-
<br>
|
3
|
-
<span class="comment">Verse 1</span>
|
4
|
-
<table><tr class="chords"><td>G</td></tr><tr><td>The other night dear as I lay sleeping</td></tr></table>
|
5
|
-
<table><tr class="chords"><td>G7</td><td>C</td><td>G</td></tr><tr><td>I dreamed I </td><td>held you in my </td><td>arms</td></tr></table>
|
6
|
-
<table><tr class="chords"><td>G7</td><td>C</td><td>G</td></tr><tr><td>But when I a</td><td>woke dear I was mis</td><td>taken</td></tr></table>
|
7
|
-
<table><tr class="chords"><td></td><td>D7</td><td>G</td></tr><tr><td>So I hung my </td><td>head and </td><td>cried</td></tr></table>
|
8
|
-
<br>
|
9
|
-
<span class="comment">Chorus</span>
|
10
|
-
|
11
|
-
<table><tr class="chords"><td></td></tr><tr><td>You are my sunshine my only sunshine</td></tr></table>
|
12
|
-
<table><tr class="chords"><td>G7</td><td>C</td><td>G</td></tr><tr><td>You make me </td><td>happy when skies are </td><td>gray</td></tr></table>
|
13
|
-
<table><tr class="chords"><td>G7</td><td>C</td><td>G</td></tr><tr><td>You'll never </td><td>know dear how much I </td><td>love you</td></tr></table>
|
14
|
-
<table><tr class="chords"><td></td><td>D7</td><td>G</td></tr><tr><td>Please don't take </td><td>my sunshine a</td><td>way</td></tr></table>
|
15
|
-
|
16
|
-
<br>
|
17
|
-
<span class="comment">Verse 2</span>
|
18
|
-
<table><tr class="chords"><td></td></tr><tr><td>I'll always love you and make you happy</td></tr></table>
|
19
|
-
<table><tr class="chords"><td>G7</td><td>C</td><td>G</td></tr><tr><td>If you will </td><td>only say the </td><td>same</td></tr></table>
|
20
|
-
<table><tr class="chords"><td>G7</td><td>C</td><td>G</td></tr><tr><td>But if you </td><td>leave me and love an</td><td>other</td></tr></table>
|
21
|
-
<table><tr class="chords"><td></td><td>D7</td><td>G</td></tr><tr><td>You'll regret </td><td>it all some </td><td>day</td></tr></table>
|
22
|
-
<br>
|
23
|
-
<span class="comment">Verse 3</span>
|
24
|
-
<table><tr class="chords"><td></td></tr><tr><td>You told me once dear you really loved me</td></tr></table>
|
25
|
-
<table><tr class="chords"><td>G7</td><td>C</td><td>G</td></tr><tr><td>And no one </td><td>else could come be</td><td>tween</td></tr></table>
|
26
|
-
<table><tr class="chords"><td>G7</td><td>C</td><td>G</td></tr><tr><td>But now you've </td><td>left me and love an</td><td>other</td></tr></table>
|
27
|
-
<table><tr class="chords"><td></td><td>D7</td><td>G</td></tr><tr><td>You have shattered </td><td>all of my </td><td>dreams</td></tr></table>
|
1
|
+
<h1 class="title">You Are My Sunshine</h1><br/><span class="comment">Verse 1</span><table><tr class="chords"><td>G</td></tr><tr><td>The other night dear as I lay sleeping</td></tr></table><table><tr class="chords"><td>G⁷</td><td>C</td><td>G</td></tr><tr><td>I dreamed I </td><td>held you in my </td><td>arms</td></tr></table><table><tr class="chords"><td>G⁷</td><td>C</td><td>G</td></tr><tr><td>But when I a</td><td>woke dear I was mis</td><td>taken</td></tr></table><table><tr class="chords"><td></td><td>D⁷</td><td>G</td></tr><tr><td>So I hung my </td><td>head and </td><td>cried</td></tr></table><br/><span class="comment">Chorus</span><table><tr><td>You are my sunshine my only sunshine</td></tr></table><table><tr class="chords"><td>G⁷</td><td>C</td><td>G</td></tr><tr><td>You make me </td><td>happy when skies are </td><td>gray</td></tr></table><table><tr class="chords"><td>G⁷</td><td>C</td><td>G</td></tr><tr><td>You'll never </td><td>know dear how much I </td><td>love you</td></tr></table><table><tr class="chords"><td></td><td>D⁷</td><td>G</td></tr><tr><td>Please don't take </td><td>my sunshine a</td><td>way</td></tr></table><br/><span class="comment">Verse 2</span><table><tr><td>I'll always love you and make you happy</td></tr></table><table><tr class="chords"><td>G⁷</td><td>C</td><td>G</td></tr><tr><td>If you will </td><td>only say the </td><td>same</td></tr></table><table><tr class="chords"><td>G⁷</td><td>C</td><td>G</td></tr><tr><td>But if you </td><td>leave me and love an</td><td>other</td></tr></table><table><tr class="chords"><td></td><td>D⁷</td><td>G</td></tr><tr><td>You'll regret </td><td>it all some </td><td>day</td></tr></table><br/><span class="comment">Verse 3</span><table><tr><td>You told me once dear you really loved me</td></tr></table><table><tr class="chords"><td>G⁷</td><td>C</td><td>G</td></tr><tr><td>And no one </td><td>else could come be</td><td>tween</td></tr></table><table><tr class="chords"><td>G⁷</td><td>C</td><td>G</td></tr><tr><td>But now you've </td><td>left me and love an</td><td>other</td></tr></table><table><tr class="chords"><td></td><td>D⁷</td><td>G</td></tr><tr><td>You have shattered </td><td>all of my </td><td>dreams</td></tr></table>
|
data/spec/spec_helper.rb
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
require
|
1
|
+
require "chordpro"
|
2
|
+
require "pry"
|
metadata
CHANGED
@@ -1,83 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chordpro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Keepers
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parslet
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: builder
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- -
|
45
|
+
- - ">="
|
32
46
|
- !ruby/object:Gem::Version
|
33
47
|
version: '0'
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- -
|
52
|
+
- - ">="
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- -
|
59
|
+
- - ">="
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: '0'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- -
|
66
|
+
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rspec
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- -
|
73
|
+
- - ">="
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '0'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- -
|
80
|
+
- - ">="
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: guard-rspec
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- -
|
87
|
+
- - ">="
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: '0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- -
|
94
|
+
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
description: A ruby parser for the chordpro song file format.
|
@@ -87,7 +101,7 @@ executables: []
|
|
87
101
|
extensions: []
|
88
102
|
extra_rdoc_files: []
|
89
103
|
files:
|
90
|
-
- .gitignore
|
104
|
+
- ".gitignore"
|
91
105
|
- Gemfile
|
92
106
|
- Guardfile
|
93
107
|
- LICENSE.txt
|
@@ -95,11 +109,25 @@ files:
|
|
95
109
|
- Rakefile
|
96
110
|
- chordpro.gemspec
|
97
111
|
- lib/chordpro.rb
|
112
|
+
- lib/chordpro/chord.rb
|
113
|
+
- lib/chordpro/directive.rb
|
98
114
|
- lib/chordpro/html.rb
|
115
|
+
- lib/chordpro/line.rb
|
116
|
+
- lib/chordpro/linebreak.rb
|
117
|
+
- lib/chordpro/lyric.rb
|
118
|
+
- lib/chordpro/metadata.rb
|
99
119
|
- lib/chordpro/parser.rb
|
120
|
+
- lib/chordpro/setup.rb
|
121
|
+
- lib/chordpro/song.rb
|
122
|
+
- lib/chordpro/transform.rb
|
100
123
|
- lib/chordpro/version.rb
|
124
|
+
- spec/chordpro/chord_spec.rb
|
125
|
+
- spec/chordpro/directive_spec.rb
|
101
126
|
- spec/chordpro/html_spec.rb
|
127
|
+
- spec/chordpro/line_spec.rb
|
102
128
|
- spec/chordpro/parser_spec.rb
|
129
|
+
- spec/chordpro/song_spec.rb
|
130
|
+
- spec/chordpro/transform_spec.rb
|
103
131
|
- spec/example_spec.rb
|
104
132
|
- spec/fixtures/example.css
|
105
133
|
- spec/fixtures/sunshine.crd
|
@@ -109,29 +137,33 @@ homepage: https://github.com/bkeepers/chordpro
|
|
109
137
|
licenses:
|
110
138
|
- MIT
|
111
139
|
metadata: {}
|
112
|
-
post_install_message:
|
140
|
+
post_install_message:
|
113
141
|
rdoc_options: []
|
114
142
|
require_paths:
|
115
143
|
- lib
|
116
144
|
required_ruby_version: !ruby/object:Gem::Requirement
|
117
145
|
requirements:
|
118
|
-
- -
|
146
|
+
- - ">="
|
119
147
|
- !ruby/object:Gem::Version
|
120
148
|
version: '0'
|
121
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
150
|
requirements:
|
123
|
-
- -
|
151
|
+
- - ">="
|
124
152
|
- !ruby/object:Gem::Version
|
125
153
|
version: '0'
|
126
154
|
requirements: []
|
127
|
-
|
128
|
-
|
129
|
-
signing_key:
|
155
|
+
rubygems_version: 3.2.22
|
156
|
+
signing_key:
|
130
157
|
specification_version: 4
|
131
158
|
summary: A ruby parser for the chordpro song file format.
|
132
159
|
test_files:
|
160
|
+
- spec/chordpro/chord_spec.rb
|
161
|
+
- spec/chordpro/directive_spec.rb
|
133
162
|
- spec/chordpro/html_spec.rb
|
163
|
+
- spec/chordpro/line_spec.rb
|
134
164
|
- spec/chordpro/parser_spec.rb
|
165
|
+
- spec/chordpro/song_spec.rb
|
166
|
+
- spec/chordpro/transform_spec.rb
|
135
167
|
- spec/example_spec.rb
|
136
168
|
- spec/fixtures/example.css
|
137
169
|
- spec/fixtures/sunshine.crd
|