burr 0.0.2
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 +3 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/LICENSE.md +30 -0
- data/README.md +180 -0
- data/Rakefile +118 -0
- data/bin/burr +9 -0
- data/burr.gemspec +36 -0
- data/generators/Gemfile.txt +3 -0
- data/generators/config.yml +55 -0
- data/generators/contents/chapter1.md +7 -0
- data/generators/contents/chapter2.md +7 -0
- data/generators/stylesheets/pdf.css +569 -0
- data/generators/stylesheets/site.css +1 -0
- data/lib/burr.rb +56 -0
- data/lib/burr/book.rb +289 -0
- data/lib/burr/cli.rb +64 -0
- data/lib/burr/converter.rb +19 -0
- data/lib/burr/core_ext/blank.rb +107 -0
- data/lib/burr/dependency.rb +28 -0
- data/lib/burr/eeepub_ext/maker.rb +131 -0
- data/lib/burr/exporter.rb +137 -0
- data/lib/burr/exporters/epub.rb +163 -0
- data/lib/burr/exporters/pdf.rb +95 -0
- data/lib/burr/exporters/site.rb +101 -0
- data/lib/burr/generator.rb +41 -0
- data/lib/burr/kramdown_ext/converter.rb +145 -0
- data/lib/burr/kramdown_ext/options.rb +38 -0
- data/lib/burr/kramdown_ext/parser.rb +65 -0
- data/lib/burr/liquid_ext/block.rb +58 -0
- data/lib/burr/liquid_ext/extends.rb +114 -0
- data/lib/burr/plugin.rb +70 -0
- data/lib/burr/plugins/aside.rb +44 -0
- data/lib/burr/plugins/codeblock.rb +42 -0
- data/lib/burr/plugins/figure.rb +62 -0
- data/lib/burr/plugins/link.rb +47 -0
- data/lib/burr/plugins/parser_plugin.rb +18 -0
- data/lib/burr/plugins/table.rb +42 -0
- data/lib/burr/plugins/toc.rb +105 -0
- data/lib/burr/ruby_version_check.rb +4 -0
- data/lib/burr/server.rb +27 -0
- data/lib/burr/ui.rb +46 -0
- data/lib/burr/version.rb +8 -0
- data/resources/locales/labels/en.yml +45 -0
- data/resources/locales/labels/zh_CN.yml +46 -0
- data/resources/locales/titles/en.yml +21 -0
- data/resources/locales/titles/zh_CN.yml +21 -0
- data/resources/templates/epub/_layout.liquid +17 -0
- data/resources/templates/epub/acknowledgement.liquid +10 -0
- data/resources/templates/epub/afterword.liquid +10 -0
- data/resources/templates/epub/appendix.liquid +10 -0
- data/resources/templates/epub/author.liquid +10 -0
- data/resources/templates/epub/chapter.liquid +10 -0
- data/resources/templates/epub/conclusion.liquid +10 -0
- data/resources/templates/epub/cover.liquid +9 -0
- data/resources/templates/epub/dedication.liquid +10 -0
- data/resources/templates/epub/edition.liquid +1 -0
- data/resources/templates/epub/epilogue.liquid +1 -0
- data/resources/templates/epub/foreword.liquid +10 -0
- data/resources/templates/epub/glossary.liquid +1 -0
- data/resources/templates/epub/introduction.liquid +1 -0
- data/resources/templates/epub/license.liquid +1 -0
- data/resources/templates/epub/lof.liquid +24 -0
- data/resources/templates/epub/lot.liquid +24 -0
- data/resources/templates/epub/part.liquid +4 -0
- data/resources/templates/epub/preface.liquid +10 -0
- data/resources/templates/epub/prologue.liquid +1 -0
- data/resources/templates/epub/table.liquid +7 -0
- data/resources/templates/epub/title.liquid +3 -0
- data/resources/templates/epub/toc.liquid +10 -0
- data/resources/templates/pdf/_item.liquid +6 -0
- data/resources/templates/pdf/acknowledgement.liquid +1 -0
- data/resources/templates/pdf/afterword.liquid +1 -0
- data/resources/templates/pdf/appendix.liquid +4 -0
- data/resources/templates/pdf/author.liquid +1 -0
- data/resources/templates/pdf/blank.liquid +3 -0
- data/resources/templates/pdf/book.liquid +42 -0
- data/resources/templates/pdf/chapter.liquid +4 -0
- data/resources/templates/pdf/code.liquid +3 -0
- data/resources/templates/pdf/conclusion.liquid +1 -0
- data/resources/templates/pdf/cover.liquid +6 -0
- data/resources/templates/pdf/dedication.liquid +3 -0
- data/resources/templates/pdf/edition.liquid +1 -0
- data/resources/templates/pdf/epilogue.liquid +1 -0
- data/resources/templates/pdf/foreword.liquid +1 -0
- data/resources/templates/pdf/glossary.liquid +1 -0
- data/resources/templates/pdf/introduction.liquid +1 -0
- data/resources/templates/pdf/license.liquid +1 -0
- data/resources/templates/pdf/lof.liquid +24 -0
- data/resources/templates/pdf/lot.liquid +24 -0
- data/resources/templates/pdf/part.liquid +4 -0
- data/resources/templates/pdf/preface.liquid +1 -0
- data/resources/templates/pdf/prologue.liquid +1 -0
- data/resources/templates/pdf/table.liquid +7 -0
- data/resources/templates/pdf/title.liquid +3 -0
- data/resources/templates/pdf/toc.liquid +4 -0
- data/resources/templates/site/_layout.liquid +27 -0
- data/resources/templates/site/author.liquid +13 -0
- data/resources/templates/site/chapter.liquid +13 -0
- data/resources/templates/site/foreword.liquid +13 -0
- data/resources/templates/site/preface.liquid +13 -0
- metadata +232 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@charset 'utf-8';
|
data/lib/burr.rb
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
|
2
|
+
|
|
3
|
+
# Require all of the Ruby files in the given directory.
|
|
4
|
+
#
|
|
5
|
+
# path - The String relative path from here to the directory.
|
|
6
|
+
#
|
|
7
|
+
# Returns nothing.
|
|
8
|
+
def require_all(path)
|
|
9
|
+
glob = File.join(File.dirname(__FILE__), path, '*.rb')
|
|
10
|
+
Dir[glob].each do |f|
|
|
11
|
+
require f
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
require 'nokogiri'
|
|
16
|
+
require 'kramdown'
|
|
17
|
+
require 'liquid'
|
|
18
|
+
require 'thor'
|
|
19
|
+
require 'thor/group'
|
|
20
|
+
require 'eeepub'
|
|
21
|
+
|
|
22
|
+
require 'yaml'
|
|
23
|
+
|
|
24
|
+
require_all 'burr/core_ext'
|
|
25
|
+
require_all 'burr/kramdown_ext'
|
|
26
|
+
require 'burr/cli'
|
|
27
|
+
require 'burr/dependency'
|
|
28
|
+
require 'burr/generator'
|
|
29
|
+
require 'burr/version'
|
|
30
|
+
require 'burr/ui'
|
|
31
|
+
require 'burr/converter'
|
|
32
|
+
require 'burr/exporter'
|
|
33
|
+
require_all 'burr/exporters'
|
|
34
|
+
require 'burr/plugin'
|
|
35
|
+
require_all 'burr/plugins'
|
|
36
|
+
require_all 'burr/liquid_ext'
|
|
37
|
+
require_all 'burr/eeepub_ext'
|
|
38
|
+
require 'burr/book'
|
|
39
|
+
require 'burr/server'
|
|
40
|
+
|
|
41
|
+
Encoding.default_internal = 'utf-8'
|
|
42
|
+
Encoding.default_external = 'utf-8'
|
|
43
|
+
|
|
44
|
+
module Burr
|
|
45
|
+
|
|
46
|
+
def self.configuration
|
|
47
|
+
path = "#{Dir.pwd}/config.yml"
|
|
48
|
+
|
|
49
|
+
begin
|
|
50
|
+
YAML.load_file path
|
|
51
|
+
rescue => e
|
|
52
|
+
puts "#{e.message}"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
data/lib/burr/book.rb
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
module Burr
|
|
2
|
+
class Book
|
|
3
|
+
|
|
4
|
+
attr_accessor :config, :format, :ui
|
|
5
|
+
attr_accessor :gem_dir, :root_dir, :outputs_dir, :caches_dir, :contents_dir, :plugins_dir, :templates_dir
|
|
6
|
+
attr_accessor :items, :toc, :images, :tables, :current_item
|
|
7
|
+
attr_accessor :labels, :titles, :ids
|
|
8
|
+
attr_accessor :uid, :slug
|
|
9
|
+
|
|
10
|
+
def initialize(config, format)
|
|
11
|
+
@config = config
|
|
12
|
+
@format = format
|
|
13
|
+
@ui = Burr::UI.new
|
|
14
|
+
|
|
15
|
+
# directory location
|
|
16
|
+
@gem_dir = File.expand_path('../../../' ,__FILE__)
|
|
17
|
+
@root_dir = Dir.pwd
|
|
18
|
+
@outputs_dir = "#{@root_dir}/outputs"
|
|
19
|
+
@caches_dir = "#{@root_dir}/caches"
|
|
20
|
+
@contents_dir = "#{@root_dir}/contents"
|
|
21
|
+
@plugins_dir = "#{@root_dir}/plugins"
|
|
22
|
+
@templates_dir = "#{@root_dir}/templates"
|
|
23
|
+
|
|
24
|
+
# publishing process variables
|
|
25
|
+
@items = []
|
|
26
|
+
@toc = ''
|
|
27
|
+
@images = []
|
|
28
|
+
@tables = []
|
|
29
|
+
@current_item = []
|
|
30
|
+
|
|
31
|
+
# labels and titles
|
|
32
|
+
book_labels # @labels = {}, @ids = []
|
|
33
|
+
book_titles # @titles = {}
|
|
34
|
+
|
|
35
|
+
# book information
|
|
36
|
+
book_uid # @uid = ''
|
|
37
|
+
book_slug # @slug = ''
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Export site files in outputs/site
|
|
41
|
+
#
|
|
42
|
+
def export_site
|
|
43
|
+
exporter = Burr::Site.new(self)
|
|
44
|
+
self.ui.confirm "Start exporting site files...."
|
|
45
|
+
exporter.run
|
|
46
|
+
self.ui.confirm "Exported site!"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Export PDF files in outputs/pdf
|
|
50
|
+
#
|
|
51
|
+
def export_pdf
|
|
52
|
+
exporter = Burr::PDF.new(self)
|
|
53
|
+
self.ui.confirm "Start exporting pdf file...."
|
|
54
|
+
exporter.run
|
|
55
|
+
self.ui.confirm "Exported PDF!"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Export Epub files in outputs/epub
|
|
59
|
+
#
|
|
60
|
+
def export_epub
|
|
61
|
+
exporter = Burr::Epub.new(self)
|
|
62
|
+
self.ui.confirm "Start exporting epub file...."
|
|
63
|
+
exporter.run
|
|
64
|
+
self.ui.confirm "Exported Epub!"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Export Mobi files in outputs/mobi
|
|
68
|
+
#
|
|
69
|
+
def export_mobi
|
|
70
|
+
dest = File.join(self.outputs_dir, 'mobi')
|
|
71
|
+
FileUtils.mkdir_p(dest) unless File.exist?(dest)
|
|
72
|
+
|
|
73
|
+
self.ui.confirm "Start exporting mobi file...."
|
|
74
|
+
|
|
75
|
+
FileUtils.cd(File.join(self.outputs_dir, 'epub')) do
|
|
76
|
+
base = "#{self.config['slug']}-#{Time.new.strftime('%Y%m%d')}"
|
|
77
|
+
epub = "#{base}.epub"
|
|
78
|
+
mobi = "#{base}.mobi"
|
|
79
|
+
unless File.exist?(epub)
|
|
80
|
+
self.ui.error('Please export Epub first!')
|
|
81
|
+
exit 1
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
system "kindlegen #{epub} -c2"
|
|
85
|
+
FileUtils.cp(mobi, dest)
|
|
86
|
+
FileUtils.rm(mobi)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
self.ui.confirm "Exported Mobi!"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Export all formats
|
|
93
|
+
#
|
|
94
|
+
def export_all
|
|
95
|
+
self.export_pdf
|
|
96
|
+
self.export_epub
|
|
97
|
+
self.export_mobi
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Gets the template file for an element.
|
|
101
|
+
#
|
|
102
|
+
# - element The element name, such as 'chapter', 'appendix'
|
|
103
|
+
#
|
|
104
|
+
# Returns The absolute path of this element's template file.
|
|
105
|
+
#
|
|
106
|
+
def template_for(element)
|
|
107
|
+
base = File.join('templates', self.format, "#{element}.liquid")
|
|
108
|
+
default = File.join(self.gem_dir, 'resources', base)
|
|
109
|
+
custom = File.join(self.root_dir, base)
|
|
110
|
+
|
|
111
|
+
if File.exist?(custom)
|
|
112
|
+
custom
|
|
113
|
+
elsif !File.exist?(custom) && File.exist?(default)
|
|
114
|
+
default
|
|
115
|
+
else
|
|
116
|
+
self.ui.error("ERROR: Template #{self.format}/#{element}.liquid not found!")
|
|
117
|
+
exit 1
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Get the stylesheet file for a format.
|
|
122
|
+
#
|
|
123
|
+
# @param [String] format The format name, could be 'pdf', 'epub', 'site' and 'mobi'
|
|
124
|
+
# @return [String] The absolute path to this format's stylesheet
|
|
125
|
+
def stylesheet_for(format)
|
|
126
|
+
if %w(pdf epub site mobi).include?(format)
|
|
127
|
+
css = File.join(self.outputs_dir, format, "style.css")
|
|
128
|
+
|
|
129
|
+
if File.exist?(css)
|
|
130
|
+
css
|
|
131
|
+
else
|
|
132
|
+
self.ui.error("ERROR: Not found stylesheet for format #{format}.")
|
|
133
|
+
exit 1
|
|
134
|
+
end
|
|
135
|
+
else
|
|
136
|
+
self.ui.error("ERROR: #{format} is not support!")
|
|
137
|
+
exit 1
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Shortcut method to get the label of any element type.
|
|
142
|
+
#
|
|
143
|
+
# element - The element type (`chapter', `foreword', ...) in String format.
|
|
144
|
+
# variables - A variables Hash used to render the label.
|
|
145
|
+
#
|
|
146
|
+
# Returns the label String of the element or an empty String.
|
|
147
|
+
def render_label(element, variables = {})
|
|
148
|
+
c_labels = self.labels.include?(element) ? self.labels[element] : ''
|
|
149
|
+
# some elements (mostly chapters and appendices) have a different label for each level (h1, ..., h6)
|
|
150
|
+
if c_labels.is_a? Array
|
|
151
|
+
index = variables['item']['level'] - 1
|
|
152
|
+
if index == 0
|
|
153
|
+
label = c_labels[0]
|
|
154
|
+
else
|
|
155
|
+
label = c_labels[1]
|
|
156
|
+
end
|
|
157
|
+
else
|
|
158
|
+
label = c_labels
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
self.render_string(label, variables)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Shortcut method to get the id of headings.
|
|
165
|
+
#
|
|
166
|
+
# variables - A variables Hash used to render the id.
|
|
167
|
+
#
|
|
168
|
+
# Returns the id String of the heading.
|
|
169
|
+
def render_id(variables = {})
|
|
170
|
+
index = variables['item']['level'] - 1
|
|
171
|
+
if index == 0
|
|
172
|
+
id = self.ids[0]
|
|
173
|
+
else
|
|
174
|
+
id = self.ids[1]
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
self.render_string(id, variables)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Renders any string as a Liquid template.
|
|
181
|
+
#
|
|
182
|
+
# @param [String] text The original content to render
|
|
183
|
+
# @param [Array] variables Optional variables passed to the template
|
|
184
|
+
def render_string(text, variables = {})
|
|
185
|
+
registers = { :registers => { :book => self } }
|
|
186
|
+
Liquid::Template.parse(text).render(variables, registers)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
# Renders any template (currently only supports Liquid templates).
|
|
191
|
+
#
|
|
192
|
+
# @param [String] template The template name, without the extension
|
|
193
|
+
# @param [Hash] parameters Optional variables passed to the template
|
|
194
|
+
# @param [String] target Optional output file path. If set, the rendered template is saved in this file.
|
|
195
|
+
# @return [String] The rendered content
|
|
196
|
+
def render(template, parameters = {}, target = nil)
|
|
197
|
+
defaults = {
|
|
198
|
+
'config' => self.config,
|
|
199
|
+
'format' => self.format,
|
|
200
|
+
'generator' => { 'name' => 'Burr', 'version' => Burr::Version::STRING }
|
|
201
|
+
}
|
|
202
|
+
text = File.read(template)
|
|
203
|
+
registers = { :registers => { :book => self } }
|
|
204
|
+
content = Liquid::Template.parse(text).render(defaults.merge(parameters), registers)
|
|
205
|
+
|
|
206
|
+
if target
|
|
207
|
+
File.open(target, 'wb') { |f| f.puts content }
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
content
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Makes the liquid tags live.
|
|
214
|
+
#
|
|
215
|
+
# Returns Hash.
|
|
216
|
+
def to_liquid
|
|
217
|
+
#{ 'book' => self }
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
private
|
|
221
|
+
|
|
222
|
+
# Generates `@labels' for chapters, appendixes, etc.
|
|
223
|
+
#
|
|
224
|
+
# Returns nil.
|
|
225
|
+
def book_labels
|
|
226
|
+
base = File.join('locales', 'labels', "#{self.config['language']}.yml")
|
|
227
|
+
default = File.join(self.gem_dir, 'resources', base)
|
|
228
|
+
custom = File.join(self.root_dir, base)
|
|
229
|
+
|
|
230
|
+
labels = YAML::load_file(default)
|
|
231
|
+
|
|
232
|
+
#books can define their own labels files
|
|
233
|
+
if File.exist? custom
|
|
234
|
+
custom_labels = YAML::load_file(custom)
|
|
235
|
+
labels.merge!(custom_labels)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
self.labels = labels
|
|
239
|
+
self.ids = labels['id']
|
|
240
|
+
nil
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Generates `@titles' for chapters, appendixes, etc.
|
|
244
|
+
#
|
|
245
|
+
# Returns nil.
|
|
246
|
+
def book_titles
|
|
247
|
+
base = File.join('locales', 'titles', "#{self.config['language']}.yml")
|
|
248
|
+
default = File.join(self.gem_dir, 'resources', base)
|
|
249
|
+
custom = File.join(self.root_dir, base)
|
|
250
|
+
|
|
251
|
+
titles = YAML::load_file(default)
|
|
252
|
+
|
|
253
|
+
#books can define their own titles files
|
|
254
|
+
if File.exist? custom
|
|
255
|
+
custom_titles = YAML::load_file(custom)
|
|
256
|
+
return titles.merge(custom_titles)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
self.titles = titles
|
|
260
|
+
nil
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# Generates a unique `@uid' for the book.
|
|
264
|
+
#
|
|
265
|
+
# Returns nil.
|
|
266
|
+
def book_uid
|
|
267
|
+
if @config['isbn']
|
|
268
|
+
@uid = @config['isbn']
|
|
269
|
+
else
|
|
270
|
+
@uid = Digest::MD5.hexdigest("#{Time.now}--#{rand}")
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Generates a `@slug' for the book.
|
|
275
|
+
#
|
|
276
|
+
# Uses the current directory name as slug, if no `slug' in `config.yml' provided.
|
|
277
|
+
#
|
|
278
|
+
# Returns String of the book's slug.
|
|
279
|
+
def book_slug
|
|
280
|
+
if @config['slug']
|
|
281
|
+
@slug = @config['slug']
|
|
282
|
+
else
|
|
283
|
+
dir = File.basename(self.root_dir)
|
|
284
|
+
@slug = CGI.escape(dir)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
end
|
|
289
|
+
end
|
data/lib/burr/cli.rb
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Burr
|
|
2
|
+
class Cli < Thor
|
|
3
|
+
|
|
4
|
+
desc 'new [PATH]', 'Create a new book'
|
|
5
|
+
def new(path)
|
|
6
|
+
generator = Burr::Generator.new
|
|
7
|
+
generator.destination_root = path
|
|
8
|
+
generator.invoke_all
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
desc 'export [FORMAT]', 'Export a book format, or all formats'
|
|
12
|
+
def export(format)
|
|
13
|
+
valid = %w(site pdf epub mobi all)
|
|
14
|
+
|
|
15
|
+
if valid.include?(format)
|
|
16
|
+
book = Burr::Book.new(config, format)
|
|
17
|
+
case format
|
|
18
|
+
when 'site'
|
|
19
|
+
book.export_site
|
|
20
|
+
when 'pdf'
|
|
21
|
+
unless Dependency.prince_installed?
|
|
22
|
+
book.ui.warn "Please install PrinceXML first."
|
|
23
|
+
exit 1
|
|
24
|
+
end
|
|
25
|
+
book.export_pdf
|
|
26
|
+
when 'epub'
|
|
27
|
+
book.export_epub
|
|
28
|
+
when 'mobi'
|
|
29
|
+
unless Dependency.kindlegen_installed?
|
|
30
|
+
book.ui.warn "Please install kindelgen first."
|
|
31
|
+
exit 1
|
|
32
|
+
end
|
|
33
|
+
book.export_mobi
|
|
34
|
+
when 'all'
|
|
35
|
+
puts 'pending'
|
|
36
|
+
# book.export_all
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
raise "ERROR: invalid format. Formats: #{valid.join(', ')}."
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
desc 'server', 'Site preview'
|
|
44
|
+
def server
|
|
45
|
+
Burr::Server.start!
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
desc 'version', 'Show the burr version'
|
|
49
|
+
def version
|
|
50
|
+
puts Burr::Version::STRING
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def config
|
|
56
|
+
@config ||= Burr.configuration
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def book_root
|
|
60
|
+
@root ||= Dir.pwd
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Burr
|
|
2
|
+
class Converter
|
|
3
|
+
|
|
4
|
+
attr_accessor :book
|
|
5
|
+
|
|
6
|
+
def initialize(book)
|
|
7
|
+
@book = book
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def convert(text)
|
|
11
|
+
::Kramdown::Document.new(text,
|
|
12
|
+
:input => 'Bsmarkdown',
|
|
13
|
+
:auto_ids => false,
|
|
14
|
+
:register => self.book
|
|
15
|
+
).to_bshtml
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
# This file is steal from Rails
|
|
4
|
+
|
|
5
|
+
class Object
|
|
6
|
+
# An object is blank if it's false, empty, or a whitespace string.
|
|
7
|
+
# For example, '', ' ', +nil+, [], and {} are all blank.
|
|
8
|
+
#
|
|
9
|
+
# This simplifies:
|
|
10
|
+
#
|
|
11
|
+
# if address.nil? || address.empty?
|
|
12
|
+
#
|
|
13
|
+
# ...to:
|
|
14
|
+
#
|
|
15
|
+
# if address.blank?
|
|
16
|
+
def blank?
|
|
17
|
+
respond_to?(:empty?) ? empty? : !self
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# An object is present if it's not <tt>blank?</tt>.
|
|
21
|
+
def present?
|
|
22
|
+
!blank?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Returns object if it's <tt>present?</tt> otherwise returns +nil+.
|
|
26
|
+
# <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
|
|
27
|
+
#
|
|
28
|
+
# This is handy for any representation of objects where blank is the same
|
|
29
|
+
# as not present at all. For example, this simplifies a common check for
|
|
30
|
+
# HTTP POST/query parameters:
|
|
31
|
+
#
|
|
32
|
+
# state = params[:state] if params[:state].present?
|
|
33
|
+
# country = params[:country] if params[:country].present?
|
|
34
|
+
# region = state || country || 'US'
|
|
35
|
+
#
|
|
36
|
+
# ...becomes:
|
|
37
|
+
#
|
|
38
|
+
# region = params[:state].presence || params[:country].presence || 'US'
|
|
39
|
+
def presence
|
|
40
|
+
self if present?
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class NilClass
|
|
45
|
+
# +nil+ is blank:
|
|
46
|
+
#
|
|
47
|
+
# nil.blank? # => true
|
|
48
|
+
def blank?
|
|
49
|
+
true
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class FalseClass
|
|
54
|
+
# +false+ is blank:
|
|
55
|
+
#
|
|
56
|
+
# false.blank? # => true
|
|
57
|
+
def blank?
|
|
58
|
+
true
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class TrueClass
|
|
63
|
+
# +true+ is not blank:
|
|
64
|
+
#
|
|
65
|
+
# true.blank? # => false
|
|
66
|
+
def blank?
|
|
67
|
+
false
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
class Array
|
|
72
|
+
# An array is blank if it's empty:
|
|
73
|
+
#
|
|
74
|
+
# [].blank? # => true
|
|
75
|
+
# [1,2,3].blank? # => false
|
|
76
|
+
alias_method :blank?, :empty?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
class Hash
|
|
80
|
+
# A hash is blank if it's empty:
|
|
81
|
+
#
|
|
82
|
+
# {}.blank? # => true
|
|
83
|
+
# { key: 'value' }.blank? # => false
|
|
84
|
+
alias_method :blank?, :empty?
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
class String
|
|
88
|
+
# A string is blank if it's empty or contains whitespaces only:
|
|
89
|
+
#
|
|
90
|
+
# ''.blank? # => true
|
|
91
|
+
# ' '.blank? # => true
|
|
92
|
+
# ' '.blank? # => true
|
|
93
|
+
# ' something here '.blank? # => false
|
|
94
|
+
def blank?
|
|
95
|
+
self !~ /[^[:space:]]/
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class Numeric #:nodoc:
|
|
100
|
+
# No number is blank:
|
|
101
|
+
#
|
|
102
|
+
# 1.blank? # => false
|
|
103
|
+
# 0.blank? # => false
|
|
104
|
+
def blank?
|
|
105
|
+
false
|
|
106
|
+
end
|
|
107
|
+
end
|