cheepub 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb88e2dae0bf74523ce1e187024db8e8e3ec3a332480461e020ca76af1ccef5e
4
- data.tar.gz: d56c9785adfca375b8892f960e4be9c2f9b3f3fc222d6953e70e7471a55279a3
3
+ metadata.gz: a95f6f76cecb9e8911a8e77f4a50a5da0743f0a02cdf8b49fe615b853378710c
4
+ data.tar.gz: 5e5615e7b17d70e35eb0a0e1b0b704d1b2ecd8fcdf5725f10e985d8c389833f3
5
5
  SHA512:
6
- metadata.gz: 05a9ec137505b9b7fe6ee3777500a96b0e9b9305e244b143406dba78ae24cb857f369e6f709b6b460dc216c5eccf2d125fb2fc4d95d468616d8bd0f29177bd13
7
- data.tar.gz: e01f312ba85bc5c318689d74efcc3dec662bbe5c7979f331167d999e6417f5b8b1ad64384a12e3bfadae74ae6226514d23511dd23a7c0d115fccdc75694e0626
6
+ metadata.gz: 68c648c08be8be16bab7d42729fe3685c7dcf8dba37c1b9d615b6e78d96faea50039412bcb2cd2891b43b74f810bbee28804fc51eee7a35a2855cb9f9b0529d2
7
+ data.tar.gz: a89df405a7ef050aa66b3cb717e10c61c352e400aa36fe1321a03e053f50b08e2ce6e3a4bcc7ca30abe182bc29358e3beefcd1c01da9aa0de704b5ab82d5294e
@@ -2,7 +2,7 @@ sudo: false
2
2
  language: ruby
3
3
  env:
4
4
  global:
5
- - CC_TEST_REPORTER_ID=787a2f89b15c637323c7340d65ec17e898ac44480706b4b4122ea040c2a88f1d
5
+ - CC_TEST_REPORTER_ID=d5331ce7fbbeb2ce680091143c984430e93910cf81cdb09cf6e60baeb2548c05
6
6
  rvm:
7
7
  - 2.4.1
8
8
  - 2.5.1
data/README.md CHANGED
@@ -66,6 +66,11 @@ You can define configration with in front-matter or `--config` option.
66
66
 
67
67
  ## History
68
68
 
69
+ ### 0.4.0
70
+
71
+ - fix writing-mode (pageDirection)
72
+ - fix to generate nav.xhtml
73
+
69
74
  ### 0.3.0
70
75
 
71
76
  - add option `--out`
@@ -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"
@@ -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
- module Cheepub
12
- # Your code goes here...
13
- end
10
+ require "cheepub/heading_parser"
11
+ require "cheepub/heading_item"
12
+ require "cheepub/nav"
@@ -47,5 +47,10 @@ module Cheepub
47
47
  return header, body
48
48
  end
49
49
 
50
+ def each_html_with_filename
51
+ html_pages.each_with_index do |page, idx|
52
+ yield page, "bodymatter_#{idx}.xhtml"
53
+ end
54
+ end
50
55
  end
51
56
  end
@@ -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.to_sym rescue nil) || key] = delete(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
@@ -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
- book = GEPUB::Book.new
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(book, 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(book, 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(book, params[:creator])
55
+ parse_creator(params[:creator])
53
56
  end
54
- book.add_creator(params[:author])
55
- book.language = params[:language] || 'ja'
56
- book.version = '3.0'
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
- book.ordered do
69
- @content.html_pages.each_with_index do |page, idx|
70
- item = book.add_item("bodymatter_0_#{idx}.xhtml")
71
- item.add_content(StringIO.new(page))
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
@@ -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>
@@ -3,9 +3,11 @@
3
3
  @namespace epub "http://www.idpf.org/2007/ops";
4
4
 
5
5
  html {
6
+ <% if @book.page_progression_direction == "rtl" %>
6
7
  -epub-writing-mode: vertical-rl;
7
8
  -webkit-writing-mode: vertical-rl;
8
9
  writing-mode: vertical-rl;
10
+ <% end %>
9
11
  }
10
12
 
11
13
  body {
@@ -1,3 +1,3 @@
1
1
  module Cheepub
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
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.3.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-06 00:00:00.000000000 Z
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