softcover 0.6.1 → 0.6.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 +4 -4
- data/{lib/softcover/template/generated_polytex/.gitkeep → .pull_requests/1384468478} +0 -0
- data/lib/softcover/book_manifest.rb +26 -6
- data/lib/softcover/builder.rb +1 -16
- data/lib/softcover/builders/epub.rb +2 -3
- data/lib/softcover/builders/html.rb +5 -7
- data/lib/softcover/builders/pdf.rb +9 -12
- data/lib/softcover/commands/server.rb +1 -1
- data/lib/softcover/server/app.rb +2 -1
- data/lib/softcover/template/chapters/a_chapter.md +1 -1
- data/lib/softcover/template/chapters/a_chapter.tex +0 -1
- data/lib/softcover/utils.rb +3 -2
- data/lib/softcover/version.rb +1 -1
- data/spec/builders/html_spec.rb +10 -9
- data/spec/builders/pdf_spec.rb +8 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df5fc92cddff6bd934a2ac83265b7577f09d6fcd
|
4
|
+
data.tar.gz: e894e67dd71e366249e23083a92f0c81d76e1680
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d4766cf6a4cb4dc2381a276a6736294297a39b4aaff78df690e6ee726e1e36c9a29b2b4de6aa6072caffe06a6c29ecbce888229624b6497af31a1730044cd5c
|
7
|
+
data.tar.gz: b15fcf53ea90b1813065b0b80885d3095e855dc27f4d1f4ed6ba02796ce9745c04dbeedec9fdd811ce5f2b8e4ab2f18cfbdd5dcdeb4d59b02d62321b09b4145b
|
File without changes
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
|
3
3
|
class Softcover::BookManifest < OpenStruct
|
4
|
+
include Softcover::Utils
|
5
|
+
|
4
6
|
class NotFound < StandardError
|
5
7
|
def message
|
6
8
|
"Invalid book directory, no manifest file found!"
|
@@ -44,6 +46,7 @@ class Softcover::BookManifest < OpenStruct
|
|
44
46
|
|
45
47
|
def initialize(options = {})
|
46
48
|
@source = options[:source] || :polytex
|
49
|
+
@origin = options[:origin]
|
47
50
|
yaml_attrs = read_from_yml
|
48
51
|
attrs = case
|
49
52
|
when polytex? then yaml_attrs
|
@@ -76,7 +79,7 @@ class Softcover::BookManifest < OpenStruct
|
|
76
79
|
chapter_includes(base_contents).each_with_index do |name, i|
|
77
80
|
slug = File.basename(name, '.*')
|
78
81
|
title_regex = /^\s*\\chapter{(.*)}/
|
79
|
-
content = File.read(File.join(
|
82
|
+
content = File.read(File.join(polytex_dir, slug + '.tex'))
|
80
83
|
title = content[title_regex, 1]
|
81
84
|
j = 0
|
82
85
|
sections = content.scan(/^\s*\\section{(.*)}/).flatten.map do |name|
|
@@ -91,9 +94,19 @@ class Softcover::BookManifest < OpenStruct
|
|
91
94
|
verify_paths! if options[:verify_paths]
|
92
95
|
end
|
93
96
|
|
97
|
+
# Returns the directory where the LaTeX files are located.
|
98
|
+
# We put them in the a separate directory when using them as an intermediate
|
99
|
+
# format when working with Markdown books. Otherwise, we use the chapters
|
100
|
+
# directory, which is the default location when writing LaTeX/PolyTeX books.
|
101
|
+
def polytex_dir
|
102
|
+
dir = (markdown? || @origin == :markdown) ? 'generated_polytex' : 'chapters'
|
103
|
+
mkdir dir
|
104
|
+
dir
|
105
|
+
end
|
106
|
+
|
94
107
|
# Returns an array of the chapters to include.
|
95
108
|
def chapter_includes(string)
|
96
|
-
chapter_regex = /^\s*\\include\{
|
109
|
+
chapter_regex = /^\s*\\include\{#{polytex_dir}\/(.*?)\}/
|
97
110
|
string.scan(chapter_regex).flatten
|
98
111
|
end
|
99
112
|
|
@@ -136,12 +149,14 @@ class Softcover::BookManifest < OpenStruct
|
|
136
149
|
@source == :polytex
|
137
150
|
end
|
138
151
|
|
139
|
-
# Returns an iterator the chapter file paths.
|
152
|
+
# Returns an iterator for the chapter file paths.
|
140
153
|
def chapter_file_paths
|
141
154
|
pdf_chapter_names.map do |name|
|
142
155
|
file_path = case
|
143
|
-
when markdown?
|
144
|
-
|
156
|
+
when markdown? || @origin == :markdown
|
157
|
+
File.join("chapters", "#{name}.md")
|
158
|
+
when polytex?
|
159
|
+
File.join("chapters", "#{name}.tex")
|
145
160
|
end
|
146
161
|
|
147
162
|
yield file_path if block_given?
|
@@ -150,7 +165,7 @@ class Softcover::BookManifest < OpenStruct
|
|
150
165
|
end
|
151
166
|
end
|
152
167
|
|
153
|
-
#
|
168
|
+
# Returns chapters for the PDF.
|
154
169
|
# The frontmatter pseudo-chapter exists for the sake of HTML/EPUB/MOBI, so
|
155
170
|
# it's not returned as part of the chapters.
|
156
171
|
def pdf_chapter_names
|
@@ -159,6 +174,11 @@ class Softcover::BookManifest < OpenStruct
|
|
159
174
|
frontmatter? ? frontmatter + chaps : chaps
|
160
175
|
end
|
161
176
|
|
177
|
+
# Returns the full chapter filenames for the PDF.
|
178
|
+
def pdf_chapter_filenames
|
179
|
+
pdf_chapter_names.map { |name| File.join(polytex_dir, "#{name}.tex") }
|
180
|
+
end
|
181
|
+
|
162
182
|
def find_chapter_by_slug(slug)
|
163
183
|
chapters.find { |chapter| chapter.slug == slug }
|
164
184
|
end
|
data/lib/softcover/builder.rb
CHANGED
@@ -6,7 +6,7 @@ module Softcover
|
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
@manifest = Softcover::BookManifest.new(verify_paths: true,
|
9
|
-
|
9
|
+
source: source)
|
10
10
|
@built_files = []
|
11
11
|
write_polytexnic_commands_file
|
12
12
|
end
|
@@ -18,21 +18,6 @@ module Softcover
|
|
18
18
|
self
|
19
19
|
end
|
20
20
|
|
21
|
-
# Returns true if we should remove the generated PolyTeX.
|
22
|
-
# This is true of Markdown books, but we can't just use `markdown?` because
|
23
|
-
# we're re-using the PolyTeX production pipeline.
|
24
|
-
def remove_polytex?
|
25
|
-
@remove_tex
|
26
|
-
end
|
27
|
-
|
28
|
-
# Removes the generated PolyTeX.
|
29
|
-
# The 'removal' actually just involves moving it to an ignored storage
|
30
|
-
# directory. This gives users the ability to inspect it if desired.
|
31
|
-
def remove_polytex!
|
32
|
-
mkdir 'generated_polytex'
|
33
|
-
FileUtils.mv(Dir.glob(path('chapters/*.tex')), 'generated_polytex')
|
34
|
-
end
|
35
|
-
|
36
21
|
def clean!; end
|
37
22
|
|
38
23
|
private
|
@@ -7,8 +7,8 @@ module Softcover
|
|
7
7
|
@preview = options[:preview]
|
8
8
|
Softcover::Builders::Html.new.build!(preserve_tex: true)
|
9
9
|
if manifest.markdown?
|
10
|
-
self.manifest = Softcover::BookManifest.new(source: :polytex
|
11
|
-
|
10
|
+
self.manifest = Softcover::BookManifest.new(source: :polytex,
|
11
|
+
origin: :markdown)
|
12
12
|
end
|
13
13
|
remove_html
|
14
14
|
create_directories
|
@@ -22,7 +22,6 @@ module Softcover
|
|
22
22
|
create_style_files
|
23
23
|
make_epub(options)
|
24
24
|
move_epub
|
25
|
-
remove_polytex! if remove_polytex?
|
26
25
|
end
|
27
26
|
|
28
27
|
# Returns true if generating a book preview.
|
@@ -20,7 +20,7 @@ module Softcover
|
|
20
20
|
|
21
21
|
if manifest.markdown?
|
22
22
|
unless options[:'find-overfull']
|
23
|
-
FileUtils.rm(Dir.glob(path(
|
23
|
+
FileUtils.rm(Dir.glob(path("#{manifest.polytex_dir}/*.tex")))
|
24
24
|
end
|
25
25
|
manifest.chapters.each do |chapter|
|
26
26
|
write_latex_files(chapter, options)
|
@@ -28,8 +28,8 @@ module Softcover
|
|
28
28
|
rewrite_master_latex_file
|
29
29
|
# Reset the manifest to use PolyTeX.
|
30
30
|
self.manifest = Softcover::BookManifest.new(source: :polytex,
|
31
|
-
verify_paths: true
|
32
|
-
|
31
|
+
verify_paths: true,
|
32
|
+
origin: :markdown)
|
33
33
|
end
|
34
34
|
|
35
35
|
if manifest.polytex?
|
@@ -49,8 +49,6 @@ module Softcover
|
|
49
49
|
printer.print(STDOUT, {})
|
50
50
|
end
|
51
51
|
|
52
|
-
remove_polytex! if remove_polytex?
|
53
|
-
|
54
52
|
true
|
55
53
|
end
|
56
54
|
|
@@ -60,7 +58,7 @@ module Softcover
|
|
60
58
|
cc = Softcover.custom_styles
|
61
59
|
md = Polytexnic::Pipeline.new(File.read(path), source: :md,
|
62
60
|
custom_commands: cc)
|
63
|
-
filename = path("
|
61
|
+
filename = path("#{manifest.polytex_dir}/#{chapter.slug}.tex")
|
64
62
|
File.write(filename, md.polytex)
|
65
63
|
end
|
66
64
|
|
@@ -71,7 +69,7 @@ module Softcover
|
|
71
69
|
tex_file = []
|
72
70
|
lines.each do |line|
|
73
71
|
if line =~ /(.*)\.md\s*$/
|
74
|
-
tex_file << "\\include{
|
72
|
+
tex_file << "\\include{#{manifest.polytex_dir}/#{$1}}"
|
75
73
|
elsif line =~ /(.*):\s*$/ # frontmatter or mainmatter
|
76
74
|
tex_file << "\\#{$1}"
|
77
75
|
elsif line.strip == 'cover'
|
@@ -8,13 +8,12 @@ module Softcover
|
|
8
8
|
# Build the HTML to produce PolyTeX as a side-effect,
|
9
9
|
# then update the manifest to reduce PDF generation
|
10
10
|
# to a previously solved problem.
|
11
|
-
Softcover::Builders::Html.new.build!
|
12
|
-
|
13
|
-
|
14
|
-
@remove_tex = true unless options[:preserve_tex]
|
11
|
+
Softcover::Builders::Html.new.build!
|
12
|
+
self.manifest = Softcover::BookManifest.new(source: :polytex,
|
13
|
+
origin: :markdown)
|
15
14
|
end
|
16
15
|
# Build the PolyTeX filename so it accepts both 'foo' and 'foo.tex'.
|
17
|
-
basename = File.basename(
|
16
|
+
basename = File.basename(manifest.filename, '.tex')
|
18
17
|
book_filename = basename + '.tex'
|
19
18
|
|
20
19
|
# In debug mode, execute `xelatex` and exit.
|
@@ -36,27 +35,25 @@ module Softcover
|
|
36
35
|
return
|
37
36
|
end
|
38
37
|
|
39
|
-
polytex_filenames =
|
40
|
-
polytex_filenames.delete(path('chapters/frontmatter.tex'))
|
38
|
+
polytex_filenames = manifest.pdf_chapter_filenames << book_filename
|
41
39
|
polytex_filenames.each do |filename|
|
42
40
|
puts filename unless options[:quiet] || options[:silent]
|
43
41
|
polytex = File.open(filename) { |f| f.read }
|
44
42
|
latex = Polytexnic::Pipeline.new(polytex).to_latex
|
45
43
|
if filename == book_filename
|
46
44
|
latex.gsub!(/\\include{(.*?)}/) do
|
47
|
-
"\\include{#{Softcover::Utils.tmpify($1)}.tmp}"
|
45
|
+
"\\include{#{Softcover::Utils.tmpify(manifest, $1)}.tmp}"
|
48
46
|
end
|
49
47
|
end
|
50
|
-
File.open(Softcover::Utils.tmpify(filename), 'w') do |f|
|
48
|
+
File.open(Softcover::Utils.tmpify(manifest, filename), 'w') do |f|
|
51
49
|
f.write(latex)
|
52
50
|
end
|
53
51
|
end
|
54
52
|
write_pygments_file(:latex)
|
55
53
|
copy_polytexnic_sty
|
56
54
|
|
57
|
-
|
58
|
-
|
59
|
-
build_pdf = "#{xelatex} #{Softcover::Utils.tmpify(book_filename)}"
|
55
|
+
tmp_filename = Softcover::Utils.tmpify(manifest, book_filename)
|
56
|
+
build_pdf = "#{xelatex} #{tmp_filename}"
|
60
57
|
# Run the command twice (to guarantee up-to-date cross-references)
|
61
58
|
# unless explicitly overriden.
|
62
59
|
# Renaming the PDF in the command is necessary because `execute`
|
@@ -12,7 +12,7 @@ module Softcover::Commands::Server
|
|
12
12
|
server_pid = Process.pid
|
13
13
|
directories = ['.', 'chapters']
|
14
14
|
@listener = Listen.to(*directories)
|
15
|
-
file_pattern = markdown? ? '\.md' : '\.tex'
|
15
|
+
file_pattern = markdown? ? '\.md|\.txt' : '\.tex'
|
16
16
|
@listener.filter(/(#{file_pattern}|custom\.sty)$/)
|
17
17
|
|
18
18
|
@listener.change do |modified|
|
data/lib/softcover/server/app.rb
CHANGED
@@ -13,7 +13,8 @@ class Softcover::App < Sinatra::Base
|
|
13
13
|
end
|
14
14
|
|
15
15
|
before do
|
16
|
-
|
16
|
+
origin = Dir.glob('chapters/*.md').empty? ? :polytex : :markdown
|
17
|
+
@manifest = Softcover::BookManifest.new(foo: "bar", origin: origin)
|
17
18
|
end
|
18
19
|
|
19
20
|
get '/' do
|
@@ -14,7 +14,7 @@ This is a section. You can refer to it using the \LaTeX\ cross-reference syntax,
|
|
14
14
|
|
15
15
|
This is a subsection.
|
16
16
|
|
17
|
-
You can typeset code samples and other verbatim text using four
|
17
|
+
You can typeset code samples and other verbatim text using four spaces of indentation:
|
18
18
|
|
19
19
|
def hello
|
20
20
|
puts "hello, world"
|
@@ -20,7 +20,6 @@ Softcover comes with full support for syntax-highlighted source code:
|
|
20
20
|
\begin{code}
|
21
21
|
def hello
|
22
22
|
puts "hello, world!"
|
23
|
-
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod t"
|
24
23
|
end
|
25
24
|
\end{code}
|
26
25
|
\noindent Softcover can highlight any language supported by \href{http://pygments.org/languages/}{Pygments} (which means most of them).
|
data/lib/softcover/utils.rb
CHANGED
@@ -51,9 +51,10 @@ module Softcover::Utils
|
|
51
51
|
|
52
52
|
# Returns the tmp version of a filename.
|
53
53
|
# E.g., tmpify('foo.tex') => 'foo.tmp.tex'
|
54
|
-
def tmpify(filename)
|
54
|
+
def tmpify(manifest, filename)
|
55
55
|
sep = File::SEPARATOR
|
56
|
-
filename.sub(
|
56
|
+
filename.sub(manifest.polytex_dir + sep, 'tmp' + sep).
|
57
|
+
sub('.tex', '.tmp.tex')
|
57
58
|
end
|
58
59
|
|
59
60
|
# Writes a Pygments style file.
|
data/lib/softcover/version.rb
CHANGED
data/spec/builders/html_spec.rb
CHANGED
@@ -98,15 +98,17 @@ describe Softcover::Builders::Html do
|
|
98
98
|
describe "when generating from Markdown source" do
|
99
99
|
before(:all) do
|
100
100
|
generate_book(markdown: true)
|
101
|
-
@file_to_be_removed = path('chapters/should_be_removed.tex')
|
102
|
-
File.write(@file_to_be_removed, '')
|
103
101
|
end
|
104
102
|
after(:all) { remove_book }
|
105
103
|
|
106
104
|
describe "#build!" do
|
107
105
|
subject(:builder) { Softcover::Builders::Html.new }
|
108
106
|
|
109
|
-
before
|
107
|
+
before do
|
108
|
+
@file_to_be_removed = path("#{builder.manifest.polytex_dir}/remove.tex")
|
109
|
+
File.write(@file_to_be_removed, '')
|
110
|
+
builder.build!
|
111
|
+
end
|
110
112
|
|
111
113
|
its(:built_files) { should include "html/a_chapter.html" }
|
112
114
|
its(:built_files) { should include "html/a_chapter_fragment.html" }
|
@@ -117,18 +119,17 @@ describe Softcover::Builders::Html do
|
|
117
119
|
expect(@file_to_be_removed).not_to exist
|
118
120
|
end
|
119
121
|
|
120
|
-
it "should
|
121
|
-
expect(Dir.glob(path('chapters/*.tex'))).to be_empty
|
122
|
+
it "should include generated LaTeX files" do
|
122
123
|
expect(Dir.glob(path('generated_polytex/*.tex'))).not_to be_empty
|
123
124
|
end
|
124
125
|
|
125
126
|
describe "master LaTeX file" do
|
126
127
|
let(:master_file) { Dir['*.tex'].reject { |f| f =~ /\.tmp/}.first }
|
127
128
|
subject { File.read(master_file) }
|
128
|
-
it { should include '\include{
|
129
|
-
it { should include '\include{
|
130
|
-
it { should include '\include{
|
131
|
-
it { should include '\include{
|
129
|
+
it { should include '\include{generated_polytex/preface}' }
|
130
|
+
it { should include '\include{generated_polytex/a_chapter}' }
|
131
|
+
it { should include '\include{generated_polytex/another_chapter}' }
|
132
|
+
it { should include '\include{generated_polytex/yet_another_chapter}' }
|
132
133
|
it { should include '\end{document}' }
|
133
134
|
end
|
134
135
|
end
|
data/spec/builders/pdf_spec.rb
CHANGED
@@ -15,17 +15,18 @@ describe Softcover::Builders::Pdf do
|
|
15
15
|
describe "#build!" do
|
16
16
|
|
17
17
|
it "should create a tmp LaTeX file" do
|
18
|
-
expect(Softcover::Utils.tmpify('book.tex')).to exist
|
18
|
+
expect(Softcover::Utils.tmpify(builder.manifest, 'book.tex')).to exist
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should create tmp files for all chapters" do
|
22
22
|
builder.manifest.chapter_file_paths.each do |filename|
|
23
|
-
expect(Softcover::Utils.tmpify(filename)).to exist
|
23
|
+
expect(Softcover::Utils.tmpify(builder.manifest, filename)).to exist
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should replace the main file's \\includes with tmp files" do
|
28
|
-
contents = File.read(Softcover::Utils.tmpify(
|
28
|
+
contents = File.read(Softcover::Utils.tmpify(builder.manifest,
|
29
|
+
'book.tex'))
|
29
30
|
builder.manifest.pdf_chapter_names.each do |name|
|
30
31
|
expect(contents).to match("\\include{tmp/#{name}.tmp}")
|
31
32
|
end
|
@@ -58,22 +59,19 @@ describe Softcover::Builders::Pdf do
|
|
58
59
|
describe "#build!" do
|
59
60
|
|
60
61
|
it "should create a tmp LaTeX file" do
|
61
|
-
expect(Softcover::Utils.tmpify('book.tex')).to exist
|
62
|
+
expect(Softcover::Utils.tmpify(builder.manifest, 'book.tex')).to exist
|
62
63
|
end
|
63
64
|
|
64
65
|
describe "LaTeX file" do
|
65
|
-
subject(:content)
|
66
|
+
subject(:content) do
|
67
|
+
File.read(Softcover::Utils.tmpify(builder.manifest, 'book.tex'))
|
68
|
+
end
|
66
69
|
it { should_not be_empty }
|
67
70
|
it { should include '\includepdf{images/cover.pdf}' }
|
68
71
|
it { should include '\maketitle' }
|
69
72
|
it { should include '\tableofcontents' }
|
70
73
|
it { should include '\include{tmp/a_chapter.tmp}' }
|
71
74
|
end
|
72
|
-
|
73
|
-
|
74
|
-
it "should remove the generated LaTeX files" do
|
75
|
-
expect(Dir.glob(path('chapters/*.tex'))).to be_empty
|
76
|
-
end
|
77
75
|
end
|
78
76
|
end
|
79
77
|
end
|
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.6.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Hartl
|
@@ -362,6 +362,7 @@ files:
|
|
362
362
|
- .pull_requests/1384207054
|
363
363
|
- .pull_requests/1384304643
|
364
364
|
- .pull_requests/1384447036
|
365
|
+
- .pull_requests/1384468478
|
365
366
|
- .rspec
|
366
367
|
- .ruby-gemset
|
367
368
|
- .ruby-version
|
@@ -423,7 +424,6 @@ files:
|
|
423
424
|
- lib/softcover/template/epub/OEBPS/styles/epub.css
|
424
425
|
- lib/softcover/template/epub/OEBPS/styles/page-template.xpgt
|
425
426
|
- lib/softcover/template/framed.sty
|
426
|
-
- lib/softcover/template/generated_polytex/.gitkeep
|
427
427
|
- lib/softcover/template/gitignore
|
428
428
|
- lib/softcover/template/html/.gitkeep
|
429
429
|
- lib/softcover/template/html/MathJax/MathJax.js
|