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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.pull_requests/1387399930 +0 -0
  3. data/.pull_requests/1387400263 +0 -0
  4. data/.pull_requests/1387592428 +0 -0
  5. data/.pull_requests/1387944330 +0 -0
  6. data/.pull_requests/1388094706 +0 -0
  7. data/.pull_requests/1388441218 +0 -0
  8. data/Gemfile +1 -0
  9. data/lib/softcover.rb +2 -1
  10. data/lib/softcover/book.rb +15 -5
  11. data/lib/softcover/book_manifest.rb +44 -5
  12. data/lib/softcover/builder.rb +27 -1
  13. data/lib/softcover/builders/epub.rb +17 -8
  14. data/lib/softcover/builders/html.rb +51 -12
  15. data/lib/softcover/builders/pdf.rb +14 -12
  16. data/lib/softcover/cli.rb +1 -0
  17. data/lib/softcover/commands/generator.rb +5 -3
  18. data/lib/softcover/commands/publisher.rb +3 -0
  19. data/lib/softcover/commands/server.rb +2 -2
  20. data/lib/softcover/directories.rb +5 -0
  21. data/lib/softcover/server/app.rb +1 -25
  22. data/lib/softcover/server/views/book.html.erb +1 -0
  23. data/lib/softcover/template/chapters/a_chapter.tex +2 -2
  24. data/lib/softcover/template/{book.yml.erb → config/book.yml.erb} +0 -1
  25. data/lib/softcover/template/config/marketing.yml +71 -0
  26. data/lib/softcover/template/html/stylesheets/custom.css +15 -0
  27. data/lib/softcover/template/images/cover-web.png +0 -0
  28. data/lib/softcover/template/{custom.sty → latex_styles/custom.sty} +0 -0
  29. data/lib/softcover/template/{framed.sty → latex_styles/framed.sty} +0 -0
  30. data/lib/softcover/template/{softcover.sty → latex_styles/softcover.sty} +6 -6
  31. data/lib/softcover/template/{upquote.sty → latex_styles/upquote.sty} +0 -0
  32. data/lib/softcover/template/screencasts/.gitkeep +0 -0
  33. data/lib/softcover/uploader.rb +9 -3
  34. data/lib/softcover/utils.rb +5 -4
  35. data/lib/softcover/version.rb +1 -1
  36. data/softcover.gemspec +1 -1
  37. data/spec/app_spec.rb +12 -1
  38. data/spec/book_manifest_spec.rb +0 -1
  39. data/spec/book_spec.rb +24 -16
  40. data/spec/builders/html_spec.rb +17 -3
  41. data/spec/builders/pdf_spec.rb +10 -2
  42. data/spec/commands/generator_spec.rb +8 -2
  43. data/spec/webmock_helpers.rb +5 -2
  44. metadata +20 -10
  45. data/lib/softcover/template/polytexnic_commands.sty +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a0c89273e495d59b500f34a6c72f3994fdcd5437
4
- data.tar.gz: 7ccaefc71bd47fa7bb2e413ec9237887a0c870a8
3
+ metadata.gz: 4e55cdffedc838f8932586db5eff983d9a84dd4b
4
+ data.tar.gz: fc341b0355f009345ef895b9d57a24ed9a651412
5
5
  SHA512:
6
- metadata.gz: c4ca22081fa2754e8e12af46337de659db136084eda0ab6888ce9a099c1125348b3e2778101a88bbaef725ff7f125d5a2dda5f7e05e834011c8d3ac75c1c8b2a
7
- data.tar.gz: f3b9d3238f4b902c8274cf44b868b029da36db2c30311eb7059f069af9b38fa9d9d9be75230a8f90dea822b74d5a6d2507bee4ac89f6c449d635faa9365f31f6
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
@@ -8,6 +8,7 @@ group :test do
8
8
  gem 'webmock', require: false
9
9
  gem 'simplecov', require: false
10
10
  gem 'rack-test'
11
+ gem 'ruby-prof'
11
12
  end
12
13
 
13
14
  group :development do
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
 
@@ -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
- cover: cover,
105
- chapters: chapter_attributes
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?# && upload_screencast!(file)
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
- Dir["#{@screencasts_dir}/**/*.mov"].map{ |path| BookFile.new path }
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
- def path
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 = "book.yml"
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
- YAML.load_file(YAML_PATH)
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
 
