class ReVIEW::EPUBMaker::EPUBCommon

EPUBCommon is the common class for EPUB producer. Some methods of this class are overridden by subclasses

Attributes

config[R]
contents[R]

Public Class Methods

new(producer) click to toggle source

Construct object with parameter hash config and message resource hash res.

# File lib/review/epubmaker/epubcommon.rb, line 25
def initialize(producer)
  @config = producer.config
  @contents = producer.contents
  @body_ext = nil
  @logger = ReVIEW.logger
  @workdir = nil
end

Public Instance Methods

call_hook(filename, *params) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 357
def call_hook(filename, *params)
  return if !filename.present? || !File.exist?(filename) || !FileTest.executable?(filename)

  if ENV['REVIEW_SAFE_MODE'].to_i & 1 > 0
    warn 'hook is prohibited in safe mode. ignored.'
  else
    system(filename, *params)
  end
end
colophon() click to toggle source

Return colophon content.

# File lib/review/epubmaker/epubcommon.rb, line 167
def colophon
  @title = h(ReVIEW::I18n.t('colophontitle'))
  @isbn_hyphen = isbn_hyphen

  @body = ReVIEW::Template.generate(path: template_name(localfile: '_colophon.html.erb', systemfile: './html/_colophon.html.erb'), binding: binding)

  @language = config['language']
  @stylesheets = config['stylesheet']
  ReVIEW::Template.generate(path: template_name, binding: binding)
end
colophon_history() click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 188
def colophon_history
  @col_history = []
  if config['history']
    config['history'].each_with_index do |items, edit|
      items.each_with_index do |item, rev|
        editstr = edit == 0 ? ReVIEW::I18n.t('first_edition') : ReVIEW::I18n.t('nth_edition', (edit + 1).to_s)
        revstr = ReVIEW::I18n.t('nth_impression', (rev + 1).to_s)
        if /\A\d+-\d+-\d+\Z/.match?(item)
          @col_history << ReVIEW::I18n.t('published_by1', [date_to_s(item), editstr + revstr])
        elsif /\A(\d+-\d+-\d+)[\s ](.+)/.match?(item)
          # custom date with string
          item.match(/\A(\d+-\d+-\d+)[\s ](.+)/) do |m|
            @col_history << ReVIEW::I18n.t('published_by3', [date_to_s(m[1]), m[2]])
          end
        else
          # free format
          @col_history << item
        end
      end
    end
  end

  ReVIEW::Template.generate(path: template_name(localfile: '_colophon_history.html.erb', systemfile: './html/_colophon_history.html.erb'), binding: binding)
end
container() click to toggle source

Return container content.

# File lib/review/epubmaker/epubcommon.rb, line 89
def container
  @opf_path = opf_path
  ReVIEW::Template.generate(path: './xml/container.xml.erb', binding: binding)
end
cover() click to toggle source

Return cover content. If Producer#config["coverimage"] is defined, it will be used for the cover image.

# File lib/review/epubmaker/epubcommon.rb, line 126
def cover
  @body_ext = config['epubversion'] >= 3 ? %Q( epub:type="cover") : nil

  if config['coverimage']
    @coverimage_src = coverimage
    raise ApplicationError, "coverimage #{config['coverimage']} not found. Abort." unless @coverimage_src
  end
  @body = ReVIEW::Template.generate(path: template_name(localfile: '_cover.html.erb', systemfile: 'html/_cover.html.erb'), binding: binding)

  @title = h(config.name_of('title'))
  @language = config['language']
  @stylesheets = config['stylesheet']
  ret = ReVIEW::Template.generate(path: template_name, binding: binding)
  @body_ext = nil
  ret
end
coverimage() click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 94
def coverimage
  return nil unless config['coverimage']

  item = contents.find { |content| content.coverimage?(config['coverimage']) }

  if item
    item.file
  end
end
coveritem() click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 234
def coveritem
  []
end
date_to_s(date) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 213
def date_to_s(date)
  require 'date'
  d = Date.parse(date)
  d.strftime(ReVIEW::I18n.t('date_format'))
