epub-parser 0.1.3 → 0.1.4
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 +4 -4
- data/.yardopts +5 -2
- data/CHANGELOG.markdown +33 -0
- data/Gemfile +0 -2
- data/README.markdown +15 -6
- data/Rakefile +7 -2
- data/docs/FixedLayout.markdown +98 -0
- data/{wiki/Home.md → docs/Home.markdown} +5 -7
- data/{wiki/Item.md → docs/Item.markdown} +10 -10
- data/epub-parser.gemspec +2 -3
- data/lib/epub.rb +6 -0
- data/lib/epub/content_document/navigation.rb +4 -0
- data/lib/epub/content_document/xhtml.rb +5 -0
- data/lib/epub/parser/content_document.rb +0 -7
- data/lib/epub/parser/ocf.rb +4 -4
- data/lib/epub/parser/publication.rb +4 -0
- data/lib/epub/parser/version.rb +1 -1
- data/lib/epub/publication/fixed_layout.rb +209 -0
- data/lib/epub/publication/package.rb +4 -0
- data/lib/epub/publication/package/manifest.rb +9 -1
- data/lib/epub/publication/package/spine.rb +36 -0
- data/test/test_content_document.rb +32 -0
- data/test/test_fixed_layout.rb +258 -0
- data/test/test_parser_fixed_layout.rb +16 -0
- data/test/test_publication.rb +95 -4
- metadata +15 -21
- data/test/fixtures/book/OPS/CASE-SENSITIVE.xhtml +0 -9
| @@ -41,6 +41,10 @@ module EPUB | |
| 41 41 | 
             
                    end
         | 
| 42 42 | 
             
                    @unique_identifier_id = elem['unique-identifier']
         | 
| 43 43 | 
             
                    @package.prefix = parse_prefix(extract_attribute(elem, 'prefix'))
         | 
| 44 | 
            +
                    if @package.prefix.key? 'rendition'
         | 
| 45 | 
            +
                      require 'epub/publication/fixed_layout'
         | 
| 46 | 
            +
                      EPUB::Publication.__send__ :include, EPUB::Publication::FixedLayout
         | 
| 47 | 
            +
                    end
         | 
| 44 48 |  | 
| 45 49 | 
             
                    @package
         | 
| 46 50 | 
             
                  end
         | 
    
        data/lib/epub/parser/version.rb
    CHANGED
    
    
| @@ -0,0 +1,209 @@ | |
| 1 | 
            +
            module EPUB
         | 
| 2 | 
            +
              module Publication
         | 
| 3 | 
            +
                module FixedLayout
         | 
| 4 | 
            +
                  PREFIX_KEY = 'rendition'.freeze
         | 
| 5 | 
            +
                  PREFIX_VALUE = 'http://www.idpf.org/vocab/rendition/#'.freeze
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  RENDITION_PROPERTIES = {
         | 
| 8 | 
            +
                    'layout'      => ['reflowable'.freeze, 'pre-paginated'.freeze].freeze,
         | 
| 9 | 
            +
                    'orientation' => ['auto'.freeze, 'landscape'.freeze, 'portrait'.freeze].freeze,
         | 
| 10 | 
            +
                    'spread'      => ['auto'.freeze, 'none'.freeze, 'landscape'.freeze, 'portrait'.freeze, 'both'.freeze].freeze
         | 
| 11 | 
            +
                  }.freeze
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  class UnsupportedRenditionValue < StandardError; end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  class << self
         | 
| 16 | 
            +
                    def included(package_class)
         | 
| 17 | 
            +
                      [
         | 
| 18 | 
            +
                       [Package, PackageMixin],
         | 
| 19 | 
            +
                       [Package::Metadata, MetadataMixin],
         | 
| 20 | 
            +
                       [Package::Spine::Itemref, ItemrefMixin],
         | 
| 21 | 
            +
                       [Package::Manifest::Item, ItemMixin],
         | 
| 22 | 
            +
                       [ContentDocument::XHTML, ContentDocumentMixin],
         | 
| 23 | 
            +
                      ].each do |(base, mixin)|
         | 
| 24 | 
            +
                        base.__send__ :include, mixin
         | 
| 25 | 
            +
                      end
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  module Rendition
         | 
| 30 | 
            +
                    # @note Call after defining #rendition_xxx and #renditionn_xxx=
         | 
| 31 | 
            +
                    def def_rendition_methods
         | 
| 32 | 
            +
                      RENDITION_PROPERTIES.each_key do |property|
         | 
