template_parser.rb 3.99 KB
require 'nokogiri'
require 'json'

module Kanjai
  class TemplateParser
    def initialize(html_source)
        @html_source = html_source
    end


    def get_elements(elements)
      mas = []


      elements.each do |item|
        new_item = item.dup
        new_item.delete(:children)
        mas << new_item if need_elements.include?(new_item[:name])

        mas = mas + get_need_elements(item[:children], need_elements)
      end

      mas
    end

    def find_subparts
      result = []
      p '!!!!!!!'
      @html_source.scan(/<!--###START element[\w\W]+?-->/).each do |item|
        p '!!!!!!!!!!!!!!'

        name, type, code = item.scan(/<!--###START\s+element\(name="([^"]+)",\s+type="([\w\s]+)"\)\s+###/)[0]

        if name.present? and type.present?

          source = item.gsub(/<!--###START\s+element\(name="([^"]+)",\s+type="([\w\s]+)"\)\s+###/, '')
          source = source.gsub('-->', '')
          source = source.gsub("\n", '')
          source = source.gsub("\r", '')

          source_dom = Nokogiri::HTML::fragment(source)

          @field_options = []
          elements = html_to_hash(source_dom)



          #field_options = elements.select {|item| (item[:name] == 'element' or item[:name] == 'repeat'  ) }
          #field_options = get_elements(elements)
          #elements.delete_if {|item| item[:name] == 'element' }



          result << {
              name: name,
              type: type,
              code: name.parameterize,
              source: source,
              elements: elements,
              field_options: @field_options
          }
        end
      end


      result
    end


    def find_static_elements
      result = []
      @html_source.scan(/{"static":[\w\W\{]+?}}/).each do |str|
        element_hash = JSON.parse(str)
        result << {:name => element_hash["static"]["title"], :itemName => element_hash["static"]["itemName"] , :type => element_hash["static"]["type"], :source => str}
      end
      result
    end

    def without_subparts
      @html_source.gsub!(/<!--###START element[\w\W]+?-->/, '')
      static_elements = self.find_static_elements
      static_elements.each do |item|
        @html_source.gsub!(item[:source], item[:name])
      end
      return @html_source
    end



    private

    def html_to_hash(root)
      mas = []

      root.children.each do |item|
        children = html_to_hash(item)
        attr = {}
        item.attributes.each do |key, value|
          attr[key] = value.value
        end

        if item.name == 'repeat'
          @field_options << {:name => item.name, :itemName => nil, :attributes => attr, :source => nil, :children => {}}
        end

        if item.name == "text"
          source = item.text
        else
          source = nil
        end

        repeat = "false"
        test = item
        while test
          if test.name == 'repeat'
            repeat = "true"
          end
          test = test.parent
        end


        source.to_s.scan(/{"element":[\w\W\{]+?}}/).each do |str|
          element_hash = JSON.parse(str)
          @field_options << {:name => element_hash["element"]["title"], :itemName => element_hash["element"]["itemName"] , main: element_hash["element"]["main"].to_i, :attributes => {'type' => element_hash["element"]["type"], 'repeat' => repeat}, :source => nil, :children => {}}
          source.gsub!(str, element_hash["element"]["title"])
        end

        attr.each do |key, value|
          value.to_s.scan(/{"element":[\w\W\{]+?}}/).each do |str|

            element_hash = JSON.parse(str)
            @field_options << {:name => element_hash["element"]["title"], :itemName => element_hash["element"]["itemName"] , main: element_hash["element"]["main"].to_i, :attributes => {'type' => element_hash["element"]["type"], 'repeat' => repeat}, :source => nil, :children => {}}
            value.gsub!(str, element_hash["element"]["title"])
          end
        end

        mas << {:name => item.name, :attributes => attr, :source => source, :children => children}
      end


      mas
    end

  end
end