softcover 0.7.11 → 0.8.0
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 +4 -4
- data/.pull_requests/1387399930 +0 -0
- data/.pull_requests/1387400263 +0 -0
- data/.pull_requests/1387592428 +0 -0
- data/.pull_requests/1387944330 +0 -0
- data/.pull_requests/1388094706 +0 -0
- data/.pull_requests/1388441218 +0 -0
- data/Gemfile +1 -0
- data/lib/softcover.rb +2 -1
- data/lib/softcover/book.rb +15 -5
- data/lib/softcover/book_manifest.rb +44 -5
- data/lib/softcover/builder.rb +27 -1
- data/lib/softcover/builders/epub.rb +17 -8
- data/lib/softcover/builders/html.rb +51 -12
- data/lib/softcover/builders/pdf.rb +14 -12
- data/lib/softcover/cli.rb +1 -0
- data/lib/softcover/commands/generator.rb +5 -3
- data/lib/softcover/commands/publisher.rb +3 -0
- data/lib/softcover/commands/server.rb +2 -2
- data/lib/softcover/directories.rb +5 -0
- data/lib/softcover/server/app.rb +1 -25
- data/lib/softcover/server/views/book.html.erb +1 -0
- data/lib/softcover/template/chapters/a_chapter.tex +2 -2
- data/lib/softcover/template/{book.yml.erb → config/book.yml.erb} +0 -1
- data/lib/softcover/template/config/marketing.yml +71 -0
- data/lib/softcover/template/html/stylesheets/custom.css +15 -0
- data/lib/softcover/template/images/cover-web.png +0 -0
- data/lib/softcover/template/{custom.sty → latex_styles/custom.sty} +0 -0
- data/lib/softcover/template/{framed.sty → latex_styles/framed.sty} +0 -0
- data/lib/softcover/template/{softcover.sty → latex_styles/softcover.sty} +6 -6
- data/lib/softcover/template/{upquote.sty → latex_styles/upquote.sty} +0 -0
- data/lib/softcover/template/screencasts/.gitkeep +0 -0
- data/lib/softcover/uploader.rb +9 -3
- data/lib/softcover/utils.rb +5 -4
- data/lib/softcover/version.rb +1 -1
- data/softcover.gemspec +1 -1
- data/spec/app_spec.rb +12 -1
- data/spec/book_manifest_spec.rb +0 -1
- data/spec/book_spec.rb +24 -16
- data/spec/builders/html_spec.rb +17 -3
- data/spec/builders/pdf_spec.rb +10 -2
- data/spec/commands/generator_spec.rb +8 -2
- data/spec/webmock_helpers.rb +5 -2
- metadata +20 -10
- data/lib/softcover/template/polytexnic_commands.sty +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e55cdffedc838f8932586db5eff983d9a84dd4b
|
4
|
+
data.tar.gz: fc341b0355f009345ef895b9d57a24ed9a651412
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 050cf03897d867223e98e3ff8b49b1efffb4984e7241a5bcd73cc53b0171fc50ea5de1ab3481ed546c53054f7a677146201f8a30e62ab69752af13addb846256
|
7
|
+
data.tar.gz: a81b24fe60937288477896740a7bd5eb11b9dc50aed52728d771bdfedde29d013410fda4944c42784632dd6e13dd45324d1734793721cbea7bfa5f5731ece8be
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/Gemfile
CHANGED
data/lib/softcover.rb
CHANGED
@@ -4,6 +4,7 @@ require 'active_support/core_ext/string'
|
|
4
4
|
require_relative 'softcover/formats'
|
5
5
|
require_relative 'softcover/utils'
|
6
6
|
require_relative 'softcover/output'
|
7
|
+
require_relative 'softcover/directories'
|
7
8
|
|
8
9
|
profile = false
|
9
10
|
if profile
|
@@ -41,7 +42,7 @@ module Softcover
|
|
41
42
|
|
42
43
|
# Return the custom styles, if any.
|
43
44
|
def custom_styles
|
44
|
-
custom_file = 'custom.sty'
|
45
|
+
custom_file = File.join(Softcover::Directories::STYLES, 'custom.sty')
|
45
46
|
File.exist?(custom_file) ? File.read(custom_file) : ''
|
46
47
|
end
|
47
48
|
|
data/lib/softcover/book.rb
CHANGED
@@ -11,6 +11,8 @@ class Softcover::Book
|
|
11
11
|
def initialize(options={})
|
12
12
|
require "softcover/client"
|
13
13
|
@manifest = Softcover::BookManifest.new(options)
|
14
|
+
@marketing = Softcover::MarketingManifest.new
|
15
|
+
|
14
16
|
@client = Softcover::Client.new_with_book self
|
15
17
|
|
16
18
|
@screencasts_dir = DEFAULT_SCREENCASTS_DIR
|
@@ -101,8 +103,11 @@ class Softcover::Book
|
|
101
103
|
slug: slug,
|
102
104
|
subtitle: subtitle,
|
103
105
|
description: description,
|
104
|
-
|
105
|
-
|
106
|
+
chapters: chapter_attributes,
|
107
|
+
prices: prices,
|
108
|
+
faq: faq,
|
109
|
+
testimonials: testimonials,
|
110
|
+
marketing_content: marketing_content
|
106
111
|
|
107
112
|
if res['errors']
|
108
113
|
@errors = res['errors']
|
@@ -166,7 +171,7 @@ class Softcover::Book
|
|
166
171
|
files_to_upload = find_screencasts.select do |file|
|
167
172
|
next false if @processed_screencasts.include?(file)
|
168
173
|
|
169
|
-
file.ready
|
174
|
+
file.ready?
|
170
175
|
end
|
171
176
|
|
172
177
|
upload_screencasts! files_to_upload
|
@@ -174,8 +179,13 @@ class Softcover::Book
|
|
174
179
|
@processed_screencasts += files_to_upload
|
175
180
|
end
|
176
181
|
|
182
|
+
SCREENCAST_FORMATS = %w{mov ogv mp4 webm}
|
183
|
+
|
177
184
|
def find_screencasts
|
178
|
-
|
185
|
+
formats = SCREENCAST_FORMATS * ','
|
186
|
+
Dir["#{@screencasts_dir}/**/*.{#{formats},zip}"].map do |path|
|
187
|
+
BookFile.new path
|
188
|
+
end
|
179
189
|
end
|
180
190
|
|
181
191
|
def upload_screencasts!(files)
|
@@ -196,6 +206,6 @@ class Softcover::Book
|
|
196
206
|
|
197
207
|
private
|
198
208
|
def method_missing(name, *args, &block)
|
199
|
-
@manifest.send(name) || super
|
209
|
+
@manifest.send(name) || @marketing.send(name) || super
|
200
210
|
end
|
201
211
|
end
|
@@ -3,6 +3,23 @@ require 'ostruct'
|
|
3
3
|
class Softcover::BookManifest < OpenStruct
|
4
4
|
include Softcover::Utils
|
5
5
|
|
6
|
+
class Softcover::MarketingManifest < Softcover::BookManifest
|
7
|
+
|
8
|
+
YAML_PATH = File.join(Softcover::Directories::CONFIG, 'marketing.yml')
|
9
|
+
def initialize
|
10
|
+
ensure_marketing_file
|
11
|
+
marshal_load read_from_yml.symbolize_keys!
|
12
|
+
end
|
13
|
+
|
14
|
+
# Ensures the existence of 'marketing.yml'.
|
15
|
+
# We copy from the template if necessary.
|
16
|
+
def ensure_marketing_file
|
17
|
+
template = File.join(File.dirname(__FILE__), 'template', YAML_PATH)
|
18
|
+
FileUtils.cp(template, YAML_PATH) unless File.exist?(YAML_PATH)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
6
23
|
class NotFound < StandardError
|
7
24
|
def message
|
8
25
|
"Invalid book directory, no manifest file found!"
|
@@ -10,9 +27,7 @@ class Softcover::BookManifest < OpenStruct
|
|
10
27
|
end
|
11
28
|
|
12
29
|
class Chapter < OpenStruct
|
13
|
-
|
14
|
-
File.join('chapters', slug + '.tex')
|
15
|
-
end
|
30
|
+
include Softcover::Utils
|
16
31
|
|
17
32
|
def fragment_name
|
18
33
|
"#{slug}_fragment.html"
|
@@ -49,13 +64,20 @@ class Softcover::BookManifest < OpenStruct
|
|
49
64
|
def full_name
|
50
65
|
"#{slug}#{extension}"
|
51
66
|
end
|
67
|
+
|
68
|
+
# Returns the name for the cached version of the chapters.
|
69
|
+
# This is used when processing Markdown to avoid unnecessary calls to
|
70
|
+
# kramdown's to_latex method, which can get expensive.
|
71
|
+
def cache_filename
|
72
|
+
Softcover::Utils.path("tmp/#{full_name}.cache")
|
73
|
+
end
|
52
74
|
end
|
53
75
|
|
54
76
|
class Section < OpenStruct
|
55
77
|
end
|
56
78
|
|
57
79
|
TXT_PATH = 'Book.txt'
|
58
|
-
YAML_PATH =
|
80
|
+
YAML_PATH = File.join(Softcover::Directories::CONFIG, 'book.yml')
|
59
81
|
|
60
82
|
def initialize(options = {})
|
61
83
|
@source = options[:source] || :polytex
|
@@ -225,6 +247,11 @@ class Softcover::BookManifest < OpenStruct
|
|
225
247
|
end
|
226
248
|
|
227
249
|
def self.valid_directory?
|
250
|
+
# Needed for backwards compatibility
|
251
|
+
if File.exist?('book.yml') && !Dir.pwd.include?('config')
|
252
|
+
Softcover::Utils.mkdir('config')
|
253
|
+
FileUtils.mv('book.yml', 'config')
|
254
|
+
end
|
228
255
|
[YAML_PATH, TXT_PATH].any? { |f| File.exist?(f) }
|
229
256
|
end
|
230
257
|
|
@@ -274,7 +301,19 @@ class Softcover::BookManifest < OpenStruct
|
|
274
301
|
require 'softcover/config'
|
275
302
|
require 'yaml/store'
|
276
303
|
self.class.find_book_root!
|
277
|
-
|
304
|
+
ensure_book_yml
|
305
|
+
YAML.load_file(self.class::YAML_PATH)
|
306
|
+
end
|
307
|
+
|
308
|
+
# Ensures that the book.yml file is in the right directory.
|
309
|
+
# This is for backwards compatibility.
|
310
|
+
def ensure_book_yml
|
311
|
+
path = self.class::YAML_PATH
|
312
|
+
unless File.exist?(path)
|
313
|
+
base = File.basename(path)
|
314
|
+
Softcover::Utils.mkdir Softcover::Directories::CONFIG
|
315
|
+
FileUtils.mv base, Softcover::Directories::CONFIG
|
316
|
+
end
|
278
317
|
end
|
279
318
|
|
280
319
|
|
data/lib/softcover/builder.rb
CHANGED
@@ -8,6 +8,7 @@ module Softcover
|
|
8
8
|
@manifest = Softcover::BookManifest.new(verify_paths: true,
|
9
9
|
source: source)
|
10
10
|
@built_files = []
|
11
|
+
ensure_style_file_locations
|
11
12
|
write_polytexnic_commands_file
|
12
13
|
end
|
13
14
|
|
@@ -24,9 +25,34 @@ module Softcover
|
|
24
25
|
def setup; end
|
25
26
|
def verify; end
|
26
27
|
|
28
|
+
# Ensures the style files are in the right location.
|
29
|
+
# This is for backwards compatibility.
|
30
|
+
def ensure_style_file_locations
|
31
|
+
styles_dir = Softcover::Directories::STYLES
|
32
|
+
mkdir styles_dir
|
33
|
+
fix_custom_include
|
34
|
+
files = Dir.glob('*.sty')
|
35
|
+
FileUtils.mv(files, styles_dir)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Fixes the custom include.
|
39
|
+
# The template includes the custom style file as an example
|
40
|
+
# of file inclusion. Unfortunately, the location of 'custom.sty', has
|
41
|
+
# changed, which will result in older templates spontaneously breaking.
|
42
|
+
def fix_custom_include
|
43
|
+
first_chapter = File.join('chapters', 'a_chapter.tex')
|
44
|
+
if File.exist?(first_chapter)
|
45
|
+
text = File.read(first_chapter)
|
46
|
+
text.gsub!('<<(custom.sty',
|
47
|
+
"<<(#{Softcover::Directories::STYLES}/custom.sty" )
|
48
|
+
File.write(first_chapter, text)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
27
52
|
# Writes out the PolyTeXnic commands from polytexnic.
|
28
53
|
def write_polytexnic_commands_file
|
29
|
-
|
54
|
+
styles_dir = File.join(Dir.pwd, Softcover::Directories::STYLES)
|
55
|
+
Polytexnic.write_polytexnic_style_file(styles_dir)
|
30
56
|
end
|
31
57
|
end
|
32
58
|
end
|
@@ -5,7 +5,7 @@ module Softcover
|
|
5
5
|
|
6
6
|
def build!(options={})
|
7
7
|
@preview = options[:preview]
|
8
|
-
Softcover::Builders::Html.new.build!
|
8
|
+
Softcover::Builders::Html.new.build!
|
9
9
|
if manifest.markdown?
|
10
10
|
self.manifest = Softcover::BookManifest.new(source: :polytex,
|
11
11
|
origin: :markdown)
|
@@ -32,7 +32,7 @@ module Softcover
|
|
32
32
|
# Removes HTML.
|
33
33
|
# All the HTML is generated, so this clears out any unused files.
|
34
34
|
def remove_html
|
35
|
-
FileUtils.rm(Dir.glob(path('epub/OEBPS
|
35
|
+
FileUtils.rm(Dir.glob(path('epub/OEBPS/*.html')))
|
36
36
|
end
|
37
37
|
|
38
38
|
def create_directories
|
@@ -218,17 +218,24 @@ module Softcover
|
|
218
218
|
epub_styles = File.join('epub', 'OEBPS', 'styles')
|
219
219
|
|
220
220
|
FileUtils.cp(File.join(html_styles, 'pygments.css'), epub_styles)
|
221
|
+
File.write(File.join(epub_styles, 'softcover.css'),
|
222
|
+
clean_book_id(path("#{html_styles}/softcover.css")))
|
221
223
|
|
222
224
|
# Copy over the EPUB-specific CSS.
|
223
225
|
template_dir = File.join(File.dirname(__FILE__), '..', 'template')
|
224
|
-
epub_css
|
226
|
+
epub_css = File.join(template_dir, epub_styles, 'epub.css')
|
225
227
|
FileUtils.cp(epub_css, epub_styles)
|
226
228
|
|
227
|
-
#
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
229
|
+
# Copy over custom CSS.
|
230
|
+
File.write(File.join(epub_styles, 'custom.css'),
|
231
|
+
clean_book_id(path("#{html_styles}/custom.css")))
|
232
|
+
end
|
233
|
+
|
234
|
+
# Removes the '#book' CSS id.
|
235
|
+
# For some reason, EPUB books hate the #book ids in the stylesheet
|
236
|
+
# (i.e., such books fail to validate), so remove them.
|
237
|
+
def clean_book_id(filename)
|
238
|
+
File.read(filename).gsub(/#book/, '')
|
232
239
|
end
|
233
240
|
|
234
241
|
# Copies the image files from the HTML version of the document.
|
@@ -334,6 +341,7 @@ module Softcover
|
|
334
341
|
<item id="pygments.css" href="styles/pygments.css" media-type="text/css"/>
|
335
342
|
<item id="softcover.css" href="styles/softcover.css" media-type="text/css"/>
|
336
343
|
<item id="epub.css" href="styles/epub.css" media-type="text/css"/>
|
344
|
+
<item id="custom.css" href="styles/custom.css" media-type="text/css"/>
|
337
345
|
<item id="cover" href="cover.html" media-type="application/xhtml+xml"/>
|
338
346
|
#{man_ch.join("\n")}
|
339
347
|
#{images.join("\n")}
|
@@ -431,6 +439,7 @@ module Softcover
|
|
431
439
|
<link rel="stylesheet" href="styles/pygments.css" type="text/css" />
|
432
440
|
<link rel="stylesheet" href="styles/softcover.css" type="text/css" />
|
433
441
|
<link rel="stylesheet" href="styles/epub.css" type="text/css" />
|
442
|
+
<link rel="stylesheet" href="styles/custom.css" type="text/css"/>
|
434
443
|
<link rel="stylesheet" type="application/vnd.adobe-page-template+xml" href="styles/page-template.xpgt" />
|
435
444
|
</head>
|
436
445
|
|
@@ -7,9 +7,14 @@ module Softcover
|
|
7
7
|
|
8
8
|
def setup
|
9
9
|
Dir.mkdir "html" unless File.directory?("html")
|
10
|
-
|
11
|
-
|
10
|
+
html_styles = path('html/stylesheets')
|
11
|
+
unless File.directory?(html_styles)
|
12
|
+
Dir.mkdir html_styles
|
12
13
|
end
|
14
|
+
template_dir = path("#{File.dirname(__FILE__)}/../template")
|
15
|
+
custom_css = path("#{template_dir}/html/stylesheets/custom.css")
|
16
|
+
target = path("#{html_styles}/custom.css")
|
17
|
+
FileUtils.cp(custom_css, target) unless File.exist?(target)
|
13
18
|
clean!
|
14
19
|
end
|
15
20
|
|
@@ -23,7 +28,7 @@ module Softcover
|
|
23
28
|
|
24
29
|
if manifest.markdown?
|
25
30
|
unless options[:'find-overfull']
|
26
|
-
|
31
|
+
remove_unneeded_polytex_files
|
27
32
|
end
|
28
33
|
manifest.chapters.each do |chapter|
|
29
34
|
write_latex_files(chapter, options)
|
@@ -40,7 +45,8 @@ module Softcover
|
|
40
45
|
@html = converted_html(basename)
|
41
46
|
@title = basename
|
42
47
|
erb_file = File.read(File.join(File.dirname(__FILE__),
|
43
|
-
'
|
48
|
+
'..', 'server', 'views',
|
49
|
+
'book.html.erb'))
|
44
50
|
file_content = ERB.new(erb_file).result(binding)
|
45
51
|
write_full_html_file(basename, file_content)
|
46
52
|
write_chapter_html_files(Nokogiri::HTML(file_content), erb_file)
|
@@ -55,20 +61,48 @@ module Softcover
|
|
55
61
|
true
|
56
62
|
end
|
57
63
|
|
64
|
+
# Removes any PolyTeX files not corresponding to current MD chapters.
|
65
|
+
def remove_unneeded_polytex_files
|
66
|
+
files_to_keep = manifest.chapters.map do |chapter|
|
67
|
+
path("#{manifest.polytex_dir}/#{chapter.slug}.tex")
|
68
|
+
end
|
69
|
+
all_files = Dir.glob(path("#{manifest.polytex_dir}/*.tex"))
|
70
|
+
files_to_remove = all_files - files_to_keep
|
71
|
+
FileUtils.rm(files_to_remove)
|
72
|
+
end
|
73
|
+
|
58
74
|
# Writes the LaTeX files for a given Markdown chapter.
|
59
75
|
def write_latex_files(chapter, options = {})
|
60
|
-
|
76
|
+
polytex_filename = path("#{manifest.polytex_dir}/#{chapter.slug}.tex")
|
61
77
|
if chapter.source == :polytex
|
62
|
-
FileUtils.cp path("chapters/#{chapter.full_name}"),
|
78
|
+
FileUtils.cp path("chapters/#{chapter.full_name}"), polytex_filename
|
63
79
|
else
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
File.
|
80
|
+
mkdir Softcover::Directories::TMP
|
81
|
+
markdown = File.read(path("chapters/#{chapter.full_name}"))
|
82
|
+
# Only write if the Markdown file hasn't changed since the last time
|
83
|
+
# it was converted, as then the current PolyTeX file is up-to-date.
|
84
|
+
# The call to File.exist?(filename) is just in case the PolyTeX file
|
85
|
+
# corresponding to the Markdown file was removed by hand in the
|
86
|
+
# interim.
|
87
|
+
unless (File.exist?(chapter.cache_filename) &&
|
88
|
+
File.read(chapter.cache_filename) == digest(markdown) &&
|
89
|
+
File.exist?(polytex_filename))
|
90
|
+
File.write(polytex_filename, polytex(chapter, markdown))
|
91
|
+
end
|
69
92
|
end
|
70
93
|
end
|
71
94
|
|
95
|
+
# Returns the PolyTeX for the chapter.
|
96
|
+
# As a side-effect, we cache a digest of the Markdown to prevent
|
97
|
+
# unnecessary conversions.
|
98
|
+
def polytex(chapter, markdown)
|
99
|
+
File.write(chapter.cache_filename, digest(markdown))
|
100
|
+
p = Polytexnic::Pipeline.new(markdown,
|
101
|
+
source: :markdown,
|
102
|
+
custom_commands: Softcover.custom_styles)
|
103
|
+
p.polytex
|
104
|
+
end
|
105
|
+
|
72
106
|
# Returns the converted HTML.
|
73
107
|
def converted_html(basename)
|
74
108
|
polytex_filename = basename + '.tex'
|
@@ -152,7 +186,12 @@ module Softcover
|
|
152
186
|
target = target_cache[ref_id]
|
153
187
|
unless target.nil?
|
154
188
|
id = target['id']
|
155
|
-
ref_chapter =
|
189
|
+
ref_chapter = if target['data-tralics-id'].nil?
|
190
|
+
# This branch is true for chapter-star.
|
191
|
+
chapter
|
192
|
+
else
|
193
|
+
ref_map[target['data-tralics-id']]
|
194
|
+
end
|
156
195
|
ref_node['href'] = "#{ref_chapter.fragment_name}##{id}"
|
157
196
|
end
|
158
197
|
end
|
@@ -28,18 +28,16 @@ module Softcover
|
|
28
28
|
|
29
29
|
polytex_filenames = manifest.pdf_chapter_filenames << book_filename
|
30
30
|
polytex_filenames.each do |filename|
|
31
|
-
polytex = File.
|
31
|
+
polytex = File.read(filename)
|
32
32
|
latex = Polytexnic::Pipeline.new(polytex).to_latex
|
33
33
|
if filename == book_filename
|
34
34
|
latex.gsub!(/\\include{(.*?)}/) do
|
35
35
|
"\\include{#{Softcover::Utils.tmpify(manifest, $1)}.tmp}"
|
36
36
|
end
|
37
37
|
end
|
38
|
-
File.
|
39
|
-
f.write(latex)
|
40
|
-
end
|
38
|
+
File.write(Softcover::Utils.tmpify(manifest, filename), latex)
|
41
39
|
end
|
42
|
-
write_pygments_file(:latex)
|
40
|
+
write_pygments_file(:latex, Softcover::Directories::STYLES)
|
43
41
|
copy_polytexnic_sty
|
44
42
|
|
45
43
|
# Renaming the PDF in the command is necessary because `execute`
|
@@ -48,7 +46,8 @@ module Softcover
|
|
48
46
|
# is ignored.
|
49
47
|
# (The reason for using `exec` is so that LaTeX errors get emitted to
|
50
48
|
# the screen rather than just hanging the process.)
|
51
|
-
cmd = "#{pdf_cmd(book_filename, options)}
|
49
|
+
cmd = "#{pdf_cmd(book_filename, options)} " +
|
50
|
+
"; #{rename_pdf(basename, options)}"
|
52
51
|
# Here we use `system` when making a preview because the preview command
|
53
52
|
# needs to run after the main PDF build.
|
54
53
|
if options[:quiet] || options[:silent]
|
@@ -106,19 +105,22 @@ module Softcover
|
|
106
105
|
# The purpose is to match the original filename.
|
107
106
|
# For example, foo_bar.tex should produce foo_bar.pdf.
|
108
107
|
# While we're at it, we move it to the standard ebooks/ directory.
|
109
|
-
def rename_pdf(basename)
|
108
|
+
def rename_pdf(basename, options={})
|
110
109
|
tmp_pdf = basename + '.tmp.pdf'
|
111
110
|
pdf = basename + '.pdf'
|
112
111
|
mkdir('ebooks')
|
113
|
-
|
112
|
+
# Remove the intermediate tmp files unless only running once.
|
113
|
+
rm_tmp = options[:once] || Softcover.test? ? "" : "&& rm -f *.tmp.*"
|
114
|
+
"mv -f #{tmp_pdf} #{File.join('ebooks', pdf)} #{rm_tmp}"
|
114
115
|
end
|
115
116
|
|
116
|
-
# Copies the
|
117
|
+
# Copies the style file to ensure it's always fresh.
|
117
118
|
def copy_polytexnic_sty
|
118
|
-
|
119
|
+
softcover_sty = File.join(Softcover::Directories::STYLES,
|
120
|
+
'softcover.sty')
|
119
121
|
source_sty = File.join(File.dirname(__FILE__),
|
120
|
-
|
121
|
-
FileUtils.cp source_sty,
|
122
|
+
'..', 'template', softcover_sty)
|
123
|
+
FileUtils.cp source_sty, softcover_sty
|
122
124
|
end
|
123
125
|
end
|
124
126
|
end
|
data/lib/softcover/cli.rb
CHANGED
@@ -133,6 +133,7 @@ module Softcover
|
|
133
133
|
# TODO: make screencasts dir .book configurable
|
134
134
|
define_method "publish:screencasts" do |dir=
|
135
135
|
Softcover::Book::DEFAULT_SCREENCASTS_DIR|
|
136
|
+
require 'softcover/commands/publisher'
|
136
137
|
|
137
138
|
puts "Publishing screencasts in #{dir}"
|
138
139
|
Softcover::Commands::Publisher.
|
@@ -40,7 +40,8 @@ module Softcover
|
|
40
40
|
if path =~ /book\.tex/
|
41
41
|
cp_path = "#{name}.tex"
|
42
42
|
elsif path =~ /\.erb/
|
43
|
-
cp_path = File.
|
43
|
+
cp_path = File.join(File.dirname(cp_path),
|
44
|
+
File.basename(path.dup, '.erb'))
|
44
45
|
elsif path =~ /gitignore/
|
45
46
|
cp_path = '.gitignore'
|
46
47
|
end
|
@@ -77,11 +78,12 @@ module Softcover
|
|
77
78
|
File.symlink("../images", "images")
|
78
79
|
|
79
80
|
Dir.chdir "../.."
|
80
|
-
|
81
|
+
book_yml = File.join(Softcover::Directories::CONFIG, 'book')
|
82
|
+
puts "Done. Please update #{book_yml}"
|
81
83
|
end
|
82
84
|
|
83
85
|
def template_dir
|
84
|
-
File.expand_path File.join File.dirname(__FILE__), "
|
86
|
+
File.expand_path File.join File.dirname(__FILE__), "..", "template"
|
85
87
|
end
|
86
88
|
|
87
89
|
# Returns a list of all the files and directories used to build the book.
|
@@ -36,6 +36,9 @@ module Softcover::Commands::Publisher
|
|
36
36
|
def publish_screencasts!(options={})
|
37
37
|
return false unless current_book
|
38
38
|
|
39
|
+
require 'ruby-progressbar'
|
40
|
+
require 'curb'
|
41
|
+
|
39
42
|
current_book.screencasts_dir = options[:dir] ||
|
40
43
|
Softcover::Book::DEFAULT_SCREENCASTS_DIR
|
41
44
|
|
@@ -10,7 +10,7 @@ module Softcover::Commands::Server
|
|
10
10
|
def listen_for_changes
|
11
11
|
return if defined?(@no_listener) && @no_listener
|
12
12
|
server_pid = Process.pid
|
13
|
-
filter_regex = /(\.md|\.tex|custom\.sty|Book\.txt|book\.yml)$/
|
13
|
+
filter_regex = /(\.md|\.tex|custom\.sty|custom\.css|Book\.txt|book\.yml)$/
|
14
14
|
@listener = Listen.to('.')
|
15
15
|
@listener.filter(filter_regex)
|
16
16
|
|
@@ -44,7 +44,7 @@ module Softcover::Commands::Server
|
|
44
44
|
'Building...'
|
45
45
|
t = Time.now
|
46
46
|
builder = Softcover::Builders::Html.new
|
47
|
-
builder.build
|
47
|
+
builder.build
|
48
48
|
puts "Done. (#{(Time.now - t).round(2)}s)"
|
49
49
|
|
50
50
|
rescue Softcover::BookManifest::NotFound => e
|
data/lib/softcover/server/app.rb
CHANGED
@@ -5,7 +5,7 @@ require 'sinatra/async'
|
|
5
5
|
class Softcover::App < Sinatra::Base
|
6
6
|
register Sinatra::Async
|
7
7
|
|
8
|
-
set :public_folder,
|
8
|
+
set :public_folder, 'html'
|
9
9
|
set :bind, '0.0.0.0'
|
10
10
|
|
11
11
|
configure do
|
@@ -28,30 +28,6 @@ class Softcover::App < Sinatra::Base
|
|
28
28
|
coffee erb :'main.js'
|
29
29
|
end
|
30
30
|
|
31
|
-
get '/stylesheets/pygments.css' do
|
32
|
-
content_type 'text/css'
|
33
|
-
@pygments_css ||= Pygments.send(:mentos, :css, ['html', '']).
|
34
|
-
gsub!(/^/, '.highlight ')
|
35
|
-
end
|
36
|
-
|
37
|
-
# Gets the image specified by the path and content type.
|
38
|
-
get '/images/*' do |path|
|
39
|
-
split_path = path.split(/\./)
|
40
|
-
extension = split_path.pop
|
41
|
-
path = split_path * ''
|
42
|
-
# Arrange to handle both '.jpeg' and '.jpg' extensions.
|
43
|
-
if extension == 'jpeg' && !File.exist?(image_filename(path, extension))
|
44
|
-
extension = 'jpg'
|
45
|
-
end
|
46
|
-
file_path = image_filename(path, extension)
|
47
|
-
if File.exists?(file_path)
|
48
|
-
content_type extension
|
49
|
-
File.read(file_path)
|
50
|
-
else
|
51
|
-
raise Sinatra::NotFound
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
31
|
get '/assets/:path' do
|
56
32
|
extension = params[:path].split('.').last
|
57
33
|
content_type extension
|
@@ -4,6 +4,7 @@
|
|
4
4
|
<meta charset="UTF-8">
|
5
5
|
<link href="stylesheets/pygments.css" media="screen" rel="stylesheet" type="text/css" />
|
6
6
|
<link href="stylesheets/softcover.css" media="screen" rel="stylesheet" type="text/css" />
|
7
|
+
<link href="stylesheets/custom.css" media="screen" rel="stylesheet" type="text/css" />
|
7
8
|
<% if @local_server %>
|
8
9
|
<script src="/jquery/1.10.2/jquery-1.10.2.js" ></script>
|
9
10
|
<link href="assets/main.css" media="screen" rel="stylesheet" type="text/css" />
|
@@ -52,8 +52,8 @@ current\_\-user
|
|
52
52
|
|
53
53
|
\begin{codelisting}
|
54
54
|
\label{code:custom}
|
55
|
-
\codecaption{Defining custom commands. \\ \filepath{custom.sty}}
|
56
|
-
%= <<(custom.sty, lang: tex)
|
55
|
+
\codecaption{Defining custom commands. \\ \filepath{latex\_styles/custom.sty}}
|
56
|
+
%= <<(latex_styles/custom.sty, lang: tex)
|
57
57
|
\end{codelisting}
|
58
58
|
|
59
59
|
Listing~\ref{code:hyphenation} also shows how to escape the underscore character using a backslash. This is necessary because plain underscores are reserved for math environments (Section~\ref{sec:mathematics}).
|
@@ -0,0 +1,71 @@
|
|
1
|
+
---
|
2
|
+
prices:
|
3
|
+
-
|
4
|
+
code: ebooks
|
5
|
+
name: "HTML & Ebook"
|
6
|
+
description:
|
7
|
+
|
|
8
|
+
Optimized for Kindle* and iPad
|
9
|
+
Almost 9000 pages of content
|
10
|
+
Includes a free copy of 1st Edition PDF
|
11
|
+
media:
|
12
|
+
- html
|
13
|
+
- pdf
|
14
|
+
- epub
|
15
|
+
- mobi
|
16
|
+
price: 3500
|
17
|
+
|
18
|
+
-
|
19
|
+
code: screencasts
|
20
|
+
name: "HTML & Screencasts"
|
21
|
+
description:
|
22
|
+
|
|
23
|
+
Full updated for the 2nd edition
|
24
|
+
100% DRM-free digital downloads
|
25
|
+
(QuickTime and Ogg Vorbis)
|
26
|
+
Includes first edition screencasts
|
27
|
+
media:
|
28
|
+
- html
|
29
|
+
- screencasts
|
30
|
+
price: 12500
|
31
|
+
|
32
|
+
-
|
33
|
+
code: all
|
34
|
+
name: "HTML, Ebook, and Screencasts"
|
35
|
+
description:
|
36
|
+
|
|
37
|
+
Includes all 50 screencasts
|
38
|
+
eBook formats for Kindle, Nook, and PDF
|
39
|
+
Read online.
|
40
|
+
media:
|
41
|
+
- html
|
42
|
+
- pdf
|
43
|
+
- epub
|
44
|
+
- mobi
|
45
|
+
- screencasts
|
46
|
+
price: 12500
|
47
|
+
regular_price: 19900
|
48
|
+
|
49
|
+
faq:
|
50
|
+
-
|
51
|
+
question: "Question 1 text"
|
52
|
+
answer: "Answer 1 text"
|
53
|
+
|
54
|
+
-
|
55
|
+
question: "Question 2 text"
|
56
|
+
answer: "Answer 2 text"
|
57
|
+
|
58
|
+
testimonials:
|
59
|
+
-
|
60
|
+
name: "Person 1"
|
61
|
+
title: "Person 1 Title"
|
62
|
+
image: /images/testimonial_1.png
|
63
|
+
text: "Testimonial 1 text"
|
64
|
+
|
65
|
+
-
|
66
|
+
name: "Person 2"
|
67
|
+
title: "Person 2 Title"
|
68
|
+
gravatar_email: "info@softcover.io"
|
69
|
+
text: "Testimonial 2 text"
|
70
|
+
|
71
|
+
marketing_content: ''
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/* Place custom styles here, scoped by the CSS id '#book' */
|
2
|
+
/* To sync up PDF styles, edit custom.sty */
|
3
|
+
/* Google for "LaTeX style files" to learn how to use custom.sty */
|
4
|
+
|
5
|
+
/*
|
6
|
+
|
7
|
+
body #book {
|
8
|
+
background: green;
|
9
|
+
}
|
10
|
+
|
11
|
+
#book p {
|
12
|
+
color: purple;
|
13
|
+
}
|
14
|
+
|
15
|
+
*/
|
Binary file
|
File without changes
|
File without changes
|
@@ -19,7 +19,7 @@
|
|
19
19
|
\usepackage{graphicx}
|
20
20
|
\def\maxwidth#1{\ifdim\Gin@nat@width>#1 #1\else\Gin@nat@width\fi}
|
21
21
|
% Commands included by PolyTeXnic
|
22
|
-
\usepackage{polytexnic_commands}
|
22
|
+
\usepackage{latex_styles/polytexnic_commands}
|
23
23
|
% Links
|
24
24
|
\definecolor{darkblue}{rgb}{0,0.18,0.45}
|
25
25
|
\definecolor{darkgreen}{rgb}{0,0.39,0}
|
@@ -32,7 +32,7 @@
|
|
32
32
|
\hypersetup{hyperfootnotes=false}
|
33
33
|
\hypersetup{colorlinks,linkcolor=darkblue,urlcolor=blue}
|
34
34
|
% Syntax highlighting
|
35
|
-
\usepackage{pygments}
|
35
|
+
\usepackage{latex_styles/pygments}
|
36
36
|
% Change color of '@go', "general output", from gray to dark green.
|
37
37
|
\expandafter\def\csname PY@tok@go\endcsname{\def\PY@tc##1{\textcolor{darkgreen}{##1}}}
|
38
38
|
% American Mathematical Society extensions
|
@@ -71,7 +71,7 @@
|
|
71
71
|
% Use a nice font in code environments.
|
72
72
|
\usepackage[scaled=0.92]{helvet}
|
73
73
|
% Fix quotes in code environments
|
74
|
-
\usepackage{upquote}
|
74
|
+
\usepackage{latex_styles/upquote}
|
75
75
|
|
76
76
|
% Filesystem paths
|
77
77
|
\newcommand{\filepath}[1]{\texttt{\small #1}}
|
@@ -125,7 +125,7 @@
|
|
125
125
|
\usepackage{amsthm}
|
126
126
|
\theoremstyle{definition}
|
127
127
|
\newtheorem{aside}{Box}[chapter]
|
128
|
-
\usepackage{framed}
|
128
|
+
\usepackage{latex_styles/framed}
|
129
129
|
\definecolor{shadecolor}{gray}{0.97}
|
130
130
|
\definecolor{boxcolor}{gray}{0.10}
|
131
131
|
\newenvironment{shaded_aside}[2]{\begin{full_framed_shaded}\begin{aside}\label{#2} \textbf{#1}\end{aside}}{\bigskip\end{full_framed_shaded}}
|
@@ -143,6 +143,6 @@
|
|
143
143
|
\vskip0.5em}%
|
144
144
|
}
|
145
145
|
|
146
|
-
% Add custom commands
|
147
|
-
\usepackage{custom}
|
146
|
+
% Add custom commands.
|
147
|
+
\usepackage{latex_styles/custom}
|
148
148
|
|
File without changes
|
File without changes
|
data/lib/softcover/uploader.rb
CHANGED
@@ -35,9 +35,15 @@ module Softcover
|
|
35
35
|
last_chunk = 0
|
36
36
|
c.on_progress do |_, _, ul_total, ul_now|
|
37
37
|
uploaded = ul_now > size ? size : ul_now
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
x = as_size(uploaded)
|
39
|
+
y = as_size(size)
|
40
|
+
x = y if x > y
|
41
|
+
begin
|
42
|
+
bar.send(:title=, "#{path} (#{x} / #{y})")
|
43
|
+
bar.progress += ul_now - last_chunk
|
44
|
+
rescue
|
45
|
+
nil
|
46
|
+
end
|
41
47
|
last_chunk = ul_now
|
42
48
|
true
|
43
49
|
end
|
data/lib/softcover/utils.rb
CHANGED
@@ -110,7 +110,7 @@ module Softcover::Utils
|
|
110
110
|
subtitle = manifest.subtitle.nil? ? "" : "\\subtitle{#{manifest.subtitle}}"
|
111
111
|
<<-EOS
|
112
112
|
\\documentclass[14pt]{extbook}
|
113
|
-
\\usepackage{softcover}
|
113
|
+
\\usepackage{#{Softcover::Directories::STYLES}/softcover}
|
114
114
|
\\VerbatimFootnotes % Allows verbatim text in footnotes
|
115
115
|
\\title{#{manifest.title}}
|
116
116
|
#{subtitle}
|
@@ -124,16 +124,17 @@ module Softcover::Utils
|
|
124
124
|
# Returns the tmp version of a filename.
|
125
125
|
# E.g., tmpify('foo.tex') => 'foo.tmp.tex'
|
126
126
|
def tmpify(manifest, filename)
|
127
|
-
|
127
|
+
tmp = Softcover::Directories::TMP
|
128
|
+
mkdir tmp
|
128
129
|
sep = File::SEPARATOR
|
129
|
-
filename.sub(manifest.polytex_dir + sep,
|
130
|
+
filename.sub(manifest.polytex_dir + sep, tmp + sep).
|
130
131
|
sub('.tex', '.tmp.tex')
|
131
132
|
end
|
132
133
|
|
133
134
|
# Writes a Pygments style file.
|
134
135
|
# We support both :html (outputting CSS) and :latex (outputting
|
135
136
|
# a LaTeX style file).
|
136
|
-
def write_pygments_file(format, path
|
137
|
+
def write_pygments_file(format, path)
|
137
138
|
require 'pygments'
|
138
139
|
extension = case format
|
139
140
|
when :html
|
data/lib/softcover/version.rb
CHANGED
data/softcover.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.add_dependency 'polytexnic', '~> 0.
|
21
|
+
gem.add_dependency 'polytexnic', '~> 0.8.0'
|
22
22
|
gem.add_dependency 'msgpack', '~> 0.4.2'
|
23
23
|
gem.add_dependency 'nokogiri', '~> 1.6.0'
|
24
24
|
gem.add_dependency 'thor'
|
data/spec/app_spec.rb
CHANGED
@@ -13,7 +13,7 @@ describe Softcover::App do
|
|
13
13
|
generate_book
|
14
14
|
Softcover::Builders::Html.new.build!
|
15
15
|
end
|
16
|
-
after(:all) { remove_book }
|
16
|
+
# after(:all) { remove_book }
|
17
17
|
|
18
18
|
before { chdir_to_book }
|
19
19
|
|
@@ -45,11 +45,22 @@ describe Softcover::App do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
describe 'serving files' do
|
48
|
+
|
48
49
|
it 'GET pygments.css' do
|
49
50
|
get '/stylesheets/pygments.css'
|
50
51
|
expect_server_response_of_type 'text/css'
|
51
52
|
end
|
52
53
|
|
54
|
+
it 'GET softcover.css' do
|
55
|
+
get '/stylesheets/softcover.css'
|
56
|
+
expect_server_response_of_type 'text/css'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'GET custom.css' do
|
60
|
+
get '/stylesheets/custom.css'
|
61
|
+
expect_server_response_of_type 'text/css'
|
62
|
+
end
|
63
|
+
|
53
64
|
it 'GET main.js' do
|
54
65
|
get '/main.js'
|
55
66
|
expect_server_response_of_type 'application/javascript'
|
data/spec/book_manifest_spec.rb
CHANGED
@@ -12,7 +12,6 @@ describe Softcover::BookManifest do
|
|
12
12
|
its(:title) { should eq "Title of the Book" }
|
13
13
|
its(:subtitle) { should eq "Change me" }
|
14
14
|
its(:description) { should eq "Change me." }
|
15
|
-
its(:cover) { should eq "images/cover.png" }
|
16
15
|
its(:author) { should eq "Author Name" }
|
17
16
|
end
|
18
17
|
|
data/spec/book_spec.rb
CHANGED
@@ -6,28 +6,36 @@ describe Softcover::Book do
|
|
6
6
|
before(:all) { generate_book(id: 1) }
|
7
7
|
after(:all) { remove_book }
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
describe "reading from book.yml" do
|
10
|
+
its(:filenames) { should_not include "html/test-book.html"}
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
its(:filenames) { should include "html/chapter-1_fragment.html"}
|
13
|
+
its(:filenames) { should_not include "html/chapter-1.html"}
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
its(:filenames) { should include "ebooks/test-book.mobi"}
|
16
|
+
its(:filenames) { should include "ebooks/test-book.epub"}
|
17
|
+
its(:filenames) { should include "ebooks/test-book.pdf"}
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
its(:slug) { should eq "book" }
|
20
|
+
its(:url) { should match /\/books\/(.*?)\/redirect/ }
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
it "sets chapter attributes" do
|
23
|
+
expect(subject.chapter_attributes.first[:menu_heading]).
|
24
|
+
to match /Frontmatter/
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has rendered latex in menu_heading" do
|
28
|
+
expect(subject.chapter_attributes.last[:menu_heading]).
|
29
|
+
to match /<em>/
|
30
|
+
end
|
25
31
|
end
|
26
32
|
|
27
|
-
|
28
|
-
|
29
|
-
|
33
|
+
describe "reading from marketing.yml" do
|
34
|
+
its(:prices) { should_not be_empty }
|
35
|
+
its(:faq) { should_not be_empty }
|
36
|
+
its(:testimonials) { should_not be_empty }
|
37
|
+
its(:marketing_content) { should be_empty }
|
30
38
|
end
|
31
39
|
end
|
32
40
|
end
|
33
|
-
end
|
41
|
+
end
|
data/spec/builders/html_spec.rb
CHANGED
@@ -29,6 +29,16 @@ describe Softcover::Builders::Html do
|
|
29
29
|
it { should match('pygments.css') }
|
30
30
|
context "HTML document" do
|
31
31
|
subject(:doc) { Nokogiri::HTML(output) }
|
32
|
+
|
33
|
+
context "frontmatter" do
|
34
|
+
subject(:frontmatter) { doc.at_css('#frontmatter') }
|
35
|
+
it { should_not be_nil }
|
36
|
+
it "should link the preface to the frontmatter page" do
|
37
|
+
link = '<a href="#preface"'
|
38
|
+
expect(frontmatter.to_xhtml).to match /#{link}/
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
32
42
|
context "first chapter" do
|
33
43
|
subject(:chapter) { doc.at_css('#cha-a_chapter') }
|
34
44
|
it { should_not be_nil }
|
@@ -72,14 +82,14 @@ describe Softcover::Builders::Html do
|
|
72
82
|
end
|
73
83
|
|
74
84
|
describe "contents" do
|
75
|
-
subject(:
|
85
|
+
subject(:doc) { Nokogiri::HTML(File.open(filename)) }
|
76
86
|
|
77
87
|
it "should include the title page" do
|
78
|
-
expect(
|
88
|
+
expect(doc.at_css('div#title_page')).not_to be_nil
|
79
89
|
end
|
80
90
|
|
81
91
|
it "should include the table of contents" do
|
82
|
-
expect(
|
92
|
+
expect(doc.at_css('div#table_of_contents')).not_to be_nil
|
83
93
|
end
|
84
94
|
end
|
85
95
|
end
|
@@ -123,6 +133,10 @@ describe Softcover::Builders::Html do
|
|
123
133
|
expect(Dir.glob(path('generated_polytex/*.tex'))).not_to be_empty
|
124
134
|
end
|
125
135
|
|
136
|
+
it "should write cache files" do
|
137
|
+
expect(Dir.glob(path('tmp/*.cache'))).not_to be_empty
|
138
|
+
end
|
139
|
+
|
126
140
|
describe "master LaTeX file" do
|
127
141
|
let(:master_file) { builder.master_filename(builder.manifest) }
|
128
142
|
subject { File.read(master_file) }
|
data/spec/builders/pdf_spec.rb
CHANGED
@@ -24,6 +24,11 @@ describe Softcover::Builders::Pdf do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
it "should prepend the fontsize verbatim declaration for source code" do
|
28
|
+
fontsize = '\begin{Verbatim}[fontsize=\relsize'
|
29
|
+
expect(File.read(Dir.glob('tmp/*.tmp.tex').first)).to include fontsize
|
30
|
+
end
|
31
|
+
|
27
32
|
it "should replace the main file's \\includes with tmp files" do
|
28
33
|
contents = File.read(Softcover::Utils.tmpify(builder.manifest,
|
29
34
|
'book.tex'))
|
@@ -37,11 +42,14 @@ describe Softcover::Builders::Pdf do
|
|
37
42
|
end
|
38
43
|
|
39
44
|
it "should create a Pygments style file" do
|
40
|
-
|
45
|
+
pygments = File.join(Softcover::Directories::STYLES, 'pygments.sty')
|
46
|
+
expect(pygments).to exist
|
41
47
|
end
|
42
48
|
|
43
49
|
it "should write the correct PolyTeXnic commands file" do
|
44
|
-
|
50
|
+
styles = File.join(Softcover::Directories::STYLES,
|
51
|
+
'polytexnic_commands.sty')
|
52
|
+
expect(File.read(styles)).to match /newcommand/
|
45
53
|
end
|
46
54
|
|
47
55
|
context "after removing Book.txt" do
|
@@ -26,7 +26,7 @@ describe Softcover::Commands::Generator do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
describe "book.yml" do
|
29
|
-
subject(:yml) { YAML.load_file(File.join name, 'book.yml') }
|
29
|
+
subject(:yml) { YAML.load_file(File.join name, 'config', 'book.yml') }
|
30
30
|
|
31
31
|
it "should have the right title" do
|
32
32
|
expect(yml['title']).to eq "Title of the Book"
|
@@ -93,16 +93,22 @@ describe Softcover::Commands::Generator do
|
|
93
93
|
describe "CSS" do
|
94
94
|
|
95
95
|
let(:css_file) { 'html/stylesheets/softcover.css' }
|
96
|
+
let(:custom_css) { 'html/stylesheets/custom.css' }
|
96
97
|
|
97
98
|
it "should have the right CSS file" do
|
98
99
|
expect(css_file).to exist
|
99
100
|
end
|
101
|
+
|
102
|
+
it "should have a custom CSS file" do
|
103
|
+
expect(custom_css).to exist
|
104
|
+
end
|
100
105
|
end
|
101
106
|
|
102
107
|
describe "styles" do
|
103
108
|
|
104
109
|
it "should have a right style file" do
|
105
|
-
|
110
|
+
style = File.join(Softcover::Directories::STYLES, 'softcover.sty')
|
111
|
+
expect(style).to exist
|
106
112
|
end
|
107
113
|
end
|
108
114
|
|
data/spec/webmock_helpers.rb
CHANGED
@@ -59,8 +59,11 @@ module WebmockHelpers
|
|
59
59
|
slug: book.slug,
|
60
60
|
subtitle: book.subtitle,
|
61
61
|
description: book.description,
|
62
|
-
|
63
|
-
|
62
|
+
chapters: book.chapter_attributes,
|
63
|
+
prices: book.prices,
|
64
|
+
faq: book.faq,
|
65
|
+
testimonials: book.testimonials,
|
66
|
+
marketing_content: ''
|
64
67
|
}.to_json,
|
65
68
|
:headers => headers).
|
66
69
|
to_return(:status => 200, :body => return_body, :headers => {})
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: softcover
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Hartl
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-12-
|
12
|
+
date: 2013-12-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: polytexnic
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 0.
|
20
|
+
version: 0.8.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ~>
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 0.
|
27
|
+
version: 0.8.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: msgpack
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -374,6 +374,12 @@ files:
|
|
374
374
|
- .pull_requests/1386099285
|
375
375
|
- .pull_requests/1386115582
|
376
376
|
- .pull_requests/1386448492
|
377
|
+
- .pull_requests/1387399930
|
378
|
+
- .pull_requests/1387400263
|
379
|
+
- .pull_requests/1387592428
|
380
|
+
- .pull_requests/1387944330
|
381
|
+
- .pull_requests/1388094706
|
382
|
+
- .pull_requests/1388441218
|
377
383
|
- .rspec
|
378
384
|
- Gemfile
|
379
385
|
- LICENSE.txt
|
@@ -403,6 +409,7 @@ files:
|
|
403
409
|
- lib/softcover/commands/publisher.rb
|
404
410
|
- lib/softcover/commands/server.rb
|
405
411
|
- lib/softcover/config.rb
|
412
|
+
- lib/softcover/directories.rb
|
406
413
|
- lib/softcover/formats.rb
|
407
414
|
- lib/softcover/mathjax.rb
|
408
415
|
- lib/softcover/output.rb
|
@@ -419,7 +426,6 @@ files:
|
|
419
426
|
- lib/softcover/template/.softcover-deploy
|
420
427
|
- lib/softcover/template/Book.txt
|
421
428
|
- lib/softcover/template/README.md
|
422
|
-
- lib/softcover/template/book.yml.erb
|
423
429
|
- lib/softcover/template/chapters/a_chapter.md
|
424
430
|
- lib/softcover/template/chapters/a_chapter.tex
|
425
431
|
- lib/softcover/template/chapters/another_chapter.md
|
@@ -428,11 +434,11 @@ files:
|
|
428
434
|
- lib/softcover/template/chapters/preface.tex
|
429
435
|
- lib/softcover/template/chapters/yet_another_chapter.md
|
430
436
|
- lib/softcover/template/chapters/yet_another_chapter.tex
|
431
|
-
- lib/softcover/template/
|
437
|
+
- lib/softcover/template/config/book.yml.erb
|
438
|
+
- lib/softcover/template/config/marketing.yml
|
432
439
|
- lib/softcover/template/epub/OEBPS/styles/.gitkeep
|
433
440
|
- lib/softcover/template/epub/OEBPS/styles/epub.css
|
434
441
|
- lib/softcover/template/epub/OEBPS/styles/page-template.xpgt
|
435
|
-
- lib/softcover/template/framed.sty
|
436
442
|
- lib/softcover/template/gitignore
|
437
443
|
- lib/softcover/template/html/.gitkeep
|
438
444
|
- lib/softcover/template/html/MathJax/MathJax.js
|
@@ -973,15 +979,19 @@ files:
|
|
973
979
|
- lib/softcover/template/html/jquery/1.10.2/jquery-1.10.2.js
|
974
980
|
- lib/softcover/template/html/jquery/1.10.2/jquery-1.10.2.min.map
|
975
981
|
- lib/softcover/template/html/stylesheets/.gitkeep
|
982
|
+
- lib/softcover/template/html/stylesheets/custom.css
|
976
983
|
- lib/softcover/template/html/stylesheets/softcover.css
|
977
984
|
- lib/softcover/template/images/.gitkeep
|
978
985
|
- lib/softcover/template/images/2011_michael_hartl.png
|
986
|
+
- lib/softcover/template/images/cover-web.png
|
979
987
|
- lib/softcover/template/images/cover.pdf
|
980
988
|
- lib/softcover/template/images/cover.png
|
981
989
|
- lib/softcover/template/images/figures/.gitkeep
|
982
|
-
- lib/softcover/template/
|
983
|
-
- lib/softcover/template/
|
984
|
-
- lib/softcover/template/
|
990
|
+
- lib/softcover/template/latex_styles/custom.sty
|
991
|
+
- lib/softcover/template/latex_styles/framed.sty
|
992
|
+
- lib/softcover/template/latex_styles/softcover.sty
|
993
|
+
- lib/softcover/template/latex_styles/upquote.sty
|
994
|
+
- lib/softcover/template/screencasts/.gitkeep
|
985
995
|
- lib/softcover/uploader.rb
|
986
996
|
- lib/softcover/utils.rb
|
987
997
|
- lib/softcover/version.rb
|
@@ -1 +0,0 @@
|
|
1
|
-
% Don't edit this file; it is overwritten every time the PDF gets built.
|