bookingit 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 175d9e2e4bc7ae8b5e306939a82fa7abaea84501
4
- data.tar.gz: 7c0b21bcb5891004f1f511acd377897090e24c9b
3
+ metadata.gz: e51a747b5a99d2461e6864e23d34a99515061a6f
4
+ data.tar.gz: f70a2eae2760cab5ad9d374de574eaad4856b5c3
5
5
  SHA512:
6
- metadata.gz: d1fb9e1d38399731774ec84c4361211fa36ae177d0f02a90662948b2ddf2590a2ff36fcc259b037a03e88dedc37292df03ab3e89417f4fab0f1b490b08eac782
7
- data.tar.gz: ab1ae505a8b1fe697929e92d7f6968761eae1478546bd7410fda1027a8817b26188d9a31e067c0c9489c55542b9d656074a3b1bd64d8eebed88d1daee9f8de19
6
+ metadata.gz: c4a10173389476b2804e9c395b0f65f94deef6e308bf630057e89e282fb89e11a01e5f96cc99aa87b94aede1a22214a9ae07c2355d2e4e685d70b50d7c37714b
7
+ data.tar.gz: eebe9e1d025aa7bc2008c2056be4c01b013ec7f6e445a2db5f40d20d9db57dafd4a522cb770044f02efb829a0b7a355973a11bf276c766aab256855ee060ac2a
data/.gitignore CHANGED
@@ -49,3 +49,4 @@ db/tmp
49
49
  spec/file-upload/stylecard-from-db.jpg
50
50
  .env
51
51
  results.html
52
+ pkg
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bookingit (0.0.1)
4
+ bookingit (0.1.0)
5
5
  gli
6
+ mustache
6
7
  redcarpet
7
8
 
8
9
  GEM
@@ -32,8 +33,12 @@ GEM
32
33
  gli (2.9.0)
33
34
  i18n (0.6.9)
34
35
  json (1.8.1)
36
+ metaclass (0.0.4)
37
+ mocha (1.0.0)
38
+ metaclass (~> 0.0.1)
35
39
  multi_json (1.8.4)
36
40
  multi_test (0.0.3)
41
+ mustache (0.99.5)
37
42
  rake (10.1.1)
38
43
  rdoc (4.1.1)
39
44
  json (~> 1.4)
@@ -48,5 +53,6 @@ DEPENDENCIES
48
53
  aruba
49
54
  bookingit!
50
55
  clean_test
56
+ mocha
51
57
  rake
52
58
  rdoc
data/README.rdoc CHANGED
@@ -1,26 +1,27 @@
1
1
  = bookingit
2
2
 
3
- A basic publishing system that takes Mardown and a Git repository and produces a readable "book" in the following forms:
3
+ A basic publishing system that takes Mardown and Git repositories and produces a readable "book" in the following forms:
4
4
 
5
5
  * Website
6
6
  * PDF
7
7
  * EBook
8
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.
9
+ The idea is that you can show the evolution of code by referencing particular versions or diffs beteween verions. Further, you can show the actual output of commands run from particular verisons of the repo.
10
+
10
11
 
11
12
  == Example
12
13
 
14
+ Let's say we have a Rails app locally in a git repo called "foobar". We coudl write the following:
13
15
 
14
16
  Here is how our controller looks currently:
15
17
 
16
- git:///path/to/repo.git/app/controlleres/users_controller.rb#initial-version
18
+ git://foobar.git/app/controlleres/users_controller.rb#initial-version
17
19
 
18
20
  We'd like to change the mailer call to use Resque
19
21
 
20
- git:///path/to/repo.git/app/controllers/users_controller.rb#initial-version..add-resque-to-controller
21
-
22
+ git://foobar.git/app/controllers/users_controller.rb#initial-version..add-resque-to-controller
22
23
 
23
- This bit of Markdown would be interpretted as if the contents were placed inline like so:
24
+ Instead of interpreting the code blocks as verbatim text, bookingit notices the single-line URL and will read the file or diff based on it, and substitute that into the output. It would be the same as if we wrote our Markdown like so:
24
25
 
