class ODFWriter::Template

Template: handles files in .odt-package

Constants

CONTENT_ENTRIES

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

CONTENT_FILES
MANIFEST

Attributes

output_stream[RW]

accessors

Public Class Methods

new(path = nil, zip_stream: nil) click to toggle source

initialize

# 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

Public Instance Methods

content() { |CONTENT_ENTRIES[:symbol], to_xml(file_content)| ... } click to toggle source

content

# 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
data() click to toggle source

data: just a handle to data in buffer

# File lib/odf_writer/template.rb, line 156
def data
  @buffer.string
end
update_content() { |self| ... } click to toggle source

update_content: create write buffer for zip

# 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) click to toggle source

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
# 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)
  
  entries.each do |entry|
  
    # search content files
    if entry.directory?
      next
      
    # process content files
    elsif 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(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

Private Instance Methods

entries() click to toggle source

entries: just open zip file or buffer

# File lib/odf_writer/template.rb, line 170
def entries
  if @path
    Zip::File.open(@path)
  elsif @zip_stream
    Zip::File.open_buffer(@zip_stream.force_encoding("ASCII-8BIT"))
  end
end
manifest() click to toggle source

manifest: read manifest

# File lib/odf_writer/template.rb, line 181
def manifest
  manifest = nil
  entries.each do |entry|
    next if entry.directory?
    entry.get_input_stream do |input_stream|
      if MANIFEST == entry.name
        manifest = input_stream.sysread.dup
      end
    end
  end
  manifest
end
process_entry(file_symbol, file_content, manifest) { |file_symbol, doc, man| ... } click to toggle source

process_entry: provide Nokogiri Object to caller, after having provided a file

# File lib/odf_writer/template.rb, line 204
def process_entry(file_symbol, file_content, manifest)

  # create xml from file content
  doc = to_xml(file_content ) # { |x| x.noblanks }
  man = to_xml(manifest     ) # { |x| x.noblanks }
  
  # yield xml
  yield file_symbol, doc, man
  
  # replace file_content and manifest in place
  # remove spurious whitespaces between tags ">  <" becomes "><"
  file_content.replace(doc.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML).squish.gsub(/(?<=>)\s+(?=<)/, ""))
  # Microsoft Words complains if no trailing newline is present
  manifest.replace(man.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML))
  
end
to_xml(raw_xml) click to toggle source

to_xml

# File lib/odf_writer/template.rb, line 197
def to_xml(raw_xml)
  Nokogiri::XML(raw_xml)
end