diff --git a/bin/review-epub2html b/bin/review-epub2html new file mode 100755 index 000000000..d5d30bfa2 --- /dev/null +++ b/bin/review-epub2html @@ -0,0 +1,19 @@ +#!/usr/bin/env ruby +# +# Copyright (c) 2018 Kenshi Muto +# +# This program is free software. +# You can distribute or modify this program under the terms of +# the GNU LGPL, Lesser General Public License version 2.1. +# For details of the GNU LGPL, see the file "COPYING". + +require 'pathname' + +bindir = Pathname.new(__FILE__).realpath.dirname +$LOAD_PATH.unshift((bindir + '../lib').realpath) + +require 'review/epub2html' + +if File.basename($PROGRAM_NAME) == File.basename(__FILE__) + ReVIEW::Epub2Html.execute(*ARGV) +end diff --git a/lib/review/book/base.rb b/lib/review/book/base.rb index b2d529583..f318bdab2 100644 --- a/lib/review/book/base.rb +++ b/lib/review/book/base.rb @@ -249,11 +249,11 @@ def part_exist? end def read_bib - File.read(File.join(@basedir, bib_file)) + File.read(File.join(contentdir, bib_file)) end def bib_exist? - File.exist?(File.join(@basedir, bib_file)) + File.exist?(File.join(contentdir, bib_file)) end def prefaces diff --git a/lib/review/epub2html.rb b/lib/review/epub2html.rb new file mode 100644 index 000000000..27a1e20d0 --- /dev/null +++ b/lib/review/epub2html.rb @@ -0,0 +1,133 @@ +# +# Copyright (c) 2018 Kenshi Muto +# +# This program is free software. +# You can distribute or modify this program under the terms of +# the GNU LGPL, Lesser General Public License version 2.1. +# For details of the GNU LGPL, see the file "COPYING". + +require 'zip' +require 'rexml/document' +require 'cgi' + +module ReVIEW + class Epub2Html + def self.execute(*args) + new.execute(*args) + end + + def execute(*args) + if args[0].nil? || !File.exist?(args[0]) + STDERR.puts < HTMLfile + file_for_head_and_foot: HTML file to extract header and footer area. + This file must be contained in the EPUB. + If omitted, the first found file is used. +EOT + exit 1 + end + + parse_epub(args[0]) + puts join_html(args[1]) + end + + def initialize + @opfxml = nil + @htmls = {} + @head = nil + @tail = nil + end + + def parse_epub(epubname) + Zip::File.open(epubname) do |zio| + zio.each do |entry| + if entry.name =~ /.+\.opf\Z/ + opf = entry.get_input_stream.read + @opfxml = REXML::Document.new(opf) + elsif entry.name =~ /.+\.x?html\Z/ + @htmls[entry.name.sub('OEBPS/', '')] = entry.get_input_stream.read.force_encoding('utf-8') + end + end + end + nil + end + + def take_headtail(html) + @head = html.sub(/().*/m, '\1') + @tail = html.sub(%r{.*()}m, '\1') + end + + def sanitize(s) + s = s.sub(/\.x?html\Z/, ''). + sub(%r{\A\./}, '') + 's_' + CGI.escape(s). + gsub(/[.,+%]/, '_') + end + + def modify_html(fname, html) + doc = REXML::Document.new(html) + doc.context[:attribute_quote] = :quote + + ids = {} + + doc.each_element('//*[@id]') do |e| + sid = "#{sanitize(fname)}_#{sanitize(e.attributes['id'])}" + while ids[sid] + sid += 'E' + end + ids[sid] = true + e.attributes['id'] = sid + end + + doc.each_element('//a[@href]') do |e| + href = e.attributes['href'] + if href.start_with?('http:', 'https:', 'ftp:', 'ftps:', 'mailto:') + next + end + + file, anc = href.split('#', 2) + if anc + if file.empty? + anc = "#{sanitize(fname)}_#{sanitize(anc)}" + else + anc = "#{sanitize(file)}_#{sanitize(anc)}" + end + else + anc = sanitize(file) + end + + e.attributes['href'] = "##{anc}" + end + + doc.to_s. + sub(/.*()/m, %Q(
)). + sub(%r{().*}m, '
') + end + + def join_html(reffile) + body = [] + make_list.each do |fname| + if @head.nil? && (reffile.nil? || reffile == fname) + take_headtail(@htmls[fname]) + end + + body << modify_html(fname, @htmls[fname]) + end + "#{@head}\n#{body.join("\n")}\n#{@tail}" + end + + def make_list + items = {} + @opfxml.each_element("/package/manifest/item[@media-type='application/xhtml+xml']") do |e| + items[e.attributes['id']] = e.attributes['href'] + end + + files = [] + @opfxml.each_element('/package/spine/itemref') do |e| + files.push(items[e.attributes['idref']]) + end + + files + end + end +end diff --git a/lib/review/init.rb b/lib/review/init.rb index e6d001064..c2575a08c 100644 --- a/lib/review/init.rb +++ b/lib/review/init.rb @@ -123,7 +123,7 @@ def generate_images_dir(dir) end def generate_cover_image(dir) - FileUtils.cp(@review_dir + '/test/sample-book/src/images/cover.jpg', + FileUtils.cp(@review_dir + '/samples/sample-book/src/images/cover.jpg', dir + '/images/') end @@ -143,7 +143,7 @@ def generate_config(dir) end def generate_style(dir) - FileUtils.cp @review_dir + '/test/sample-book/src/style.css', dir + FileUtils.cp @review_dir + '/samples/sample-book/src/style.css', dir end def generate_texmacro(dir) @@ -165,7 +165,7 @@ def generate_rakefile(dir) EOS end - FileUtils.cp(@review_dir + '/test/sample-book/src/Rakefile', + FileUtils.cp(@review_dir + '/samples/sample-book/src/Rakefile', dir + '/lib/tasks/review.rake') end diff --git a/samples/LICENSE b/samples/LICENSE new file mode 100644 index 000000000..83a1a9512 --- /dev/null +++ b/samples/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2006-2018 Minero Aoki, Kenshi Muto, Masayoshi Takahashi, Masanori Kado. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/test/sample-book/README.md b/samples/sample-book/README.md similarity index 100% rename from test/sample-book/README.md rename to samples/sample-book/README.md diff --git a/test/sample-book/src/Rakefile b/samples/sample-book/src/Rakefile similarity index 100% rename from test/sample-book/src/Rakefile rename to samples/sample-book/src/Rakefile diff --git a/test/sample-book/src/_cover.html b/samples/sample-book/src/_cover.html similarity index 100% rename from test/sample-book/src/_cover.html rename to samples/sample-book/src/_cover.html diff --git a/test/sample-book/src/catalog.yml b/samples/sample-book/src/catalog.yml similarity index 100% rename from test/sample-book/src/catalog.yml rename to samples/sample-book/src/catalog.yml diff --git a/test/sample-book/src/ch01.re b/samples/sample-book/src/ch01.re similarity index 100% rename from test/sample-book/src/ch01.re rename to samples/sample-book/src/ch01.re diff --git a/test/sample-book/src/ch02.re b/samples/sample-book/src/ch02.re similarity index 100% rename from test/sample-book/src/ch02.re rename to samples/sample-book/src/ch02.re diff --git a/test/sample-book/src/config-epub2.yml b/samples/sample-book/src/config-epub2.yml similarity index 100% rename from test/sample-book/src/config-epub2.yml rename to samples/sample-book/src/config-epub2.yml diff --git a/test/sample-book/src/config.yml b/samples/sample-book/src/config.yml similarity index 100% rename from test/sample-book/src/config.yml rename to samples/sample-book/src/config.yml diff --git a/test/sample-book/src/images/ch01-imgsample.jpg b/samples/sample-book/src/images/ch01-imgsample.jpg similarity index 100% rename from test/sample-book/src/images/ch01-imgsample.jpg rename to samples/sample-book/src/images/ch01-imgsample.jpg diff --git a/test/sample-book/src/images/cover.jpg b/samples/sample-book/src/images/cover.jpg similarity index 100% rename from test/sample-book/src/images/cover.jpg rename to samples/sample-book/src/images/cover.jpg diff --git a/test/sample-book/src/preface.re b/samples/sample-book/src/preface.re similarity index 100% rename from test/sample-book/src/preface.re rename to samples/sample-book/src/preface.re diff --git a/test/sample-book/src/sty/jumoline.sty b/samples/sample-book/src/sty/jumoline.sty similarity index 100% rename from test/sample-book/src/sty/jumoline.sty rename to samples/sample-book/src/sty/jumoline.sty diff --git a/test/sample-book/src/sty/reviewmacro.sty b/samples/sample-book/src/sty/reviewmacro.sty similarity index 100% rename from test/sample-book/src/sty/reviewmacro.sty rename to samples/sample-book/src/sty/reviewmacro.sty diff --git a/test/sample-book/src/style-web.css b/samples/sample-book/src/style-web.css similarity index 100% rename from test/sample-book/src/style-web.css rename to samples/sample-book/src/style-web.css diff --git a/test/sample-book/src/style.css b/samples/sample-book/src/style.css similarity index 100% rename from test/sample-book/src/style.css rename to samples/sample-book/src/style.css diff --git a/test/syntax-book/Gemfile b/samples/syntax-book/Gemfile similarity index 100% rename from test/syntax-book/Gemfile rename to samples/syntax-book/Gemfile diff --git a/test/syntax-book/Rakefile b/samples/syntax-book/Rakefile similarity index 100% rename from test/syntax-book/Rakefile rename to samples/syntax-book/Rakefile diff --git a/test/syntax-book/appA.re b/samples/syntax-book/appA.re similarity index 100% rename from test/syntax-book/appA.re rename to samples/syntax-book/appA.re diff --git a/test/syntax-book/bib.re b/samples/syntax-book/bib.re similarity index 100% rename from test/syntax-book/bib.re rename to samples/syntax-book/bib.re diff --git a/test/syntax-book/catalog.yml b/samples/syntax-book/catalog.yml similarity index 100% rename from test/syntax-book/catalog.yml rename to samples/syntax-book/catalog.yml diff --git a/test/syntax-book/ch01.re b/samples/syntax-book/ch01.re similarity index 100% rename from test/syntax-book/ch01.re rename to samples/syntax-book/ch01.re diff --git a/test/syntax-book/ch02.re b/samples/syntax-book/ch02.re similarity index 100% rename from test/syntax-book/ch02.re rename to samples/syntax-book/ch02.re diff --git a/test/syntax-book/ch03.re b/samples/syntax-book/ch03.re similarity index 100% rename from test/syntax-book/ch03.re rename to samples/syntax-book/ch03.re diff --git a/test/syntax-book/config.yml b/samples/syntax-book/config.yml similarity index 100% rename from test/syntax-book/config.yml rename to samples/syntax-book/config.yml diff --git a/test/syntax-book/images/ball.png b/samples/syntax-book/images/ball.png similarity index 100% rename from test/syntax-book/images/ball.png rename to samples/syntax-book/images/ball.png diff --git a/test/syntax-book/images/cover.jpg b/samples/syntax-book/images/cover.jpg similarity index 100% rename from test/syntax-book/images/cover.jpg rename to samples/syntax-book/images/cover.jpg diff --git a/test/syntax-book/images/fractal.png b/samples/syntax-book/images/fractal.png similarity index 100% rename from test/syntax-book/images/fractal.png rename to samples/syntax-book/images/fractal.png diff --git a/test/syntax-book/images/img3-1.png b/samples/syntax-book/images/img3-1.png similarity index 100% rename from test/syntax-book/images/img3-1.png rename to samples/syntax-book/images/img3-1.png diff --git a/test/syntax-book/images/inlineicon.jpg b/samples/syntax-book/images/inlineicon.jpg similarity index 100% rename from test/syntax-book/images/inlineicon.jpg rename to samples/syntax-book/images/inlineicon.jpg diff --git a/test/syntax-book/images/logic.png b/samples/syntax-book/images/logic.png similarity index 100% rename from test/syntax-book/images/logic.png rename to samples/syntax-book/images/logic.png diff --git a/test/syntax-book/images/logic2.png b/samples/syntax-book/images/logic2.png similarity index 100% rename from test/syntax-book/images/logic2.png rename to samples/syntax-book/images/logic2.png diff --git a/test/syntax-book/images/puzzle.jpg b/samples/syntax-book/images/puzzle.jpg similarity index 100% rename from test/syntax-book/images/puzzle.jpg rename to samples/syntax-book/images/puzzle.jpg diff --git a/test/syntax-book/images/table.jpg b/samples/syntax-book/images/table.jpg similarity index 100% rename from test/syntax-book/images/table.jpg rename to samples/syntax-book/images/table.jpg diff --git a/test/syntax-book/part2.re b/samples/syntax-book/part2.re similarity index 100% rename from test/syntax-book/part2.re rename to samples/syntax-book/part2.re diff --git a/test/syntax-book/pre01.re b/samples/syntax-book/pre01.re similarity index 100% rename from test/syntax-book/pre01.re rename to samples/syntax-book/pre01.re diff --git a/test/syntax-book/review-ext.rb b/samples/syntax-book/review-ext.rb similarity index 100% rename from test/syntax-book/review-ext.rb rename to samples/syntax-book/review-ext.rb diff --git a/test/syntax-book/sty/jumoline.sty b/samples/syntax-book/sty/jumoline.sty similarity index 100% rename from test/syntax-book/sty/jumoline.sty rename to samples/syntax-book/sty/jumoline.sty diff --git a/test/syntax-book/sty/reviewmacro.sty b/samples/syntax-book/sty/reviewmacro.sty similarity index 100% rename from test/syntax-book/sty/reviewmacro.sty rename to samples/syntax-book/sty/reviewmacro.sty diff --git a/test/syntax-book/style.css b/samples/syntax-book/style.css similarity index 100% rename from test/syntax-book/style.css rename to samples/syntax-book/style.css diff --git a/test/syntax-book/syntax.dic b/samples/syntax-book/syntax.dic similarity index 100% rename from test/syntax-book/syntax.dic rename to samples/syntax-book/syntax.dic diff --git a/test/test_helper.rb b/test/test_helper.rb index e5aa7b1f3..c7a695622 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -11,7 +11,7 @@ def assets_dir end def prepare_samplebook(srcdir) - samplebook_dir = File.expand_path('sample-book/src/', File.dirname(__FILE__)) + samplebook_dir = File.expand_path('../samples/sample-book/src/', File.dirname(__FILE__)) FileUtils.cp_r(Dir.glob(samplebook_dir + '/*'), srcdir) YAML.load(File.open(srcdir + '/config.yml')) end