0

This is the XML function to create XML dynamically:

def make_toc
  builder = Nokogiri::XML::Builder.new do |xml|
    xml.ncx( xmlns: "http://www.daisy.org/z3986/2005/ncx/", version: "2005-1", "xml:lang"=>"eng"  ) do
      xml.head do
        xml.meta( content: book.uuid, name: "dtb:uid")
        xml.meta( content: "2", name: "dtb:depth")
        xml.meta( content: "0", name: "dtb:totalPageCount")
        xml.meta( content: "0", name: "dtb:maxPageNumber")
      end
      xml.docTitle do
        xml.text_ book.full_title
      end
      xml.navMap do
        i=0
        self.oeb_parts.each do |section|
          next if section.name.blank?
          i = i + 1
          xml.navPoint( id: section.uuid, playOrder: i.to_s) do
            xml.navLabel do
              xml.text_ section.name
            end
            xml.content(src: File.basename(section.file.path))
      unless self.toc_json.nil?
  toc = eval(self.toc_json)
  prev_list = 0
  value=''
  toc.each do |toc_node|
    if toc_node['part_id'].to_i == section.id.to_i
      j=0
      toc_node.each do |key, toc_part|
        if key != "part_id" && key != "position" && key != "part_name"
    value = ''
    j=i+1
    i=j
    n = toc_part['list'] - prev_list
    if n > 0
      n.times {
        value = value+"xml.navPoint( id: toc_part['id'], playOrder: j.to_s) do"
      }
    end
    m = prev_list - toc_part['list']
    if m > 0
      m.times {
        value = value+"end"
      }
    end
    value = value+"xml.navLabel do
      xml.text_ toc_part['value']
    end
    xml.content(src: File.basename(section.file.path)+'#'+toc_part['id'])"
    prev_list = toc_part['list']
                      "#{value}"
        end
      end
    end
  end
  m = prev_list - (-1)
  if m > 0
    m.times {
      value=value+"end"
    }
        end
      end
          end
        end
      end
    end
  end
  builder.to_xml
end

How to execute this?

if n > 0
  n.times {
    value = value+"xml.navPoint( id: toc_part['id'], playOrder: j.to_s) do"
  }
end

I want to run xml.navPoint( id: toc_part['id'], playOrder: j.to_s) do in the loop. If I call it directly without any interpolation, it throws an "unexpected end" error.

In the view file I can convert the string into HTML by using html_safe or raw. But in the model I don't know how to convert it.

Can anyone help me on this to solve it?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
user2138489
  • 77
  • 3
  • 10

1 Answers1

0

Okay I am going to try and make this as constructive as possible but please look into some ruby programming tutorials. There are quite a few syntax mistakes in this file and your implementation is very confusing as to what you are hoping to have in the end. There are also variables that I have no definition for that this question may be impossible to answer as it is. (e.g. book)

This Line is very wrong. It looks like you want to call a block at the end with the do but this will not be evaluated inside your string. Also value = value + is not the ruby way. try <<. Also {..} is for calling an inline block if you need a multiline block call it with do keyword.

n.times {value = value+"xml.navPoint( id: toc_part['id'], playOrder: j.to_s) do"}

n.times do |i|
   #i will contain the current iteration number as it loops through n
   value << xml.navPoint( id: toc_part['id'], playOrder: j.to_s) do
      #some other block here
   end 
end

This line has an unterminated string. It seems again you are trying to call a block inside a string and again value = value +

value = value+"xml.navLabel do
                  xml.text_ toc_part['value']
                end

Not sure what this line is for? Each loop will not return that value it will return the original object .each was called on.

"#{value}"

There are other issues as well but like I said it seems the real issue here is just limited understanding of ruby and it's syntax. Please do not take this as a negative comment as it is meant to be constructive, if you better understand the language you can better understand your issues.

engineersmnky
  • 25,495
  • 2
  • 36
  • 52