| 33 | 
            +
                        alias_method property, "rendition_#{property}"
         | 
| 34 | 
            +
                        alias_method "#{property}=", "rendition_#{property}="
         | 
| 35 | 
            +
                      end
         | 
| 36 | 
            +
                      def_rendition_layout_methods
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    def def_rendition_layout_methods
         | 
| 40 | 
            +
                      property = 'layout'
         | 
| 41 | 
            +
                      RENDITION_PROPERTIES[property].each do |value|
         | 
| 42 | 
            +
                        method_name_base = value.gsub('-', '_')
         | 
| 43 | 
            +
                        writer_name = "#{method_name_base}="
         | 
| 44 | 
            +
                        define_method writer_name do |new_value|
         | 
| 45 | 
            +
                          new_prop = new_value ? value : values.find {|l| l != value}
         | 
| 46 | 
            +
                          __send__ "rendition_#{property}=", new_prop
         | 
| 47 | 
            +
                        end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                        maker_name = "make_#{method_name_base}"
         | 
| 50 | 
            +
                        define_method maker_name do
         | 
| 51 | 
            +
                          __send__ "rendition_#{property}=", value
         | 
| 52 | 
            +
                        end
         | 
| 53 | 
            +
                        destructive_method_name = "#{method_name_base}!"
         | 
| 54 | 
            +
                        alias_method destructive_method_name, maker_name
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                        predicate_name = "#{method_name_base}?"
         | 
| 57 | 
            +
                        define_method predicate_name do
         | 
| 58 | 
            +
                          __send__("rendition_#{property}") == value
         | 
| 59 | 
            +
                        end
         | 
| 60 | 
            +
                      end
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  module PackageMixin
         | 
| 65 | 
            +
                    # @return [true, false]
         | 
| 66 | 
            +
                    def using_fixed_layout
         | 
| 67 | 
            +
                      prefix.has_key? PREFIX_KEY and
         | 
| 68 | 
            +
                        prefix[PREFIX_KEY] == PREFIX_VALUE
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
                    alias using_fixed_layout? using_fixed_layout
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                    # @param using_fixed_layout [true, false]
         | 
| 73 | 
            +
                    def using_fixed_layout=(using_fixed_layout)
         | 
| 74 | 
            +
                      if using_fixed_layout
         | 
| 75 | 
            +
                        prefix[PREFIX_KEY] = PREFIX_VALUE
         | 
| 76 | 
            +
                      else
         | 
| 77 | 
            +
                        prefix.delete PREFIX_KEY
         | 
| 78 | 
            +
                      end
         | 
| 79 | 
            +
                    end
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  module MetadataMixin
         | 
| 83 | 
            +
                    extend Rendition
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                    RENDITION_PROPERTIES.each_pair do |property, values|
         | 
| 86 | 
            +
                      define_method "rendition_#{property}" do
         | 
| 87 | 
            +
                        meta = metas.find {|m| m.property == "rendition:#{property}"}
         | 
| 88 | 
            +
                        meta ? meta.content : values.first
         | 
| 89 | 
            +
                      end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                      define_method "rendition_#{property}=" do |new_value|
         | 
| 92 | 
            +
                        raise UnsupportedRenditionValue, new_value unless values.include? new_value
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                        prefixed_property = "rendition:#{property}"
         | 
| 95 | 
            +
                        values_to_be_deleted = values - [new_value]
         | 
| 96 | 
            +
                        metas.delete_if {|meta| meta.property == prefixed_property && values_to_be_deleted.include?(meta.content)}
         | 
| 97 | 
            +
                        unless metas.any? {|meta| meta.property == prefixed_property && meta.content == new_value}
         | 
| 98 | 
            +
                          meta = Package::Metadata::Meta.new
         | 
| 99 | 
            +
                          meta.property = prefixed_property
         | 
| 100 | 
            +
                          meta.content = new_value
         | 
| 101 | 
            +
                          metas << meta
         | 
| 102 | 
            +
                        end
         | 
| 103 | 
            +
                        new_value
         | 
| 104 | 
            +
                      end
         | 
| 105 | 
            +
                    end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                    def_rendition_methods
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                  module ItemrefMixin
         | 
| 111 | 
            +
                    extend Rendition
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                    PAGE_SPREAD_PROPERTY = 'center'
         | 
| 114 | 
            +
                    PAGE_SPREAD_PREFIX = 'rendition:page-spread-'
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                    class << self
         | 