end
flat_ncx(type, indent = nil) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 309
def flat_ncx(type, indent = nil)
  s = %Q(<#{type} class="toc-h1">\n)
  (coveritem + contents).each do |item|
    next if !item.notoc.nil? || item.level.nil? || item.file.nil? || item.title.nil? || item.level > config['toclevel'].to_i

    is = indent == true ? ' ' * item.level : ''
    s << %Q(<li><a href="#{item.file}">#{is}#{h(item.title)}</a></li>\n)
  end
  s << %Q(</#{type}>\n)

  s
end
h(str) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 36
def h(str)
  CGI.escapeHTML(str)
end
hierarchy_ncx(type) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 238
def hierarchy_ncx(type)
  require 'rexml/document'
  level = 1
  find_jump = nil
  has_part = nil
  toclevel = config['toclevel'].to_i

  # check part existance
  contents.each do |item|
    next if item.notoc || item.chaptype != 'part'

    has_part = true
    break
  end

  if has_part
    contents.each do |item|
      if item.chaptype == 'part' && item.level > 0
        # sections in part
        item.level -= 1
      end
      # down level for part and chaps. pre, appendix, post are preserved
      if item.chaptype == 'part' || item.chaptype == 'body'
        item.level += 1
      end
    end
    toclevel += 1
  end

  doc = REXML::Document.new(%Q(<#{type} class="toc-h#{level}"><li /></#{type}>))
  doc.context[:attribute_quote] = :quote

  e = doc.root.elements[1] # first <li/>
  (coveritem + contents).each do |item|
    next if !item.notoc.nil? || item.level.nil? || item.file.nil? || item.title.nil? || item.level > toclevel

    if item.level == level
      e2 = e.parent.add_element('li')
      e = e2
    elsif item.level > level
      find_jump = true if (item.level - level) > 1
      # deeper
      (level + 1).upto(item.level) do |n|
        if e.size == 0
          # empty span for epubcheck
          e.attributes['style'] = 'list-style-type: none;'
          es = e.add_element('span', 'style' => 'display:none;')
          es.add_text(REXML::Text.new('&#xa0;', false, nil, true))
        end

        e2 = e.add_element(type, 'class' => "toc-h#{n}")
        e3 = e2.add_element('li')
        e = e3
      end
      level = item.level
    elsif item.level < level
      # shallower
      (level - 1).downto(item.level) { e = e.parent.parent }
      e2 = e.parent.add_element('li')
      e = e2
      level = item.level
    end
    e2 = e.add_element('a', 'href' => item.file)
    e2.add_text(REXML::Text.new(item.title, true))
  end

  warn %Q(found level jumping in table of contents. consider to use 'epubmaker:flattoc: true' for strict ePUB validator.) unless find_jump.nil?

  doc.to_s.gsub('<li/>', '').gsub('</li>', "</li>\n").gsub("<#{type} ", "\n" + '\&') # ugly
end
isbn_hyphen() click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 178
def isbn_hyphen
  str = config['isbn'].to_s

  if /\A\d{10}\Z/.match?(str)
    "#{str[0..0]}-#{str[1..5]}-#{str[6..8]}-#{str[9..9]}"
  elsif /\A\d{13}\Z/.match?(str)
    "#{str[0..2]}-#{str[3..3]}-#{str[4..8]}-#{str[9..11]}-#{str[12..12]}"
  end
end
join_with_separator(value, sep) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 371
def join_with_separator(value, sep)
  if value.is_a?(Array)
    value.join(sep)
  else
    value
  end
end
legacy_cover_and_title_file(loadfile, writefile) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 367
def legacy_cover_and_title_file(loadfile, writefile)
  FileUtils.cp(loadfile, writefile)
end
mimetype() click to toggle source

Return mimetype content.

# File lib/review/epubmaker/epubcommon.rb, line 46
def mimetype
  'application/epub+zip'
end
mytoc() click to toggle source

Return own toc content.

# File lib/review/epubmaker/epubcommon.rb, line 220
def mytoc
  @title = h(ReVIEW::I18n.t('toctitle'))
  @body = %Q(  <h1 class="toc-title">#{h(ReVIEW::I18n.t('toctitle'))}</h1>\n)
  @body << if config['epubmaker']['flattoc'].nil?
             hierarchy_ncx('ul')
           else
             flat_ncx('ul', config['epubmaker']['flattocindent'])
           end

  @language = config['language']
  @stylesheets = config['stylesheet']
  ReVIEW::Template.generate(path: template_name, binding: binding)
end
ncx(indentarray) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 84
def ncx(indentarray)
  raise NotImplementedError # should be overridden
end
opf() click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 50
def opf
  raise NotImplementedError # should be overridden
end
opf_coverimage() click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 70
def opf_coverimage
  if config['coverimage']
    item = contents.find { |content| content.coverimage?(config['coverimage']) }

    unless item
      raise ApplicationError, "coverimage #{config['coverimage']} not found. Abort."
    end

    %Q(    <meta name="cover" content="#{item.id}"/>\n)
  else
    ''
  end
end
opf_manifest() click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 54
def opf_manifest
  raise NotImplementedError # should be overridden
end
opf_metainfo() click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 58
def opf_metainfo
  raise NotImplementedError # should be overridden
end
opf_path() click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 66
def opf_path
  "OEBPS/#{config['bookname']}.opf"
end
opf_tocx() click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 62
def opf_tocx
  raise NotImplementedError # should be overridden
end
produce(_epubfile, _basedir, _tmpdir, base_dir:) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 40
def produce(_epubfile, _basedir, _tmpdir, base_dir:)
  @workdir = base_dir
  raise NotImplementedError # should be overridden
end
produce_write_common(basedir, tmpdir) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 322
def produce_write_common(basedir, tmpdir)
  File.write(File.join(tmpdir, 'mimetype'), mimetype)

  FileUtils.mkdir_p(File.join(tmpdir, 'META-INF'))
  File.write(File.join(tmpdir, 'META-INF', 'container.xml'), container)

  FileUtils.mkdir_p(File.join(tmpdir, 'OEBPS'))
  File.write(File.join(tmpdir, opf_path), opf)

  if config['cover']
    if File.exist?(File.join(basedir, File.basename(config['cover'])))
      FileUtils.cp(File.join(basedir, File.basename(config['cover'])), File.join(tmpdir, 'OEBPS'))
    else
      File.write(File.join(tmpdir, 'OEBPS', File.basename(config['cover'])), cover)
    end
  end

  if config['colophon'] && !config['colophon'].is_a?(String)
    filename = File.join(basedir, "colophon.#{config['htmlext']}")
    File.write(filename, colophon)
  end

  contents.each do |item|
    next if /#/.match?(item.file) # skip subgroup

    fname = File.join(basedir, item.file)
    unless File.exist?(fname)
      raise ApplicationError, "#{fname} is not found."
    end

    FileUtils.mkdir_p(File.dirname(File.join(tmpdir, 'OEBPS', item.file)))
    FileUtils.cp(fname, File.join(tmpdir, 'OEBPS', item.file))
  end
end
template_name(localfile: 'layout.html.erb', systemfile: nil) click to toggle source
# File lib/review/epubmaker/epubcommon.rb, line 104
def template_name(localfile: 'layout.html.erb', systemfile: nil)
  if @workdir
    layoutfile = File.join(@workdir, 'layouts', localfile)
    if File.exist?(layoutfile)
      return layoutfile
    end
  end

  if systemfile
    return systemfile
  end

  if config['htmlversion'].to_i == 5
    './html/layout-html5.html.erb'
  else
    './html/layout-xhtml1.html.erb'
  end
end
titlepage() click to toggle source

Return title (copying) content. NOTE: this method is not used yet.

see lib/review/epubmaker.rb#build_titlepage
# File lib/review/epubmaker/epubcommon.rb, line 146
def titlepage
  @title = h(config.name_of('title'))

  @title_str = config.name_of('title')
  if config['subtitle']
    @subtitle_str = config.name_of('subtitle')
  end
  if config['aut']
    @author_str = join_with_separator(config.names_of('aut'), ReVIEW::I18n.t('names_splitter'))
  end
  if config.names_of('pbl')
    @publisher_str = join_with_separator(config.names_of('pbl'), ReVIEW::I18n.t('names_splitter'))
  end
  @body = ReVIEW::Template.generate(path: template_name(localfile: '_titlepage.html.erb', systemfile: './html/_titlepage.html.erb'), binding: binding)

  @language = config['language']
  @stylesheets = config['stylesheet']
  ReVIEW::Template.generate(path: template_name, binding: binding)
end