markover 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +102 -0
  4. data/bin/markover +31 -0
  5. data/config/style.css +174 -0
  6. data/ext/github_markup.rb +11 -0
  7. data/lib/markover.rb +31 -0
  8. data/lib/markover/config.rb +28 -0
  9. data/lib/markover/converter.rb +120 -0
  10. data/lib/markover/markup.rb +28 -0
  11. data/lib/markover/markup/code.rb +40 -0
  12. data/lib/markover/markup/code_block.rb +30 -0
  13. data/lib/markover/markup/renderer.rb +67 -0
  14. data/lib/markover/markup/yaml_frontmatter_remover.rb +17 -0
  15. data/lib/markover/markupfile.rb +67 -0
  16. data/lib/markover/optionparser.rb +93 -0
  17. data/lib/markover/path.rb +29 -0
  18. data/lib/markover/version.rb +6 -0
  19. data/lib/markover/wkhtmltopdf.rb +39 -0
  20. data/spec/fixtures/autolink_url.md +3 -0
  21. data/spec/fixtures/code_block.textile +8 -0
  22. data/spec/fixtures/code_block_with_utf8.textile +7 -0
  23. data/spec/fixtures/code_with_utf8.textile +6 -0
  24. data/spec/fixtures/integration/markdown.md +60 -0
  25. data/spec/fixtures/integration/style.css +3 -0
  26. data/spec/fixtures/integration/textile.textile +47 -0
  27. data/spec/fixtures/long_code_block.md +5 -0
  28. data/spec/fixtures/recursion/level1.textile +1 -0
  29. data/spec/fixtures/recursion/level2/level2.markdown +1 -0
  30. data/spec/fixtures/table.md +7 -0
  31. data/spec/fixtures/yaml_front_matter.textile +7 -0
  32. data/spec/integration_spec.rb +41 -0
  33. data/spec/markover/converter_spec.rb +124 -0
  34. data/spec/markover/markup/code_block_spec.rb +21 -0
  35. data/spec/markover/markup/code_spec.rb +45 -0
  36. data/spec/markover/markup/renderer_spec.rb +18 -0
  37. data/spec/markover/markup/yaml_frontmatter_remover_spec.rb +21 -0
  38. data/spec/markover/markup_file_spec.rb +45 -0
  39. data/spec/markover/path_spec.rb +32 -0
  40. data/spec/markover/wkhtmltopdf_spec.rb +35 -0
  41. data/spec/spec_helper.rb +11 -0
  42. metadata +228 -0
