ebookbinder 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e84bb03efbd7cc1485383c90b47e60fbe9e61f711b5dcd19f016372433c08b00
4
+ data.tar.gz: 43a1abc9fde8c47f9d8cd50f8829f490f249381240bbf7e772a7d7377c7d92c3
5
+ SHA512:
6
+ metadata.gz: be92f5553c6ff6417c4d2bafe8e8b487cbc9084f7721f647e8de787d354c9816a3dd81a44bf322231de57c84881a42a084b0d7460764dd622436842edc4cac30
7
+ data.tar.gz: 388f22704f7770c26881542c3fe53d97ef58a5cd9e851e74382441ce26dca73c599048532b06ec704f60caee3e1202bd6ee2479fcbd05793cb20f6c3685667f3
data/Changelog ADDED
@@ -0,0 +1,2 @@
1
+ 1.0.0
2
+ First public release.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+
3
+ gem 'nokogiri'
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2015, 2017, 2024 Jan Friedrich
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Ebookbinder
2
+
3
+
4
+ ## Description
5
+
6
+ This library should help to make ebooks as easy as possible. It interprets an
7
+ XHTML structure and generate a corresponding ebook on base of easy asumptions.
8
+
9
+
10
+ ## Requirements
11
+
12
+ To use rake check it needs an actual version of
13
+ [epubcheck](https://www.w3.org/publishing/epubcheck/) accessible on the
14
+ commandline via `epubcheck`.
15
+
16
+
17
+ ## Versioning
18
+
19
+ Ebookbinder follows [Semantic Versioning](https://semver.org/), both SemVer and
20
+ SemVerTag.
21
+
22
+
23
+ ## Author
24
+
25
+ Jan Friedrich <janfri26@gmail.com>
26
+
27
+
28
+ ## MIT License
29
+
30
+ See file LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rim/tire'
4
+ require 'rim/version'
5
+ require_relative 'lib/ebookbinder/version'
6
+
7
+ Rim.setup do |r|
8
+ r.name = 'ebookbinder'
9
+ r.authors = 'Jan Friedrich'
10
+ r.email = 'janfri26@gmail.com'
11
+ r.version = Ebookbinder::VERSION
12
+ r.gem_files.exclude(/build/).exclude {|e| File.directory?(e)}
13
+ r.test_files = FileList.new()
14
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # stub: ebookbinder 1.0.0 ruby lib
3
+ #
4
+ # This file is automatically generated by rim.
5
+ # PLEASE DO NOT EDIT IT DIRECTLY!
6
+ # Change the values in Rim.setup in Rakefile instead.
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = "ebookbinder"
10
+ s.version = "1.0.0"
11
+
12
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
13
+ s.require_paths = ["lib"]
14
+ s.authors = ["Jan Friedrich"]
15
+ s.date = "2024-03-02"
16
+ s.description = ""
17
+ s.email = "janfri26@gmail.com"
18
+ s.files = ["Changelog", "Gemfile", "LICENSE", "README.md", "Rakefile", "ebookbinder.gemspec", "lib/ebookbinder.rb", "lib/ebookbinder/ebook_base.rb", "lib/ebookbinder/epub2.rb", "lib/ebookbinder/epub3.rb", "lib/ebookbinder/epub_base.rb", "lib/ebookbinder/version.rb", "test/epub2/Rakefile", "test/epub2/src/01.xhtml", "test/epub2/src/02.xhtml", "test/epub3/Rakefile", "test/epub3/src/01.xhtml", "test/epub3/src/02.xhtml"]
19
+ s.rubygems_version = "3.6.0.dev"
20
+ s.summary = ""
21
+
22
+ s.specification_version = 4
23
+
24
+ s.add_development_dependency(%q<rake>, [">= 0"])
25
+ s.add_development_dependency(%q<rim>, ["~> 2.17"])
26
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ require_relative '../ebookbinder'
3
+
4
+ require 'rake/clean'
5
+ require 'singleton'
6
+
7
+ module Ebookbinder
8
+
9
+ class EbookBase
10
+
11
+ include Singleton
12
+ include Rake::DSL
13
+
14
+ attr_accessor :author, :id, :language, :title
15
+ attr_accessor :build_dir, :src_dir
16
+ attr_accessor :task_defs
17
+
18
+ def self.setup
19
+ instance.setup do |i|
20
+ yield i
21
+ end
22
+ end
23
+
24
+ def self.define_tasks &blk
25
+ instance.task_defs ||= []
26
+ instance.task_defs << blk
27
+ end
28
+
29
+ def setup
30
+ yield self
31
+ check_mandatory_values
32
+ set_defaults
33
+ define_tasks
34
+ self
35
+ end
36
+
37
+ protected
38
+
39
+ def define_tasks
40
+ Array(@task_defs).each do |blk|
41
+ instance_exec &blk
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,147 @@
1
+ # encoding: utf-8
2
+ require_relative 'epub_base'
3
+
4
+ module Ebookbinder
5
+
6
+ class Epub2 < EpubBase
7
+
8
+ def set_defaults
9
+ @id ||= Digest::MD5.hexdigest(@title)
10
+ @language ||= 'en'
11
+ @src_dir ||= 'src'
12
+ @build_dir ||= 'build'
13
+ @epub_dir ||= File.join(@build_dir, 'epub2')
14
+ @meta_inf_dir = File.join(@epub_dir, 'META-INF')
15
+ @epub_filename ||= File.join(@build_dir, format('%s - %s.epub', @author, @title))
16
+ end
17
+
18
+ def generate_content_file
19
+ puts "generate #{content_filename}" if verbose
20
+ builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
21
+ xml.package(xmlns: "http://www.idpf.org/2007/opf", 'unique-identifier': 'pub-id', version: '2.0') do
22
+ xml.metadata('xmlns:dc': 'http://purl.org/dc/elements/1.1/', 'xmlns:dcterms': 'http://purl.org/dc/terms/',
23
+ 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:opf': 'http://www.idpf.org/2007/opf') do
24
+ xml['dc'].identifier(id, id: 'pub-id')
25
+ xml['dc'].title title
26
+ xml['dc'].creator(@author, 'xml:lang' => language)
27
+ xml['dc'].language language, 'xsi:type' => 'dcterms:RFC3066'
28
+ end
29
+ xml.manifest do
30
+ i = 0
31
+ content_filenames.each do |fn|
32
+ i += 1
33
+ xml.item(id: format('id_%04d', i), href: href(fn), 'media-type' => Ebookbinder.mimetype_for_filename(fn))
34
+ end
35
+ xml.item(id: 'ncx', href: href(ncx_filename), 'media-type' => 'application/x-dtbncx+xml')
36
+ end
37
+ xml.spine toc: 'ncx' do
38
+ i = 0
39
+ content_filenames.each do |fn|
40
+ i += 1
41
+ next unless Ebookbinder.mimetype_for_filename(fn) == 'application/xhtml+xml'
42
+ xml.itemref(idref: format('id_%04d', i))
43
+ end
44
+ end
45
+ end
46
+ end
47
+ File.write(content_filename, builder.to_xml)
48
+ end
49
+
50
+ def ncx_filename
51
+ File.join(@epub_dir, 'toc.ncx')
52
+ end
53
+
54
+ def generate_ncx_file
55
+ builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
56
+ xml.ncx(xmlns: 'http://www.daisy.org/z3986/2005/ncx/', version: '2005-1') do
57
+ xml.head do
58
+ xml.meta name: 'dtb:uid', content: id
59
+ xml.meta name: 'dtb:depth', content: '2'
60
+ xml.meta name: 'dtb:totalPageCount', content: '0'
61
+ xml.meta name: 'dtb:maxPageNumber', content: '0'
62
+ end
63
+ xml.docTitle do
64
+ xml.text! title
65
+ end
66
+ xml.navMap do
67
+ i = 0
68
+ content_filenames.each do |fn|
69
+ next unless Ebookbinder.mimetype_for_filename(fn) == 'application/xhtml+xml'
70
+ Nokogiri.XML(File.read(fn)).search('h1').each do |e|
71
+ if id = e.attribute('id')
72
+ i +=1
73
+ xml.navPoint id: format('id_%04d', i), playOrder: i do
74
+ xml.navLabel do
75
+ xml.text! e.text
76
+ end
77
+ xml.content src: href(fn, id)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ File.write(ncx_filename, builder.to_xml)
86
+ end
87
+
88
+ end
89
+
90
+ Epub2.define_tasks do
91
+
92
+ ::CLEAN << epub_dir
93
+ ::CLOBBER << build_dir << epub_filename
94
+
95
+ namespace :epub2 do
96
+
97
+ directory build_dir
98
+ directory epub_dir
99
+ directory meta_inf_dir
100
+
101
+ content_filenames.zip(source_filenames) do |cf, sf|
102
+ td = File.dirname(cf)
103
+ directory td
104
+ file cf => [td, sf] do
105
+ cp sf, cf
106
+ end
107
+ end
108
+
109
+ file mimetype_filename => epub_dir do
110
+ generate_mimetype_file
111
+ end
112
+
113
+ file container_filename => meta_inf_dir do
114
+ generate_container_file
115
+ end
116
+
117
+ file content_filename => [epub_dir, content_filenames].flatten do
118
+ generate_content_file
119
+ end
120
+
121
+ file ncx_filename => [epub_dir, content_filenames].flatten do
122
+ generate_ncx_file
123
+ end
124
+
125
+ all_filenames = [mimetype_filename, container_filename, content_filenames, content_filename, ncx_filename].flatten
126
+
127
+ file epub_filename => all_filenames do
128
+ root = Dir.pwd
129
+ epub_filename_fullpath = File.join(root, epub_filename)
130
+ cd epub_dir do
131
+ sh "zip -Xr9D \"#{epub_filename_fullpath}\" mimetype *"
132
+ end
133
+ end
134
+
135
+ task :build => epub_filename
136
+
137
+ end
138
+
139
+ task :build => 'epub2:build'
140
+
141
+ task :check => epub_filename do
142
+ sh 'epubcheck', epub_filename
143
+ end
144
+
145
+ end
146
+
147
+ end
@@ -0,0 +1,142 @@
1
+ # encoding: utf-8
2
+ require_relative 'epub_base'
3
+
4
+ module Ebookbinder
5
+
6
+ class Epub3 < EpubBase
7
+
8
+ def set_defaults
9
+ @id ||= Digest::MD5.hexdigest(@title)
10
+ @language ||= 'en'
11
+ @src_dir ||= 'src'
12
+ @build_dir ||= 'build'
13
+ @epub_dir ||= File.join(@build_dir, 'epub3')
14
+ @meta_inf_dir = File.join(@epub_dir, 'META-INF')
15
+ @epub_filename ||= File.join(@build_dir, format('%s - %s.epub', @author, @title))
16
+ end
17
+
18
+ def generate_content_file
19
+ puts "generate #{content_filename}" if verbose
20
+ builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
21
+ xml.package(xmlns: "http://www.idpf.org/2007/opf", 'unique-identifier': 'pub-id', version: '3.0', 'xml:lang': language) do
22
+ xml.metadata('xmlns:dc': 'http://purl.org/dc/elements/1.1/', 'xmlns:dcterms': 'http://purl.org/dc/terms/',
23
+ 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:opf': 'http://www.idpf.org/2007/opf') do
24
+ xml['dc'].identifier(id, id: 'pub-id')
25
+ xml['dc'].title title
26
+ xml['dc'].creator(@author, 'xml:lang' => language)
27
+ xml['dc'].language language
28
+ xml.meta(Time.now.utc.to_datetime.to_s.sub(/\+00:00$/, 'Z'), property: 'dcterms:modified')
29
+ end
30
+ xml.manifest do
31
+ i = 0
32
+ content_filenames.each do |fn|
33
+ i += 1
34
+ xml.item(id: format('id_%04d', i), href: href(fn), 'media-type' => Ebookbinder.mimetype_for_filename(fn))
35
+ end
36
+ xml.item(id: 'nav', href: href(nav_filename), 'media-type' => Ebookbinder.mimetype_for_filename(nav_filename), properties: 'nav')
37
+ end
38
+ xml.spine do
39
+ i = 0
40
+ content_filenames.each do |fn|
41
+ i += 1
42
+ next unless Ebookbinder.mimetype_for_filename(fn) == 'application/xhtml+xml'
43
+ xml.itemref(idref: format('id_%04d', i))
44
+ end
45
+ end
46
+ end
47
+ end
48
+ File.write(content_filename, builder.to_xml)
49
+ end
50
+
51
+ def nav_filename
52
+ File.join(@epub_dir, 'nav.xhtml')
53
+ end
54
+
55
+ def generate_nav_file
56
+ puts "generate #{nav_filename}"
57
+ builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
58
+ xml.html(xmlns: 'http://www.w3.org/1999/xhtml') do
59
+ xml.head do
60
+ xml.title @title
61
+ end
62
+ xml.body do
63
+ xml.nav('xmlns:epub' => 'http://www.idpf.org/2007/ops', 'epub:type' => 'toc', id: 'toc') do
64
+ xml.ol do
65
+ content_filenames.each do |fn|
66
+ next unless Ebookbinder.mimetype_for_filename(fn) == 'application/xhtml+xml'
67
+ Nokogiri.XML(File.read(fn)).search('h1').each do |e|
68
+ if id = e.attribute('id')
69
+ xml.li do
70
+ xml.a(e.text, href: href(fn, id))
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ File.write(nav_filename, builder.to_xml)
81
+ end
82
+
83
+ end
84
+
85
+ Epub3.define_tasks do
86
+
87
+ ::CLEAN << epub_dir
88
+ ::CLOBBER << build_dir << epub_filename
89
+
90
+ namespace :epub3 do
91
+
92
+ directory build_dir
93
+ directory epub_dir
94
+ directory meta_inf_dir
95
+
96
+ content_filenames.zip(source_filenames) do |cf, sf|
97
+ td = File.dirname(cf)
98
+ directory td
99
+ file cf => [td, sf] do
100
+ cp sf, cf
101
+ end
102
+ end
103
+
104
+ file mimetype_filename => epub_dir do
105
+ generate_mimetype_file
106
+ end
107
+
108
+ file container_filename => meta_inf_dir do
109
+ generate_container_file
110
+ end
111
+
112
+ file content_filename => [epub_dir, content_filenames].flatten do
113
+ generate_content_file
114
+ end
115
+
116
+ file nav_filename => [epub_dir, content_filenames].flatten do
117
+ generate_nav_file
118
+ end
119
+
120
+ all_filenames = [mimetype_filename, container_filename, content_filenames, content_filename, nav_filename].flatten
121
+
122
+ file epub_filename => all_filenames do
123
+ root = Dir.pwd
124
+ epub_filename_fullpath = File.join(root, epub_filename)
125
+ cd epub_dir do
126
+ sh "zip -Xr9D \"#{epub_filename_fullpath}\" mimetype *"
127
+ end
128
+ end
129
+
130
+ task :build => epub_filename
131
+
132
+ end
133
+
134
+ task :build => 'epub3:build'
135
+
136
+ task :check => epub_filename do
137
+ sh 'epubcheck', epub_filename
138
+ end
139
+
140
+ end
141
+
142
+ end
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+ require_relative 'ebook_base'
3
+
4
+ require 'date'
5
+ require 'digest/md5'
6
+ require 'nokogiri'
7
+
8
+ module Ebookbinder
9
+
10
+ class EpubBase < EbookBase
11
+
12
+ attr_accessor :epub_filename
13
+ attr_reader :epub_dir, :meta_inf_dir, :mimetype_filename, :nav_filename
14
+
15
+ protected
16
+
17
+ def check_mandatory_values
18
+ %w(title author).each do |attr|
19
+ unless self.send(attr)
20
+ raise format('No value for %s given!', attr)
21
+ end
22
+ end
23
+ end
24
+
25
+ def mimetype_filename
26
+ File.join(@epub_dir, 'mimetype')
27
+ end
28
+
29
+ def generate_mimetype_file
30
+ puts "generate #{mimetype_filename}" if verbose
31
+ File.write(mimetype_filename, 'application/epub+zip')
32
+ end
33
+
34
+ def container_filename
35
+ File.join(@meta_inf_dir, 'container.xml')
36
+ end
37
+
38
+ def generate_container_file
39
+ puts "generate #{container_filename}" if verbose
40
+ builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
41
+ xml.container(version: '1.0', xmlns: 'urn:oasis:names:tc:opendocument:xmlns:container') do
42
+ xml.rootfiles do
43
+ xml.rootfile('full-path': content_filename.sub(%r(^#{epub_dir}/?), ''), 'media-type': 'application/oebps-package+xml')
44
+ end
45
+ end
46
+ end
47
+ File.write(container_filename, builder.to_xml)
48
+ end
49
+
50
+ def content_filename
51
+ File.join(@epub_dir, 'content.opf')
52
+ end
53
+
54
+ def content_filenames
55
+ source_filenames.sub(/^#{src_dir}/, epub_dir)
56
+ end
57
+
58
+ def source_filenames
59
+ FileList.new(File.join(src_dir, '**/*')).select {|fn| !File.directory?(fn)}.sort
60
+ end
61
+
62
+ def href filename, id=nil
63
+ res = filename.sub(%r(^#{epub_dir}/?), '')
64
+ res << '#' << id.to_s if id
65
+ res
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ module Ebookbinder
4
+
5
+ VERSION = '1.0.0'
6
+
7
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ require 'rake'
3
+ require 'yaml'
4
+
5
+ module Ebookbinder
6
+
7
+ MIMETYPE_MAPPING = YAML.load <<-END
8
+ css: text/css
9
+ gif: image/gif
10
+ htm: text/html
11
+ html: text/html
12
+ jpe: image/jpeg
13
+ jpeg: image/jpeg
14
+ jpg: image/jpeg
15
+ png: image/png
16
+ svg: image/svg+xml
17
+ svgz: image/svg+xml
18
+ ttc: application/x-font-ttf
19
+ ttf: application/x-font-ttf
20
+ xhtml: application/xhtml+xml
21
+ END
22
+
23
+ def self.mimetype_for_filename fn
24
+ MIMETYPE_MAPPING[File.extname(fn).sub(/^\./, '')] or raise "Unknown mimetype for file #{fn}!"
25
+ end
26
+
27
+ end
28
+
29
+ include Ebookbinder
30
+
31
+ desc 'Build ebook file(s)'
32
+ task :build
33
+
34
+ desc 'Check ebook file(s)'
35
+ task :check
36
+
37
+ task :default => :build
@@ -0,0 +1,6 @@
1
+ require_relative '../../lib/ebookbinder/epub2'
2
+
3
+ Epub2.setup do |e|
4
+ e.author = 'Jan Friedrich'
5
+ e.title = 'Test Book in EPUB 2'
6
+ end
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/>
6
+ <title>Title 01</title>
7
+ </head>
8
+ <body>
9
+ <h1 id="id1">H1 number 1</h1>
10
+ <h1 id="id2">H1 number 2</h1>
11
+ <h1 id="id3">H1 number 3</h1>
12
+ <h1 id="id4">H1 number 4</h1>
13
+ <h1 id="id5">H1 number 5</h1>
14
+ </body>
15
+ </html>
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/>
6
+ <title>Title 02</title>
7
+ </head>
8
+ <body>
9
+ <h1 id="id1">H1 number 1</h1>
10
+ <h1 id="id2">H1 number 2</h1>
11
+ <h1 id="id3">H1 number 3</h1>
12
+ <h1 id="id4">H1 number 4</h1>
13
+ <h1 id="id5">H1 number 5</h1>
14
+ </body>
15
+ </html>
16
+
@@ -0,0 +1,6 @@
1
+ require_relative '../../lib/ebookbinder/epub3'
2
+
3
+ Epub3.setup do |e|
4
+ e.author = 'Jan Friedrich'
5
+ e.title = 'Test Book in EPUB 3'
6
+ end
@@ -0,0 +1,14 @@
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="en" lang="en">
4
+ <head>
5
+ <title>Title 01</title>
6
+ </head>
7
+ <body>
8
+ <h1 id="id1">H1 number 1</h1>
9
+ <h1 id="id2">H1 number 2</h1>
10
+ <h1 id="id3">H1 number 3</h1>
11
+ <h1 id="id4">H1 number 4</h1>
12
+ <h1 id="id5">H1 number 5</h1>
13
+ </body>
14
+ </html>
@@ -0,0 +1,15 @@
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="en" lang="en">
4
+ <head>
5
+ <title>Title 02</title>
6
+ </head>
7
+ <body>
8
+ <h1 id="id1">H1 number 1</h1>
9
+ <h1 id="id2">H1 number 2</h1>
10
+ <h1 id="id3">H1 number 3</h1>
11
+ <h1 id="id4">H1 number 4</h1>
12
+ <h1 id="id5">H1 number 5</h1>
13
+ </body>
14
+ </html>
15
+
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ebookbinder
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jan Friedrich
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2024-03-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rake
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rim
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.17'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.17'
40
+ description: ''
41
+ email: janfri26@gmail.com
42
+ executables: []
43
+ extensions: []
44
+ extra_rdoc_files: []
45
+ files:
46
+ - Changelog
47
+ - Gemfile
48
+ - LICENSE
49
+ - README.md
50
+ - Rakefile
51
+ - ebookbinder.gemspec
52
+ - lib/ebookbinder.rb
53
+ - lib/ebookbinder/ebook_base.rb
54
+ - lib/ebookbinder/epub2.rb
55
+ - lib/ebookbinder/epub3.rb
56
+ - lib/ebookbinder/epub_base.rb
57
+ - lib/ebookbinder/version.rb
58
+ - test/epub2/Rakefile
59
+ - test/epub2/src/01.xhtml
60
+ - test/epub2/src/02.xhtml
61
+ - test/epub3/Rakefile
62
+ - test/epub3/src/01.xhtml
63
+ - test/epub3/src/02.xhtml
64
+ licenses: []
65
+ metadata: {}
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubygems_version: 3.6.0.dev
81
+ specification_version: 4
82
+ summary: ''
83
+ test_files: []