mint 0.8.1 → 0.10.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/Gemfile +1 -26
- data/README.md +117 -37
- data/bin/mint +2 -81
- data/config/templates/base/navigation.css +136 -0
- data/config/templates/base/print.css +152 -0
- data/config/templates/{reset.css → base/reset.css} +1 -1
- data/config/templates/base/style.css +117 -137
- data/config/templates/base/utilities.css +136 -0
- data/config/templates/base/variables.css +124 -0
- data/config/templates/basic/style.css +151 -0
- data/config/templates/default/layout.erb +33 -3
- data/config/templates/default/style.css +95 -164
- data/config/templates/magazine/style.css +383 -0
- data/config/templates/nord/style.css +105 -220
- data/config/templates/nord-dark/style.css +82 -263
- data/lib/mint/commandline/parse.rb +144 -0
- data/lib/mint/commandline/publish.rb +46 -0
- data/lib/mint/commandline/run.rb +30 -0
- data/lib/mint/config.rb +162 -0
- data/lib/mint/{css.rb → css_dsl.rb} +9 -9
- data/lib/mint/css_parser.rb +45 -25
- data/lib/mint/document.rb +250 -365
- data/lib/mint/document_tree.rb +163 -0
- data/lib/mint/exceptions.rb +2 -3
- data/lib/mint/helpers.rb +23 -180
- data/lib/mint/layout.rb +26 -9
- data/lib/mint/renderers/css_renderer.rb +32 -0
- data/lib/mint/renderers/erb_renderer.rb +11 -0
- data/lib/mint/renderers/markdown_renderer.rb +45 -0
- data/lib/mint/style.rb +21 -31
- data/lib/mint/template.rb +30 -0
- data/lib/mint/version.rb +1 -1
- data/lib/mint/workspace.rb +171 -0
- data/lib/mint.rb +44 -12
- data/man/mint.1 +85 -44
- data/spec/cli/README.md +2 -2
- data/spec/cli/argument_parsing_spec.rb +89 -147
- data/spec/cli/bin_integration_spec.rb +23 -243
- data/spec/cli/full_workflow_integration_spec.rb +99 -442
- data/spec/cli/original_style_integration_spec.rb +58 -0
- data/spec/cli/publish_workflow_spec.rb +72 -70
- data/spec/commandline_path_integration_spec.rb +230 -0
- data/spec/config_file_integration_spec.rb +362 -0
- data/spec/{css_spec.rb → css_dsl_spec.rb} +7 -3
- data/spec/css_parser_spec.rb +59 -1
- data/spec/document_spec.rb +37 -242
- data/spec/flattened_path_spec.rb +150 -0
- data/spec/layout_spec.rb +42 -3
- data/spec/mint_spec.rb +22 -217
- data/spec/path_handling_spec.rb +237 -0
- data/spec/run_cli_tests.rb +1 -1
- data/spec/spec_helper.rb +3 -10
- data/spec/style_spec.rb +31 -56
- data/spec/support/cli_helpers.rb +7 -10
- data/spec/support/matchers.rb +1 -1
- data/spec/template_spec.rb +31 -0
- data/spec/workspace_spec.rb +177 -0
- metadata +75 -89
- data/bin/mint-epub +0 -20
- data/config/templates/garden/layout.erb +0 -38
- data/config/templates/garden/style.css +0 -303
- data/config/templates/nord/layout.erb +0 -11
- data/config/templates/nord-dark/layout.erb +0 -11
- data/config/templates/zen/layout.erb +0 -11
- data/config/templates/zen/style.css +0 -114
- data/lib/mint/command_line.rb +0 -360
- data/lib/mint/css_template.rb +0 -37
- data/lib/mint/markdown_template.rb +0 -47
- data/lib/mint/mint.rb +0 -313
- data/lib/mint/plugin.rb +0 -136
- data/lib/mint/plugins/epub.rb +0 -293
- data/lib/mint/resource.rb +0 -101
- data/plugins/templates/epub/layouts/container.haml +0 -5
- data/plugins/templates/epub/layouts/content.haml +0 -35
- data/plugins/templates/epub/layouts/layout.haml +0 -6
- data/plugins/templates/epub/layouts/title.haml +0 -11
- data/plugins/templates/epub/layouts/toc.haml +0 -26
- data/spec/cli/configuration_management_spec.rb +0 -363
- data/spec/cli/template_management_spec.rb +0 -300
- data/spec/helpers_spec.rb +0 -249
- data/spec/plugin_spec.rb +0 -449
- data/spec/resource_spec.rb +0 -135
data/lib/mint/plugins/epub.rb
DELETED
@@ -1,293 +0,0 @@
|
|
1
|
-
require "nokogiri"
|
2
|
-
require "hashie"
|
3
|
-
require "zip"
|
4
|
-
require "active_support/core_ext/hash/deep_merge"
|
5
|
-
require "active_support/core_ext/hash/keys"
|
6
|
-
|
7
|
-
# Note: This code is not as clean as I want it to be. It is an example
|
8
|
-
# plugin with which I'm developing the Mint plugin system. Code cleanup
|
9
|
-
# to follow.
|
10
|
-
|
11
|
-
module Mint
|
12
|
-
META_DIR = "META-INF"
|
13
|
-
CONTENT_DIR = "OPS"
|
14
|
-
|
15
|
-
# Add chapters to document -- this is probably not a sustainable pattern
|
16
|
-
# for all plugins, but it's useful here.
|
17
|
-
class Document
|
18
|
-
def chapters
|
19
|
-
html_document = Nokogiri::HTML::Document.parse render
|
20
|
-
EPub.split_on(html_document, "h2").map &:to_s
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class InvalidDocumentError < StandardError; end
|
25
|
-
|
26
|
-
class EPub < Plugin
|
27
|
-
def self.after_publish(document)
|
28
|
-
# This check doesn't currently follow symlinks
|
29
|
-
if document.destination_directory == Dir.getwd
|
30
|
-
raise InvalidDocumentError
|
31
|
-
end
|
32
|
-
|
33
|
-
Dir.chdir document.destination_directory do
|
34
|
-
metadata = standardized_metadata document
|
35
|
-
chapters = document.chapters
|
36
|
-
locals = { chapters: chapters }.merge metadata
|
37
|
-
|
38
|
-
prepare_directory!
|
39
|
-
create_chapters! chapters, :locals => metadata
|
40
|
-
|
41
|
-
create! do |container|
|
42
|
-
container.type = "container"
|
43
|
-
container.locals = locals
|
44
|
-
end
|
45
|
-
|
46
|
-
create! do |content|
|
47
|
-
content.type = "content"
|
48
|
-
content.locals = locals
|
49
|
-
end
|
50
|
-
|
51
|
-
create! do |toc|
|
52
|
-
toc.type = "toc"
|
53
|
-
toc.locals = locals
|
54
|
-
end
|
55
|
-
|
56
|
-
create! do |title|
|
57
|
-
title.type = "title"
|
58
|
-
title.locals = locals
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
FileUtils.rm document.destination_file
|
63
|
-
|
64
|
-
self.zip! document.destination_directory,
|
65
|
-
:mimetype => "application/epub+zip",
|
66
|
-
:extension => "epub"
|
67
|
-
|
68
|
-
FileUtils.rm_r document.destination_directory
|
69
|
-
end
|
70
|
-
|
71
|
-
protected
|
72
|
-
|
73
|
-
def self.split_on(document, tag_name, opts={})
|
74
|
-
container_node = opts[:container] || "#container"
|
75
|
-
|
76
|
-
new_document = document.dup.tap do |node|
|
77
|
-
container = node.at container_node
|
78
|
-
|
79
|
-
unless container
|
80
|
-
raise InvalidDocumentError,
|
81
|
-
"Document doesn't contain expected container: #{container}",
|
82
|
-
caller
|
83
|
-
end
|
84
|
-
|
85
|
-
div = nil
|
86
|
-
container.element_children.each do |elem|
|
87
|
-
if elem.name == tag_name
|
88
|
-
div = node.create_element "div"
|
89
|
-
# div.add_class "chapter"
|
90
|
-
elem.replace div
|
91
|
-
end
|
92
|
-
div << elem if div
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
new_document.search("div div")
|
97
|
-
end
|
98
|
-
|
99
|
-
# This is an opinionated version of ZIP, specifically
|
100
|
-
# tailored to ePub creation
|
101
|
-
def self.zip!(directory, opts={})
|
102
|
-
default_opts = {
|
103
|
-
extension: "zip",
|
104
|
-
mimetype: nil
|
105
|
-
}
|
106
|
-
|
107
|
-
opts = default_opts.merge opts
|
108
|
-
extension = opts[:extension]
|
109
|
-
parent_directory = File.expand_path "#{directory}/.."
|
110
|
-
child_directory = File.basename directory
|
111
|
-
|
112
|
-
Zip::ZipOutputStream.open "#{directory}.#{extension}" do |zos|
|
113
|
-
if opts[:mimetype]
|
114
|
-
zos.put_next_entry("mimetype", nil, nil, Zip::ZipEntry::STORED)
|
115
|
-
zos << opts[:mimetype]
|
116
|
-
end
|
117
|
-
|
118
|
-
Dir.chdir parent_directory do
|
119
|
-
Dir["#{child_directory}/**/*"].each do |file|
|
120
|
-
if File.file? file
|
121
|
-
relative_path = Helpers.normalize_path(file, child_directory)
|
122
|
-
zos.put_next_entry(relative_path,
|
123
|
-
nil,
|
124
|
-
nil,
|
125
|
-
Zip::ZipEntry::DEFLATED)
|
126
|
-
zos << File.read(file)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def self.create!
|
134
|
-
options = Hashie::Mash.new
|
135
|
-
yield options if block_given?
|
136
|
-
options = options.to_hash.symbolize_keys
|
137
|
-
|
138
|
-
type = options[:type] || "container"
|
139
|
-
default_options =
|
140
|
-
case type.to_sym
|
141
|
-
when :container
|
142
|
-
container_defaults
|
143
|
-
when :content
|
144
|
-
content_defaults
|
145
|
-
when :toc
|
146
|
-
toc_defaults
|
147
|
-
when :title
|
148
|
-
title_defaults
|
149
|
-
else
|
150
|
-
{}
|
151
|
-
end
|
152
|
-
|
153
|
-
create_from_template! default_options.deep_merge(options)
|
154
|
-
end
|
155
|
-
|
156
|
-
def self.create_chapters!(chapters, opts={})
|
157
|
-
opts = chapter_defaults.deep_merge(opts)
|
158
|
-
template_file = EPub.template_directory + "/layouts/layout.haml"
|
159
|
-
renderer = Tilt.new template_file, :ugly => true
|
160
|
-
chapters.map do |chapter|
|
161
|
-
renderer.render Object.new, opts[:locals].merge(:content => chapter)
|
162
|
-
end.each_with_index do |text, id|
|
163
|
-
create_chapter!(id + 1, text)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
private
|
168
|
-
|
169
|
-
def self.create_from_template!(opts={})
|
170
|
-
template_file = EPub.template_directory + "/layouts/#{opts[:from]}"
|
171
|
-
renderer = Tilt.new template_file, :ugly => true
|
172
|
-
content = renderer.render Object.new, opts[:locals]
|
173
|
-
|
174
|
-
File.open(opts[:to], "w") do |f|
|
175
|
-
f << content
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
def self.prepare_directory!
|
180
|
-
[META_DIR, CONTENT_DIR].each do |dir|
|
181
|
-
FileUtils.mkdir dir unless File.exist?(dir)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def self.locals_lookup_table
|
186
|
-
{
|
187
|
-
author: [:creators, :array],
|
188
|
-
authors: [:creators, :array],
|
189
|
-
editor: [:contributors, :array],
|
190
|
-
editors: [:contributors, :array],
|
191
|
-
barcode: [:uuid, :string],
|
192
|
-
upc: [:uuid, :string],
|
193
|
-
copyright: [:rights, :string]
|
194
|
-
}
|
195
|
-
end
|
196
|
-
|
197
|
-
def self.standardized_metadata(document)
|
198
|
-
metadata = document.metadata.merge(:stylesheet => document.stylesheet)
|
199
|
-
sanitized_metadata =
|
200
|
-
Helpers.symbolize_keys(metadata, :downcase => true)
|
201
|
-
standardized_metadata =
|
202
|
-
Helpers.standardize(sanitized_metadata,
|
203
|
-
:table => locals_lookup_table)
|
204
|
-
end
|
205
|
-
|
206
|
-
def self.chapter_filename(id)
|
207
|
-
"OPS/chapter-#{id}.html"
|
208
|
-
end
|
209
|
-
|
210
|
-
# def self.metadata_from(document)
|
211
|
-
# document.metadata
|
212
|
-
# end
|
213
|
-
|
214
|
-
# def self.chapters_from(document)
|
215
|
-
# html_text = File.read document.destination_file
|
216
|
-
# html_document = Nokogiri::HTML::Document.parse html_text
|
217
|
-
# chapter_contents = self.split_on(html_document, "h2")
|
218
|
-
# chapter_ids = (1..chapters.length).map {|x| "chapter-#{x}" }
|
219
|
-
# chapters = Hash[chapter_ids.zip chapter_contents]
|
220
|
-
# end
|
221
|
-
|
222
|
-
def self.create_chapter!(id, text)
|
223
|
-
File.open chapter_filename(id), "w" do |file|
|
224
|
-
file << text
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
def self.chapter_defaults
|
229
|
-
{
|
230
|
-
locals: {
|
231
|
-
title: "Untitled"
|
232
|
-
}
|
233
|
-
}
|
234
|
-
end
|
235
|
-
|
236
|
-
def self.container_defaults
|
237
|
-
defaults = {
|
238
|
-
from: "container.haml",
|
239
|
-
to: "#{META_DIR}/container.xml",
|
240
|
-
locals: {
|
241
|
-
opf_file: "OPS/content.opf"
|
242
|
-
}
|
243
|
-
}
|
244
|
-
end
|
245
|
-
|
246
|
-
def self.content_defaults
|
247
|
-
defaults = {
|
248
|
-
from: "content.haml",
|
249
|
-
to: "#{CONTENT_DIR}/content.opf",
|
250
|
-
locals: {
|
251
|
-
title: "Untitled",
|
252
|
-
language: "English",
|
253
|
-
short_title: "",
|
254
|
-
uuid: "Unspecified",
|
255
|
-
description: "No description",
|
256
|
-
date: Date.today,
|
257
|
-
creators: ["Anonymous"],
|
258
|
-
contributors: [],
|
259
|
-
publisher: "Self published",
|
260
|
-
genre: "Non-fiction",
|
261
|
-
rights: "All Rights Reserved",
|
262
|
-
ncx_file: "toc.ncx",
|
263
|
-
stylesheet: "style.css",
|
264
|
-
title_file: "title.html",
|
265
|
-
}
|
266
|
-
}
|
267
|
-
end
|
268
|
-
|
269
|
-
def self.toc_defaults
|
270
|
-
defaults = {
|
271
|
-
from: "toc.haml",
|
272
|
-
to: "#{CONTENT_DIR}/toc.ncx",
|
273
|
-
locals: {
|
274
|
-
uuid: "Unspecified",
|
275
|
-
title: "Untitled",
|
276
|
-
title_file: "title.html",
|
277
|
-
}
|
278
|
-
}
|
279
|
-
end
|
280
|
-
|
281
|
-
def self.title_defaults
|
282
|
-
defaults = {
|
283
|
-
from: "title.haml",
|
284
|
-
to: "#{CONTENT_DIR}/title.html",
|
285
|
-
locals: {
|
286
|
-
title: "Untitled",
|
287
|
-
creators: ["Anonymous"],
|
288
|
-
stylesheet: "style.css"
|
289
|
-
}
|
290
|
-
}
|
291
|
-
end
|
292
|
-
end
|
293
|
-
end
|
data/lib/mint/resource.rb
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
require "mint/mint"
|
2
|
-
|
3
|
-
module Mint
|
4
|
-
class Resource
|
5
|
-
attr_accessor :type
|
6
|
-
|
7
|
-
attr_accessor :context
|
8
|
-
|
9
|
-
attr_reader :name
|
10
|
-
def name=(name)
|
11
|
-
@name = name
|
12
|
-
end
|
13
|
-
|
14
|
-
attr_reader :root
|
15
|
-
def root=(root)
|
16
|
-
@root = root
|
17
|
-
end
|
18
|
-
|
19
|
-
def root_directory_path
|
20
|
-
Pathname.new(root || Dir.getwd).expand_path
|
21
|
-
end
|
22
|
-
|
23
|
-
def root_directory
|
24
|
-
root_directory_path.to_s
|
25
|
-
end
|
26
|
-
|
27
|
-
attr_accessor :source
|
28
|
-
|
29
|
-
def source_file_path
|
30
|
-
path = Pathname.new(source)
|
31
|
-
path.absolute? ?
|
32
|
-
path.expand_path : root_directory_path + path
|
33
|
-
end
|
34
|
-
|
35
|
-
def source_file
|
36
|
-
source_file_path.to_s
|
37
|
-
end
|
38
|
-
|
39
|
-
def source_directory_path
|
40
|
-
source_file_path.dirname
|
41
|
-
end
|
42
|
-
|
43
|
-
def source_directory
|
44
|
-
source_directory_path.to_s
|
45
|
-
end
|
46
|
-
|
47
|
-
attr_accessor :destination
|
48
|
-
|
49
|
-
def destination_file_path
|
50
|
-
root_directory_path + (destination || "") + name
|
51
|
-
end
|
52
|
-
|
53
|
-
def destination_file
|
54
|
-
destination_file_path.to_s
|
55
|
-
end
|
56
|
-
|
57
|
-
def destination_directory_path
|
58
|
-
destination_file_path.dirname
|
59
|
-
end
|
60
|
-
|
61
|
-
def destination_directory
|
62
|
-
destination_directory_path.to_s
|
63
|
-
end
|
64
|
-
|
65
|
-
def renderer=(renderer)
|
66
|
-
@renderer = renderer
|
67
|
-
end
|
68
|
-
|
69
|
-
def initialize(source, root: nil, destination: nil, context: nil, name: nil, &block)
|
70
|
-
return nil unless source
|
71
|
-
|
72
|
-
self.type = :resource
|
73
|
-
self.source = source
|
74
|
-
self.root = root || source_directory
|
75
|
-
self.destination = destination
|
76
|
-
self.context = context
|
77
|
-
|
78
|
-
yield self if block
|
79
|
-
|
80
|
-
self.name = name || Mint.guess_name_from(source)
|
81
|
-
self.renderer = Mint.renderer source
|
82
|
-
end
|
83
|
-
|
84
|
-
def equal?(other)
|
85
|
-
self.destination_file_path == other.destination_file_path
|
86
|
-
end
|
87
|
-
alias_method :==, :equal?
|
88
|
-
|
89
|
-
def render(context=self, args={})
|
90
|
-
# see Tilt TEMPLATES.md for more info
|
91
|
-
@renderer.render context, args
|
92
|
-
end
|
93
|
-
|
94
|
-
def publish!(opts={})
|
95
|
-
FileUtils.mkdir_p self.destination_directory
|
96
|
-
File.open(self.destination_file, "w+") do |f|
|
97
|
-
f << self.render
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
!!! XML
|
2
|
-
%package(version='2.0' xmlns='http://www.idpf.org/2007/opf' unique-identifier=uuid)
|
3
|
-
%metadata(xmlns:dc='http://purl.org/dc/elements/1.1/'
|
4
|
-
xmlns:dcterms='http://purl.org/dc/terms/'
|
5
|
-
xmlns:opf='http://www.idpf.org/2007/opf'
|
6
|
-
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance')
|
7
|
-
|
8
|
-
%dc:title= title
|
9
|
-
%dc:language(xsi:type='dcterms:RFC3066')= language
|
10
|
-
%dc:identifier(id=uuid)= short_title
|
11
|
-
%dc:description= description
|
12
|
-
%dc:date(xsi:type='dcterms:W3CDTF')= date
|
13
|
-
|
14
|
-
- creators.each do |creator|
|
15
|
-
%dc:creator(opf:file-as=creator opf:role='aut')
|
16
|
-
- contributors.each do |contributor|
|
17
|
-
%dc:contributor(opf:file-as=contributor opf:role='edt')
|
18
|
-
|
19
|
-
%dc:publisher= publisher
|
20
|
-
%dc:type= genre
|
21
|
-
%dc:rights= rights
|
22
|
-
|
23
|
-
%manifest
|
24
|
-
%item(id='ncx' href=ncx_file media-type='application/x-dtbncx+xml')/
|
25
|
-
%item(id='style' href=stylesheet media-type='text/css')/
|
26
|
-
%item(id='title' href=title_file media-type='application/xhtml+xml')/
|
27
|
-
- chapters.each_with_index do |content, id|
|
28
|
-
- idx = id + 1
|
29
|
-
%item(id="chapter-#{idx}" href="chapter-#{idx}.html" media-type='application/xhtml+xml')/
|
30
|
-
|
31
|
-
%spine(toc='ncx')
|
32
|
-
%itemref(idref='title')/
|
33
|
-
- chapters.each_with_index do |content, id|
|
34
|
-
- idx = id + 1
|
35
|
-
%itemref(idref="chapter-#{idx}")/
|
@@ -1,11 +0,0 @@
|
|
1
|
-
!!! 1.1
|
2
|
-
%html(xmlns='http://www.w3.org/1999/xhtml')
|
3
|
-
%head
|
4
|
-
%meta(http-equiv='Content-Type'
|
5
|
-
content='text/html; charset=utf-8')
|
6
|
-
%title= title
|
7
|
-
%link(href=stylesheet type='text/css' rel='stylesheet')
|
8
|
-
|
9
|
-
%body
|
10
|
-
%h1= title
|
11
|
-
%h2= Mint::Helpers.listify creators
|
@@ -1,26 +0,0 @@
|
|
1
|
-
!!! XML
|
2
|
-
<!DOCTYPE ncx PUBLIC '-//NISO//DTD ncx 2005-1//EN' 'http://www.daisy.org/z3986/2005/ncx-2005-1.dtd'>
|
3
|
-
|
4
|
-
%ncx(xmlns='http://www.daisy.org/z3986/2005/ncx/' version='2005-1')
|
5
|
-
%head
|
6
|
-
%meta(name='dtb:uid' content=uuid)
|
7
|
-
%meta(name='dtb:depth' content='1')
|
8
|
-
%meta(name='dtb:totalPageCount' content='0')
|
9
|
-
%meta(name='dtb:maxPageNumber' content='0')
|
10
|
-
|
11
|
-
%docTitle
|
12
|
-
%text= title
|
13
|
-
|
14
|
-
%navMap
|
15
|
-
%navPoint(id='navpoint-1' playOrder=1)
|
16
|
-
%navLabel
|
17
|
-
%text= title
|
18
|
-
%content(src=title_file)
|
19
|
-
|
20
|
-
- chapters.each_with_index do |content, id|
|
21
|
-
- idx = Integer(id) + 1
|
22
|
-
- order = idx + 1
|
23
|
-
%navPoint(id="navpoint-#{order}" playOrder=order)
|
24
|
-
%navLabel
|
25
|
-
%text= "Chapter #{idx}"
|
26
|
-
%content(src="chapter-#{idx}.html")
|