25
26
  Here is how our controller looks currently:
26
27
 
@@ -52,52 +53,100 @@ This bit of Markdown would be interpretted as if the contents were placed inline
52
53
  else
53
54
  ```
54
55
 
55
- We can also insert the output of commands:
56
+ Here is what is currently supported:
56
57
 
57
- Now, let's run our tests
58
+ * <code>git://some_repo.git/path/in/repo.rb#sha1_or_tag</code> - show the contents of the file from the git repo at the given version (either SHA1 or tag)
59
+ * <code>git://some_repo.git/path/in/repo.rb#sha1_or_tag..other_sha1_or_tag</code> - show a diff of the contents of the file between the two versions.
60
+ * <code>git://some_repo.git/path/in/repo.rb#..other_sha1_or_tag</code> - shortcut for showing a diff between the given SHA1 or tag and the previous revision.
61
+ * <code>git://some_repo.git/#sha1_or_tag!rake test</code> - check out the repo at the given SHA1 or tag, then run the command after the bang, and include the output of that command in the text
62
+ * <code>sh:///some/filesystem/path#ls -l</code> - cd to the given path, run the command, and include its output in the text.
58
63
 
59
- sh:///path/to/wherever#rake test
64
+ The paths used can be relative (e.g. <code>git://some_repo.git</code>) or absolute (e.g. <code>git:///some/other/repo.git</code>). Relative paths are relative to the directory where ran +bookingit+. You can change where the git repos are located by setting +git_repos_basedir+ in your config (see below).
60
65
 
61
- This would be as if the output were inline like so:
66
+ For URLs that contain shell commands, +bookingit+ will fail if the shell command fails, because the assumption is that your embedded commands are expected to succeed (exit 0). If you need to run a shell command that is expected to fail (e.g. demonstrate a failing test case), append <code>!nonzero</code> to the URL, e.g. <code>git://some_repo.git/!rake test!nonzero</code>. In this form, +bookingit+ will fail if the command _succeeds_.
62
67
 
68
+ === Configuration
63
69
 
64
- Now, let's run our tests.
70
+ The book's configuration is driven by +config.json+, which looks like so:
65
71
 
66
- ```bash
67
- > rake test
68
- ...........................
72
+ {
73
+ "front_matter": [
74
+ "intro.md"
75
+ ],
76
+ "main_matter": [
77
+ "chapter1.md",
78
+ "chapter2.md"
79
+ ],
80
+ "back_matter": [
81
+ "appendix.md"
82
+ ],
83
+ "rendering": {
84
+ "stylesheets": "styles.css",
85
+ "git_repos_basedir": "./git_repos",
86
+ "languages" : {
87
+ ".super": "superscript",
88
+ "/Makefile": "make"
89
+ }
90
+ },
91
+ "templates": {
92
+ "index": "/full/path/to/index/html"
93
+ }
94
+ }
69
95
 
70
- Finished in 0.00946 seconds
71
- 27 examples, 0 failures
96
+ The book's contents are described in +front_matter+, +main_matter+, and +back_matter+. The values of these can be a single file or an array of files. The likely pattern is that you would have a single entry for +front_matter+, an array in +main_matter+ for each chapter, and an optional +back_matter+ for things like appendeces or a colophon.
72
97
 