@@ -0,0 +1,6 @@
1
+ a
2
+
3
+ @<img src="åäö.png" alt="Abcåäö" />@
4
+
5
+ b
6
+
@@ -0,0 +1,60 @@
1
+ # Test file
2
+
3
+ * A
4
+ * Simple
5
+ * List
6
+
7
+ ***
8
+
9
+ 1. A
10
+ 2. Numbered
11
+ 3. List
12
+
13
+ ## Tests
14
+
15
+ ### Link
16
+
17
+ * http://google.com
18
+ * <http://google.com>
19
+ * [an example](http://example.com/ "Title")
20
+ * [Google][]
21
+
22
+ ### Image
23
+
24
+ ![Alt text](https://www.google.se/images/srpr/logo3w.png)
25
+
26
+ ### Blockquote
27
+
28
+ > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
29
+ > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
30
+ > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
31
+ >
32
+ > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
33
+ > id sem consectetuer libero luctus adipiscing.
34
+
35
+ ### Code
36
+
37
+ ```ruby
38
+ puts 'Hello world!'
39
+ (1..10).each do |number|
40
+ p number
41
+ end
42
+ ```
43
+
44
+ ## Subheading
45
+
46
+ **Lorem** ipsum __dolor__ sit *amet*, _consectetur_ adipiscing elit. Phasellus aliquet hendrerit velit eu bibendum. Phasellus et metus at velit vulputate posuere ac a turpis. Vivamus lobortis lectus at augue pretium vel dictum enim mollis. Fusce quis urna eget urna porta vulputate. Mauris eget sapien quis orci auctor adipiscing ac vitae magna. Nulla mauris quam, convallis porta tincidunt quis, imperdiet vitae magna. Maecenas orci odio, ullamcorper et ullamcorper nec, commodo ut lacus. Morbi tortor nulla, facilisis id laoreet non, imperdiet scelerisque sapien. Cras posuere arcu mauris. Nullam ac arcu tellus, a pharetra tellus. Nulla ac odio felis, nec porttitor nisi. Mauris fringilla adipiscing urna, vel ullamcorper felis congue et. Sed sollicitudin tempor odio, vel dignissim diam facilisis et. Nam rhoncus lacinia commodo.
47
+
48
+ [Google]: http://google.com/
49
+
50
+ ## Autolink
51
+
52
+ https://github.com
53
+
54
+ ## Table
55
+
56
+ | Tables | Are | Cool |
57
+ | ------------- |:-------------:| -----:|
58
+ | col 3 is | right-aligned | $1600 |
59
+ | col 2 is | centered | $12 |
60
+ | zebra stripes | are neat | $1 |
@@ -0,0 +1,3 @@
1
+ body {
2
+ background: #f00;
3
+ }
@@ -0,0 +1,47 @@
1
+ h1. Test file
2
+
3
+ * A
4
+ * Simple
5
+ * List
6
+
7
+ ***
8
+
9
+ # A
10
+ # Numbered
11
+ # List
12
+
13
+ h2. Tests
14
+
15
+ h3. Link
16
+
17
+ * http://google.com
18
+ * "an example":http://example.com/
19
+ * Google[1]
20
+
21
+ h3. Image
22
+
23
+ !https://www.google.se/images/srpr/logo3w.png!
24
+
25
+ h3. Blockquote
26
+
27
+ bq. This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
28
+ consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
29
+ Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
30
+
31
+ bq. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
32
+ id sem consectetuer libero luctus adipiscing.
33
+
34
+ h3. Code
35
+
36
+ ```ruby
37
+ puts 'Hello world!'
38
+ (1..10).each do |number|
39
+ p number
40
+ end
41
+ ```
42
+
43
+ ## Subheading
44
+
45
+ *Lorem* ipsum -dolor- sit ~amet~, _consectetur_ adipiscing elit. Phasellus aliquet hendrerit velit eu bibendum. Phasellus et metus at velit vulputate posuere ac a turpis. Vivamus lobortis lectus at augue pretium vel dictum enim mollis. Fusce quis urna eget urna porta vulputate. Mauris eget sapien quis orci auctor adipiscing ac vitae magna. Nulla mauris quam, convallis porta tincidunt quis, imperdiet vitae magna. Maecenas orci odio, ullamcorper et ullamcorper nec, commodo ut lacus. Morbi tortor nulla, facilisis id laoreet non, imperdiet scelerisque sapien. Cras posuere arcu mauris. Nullam ac arcu tellus, a pharetra tellus. Nulla ac odio felis, nec porttitor nisi. Mauris fringilla adipiscing urna, vel ullamcorper felis congue et. Sed sollicitudin tempor odio, vel dignissim diam facilisis et. Nam rhoncus lacinia commodo.
46
+
47
+ http://google.com/[1]
@@ -0,0 +1,5 @@
1
+ # Google!
2
+ Following is a long line from `view-source:https://www.google.com/`.
3
+ ```HTML
4
+ window.google={kEI:"-YueUd_QCYLc8AS01IHgDg",getEI:function(a){for(var b;a&&(!a.getAttribute||!(b=a.getAttribute("eid")));)a=a.parentNode;return b||google.kEI},https:function(){return"https:"==window.location.protocol},kEXPI:"31215,140438,3300066,3300103,3300124,3300133,3300135,3300156,3310062,4000116,4001351,4001948,4002855,4003714,4003881,4003921,4004205,4004320,4004334,4004702,4004788,4004844,4004897,4004939,4004949,4004953,4004972,4005031,4005155,4005198,4005335,4005602,4005864,4005874,4006191,4006374,4006426,4006442,4006541,4006578,4006609,4006727,4006766,4006793,4006796,4006806,4007007,4007009,4007020,4007055,4007060,4007073,4007077,4007117,4007118,4007131,4007132,4007140,4007158,4007217,4007334",kCSI:{e:"31215,140438,3300066,3300103,3300124,3300133,3300135,3300156,3310062,4000116,4001351,4001948,4002855,4003714,4003881,4003921,4004205,4004320,4004334,4004702,4004788,4004844,4004897,4004939,4004949,4004953,4004972,4005031,4005155,4005198,4005335,4005602,4005864,4005874,4006191,4006374,4006426,4006442,4006541,4006578,4006609,4006727,4006766,4006793,4006796,4006806,4007007,4007009,4007020,4007055,4007060,4007073,4007077,4007117,4007118,4007131,4007132,4007140,4007158,4007217,4007334",ei:"-YueUd_QCYLc8AS01IHgDg"},authuser:0,ml:function(){},kHL:"en",time:function(){return(new Date).getTime()},log:function(a,b,c,h){var d=new Image,f=google.lc,e=google.li,g="";d.onerror=d.onload=
5
+ ```
@@ -0,0 +1 @@
1
+ h1. Level 1
@@ -0,0 +1,7 @@
1
+ # Table
2
+
3
+ | Tables | Are | Cool |
4
+ | ------------- |:-------------:| -----:|
5
+ | col 3 is | right-aligned | $1600 |
6
+ | col 2 is | centered | $12 |
7
+ | zebra stripes | are neat | $1 |
@@ -0,0 +1,7 @@
1
+ ---
2
+ layout: test
3
+ ---
4
+
5
+
6
+
7
+ This should be at the top of the file
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ require './spec/spec_helper'
4
+
5
+ require './lib/markover'
6
+
7
+ require 'fileutils'
8
+
9
+ describe 'Integration' do
10
+
11
+ it 'should generate files from fixtures' do
12
+ config = Markover.configure do |c|
13
+ c.file = 'spec/fixtures/integration/'
14
+ c.output_dir = 'spec/tmp'
15
+ end
16
+
17
+ Markover.process! config
18
+
19
+ ::File.exists?('spec/tmp/markdown.pdf').should be true
20
+ ::File.exists?('spec/tmp/textile.pdf').should be true
21
+ end
22
+
23
+ it 'should generate files from fixtures with aditional parameters' do
24
+ config = Markover.configure do |c|
25
+ c.file = 'spec/fixtures/integration/'
26
+ c.output_dir = 'spec/tmp/merged'
27
+ c.merge = true
28
+ c.stylesheet = 'spec/fixtures/integration/style.css'
29
+ c.output_filename = 'merged'
30
+ end
31
+
32
+ Markover.process! config
33
+
34
+ ::File.exists?('spec/tmp/merged/merged.pdf').should be true
35
+ end
36
+
37
+ after do
38
+ ::FileUtils.rm_rf 'spec/tmp'
39
+ end
40
+
41
+ end
@@ -0,0 +1,124 @@
1
+ # encoding: utf-8
2
+
3
+ require './spec/spec_helper'
4
+
5
+ require './lib/markover'
6
+
7
+ describe Markover::Converter do
8
+ it 'should give the correct output_file with none given' do
9
+ file = Markover::MarkupFile.new 'fake'
10
+ name = 'my_file'
11
+ mock(file).name { name }
12
+
13
+ converter = Markover::Converter.new [file], Markover::Config.new
14
+ mock(converter).output_dir { Dir.getwd }
15
+
16
+ converter.output_file.should == File.join(Dir.getwd, "#{name}.pdf")
17
+ end
18
+
19
+ it 'should give the correct output_file with one given' do
20
+ file = Markover::MarkupFile.new 'fake'
21
+ name = 'my_file'
22
+ mock(file).name { name }
23
+
24
+ converter = Markover::Converter.new [file], Markover::Config.new
25
+ mock(converter).output_dir { '/tmp/out' }
26
+
27
+ converter.output_file(file).should == "/tmp/out/#{name}.pdf"
28
+ end
29
+
30
+ it 'should give the correct output_file when one is set' do
31
+ file = Markover::MarkupFile.new 'fake'
32
+ output_filename = 'my_file'
33
+
34
+ config = Markover.configure do |c|
35
+ c.output_filename = output_filename
36
+ end
37
+
38
+ converter = Markover::Converter.new [file], config
39
+ mock(converter).output_dir { Dir.getwd }
40
+
41
+ converter.output_file(file).should == File.join(Dir.getwd, "#{output_filename}.pdf")
42
+ end
43
+
44
+ it 'should give the correct output_dir when none given' do
45
+ dir = Dir.getwd
46
+
47
+ file = Markover::MarkupFile.new 'fake'
48
+ converter = Markover::Converter.new file, Markover::Config.new
49
+
50
+ converter.output_dir.should == dir
51
+ end
52
+
53
+ it 'should give the correct output_dir when given' do
54
+ dir = '/tmp/out'
55
+
56
+ file = Markover::MarkupFile.new 'fake'
57
+
58
+ config = Markover.configure do |c|
59
+ c.output_dir = dir
60
+ end
61
+
62
+ converter = Markover::Converter.new file, config
63
+
64
+ mock(File).directory?(dir) { true }
65
+
66
+ converter.output_dir.should == dir
67
+ end
68
+
69
+ it 'should use default stylesheet if none given' do
70
+ file = Markover::MarkupFile.new 'fake'
71
+ converter = Markover::Converter.new file, Markover::Config.new
72
+
73
+ converter.stylesheet.should == 'markover.css'
74
+ end
75
+
76
+ it 'should use stylesheet if given' do
77
+ file = Markover::MarkupFile.new 'fake'
78
+ stylesheet = '/home/me/Markover/my-style.css'
79
+
80
+ config = Markover.configure do |c|
81
+ c.stylesheet = stylesheet
82
+ end
83
+
84
+ converter = Markover::Converter.new file, config
85
+
86
+ converter.stylesheet.should == stylesheet
87
+ end
88
+
89
+ it 'should convert relative image urls to absolute' do
90
+ file = Markover::MarkupFile.new 'fake'
91
+ filename = 'fixtures/fake.textile'
92
+ dir_string = ::File.dirname(::File.expand_path(filename))
93
+ converter = Markover::Converter.new file, Markover::Config.new
94
+
95
+ html = '<p>foo</p><img src="test.jpg" alt="" /><p>bar</p><img src="test2.jpg" alt="" />'
96
+ valid_html = "<p>foo</p><img src=\"#{File.expand_path('test.jpg', dir_string)}\" alt=\"\" /><p>bar</p><img src=\"#{File.expand_path('test2.jpg', dir_string)}\" alt=\"\" />"
97
+
98
+ converter.convert_image_urls(html, filename).should == valid_html
99
+ end
100
+
101
+ it 'should not rewrite non relative urls' do
102
+ file = Markover::MarkupFile.new 'fake'
103
+ filename = '../../fixtures/fake.textile'
104
+ dir_string = ::File.dirname(::File.expand_path(filename))
105
+ converter = Markover::Converter.new file, Markover::Config.new
106
+
107
+ html = '<p>foo</p><img src="https://d3nwyuy0nl342s.cloudfront.net/images/modules/header/logov3-hover.png" alt="" /><p>bar</p>'
108
+
109
+ converter.convert_image_urls(html, filename).should == html
110
+ end
111
+
112
+ it 'should work on both absolute and relative images' do
113
+ file = Markover::MarkupFile.new 'fake'
114
+ filename = '../../fixtures/fake.textile'
115
+ dir_string = ::File.dirname(::File.expand_path(filename))
116
+ converter = Markover::Converter.new file, Markover::Config.new
117
+
118
+ html = '<p>foo</p><img src="test.jpg" alt="" /><p>bar</p><img src="/tmp/test2.jpg" alt="" /> <img src="https://d3nwyuy0nl342s.cloudfront.net/images/modules/header/logov3-hover.png" alt="" />'
119
+ valid_html = "<p>foo</p><img src=\"#{File.expand_path('test.jpg', dir_string)}\" alt=\"\" /><p>bar</p><img src=\"/tmp/test2.jpg\" alt=\"\" /> <img src=\"https://d3nwyuy0nl342s.cloudfront.net/images/modules/header/logov3-hover.png\" alt=\"\" />"
120
+
121
+ converter.convert_image_urls(html, filename).should == valid_html
122
+ end
123
+ end
124
+
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require './spec/spec_helper'
4
+
5
+ require './lib/markover'
6
+ require './lib/markover/markup'
7
+
8
+ describe Markover::Markup::CodeBlock do
9
+
10
+ it 'should highlight code if language is supplied' do
11
+ code_block = Markover::Markup::CodeBlock.new('1', 'ruby', 'puts "hi"')
12
+ code_block.highlighted.should include('class="CodeRay"')
13
+ code_block.highlighted.should include('class="delimiter"')
14
+ end
15
+
16
+ it 'should highlight code if no language is supplied' do
17
+ code_block = Markover::Markup::CodeBlock.new('1', nil, 'puts "hi"')
18
+ code_block.highlighted.should include('class="CodeRay"')
19
+ end
20
+ end
21
+
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require './spec/spec_helper'
4
+
5
+ require './lib/markover'
6
+ require './lib/markover/markup'
7
+
8
+ describe Markover::Markup::Code do
9
+
10
+ before do
11
+ @code = Markover::Markup::Code.new
12
+ end
13
+
14
+ it 'should extract code block with language' do
15
+ language = 'ruby'
16
+ code = "\tputs 'hi'"
17
+ markup = "```#{language}\n#{code}\n```"
18
+ @code.extract(markup)
19
+ code_block = @code.instance_variable_get("@code_blocks").first
20
+ code_block.id.should eq Digest::SHA1.hexdigest(code)
21
+ code_block.language.should eq language
22
+ code_block.code.should eq code
23
+ end
24
+
25
+ it 'should extract code block without language' do
26
+ code = "\tputs 'hi'"
27
+ markup = "```\n#{code}\n```"
28
+ @code.extract(markup)
29
+ code_block = @code.instance_variable_get("@code_blocks").first
30
+ code_block.id.should eq Digest::SHA1.hexdigest(code)
31
+ code_block.language.should be nil
32
+ code_block.code.should eq code
33
+ end
34
+
35
+ it 'should process markup and give back code from id' do
36
+ language = 'ruby'
37
+ code = "\tputs 'hi'"
38
+ id = Digest::SHA1.hexdigest(code)
39
+ markup = "```#{language}\n#{code}\n```"
40
+ markup = @code.extract(markup)
41
+ code_block = @code.instance_variable_get("@code_blocks").first
42
+ @code.process(markup).should eq code_block.highlighted
43
+ end
44
+ end
45
+
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ require './spec/spec_helper'
4
+
5
+ require './lib/markover'
6
+
7
+ describe Markover::Markup::Renderer do
8
+
9
+ it "should remove yaml front matter if asked to" do
10
+ output = "<p>This should be at the top of the file</p>"
11
+
12
+ file = Markover::MarkupFile.new File.expand_path('../../../fixtures/yaml_front_matter.textile', __FILE__)
13
+ markup = Markover::Markup::Renderer.new file, true
14
+
15
+ markup.render.should == output
16
+ end
17
+ end
18
+
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require './spec/spec_helper'
4
+
5
+ require './lib/markover'
6
+ require './lib/markover/markup'
7
+
8
+ describe Markover::Markup::YamlFrontmatterRemover do
9
+
10
+ it 'should remove front matter' do
11
+ data = "---\nlayout: test\n---\n\n\nReal data"
12
+ expected = 'Real data'
13
+ Markover::Markup::YamlFrontmatterRemover.new.process(data).should == expected
14
+ end
15
+
16
+ it 'should not modify string if no front matter exists' do
17
+ data = 'Should not be modified'
18
+ Markover::Markup::YamlFrontmatterRemover.new.process(data).should == data
19
+ end
20
+ end
21
+
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require './spec/spec_helper'
4
+
5
+ require './lib/markover'
6
+
7
+ describe Markover::MarkupFile do
8
+
9
+ before do
10
+ @file = Markover::MarkupFile.new 'fake'
11
+ end
12
+
13
+ it 'should recognize valid format' do
14
+ @file.valid_format?('textile').should be_true
15
+ end
16
+
17
+ it 'should recognize invalid format' do
18
+ @file.valid_format?('abc123').should be_false
19
+ end
20
+
21
+ it 'should recognize nil as invalid format' do
22
+ @file.valid_format?(nil).should be_false
23
+ end
24
+
25
+ it 'should give the name as the filename without the extension' do
26
+ file = Markover::MarkupFile.new 'test.txt'
27
+ file.name.should == File.basename(file.filename, File.extname(file.filename))
28
+ end
29
+
30
+ it 'should know which formats that are valid' do
31
+ @file.load_format(:md).should eq :markdown
32
+ @file.load_format(:textile).should eq :textile
33
+ @file.load_format(:rdoc).should eq :rdoc
34
+ @file.load_format(:org).should eq :org
35
+ @file.load_format(:creole).should eq :creole
36
+ @file.load_format(:rst).should eq :rest
37
+ @file.load_format(:asciidoc).should eq :asciidoc
38
+ @file.load_format(:pod).should eq :pod
39
+ @file.load_format('1').should eq :roff
40
+ @file.load_format(:mediawiki).should eq :mediawiki
41
+ @file.load_format('fake').should be nil
42
+ @file.load_format(nil).should be nil
43
+ end
44
+ end
45
+