| 117 | 
            +
                      # @todo Define using Module#prepend after Ruby 2.0 will become popular
         | 
| 118 | 
            +
                      def included(base)
         | 
| 119 | 
            +
                        return if base.instance_methods.include? :page_spread_without_fixed_layout
         | 
| 120 | 
            +
                        base.__send__ :alias_method, :page_spread_without_fixed_layout, :page_spread
         | 
| 121 | 
            +
                        base.__send__ :alias_method, :page_spread_writer_without_fixed_layout, :page_spread=
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                        prefixed_page_spread_property = "#{PAGE_SPREAD_PREFIX}#{PAGE_SPREAD_PROPERTY}"
         | 
| 124 | 
            +
                        base.__send__ :define_method, :page_spread do
         | 
| 125 | 
            +
                          property = page_spread_without_fixed_layout
         | 
| 126 | 
            +
                          return property if property
         | 
| 127 | 
            +
                          property = properties.find {|prop| prop == prefixed_page_spread_property}
         | 
| 128 | 
            +
                          property ? PAGE_SPREAD_PROPERTY : nil
         | 
| 129 | 
            +
                        end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                        base.__send__ :define_method, :page_spread= do |new_value|
         | 
| 132 | 
            +
                          if new_value == PAGE_SPREAD_PROPERTY
         | 
| 133 | 
            +
                            page_spread_writer_without_fixed_layout nil
         | 
| 134 | 
            +
                            properties << prefixed_page_spread_property
         | 
| 135 | 
            +
                          else
         | 
| 136 | 
            +
                            page_spread_writer_without_fixed_layout new_value
         | 
| 137 | 
            +
                          end
         | 
| 138 | 
            +
                          new_value
         | 
| 139 | 
            +
                        end
         | 
| 140 | 
            +
                      end
         | 
| 141 | 
            +
                    end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                    RENDITION_PROPERTIES.each do |property, values|
         | 
| 144 | 
            +
                      rendition_property_prefix = "rendition:#{property}-"
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                      reader_name = "rendition_#{property}"
         | 
| 147 | 
            +
                      define_method reader_name do
         | 
| 148 | 
            +
                        prop_value = properties.find {|prop| prop.start_with? rendition_property_prefix}
         | 
