Class: Idml::Package
- Inherits:
-
Object
- Object
- Idml::Package
- Defined in:
- lib/idml/package.rb
Overview
Read/write access to an IDML package's ZIP container. A Package
holds a path; ZIP and part reads are lazy. Typed part access goes
through #part(name) which dispatches via Idml::Parts.class_for.
Instance Attribute Summary collapse
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Class Method Summary collapse
Instance Method Summary collapse
- #backing_story ⇒ Object
- #designmap ⇒ Object
- #dom_version ⇒ Object
- #each_part ⇒ Object
- #fonts ⇒ Object
- #graphic ⇒ Object
- #has_part?(name) ⇒ Boolean
-
#initialize(path) ⇒ Package
constructor
A new instance of Package.
- #mapping ⇒ Object
- #master_spread_by_id(master_id) ⇒ Object
- #master_spreads ⇒ Object
-
#part(name) ⇒ Object
Returns a typed part instance for
namewhen a class is registered for that file pattern (e.g. Designmap for designmap.xml). - #part_names ⇒ Object
- #preferences ⇒ Object
- #read_part(name) ⇒ Object
- #spreads ⇒ Object
- #stories ⇒ Object
- #story_by_id(story_id) ⇒ Object
- #style ⇒ Object
- #style_mapping ⇒ Object
- #tags ⇒ Object
Constructor Details
#initialize(path) ⇒ Package
Returns a new instance of Package.
22 23 24 25 26 |
# File 'lib/idml/package.rb', line 22 def initialize(path) raise Errors::PackageNotFound, path.to_s unless File.exist?(path) @path = File.(path) end |
Instance Attribute Details
#path ⇒ Object (readonly)
Returns the value of attribute path.
28 29 30 |
# File 'lib/idml/package.rb', line 28 def path @path end |
Class Method Details
.write(parts:, to:) ⇒ Object
167 168 169 170 171 172 173 174 |
# File 'lib/idml/package.rb', line 167 def self.write(parts:, to:) raise Errors::InvalidPackage, "no parts given" if parts.empty? output_path = File.(to) FileUtils.mkdir_p(File.dirname(output_path)) write_to_zip(parts, output_path) new(output_path) end |
Instance Method Details
#backing_story ⇒ Object
34 35 36 |
# File 'lib/idml/package.rb', line 34 def backing_story @backing_story ||= part("XML/BackingStory.xml") end |
#designmap ⇒ Object
30 31 32 |
# File 'lib/idml/package.rb', line 30 def designmap @designmap ||= part("designmap.xml") end |
#dom_version ⇒ Object
110 111 112 |
# File 'lib/idml/package.rb', line 110 def dom_version designmap&.dom_version end |
#each_part ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/idml/package.rb', line 155 def each_part return enum_for(:each_part) unless block_given? with_zip do |zip_file| zip_file.each do |entry| next if entry.directory? yield entry.name, entry.get_input_stream.read end end end |
#fonts ⇒ Object
70 71 72 73 74 |
# File 'lib/idml/package.rb', line 70 def fonts return unless has_part?("Resources/Fonts.xml") @fonts ||= part("Resources/Fonts.xml") end |
#graphic ⇒ Object
76 77 78 79 80 |
# File 'lib/idml/package.rb', line 76 def graphic return unless has_part?("Resources/Graphic.xml") @graphic ||= part("Resources/Graphic.xml") end |
#has_part?(name) ⇒ Boolean
124 125 126 |
# File 'lib/idml/package.rb', line 124 def has_part?(name) part_names.include?(name) end |
#mapping ⇒ Object
106 107 108 |
# File 'lib/idml/package.rb', line 106 def mapping @mapping ||= part("XML/Mapping.xml") if has_part?("XML/Mapping.xml") end |
#master_spread_by_id(master_id) ⇒ Object
61 62 63 64 65 66 67 68 |
# File 'lib/idml/package.rb', line 61 def master_spread_by_id(master_id) return nil unless master_id name = "MasterSpreads/MasterSpread_#{master_id}.xml" return nil unless has_part?(name) part(name) end |
#master_spreads ⇒ Object
42 43 44 45 46 |
# File 'lib/idml/package.rb', line 42 def master_spreads @master_spreads ||= part_names.grep(%r{\AMasterSpreads/}).map do |n| part(n) end end |
#part(name) ⇒ Object
Returns a typed part instance for name when a class is registered
for that file pattern (e.g. Designmap for designmap.xml). Falls
back to Parts::Raw — a lossless XML wrapper — for unmodeled parts.
Parsed parts are memoized: rendering resolves stories,
preferences, and styles repeatedly (per frame), and each
un-memoized read would re-decompress and re-parse the zip
entry.
141 142 143 144 |
# File 'lib/idml/package.rb', line 141 def part(name) @part_cache ||= {} @part_cache[name] ||= parse_part(name) end |
#part_names ⇒ Object
114 115 116 117 118 119 120 121 122 |
# File 'lib/idml/package.rb', line 114 def part_names @part_names ||= with_zip do |zip_file| names = [] zip_file.each do |entry| names << entry.name if entry.name && !entry.name.empty? end names.sort end end |
#preferences ⇒ Object
95 96 97 98 99 100 |
# File 'lib/idml/package.rb', line 95 def preferences if has_part?("Resources/Preferences.xml") @preferences ||= part("Resources/Preferences.xml") end end |
#read_part(name) ⇒ Object
128 129 130 131 132 |
# File 'lib/idml/package.rb', line 128 def read_part(name) raise Errors::PartNotFound, name unless has_part?(name) with_zip { |zip_file| zip_file.read(name) } end |
#spreads ⇒ Object
38 39 40 |
# File 'lib/idml/package.rb', line 38 def spreads @spreads ||= part_names.grep(%r{\ASpreads/}).map { |n| part(n) } end |
#stories ⇒ Object
48 49 50 |
# File 'lib/idml/package.rb', line 48 def stories @stories ||= part_names.grep(%r{\AStories/}).map { |n| part(n) } end |
#story_by_id(story_id) ⇒ Object
52 53 54 55 56 57 58 59 |
# File 'lib/idml/package.rb', line 52 def story_by_id(story_id) return nil unless story_id name = "Stories/Story_#{story_id}.xml" return nil unless has_part?(name) part(name) end |
#style ⇒ Object
82 83 84 85 86 |
# File 'lib/idml/package.rb', line 82 def style return unless has_part?("Resources/Styles.xml") @style ||= part("Resources/Styles.xml") end |
#style_mapping ⇒ Object
88 89 90 91 92 93 |
# File 'lib/idml/package.rb', line 88 def style_mapping if has_part?("Resources/StyleMapping.xml") @style_mapping ||= part("Resources/StyleMapping.xml") end end |
#tags ⇒ Object
102 103 104 |
# File 'lib/idml/package.rb', line 102 def @tags ||= part("XML/Tags.xml") if has_part?("XML/Tags.xml") end |