Class: ODFWriter::Template

Inherits:
Object
  • Object
show all
Defined in:
lib/odf_writer/template.rb

Overview

Template: handles files in .odt-package

Constant Summary collapse

CONTENT_ENTRIES =

constants - we only work and content and styles (contains headers and footers) parts of odf

{
  "content.xml"  => {:symbol => :content,  :path => "content.xml"},
  "styles.xml"   => {:symbol => :styles,   :path => "styles.xml" }
}.freeze
CONTENT_FILES =
{
  :content       => {:file => "content.xml",  :path => "content.xml"},
  :styles        => {:file => "styles.xml",   :path => "styles.xml" }
}.freeze
MANIFEST =
'META-INF/manifest.xml'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path = nil, zip_stream: nil) ⇒ Template

initialize



60
61
62
63
64
65
66
67
# File 'lib/odf_writer/template.rb', line 60

def initialize(path = nil, zip_stream: nil)

  raise "You must provide either a filename or a zip_stream: string" unless path || zip_stream
  raise "Template [#{template}] not found." if path && !::File.exist?(path)
  
  @path       = path
  @zip_stream = zip_stream
end

Instance Attribute Details

#output_streamObject

accessors



53
54
55
# File 'lib/odf_writer/template.rb', line 53

def output_stream
  @output_stream
end

Instance Method Details

#content(&block) ⇒ Object

content



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/odf_writer/template.rb', line 74

def content(&block)

  entries.each do |entry|
  
    if entry.directory?
      next
      
    elsif CONTENT_ENTRIES.keys.include?(entry.name)
      # relevant file with valid file name
      entry.get_input_stream do |input_stream|
        file_content = input_stream.sysread
        yield CONTENT_ENTRIES[entry.name][:symbol], to_xml(file_content)
      end
      
    end #if
  end #each
end

#dataObject

data: just a handle to data in buffer



168
169
170
# File 'lib/odf_writer/template.rb', line 168

def data
  @buffer.string
end

#update_contentObject

update_content: create write buffer for zip



97
98
99
100
101
102
# File 'lib/odf_writer/template.rb', line 97

def update_content
  @buffer = Zip::OutputStream.write_buffer do |out|
    @output_stream = out
    yield self
  end
end

#update_files(&block) ⇒ Object

update_files: open and traverse zip directory, pick content.xml

and styles.xml process and eventually write contents 
to buffer
a pointer to manifest.xml is provided


112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/odf_writer/template.rb', line 112

def update_files(&block)
  
  # get manifest, in case a file is added
  # @manifest = manifest; digest = Digest::MD5.hexdigest(@manifest)
  @manifest = manifest
  
  # the very first entry must be a file named "mimetype", not compressed
  #mimetype = ::Zip::Entry.new("out.zip", "mimetype")
  # file attribute 0 means binary file
  #mimetype.internal_file_attributes = 0
  #mimetype.compression_method = ::Zip::COMPRESSION_METHOD_STORE
  #@output_stream.put_next_entry(mimetype)
  @output_stream.put_next_entry("mimetype", nil, nil, ::Zip::COMPRESSION_METHOD_STORE)
  @output_stream.write "application/vnd.oasis.opendocument.text"
  
  entries.each do |entry|
  
    next if entry.directory?
    next if entry.name == "mimetype" # neglect possible other mimetype files
    next if entry.name == MANIFEST
    
    # process content files
    if CONTENT_ENTRIES.keys.include?(entry.name)
    
      entry.get_input_stream do |input_stream|
        file_content = input_stream.sysread
        file_symbol  = CONTENT_ENTRIES[entry.name][:symbol]
        # process entry, if files are added, then @mainfest is changed
        process_entry(file_symbol, file_content, @manifest, &block)
        
        @output_stream.put_next_entry(entry.name)
        @output_stream.write file_content
      end #do
      
    else
      entry.get_input_stream do |input_stream|
        @output_stream.put_next_entry(entry.name)
        @output_stream.write input_stream.sysread
      end
    end #if
  end #each
  
  # eventually write back content file
 #if @manifest && digest != Digest::MD5.hexdigest(@manifest)
    @output_stream.put_next_entry(MANIFEST)
    @output_stream.write @manifest
 #end #if
  
end