73
- Randomized with seed 43200
74
- ```
98
+ Example:
99
+
100
+ {
101
+ "front_matter": "intro.md"
102
+ "main_matter": [
103
+ "chapter1.md",
104
+ "chapter2.md",
105
+ "chapter3.md",
106
+ "chapter4.md"
107
+ ],
108
+ "back_matter": "appendix.md"
109
+ }
75
110
 
76
- == TODO
77
111
 
78
- Given the above, a minimal solution would be:
112
+ The +rendering+ section allows some control over the rendering process. It supports three keys:
79
113
 
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
114
+ +git_repos_basedir+:: path to where your git repos are, for bringing in code. For example, if you specify the value "./repos", then a url like <code>git://my_repo.git/foo/bar.rb#version-1</code> would look in <code>./repos/my_repo/foo/bar.rb</code> for the file contents. This path should be relative to where you run +bookingit+.
115
+ +languages+:: A map of file extensions or regexps to language names for syntax detection. If the key starts and ends with a +/+, it will be interpreted as a regexp, otherwise as a file extension
116
+ +stylesheets+:: An array of stylesheets that will be copied and linked to each HTML page
117
+ +syntax_theme+:: A highlight.js name for the syntax highlighting theme to use.
83
118
 
84
- === Configuration
119
+ The +templates+ section allows you to specify a Mustache template for various bits of the generated markup. The files listed must be full-qualified paths and must omit the <code>.mustache</code> extension, which must be present on the file (e.g. if you specify <code>/tmp/foo.html</code>, the file should be located in <code>/tmp/foo.html.mustache</code>.
120
+
121
+ Current templates are:
122
+
123
+ +index+:: The template of the main home page or splash page. See the built-in one for values you have access to.
124
+
125
+ In addition to values provided by bookingit, you can specify any values you want in your <code>config.json</code> file and they will be available in your templates under the +config+ namespace, e.g.:
85
126
 
86
- At the bare minimum the configuration file needs to indicate a structure that maps sections to markdown files. Something like this:
87
127
 
88
128
  {
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",
129
+ "front_matter": "intro.md"
130
+ "main_matter": [
131
+ "chapter1.md",
132
+ "chapter2.md",
133
+ "chapter3.md",
134
+ "chapter4.md"
97
135
  ],
98
- back_matter: [
99
- "glossary.md"
100
- ]
136
+ "back_matter": "appendix.md",
137
+ "templates": {
138
+ "index": "/tmp/foo.html"
139
+ },
140
+ "title": "My Great Book!",
141
+ "subtitle": "A long journey from Milan to Minsk"
101
142
  }
102
143
 
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.
144
+ Then, in <code>/tmp/foo.html</code>
145
+
146
+ <html>
147
+ <body>
148
+ <h1>{{#config}}{{title}}{{/config}}</h1>
149
+ <h2>{{#config}}{{subtitle}}{{/config}}</h2>
150
+ </body>
151
+ </html>
152
+
data/TODO.md ADDED
@@ -0,0 +1,7 @@
1
+ # TODO
2
+
3
+ * Better TOC page
4
+ * Better diffs
5
+ * Ability to highlight certain lines
6
+ * Ability to show only certain lines from a file
7
+ * Able to keep going if things go wrong
data/bin/bookingit CHANGED
@@ -20,7 +20,7 @@ command :init do |c|
20
20
  {
21
21
  "front_matter": "front.md",
22
22
  "main_matter": "main.md",
23
- "back_matter": "back.md",
23
+ "back_matter": "back.md"
24
24
  }
25
25
  }
26
26
  end
@@ -38,64 +38,15 @@ command :init do |c|
38
38
  end
39
39
 
40
40
  desc 'build your book from markdown files'
41
- arg_name 'config_file output_dir'
42
41
  command :build do |c|
42
+ c.desc "Use cache for code samples and console sessions"
43
+ c.default_value true
44
+ c.switch :cache
43
45
  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
46
+ config = Bookingit::Config.new(File.read('config.json'),File.expand_path('.'))
47
+ config.cache = options[:cache]
48
+ book = Bookingit::Book.new(config)
49
+ book.render_html!
99
50
  end
100
51
  end
101
52
 
@@ -107,7 +58,17 @@ post do |global,command,options,args|
107
58
  end
108
59
 
109
60
  on_error do |exception|
110
- true
61
+ case exception
62
+ when Bookingit::UnexpectedShellCommandExit
63
+ $stderr.puts "'#{exception.command}' exited in an unexpected way with exit status #{exception.exit_code}"
64
+ $stderr.puts "stdout:"
65
+ $stderr.puts exception.stdout
66
+ $stderr.puts "stderr:"
67
+ $stderr.puts exception.stderr
68
+ false
69
+ else
70
+ true
71
+ end
111
72
  end
112
73
 
113
74
  exit run(ARGV)
data/bookingit.gemspec CHANGED
@@ -20,6 +20,8 @@ spec = Gem::Specification.new do |s|
20
20
  s.add_development_dependency('rdoc')
21
21
  s.add_development_dependency('aruba')
22
22
  s.add_development_dependency('clean_test')
23
+ s.add_development_dependency('mocha')
23
24
  s.add_runtime_dependency('gli')
24
25
  s.add_runtime_dependency('redcarpet')
26
+ s.add_runtime_dependency('mustache')
25
27
  end
@@ -10,6 +10,7 @@ Feature: App does what it's supposed to do
10
10
 
11
11
  This is the introduction
12
12
  """
13
+ And a git repo "foobar" in "repos" containing the file "blah.rb" and a tag "some-tag"
13
14
  And the file "chapter1.md" contains:
14
15
  """
15
16
  # It Begins
@@ -18,9 +19,15 @@ This is the beginning
18
19
 
19
20
  ```