| 149 | 
            +
                        prop_value ? prop_value.gsub(/\A#{Regexp.escape(rendition_property_prefix)}/, '') :
         | 
| 150 | 
            +
                          spine.package.metadata.__send__(reader_name)
         | 
| 151 | 
            +
                      end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                      writer_name = "#{reader_name}="
         | 
| 154 | 
            +
                      define_method writer_name do |new_value|
         | 
| 155 | 
            +
                        if new_value.nil?
         | 
| 156 | 
            +
                          properties.delete_if {|prop| prop.start_with? rendition_property_prefix}
         | 
| 157 | 
            +
                          return new_value
         | 
| 158 | 
            +
                        end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                        raise UnsupportedRenditionValue, new_value unless values.include? new_value
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                        values_to_be_deleted = (values - [new_value]).map {|value| "#{rendition_property_prefix}#{value}"}
         | 
| 163 | 
            +
                        properties.delete_if {|prop| values_to_be_deleted.include? prop}
         | 
| 164 | 
            +
                        new_property = "#{rendition_property_prefix}#{new_value}"
         | 
| 165 | 
            +
                        properties << new_property unless properties.any? {|prop| prop == new_property}
         | 
| 166 | 
            +
                        new_value
         | 
| 167 | 
            +
                      end
         | 
| 168 | 
            +
                    end
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                    def_rendition_methods
         | 
| 171 | 
            +
                  end
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                  module ItemMixin
         | 
| 174 | 
            +
                    extend Rendition
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                    RENDITION_PROPERTIES.each_key do |property|
         | 
| 177 | 
            +
                      define_method "rendition_#{property}" do
         | 
| 178 | 
            +
                        itemref.__send__ property
         | 
| 179 | 
            +
                      end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                      writer_name = "rendition_#{property}="
         | 
| 182 | 
            +
                      define_method writer_name do |value|
         | 
| 183 | 
            +
                        itemref.__send__ writer_name, value
         | 
| 184 | 
            +
                      end
         | 
| 185 | 
            +
                    end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                    def_rendition_methods
         | 
| 188 | 
            +
                  end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                  module ContentDocumentMixin
         | 
| 191 | 
            +
                    extend Rendition
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                    RENDITION_PROPERTIES.each_key do |property|
         | 
| 194 | 
            +
                      reader_name = "rendition_#{property}"
         | 
| 195 | 
            +
                      define_method reader_name do
         | 
| 196 | 
            +
                        item.__send__ reader_name
         | 
| 197 | 
            +
                      end
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                      writer_name = "rendition_#{property}="
         | 
| 200 | 
            +
                      define_method writer_name do |value|
         | 
| 201 | 
            +
                        item.__send__ writer_name, value
         | 
| 202 | 
            +
                      end
         | 
| 203 | 
            +
                    end
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                    def_rendition_methods
         | 
| 206 | 
            +
                  end
         | 
| 207 | 
            +
                end
         | 
| 208 | 
            +
              end
         | 
| 209 | 
            +
            end
         | 
| @@ -9,10 +9,12 @@ module EPUB | |
| 9 9 | 
             
                    attr_accessor :package,
         | 
| 10 10 | 
             
                                  :id
         | 
| 11 11 |  | 
| 12 | 
            +
                    # @return self
         | 
| 12 13 | 
             
                    def <<(item)
         | 
| 13 14 | 
             
                      @items ||= {}
         | 
| 14 15 | 
             
                      item.manifest = self
         | 
| 15 16 | 
             
                      @items[item.id] = item
         | 
| 17 | 
            +
                      self
         | 
| 16 18 | 
             
                    end
         | 
| 17 19 |  | 
| 18 20 | 
             
                    def navs
         | 
| @@ -90,7 +92,13 @@ module EPUB | |
| 90 92 |  | 
| 91 93 | 
             
                      def content_document
         | 
| 92 94 | 
             
                        return nil unless %w[application/xhtml+xml image/svg+xml].include? media_type
         | 
| 93 | 
            -
                        @content_document ||= Parser::ContentDocument. | 
| 95 | 
            +
                        @content_document ||= Parser::ContentDocument.new(self).parse
         | 
| 96 | 
            +
                      end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                      # @return [Package::Spine::Itemref]
         | 
| 99 | 
            +
                      # @return nil when no Itemref refers this Item
         | 
| 100 | 
            +
                      def itemref
         | 
| 101 | 
            +
                        manifest.package.spine.itemrefs.find {|itemref| itemref.idref == id}
         | 
| 94 102 | 
             
                      end
         | 
| 95 103 |  | 
| 96 104 | 
             
                      protected
         | 
| @@ -6,10 +6,12 @@ module EPUB | |
| 6 6 | 
             
                                  :id, :toc, :page_progression_direction
         | 
| 7 7 | 
             
                    attr_reader :itemrefs
         | 
| 8 8 |  | 
| 9 | 
            +
                    # @return self
         | 
| 9 10 | 
             
                    def <<(itemref)
         | 
| 10 11 | 
             
                      @itemrefs ||= []
         | 
| 11 12 | 
             
                      itemref.spine = self
         | 
| 12 13 | 
             
                      @itemrefs << itemref
         | 
| 14 | 
            +
                      self
         | 
| 13 15 | 
             
                    end
         | 
| 14 16 |  | 
| 15 17 | 
             
                    # @yield [itemref]
         | 
| @@ -32,20 +34,54 @@ module EPUB | |
| 32 34 | 
             
                    end
         | 
| 33 35 |  | 
| 34 36 | 
             
                    class Itemref
         | 
| 37 | 
            +
                      PAGE_SPREAD_PROPERTIES = ['left'.freeze, 'right'.freeze].freeze
         | 
| 38 | 
            +
                      PAGE_SPREAD_PREFIX = 'page-spread-'.freeze
         | 
| 39 | 
            +
             | 
| 35 40 | 
             
                      attr_accessor :spine,
         | 
| 36 41 | 
             
                                    :idref, :linear, :id, :properties
         | 
| 37 42 | 
             
                      alias linear? linear
         | 
| 38 43 |  | 
| 44 | 
            +
                      def initialize
         | 
| 45 | 
            +
                        @properties = []
         | 
| 46 | 
            +
                      end
         | 
| 47 | 
            +
             | 
| 39 48 | 
             
                      # @return [Package::Manifest::Item] item referred by this object
         | 
| 40 49 | 
             
                      def item
         | 
| 41 50 | 
             
                        @item ||= @spine.package.manifest[idref]
         | 
| 42 51 | 
             
                      end
         | 
| 43 52 |  | 
| 53 | 
            +
                      def item=(item)
         | 
| 54 | 
            +
                        self.idref = item.id
         | 
| 55 | 
            +
                        item
         | 
| 56 | 
            +
                      end
         | 
| 57 | 
            +
             | 
| 44 58 | 
             
                      def ==(other)
         | 
| 45 59 | 
             
                        [:spine, :idref, :linear, :id].all? {|meth|
         | 
| 46 60 | 
             
                          self.__send__(meth) == other.__send__(meth)
         | 
| 47 61 | 
             
                        } and (other.properties - properties).empty?
         | 
| 48 62 | 
             
                      end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                      # @return ["left", "right", nil]
         | 
| 65 | 
            +
                      def page_spread
         | 
| 66 | 
            +
                        property = properties.find {|prop| prop.start_with? PAGE_SPREAD_PREFIX}
         | 
| 67 | 
            +
                        property ? property.gsub(/\A#{Regexp.escape(PAGE_SPREAD_PREFIX)}/, '') : nil
         | 
| 68 | 
            +
                      end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                      # @param new_value ["left", "right", nil]
         | 
| 71 | 
            +
                      def page_spread=(new_value)
         | 
| 72 | 
            +
                        if new_value.nil?
         | 
| 73 | 
            +
                          properties.delete_if {|prop| prop.start_with? PAGE_SPREAD_PREFIX}
         | 
| 74 | 
            +
                          return new_value
         | 
| 75 | 
            +
                        end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                        raise "Unsupported page-spread property: #{new_value}" unless PAGE_SPREAD_PROPERTIES.include? new_value
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                        props_to_be_deleted = (PAGE_SPREAD_PROPERTIES - [new_value]).map {|prop| "#{PAGE_SPREAD_PREFIX}#{prop}"}
         | 
| 80 | 
            +
                        properties.delete_if {|prop| props_to_be_deleted.include? prop}
         | 
| 81 | 
            +
                        new_property = "#{PAGE_SPREAD_PREFIX}#{new_value}"
         | 
| 82 | 
            +
                        properties << new_property unless properties.include? new_property
         | 
| 83 | 
            +
                        new_value
         | 
| 84 | 
            +
                      end
         | 
| 49 85 | 
             
                    end
         | 
| 50 86 | 
             
                  end
         | 
| 51 87 | 
             
                end
         | 
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            require_relative 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TestContentDocument < Test::Unit::TestCase
         | 
| 4 | 
            +
              include EPUB::ContentDocument
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def test_top_level?
         | 
| 7 | 
            +
                manifest = EPUB::Publication::Package::Manifest.new
         | 
| 8 | 
            +
                spine = EPUB::Publication::Package::Spine.new
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                item1 = EPUB::Publication::Package::Manifest::Item.new
         | 
| 11 | 
            +
                item1.id = 'item1'
         | 
| 12 | 
            +
                item2 = EPUB::Publication::Package::Manifest::Item.new
         | 
| 13 | 
            +
                item2.id = 'item2'
         | 
| 14 | 
            +
                manifest << item1 << item2
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                itemref = EPUB::Publication::Package::Spine::Itemref.new
         | 
| 17 | 
            +
                itemref.idref = 'item1'
         | 
| 18 | 
            +
                spine << itemref
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                package = EPUB::Publication::Package.new
         | 
| 21 | 
            +
                package.manifest = manifest
         | 
| 22 | 
            +
                package.spine = spine
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                doc = XHTML.new
         | 
| 25 | 
            +
                doc.item = item1
         | 
| 26 | 
            +
                assert_true doc.top_level?
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                doc = XHTML.new
         | 
| 29 | 
            +
                doc.item = item2
         | 
| 30 | 
            +
                assert_false doc.top_level?
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| @@ -0,0 +1,258 @@ | |
| 1 | 
            +
            require_relative 'helper'
         | 
| 2 | 
            +
            require 'epub/book'
         | 
| 3 | 
            +
            require 'epub/publication'
         | 
| 4 | 
            +
            require 'epub/publication/fixed_layout'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            class EPUB::Publication::Package
         | 
| 7 | 
            +
              include EPUB::Publication::FixedLayout
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            class TestFixedLayout < Test::Unit::TestCase
         | 
| 11 | 
            +
              include EPUB::Publication
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              class TestPackage < TestFixedLayout
         | 
| 14 | 
            +
                def test_package_dont_use_fixed_layout_by_default
         | 
| 15 | 
            +
                  assert_false Package.new.using_fixed_layout?
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def test_make_package_use_fixed_layout
         | 
| 19 | 
            +
                  package = Package.new
         | 
| 20 | 
            +
                  package.using_fixed_layout = true
         | 
| 21 | 
            +
                  assert_true package.using_fixed_layout?
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  package.using_fixed_layout = false
         | 
| 24 | 
            +
                  assert_false package.using_fixed_layout?
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              class TestMetadata < TestFixedLayout
         | 
| 29 | 
            +
                def setup
         | 
| 30 | 
            +
                  @metadata = Package::Metadata.new
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def test_default_layout_is_reflowable
         | 
| 34 | 
            +
                  assert_equal 'reflowable', @metadata.rendition_layout
         | 
| 35 | 
            +
                  assert_true @metadata.reflowable?
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def test_deafult_layout_is_not_pre_paginated
         | 
| 39 | 
            +
                  assert_false @metadata.pre_paginated?
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def test_layout_is_pre_paginated_when_has_meta_with_rendition_layout
         | 
| 43 | 
            +
                  meta = Package::Metadata::Meta.new
         | 
| 44 | 
            +
                  meta.property = 'rendition:layout'
         | 
| 45 | 
            +
                  meta.content = 'pre-paginated'
         | 
| 46 | 
            +
                  @metadata.metas << meta
         | 
| 47 | 
            +
                  assert_equal 'pre-paginated', @metadata.rendition_layout
         | 
| 48 | 
            +
                  assert_true @metadata.pre_paginated?
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                def test_layout_is_reflowable_when_has_meta_with_rendition_layout
         | 
| 52 | 
            +
                  meta = Package::Metadata::Meta.new
         | 
| 53 | 
            +
                  meta.property = 'rendition:layout'
         | 
| 54 | 
            +
                  meta.content = 'reflowable'
         | 
| 55 | 
            +
                  @metadata.metas << meta
         | 
| 56 | 
            +
                  assert_equal 'reflowable', @metadata.rendition_layout
         | 
| 57 | 
            +
                  assert_true @metadata.reflowable?
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def test_can_set_rendition_layout_by_method_of_metadata
         | 
| 61 | 
            +
                  @metadata.pre_paginated = true
         | 
| 62 | 
            +
                  assert_equal 'pre-paginated', @metadata.rendition_layout
         | 
| 63 | 
            +
                  assert_false @metadata.reflowable?
         | 
| 64 | 
            +
                  assert_true @metadata.pre_paginated?
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  @metadata.reflowable = true
         | 
| 67 | 
            +
                  assert_equal 'reflowable', @metadata.rendition_layout
         | 
| 68 | 
            +
                  assert_true @metadata.reflowable?
         | 
| 69 | 
            +
                  assert_false @metadata.pre_paginated?
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                def test_remove_meta_for_pre_paginated_when_making_reflowable
         | 
| 73 | 
            +
                  meta = Package::Metadata::Meta.new
         | 
| 74 | 
            +
                  meta.property = 'rendition:layout'
         | 
| 75 | 
            +
                  meta.content = 'pre-paginated'
         | 
| 76 | 
            +
                  @metadata.metas << meta
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  @metadata.reflowable = true
         | 
| 79 | 
            +
                  assert_false @metadata.metas.any? {|m| m.property == 'rendition:layout' && m.content == 'pre-paginated'}
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                def test_remove_meta_for_reflowable_when_making_pre_paginated
         | 
| 83 | 
            +
                  meta = Package::Metadata::Meta.new
         | 
| 84 | 
            +
                  meta.property = 'rendition:layout'
         | 
| 85 | 
            +
                  meta.content = 'pre-paginated'
         | 
| 86 | 
            +
                  @metadata.metas << meta
         | 
| 87 | 
            +
                  meta = Package::Metadata::Meta.new
         | 
| 88 | 
            +
                  meta.property = 'rendition:layout'
         | 
| 89 | 
            +
                  meta.content = 'reflowable'
         | 
| 90 | 
            +
                  @metadata.metas << meta
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  @metadata.pre_paginated = true
         | 
| 93 | 
            +
                  assert_false @metadata.metas.any? {|m| m.property == 'rendition:layout' && m.content == 'reflowable'}
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                def test_layout_setter
         | 
| 97 | 
            +
                  @metadata.rendition_layout = 'reflowable'
         | 
| 98 | 
            +
                  assert_equal 'reflowable', @metadata.rendition_layout
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                  @metadata.rendition_layout = 'pre-paginated'
         | 
| 101 | 
            +
                  assert_equal 'pre-paginated', @metadata.rendition_layout
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  assert_raise FixedLayout::UnsupportedRenditionValue do
         | 
| 104 | 
            +
                    @metadata.rendition_layout = 'undefined'
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                def test_utility_methods_for_rendition_layout_setter
         | 
| 109 | 
            +
                  @metadata.make_pre_paginated
         | 
| 110 | 
            +
                  assert_equal 'pre-paginated', @metadata.rendition_layout
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  @metadata.make_reflowable
         | 
| 113 | 
            +
                  assert_equal 'reflowable', @metadata.rendition_layout
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                  @metadata.pre_paginated!
         | 
| 116 | 
            +
                  assert_equal 'pre-paginated', @metadata.rendition_layout
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                  @metadata.reflowable!
         | 
| 119 | 
            +
                  assert_equal 'reflowable', @metadata.rendition_layout
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                def test_default_orientation_is_auto
         | 
| 123 | 
            +
                  assert_equal 'auto', @metadata.rendition_orientation
         | 
| 124 | 
            +
                end
         | 
| 125 | 
            +
              end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
              class TestItemref < TestFixedLayout
         | 
| 128 | 
            +
                def setup
         | 
| 129 | 
            +
                  @itemref = Package::Spine::Itemref.new
         | 
| 130 | 
            +
                  @package = Package.new
         | 
| 131 | 
            +
                  @package.metadata = Package::Metadata.new
         | 
| 132 | 
            +
                  @package.spine = Package::Spine.new
         | 
| 133 | 
            +
                  @package.spine << @itemref
         | 
| 134 | 
            +
                end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                def test_inherits_metadatas_rendition_layout_by_default
         | 
| 137 | 
            +
                  assert_equal 'reflowable', @itemref.rendition_layout
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                  @package.metadata.rendition_layout = 'pre-paginated'
         | 
| 140 | 
            +
                  assert_equal 'pre-paginated', @itemref.rendition_layout
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                def test_overwrite_rendition_layout_of_metadata_when_set_explicitly
         | 
| 144 | 
            +
                  @package.metadata.rendition_layout = 'pre-paginated'
         | 
| 145 | 
            +
                  @itemref.properties << 'rendition:layout-reflowable'
         | 
| 146 | 
            +
                  assert_equal 'reflowable', @itemref.rendition_layout
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                def test_can_set_explicitly
         | 
| 150 | 
            +
                  @itemref.rendition_layout = 'pre-paginated'
         | 
| 151 | 
            +
                  assert_equal 'pre-paginated', @itemref.rendition_layout
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                def test_can_unset_explicitly
         | 
| 155 | 
            +
                  @itemref.rendition_layout = 'pre-paginated'
         | 
| 156 | 
            +
                  @itemref.rendition_layout = nil
         | 
| 157 | 
            +
                  assert_equal 'reflowable', @itemref.rendition_layout
         | 
| 158 | 
            +
                  assert_not_include @itemref.properties, 'rendition:layout-reflowable'
         | 
| 159 | 
            +
                end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                def test_property_added_when_rendition_layout_set
         | 
| 162 | 
            +
                  @itemref.rendition_layout = 'pre-paginated'
         | 
| 163 | 
            +
                  assert_include @itemref.properties, 'rendition:layout-pre-paginated'
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                def test_opposite_property_removed_if_exists_when_rendition_layout_set
         | 
| 167 | 
            +
                  @itemref.rendition_layout = 'reflowable'
         | 
| 168 | 
            +
                  @itemref.rendition_layout = 'pre-paginated'
         | 
| 169 | 
            +
                  assert_not_include @itemref.properties, 'rendition:layout-reflowable'
         | 
| 170 | 
            +
                end
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                def test_utility_methods
         | 
| 173 | 
            +
                  assert_true @itemref.reflowable?
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                  @itemref.make_pre_paginated
         | 
| 176 | 
            +
                  assert_false @itemref.reflowable?
         | 
| 177 | 
            +
                  assert_true @itemref.pre_paginated?
         | 
| 178 | 
            +
                  assert_not_include @itemref.properties, 'rendition:layout-reflowbale'
         | 
| 179 | 
            +
                  assert_include @itemref.properties, 'rendition:layout-pre-paginated'
         | 
| 180 | 
            +
                end
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                def test_inherits_metadatas_rendition_spread_by_default
         | 
| 183 | 
            +
                  assert_equal 'auto', @itemref.rendition_spread
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                  @package.metadata.rendition_spread = 'portrait'
         | 
| 186 | 
            +
                  assert_equal 'portrait', @itemref.rendition_spread
         | 
| 187 | 
            +
                end
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                def test_rendition_property_reader_has_alias
         | 
| 190 | 
            +
                  assert_equal 'auto', @itemref.orientation
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                  @itemref.orientation = 'landscape'
         | 
| 193 | 
            +
                  assert_equal 'landscape', @itemref.rendition_orientation
         | 
| 194 | 
            +
                end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                def test_page_spread_center_defined
         | 
| 197 | 
            +
                  @itemref.properties << 'rendition:page-spread-center'
         | 
| 198 | 
            +
                  assert_equal 'center', @itemref.page_spread
         | 
| 199 | 
            +
                end
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                def test_can_make_page_spread_center_explicitly
         | 
| 202 | 
            +
                  @itemref.page_spread = 'center'
         | 
| 203 | 
            +
                  assert_include @itemref.properties, 'rendition:page-spread-center'
         | 
| 204 | 
            +
                end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                def test_page_spread_is_exclusive
         | 
| 207 | 
            +
                  @itemref.page_spread = 'right'
         | 
| 208 | 
            +
                  @itemref.page_spread = 'center'
         | 
| 209 | 
            +
                  assert_not_include @itemref.properties, 'page-spread-right'
         | 
| 210 | 
            +
                end
         | 
| 211 | 
            +
              end
         | 
| 212 | 
            +
             | 
| 213 | 
            +
              class TestItem < TestFixedLayout
         | 
| 214 | 
            +
                def setup
         | 
| 215 | 
            +
                  package = Package.new
         | 
| 216 | 
            +
                  package.manifest = Package::Manifest.new
         | 
| 217 | 
            +
                  @item = Package::Manifest::Item.new
         | 
| 218 | 
            +
                  @item.id = 'item'
         | 
| 219 | 
            +
                  package.manifest << @item
         | 
| 220 | 
            +
                  package.spine = Package::Spine.new
         | 
| 221 | 
            +
                  @itemref = Package::Spine::Itemref.new
         | 
| 222 | 
            +
                  @itemref.idref = 'item'
         | 
| 223 | 
            +
                  package.spine << @itemref
         | 
| 224 | 
            +
                end
         | 
| 225 | 
            +
             | 
| 226 | 
            +
                def test_can_access_rendition_attributes
         | 
| 227 | 
            +
                  @itemref.rendition_layout = 'pre-paginated'
         | 
| 228 | 
            +
                  assert_true @item.pre_paginated?
         | 
| 229 | 
            +
             | 
| 230 | 
            +
                  @item.rendition_orientation = 'portrait'
         | 
| 231 | 
            +
                  assert_equal 'portrait', @itemref.rendition_orientation
         | 
| 232 | 
            +
                end
         | 
| 233 | 
            +
              end
         | 
| 234 | 
            +
             | 
| 235 | 
            +
              class TestContentDocument < TestFixedLayout
         | 
| 236 | 
            +
                def setup
         | 
| 237 | 
            +
                  package = Package.new
         | 
| 238 | 
            +
                  package.manifest = Package::Manifest.new
         | 
| 239 | 
            +
                  item = Package::Manifest::Item.new
         | 
| 240 | 
            +
                  item.id = 'item'
         | 
| 241 | 
            +
                  package.manifest << item
         | 
| 242 | 
            +
                  package.spine = Package::Spine.new
         | 
| 243 | 
            +
                  @itemref = Package::Spine::Itemref.new
         | 
| 244 | 
            +
                  @itemref.idref = 'item'
         | 
| 245 | 
            +
                  package.spine << @itemref
         | 
| 246 | 
            +
                  @doc = EPUB::ContentDocument::XHTML.new
         | 
| 247 | 
            +
                  @doc.item = item
         | 
| 248 | 
            +
                end
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                def test_can_access_rendition_attributes
         | 
| 251 | 
            +
                  @itemref.rendition_layout = 'pre-paginated'
         | 
| 252 | 
            +
                  assert_true @doc.pre_paginated?
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                  @doc.rendition_spread = 'none'
         | 
| 255 | 
            +
                  assert_equal 'none', @itemref.rendition_spread
         | 
| 256 | 
            +
                end
         | 
| 257 | 
            +
              end
         | 
| 258 | 
            +
            end
         |