wordsmith 0.0.2 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile.lock +10 -6
- data/README.md +28 -15
- data/Rakefile +3 -2
- data/bin/wordsmith +3 -5
- data/lib/wordsmith.rb +10 -10
- data/lib/wordsmith/cli.rb +1 -1
- data/lib/wordsmith/generate.rb +177 -89
- data/lib/wordsmith/init.rb +3 -3
- data/lib/wordsmith/version.rb +2 -2
- data/template/.wordsmith +4 -1
- data/template/assets/stylesheets/{default.css → _partial.scss} +3 -17
- data/template/assets/stylesheets/_with_sass.scss +8 -0
- data/template/assets/stylesheets/epub.css +44 -0
- data/template/assets/stylesheets/master.scss +2 -0
- data/template/assets/stylesheets/other.css +10 -0
- data/test/css_test.rb +60 -0
- data/test/generate_test.rb +35 -3
- data/test/init_test.rb +9 -1
- data/test/sass_test.rb +49 -0
- data/wordsmith.gemspec +4 -2
- metadata +49 -39
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3ba51f5ebeeeb48a9dfc57e523b20bdfc349c7f3
|
4
|
+
data.tar.gz: 085af8ce32876d4a1d6bac36d4db1779482b349d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 64a3a77b9047716d9c88add36d9f417e155a01326c8069e4bed55d9f1cf922f81ecfa54429e8d24652f7750e6c45884220f5abd023adab6318a600d09da9af10
|
7
|
+
data.tar.gz: a53b78251c9acd1f669bb483514d5e06dec48f3b1b7ccc9a3599e19591ee4ec48efa69e1d1f08d25a6f6fd9a1eb9f25d57bdbc1f30d023b0a73b44400e7828ea
|
data/Gemfile.lock
CHANGED
@@ -1,20 +1,24 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
wordsmith (0.0.
|
4
|
+
wordsmith (0.0.6)
|
5
5
|
git
|
6
|
-
kindlegen (
|
7
|
-
nokogiri (
|
6
|
+
kindlegen (~> 2.3)
|
7
|
+
nokogiri (~> 1.5)
|
8
|
+
sass (~> 3.1)
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: http://rubygems.org/
|
11
12
|
specs:
|
12
|
-
git (1.2.
|
13
|
+
git (1.2.6)
|
13
14
|
kindlegen (2.8.0)
|
14
15
|
systemu
|
15
|
-
|
16
|
+
mini_portile (0.5.2)
|
17
|
+
nokogiri (1.6.1)
|
18
|
+
mini_portile (~> 0.5.0)
|
16
19
|
rake (0.9.2.2)
|
17
|
-
|
20
|
+
sass (3.2.13)
|
21
|
+
systemu (2.6.0)
|
18
22
|
test-unit (2.4.8)
|
19
23
|
|
20
24
|
PLATFORMS
|
data/README.md
CHANGED
@@ -50,8 +50,10 @@ need to start creating your own content without worrying about anything else.
|
|
50
50
|
images/
|
51
51
|
cover.jpg
|
52
52
|
stylesheets/
|
53
|
-
|
54
|
-
|
53
|
+
master.scss
|
54
|
+
_partial.scss
|
55
|
+
other.css
|
56
|
+
epub.css
|
55
57
|
content/
|
56
58
|
01_chapter_one.md
|
57
59
|
02_chapter_two.md
|
@@ -69,15 +71,23 @@ You can edit your book metadata inside the **.wordsmith** file:
|
|
69
71
|
---
|
70
72
|
edition: 0.1
|
71
73
|
language: en
|
72
|
-
author: Your Name
|
74
|
+
author: Your Name; Additional author
|
73
75
|
title: Your Book Title
|
74
76
|
cover: assets/images/cover.jpg
|
75
|
-
|
77
|
+
|
78
|
+
# Other configuration options
|
79
|
+
# font: YOUR_FONT_FAMILY
|
80
|
+
|
81
|
+
If you are publishing in a language like Chinese, you should specify a `font`
|
82
|
+
with Chinese glyphs.
|
83
|
+
|
84
|
+
You can specify additional authors by separating them with a `;`
|
76
85
|
|
77
86
|
The **layout** directory contains the header and footer for an
|
78
87
|
online version of your book.
|
79
88
|
|
80
|
-
The **assets** directory contains images and stylesheets.
|
89
|
+
The **assets** directory contains images and stylesheets. Wordsmith has
|
90
|
+
built-in support for [Sass](http://sass-lang.com/).
|
81
91
|
|
82
92
|
In the **content** directory you can:
|
83
93
|
|
@@ -107,27 +117,30 @@ This will be available in a site like http://jassa.github.com/wordsmith-demo/
|
|
107
117
|
Git is an important part of this tool, a typical workflow should look like this:
|
108
118
|
|
109
119
|
$ wordsmith new ruby_guide
|
110
|
-
|
111
|
-
|
112
|
-
|
120
|
+
// this command will also create a git repository
|
121
|
+
// and the first commit, but IT WILL NOT BE PUSHED YET
|
122
|
+
// since you haven't provided a remote ref
|
113
123
|
|
114
124
|
$ cd ruby_guide
|
115
|
-
|
125
|
+
// Here you edit your 'content' directory with your own chapters
|
116
126
|
|
117
|
-
|
127
|
+
// Generate your output files..
|
118
128
|
$ wordsmith generate
|
129
|
+
|
130
|
+
// ..and when you are ready to commit, do it normally:
|
119
131
|
$ git commit -am "finished chapter one"
|
120
132
|
|
121
|
-
|
133
|
+
// Add a ref to your (newly created) remote repo
|
122
134
|
$ git add remote origin git@github.com:jassa/wordsmith-demo.git
|
123
135
|
$ git push origin master
|
124
136
|
|
125
|
-
|
137
|
+
// Note that if you want to publish to github pages,
|
138
|
+
// you can do this instead:
|
126
139
|
$ wordsmith publish git@github.com:jassa/wordsmith-demo.git
|
127
140
|
|
128
|
-
|
129
|
-
|
130
|
-
|
141
|
+
// This command will create a branch called 'gh-pages' (as github requires),
|
142
|
+
// just remember that you'll still need to run `git push origin master`
|
143
|
+
// to push your book editables
|
131
144
|
|
132
145
|
## License
|
133
146
|
|
data/Rakefile
CHANGED
data/bin/wordsmith
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
2
|
+
# encoding: UTF-8
|
4
3
|
|
5
4
|
begin
|
6
5
|
# resolve bin path, ignoring symlinks
|
@@ -10,11 +9,10 @@ begin
|
|
10
9
|
# add self to libpath
|
11
10
|
$:.unshift File.expand_path("../../lib", bin_file)
|
12
11
|
|
13
|
-
require 'wordsmith'
|
14
|
-
|
15
12
|
# start up the CLI
|
13
|
+
require 'wordsmith'
|
16
14
|
require 'wordsmith/cli'
|
17
15
|
Wordsmith.new.run
|
18
16
|
rescue Interrupt
|
19
17
|
puts("\n ! Command cancelled.")
|
20
|
-
end
|
18
|
+
end
|
data/lib/wordsmith.rb
CHANGED
@@ -1,40 +1,40 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
2
4
|
require 'nokogiri'
|
3
5
|
require 'kindlegen'
|
4
6
|
require 'yaml'
|
5
7
|
require 'git'
|
6
8
|
|
9
|
+
require 'fileutils'
|
10
|
+
require 'pp'
|
11
|
+
|
7
12
|
require 'wordsmith/init'
|
8
13
|
require 'wordsmith/generate'
|
9
14
|
require 'wordsmith/publish'
|
10
15
|
|
11
|
-
|
12
|
-
require 'pp'
|
13
|
-
|
14
|
-
class Wordsmith
|
16
|
+
class Wordsmith
|
15
17
|
include Init
|
16
18
|
include Generate
|
17
19
|
include Publish
|
18
|
-
|
20
|
+
|
19
21
|
attr_accessor :subcommand, :args, :options, :name, :files, :stylesheet
|
20
22
|
attr_reader :info
|
21
|
-
|
23
|
+
|
22
24
|
OUTPUT_TYPES = ['html', 'epub', 'mobi', 'pdf']
|
23
25
|
WORDSMITH_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
24
|
-
|
26
|
+
|
25
27
|
def initialize
|
26
28
|
@subcommand = nil
|
27
29
|
@args = []
|
28
30
|
@options = {}
|
29
|
-
@config = YAML::parse(File.open(local('.wordsmith'))).transform rescue {}
|
30
|
-
@name = File.basename(local('.'))
|
31
31
|
end
|
32
32
|
|
33
33
|
def info(message)
|
34
34
|
@info ||= []
|
35
35
|
@info << message
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def local(file)
|
39
39
|
File.expand_path(File.join(Dir.pwd, file))
|
40
40
|
end
|
data/lib/wordsmith/cli.rb
CHANGED
data/lib/wordsmith/generate.rb
CHANGED
@@ -1,131 +1,219 @@
|
|
1
|
+
require 'sass/plugin'
|
2
|
+
|
1
3
|
class Wordsmith
|
2
4
|
module Generate
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
build_metadata_xml
|
18
|
-
|
19
|
-
@stylesheet = if @config["stylesheet"] && File.exists?(local(@config["stylesheet"]))
|
20
|
-
local(@config["stylesheet"])
|
5
|
+
attr_reader :config, :files, :name, :output
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@name = File.basename(local("."))
|
9
|
+
@config = YAML::parse(File.open(local(".wordsmith"))).
|
10
|
+
transform rescue {}
|
11
|
+
|
12
|
+
run_callback("before_all")
|
13
|
+
content_dir = local(File.join("content"))
|
14
|
+
@files = Dir.glob(content_dir + "/**/*.*").sort.join(" \\\n")
|
15
|
+
|
16
|
+
if files.empty?
|
17
|
+
raise "Exiting.. Nothing to generate in #{content_dir}." +
|
18
|
+
"\nHave you run 'wordsmith new'?"
|
21
19
|
end
|
22
|
-
|
23
|
-
Dir.mkdir(local(
|
24
|
-
|
20
|
+
|
21
|
+
Dir.mkdir(local("final")) unless File.exists?(local("final"))
|
22
|
+
@output = local(File.join("final", name))
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate(args = [])
|
26
|
+
setup
|
27
|
+
|
25
28
|
formats = args.empty? ? OUTPUT_TYPES : args
|
29
|
+
|
26
30
|
formats.each do |format|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
if $?.exitstatus == 0 && out == '' || $?.exitstatus == 1 && format == 'mobi'
|
34
|
-
if format == 'html'
|
35
|
-
info "Created #{@output}/index.html"
|
36
|
-
else
|
37
|
-
info "Created #{@output}.#{format}"
|
38
|
-
end
|
39
|
-
else
|
40
|
-
raise "#{format} generator failed"
|
41
|
-
end
|
31
|
+
raise "No generator found for #{format}" unless respond_to?("to_#{format}")
|
32
|
+
|
33
|
+
run_callback("before_#{format}")
|
34
|
+
out = if format == "mobi"
|
35
|
+
send("to_#{format}")
|
42
36
|
else
|
43
|
-
|
37
|
+
run_command(send("to_#{format}"))
|
38
|
+
end
|
39
|
+
run_callback("after_#{format}")
|
40
|
+
|
41
|
+
if $?.exitstatus == 0 && out.empty? || format == "mobi" && $?.exitstatus == 1
|
42
|
+
info "Created #{output}" +
|
43
|
+
(format == "html" ? "/index.html" : ".#{format}")
|
44
|
+
else
|
45
|
+
raise "#{format} generator failed"
|
44
46
|
end
|
45
47
|
end
|
48
|
+
run_callback("after_all")
|
46
49
|
end
|
47
|
-
|
48
|
-
def
|
49
|
-
|
50
|
-
builder = Nokogiri::XML::Builder.new do |xml|
|
51
|
-
xml.metadata('xmlns:dc' => 'http://purl.org/dc/elements/1.1/') {
|
52
|
-
xml['dc'].title { xml.text @config["title"] }
|
53
|
-
xml['dc'].creator { xml.text @config["author"] }
|
54
|
-
xml['dc'].language { xml.text @config["language"] }
|
55
|
-
}
|
56
|
-
end
|
57
|
-
frg = Nokogiri::XML.fragment(builder.to_xml)
|
58
|
-
nodes = frg.search('.//metadata/*')
|
59
|
-
File.open(metadata, 'w') { |f| f.write(nodes.to_xml) }
|
50
|
+
|
51
|
+
def run_callback(meth)
|
52
|
+
run_command(config[meth]) if config[meth]
|
60
53
|
end
|
61
|
-
|
54
|
+
|
62
55
|
def to_html
|
63
56
|
info "Generating html..."
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
local(File.join('layout', 'footer.html'))
|
71
|
-
end
|
72
|
-
`cp -r #{base(File.join('template', 'assets'))} #{html_dir}`
|
73
|
-
cmd = "pandoc -s -S --toc -o #{File.join(html_dir, 'index.html')} -t html"
|
74
|
-
puts @config['stylesheet']
|
75
|
-
cmd += " -c #{@config['stylesheet']}" if @stylesheet
|
57
|
+
|
58
|
+
compile_stylesheets
|
59
|
+
copy_assets
|
60
|
+
|
61
|
+
cmd = "pandoc -f markdown_mmd -s -S --toc -o #{File.join(output, "index.html")} -t html"
|
62
|
+
stylesheets.each { |stylesheet| cmd += " -c #{stylesheet}" }
|
76
63
|
cmd += " -B #{header}" if header
|
77
64
|
cmd += " -A #{footer}" if footer
|
78
|
-
cmd += " \\\n#{
|
65
|
+
cmd += " \\\n#{files}"
|
66
|
+
cmd
|
79
67
|
end
|
80
|
-
|
68
|
+
|
81
69
|
def to_epub
|
82
70
|
info "Generating epub..."
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
89
|
-
cmd = "pandoc -S -o #{@output}.epub -t epub"
|
90
|
-
cmd += " \\\n--epub-metadata=#{metadata}"
|
71
|
+
|
72
|
+
build_metadata_xml
|
73
|
+
|
74
|
+
cmd = "pandoc -f markdown_mmd -S -o #{output}.epub -t epub"
|
75
|
+
cmd += " \\\n--epub-metadata=#{metadata}" if metadata
|
91
76
|
cmd += " \\\n--epub-cover-image=#{cover}" if cover
|
92
|
-
cmd += " \\\n--epub-stylesheet=#{
|
93
|
-
cmd += " \\\n#{
|
77
|
+
cmd += " \\\n--epub-stylesheet=#{epub_stylesheet}" if epub_stylesheet
|
78
|
+
cmd += " \\\n#{files}"
|
79
|
+
cmd
|
94
80
|
end
|
95
|
-
|
81
|
+
|
96
82
|
def to_mobi
|
97
|
-
if File.exists?(
|
83
|
+
if File.exists?(output + ".epub")
|
98
84
|
info "Generating mobi..."
|
99
|
-
Kindlegen.run("#{
|
85
|
+
Kindlegen.run("#{output}.epub", "-o", "#{name}.mobi")
|
100
86
|
else
|
101
|
-
info "Skipping .mobi (#{
|
87
|
+
info "Skipping .mobi (#{name}.epub doesn't exist)"
|
102
88
|
end
|
103
89
|
end
|
104
|
-
|
90
|
+
|
105
91
|
def to_pdf
|
106
92
|
info "Generating pdf..."
|
107
|
-
|
108
|
-
|
93
|
+
|
94
|
+
engine = ""
|
95
|
+
|
96
|
+
[["xetex", "xelatex"], ["pdftex", "pdflatex"], "lualatex"].each do |e|
|
109
97
|
if e.is_a? Array
|
110
98
|
cmd, name = e
|
111
99
|
else
|
112
100
|
cmd = name = e
|
113
101
|
end
|
114
|
-
if can_run?(cmd +
|
102
|
+
if can_run?(cmd + " -v")
|
115
103
|
engine = name
|
116
|
-
break
|
104
|
+
break
|
117
105
|
end
|
118
106
|
end
|
119
|
-
|
120
|
-
cmd
|
107
|
+
|
108
|
+
cmd = "pandoc -f markdown_mmd -N --toc -o #{output}.pdf #{files}"
|
109
|
+
cmd += " --latex-engine=#{engine}" unless engine.empty?
|
110
|
+
cmd += " -V mainfont='#{config['font']}'" unless (config.fetch('font', '')).empty?
|
111
|
+
cmd
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def build_metadata_xml
|
117
|
+
metadata = local(File.join("metadata.xml"))
|
118
|
+
|
119
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
120
|
+
xml.metadata("xmlns:dc" => "http://purl.org/dc/elements/1.1/") {
|
121
|
+
xml["dc"].title { xml.text config["title"] }
|
122
|
+
config["author"].split(/\s*;\s*/).each do |creator|
|
123
|
+
xml["dc"].creator { xml.text creator }
|
124
|
+
end if config["author"]
|
125
|
+
xml["dc"].language { xml.text config["language"] }
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
frg = Nokogiri::XML.fragment(builder.to_xml)
|
130
|
+
nodes = frg.search(".//metadata/*")
|
131
|
+
File.open(metadata, "w") { |f| f.write(nodes.to_xml) }
|
132
|
+
end
|
133
|
+
|
134
|
+
def compile_stylesheets
|
135
|
+
unless defined?(SASS_LOADED)
|
136
|
+
Sass::Plugin.reset!
|
137
|
+
|
138
|
+
css_location = File.join(output, "assets", "stylesheets")
|
139
|
+
sass_location = File.join(local("assets"), "stylesheets")
|
140
|
+
|
141
|
+
Sass::Plugin.options.merge!(:template_location => sass_location,
|
142
|
+
:css_location => css_location,
|
143
|
+
:always_update => false,
|
144
|
+
:always_check => true)
|
145
|
+
end
|
146
|
+
|
147
|
+
Sass::Plugin.on_updated_stylesheet do |template, css|
|
148
|
+
info "Compiling #{template} to #{css}"
|
149
|
+
end
|
150
|
+
|
151
|
+
Sass::Plugin.update_stylesheets
|
152
|
+
end
|
153
|
+
|
154
|
+
def copy_assets
|
155
|
+
assets = Dir.glob(File.join("assets", "**", "*"))
|
156
|
+
sass = Dir.glob(File.join("assets", "stylesheets", "**", "*.scss"))
|
157
|
+
|
158
|
+
copies = assets - sass - [epub_stylesheet_location]
|
159
|
+
copies.each do |entry|
|
160
|
+
dest = File.join(output, File.dirname(entry))
|
161
|
+
FileUtils.mkdir_p dest
|
162
|
+
FileUtils.cp entry, dest unless File.directory?(entry)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def cover
|
167
|
+
@cover ||= if config["cover"] && File.exists?(local(File.join(config["cover"])))
|
168
|
+
local(File.join(config["cover"]))
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def epub_stylesheet
|
173
|
+
@epub_stylesheet ||= if File.exists?(epub_stylesheet_location)
|
174
|
+
local(epub_stylesheet_location)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def epub_stylesheet_location
|
179
|
+
File.join("assets", "stylesheets", "epub.css")
|
180
|
+
end
|
181
|
+
|
182
|
+
def footer
|
183
|
+
@footer ||= if File.exists?(local(File.join("layout", "footer.html")))
|
184
|
+
local(File.join("layout", "footer.html"))
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def header
|
189
|
+
@header ||= if File.exists?(local(File.join("layout", "header.html")))
|
190
|
+
local(File.join("layout", "header.html"))
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def metadata
|
195
|
+
@metadata ||= if File.exists?(local(File.join("metadata.xml")))
|
196
|
+
local(File.join("metadata.xml"))
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def stylesheets
|
201
|
+
@stylesheet ||= begin
|
202
|
+
styles = Dir.glob(File.join(output, "assets", "stylesheets", "**", "*.css"))
|
203
|
+
partials = Dir.glob(File.join(output, "assets", "stylesheets", "**", "_*.css"))
|
204
|
+
all = styles - partials - [epub_stylesheet_location]
|
205
|
+
|
206
|
+
all.map { |css| css.gsub(output + "/", "") }
|
207
|
+
end
|
121
208
|
end
|
122
|
-
|
209
|
+
|
123
210
|
def run_command(cmd)
|
124
211
|
`#{cmd}`.strip
|
125
212
|
end
|
126
|
-
|
213
|
+
|
127
214
|
def can_run?(cmd)
|
128
|
-
`#{cmd} 2>&1`
|
215
|
+
out = `#{cmd} 2>&1`
|
216
|
+
info out
|
129
217
|
$?.success?
|
130
218
|
end
|
131
219
|
end
|
data/lib/wordsmith/init.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Wordsmith
|
2
2
|
module Init
|
3
|
-
|
3
|
+
|
4
4
|
# start a new wordsmith directory with skeleton structure
|
5
5
|
def init(args = [])
|
6
6
|
name = Array(args).shift
|
@@ -11,7 +11,7 @@ class Wordsmith
|
|
11
11
|
template_dir = File.join(WORDSMITH_ROOT, 'template')
|
12
12
|
ign = Dir.glob(template_dir + '/.[a-z]*')
|
13
13
|
FileUtils.cp_r template_dir, name
|
14
|
-
|
14
|
+
|
15
15
|
# also copy files that start with .
|
16
16
|
FileUtils.cp_r ign, name
|
17
17
|
if Git.init(local(name))
|
@@ -24,4 +24,4 @@ class Wordsmith
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
|
-
end
|
27
|
+
end
|
data/lib/wordsmith/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.0.
|
1
|
+
class Wordsmith
|
2
|
+
VERSION = "0.0.6"
|
3
3
|
end
|
data/template/.wordsmith
CHANGED
@@ -4,4 +4,7 @@ language: en
|
|
4
4
|
author: Your Name
|
5
5
|
title: Your Book Title
|
6
6
|
cover: assets/images/cover.jpg
|
7
|
-
|
7
|
+
|
8
|
+
# Other configuration options
|
9
|
+
# If you need to specify the font to use non-unicode characters (e.g. Chinese)
|
10
|
+
# font: HanaMinA
|
@@ -3,6 +3,7 @@ html {
|
|
3
3
|
padding: 40px;
|
4
4
|
background: #DFE1E5;
|
5
5
|
}
|
6
|
+
|
6
7
|
body {
|
7
8
|
margin: 0;
|
8
9
|
padding: 30px;
|
@@ -18,27 +19,12 @@ body {
|
|
18
19
|
-webkit-border-radius: 3px;
|
19
20
|
-moz-border-radius: 3px;
|
20
21
|
border-radius: 3px;
|
21
|
-
|
22
22
|
}
|
23
|
+
|
23
24
|
a {
|
24
25
|
color: #1A4882;
|
25
26
|
}
|
27
|
+
|
26
28
|
h1, h2, h3 {
|
27
29
|
margin: 30px 0 10px 0;
|
28
30
|
}
|
29
|
-
body {
|
30
|
-
display: inline-block;
|
31
|
-
}
|
32
|
-
div#TOC {
|
33
|
-
border: 1px solid #C7C7C7;
|
34
|
-
-webkit-border-radius: 3px;
|
35
|
-
-moz-border-radius: 3px;
|
36
|
-
border-radius: 3px;
|
37
|
-
}
|
38
|
-
div#cover {
|
39
|
-
text-align: center;
|
40
|
-
padding: 0 0 30px 0;
|
41
|
-
}
|
42
|
-
div#cover img {
|
43
|
-
max-height: 400px;
|
44
|
-
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
html {
|
2
|
+
margin: 0;
|
3
|
+
padding: 40px;
|
4
|
+
background: #DFE1E5;
|
5
|
+
}
|
6
|
+
body {
|
7
|
+
margin: 0;
|
8
|
+
padding: 30px;
|
9
|
+
font-family: "Lucida Grande",verdana,arial,helvetica,sans-serif;
|
10
|
+
font-size: 14px;
|
11
|
+
color: #373737;
|
12
|
+
width: 800px;
|
13
|
+
background: rgba(255, 255, 255, 0.8);
|
14
|
+
-webkit-box-shadow: 2px 2px 6px rgba(0,0,0,.30);
|
15
|
+
-moz-box-shadow: 2px 2px 6px rgba(0,0,0,.30);
|
16
|
+
box-shadow: 2px 2px 6px rgba(0,0,0,.30);
|
17
|
+
border: 1px solid #C7C7C7;
|
18
|
+
-webkit-border-radius: 3px;
|
19
|
+
-moz-border-radius: 3px;
|
20
|
+
border-radius: 3px;
|
21
|
+
|
22
|
+
}
|
23
|
+
a {
|
24
|
+
color: #1A4882;
|
25
|
+
}
|
26
|
+
h1, h2, h3 {
|
27
|
+
margin: 30px 0 10px 0;
|
28
|
+
}
|
29
|
+
body {
|
30
|
+
display: inline-block;
|
31
|
+
}
|
32
|
+
div#TOC {
|
33
|
+
border: 1px solid #C7C7C7;
|
34
|
+
-webkit-border-radius: 3px;
|
35
|
+
-moz-border-radius: 3px;
|
36
|
+
border-radius: 3px;
|
37
|
+
}
|
38
|
+
div#cover {
|
39
|
+
text-align: center;
|
40
|
+
padding: 0 0 30px 0;
|
41
|
+
}
|
42
|
+
div#cover img {
|
43
|
+
max-height: 400px;
|
44
|
+
}
|
data/test/css_test.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path "../test_helper", __FILE__
|
2
|
+
|
3
|
+
context "wordsmith css tests" do
|
4
|
+
|
5
|
+
def wordsmith
|
6
|
+
Wordsmith.new
|
7
|
+
end
|
8
|
+
|
9
|
+
test "copies all css files into final assets directory" do
|
10
|
+
in_temp_dir do
|
11
|
+
wordsmith.init('w')
|
12
|
+
|
13
|
+
File.rename "w/assets/stylesheets/master.scss",
|
14
|
+
"w/assets/stylesheets/_a_css_partial.css"
|
15
|
+
|
16
|
+
Dir.chdir("w") { wordsmith.generate ["html"] }
|
17
|
+
files = Dir.glob('w/final/**/*')
|
18
|
+
|
19
|
+
assert files.include? "w/final/w/assets/stylesheets/other.css"
|
20
|
+
assert files.include? "w/final/w/assets/stylesheets/_a_css_partial.css"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
test "includes all final css files inside output html" do
|
25
|
+
in_temp_dir do
|
26
|
+
wordsmith.init('w')
|
27
|
+
|
28
|
+
File.rename "w/assets/stylesheets/master.scss",
|
29
|
+
"w/assets/stylesheets/master.css"
|
30
|
+
|
31
|
+
FileUtils.cp "w/assets/stylesheets/master.css",
|
32
|
+
"w/assets/stylesheets/_a_css_partial.css"
|
33
|
+
|
34
|
+
assert File.exists?("w/assets/stylesheets/other.css")
|
35
|
+
|
36
|
+
Dir.chdir("w") { wordsmith.generate ["html"] }
|
37
|
+
html_content = File.read("w/final/w/index.html")
|
38
|
+
|
39
|
+
assert html_content =~ /="assets\/stylesheets\/master\.css"/
|
40
|
+
assert html_content =~ /other\.css/
|
41
|
+
assert !(html_content =~ /_a_css_partial\.css/)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
test "ignores epub.css in html" do
|
46
|
+
in_temp_dir do
|
47
|
+
wordsmith.init('w')
|
48
|
+
assert File.exists?("w/assets/stylesheets/epub.css")
|
49
|
+
|
50
|
+
Dir.chdir("w") { wordsmith.generate ["html"] }
|
51
|
+
|
52
|
+
html_content = File.read("w/final/w/index.html")
|
53
|
+
files = Dir.glob('w/final/**/*')
|
54
|
+
|
55
|
+
assert !files.include?("w/final/w/assets/stylesheets/epub.css")
|
56
|
+
assert !(html_content =~ /epub\.css/)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
data/test/generate_test.rb
CHANGED
@@ -1,7 +1,39 @@
|
|
1
1
|
require File.expand_path "../test_helper", __FILE__
|
2
2
|
|
3
3
|
context "wordsmith generate tests" do
|
4
|
-
|
5
|
-
|
4
|
+
|
5
|
+
def wordsmith
|
6
|
+
Wordsmith.new
|
7
|
+
end
|
8
|
+
|
9
|
+
test "fails without files" do
|
10
|
+
assert_raise RuntimeError do
|
11
|
+
wordsmith.generate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
%w(epub html pdf).each do |format|
|
16
|
+
test "generates book.#{format}" do
|
17
|
+
in_temp_dir do
|
18
|
+
wordsmith.init "book"
|
19
|
+
Dir.chdir("book") { wordsmith.generate [format] }
|
20
|
+
end
|
21
|
+
end
|
6
22
|
end
|
7
|
-
|
23
|
+
|
24
|
+
# mobi requires epub
|
25
|
+
test "generates book.mobi" do
|
26
|
+
in_temp_dir do
|
27
|
+
wordsmith.init "book"
|
28
|
+
Dir.chdir("book") { wordsmith.generate ["epub", "mobi"] }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
test "generates all" do
|
33
|
+
in_temp_dir do
|
34
|
+
wordsmith.init "book"
|
35
|
+
Dir.chdir("book") { wordsmith.generate }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/test/init_test.rb
CHANGED
@@ -31,4 +31,12 @@ context "wordsmith init tests" do
|
|
31
31
|
assert files.include? "w/.gitignore"
|
32
32
|
end
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
|
+
test "creates git repo" do
|
36
|
+
in_temp_dir do
|
37
|
+
@wordsmith.init('w')
|
38
|
+
files = Dir.glob('w/**/*', File::FNM_DOTMATCH)
|
39
|
+
assert files.include? "w/.git"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/test/sass_test.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.expand_path "../test_helper", __FILE__
|
2
|
+
|
3
|
+
context "wordsmith sass tests" do
|
4
|
+
|
5
|
+
def wordsmith
|
6
|
+
Wordsmith.new
|
7
|
+
end
|
8
|
+
|
9
|
+
test "compiles sass files" do
|
10
|
+
in_temp_dir do
|
11
|
+
wordsmith.init('w')
|
12
|
+
Dir.chdir("w") { wordsmith.generate ["html"] }
|
13
|
+
|
14
|
+
sass1 = File.read("w/assets/stylesheets/_partial.scss")
|
15
|
+
sass2 = File.read("w/assets/stylesheets/_with_sass.scss")
|
16
|
+
compiled_css = File.read("w/final/w/assets/stylesheets/master.css")
|
17
|
+
|
18
|
+
assert compiled_css =~ /#{sass1.split("\n").first}/
|
19
|
+
assert compiled_css =~ /#{sass2.split("\n").first}/
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
test "doesn't copy sass assets to final" do
|
24
|
+
in_temp_dir do
|
25
|
+
wordsmith.init('w')
|
26
|
+
Dir.chdir("w") { wordsmith.generate ["html"] }
|
27
|
+
|
28
|
+
files = Dir.glob('w/final/**/*')
|
29
|
+
|
30
|
+
assert files.include?("w/final/w/assets/stylesheets/master.css")
|
31
|
+
assert files.include?("w/final/w/assets/stylesheets/other.css")
|
32
|
+
|
33
|
+
assert files.grep(/.scss$/).empty?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
test "includes compiled css files inside final html" do
|
38
|
+
in_temp_dir do
|
39
|
+
wordsmith.init('w')
|
40
|
+
assert File.exists?("w/assets/stylesheets/master.scss")
|
41
|
+
|
42
|
+
Dir.chdir("w") { wordsmith.generate ["html"] }
|
43
|
+
html_content = File.read("w/final/w/index.html")
|
44
|
+
|
45
|
+
assert html_content =~ /master.css/
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/wordsmith.gemspec
CHANGED
@@ -15,9 +15,11 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.files = `git ls-files`.split("\n")
|
16
16
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
17
|
|
18
|
-
gem.add_dependency "nokogiri", ">= 1.5.2"
|
19
|
-
gem.add_dependency "kindlegen", ">= 2.3.1"
|
20
18
|
gem.add_dependency "git"
|
19
|
+
gem.add_dependency "kindlegen", "~> 2.3"
|
20
|
+
gem.add_dependency "nokogiri", "~> 1.5"
|
21
|
+
gem.add_dependency "sass", "~> 3.1"
|
22
|
+
|
21
23
|
gem.add_development_dependency "rake"
|
22
24
|
gem.add_development_dependency "test-unit"
|
23
25
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wordsmith
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.6
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Amed Rodriguez
|
@@ -11,86 +10,90 @@ authors:
|
|
11
10
|
autorequire:
|
12
11
|
bindir: bin
|
13
12
|
cert_chain: []
|
14
|
-
date:
|
13
|
+
date: 2014-05-23 00:00:00.000000000 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
|
-
name:
|
16
|
+
name: git
|
18
17
|
requirement: !ruby/object:Gem::Requirement
|
19
|
-
none: false
|
20
18
|
requirements:
|
21
|
-
- -
|
19
|
+
- - ">="
|
22
20
|
- !ruby/object:Gem::Version
|
23
|
-
version:
|
21
|
+
version: '0'
|
24
22
|
type: :runtime
|
25
23
|
prerelease: false
|
26
24
|
version_requirements: !ruby/object:Gem::Requirement
|
27
|
-
none: false
|
28
25
|
requirements:
|
29
|
-
- -
|
26
|
+
- - ">="
|
30
27
|
- !ruby/object:Gem::Version
|
31
|
-
version:
|
28
|
+
version: '0'
|
32
29
|
- !ruby/object:Gem::Dependency
|
33
30
|
name: kindlegen
|
34
31
|
requirement: !ruby/object:Gem::Requirement
|
35
|
-
none: false
|
36
32
|
requirements:
|
37
|
-
- -
|
33
|
+
- - "~>"
|
38
34
|
- !ruby/object:Gem::Version
|
39
|
-
version: 2.3
|
35
|
+
version: '2.3'
|
40
36
|
type: :runtime
|
41
37
|
prerelease: false
|
42
38
|
version_requirements: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
39
|
requirements:
|
45
|
-
- -
|
40
|
+
- - "~>"
|
46
41
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.3
|
42
|
+
version: '2.3'
|
48
43
|
- !ruby/object:Gem::Dependency
|
49
|
-
name:
|
44
|
+
name: nokogiri
|
50
45
|
requirement: !ruby/object:Gem::Requirement
|
51
|
-
none: false
|
52
46
|
requirements:
|
53
|
-
- -
|
47
|
+
- - "~>"
|
54
48
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
49
|
+
version: '1.5'
|
56
50
|
type: :runtime
|
57
51
|
prerelease: false
|
58
52
|
version_requirements: !ruby/object:Gem::Requirement
|
59
|
-
none: false
|
60
53
|
requirements:
|
61
|
-
- -
|
54
|
+
- - "~>"
|
62
55
|
- !ruby/object:Gem::Version
|
63
|
-
version: '
|
56
|
+
version: '1.5'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: sass
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '3.1'
|
64
|
+
type: :runtime
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - "~>"
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '3.1'
|
64
71
|
- !ruby/object:Gem::Dependency
|
65
72
|
name: rake
|
66
73
|
requirement: !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
74
|
requirements:
|
69
|
-
- -
|
75
|
+
- - ">="
|
70
76
|
- !ruby/object:Gem::Version
|
71
77
|
version: '0'
|
72
78
|
type: :development
|
73
79
|
prerelease: false
|
74
80
|
version_requirements: !ruby/object:Gem::Requirement
|
75
|
-
none: false
|
76
81
|
requirements:
|
77
|
-
- -
|
82
|
+
- - ">="
|
78
83
|
- !ruby/object:Gem::Version
|
79
84
|
version: '0'
|
80
85
|
- !ruby/object:Gem::Dependency
|
81
86
|
name: test-unit
|
82
87
|
requirement: !ruby/object:Gem::Requirement
|
83
|
-
none: false
|
84
88
|
requirements:
|
85
|
-
- -
|
89
|
+
- - ">="
|
86
90
|
- !ruby/object:Gem::Version
|
87
91
|
version: '0'
|
88
92
|
type: :development
|
89
93
|
prerelease: false
|
90
94
|
version_requirements: !ruby/object:Gem::Requirement
|
91
|
-
none: false
|
92
95
|
requirements:
|
93
|
-
- -
|
96
|
+
- - ">="
|
94
97
|
- !ruby/object:Gem::Version
|
95
98
|
version: '0'
|
96
99
|
description: Create, collaborate and publish ebooks easily.
|
@@ -103,7 +106,7 @@ executables:
|
|
103
106
|
extensions: []
|
104
107
|
extra_rdoc_files: []
|
105
108
|
files:
|
106
|
-
- .gitignore
|
109
|
+
- ".gitignore"
|
107
110
|
- Gemfile
|
108
111
|
- Gemfile.lock
|
109
112
|
- README.md
|
@@ -120,45 +123,52 @@ files:
|
|
120
123
|
- template/.wordsmith
|
121
124
|
- template/README.md
|
122
125
|
- template/assets/images/cover.jpg
|
123
|
-
- template/assets/stylesheets/
|
126
|
+
- template/assets/stylesheets/_partial.scss
|
127
|
+
- template/assets/stylesheets/_with_sass.scss
|
128
|
+
- template/assets/stylesheets/epub.css
|
129
|
+
- template/assets/stylesheets/master.scss
|
130
|
+
- template/assets/stylesheets/other.css
|
124
131
|
- template/content/01_manifesto.md
|
125
132
|
- template/content/02_read_read_read.md
|
126
133
|
- template/content/03_pay_special_attention/01_intro.md
|
127
134
|
- template/content/03_pay_special_attention/02_conclusion.md
|
128
135
|
- template/layout/footer.html
|
129
136
|
- template/layout/header.html
|
137
|
+
- test/css_test.rb
|
130
138
|
- test/generate_test.rb
|
131
139
|
- test/init_test.rb
|
132
140
|
- test/publish_test.rb
|
141
|
+
- test/sass_test.rb
|
133
142
|
- test/test_helper.rb
|
134
143
|
- wordsmith.gemspec
|
135
144
|
homepage: https://github.com/tractical/wordsmith
|
136
145
|
licenses:
|
137
146
|
- MIT
|
147
|
+
metadata: {}
|
138
148
|
post_install_message:
|
139
149
|
rdoc_options: []
|
140
150
|
require_paths:
|
141
151
|
- lib
|
142
152
|
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
-
none: false
|
144
153
|
requirements:
|
145
|
-
- -
|
154
|
+
- - ">="
|
146
155
|
- !ruby/object:Gem::Version
|
147
156
|
version: '0'
|
148
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
-
none: false
|
150
158
|
requirements:
|
151
|
-
- -
|
159
|
+
- - ">="
|
152
160
|
- !ruby/object:Gem::Version
|
153
161
|
version: '0'
|
154
162
|
requirements: []
|
155
163
|
rubyforge_project:
|
156
|
-
rubygems_version:
|
164
|
+
rubygems_version: 2.2.2
|
157
165
|
signing_key:
|
158
|
-
specification_version:
|
166
|
+
specification_version: 4
|
159
167
|
summary: The best way to publish ebooks. No, really.
|
160
168
|
test_files:
|
169
|
+
- test/css_test.rb
|
161
170
|
- test/generate_test.rb
|
162
171
|
- test/init_test.rb
|
163
172
|
- test/publish_test.rb
|
173
|
+
- test/sass_test.rb
|
164
174
|
- test/test_helper.rb
|