cheepub 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +5 -0
- data/cheepub.gemspec +1 -0
- data/lib/cheepub.rb +3 -4
- data/lib/cheepub/content.rb +5 -0
- data/lib/cheepub/ext_hash.rb +5 -1
- data/lib/cheepub/generator.rb +30 -25
- data/lib/cheepub/heading_item.rb +73 -0
- data/lib/cheepub/heading_parser.rb +73 -0
- data/lib/cheepub/nav.rb +35 -0
- data/lib/cheepub/templates/nav.xhtml.erb +28 -0
- data/lib/cheepub/templates/style.css.erb +2 -0
- data/lib/cheepub/version.rb +1 -1
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a95f6f76cecb9e8911a8e77f4a50a5da0743f0a02cdf8b49fe615b853378710c
|
4
|
+
data.tar.gz: 5e5615e7b17d70e35eb0a0e1b0b704d1b2ecd8fcdf5725f10e985d8c389833f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68c648c08be8be16bab7d42729fe3685c7dcf8dba37c1b9d615b6e78d96faea50039412bcb2cd2891b43b74f810bbee28804fc51eee7a35a2855cb9f9b0529d2
|
7
|
+
data.tar.gz: a89df405a7ef050aa66b3cb717e10c61c352e400aa36fe1321a03e053f50b08e2ce6e3a4bcc7ca30abe182bc29358e3beefcd1c01da9aa0de704b5ab82d5294e
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
data/cheepub.gemspec
CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_dependency "gepub"
|
23
23
|
spec.add_dependency "kramdown", "~> 1.16"
|
24
24
|
spec.add_dependency "clamp", "~> 1.2"
|
25
|
+
spec.add_dependency "oga"
|
25
26
|
|
26
27
|
spec.add_development_dependency "rufo", "~> 0.3"
|
27
28
|
spec.add_development_dependency "bundler", "~> 1.16"
|
data/lib/cheepub.rb
CHANGED
@@ -7,7 +7,6 @@ require "cheepub/markdown/cheemarkdown"
|
|
7
7
|
require "cheepub/cli"
|
8
8
|
require "cheepub/generator"
|
9
9
|
require "cheepub/content"
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
10
|
+
require "cheepub/heading_parser"
|
11
|
+
require "cheepub/heading_item"
|
12
|
+
require "cheepub/nav"
|
data/lib/cheepub/content.rb
CHANGED
data/lib/cheepub/ext_hash.rb
CHANGED
@@ -6,10 +6,14 @@ module Cheepub
|
|
6
6
|
if self[key].kind_of? Hash
|
7
7
|
self[key].symbolize_keys!
|
8
8
|
end
|
9
|
-
self[(key
|
9
|
+
self[symbolize_key(key)] = delete(key)
|
10
10
|
end
|
11
11
|
self
|
12
12
|
end
|
13
|
+
|
14
|
+
def symbolize_key(key)
|
15
|
+
(key.to_sym rescue nil) || key
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
data/lib/cheepub/generator.rb
CHANGED
@@ -4,6 +4,8 @@ require 'gepub'
|
|
4
4
|
module Cheepub
|
5
5
|
class Generator
|
6
6
|
|
7
|
+
attr_reader :book
|
8
|
+
|
7
9
|
ROLES = %i{aut edt trl ill cov cre pht cwt nrt}
|
8
10
|
|
9
11
|
def initialize(src, params = Hash.new)
|
@@ -15,26 +17,26 @@ module Cheepub
|
|
15
17
|
@content = Cheepub::Content.new(File.read(@src))
|
16
18
|
end
|
17
19
|
@params = params
|
20
|
+
@book = GEPUB::Book.new
|
18
21
|
end
|
19
22
|
|
20
23
|
def execute
|
21
24
|
params = @params.merge(@content.header)
|
22
25
|
check_params(params)
|
23
|
-
|
24
|
-
apply_params(book, params)
|
26
|
+
apply_params(params)
|
25
27
|
epubfile = params[:epubfile] || "book.epub"
|
26
|
-
book.generate_epub(epubfile)
|
28
|
+
@book.generate_epub(epubfile)
|
27
29
|
end
|
28
30
|
|
29
|
-
def parse_creator(
|
31
|
+
def parse_creator(creator)
|
30
32
|
if creator.kind_of? String
|
31
|
-
book.add_creator(creator)
|
33
|
+
@book.add_creator(creator)
|
32
34
|
else
|
33
35
|
creator.each do |role, name|
|
34
36
|
if !ROLES.include?(role)
|
35
37
|
raise Cheepub::Error, "invalid role: '#{role}' for creator '#{name}'."
|
36
38
|
end
|
37
|
-
book.add_creator(name, nil, role)
|
39
|
+
@book.add_creator(name, nil, role)
|
38
40
|
end
|
39
41
|
end
|
40
42
|
end
|
@@ -45,30 +47,33 @@ module Cheepub
|
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
|
-
def apply_params(
|
49
|
-
book.identifier = params[:id] || "urn:uuid:#{SecureRandom.uuid}"
|
50
|
-
book.title = params[:title]
|
50
|
+
def apply_params(params)
|
51
|
+
@book.identifier = params[:id] || "urn:uuid:#{SecureRandom.uuid}"
|
52
|
+
@book.title = params[:title]
|
53
|
+
@book.add_creator(params[:author])
|
51
54
|
if params[:creator]
|
52
|
-
parse_creator(
|
55
|
+
parse_creator(params[:creator])
|
53
56
|
end
|
54
|
-
book.
|
55
|
-
book.
|
56
|
-
book.
|
57
|
-
book.publisher = params[:publisher]
|
57
|
+
@book.language = params[:language] || 'ja'
|
58
|
+
@book.version = '3.0'
|
59
|
+
@book.publisher = params[:publisher]
|
58
60
|
## book.date= params[:date] || Time.now
|
59
|
-
book.add_date(params[:date] || Time.now, nil)
|
60
|
-
book.lastmodified = params[:lastModified] || Time.now
|
61
|
+
@book.add_date(params[:date] || Time.now, nil)
|
62
|
+
@book.lastmodified = params[:lastModified] || Time.now
|
61
63
|
if params[:pageDirection]
|
62
|
-
book.page_progression_direction = params[:pageDirection]
|
63
|
-
end
|
64
|
-
File.open(File.join(File.dirname(__FILE__), "templates/style.css.erb")) do |f|
|
65
|
-
item = book.add_item("style.css")
|
66
|
-
item.add_content(f)
|
64
|
+
@book.page_progression_direction = params[:pageDirection]
|
67
65
|
end
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
66
|
+
template = File.read(File.join(File.dirname(__FILE__), "templates/style.css.erb"))
|
67
|
+
style_content = ERB.new(template).result(binding)
|
68
|
+
@book.add_item("style.css").add_content(StringIO.new(style_content))
|
69
|
+
@book.ordered do
|
70
|
+
nav = Cheepub::Nav.new(@content)
|
71
|
+
item = @book.add_item('nav.xhtml')
|
72
|
+
item.add_content(StringIO.new(nav.to_html))
|
73
|
+
item.add_property('nav')
|
74
|
+
@content.each_html_with_filename do |html, filename|
|
75
|
+
item = @book.add_item(filename)
|
76
|
+
item.add_content(StringIO.new(html))
|
72
77
|
end
|
73
78
|
end
|
74
79
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Cheepub
|
2
|
+
class HeadingItem
|
3
|
+
|
4
|
+
attr_reader :id, :level, :name, :filename, :content, :children
|
5
|
+
attr_accessor :parent
|
6
|
+
|
7
|
+
def initialize(id:nil, level:, name:nil, filename:nil, content:nil, children:nil, parent:nil)
|
8
|
+
@id = id
|
9
|
+
@level = level
|
10
|
+
@name = name
|
11
|
+
@filename = filename
|
12
|
+
@content = content
|
13
|
+
@children = children
|
14
|
+
@parent = parent
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_child(node)
|
18
|
+
children << node
|
19
|
+
node.parent = self
|
20
|
+
node
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_sibling(node)
|
24
|
+
parent.add_child(node)
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_descendant(node)
|
28
|
+
current = self
|
29
|
+
while current.level + 1 != node.level
|
30
|
+
item = HeadingItem.new(level: current.level+1, children: [])
|
31
|
+
current.add_child(item)
|
32
|
+
current = item
|
33
|
+
end
|
34
|
+
current.add_child(node)
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_ancestor(node)
|
38
|
+
current = self
|
39
|
+
while current.level != node.level
|
40
|
+
current = current.parent
|
41
|
+
end
|
42
|
+
current.add_sibling(node)
|
43
|
+
end
|
44
|
+
|
45
|
+
def dump
|
46
|
+
print "*" * level
|
47
|
+
print "{id:#{id}} content: #{content}\n"
|
48
|
+
children.each do |child|
|
49
|
+
child.dump
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_html_ol
|
54
|
+
indent = " " * (2 * level)
|
55
|
+
buf = ""
|
56
|
+
if level > 0
|
57
|
+
buf << "#{indent}<li>\n"
|
58
|
+
end
|
59
|
+
if id && content.length > 0
|
60
|
+
buf << " #{indent}<a href=\"#{filename}\##{id}\">#{content}</a>\n"
|
61
|
+
end
|
62
|
+
if !children.empty?
|
63
|
+
buf << " #{indent}<ol>\n" +
|
64
|
+
children.map(&:to_html_ol).join("") +
|
65
|
+
" #{indent}</ol>\n"
|
66
|
+
end
|
67
|
+
if level > 0
|
68
|
+
buf << "#{indent}</li>\n"
|
69
|
+
end
|
70
|
+
buf
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "oga"
|
2
|
+
require "cheepub/heading_item"
|
3
|
+
|
4
|
+
module Cheepub
|
5
|
+
class HeadingParser
|
6
|
+
|
7
|
+
class Handler
|
8
|
+
|
9
|
+
attr_reader :result
|
10
|
+
|
11
|
+
def initialize(filename)
|
12
|
+
@filename = filename
|
13
|
+
@stack = []
|
14
|
+
@result = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_element(ns, name, attrs)
|
18
|
+
if name =~ /^h([1-6])/i
|
19
|
+
@stack.push({filename: @filename, name: name, level: $1.to_i, content: "", id: attrs["id"]})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_text(text)
|
24
|
+
last_elem = @stack[-1]
|
25
|
+
return if !last_elem
|
26
|
+
last_elem[:content] = last_elem[:content]+text
|
27
|
+
end
|
28
|
+
|
29
|
+
def after_element(ns, name)
|
30
|
+
return if @stack.empty?
|
31
|
+
@result.push(@stack.pop)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_files(files)
|
39
|
+
heading_list = files.map{ |filename, content| parse_html_heading(filename, content) }.flatten
|
40
|
+
root = layering_heading(heading_list)
|
41
|
+
root
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_html_heading(filename, content)
|
45
|
+
handler = Cheepub::HeadingParser::Handler.new(filename)
|
46
|
+
Oga::HTML::SaxParser.new(handler, content).parse
|
47
|
+
handler.result
|
48
|
+
end
|
49
|
+
|
50
|
+
def layering_heading(list)
|
51
|
+
root = HeadingItem.new(level: 0, children: [])
|
52
|
+
prev = root
|
53
|
+
|
54
|
+
list.each do |item|
|
55
|
+
next if !item[:id] || item[:content].empty?
|
56
|
+
node = HeadingItem.new(id: item[:id], level: item[:level], name: item[:name],
|
57
|
+
content: item[:content], filename: item[:filename], children: [])
|
58
|
+
if node.level == prev.level + 1
|
59
|
+
prev.add_child(node)
|
60
|
+
elsif node.level == prev.level
|
61
|
+
prev.add_sibling(node)
|
62
|
+
elsif node.level > prev.level
|
63
|
+
prev.add_descendant(node)
|
64
|
+
else ## node.level < prev.level
|
65
|
+
prev.add_ancestor(node)
|
66
|
+
end
|
67
|
+
prev = node
|
68
|
+
end
|
69
|
+
|
70
|
+
root
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/cheepub/nav.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Cheepub
|
4
|
+
class Nav
|
5
|
+
|
6
|
+
attr_reader :root
|
7
|
+
|
8
|
+
def initialize(content)
|
9
|
+
@content = content
|
10
|
+
@root = @body = nil
|
11
|
+
parse
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_html
|
15
|
+
template = File.read(File.join(File.dirname(__FILE__), "templates/nav.xhtml.erb"))
|
16
|
+
@body = @root.to_html_ol
|
17
|
+
erb = ERB.new(template)
|
18
|
+
str = erb.result(binding)
|
19
|
+
str
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def parse
|
26
|
+
parser = HeadingParser.new()
|
27
|
+
list = make_file_list()
|
28
|
+
@root = parser.parse_files(list)
|
29
|
+
end
|
30
|
+
|
31
|
+
def make_file_list
|
32
|
+
@content.to_enum(:each_html_with_filename).map{|html,filename| [filename, html]}.to_a
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE html>
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja" lang="ja">
|
4
|
+
<head>
|
5
|
+
<meta charset="utf-8" />
|
6
|
+
<link rel="stylesheet" href="style.css" type="text/css" />
|
7
|
+
<title>nav</title>
|
8
|
+
<style type="text/css">
|
9
|
+
ol {
|
10
|
+
list-style-type: none;
|
11
|
+
margin-left: 0em;
|
12
|
+
padding-left: 0em;
|
13
|
+
}
|
14
|
+
</style>
|
15
|
+
</head>
|
16
|
+
<body class="frontmatter" epub:type="frontmatter">
|
17
|
+
<nav id="toc" class="toc" epub:type="toc">
|
18
|
+
<h2>目次</h2>
|
19
|
+
<%= @body %> </nav>
|
20
|
+
<nav id="landmarks" class="landmarks" epub:type="landmarks" hidden="hidden">
|
21
|
+
<h2>ガイド</h2>
|
22
|
+
<ol>
|
23
|
+
<li><a epub:type="toc" href="nav.xhtml"><span>目次</span></a></li>
|
24
|
+
<li><a epub:type="bodymatter" href="bodymatter_0.xhtml"><span>本文</span></a></li>
|
25
|
+
</ol>
|
26
|
+
</nav>
|
27
|
+
</body>
|
28
|
+
</html>
|
data/lib/cheepub/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cheepub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- takahashim
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gepub
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: oga
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rufo
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -161,9 +175,13 @@ files:
|
|
161
175
|
- lib/cheepub/error.rb
|
162
176
|
- lib/cheepub/ext_hash.rb
|
163
177
|
- lib/cheepub/generator.rb
|
178
|
+
- lib/cheepub/heading_item.rb
|
179
|
+
- lib/cheepub/heading_parser.rb
|
164
180
|
- lib/cheepub/markdown.rb
|
165
181
|
- lib/cheepub/markdown/cheemarkdown.rb
|
182
|
+
- lib/cheepub/nav.rb
|
166
183
|
- lib/cheepub/templates/bodymatter.html.erb
|
184
|
+
- lib/cheepub/templates/nav.xhtml.erb
|
167
185
|
- lib/cheepub/templates/style.css.erb
|
168
186
|
- lib/cheepub/version.rb
|
169
187
|
homepage: https://github.com/takahashim/cheepub
|