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
         
     |