@@ -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
- Polytexnic.write_polytexnic_style_file(Dir.pwd)
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!(preserve_tex: true)
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/html/*.html')))
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 = File.join(template_dir, epub_styles, 'epub.css')
226
+ epub_css = File.join(template_dir, epub_styles, 'epub.css')
225
227
  FileUtils.cp(epub_css, epub_styles)
226
228
 
227
- # For some reason, EPUB books hate the #book ids in the stylesheet
228
- # (i.e., such books fail to validate), so remove them.
229
- polytexnic_css = File.read(File.join(html_styles, 'softcover.css'))
230
- polytexnic_css.gsub!(/\s*#book\s+/, '')
231
- File.write(File.join(epub_styles, 'softcover.css'), polytexnic_css)
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
- unless File.directory?(path('html/stylesheets'))
11
- Dir.mkdir path('html/stylesheets')
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
- FileUtils.rm(Dir.glob(path("#{manifest.polytex_dir}/*.tex")))
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
- '../server/views/book.html.erb'))
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
- filename = path("#{manifest.polytex_dir}/#{chapter.slug}.tex")
76
+ polytex_filename = path("#{manifest.polytex_dir}/#{chapter.slug}.tex")
61
77
  if chapter.source == :polytex
62
- FileUtils.cp path("chapters/#{chapter.full_name}"), filename
78
+ FileUtils.cp path("chapters/#{chapter.full_name}"), polytex_filename
63
79
  else
64
- path = File.join('chapters', chapter.full_name)
65
- cc = Softcover.custom_styles
66
- md = Polytexnic::Pipeline.new(File.read(path), source: :markdown,
67
- custom_commands: cc)
68
- File.write(filename, md.polytex)
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 = ref_map[target['data-tralics-id']]
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.open(filename) { |f| f.read }
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.open(Softcover::Utils.tmpify(manifest, filename), 'w') do |f|
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)} ; #{rename_pdf(basename)}"
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
- "mv -f #{tmp_pdf} #{File.join('ebooks', pdf)}"
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 PolyTeXnic style file to ensure it's always fresh.
117
+ # Copies the style file to ensure it's always fresh.
117
118
  def copy_polytexnic_sty
118
- polytexnic_sty = 'softcover.sty'
119
+ softcover_sty = File.join(Softcover::Directories::STYLES,
120
+ 'softcover.sty')
119
121
  source_sty = File.join(File.dirname(__FILE__),
120
- "../template/#{polytexnic_sty}")
121
- FileUtils.cp source_sty, polytexnic_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.basename path.dup, '.erb'
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
- puts "Done. Please update book.yml"
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__), "../template"
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(preserve_tex: true)
47
+ builder.build
48
48
  puts "Done. (#{(Time.now - t).round(2)}s)"
49
49
 
50
50
  rescue Softcover::BookManifest::NotFound => e
@@ -0,0 +1,5 @@
1
+ module Softcover::Directories
2
+ CONFIG = 'config'
3
+ TMP = 'tmp'
4
+ STYLES = 'latex_styles'
5
+ end
@@ -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, File.join(File.dirname(__FILE__),'../template/html')
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}).
@@ -7,6 +7,5 @@ description: Change me.
7
7
  author: Author Name
8
8
  copyright: <%= Time.new.year %>
9
9
  uuid: <%= SecureRandom.uuid %>
10
- cover: images/cover.png
11
10
  pdf_preview_page_range: 1..30
12
11
  epub_mobi_preview_chapter_range: 0..1
@@ -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
+ */
@@ -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
@@ -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
- bar.send(:title=, "#{path} (#{as_size uploaded} / #{as_size size})")
40
- bar.progress += ul_now - last_chunk rescue nil
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
@@ -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
- mkdir 'tmp'
127
+ tmp = Softcover::Directories::TMP
128
+ mkdir tmp
128
129
  sep = File::SEPARATOR
129
- filename.sub(manifest.polytex_dir + sep, 'tmp' + 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
@@ -1,3 +1,3 @@
1
1
  module Softcover
2
- VERSION = "0.7.11"
2
+ VERSION = "0.8.0"
3
3
  end
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.7.6'
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'
@@ -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
- # disabling these tests for now:
10
- its(:filenames) { should_not include "html/test-book.html"}
9
+ describe "reading from book.yml" do
10
+ its(:filenames) { should_not include "html/test-book.html"}
11
11
 
12
- its(:filenames) { should include "html/chapter-1_fragment.html"}
13
- its(:filenames) { should_not include "html/chapter-1.html"}
12
+ its(:filenames) { should include "html/chapter-1_fragment.html"}
13
+ its(:filenames) { should_not include "html/chapter-1.html"}
14
14
 
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"}
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
- its(:slug) { should eq "book" }
20
- its(:url) { should match /\/books\/(.*?)\/redirect/ }
19
+ its(:slug) { should eq "book" }
20
+ its(:url) { should match /\/books\/(.*?)\/redirect/ }
21
21
 
22
- it "sets chapter attributes" do
23
- expect(subject.chapter_attributes.first[:menu_heading]).
24
- to match /Frontmatter/
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
- it "has rendered latex in menu_heading" do
28
- expect(subject.chapter_attributes.last[:menu_heading]).
29
- to match /<em>/
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
@@ -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(:html) { Nokogiri::HTML(File.open(filename)) }
85
+ subject(:doc) { Nokogiri::HTML(File.open(filename)) }
76
86
 
77
87
  it "should include the title page" do
78
- expect(html.at_css('div#title_page')).not_to be_nil
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(html.at_css('div#table_of_contents')).not_to be_nil
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) }
@@ -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
- expect('pygments.sty').to exist
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
- expect(File.read('polytexnic_commands.sty')).to match /newcommand/
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
- expect('softcover.sty').to exist
110
+ style = File.join(Softcover::Directories::STYLES, 'softcover.sty')
111
+ expect(style).to exist
106
112
  end
107
113
  end
108
114
 
@@ -59,8 +59,11 @@ module WebmockHelpers
59
59
  slug: book.slug,
60
60
  subtitle: book.subtitle,
61
61
  description: book.description,
62
- cover: book.cover,
63
- chapters: book.chapter_attributes
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.7.11
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-18 00:00:00.000000000 Z
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.7.6
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.7.6
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/custom.sty
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/polytexnic_commands.sty
983
- - lib/softcover/template/softcover.sty
984
- - lib/softcover/template/upquote.sty
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.