carta 0.0.3.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +46 -0
- data/Rakefile +1 -0
- data/bin/carta +9 -0
- data/carta.gemspec +28 -0
- data/lib/carta/cli/book.rb +20 -0
- data/lib/carta/cli/chapter.rb +47 -0
- data/lib/carta/cli/compile.rb +129 -0
- data/lib/carta/cli/html_renderer.rb +55 -0
- data/lib/carta/cli/outline_renderer.rb +32 -0
- data/lib/carta/cli.rb +69 -0
- data/lib/carta/templates/ebook/assets/cover.jpg +0 -0
- data/lib/carta/templates/ebook/assets/css/.empty_directory +0 -0
- data/lib/carta/templates/ebook/assets/fonts/.empty_directory +0 -0
- data/lib/carta/templates/ebook/layouts/epub/EPUB/content.xhtml.erb +7 -0
- data/lib/carta/templates/ebook/layouts/epub/EPUB/main.ncx.erb +30 -0
- data/lib/carta/templates/ebook/layouts/epub/EPUB/main.opf.erb +31 -0
- data/lib/carta/templates/ebook/layouts/epub/EPUB/nav.xhtml.erb +12 -0
- data/lib/carta/templates/ebook/layouts/epub/META-INF/container.xml.erb +7 -0
- data/lib/carta/templates/ebook/layouts/html/index.html.erb +11 -0
- data/lib/carta/templates/ebook/manuscript/book.yaml.tt +5 -0
- data/lib/carta/templates/ebook/manuscript/figures/.empty_directory +0 -0
- data/lib/carta/templates/new_chapter.tt +1 -0
- data/lib/carta/util.rb +18 -0
- data/lib/carta/version.rb +3 -0
- data/lib/carta.rb +10 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6573752786e7b5fb4b78048bd2bff5587dc1dd3e
|
4
|
+
data.tar.gz: 113b54e8aab31cf481df770a19adcc395eacd281
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 06493f69384d0dedc81f0c56ba07cf216f31a550d9000dad7593546d898b6db23ca1bb075248b63ecbb0ad1df60ae8d02e8d9a495d62f7add5e203d33c0c4451
|
7
|
+
data.tar.gz: 4559e6ab6ce87fab4d5e72a9bdd7cb1dad1bda07e08e43c44f1b5378d424dbdc836c96621b953ed7d6993bec31ca957e2aa78fe0222d6ea80e63c906c6bbbeb3
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Dylan Wreggelsworth
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Carta
|
2
|
+
|
3
|
+
Carta is a command line tool to aid in the ebook creation workflow. Initially it will support the HTML and EPUB formats.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'carta'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install carta
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
$ carta book
|
22
|
+
Walks you through a book project creation process.
|
23
|
+
|
24
|
+
$ carta chapter [number] [name]
|
25
|
+
Will create a markdown file in the correct place with the name you specify.
|
26
|
+
numbers formatted like `1.1` will create a folder that matches the correct heirarchy and then create an H# tag with the correct level. Following these formats help generate a well formed table of contents
|
27
|
+
|
28
|
+
$ carta compile
|
29
|
+
Will generate a build folder with the compiled files in it.
|
30
|
+
|
31
|
+
## TODO
|
32
|
+
* Add partial support
|
33
|
+
* Remove html generation from the cli codebase
|
34
|
+
* Maybe switch to tilt for templates
|
35
|
+
* Improve chapter creation (not intuitive atm)
|
36
|
+
* Improve status messages
|
37
|
+
* Use thor for more of the template rendering/etc.
|
38
|
+
* Integrate SCSS/etc.
|
39
|
+
|
40
|
+
## Contributing
|
41
|
+
|
42
|
+
1. Fork it ( http://github.com/<my-github-username>/carta/fork )
|
43
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
44
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
45
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
46
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/carta
ADDED
data/carta.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'carta/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'carta'
|
8
|
+
spec.version = Carta::VERSION
|
9
|
+
spec.authors = ['Dylan Wreggelsworth']
|
10
|
+
spec.email = ['dylan@bvrgroup.us']
|
11
|
+
spec.summary = 'An ebook generator.'
|
12
|
+
spec.description = 'Generates a basic ebook project directory and renders it.'
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_runtime_dependency 'uuid', '>= 0'
|
24
|
+
spec.add_runtime_dependency 'rubyzip', '~> 1.0.0'
|
25
|
+
spec.add_runtime_dependency 'mime-types', '~> 2.1'
|
26
|
+
spec.add_runtime_dependency 'thor', '= 0.18.1'
|
27
|
+
spec.add_runtime_dependency 'redcarpet', '= 3.0.0'
|
28
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Carta::CLI
|
2
|
+
# This is our book generator
|
3
|
+
class Book
|
4
|
+
attr_reader :meta, :thor, :book_name
|
5
|
+
|
6
|
+
def initialize(thor, meta)
|
7
|
+
@thor = thor
|
8
|
+
@meta = meta
|
9
|
+
@book_name = (meta[:title].is_a? String) ? meta[:title] : meta[:title].join(' ')
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
require 'carta/cli/chapter'
|
14
|
+
thor.directory 'ebook', book_name
|
15
|
+
thor.inside book_name do
|
16
|
+
Carta::CLI::Chapter.new(thor, 0, "My First #{book_name} Chapter").run
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Carta::CLI
|
2
|
+
# A class for chapter generation
|
3
|
+
class Chapter
|
4
|
+
attr_reader :thor,
|
5
|
+
:chapter_number,
|
6
|
+
:pretty_number,
|
7
|
+
:chapter_name,
|
8
|
+
:sub_chapter_name,
|
9
|
+
:level
|
10
|
+
|
11
|
+
def initialize(thor, chapter_number, *chapter_name)
|
12
|
+
@thor = thor
|
13
|
+
@chapters = chapter_number.to_s.split('.')
|
14
|
+
@chapters[0] = Carta::Util.pad(@chapters[0])
|
15
|
+
|
16
|
+
if @chapters.length > 1
|
17
|
+
@chapters[1] = Carta::Util.pad(@chapters[1])
|
18
|
+
else
|
19
|
+
@chapters[1] = '01'
|
20
|
+
end
|
21
|
+
|
22
|
+
@chapter_name = chapter_name.join(' ')
|
23
|
+
@dasherized_name = Carta::Util.slug(@chapter_name)
|
24
|
+
@handy_chapter_name = "#{@chapters[0]}-#{@dasherized_name}"
|
25
|
+
@handy_subchapter_name = "#{@chapters[1]}-#{@dasherized_name}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
if Dir.exists?('manuscript')
|
30
|
+
target_dir = Dir.glob("manuscript/#{@chapters[0]}*")
|
31
|
+
if target_dir.empty?
|
32
|
+
path = "manuscript/#{@handy_chapter_name}/#{@handy_subchapter_name}.md"
|
33
|
+
else
|
34
|
+
path = "#{target_dir[0]}/#{@handy_subchapter_name}.md"
|
35
|
+
end
|
36
|
+
thor.create_file path do
|
37
|
+
level = @chapters[2].nil? ? '#' : '#' * (@chapters[2].to_i + 1)
|
38
|
+
contents = "#{level} #{chapter_name}"
|
39
|
+
contents << "\nLorem ipsum dolor sit amet, consectetur adipisicing elit."
|
40
|
+
end
|
41
|
+
else
|
42
|
+
thor.say('Please create a book first.',:red)
|
43
|
+
thor.help
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'thor/rake_compat'
|
3
|
+
require 'mime-types'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'zip'
|
6
|
+
require 'carta/cli/html_renderer'
|
7
|
+
require 'pry'
|
8
|
+
|
9
|
+
|
10
|
+
module Carta
|
11
|
+
class CLI::Compile
|
12
|
+
attr_reader :thor,
|
13
|
+
:book,
|
14
|
+
:PROJECT_DIR,
|
15
|
+
:LAYOUT_DIR,
|
16
|
+
:MANUSCRIPT_DIR,
|
17
|
+
:FIGURE_DIR,
|
18
|
+
:ASSET_DIR,
|
19
|
+
:BUILD_DIR,
|
20
|
+
:ASSET_FILES
|
21
|
+
|
22
|
+
def initialize(thor)
|
23
|
+
if Dir.exists?('manuscript')
|
24
|
+
@thor = thor
|
25
|
+
@PROJECT_DIR = Dir.pwd
|
26
|
+
@BUILD_DIR = "build"
|
27
|
+
@LAYOUT_DIR = "#{@PROJECT_DIR}/layouts"
|
28
|
+
@MANUSCRIPT_DIR = "#{@PROJECT_DIR}/manuscript"
|
29
|
+
@FIGURE_DIR = "#{@MANUSCRIPT_DIR}/figures"
|
30
|
+
@ASSET_DIR = "#{@PROJECT_DIR}/assets"
|
31
|
+
@ASSET_FILES = 'css,otf,ttf,jpeg,jpg,png,svg,gif'
|
32
|
+
@book = YAML.load_file("#{@MANUSCRIPT_DIR}/book.yaml")
|
33
|
+
else
|
34
|
+
thor.error 'No book found to compile!'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def run
|
39
|
+
generate_html if Dir.exists?('manuscript')
|
40
|
+
end
|
41
|
+
|
42
|
+
# Generates our HTML from markdown files and creates an outline
|
43
|
+
def generate_html
|
44
|
+
html_renderer = Carta::CLI::HTMLRenderer.new(@PROJECT_DIR)
|
45
|
+
# puts @MANUSCRIPT_DIR
|
46
|
+
book['html'] = html_renderer.manuscript_html
|
47
|
+
book['outline'] = html_renderer.outline
|
48
|
+
book['toc_html'] = html_renderer.toc_html
|
49
|
+
|
50
|
+
generate_manifest
|
51
|
+
end
|
52
|
+
|
53
|
+
# Runs through our ERBs
|
54
|
+
def render_layouts
|
55
|
+
FileList.new("#{@LAYOUT_DIR}/epub/**/*.erb").each do |layout|
|
56
|
+
filename = layout.pathmap("%{^#{@LAYOUT_DIR},#{@BUILD_DIR}}X")
|
57
|
+
path = filename.pathmap('%d')
|
58
|
+
|
59
|
+
FileUtils.mkpath(path) unless File.exists? path
|
60
|
+
|
61
|
+
template = ERB.new(File.read(layout), nil, '-')
|
62
|
+
File.open(filename, 'w+') do |handle|
|
63
|
+
handle.write template.result(binding)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def generate_manifest
|
69
|
+
files = FileList.new("#{@LAYOUT_DIR}/epub/EPUB/*.erb")
|
70
|
+
.pathmap("%{^#{@LAYOUT_DIR}/epub/EPUB/,}X")
|
71
|
+
.exclude('**/*.opf*')
|
72
|
+
.exclude('content.xhtml', 'nav.xhtml')
|
73
|
+
.exclude('**/*.ncx*')
|
74
|
+
.add("#{@FIGURE_DIR}/**/*.{#{@ASSET_FILES}}",
|
75
|
+
"#{@ASSET_DIR}/**/*.{#{@ASSET_FILES}}",
|
76
|
+
"#{@MANUSCRIPT_DIR}/cover.{#{@ASSET_FILES}}")
|
77
|
+
.pathmap("%{^#{@ASSET_DIR}/,}p")
|
78
|
+
.pathmap("%{^#{@FIGURE_DIR},figures}p")
|
79
|
+
|
80
|
+
book['manifest'] = []
|
81
|
+
|
82
|
+
files.each do |file|
|
83
|
+
media_type = MIME::Types.type_for(file).first.content_type
|
84
|
+
if file.include? 'cover'
|
85
|
+
book['cover'] = { filename: file, media_type: media_type }
|
86
|
+
else
|
87
|
+
book['manifest'] << { filename: file, media_type: media_type }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
copy_files
|
91
|
+
render_layouts
|
92
|
+
generate_epub
|
93
|
+
end
|
94
|
+
|
95
|
+
def copy_files
|
96
|
+
assets = FileList.new("#{@FIGURE_DIR}/**/*.{#{@ASSET_FILES}}",
|
97
|
+
"#{@ASSET_DIR}/**/*.{#{@ASSET_FILES}}",
|
98
|
+
"#{@MANUSCRIPT_DIR}/cover.{#{@ASSET_FILES}}")
|
99
|
+
|
100
|
+
dest = assets.pathmap("%{^#{@ASSET_DIR},#{@BUILD_DIR}/epub/EPUB}p")
|
101
|
+
.pathmap("%{^#{@FIGURE_DIR},#{@BUILD_DIR}/epub/EPUB/figures}p")
|
102
|
+
|
103
|
+
assets.each_with_index do |file, index|
|
104
|
+
thor.copy_file file, dest[index]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def generate_epub
|
109
|
+
files = FileList.new("#{@BUILD_DIR}/epub/**/*")
|
110
|
+
zip_path = files.pathmap("%{^#{@BUILD_DIR}/epub/,}p")
|
111
|
+
.exclude('EPUB', 'META-INF', 'mimetype')
|
112
|
+
files = files.exclude("#{@BUILD_DIR}/epub/EPUB", "#{@BUILD_DIR}/epub/META-INF")
|
113
|
+
zip = Zip::OutputStream.new("#{@BUILD_DIR}/#{book['title']}.epub")
|
114
|
+
zip.put_next_entry('mimetype', nil, nil, Zip::Entry::STORED, Zlib::NO_COMPRESSION)
|
115
|
+
zip.write "application/epub+zip"
|
116
|
+
zip_list = {}
|
117
|
+
zip_path.each_with_index do |value, i|
|
118
|
+
zip_list[value] = files[i]
|
119
|
+
end
|
120
|
+
zip_list.keys.each do |key|
|
121
|
+
# puts "#{key}: #{zip_list[key]}"
|
122
|
+
zip.put_next_entry key, nil, nil, Zip::Entry::DEFLATED, Zlib::BEST_COMPRESSION
|
123
|
+
zip.write IO.read(zip_list[key])
|
124
|
+
end
|
125
|
+
zip.close
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'carta/cli/outline_renderer'
|
2
|
+
|
3
|
+
module Carta
|
4
|
+
class CLI::HTMLRenderer
|
5
|
+
attr_accessor :markdown,
|
6
|
+
:manuscript_html,
|
7
|
+
:toc_html,
|
8
|
+
:outline
|
9
|
+
|
10
|
+
def initialize(path)
|
11
|
+
@markdown = ''
|
12
|
+
@toc_html = ''
|
13
|
+
@manuscript_html = ''
|
14
|
+
@outline = nil
|
15
|
+
load_markdown(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_markdown(path)
|
19
|
+
FileList.new("#{path}/manuscript/**/*.md").sort.each do |md_file|
|
20
|
+
IO.readlines(md_file).each { |line| markdown << line }
|
21
|
+
markdown << "\n\n"
|
22
|
+
end
|
23
|
+
render_manuscript
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_manuscript
|
27
|
+
renderer = OutlineRenderer.new
|
28
|
+
r = Redcarpet::Markdown.new(renderer)
|
29
|
+
manuscript_html << r.render(markdown)
|
30
|
+
@outline = renderer.outline
|
31
|
+
render_outline
|
32
|
+
end
|
33
|
+
|
34
|
+
def render_outline(html_class='toc')
|
35
|
+
final_class = "class='#{html_class}'"
|
36
|
+
outline.each_with_index do |data, i|
|
37
|
+
level, text, link, *children = data
|
38
|
+
toc_html << "<ol #{final_class}>" if i == 0
|
39
|
+
toc_html << "\n <li><a href='content.xhtml##{link}'>#{text}</a>"
|
40
|
+
|
41
|
+
if children.empty?
|
42
|
+
toc_html << '</li>'
|
43
|
+
else
|
44
|
+
children.each_with_index do |child, j|
|
45
|
+
level, text, link = child
|
46
|
+
toc_html << "\n <ol>" if j == 0
|
47
|
+
toc_html << "\n <li><a href='content.xhtml##{link}'>#{text}</a></li>"
|
48
|
+
toc_html << "\n </ol>\n </li>" if j == children.length - 1
|
49
|
+
end
|
50
|
+
end
|
51
|
+
toc_html << "\n</ol>" if i == outline.length - 1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Custom Renderer for Redcarpet
|
2
|
+
class OutlineRenderer < Redcarpet::Render::HTML
|
3
|
+
attr_accessor :outline
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@outline = []
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
# Required by Redcarpet to change behavior of the the renderer
|
11
|
+
def header(text, header_level)
|
12
|
+
prior_level = 1
|
13
|
+
text_slug = sluggize(text)
|
14
|
+
value = [header_level, text, text_slug]
|
15
|
+
if header_level <= 2
|
16
|
+
(prior_level < header_level) ? outline.last << value : outline << value
|
17
|
+
with_id = true
|
18
|
+
elsif header_level > 2
|
19
|
+
with_id = false
|
20
|
+
end
|
21
|
+
render_line(header_level, text, text_slug, with_id)
|
22
|
+
end
|
23
|
+
|
24
|
+
def render_line(header_level, text, text_slug, with_id = false)
|
25
|
+
id = "id='#{text_slug}'" if with_id
|
26
|
+
"<h#{header_level} #{id}>#{text}</h#{header_level}>"
|
27
|
+
end
|
28
|
+
|
29
|
+
def sluggize(text)
|
30
|
+
text.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
|
31
|
+
end
|
32
|
+
end
|
data/lib/carta/cli.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'uuid'
|
2
|
+
require 'carta/cli/book'
|
3
|
+
require 'carta/cli/chapter'
|
4
|
+
|
5
|
+
module Carta::CLI
|
6
|
+
# The class from which it all begins
|
7
|
+
class Base < Thor
|
8
|
+
include Thor::Actions
|
9
|
+
attr_reader :meta,
|
10
|
+
:BUILD_PATH,
|
11
|
+
:LAYOUT_PATH,
|
12
|
+
:MANU_PATH,
|
13
|
+
:ASSET_PATH
|
14
|
+
|
15
|
+
# def initialize(*args)
|
16
|
+
# @BUILD_PATH = 'build'
|
17
|
+
# @LAYOUT_PATH = 'layouts'
|
18
|
+
# @MANU_PATH = 'manuscript'
|
19
|
+
# @ASSET_PATH = 'assets'
|
20
|
+
# end
|
21
|
+
|
22
|
+
def self.source_root
|
23
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
24
|
+
end
|
25
|
+
|
26
|
+
# desc 'book', 'Create a book with the given name'
|
27
|
+
desc 'book', 'Generate a book with an optional [NAME].'
|
28
|
+
def book(*name)
|
29
|
+
name = name.empty? ? '' : name.join(' ')
|
30
|
+
|
31
|
+
say("\nThis utility will walk you through creating an ebook project.")
|
32
|
+
say("\nPress ^C at any time to quit.")
|
33
|
+
|
34
|
+
require 'carta/cli/book'
|
35
|
+
|
36
|
+
default_name = name.empty? ? '' : "(#{name})"
|
37
|
+
|
38
|
+
ask_title = ask "Title:#{default_name}"
|
39
|
+
ask_license = ask 'License: (MIT)'
|
40
|
+
ask_lang = ask 'Language: (en-US)'
|
41
|
+
ask_author = ask 'Author(s): (Anonymous)'
|
42
|
+
ask_uuid = ask 'uuid:'
|
43
|
+
|
44
|
+
@meta = {
|
45
|
+
title: ask_title.empty? ? name : ask_title,
|
46
|
+
subtitle: ask('Subtitle: (blank)'),
|
47
|
+
authors: ask_author.empty? ? 'Anonymous' : ask_author,
|
48
|
+
language: ask_lang.empty? ? 'en-US' : ask_lang,
|
49
|
+
license: ask_license.empty? ? 'MIT' : ask_license,
|
50
|
+
uid: ask_uuid.empty? ? UUID.new.generate : ask_uuid
|
51
|
+
}
|
52
|
+
Carta::CLI::Book.new(self, meta).run
|
53
|
+
end
|
54
|
+
|
55
|
+
desc 'chapter [number] [name]',
|
56
|
+
'Create a chapter with the given name or number.'
|
57
|
+
def chapter(number, *name)
|
58
|
+
number, name = '00', [number].concat(name) unless /\d+/.match number
|
59
|
+
require 'carta/cli/chapter'
|
60
|
+
Carta::CLI::Chapter.new(self, number, name).run
|
61
|
+
end
|
62
|
+
|
63
|
+
desc 'compile', 'Create the final ebook'
|
64
|
+
def compile
|
65
|
+
require 'carta/cli/compile'
|
66
|
+
Carta::CLI::Compile.new(self).run
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
Binary file
|
File without changes
|
File without changes
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<ncx xmlns:ncx="http://www.daisy.org/z3986/2005/ncx/" xmlns="http://www.daisy.org/z3986/2005/ncx/"
|
3
|
+
version="2005-1" xml:lang="en">
|
4
|
+
<head>
|
5
|
+
<meta name="dtb:uid" content="<%= book['uid'] %>"/>
|
6
|
+
</head>
|
7
|
+
<docTitle>
|
8
|
+
<text><%= book['title'] %></text>
|
9
|
+
</docTitle>
|
10
|
+
<navMap>
|
11
|
+
<%- book['outline'].each_with_index do |item, i| -%>
|
12
|
+
<navPoint id="#<%= item[2] %>">
|
13
|
+
<navLabel>
|
14
|
+
<text><%= i+1 -%>. <%= item[1] %></text>
|
15
|
+
</navLabel>
|
16
|
+
<content src="content.xhtml#<%= item[2] %>"/>
|
17
|
+
<%- if item.length > 3
|
18
|
+
for j in (3..(item.length - 3)) -%>
|
19
|
+
<navPoint id="#<%= item[j][2] %>">
|
20
|
+
<navLabel>
|
21
|
+
<text><%= "#{i+1}.#{j-2}" %> <%= item[j][1] %></text>
|
22
|
+
</navLabel>
|
23
|
+
<content src="content.xhtml#<%= item[j][2] %>"/>
|
24
|
+
</navPoint>
|
25
|
+
<%- end -%>
|
26
|
+
<%- end -%>
|
27
|
+
</navPoint>
|
28
|
+
<%- end -%>
|
29
|
+
</navMap>
|
30
|
+
</ncx>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<package xmlns="http://www.idpf.org/2007/opf"
|
3
|
+
version="3.0"
|
4
|
+
unique-identifier="uid"
|
5
|
+
xml:lang="<%= book['language'] %>"
|
6
|
+
prefix="cc: http://creativecommons.org/ns#">
|
7
|
+
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
|
8
|
+
<dc:identifier id="uid"><%= book['uid'] %></dc:identifier>
|
9
|
+
<dc:title><%= book['title'] %></dc:title>
|
10
|
+
<dc:creator><%= book['authors'] %></dc:creator>
|
11
|
+
<dc:language><%= book['language'] %></dc:language>
|
12
|
+
<dc:rights><%= book['license'] %></dc:rights>
|
13
|
+
<meta property="dcterms:modified"><%= DateTime.now.strftime('%Y-%m-%dT%TZ') %></meta>
|
14
|
+
<!-- cover meta element included for 2.0 reading system compatibility: -->
|
15
|
+
<meta name="cover" content="cover"/>
|
16
|
+
</metadata>
|
17
|
+
<manifest>
|
18
|
+
<%- book['manifest'].each do |item| -%>
|
19
|
+
<item id="<%= File.basename(item[:filename],'.*') %>" href="<%= item[:filename].gsub('EPUB/','') %>" media-type="<%= item[:media_type] %>" />
|
20
|
+
<%- end -%>
|
21
|
+
<item id="cover" href="<%= book['cover'][:filename] %>" media-type="<%= book['cover'][:media_type] %>" properties="cover-image" />
|
22
|
+
<item id="content" href="content.xhtml" media-type="application/xhtml+xml"/>
|
23
|
+
<item id="toc" properties="nav" href="nav.xhtml" media-type="application/xhtml+xml"/>
|
24
|
+
<!-- ncx included for 2.0 reading system compatibility: -->
|
25
|
+
<item id="ncx" href="main.ncx" media-type="application/x-dtbncx+xml" />
|
26
|
+
</manifest>
|
27
|
+
<spine toc='ncx'>
|
28
|
+
<itemref linear='yes' idref="toc" />
|
29
|
+
<itemref linear='yes' idref="content" />
|
30
|
+
</spine>
|
31
|
+
</package>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<html xmlns="http://www.w3.org/1999/xhtml"
|
2
|
+
xmlns:epub="http://www.idpf.org/2007/ops">
|
3
|
+
<head></head>
|
4
|
+
<body>
|
5
|
+
<section>
|
6
|
+
<nav epub:type="toc">
|
7
|
+
<h1><%= book['title'].gsub(/\w+/) {|word| word.capitalize} %></h1>
|
8
|
+
<%= book['toc_html'] %>
|
9
|
+
</nav>
|
10
|
+
</section>
|
11
|
+
</body>
|
12
|
+
</html>
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= level %> <%= chapter_name %>
|
data/lib/carta/util.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Carta::Util
|
2
|
+
# Takes a string and prepares it for use as a filename
|
3
|
+
# or URL.
|
4
|
+
# "Hello World!" -> "hello-world"
|
5
|
+
def self.slug(string)
|
6
|
+
string.downcase
|
7
|
+
.strip
|
8
|
+
.gsub(' ', '-')
|
9
|
+
.gsub(/[^0-9A-z.\-]/, '')
|
10
|
+
end
|
11
|
+
|
12
|
+
# Pads at number so that it's 2 digits wide with leading
|
13
|
+
# zeros if needed.
|
14
|
+
# 1 -> 01
|
15
|
+
def self.pad(number)
|
16
|
+
sprintf('%02d', number.to_s)
|
17
|
+
end
|
18
|
+
end
|
data/lib/carta.rb
ADDED
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: carta
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3.pre1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dylan Wreggelsworth
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: uuid
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubyzip
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.0.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.0.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mime-types
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.1'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.1'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: thor
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.18.1
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.18.1
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: redcarpet
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 3.0.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 3.0.0
|
111
|
+
description: Generates a basic ebook project directory and renders it.
|
112
|
+
email:
|
113
|
+
- dylan@bvrgroup.us
|
114
|
+
executables:
|
115
|
+
- carta
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- ".gitignore"
|
120
|
+
- Gemfile
|
121
|
+
- LICENSE.txt
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- bin/carta
|
125
|
+
- carta.gemspec
|
126
|
+
- lib/carta.rb
|
127
|
+
- lib/carta/cli.rb
|
128
|
+
- lib/carta/cli/book.rb
|
129
|
+
- lib/carta/cli/chapter.rb
|
130
|
+
- lib/carta/cli/compile.rb
|
131
|
+
- lib/carta/cli/html_renderer.rb
|
132
|
+
- lib/carta/cli/outline_renderer.rb
|
133
|
+
- lib/carta/templates/ebook/assets/cover.jpg
|
134
|
+
- lib/carta/templates/ebook/assets/css/.empty_directory
|
135
|
+
- lib/carta/templates/ebook/assets/fonts/.empty_directory
|
136
|
+
- lib/carta/templates/ebook/layouts/epub/EPUB/content.xhtml.erb
|
137
|
+
- lib/carta/templates/ebook/layouts/epub/EPUB/main.ncx.erb
|
138
|
+
- lib/carta/templates/ebook/layouts/epub/EPUB/main.opf.erb
|
139
|
+
- lib/carta/templates/ebook/layouts/epub/EPUB/nav.xhtml.erb
|
140
|
+
- lib/carta/templates/ebook/layouts/epub/META-INF/container.xml.erb
|
141
|
+
- lib/carta/templates/ebook/layouts/html/index.html.erb
|
142
|
+
- lib/carta/templates/ebook/manuscript/book.yaml.tt
|
143
|
+
- lib/carta/templates/ebook/manuscript/figures/.empty_directory
|
144
|
+
- lib/carta/templates/new_chapter.tt
|
145
|
+
- lib/carta/util.rb
|
146
|
+
- lib/carta/version.rb
|
147
|
+
homepage: ''
|
148
|
+
licenses:
|
149
|
+
- MIT
|
150
|
+
metadata: {}
|
151
|
+
post_install_message:
|
152
|
+
rdoc_options: []
|
153
|
+
require_paths:
|
154
|
+
- lib
|
155
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: 1.3.1
|
165
|
+
requirements: []
|
166
|
+
rubyforge_project:
|
167
|
+
rubygems_version: 2.2.0
|
168
|
+
signing_key:
|
169
|
+
specification_version: 4
|
170
|
+
summary: An ebook generator.
|
171
|
+
test_files: []
|