ebookbinder 1.0.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 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: []