bookingit 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +51 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +52 -0
- data/README.rdoc +103 -0
- data/Rakefile +48 -0
- data/bin/bookingit +113 -0
- data/bookingit.gemspec +25 -0
- data/features/bookingit.feature +81 -0
- data/features/step_definitions/bookinggit_steps.rb +26 -0
- data/features/support/env.rb +19 -0
- data/lib/bookingit.rb +3 -0
- data/lib/bookingit/config.rb +56 -0
- data/lib/bookingit/renderer.rb +68 -0
- data/lib/bookingit/version.rb +3 -0
- data/test/config_test.rb +119 -0
- data/test/renderer_test.rb +269 -0
- data/test/test_helper.rb +14 -0
- metadata +159 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 175d9e2e4bc7ae8b5e306939a82fa7abaea84501
|
|
4
|
+
data.tar.gz: 7c0b21bcb5891004f1f511acd377897090e24c9b
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d1fb9e1d38399731774ec84c4361211fa36ae177d0f02a90662948b2ddf2590a2ff36fcc259b037a03e88dedc37292df03ab3e89417f4fab0f1b490b08eac782
|
|
7
|
+
data.tar.gz: ab1ae505a8b1fe697929e92d7f6968761eae1478546bd7410fda1027a8817b26188d9a31e067c0c9489c55542b9d656074a3b1bd64d8eebed88d1daee9f8de19
|
data/.gitignore
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
|
|
2
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
|
3
|
+
#
|
|
4
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
|
5
|
+
# or operating system, you probably want to add a global ignore instead:
|
|
6
|
+
# git config --global core.excludesfile ~/.gitignore_global
|
|
7
|
+
|
|
8
|
+
# Ignore bundler config
|
|
9
|
+
/.bundle
|
|
10
|
+
|
|
11
|
+
# Ignore the default SQLite database.
|
|
12
|
+
/db/*.sqlite3
|
|
13
|
+
|
|
14
|
+
# Ignore all logfiles and tempfiles.
|
|
15
|
+
/log/*.log
|
|
16
|
+
/tmp
|
|
17
|
+
# vim
|
|
18
|
+
*.sw?
|
|
19
|
+
*.rbc
|
|
20
|
+
*.sassc
|
|
21
|
+
.sass-cache
|
|
22
|
+
capybara-*.html
|
|
23
|
+
.rspec
|
|
24
|
+
/vendor/bundle
|
|
25
|
+
/public/system/*
|
|
26
|
+
/coverage/
|
|
27
|
+
/spec/tmp/*
|
|
28
|
+
**.orig
|
|
29
|
+
rerun.txt
|
|
30
|
+
pickle-email-*.html
|
|
31
|
+
|
|
32
|
+
.rvmrc
|
|
33
|
+
.rbenv-version
|
|
34
|
+
|
|
35
|
+
config/database.yml
|
|
36
|
+
|
|
37
|
+
.idea/*
|
|
38
|
+
|
|
39
|
+
.DS_Store
|
|
40
|
+
# Emacs
|
|
41
|
+
.\#*
|
|
42
|
+
*~
|
|
43
|
+
\#*
|
|
44
|
+
|
|
45
|
+
.vimrc
|
|
46
|
+
.jhw-cache
|
|
47
|
+
.tddium*
|
|
48
|
+
db/tmp
|
|
49
|
+
spec/file-upload/stylecard-from-db.jpg
|
|
50
|
+
.env
|
|
51
|
+
results.html
|
data/.ruby-gemset
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bookingit
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.1.0
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
bookingit (0.0.1)
|
|
5
|
+
gli
|
|
6
|
+
redcarpet
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: https://rubygems.org/
|
|
10
|
+
specs:
|
|
11
|
+
aruba (0.5.4)
|
|
12
|
+
childprocess (>= 0.3.6)
|
|
13
|
+
cucumber (>= 1.1.1)
|
|
14
|
+
rspec-expectations (>= 2.7.0)
|
|
15
|
+
builder (3.2.2)
|
|
16
|
+
childprocess (0.5.1)
|
|
17
|
+
ffi (~> 1.0, >= 1.0.11)
|
|
18
|
+
clean_test (1.0.0)
|
|
19
|
+
faker
|
|
20
|
+
cucumber (1.3.11)
|
|
21
|
+
builder (>= 2.1.2)
|
|
22
|
+
diff-lcs (>= 1.1.3)
|
|
23
|
+
gherkin (~> 2.12)
|
|
24
|
+
multi_json (>= 1.7.5, < 2.0)
|
|
25
|
+
multi_test (>= 0.0.2)
|
|
26
|
+
diff-lcs (1.2.5)
|
|
27
|
+
faker (1.2.0)
|
|
28
|
+
i18n (~> 0.5)
|
|
29
|
+
ffi (1.9.3)
|
|
30
|
+
gherkin (2.12.2)
|
|
31
|
+
multi_json (~> 1.3)
|
|
32
|
+
gli (2.9.0)
|
|
33
|
+
i18n (0.6.9)
|
|
34
|
+
json (1.8.1)
|
|
35
|
+
multi_json (1.8.4)
|
|
36
|
+
multi_test (0.0.3)
|
|
37
|
+
rake (10.1.1)
|
|
38
|
+
rdoc (4.1.1)
|
|
39
|
+
json (~> 1.4)
|
|
40
|
+
redcarpet (3.1.1)
|
|
41
|
+
rspec-expectations (2.14.5)
|
|
42
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
|
43
|
+
|
|
44
|
+
PLATFORMS
|
|
45
|
+
ruby
|
|
46
|
+
|
|
47
|
+
DEPENDENCIES
|
|
48
|
+
aruba
|
|
49
|
+
bookingit!
|
|
50
|
+
clean_test
|
|
51
|
+
rake
|
|
52
|
+
rdoc
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
= bookingit
|
|
2
|
+
|
|
3
|
+
A basic publishing system that takes Mardown and a Git repository and produces a readable "book" in the following forms:
|
|
4
|
+
|
|
5
|
+
* Website
|
|
6
|
+
* PDF
|
|
7
|
+
* EBook
|
|
8
|
+
|
|
9
|
+
The idea is to easily show the evolution of code over the course of the book, based entirely on git diffs and pull requests.
|
|
10
|
+
|
|
11
|
+
== Example
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Here is how our controller looks currently:
|
|
15
|
+
|
|
16
|
+
git:///path/to/repo.git/app/controlleres/users_controller.rb#initial-version
|
|
17
|
+
|
|
18
|
+
We'd like to change the mailer call to use Resque
|
|
19
|
+
|
|
20
|
+
git:///path/to/repo.git/app/controllers/users_controller.rb#initial-version..add-resque-to-controller
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
This bit of Markdown would be interpretted as if the contents were placed inline like so:
|
|
24
|
+
|
|
25
|
+
Here is how our controller looks currently:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
class UsersController < ApplicationController::Base
|
|
29
|
+
def create
|
|
30
|
+
@user = User.new(params.require(:user))
|
|
31
|
+
if @user.save
|
|
32
|
+
UserMailer.welcome_email(user).deliver
|
|
33
|
+
redirect_to root_path
|
|
34
|
+
else
|
|
35
|
+
render 'new'
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
We'd like to change the mailer call to use Resque
|
|
42
|
+
|
|
43
|
+
```diff
|
|
44
|
+
--- a/app/controllers/users_controller.rb
|
|
45
|
+
+++ b/app/controllers/users_controller.rb
|
|
46
|
+
def create
|
|
47
|
+
@user = User.new(params.require(:user))
|
|
48
|
+
if @user.save
|
|
49
|
+
- UserMailer.welcome_email(user).deliver
|
|
50
|
+
+ Resque.enqueue(WelcomeEmailJob,user.id)
|
|
51
|
+
redirect_to root_path
|
|
52
|
+
else
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
We can also insert the output of commands:
|
|
56
|
+
|
|
57
|
+
Now, let's run our tests
|
|
58
|
+
|
|
59
|
+
sh:///path/to/wherever#rake test
|
|
60
|
+
|
|
61
|
+
This would be as if the output were inline like so:
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
Now, let's run our tests.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
> rake test
|
|
68
|
+
...........................
|
|
69
|
+
|
|
70
|
+
Finished in 0.00946 seconds
|
|
71
|
+
27 examples, 0 failures
|
|
72
|
+
|
|
73
|
+
Randomized with seed 43200
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
== TODO
|
|
77
|
+
|
|
78
|
+
Given the above, a minimal solution would be:
|
|
79
|
+
|
|
80
|
+
* Given some markdown files
|
|
81
|
+
* And a configuration file
|
|
82
|
+
* Be able to generate a multi-page HTML5 website with a table of contents
|
|
83
|
+
|
|
84
|
+
=== Configuration
|
|
85
|
+
|
|
86
|
+
At the bare minimum the configuration file needs to indicate a structure that maps sections to markdown files. Something like this:
|
|
87
|
+
|
|
88
|
+
{
|
|
89
|
+
front_matter: [
|
|
90
|
+
"acknowledgements.md",
|
|
91
|
+
"intro.md"
|
|
92
|
+
],
|
|
93
|
+
main_matter: [
|
|
94
|
+
"getting_started.md",
|
|
95
|
+
["our_first_controller.md","our_first_model.md","running_tests.md"],
|
|
96
|
+
"chapter3*.md",
|
|
97
|
+
],
|
|
98
|
+
back_matter: [
|
|
99
|
+
"glossary.md"
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
We have front, main, and back matter. Inside each we can provide a list of files the be used in order, that represent "chapters" in that section. A chapter can be specified either as a single file, a list of files that are subsections, or a glob. No markup is added, this just specifies the order of processing and how to make the TOC.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'rake/clean'
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
require 'rubygems/package_task'
|
|
4
|
+
require 'rdoc/task'
|
|
5
|
+
require 'cucumber'
|
|
6
|
+
require 'cucumber/rake/task'
|
|
7
|
+
require 'bundler'
|
|
8
|
+
|
|
9
|
+
Bundler::GemHelper.install_tasks
|
|
10
|
+
|
|
11
|
+
Rake::RDocTask.new do |rd|
|
|
12
|
+
rd.main = "README.rdoc"
|
|
13
|
+
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
|
14
|
+
rd.title = 'Your application title'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
spec = eval(File.read('bookingit.gemspec'))
|
|
18
|
+
|
|
19
|
+
Gem::PackageTask.new(spec) do |pkg|
|
|
20
|
+
end
|
|
21
|
+
CUKE_RESULTS = 'results.html'
|
|
22
|
+
CLEAN << CUKE_RESULTS
|
|
23
|
+
desc 'Run features'
|
|
24
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
|
25
|
+
opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
|
|
26
|
+
opts += " --tags #{ENV['TAGS']}" if ENV['TAGS']
|
|
27
|
+
t.cucumber_opts = opts
|
|
28
|
+
t.fork = false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
desc 'Run features tagged as work-in-progress (@wip)'
|
|
32
|
+
Cucumber::Rake::Task.new('features:wip') do |t|
|
|
33
|
+
tag_opts = ' --tags ~@pending'
|
|
34
|
+
tag_opts = ' --tags @wip'
|
|
35
|
+
t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}"
|
|
36
|
+
t.fork = false
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
task :cucumber => :features
|
|
40
|
+
task 'cucumber:wip' => 'features:wip'
|
|
41
|
+
task :wip => 'features:wip'
|
|
42
|
+
require 'rake/testtask'
|
|
43
|
+
Rake::TestTask.new do |t|
|
|
44
|
+
t.libs << "test"
|
|
45
|
+
t.test_files = FileList['test/*_test.rb']
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
task :default => [:test,:features]
|
data/bin/bookingit
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'gli'
|
|
3
|
+
require 'bookingit'
|
|
4
|
+
|
|
5
|
+
include GLI::App
|
|
6
|
+
include FileUtils
|
|
7
|
+
|
|
8
|
+
program_desc 'Manage a bookingit book'
|
|
9
|
+
|
|
10
|
+
version Bookingit::VERSION
|
|
11
|
+
|
|
12
|
+
desc 'Set up a new book'
|
|
13
|
+
arg_name 'dir (defaults to .)'
|
|
14
|
+
command :init do |c|
|
|
15
|
+
c.action do |global_options,options,args|
|
|
16
|
+
dir = args.shift || "."
|
|
17
|
+
chdir dir do
|
|
18
|
+
File.open('config.json','w') do |file|
|
|
19
|
+
file.puts %{
|
|
20
|
+
{
|
|
21
|
+
"front_matter": "front.md",
|
|
22
|
+
"main_matter": "main.md",
|
|
23
|
+
"back_matter": "back.md",
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
File.open("front.md",'w') do |file|
|
|
28
|
+
file.puts "# Intro Goes Here"
|
|
29
|
+
end
|
|
30
|
+
File.open("main.md",'w') do |file|
|
|
31
|
+
file.puts "# Main stuff here"
|
|
32
|
+
end
|
|
33
|
+
File.open("back.md",'w') do |file|
|
|
34
|
+
file.puts "# Appendeces and whatnot"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
desc 'build your book from markdown files'
|
|
41
|
+
arg_name 'config_file output_dir'
|
|
42
|
+
command :build do |c|
|
|
43
|
+
c.action do |global_options,options,args|
|
|
44
|
+
puts pwd
|
|
45
|
+
config = Bookingit::Config.new(File.read(args.shift),File.expand_path('.'))
|
|
46
|
+
output_dir = args.shift
|
|
47
|
+
mkdir output_dir unless Dir.exists?(output_dir)
|
|
48
|
+
|
|
49
|
+
renderer = Bookingit::Renderer.new
|
|
50
|
+
redcarpet = Redcarpet::Markdown.new(renderer, no_intra_emphasis: true,
|
|
51
|
+
tables: true,
|
|
52
|
+
fenced_code_blocks: true,
|
|
53
|
+
autolink: true,
|
|
54
|
+
strikethrough: true,
|
|
55
|
+
superscript: true)
|
|
56
|
+
|
|
57
|
+
chdir output_dir do
|
|
58
|
+
File.open('index.html','w') do |index|
|
|
59
|
+
index.puts %{<!DOCTYPE html>
|
|
60
|
+
<html>
|
|
61
|
+
<head>
|
|
62
|
+
</head>
|
|
63
|
+
<body>
|
|
64
|
+
}
|
|
65
|
+
index.puts "<ol>"
|
|
66
|
+
%w(front_matter main_matter back_matter).each do |matter|
|
|
67
|
+
index.puts "<li>#{matter}<ol>"
|
|
68
|
+
config.send(matter).chapters.each_with_index do |chapter,i|
|
|
69
|
+
contents = if chapter.path.nil?
|
|
70
|
+
chapter.sections.map(&:path).map { |path|
|
|
71
|
+
File.read(path)
|
|
72
|
+
}.join("\n")
|
|
73
|
+
else
|
|
74
|
+
File.read(chapter.path)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
output_file = "#{matter}_#{i+1}.html"
|
|
78
|
+
File.open(output_file,'w') do |file|
|
|
79
|
+
file.puts redcarpet.render(contents)
|
|
80
|
+
end
|
|
81
|
+
title = (Array(renderer.headers[1]) +
|
|
82
|
+
Array(renderer.headers[2]) +
|
|
83
|
+
Array(renderer.headers[3]) +
|
|
84
|
+
Array(renderer.headers[4]) +
|
|
85
|
+
Array(renderer.headers[5]) +
|
|
86
|
+
Array(renderer.headers[6])).first
|
|
87
|
+
index.puts "<li><a href='#{output_file}'>#{title}</a></li>"
|
|
88
|
+
end
|
|
89
|
+
index.puts "</ol></li>"
|
|
90
|
+
end
|
|
91
|
+
index.puts "</ol>"
|
|
92
|
+
index.puts %{
|
|
93
|
+
|
|
94
|
+
</body>
|
|
95
|
+
</html>
|
|
96
|
+
}
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
pre do |global,command,options,args|
|
|
103
|
+
true
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
post do |global,command,options,args|
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
on_error do |exception|
|
|
110
|
+
true
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
exit run(ARGV)
|
data/bookingit.gemspec
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Ensure we require the local version and not one we might have installed already
|
|
2
|
+
require File.join([File.dirname(__FILE__),'lib','bookingit','version.rb'])
|
|
3
|
+
spec = Gem::Specification.new do |s|
|
|
4
|
+
s.name = 'bookingit'
|
|
5
|
+
s.version = Bookingit::VERSION
|
|
6
|
+
s.author = 'Dave Copeland'
|
|
7
|
+
s.email = 'davetron5000@gmail.com'
|
|
8
|
+
s.homepage = 'http://www.naildrivin5.com'
|
|
9
|
+
s.platform = Gem::Platform::RUBY
|
|
10
|
+
s.summary = 'Write a code-heavy book in Markdown'
|
|
11
|
+
# Add your other files here if you make them
|
|
12
|
+
s.require_paths << 'lib'
|
|
13
|
+
s.has_rdoc = true
|
|
14
|
+
s.extra_rdoc_files = ['README.rdoc']
|
|
15
|
+
s.rdoc_options << '--title' << 'bookingit' << '--main' << 'README.rdoc' << '-ri'
|
|
16
|
+
s.files = `git ls-files`.split("\n")
|
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
19
|
+
s.add_development_dependency('rake')
|
|
20
|
+
s.add_development_dependency('rdoc')
|
|
21
|
+
s.add_development_dependency('aruba')
|
|
22
|
+
s.add_development_dependency('clean_test')
|
|
23
|
+
s.add_runtime_dependency('gli')
|
|
24
|
+
s.add_runtime_dependency('redcarpet')
|
|
25
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Feature: App does what it's supposed to do
|
|
2
|
+
In order to build a kickass website
|
|
3
|
+
I want to use bookingit to translate markdown
|
|
4
|
+
and all that
|
|
5
|
+
|
|
6
|
+
Scenario: App works
|
|
7
|
+
Given the file "intro.md" contains:
|
|
8
|
+
"""
|
|
9
|
+
# My awesome book
|
|
10
|
+
|
|
11
|
+
This is the introduction
|
|
12
|
+
"""
|
|
13
|
+
And the file "chapter1.md" contains:
|
|
14
|
+
"""
|
|
15
|
+
# It Begins
|
|
16
|
+
|
|
17
|
+
This is the beginning
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
sh:///# ls
|
|
21
|
+
```
|
|
22
|
+
"""
|
|
23
|
+
And the file "chapter2.1.md" contains:
|
|
24
|
+
"""
|
|
25
|
+
# The continuation
|
|
26
|
+
|
|
27
|
+
This is how we work
|
|
28
|
+
|
|
29
|
+
## Some section
|
|
30
|
+
|
|
31
|
+
Some more stuff
|
|
32
|
+
"""
|
|
33
|
+
And the file "chapter2.2.md" contains:
|
|
34
|
+
"""
|
|
35
|
+
## Some other section
|
|
36
|
+
|
|
37
|
+
Even more stuff
|
|
38
|
+
"""
|
|
39
|
+
And the file "appendix.md" contains:
|
|
40
|
+
"""
|
|
41
|
+
# Glossary
|
|
42
|
+
|
|
43
|
+
This is the glossary
|
|
44
|
+
"""
|
|
45
|
+
And this config file:
|
|
46
|
+
"""
|
|
47
|
+
{
|
|
48
|
+
"front_matter": [
|
|
49
|
+
"intro.md"
|
|
50
|
+
],
|
|
51
|
+
"main_matter": [
|
|
52
|
+
"chapter1.md",
|
|
53
|
+
"chapter2.*.md"
|
|
54
|
+
],
|
|
55
|
+
"back_matter": [
|
|
56
|
+
"appendix.md"
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
"""
|
|
60
|
+
When I run `bookingit build config.json book`
|
|
61
|
+
Then the exit status should be 0
|
|
62
|
+
And the file "book/front_matter_1.html" should contain "This is the introduction"
|
|
63
|
+
And the file "book/main_matter_1.html" should contain "This is the beginning"
|
|
64
|
+
And the file "book/main_matter_1.html" should contain "ls"
|
|
65
|
+
And the file "book/main_matter_2.html" should contain "This is how we work"
|
|
66
|
+
And the file "book/main_matter_2.html" should contain "Even more stuff"
|
|
67
|
+
And the file "book/back_matter_1.html" should contain "This is the glossary"
|
|
68
|
+
And the file "book/index.html" should contain "front_matter_1.html"
|
|
69
|
+
And the file "book/index.html" should contain "My awesome book"
|
|
70
|
+
And the file "book/index.html" should contain "main_matter_1.html"
|
|
71
|
+
And the file "book/index.html" should contain "It Begins"
|
|
72
|
+
And the file "book/index.html" should contain "main_matter_2.html"
|
|
73
|
+
And the file "book/index.html" should contain "The continuation"
|
|
74
|
+
And the file "book/index.html" should contain "back_matter_1.html"
|
|
75
|
+
And the file "book/index.html" should contain "Glossary"
|
|
76
|
+
|
|
77
|
+
@wip
|
|
78
|
+
Scenario: Init a new book
|
|
79
|
+
When I run `bookingit init`
|
|
80
|
+
Then a file named "config.json" should exist
|
|
81
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'tempfile'
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
|
|
4
|
+
When /^I get help for "([^"]*)"$/ do |app_name|
|
|
5
|
+
@app_name = app_name
|
|
6
|
+
step %(I run `#{app_name} help`)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
Given(/^the file "(.*?)" contains:$/) do |filename, contents|
|
|
10
|
+
FileUtils.chdir "tmp/aruba" do
|
|
11
|
+
@files_created << filename
|
|
12
|
+
File.open(filename,'w') do |file|
|
|
13
|
+
file.puts contents
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Given(/^this config file:$/) do |string|
|
|
19
|
+
FileUtils.chdir "tmp/aruba" do
|
|
20
|
+
@files_created << "config.json"
|
|
21
|
+
File.open("config.json",'w') do |file|
|
|
22
|
+
file.puts string
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'aruba/cucumber'
|
|
2
|
+
|
|
3
|
+
ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
|
4
|
+
LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
|
|
5
|
+
|
|
6
|
+
Before do
|
|
7
|
+
# Using "announce" causes massive warnings on 1.9.2
|
|
8
|
+
@puts = true
|
|
9
|
+
@original_rubylib = ENV['RUBYLIB']
|
|
10
|
+
@files_created = []
|
|
11
|
+
ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
After do
|
|
15
|
+
ENV['RUBYLIB'] = @original_rubylib
|
|
16
|
+
@files_created.each do |file|
|
|
17
|
+
FileUtils.rm file
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/bookingit.rb
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
module Bookingit
|
|
5
|
+
class Config
|
|
6
|
+
include FileUtils
|
|
7
|
+
|
|
8
|
+
attr_reader :front_matter,
|
|
9
|
+
:main_matter,
|
|
10
|
+
:back_matter
|
|
11
|
+
|
|
12
|
+
def initialize(config_json,root_dir)
|
|
13
|
+
config_hash = JSON.parse(config_json)
|
|
14
|
+
|
|
15
|
+
@front_matter = Matter.new(config_hash['front_matter'],root_dir)
|
|
16
|
+
@main_matter = Matter.new(config_hash['main_matter'],root_dir)
|
|
17
|
+
@back_matter = Matter.new(config_hash['back_matter'],root_dir)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class Matter
|
|
21
|
+
attr_reader :chapters
|
|
22
|
+
def initialize(chapters_config,root_dir)
|
|
23
|
+
@chapters = Array(chapters_config).map { |chapter_config|
|
|
24
|
+
Chapter.new(chapter_config,root_dir)
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class Chapter
|
|
30
|
+
attr_reader :sections
|
|
31
|
+
attr_reader :path
|
|
32
|
+
|
|
33
|
+
def initialize(chapter_config,root_dir)
|
|
34
|
+
files = Array(chapter_config).flatten(1).map { |file|
|
|
35
|
+
Dir[File.join(root_dir,file)]
|
|
36
|
+
}.flatten
|
|
37
|
+
if files.size == 1
|
|
38
|
+
@sections = []
|
|
39
|
+
@path = files[0]
|
|
40
|
+
else
|
|
41
|
+
@sections = files.map { |file|
|
|
42
|
+
Section.new(file)
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class Section
|
|
49
|
+
attr_reader :path
|
|
50
|
+
def initialize(path)
|
|
51
|
+
@path = path
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require 'redcarpet'
|
|
2
|
+
require 'cgi'
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
module Bookingit
|
|
6
|
+
class Renderer < Redcarpet::Render::HTML
|
|
7
|
+
include FileUtils
|
|
8
|
+
|
|
9
|
+
attr_accessor :headers
|
|
10
|
+
def header(text,header_level,anchor)
|
|
11
|
+
@headers[header_level] ||= []
|
|
12
|
+
@headers[header_level] << text
|
|
13
|
+
"<h#{header_level}>#{text}</h#{header_level}>"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def doc_header
|
|
17
|
+
@headers = {}
|
|
18
|
+
""
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
EXTENSION_TO_LANGUAGE = {
|
|
22
|
+
'.rb' => 'ruby',
|
|
23
|
+
'.html' => 'html',
|
|
24
|
+
'.scala' => 'scala',
|
|
25
|
+
}
|
|
26
|
+
def block_code(code, language)
|
|
27
|
+
if code.strip =~ /file:\/\/(.*)$/
|
|
28
|
+
path = $1
|
|
29
|
+
code = File.read(path)
|
|
30
|
+
language = EXTENSION_TO_LANGUAGE.fetch(File.extname(path))
|
|
31
|
+
elsif code.strip =~ /git:\/\/(.*)$/
|
|
32
|
+
path = $1
|
|
33
|
+
if path =~ /(^.*).git\/(.*)#([^#]+)$/
|
|
34
|
+
repo_path = $1
|
|
35
|
+
path_in_repo = $2
|
|
36
|
+
reference = $3
|
|
37
|
+
chdir repo_path do
|
|
38
|
+
if reference =~ /^(.+)\.\.(.+)$/
|
|
39
|
+
code = `git diff #{reference}`
|
|
40
|
+
language = 'diff'
|
|
41
|
+
else
|
|
42
|
+
`git checkout #{reference} 2>&1`
|
|
43
|
+
code = File.read(path_in_repo)
|
|
44
|
+
`git checkout master 2>&1`
|
|
45
|
+
language = EXTENSION_TO_LANGUAGE.fetch(File.extname(path_in_repo))
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
raise "You must provide a SHA1 or tagname: #{path}"
|
|
50
|
+
end
|
|
51
|
+
elsif code.strip =~ /sh:\/\/(.+)#([^#]+)$/
|
|
52
|
+
path = $1
|
|
53
|
+
command = $2
|
|
54
|
+
chdir path do
|
|
55
|
+
output = `#{command}`
|
|
56
|
+
code = "> #{command}\n#{output}"
|
|
57
|
+
language = 'shell'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
css_class = if language.nil? || language.strip == ''
|
|
61
|
+
""
|
|
62
|
+
else
|
|
63
|
+
" class=\"language-#{language}\""
|
|
64
|
+
end
|
|
65
|
+
%{<pre><code#{css_class}>#{CGI.escapeHTML(code)}</code></pre>}
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
data/test/config_test.rb
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'tempfile'
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
class Bookingit::ConfigTest < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
def setup
|
|
9
|
+
@tempdir = Dir.mktmpdir
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def teardown
|
|
13
|
+
remove_entry @tempdir
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test_that "wraps single files in arrays" do
|
|
17
|
+
Given :some_markdown_files
|
|
18
|
+
And {
|
|
19
|
+
@config = {
|
|
20
|
+
front_matter: "foo.md",
|
|
21
|
+
main_matter: "bar.md",
|
|
22
|
+
back_matter: "baz.md",
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
When {
|
|
26
|
+
@normalized_config = Bookingit::Config.new(@config.to_json,@tempdir)
|
|
27
|
+
}
|
|
28
|
+
Then {
|
|
29
|
+
assert_equal 1,@normalized_config.front_matter.chapters.size
|
|
30
|
+
assert_equal File.join(@tempdir,'foo.md'),@normalized_config.front_matter.chapters[0].path
|
|
31
|
+
assert_equal 1,@normalized_config.main_matter.chapters.size
|
|
32
|
+
assert_equal File.join(@tempdir,'bar.md'),@normalized_config.main_matter.chapters[0].path
|
|
33
|
+
assert_equal 0,@normalized_config.main_matter.chapters[0].sections.size
|
|
34
|
+
assert_equal 1,@normalized_config.back_matter.chapters.size
|
|
35
|
+
assert_equal File.join(@tempdir,'baz.md'),@normalized_config.back_matter.chapters[0].path
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
test_that "does nothing to arrays" do
|
|
40
|
+
Given :some_markdown_files
|
|
41
|
+
And {
|
|
42
|
+
@config = {
|
|
43
|
+
front_matter: ["foo.md"],
|
|
44
|
+
main_matter: ["bar.md"],
|
|
45
|
+
back_matter: ["baz.md"],
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
When {
|
|
49
|
+
@normalized_config = Bookingit::Config.new(@config.to_json,@tempdir)
|
|
50
|
+
}
|
|
51
|
+
Then {
|
|
52
|
+
assert_equal 1,@normalized_config.front_matter.chapters.size
|
|
53
|
+
assert_equal File.join(@tempdir,'foo.md'),@normalized_config.front_matter.chapters[0].path
|
|
54
|
+
assert_equal 1,@normalized_config.main_matter.chapters.size
|
|
55
|
+
assert_equal File.join(@tempdir,'bar.md'),@normalized_config.main_matter.chapters[0].path
|
|
56
|
+
assert_equal 0,@normalized_config.main_matter.chapters[0].sections.size
|
|
57
|
+
assert_equal 1,@normalized_config.back_matter.chapters.size
|
|
58
|
+
assert_equal File.join(@tempdir,'baz.md'),@normalized_config.back_matter.chapters[0].path
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
test_that "parses sections" do
|
|
63
|
+
Given :some_markdown_files
|
|
64
|
+
And {
|
|
65
|
+
@config = {
|
|
66
|
+
front_matter: ["foo.md"],
|
|
67
|
+
main_matter: [
|
|
68
|
+
"bar.md",
|
|
69
|
+
["blah1.md","blah2.md"],
|
|
70
|
+
],
|
|
71
|
+
back_matter: ["baz.md"],
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
When {
|
|
75
|
+
@normalized_config = Bookingit::Config.new(@config.to_json,@tempdir)
|
|
76
|
+
}
|
|
77
|
+
Then {
|
|
78
|
+
assert_equal 2,@normalized_config.main_matter.chapters.size,"chapters"
|
|
79
|
+
assert_equal 2,@normalized_config.main_matter.chapters[1].sections.size,"sections"
|
|
80
|
+
}
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
test_that "globs" do
|
|
84
|
+
Given :some_markdown_files
|
|
85
|
+
And {
|
|
86
|
+
@config = {
|
|
87
|
+
front_matter: ["foo.md"],
|
|
88
|
+
main_matter: [
|
|
89
|
+
"bar.md",
|
|
90
|
+
"blah*.md",
|
|
91
|
+
],
|
|
92
|
+
back_matter: ["baz.md"],
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
When {
|
|
96
|
+
@normalized_config = Bookingit::Config.new(@config.to_json,@tempdir)
|
|
97
|
+
}
|
|
98
|
+
Then {
|
|
99
|
+
assert_equal 2,@normalized_config.main_matter.chapters.size
|
|
100
|
+
assert_equal 3,@normalized_config.main_matter.chapters[1].sections.size
|
|
101
|
+
assert_equal File.join(@tempdir,'blah1.md'),@normalized_config.main_matter.chapters[1].sections[0].path
|
|
102
|
+
assert_equal File.join(@tempdir,'blah2.md'),@normalized_config.main_matter.chapters[1].sections[1].path
|
|
103
|
+
assert_equal File.join(@tempdir,'blah3.md'),@normalized_config.main_matter.chapters[1].sections[2].path
|
|
104
|
+
}
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def some_markdown_files
|
|
110
|
+
chdir @tempdir do
|
|
111
|
+
system "touch foo.md"
|
|
112
|
+
system "touch baz.md"
|
|
113
|
+
system "touch bar.md"
|
|
114
|
+
system "touch blah1.md"
|
|
115
|
+
system "touch blah2.md"
|
|
116
|
+
system "touch blah3.md"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'tempfile'
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
include FileUtils
|
|
6
|
+
|
|
7
|
+
class RendererTest < Test::Unit::TestCase
|
|
8
|
+
|
|
9
|
+
def setup
|
|
10
|
+
@tempdir = Dir.mktmpdir
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def teardown
|
|
14
|
+
remove_entry @tempdir
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test_that "block_code can read a file URL and guess ruby" do
|
|
18
|
+
Given a_file_with_extension(".rb")
|
|
19
|
+
When render_file_url_code_block
|
|
20
|
+
Then {
|
|
21
|
+
assert_equal %{<pre><code class="language-ruby">#{@code}</code></pre>},@html
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test_that "block_code can read a file URL and guess scala" do
|
|
26
|
+
Given a_file_with_extension(".scala")
|
|
27
|
+
When render_file_url_code_block
|
|
28
|
+
Then {
|
|
29
|
+
assert_equal %{<pre><code class="language-scala">#{@code}</code></pre>},@html
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
test_that "it HTML-escapes" do
|
|
34
|
+
Given a_file_with_extension_and_contents('.html',%{<!DOCTYPE html>
|
|
35
|
+
<html>
|
|
36
|
+
<body>
|
|
37
|
+
<h1>HELLO!</h1>
|
|
38
|
+
<h2>& Goodbye</h2>
|
|
39
|
+
</body>
|
|
40
|
+
</html>
|
|
41
|
+
})
|
|
42
|
+
When render_file_url_code_block
|
|
43
|
+
Then {
|
|
44
|
+
assert_equal %{<pre><code class="language-html"><!DOCTYPE html>
|
|
45
|
+
<html>
|
|
46
|
+
<body>
|
|
47
|
+
<h1>HELLO!</h1>
|
|
48
|
+
<h2>&amp; Goodbye</h2>
|
|
49
|
+
</body>
|
|
50
|
+
</html>
|
|
51
|
+
</code></pre>},@html
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
test_that "a git url without a SHA1 or tag raises" do
|
|
56
|
+
Given a_git_repo_with_file("foo.rb")
|
|
57
|
+
When {
|
|
58
|
+
@code = -> {
|
|
59
|
+
Bookingit::Renderer.new.block_code(@file_git_url,nil)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
Then {
|
|
63
|
+
assert_raises RuntimeError,&@code
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
test_that "a git url with a SHA1 gets that version" do
|
|
68
|
+
Given a_git_repo_with_two_verions_of_file("foo.rb")
|
|
69
|
+
When {
|
|
70
|
+
@parsed_versions = Hash[@versions.map { |sha1,_|
|
|
71
|
+
[sha1, Bookingit::Renderer.new.block_code(@file_git_url + "##{sha1}",nil)]
|
|
72
|
+
}]
|
|
73
|
+
}
|
|
74
|
+
Then {
|
|
75
|
+
@parsed_versions.each do |sha1,code|
|
|
76
|
+
assert_equal %{<pre><code class="language-ruby">#{@versions[sha1]}\n</code></pre>},code,"For SHA: #{sha1}"
|
|
77
|
+
end
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
test_that "a git url with a tag gets that version" do
|
|
82
|
+
Given a_git_repo_with_two_tagged_verions_of_file("foo.rb")
|
|
83
|
+
When {
|
|
84
|
+
@parsed_versions = Hash[@versions.map { |tagname,_|
|
|
85
|
+
[tagname, Bookingit::Renderer.new.block_code(@file_git_url + "##{tagname}",nil)]
|
|
86
|
+
}]
|
|
87
|
+
}
|
|
88
|
+
Then {
|
|
89
|
+
@parsed_versions.each do |tagname,code|
|
|
90
|
+
assert_equal %{<pre><code class="language-ruby">#{@versions[tagname]}\n</code></pre>},code,"For Tag: #{tagname}"
|
|
91
|
+
end
|
|
92
|
+
}
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
test_that "a git url with a diff spec shows the diff instead" do
|
|
96
|
+
Given a_git_repo_with_two_tagged_verions_of_file("foo.rb")
|
|
97
|
+
When {
|
|
98
|
+
url = @file_git_url + "#" + @versions.keys[0] + ".." + @versions.keys[1]
|
|
99
|
+
@html = Bookingit::Renderer.new.block_code(url,nil)
|
|
100
|
+
}
|
|
101
|
+
Then {
|
|
102
|
+
assert_match /<pre><code class=\"language-diff\">diff --git/,@html
|
|
103
|
+
assert_match /a\/foo.rb b\/foo.rb/,@html
|
|
104
|
+
assert_match /index [a-z0-9]+..[a-z0-9]+ 100644/,@html
|
|
105
|
+
assert_match /\-\-\- a\/foo.rb/,@html
|
|
106
|
+
assert_match /\+\+\+ b\/foo.rb/,@html
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
test_that "an sh url will run the given command and put the contents into the output" do
|
|
111
|
+
Given {
|
|
112
|
+
chdir @tempdir do
|
|
113
|
+
mkdir "play"
|
|
114
|
+
chdir "play" do
|
|
115
|
+
system "touch blah"
|
|
116
|
+
system "touch bar"
|
|
117
|
+
system "touch quux"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
}
|
|
121
|
+
When {
|
|
122
|
+
@html = Bookingit::Renderer.new.block_code("sh://#{@tempdir}/play#ls -1",nil)
|
|
123
|
+
}
|
|
124
|
+
Then {
|
|
125
|
+
assert_equal %{<pre><code class="language-shell">> ls -1
|
|
126
|
+
bar
|
|
127
|
+
blah
|
|
128
|
+
quux
|
|
129
|
+
</code></pre>},@html
|
|
130
|
+
}
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
test_that "we pass through inline code blocks" do
|
|
134
|
+
When {
|
|
135
|
+
@html = Bookingit::Renderer.new.block_code("class Foo", 'coffeescript')
|
|
136
|
+
}
|
|
137
|
+
Then {
|
|
138
|
+
assert_equal %{<pre><code class="language-coffeescript">class Foo</code></pre>},@html
|
|
139
|
+
}
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
test_that "we omit the language class if it's not provided in inline code" do
|
|
143
|
+
When {
|
|
144
|
+
@html = Bookingit::Renderer.new.block_code("class Foo", nil)
|
|
145
|
+
}
|
|
146
|
+
Then {
|
|
147
|
+
assert_equal %{<pre><code>class Foo</code></pre>},@html
|
|
148
|
+
}
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
private
|
|
152
|
+
|
|
153
|
+
def create_and_commit_file(file,contents)
|
|
154
|
+
File.open(file,'w') do |file|
|
|
155
|
+
file.puts contents
|
|
156
|
+
end
|
|
157
|
+
system "git add . #{devnull}"
|
|
158
|
+
system "git commit -m \"new file\" #{devnull}"
|
|
159
|
+
`git rev-parse HEAD`.chomp
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def a_git_repo_with_two_verions_of_file(file)
|
|
163
|
+
-> {
|
|
164
|
+
@versions = {}
|
|
165
|
+
git_repo_in_tempdir do
|
|
166
|
+
code = %{class Foo
|
|
167
|
+
def initialize
|
|
168
|
+
end
|
|
169
|
+
end}
|
|
170
|
+
2.times {
|
|
171
|
+
@versions[create_and_commit_file(file,code)] = code
|
|
172
|
+
|
|
173
|
+
code = %{class Foo
|
|
174
|
+
def initialize
|
|
175
|
+
@added = true
|
|
176
|
+
end
|
|
177
|
+
end}
|
|
178
|
+
}
|
|
179
|
+
create_and_commit_file(file,code)
|
|
180
|
+
# make sure test doesn't get the HEAD version
|
|
181
|
+
end
|
|
182
|
+
@file_git_url = "git://#{File.join(@tempdir,'git_repo.git')}/#{file}"
|
|
183
|
+
}
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def a_git_repo_with_two_tagged_verions_of_file(file)
|
|
187
|
+
-> {
|
|
188
|
+
@versions = {}
|
|
189
|
+
git_repo_in_tempdir do
|
|
190
|
+
code = %{class Foo
|
|
191
|
+
def initialize
|
|
192
|
+
end
|
|
193
|
+
end}
|
|
194
|
+
2.times { |index|
|
|
195
|
+
create_and_commit_file(file,code)
|
|
196
|
+
tag = "tag-#{index}"
|
|
197
|
+
system "git tag #{tag} #{devnull}"
|
|
198
|
+
|
|
199
|
+
@versions[tag] = code
|
|
200
|
+
|
|
201
|
+
code = %{class Foo
|
|
202
|
+
def initialize
|
|
203
|
+
@added = true
|
|
204
|
+
end
|
|
205
|
+
end}
|
|
206
|
+
}
|
|
207
|
+
create_and_commit_file(file,code)
|
|
208
|
+
# make sure test doesn't get the HEAD version
|
|
209
|
+
end
|
|
210
|
+
@file_git_url = "git://#{File.join(@tempdir,'git_repo.git')}/#{file}"
|
|
211
|
+
}
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def git_repo_in_tempdir(&block)
|
|
215
|
+
chdir @tempdir do
|
|
216
|
+
mkdir 'git_repo'
|
|
217
|
+
chdir 'git_repo' do
|
|
218
|
+
system "git init #{devnull}"
|
|
219
|
+
system "git add . #{devnull}"
|
|
220
|
+
system "git commit -m \"initial commit\" #{devnull}"
|
|
221
|
+
block.()
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def a_git_repo_with_file(file)
|
|
227
|
+
-> {
|
|
228
|
+
git_repo_in_tempdir do
|
|
229
|
+
@code = %{class Foo
|
|
230
|
+
def initialize
|
|
231
|
+
end
|
|
232
|
+
end}
|
|
233
|
+
create_and_commit_file(file,@code)
|
|
234
|
+
end
|
|
235
|
+
@file_git_url = "git://#{File.join(@tempdir,'git_repo.git')}/#{file}"
|
|
236
|
+
}
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def render_file_url_code_block
|
|
240
|
+
-> {
|
|
241
|
+
@html = Bookingit::Renderer.new.block_code("file://#{@path}",nil)
|
|
242
|
+
}
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def a_file_with_extension_and_contents(extension,contents)
|
|
246
|
+
-> {
|
|
247
|
+
file = Tempfile.new(['foo',extension])
|
|
248
|
+
@path = file.path
|
|
249
|
+
@code = contents
|
|
250
|
+
File.open(@path,'w') do |file|
|
|
251
|
+
file.puts @code
|
|
252
|
+
end
|
|
253
|
+
}
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def a_file_with_extension(extension)
|
|
257
|
+
a_file_with_extension_and_contents(extension,%{class SomeCode
|
|
258
|
+
def initialize(ohyeah)
|
|
259
|
+
@oh yeah = ohyeah
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
})
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def devnull
|
|
266
|
+
return "" if ENV['DEBUG']
|
|
267
|
+
" 2>&1 > /dev/null"
|
|
268
|
+
end
|
|
269
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'clean_test/test_case'
|
|
3
|
+
require 'bookingit'
|
|
4
|
+
|
|
5
|
+
# Add test libraries you want to use here, e.g. mocha
|
|
6
|
+
|
|
7
|
+
class Test::Unit::TestCase
|
|
8
|
+
include Clean::Test::GivenWhenThen
|
|
9
|
+
include Clean::Test::TestThat
|
|
10
|
+
include Clean::Test::Any
|
|
11
|
+
|
|
12
|
+
# Add global extensions to the test case class here
|
|
13
|
+
|
|
14
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bookingit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Dave Copeland
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-03-03 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rake
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rdoc
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: aruba
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: clean_test
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: gli
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: redcarpet
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
description:
|
|
98
|
+
email: davetron5000@gmail.com
|
|
99
|
+
executables:
|
|
100
|
+
- bookingit
|
|
101
|
+
extensions: []
|
|
102
|
+
extra_rdoc_files:
|
|
103
|
+
- README.rdoc
|
|
104
|
+
files:
|
|
105
|
+
- ".gitignore"
|
|
106
|
+
- ".ruby-gemset"
|
|
107
|
+
- ".ruby-version"
|
|
108
|
+
- Gemfile
|
|
109
|
+
- Gemfile.lock
|
|
110
|
+
- README.rdoc
|
|
111
|
+
- Rakefile
|
|
112
|
+
- bin/bookingit
|
|
113
|
+
- bookingit.gemspec
|
|
114
|
+
- features/bookingit.feature
|
|
115
|
+
- features/step_definitions/bookinggit_steps.rb
|
|
116
|
+
- features/support/env.rb
|
|
117
|
+
- lib/bookingit.rb
|
|
118
|
+
- lib/bookingit/config.rb
|
|
119
|
+
- lib/bookingit/renderer.rb
|
|
120
|
+
- lib/bookingit/version.rb
|
|
121
|
+
- test/config_test.rb
|
|
122
|
+
- test/renderer_test.rb
|
|
123
|
+
- test/test_helper.rb
|
|
124
|
+
homepage: http://www.naildrivin5.com
|
|
125
|
+
licenses: []
|
|
126
|
+
metadata: {}
|
|
127
|
+
post_install_message:
|
|
128
|
+
rdoc_options:
|
|
129
|
+
- "--title"
|
|
130
|
+
- bookingit
|
|
131
|
+
- "--main"
|
|
132
|
+
- README.rdoc
|
|
133
|
+
- "-ri"
|
|
134
|
+
require_paths:
|
|
135
|
+
- lib
|
|
136
|
+
- lib
|
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
138
|
+
requirements:
|
|
139
|
+
- - ">="
|
|
140
|
+
- !ruby/object:Gem::Version
|
|
141
|
+
version: '0'
|
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
|
+
requirements:
|
|
144
|
+
- - ">="
|
|
145
|
+
- !ruby/object:Gem::Version
|
|
146
|
+
version: '0'
|
|
147
|
+
requirements: []
|
|
148
|
+
rubyforge_project:
|
|
149
|
+
rubygems_version: 2.2.0.rc.1
|
|
150
|
+
signing_key:
|
|
151
|
+
specification_version: 4
|
|
152
|
+
summary: Write a code-heavy book in Markdown
|
|
153
|
+
test_files:
|
|
154
|
+
- features/bookingit.feature
|
|
155
|
+
- features/step_definitions/bookinggit_steps.rb
|
|
156
|
+
- features/support/env.rb
|
|
157
|
+
- test/config_test.rb
|
|
158
|
+
- test/renderer_test.rb
|
|
159
|
+
- test/test_helper.rb
|