learningtapestry/lcms-engine

View on GitHub
lib/doc_template/tables/target.rb

Summary

Maintainability
A
0 mins
Test Coverage
F
27%
# frozen_string_literal: true

module DocTemplate
  module Tables
    class Target < Base
      HEADER_LABEL_PIECE = 'Long-Term Targets Addressed'
      TEMPLATE = 'target-table.html.erb'

      def parse(fragment, *_args)
        path = ".//table/*/tr[1]/td[1][case_insensitive_contains(.//*/text(), '#{HEADER_LABEL_PIECE}')]"
        return unless (element = fragment.at_xpath path, XpathFunctions.new)
        return unless (table = element.ancestors('table').first)

        @target_data = fetch table

        template = File.read DocTemplate::Tags::BaseTag.template_path_for(TEMPLATE)
        content = ERB.new(template).result(binding).squish
        content = DocTemplate::Document.parse Nokogiri::HTML.fragment(content)

        # remove next element if it's empty paragraph
        # (quick fix before refactoring at https://github.com/learningtapestry/unbounded/issues/780)
        el_next = table.next_element
        el_next.remove if el_next&.name == 'p' && el_next.content.blank?

        table.replace content&.render
        content
      end

      private

      def fetch(table)
        data = {}.tap do |result|
          # Need to handle every `p` and `ul` elements
          result[:long_term_title] = table.xpath('*//tr[1]/td').map(&:content).join(' ')
          result[:long_term] = table.xpath('*//tr[2]/td/p').map(&:content).join('; ')
          result[:long_term] += table.xpath('*//tr[3]/td/ul/li').map(&:content).join('; ')

          result[:short_term] = table.xpath('*//tr[4]/td[1]/p').map(&:content).join('; ')
          result[:short_term] += table.xpath('*//tr[4]/td[1]/ul/li').map(&:content).join('; ')

          result[:assessment] = table.xpath('*//tr[4]/td[2]/p').map(&:content).join('; ')
          result[:assessment] += table.xpath('*//tr[4]/td[2]/ul/li').map(&:content).join('; ')
        end

        # Wraps all tags into spans to keep consistence with the parser
        data.each_key { |key| data[key] = data[key].gsub('[', '<span>[').gsub(']', ']</span>') }
        data
      end
    end
  end
end