marksman 0.0.0 → 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +23 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +7 -0
  6. data/Guardfile +7 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +80 -0
  9. data/Rakefile +14 -0
  10. data/bin/marksman +8 -0
  11. data/lib/marksman.rb +13 -0
  12. data/lib/marksman/cli.rb +29 -0
  13. data/lib/marksman/converter.rb +50 -0
  14. data/lib/marksman/equality.rb +15 -0
  15. data/lib/marksman/parser.rb +55 -0
  16. data/lib/marksman/presentation.rb +26 -0
  17. data/lib/marksman/slide.rb +12 -0
  18. data/lib/marksman/theme.rb +21 -0
  19. data/lib/marksman/version.rb +3 -0
  20. data/lib/marksman/watcher.rb +47 -0
  21. data/lib/marksman/writer.rb +18 -0
  22. data/marksman.gemspec +32 -0
  23. data/spec/data/example.md +11 -0
  24. data/spec/data/example_without_metadata.md +7 -0
  25. data/spec/data/output/index.html +44 -0
  26. data/spec/marksman/cli_spec.rb +26 -0
  27. data/spec/marksman/converter_spec.rb +40 -0
  28. data/spec/marksman/parser_spec.rb +64 -0
  29. data/spec/marksman/presentation_spec.rb +25 -0
  30. data/spec/marksman/slide_spec.rb +17 -0
  31. data/spec/marksman/theme_spec.rb +29 -0
  32. data/spec/marksman/watcher_spec.rb +45 -0
  33. data/spec/marksman/writer_spec.rb +15 -0
  34. data/spec/spec_helper.rb +12 -0
  35. data/themes/blank/css/blank.css +5 -0
  36. data/themes/blank/css/tomorrow-night.css +93 -0
  37. data/themes/blank/index.haml +21 -0
  38. data/themes/blank/js/highlight.min.js +1 -0
  39. data/themes/plain/css/default.css +42 -0
  40. data/themes/plain/css/github.css +125 -0
  41. data/themes/plain/css/tomorrow-night.css +93 -0
  42. data/themes/plain/css/tomorrow.css +90 -0
  43. data/themes/plain/index.haml +18 -0
  44. data/themes/plain/js/highlight.min.js +1 -0
  45. metadata +210 -14