20
21
  sh:///# ls
22
+ ```
23
+
24
+ And then
25
+
26
+ ```
27
+ git://foobar.git/blah.rb#some-tag
21
28
  ```
22
29
  """
23
- And the file "chapter2.1.md" contains:
30
+ And the file "chapter2.md" contains:
24
31
  """
25
32
  # The continuation
26
33
 
@@ -30,7 +37,7 @@ This is how we work
30
37
 
31
38
  Some more stuff
32
39
  """
33
- And the file "chapter2.2.md" contains:
40
+ And the file "chapter3.md" contains:
34
41
  """
35
42
  ## Some other section
36
43
 
@@ -41,41 +48,167 @@ Even more stuff
41
48
  # Glossary
42
49
 
43
50
  This is the glossary
51
+ """
52
+ And the file "styles.css" contains:
53
+ """
54
+ p, td, li {
55
+ font-family: 'Avenir';
56
+ }
44
57
  """
45
58
  And this config file:
46
59
  """
47
60
  {
61
+ "title": "OH YEAH!",
48
62
  "front_matter": [
49
63
  "intro.md"
50
64
  ],
51
65
  "main_matter": [
52
66
  "chapter1.md",
53
- "chapter2.*.md"
67
+ "chapter2.md",
68
+ "chapter3.md"
54
69
  ],
55
70
  "back_matter": [
56
71
  "appendix.md"
57
- ]
72
+ ],
73
+ "rendering": {
74
+ "stylesheets": "styles.css",
75
+ "git_repos_basedir": "repos"
76
+ }
58
77
  }
59
78
  """
60
- When I run `bookingit build config.json book`
79
+ When I run `bookingit build`
61
80
  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"
81
+ And a file named "book/styles.css" should exist
82
+ And the file "book/intro.html" should contain "This is the introduction"
83
+ And the file "book/intro.html" should contain "styles.css"
84
+ And the file "book/chapter1.html" should contain "This is the beginning"
85
+ And the file "book/chapter1.html" should contain "styles.css"
86
+ And the file "book/chapter1.html" should contain "ls"
87
+ And the file "book/chapter2.html" should contain "This is how we work"
88
+ And the file "book/chapter3.html" should contain "Even more stuff"
89
+ And the file "book/chapter3.html" should contain "styles.css"
90
+ And the file "book/appendix.html" should contain "This is the glossary"
91
+ And the file "book/appendix.html" should contain "styles.css"
92
+ And the file "book/index.html" should contain "OH YEAH"
93
+ And the file "book/index.html" should contain "intro.html"
69
94
  And the file "book/index.html" should contain "My awesome book"
70
- And the file "book/index.html" should contain "main_matter_1.html"
95
+ And the file "book/index.html" should contain "chapter1.html"
71
96
  And the file "book/index.html" should contain "It Begins"
72
- And the file "book/index.html" should contain "main_matter_2.html"
97
+ And the file "book/index.html" should contain "chapter2.html"
73
98
  And the file "book/index.html" should contain "The continuation"
74
- And the file "book/index.html" should contain "back_matter_1.html"
99
+ And the file "book/index.html" should contain "chapter3.html"
100
+ And the file "book/index.html" should contain "styles.css"
101
+ And the file "book/index.html" should contain "appendix.html"
75
102
  And the file "book/index.html" should contain "Glossary"
76
103
 
77
- @wip
78
104
  Scenario: Init a new book
79
105
  When I run `bookingit init`
80
106
  Then a file named "config.json" should exist
81
107
 
108
+ Scenario: Passes through stderr/stdout of failing commands
109
+ Given the file "intro.md" contains:
110
+ """
111
+ ```
112
+ sh:///# ls bleorgh
113
+ ```
114
+ """
115
+ And this config file:
116
+ """
117
+ {
118
+ "front_matter": [
119
+ "intro.md"
120
+ ],
121
+ "main_matter": [
122
+ "intro.md"
123
+ ],
124
+ "back_matter": [
125
+ "intro.md"
126
+ ]
127
+ }
128
+ """
129
+ When I run `bookingit build`
130
+ Then the exit status should not be 0
131
+ And the stderr should contain "ls bleorgh"
132
+ And the stderr should contain "stdout:"
133
+ And the stderr should contain "stderr:"
134
+
135
+ Scenario: Use my own template
136
+ Given the file "intro.md" contains:
137
+ """
138
+ # My awesome book
139
+
140
+ This is the introduction
141
+ """
142
+ And the file "chapter1.md" contains:
143
+ """
144
+ # It Begins
145
+
146
+ This is the beginning
147
+
148
+ """
149
+ And the file "/tmp/my_index.html.mustache" contains:
150
+ """
151
+ <HTML>
152
+ <BODY>
153
+ <CENTER>
154
+ {{#config}}
155
+ <H1><FONT NAME='comic sans'>{{ title }}</FONT></H1>
156
+ <H2>{{ frob }}</H2>
157
+ {{/config}}
158
+ </CENTER>
159
+ </BODY>
160
+ </HTML>
161
+ """
162
+ And this config file:
163
+ """
164
+ {
165
+ "title": "OH YEAH!",
166
+ "frob": "nosticate",
167
+ "front_matter": [
168
+ "intro.md"
169
+ ],
170
+ "main_matter": [
171
+ "chapter1.md"
172
+ ],
173
+ "templates": {
174
+ "index": "/tmp/my_index.html"
175
+ }
176
+ }
177
+ """
178
+ When I run `bookingit build`
179
+ Then the exit status should be 0
180
+ And the file "book/intro.html" should contain "This is the introduction"
181
+ And the file "book/chapter1.html" should contain "This is the beginning"
182
+ And the file "book/index.html" should contain "OH YEAH"
183
+ And the file "book/index.html" should contain "nosticate"
184
+
185
+ Scenario: Init a new book
186
+ When I run `bookingit init`
187
+ Then a file named "config.json" should exist
188
+
189
+ Scenario: Passes through stderr/stdout of failing commands
190
+ Given the file "intro.md" contains:
191
+ """
192
+ ```
193
+ sh:///# ls bleorgh
194
+ ```
195
+ """
196
+ And this config file:
197
+ """
198
+ {
199
+ "front_matter": [
200
+ "intro.md"
201
+ ],
202
+ "main_matter": [
203
+ "intro.md"
204
+ ],
205
+ "back_matter": [
206
+ "intro.md"
207
+ ]
208
+ }
209
+ """
210
+ When I run `bookingit build`
211
+ Then the exit status should not be 0
212
+ And the stderr should contain "ls bleorgh"
213
+ And the stderr should contain "stdout:"
214
+ And the stderr should contain "stderr:"