@@ -0,0 +1,18 @@
1
+ module Marksman
2
+ class Writer
3
+
4
+ def initialize(file, output_directory, theme = nil)
5
+ @file = file
6
+ @output_directory = output_directory
7
+ @theme = theme
8
+ end
9
+
10
+ def generate
11
+ presentation = Marksman::Parser.new.parse(@file)
12
+ presentation.theme = Theme.new(@theme) if @theme
13
+ Marksman::Converter.new(presentation).write(@output_directory)
14
+ presentation
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'marksman/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "marksman"
8
+ spec.version = Marksman::VERSION
9
+ spec.authors = ["Bodo Tasche"]
10
+ spec.email = ["bodo@wannawork.de"]
11
+ spec.summary = %q{A opinionated presentation software}
12
+ spec.description = %q{Write slides in markdown and create beautifull presentation within minutes.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "redcarpet", "~> 3.1.1"
22
+ spec.add_dependency "haml", "~> 4.0.5"
23
+ spec.add_dependency "thor", "~> 0.19.1"
24
+ spec.add_dependency "listen", "~> 2.7.1"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.5"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "pry"
29
+ spec.add_development_dependency "rspec"
30
+ spec.add_development_dependency "guard"
31
+ spec.add_development_dependency "guard-rspec"
32
+ end
@@ -0,0 +1,11 @@
1
+ ---
2
+ example: true
3
+ title: "This is an example presentation"
4
+ ---
5
+ First Page
6
+ ----------
7
+ Second Page
8
+ ******
9
+ Author comment
10
+ ----------
11
+ Third Page
@@ -0,0 +1,7 @@
1
+ First Page
2
+ ----------
3
+ Second Page
4
+ ******
5
+ Author comment
6
+ ----------
7
+ Third Page
@@ -0,0 +1,44 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>This is an example presentation</title>
5
+ <link href='css/default.css' rel='stylesheet'>
6
+ <link href='css/tomorrow-night.css' rel='stylesheet'>
7
+ <script src='js/highlight.min.js'></script>
8
+ <script>
9
+ hljs.initHighlightingOnLoad();
10
+ </script>
11
+ </head>
12
+ <body>
13
+ <section>
14
+ <div>
15
+ <div class='slide'>
16
+ <p>First Page</p>
17
+ </div>
18
+ <div class='note'>
19
+
20
+ </div>
21
+ </div>
22
+ </section>
23
+ <section>
24
+ <div>
25
+ <div class='slide'>
26
+ <p>Second Page</p>
27
+ </div>
28
+ <div class='note'>
29
+ <p>Author comment</p>
30
+ </div>
31
+ </div>
32
+ </section>
33
+ <section>
34
+ <div>
35
+ <div class='slide'>
36
+ <p>Third Page</p>
37
+ </div>
38
+ <div class='note'>
39
+
40
+ </div>
41
+ </div>
42
+ </section>
43
+ </body>
44
+ </html>
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Marksman::CLI do
4
+
5
+ context 'generate' do
6
+
7
+ it 'should call writer' do
8
+ writer = double(Marksman::Writer)
9
+ expect(Marksman::Writer).to receive(:new).with('spec/data/example.md', 'output', nil).and_return(writer)
10
+ expect(writer).to receive(:generate)
11
+ subject.generate('spec/data/example.md', 'output')
12
+ end
13
+
14
+ end
15
+
16
+ context 'watch' do
17
+
18
+ it 'should call watch' do
19
+ writer = double(Marksman::Watcher)
20
+ expect(Marksman::Watcher).to receive(:new).with('spec/data/example.md', 'output', nil).and_return(writer)
21
+ expect(writer).to receive(:watch)
22
+ subject.watch('spec/data/example.md', 'output')
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Marksman::Converter do
4
+
5
+ before do
6
+ @test_dir = Dir.mktmpdir
7
+ end
8
+
9
+ after do
10
+ FileUtils.rm_r @test_dir
11
+ end
12
+
13
+ subject do
14
+ presentation = Marksman::Parser.new.parse('spec/data/example.md')
15
+ Marksman::Converter.new(presentation)
16
+ end
17
+
18
+ it "should generate all the files" do
19
+ subject.write(@test_dir)
20
+ expect(
21
+ temp_file("index.html")
22
+ ).to eq(File.read('spec/data/output/index.html'))
23
+ compare_directory('themes/plain/css', 'css')
24
+ compare_directory('themes/plain/js', 'js')
25
+ end
26
+
27
+ def compare_directory(source, target)
28
+ Dir.glob(Pathname.new(source).join('**').join('*')).each do |f|
29
+ name = f.to_s[(source.length + 1)..-1]
30
+ source_content = File.read(Pathname.new(source).join(name))
31
+ target_content = File.read(Pathname.new(@test_dir).join(target).join(name))
32
+ expect(target_content).to eq(source_content)
33
+ end
34
+ end
35
+
36
+ def temp_file(file)
37
+ File.read(Pathname.new(@test_dir).join(file))
38
+ end
39
+
40
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe Marksman::Parser do
4
+
5
+ it 'should parse a file with meta data' do
6
+ presentation = Marksman::Parser.new.parse('spec/data/example.md')
7
+ expect(presentation.title).to eq('This is an example presentation')
8
+ expect(presentation.slides).to eq([
9
+ Marksman::Slide.new({
10
+ slide: '<p>First Page</p>',
11
+ notes: ''
12
+ }),
13
+ Marksman::Slide.new({
14
+ slide: '<p>Second Page</p>',
15
+ notes: '<p>Author comment</p>'
16
+ }),
17
+ Marksman::Slide.new({
18
+ slide: '<p>Third Page</p>',
19
+ notes: ''
20
+ })
21
+ ])
22
+
23
+ expect(presentation.filename).to eq('example.md')
24
+ expect(presentation.theme).to eq(Marksman::Theme.new('plain'))
25
+ expect(presentation.metadata).to eq({
26
+ example: true,
27
+ filename: 'example.md',
28
+ theme: 'plain',
29
+ title: 'This is an example presentation'
30
+ })
31
+ end
32
+
33
+ it 'should parse a file without meta data' do
34
+ presentation = Marksman::Parser.new.parse('spec/data/example_without_metadata.md')
35
+ expect(presentation.title).to eq('example_without_metadata.md')
36
+ expect(presentation.slides).to eq([
37
+ Marksman::Slide.new({
38
+ slide: '<p>First Page</p>',
39
+ notes: ''
40
+ }),
41
+ Marksman::Slide.new({
42
+ slide: '<p>Second Page</p>',
43
+ notes: '<p>Author comment</p>'
44
+ }),
45
+ Marksman::Slide.new({
46
+ slide: '<p>Third Page</p>',
47
+ notes: ''
48
+ })
49
+ ])
50
+
51
+ expect(presentation.filename).to eq('example_without_metadata.md')
52
+ expect(presentation.theme).to eq(Marksman::Theme.new('plain'))
53
+ expect(presentation.metadata).to eq({
54
+ filename: 'example_without_metadata.md',
55
+ theme: 'plain',
56
+ title: 'example_without_metadata.md'
57
+ })
58
+ end
59
+
60
+ it 'should throw an exception if the file was not there' do
61
+ expect{Marksman::Parser.new.parse('spec/data/example-not-existing.md')}.to raise_error
62
+ end
63
+
64
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Marksman::Presentation do
4
+
5
+ context 'equality' do
6
+
7
+ it 'should return true if presentation is equal' do
8
+ expect(Marksman::Presentation.new({filename: 'example.md'})).to eq(Marksman::Presentation.new({filename: 'example.md'}))
9
+ end
10
+
11
+ it 'should return false if the presentation is not equal' do
12
+ expect(Marksman::Presentation.new({filename: 'example.md'})).not_to eq(Marksman::Presentation.new({}))
13
+ end
14
+
15
+ end
16
+
17
+ context 'title' do
18
+
19
+ it 'should return the title' do
20
+ expect(Marksman::Presentation.new({metadata: {title: 'Example Title'}}).title).to eq('Example Title')
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Marksman::Slide do
4
+
5
+ context 'equality' do
6
+
7
+ it 'should return true if slide is equal' do
8
+ expect(Marksman::Slide.new({slide: 'Slide'})).to eq(Marksman::Slide.new({slide: 'Slide'}))
9
+ end
10
+
11
+ it 'should return false if the slide is not equal' do
12
+ expect(Marksman::Slide.new({slide: 'Slide'})).not_to eq(Marksman::Slide.new({}))
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Marksman::Theme do
4
+
5
+ context 'equality' do
6
+
7
+ it 'should return true if theme is equal' do
8
+ expect(Marksman::Theme.new('example')).to eq(Marksman::Theme.new('example'))
9
+ end
10
+
11
+ it 'should return false if the theme is not equal' do
12
+ expect(Marksman::Theme.new('example')).not_to eq(Marksman::Theme.new('another_example'))
13
+ end
14
+
15
+ end
16
+
17
+ context 'path' do
18
+
19
+ it 'should expect the theme in the gem folder if not found in current one' do
20
+ expect(Marksman::Theme.new('plain').path).to eq(Pathname.new('themes/plain').realpath)
21
+ end
22
+
23
+ it 'should expect the theme in the current folder if a directory with the same name was found' do
24
+ expect(Marksman::Theme.new('spec').path).to eq(Pathname.new('spec'))
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+ require 'tmpdir'
4
+
5
+ describe Marksman::Watcher do
6
+
7
+ before do
8
+ @test_dir = Dir.mktmpdir
9
+ @markdown_file = Pathname.new(@test_dir).join('example.md')
10
+ @theme_dir = Pathname.new(@test_dir).join('plain')
11
+ FileUtils.copy 'spec/data/example.md', @markdown_file
12
+ FileUtils.cp_r 'themes/plain', @test_dir
13
+ end
14
+
15
+ after do
16
+ FileUtils.rm_r @test_dir
17
+ end
18
+
19
+ subject do
20
+ converter = double(Marksman::Converter)
21
+ expect(Marksman::Converter).to receive(:new).with(anything).and_return(converter).exactly(2).times
22
+ expect(converter).to receive(:write).exactly(2).times
23
+
24
+ Marksman::Watcher.new(@markdown_file, 'output', @theme_dir)
25
+ end
26
+
27
+ it 'should monitor changes on the markdown file' do
28
+ expect(subject).to receive(:sleep)
29
+ subject.watch
30
+ sleep 1
31
+ File.write(@markdown_file, 'more example text')
32
+ sleep 1
33
+ subject.stop
34
+ end
35
+
36
+ it 'should monitor changes on the theme files' do
37
+ expect(subject).to receive(:sleep)
38
+ subject.watch
39
+ sleep 1
40
+ File.write(@theme_dir.join('index.haml'), 'haml')
41
+ sleep 1
42
+ subject.stop
43
+ end
44
+
45
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Marksman::Writer do
4
+
5
+ it 'should call write on the converter' do
6
+ converter = double(Marksman::Converter)
7
+ presentation = Marksman::Parser.new.parse('spec/data/example.md')
8
+
9
+ expect(Marksman::Converter).to receive(:new).with(presentation).and_return(converter)
10
+ expect(converter).to receive(:write).with('output')
11
+
12
+ Marksman::Writer.new('spec/data/example.md', 'output').generate
13
+ end
14
+
15
+ end
@@ -0,0 +1,12 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ require 'marksman'
5
+
6
+ RSpec.configure do |config|
7
+ # Run specs in random order to surface order dependencies. If you find an
8
+ # order dependency and want to debug it, you can fix the order by providing
9
+ # the seed, which is printed after each run.
10
+ # --seed 1234
11
+ config.order = 'random'
12
+ end
@@ -0,0 +1,5 @@
1
+
2
+ header, section {
3
+ max-width: 720px;
4
+ margin: 20px auto;
5
+ }
@@ -0,0 +1,93 @@
1
+ /* Tomorrow Night Theme */
2
+ /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
3
+ /* Original theme - https://github.com/chriskempson/tomorrow-theme */
4
+ /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
5
+
6
+ /* Tomorrow Comment */
7
+ .hljs-comment,
8
+ .hljs-title {
9
+ color: #969896;
10
+ }
11
+
12
+ /* Tomorrow Red */
13
+ .hljs-variable,
14
+ .hljs-attribute,
15
+ .hljs-tag,
16
+ .hljs-regexp,
17
+ .ruby .hljs-constant,
18
+ .xml .hljs-tag .hljs-title,
19
+ .xml .hljs-pi,
20
+ .xml .hljs-doctype,
21
+ .html .hljs-doctype,
22
+ .css .hljs-id,
23
+ .css .hljs-class,
24
+ .css .hljs-pseudo {
25
+ color: #cc6666;
26
+ }
27
+
28
+ /* Tomorrow Orange */
29
+ .hljs-number,
30
+ .hljs-preprocessor,
31
+ .hljs-pragma,
32
+ .hljs-built_in,
33
+ .hljs-literal,
34
+ .hljs-params,
35
+ .hljs-constant {
36
+ color: #de935f;
37
+ }
38
+
39
+ /* Tomorrow Yellow */
40
+ .ruby .hljs-class .hljs-title,
41
+ .css .hljs-rules .hljs-attribute {
42
+ color: #f0c674;
43
+ }
44
+
45
+ /* Tomorrow Green */
46
+ .hljs-string,
47
+ .hljs-value,
48
+ .hljs-inheritance,
49
+ .hljs-header,
50
+ .ruby .hljs-symbol,
51
+ .xml .hljs-cdata {
52
+ color: #b5bd68;
53
+ }
54
+
55
+ /* Tomorrow Aqua */
56
+ .css .hljs-hexcolor {
57
+ color: #8abeb7;
58
+ }
59
+
60
+ /* Tomorrow Blue */
61
+ .hljs-function,
62
+ .python .hljs-decorator,
63
+ .python .hljs-title,
64
+ .ruby .hljs-function .hljs-title,
65
+ .ruby .hljs-title .hljs-keyword,
66
+ .perl .hljs-sub,
67
+ .javascript .hljs-title,
68
+ .coffeescript .hljs-title {
69
+ color: #81a2be;
70
+ }
71
+
72
+ /* Tomorrow Purple */
73
+ .hljs-keyword,
74
+ .javascript .hljs-function {
75
+ color: #b294bb;
76
+ }
77
+
78
+ .hljs {
79
+ display: block;
80
+ background: #1d1f21;
81
+ color: #c5c8c6;
82
+ padding: 0.5em;
83
+ }
84
+
85
+ .coffeescript .javascript,
86
+ .javascript .xml,
87
+ .tex .hljs-formula,
88
+ .xml .javascript,
89
+ .xml .vbscript,
90
+ .xml .css,
91
+ .xml .hljs-cdata {
92
+ opacity: 0.5;
93
+ }