Commit 9cfb8d0d authored by Miguel Angel Reina Ortega's avatar Miguel Angel Reina Ortega
Browse files

Enhancement of handling content, including lists in cells

parent b621572f
Loading
Loading
Loading
Loading
+34 −34
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ module Banzai
      GRID_TABLE_BODY_SEPARATOR = /[^\n]*\+([:-]+\+)+[^\n]*$/
      GRID_TABLE_BODY_SEPARATOR_LINE = /^[-:]+$/

      NEXT_ELEMENT_LIST_MARK = "∆"
        
      class Cell
          attr_accessor :content, :rowspan, :colspan, :colspan_adjusted, :alignment, :position_start, :position, :list_flag

@@ -113,34 +115,40 @@ module Banzai
      end
      # Helper method to handle content in cells
      def handling_content(cell, content)
        _c = content.strip
        if cell.content.nil?
          cell.rowspan += 1
          cell.colspan += 1
          if content.strip.start_with?("- ") # List
          if _c.start_with?("- ") # List
            cell.list_flag = true
            cell.content = "#{content.strip}\n"
            _c = _c.gsub(/\\\s*$/, '\n')
				    cell.content = "#{_c}#{NEXT_ELEMENT_LIST_MARK}"  # Add list element end mark to know when the list element ends
          elsif cell.list_flag && !content.strip.empty?
            cell.content += "#{content.strip}\n"
          elsif content.strip == ""
            cell.list_flag = false
            _c = _c.gsub(/\\\s*$/, '\n')
            cell.content = "#{_c}#{NEXT_ELEMENT_LIST_MARK}" #add the list element end mark
          elsif _c.empty?
            cell.content = "\n"
          else
            cell.content = content.strip.gsub(/\\\s*$/, "\n")
            cell.content = _c.gsub(/\\\s*$/, "\n")
          end
        elsif content.strip.start_with?("- ")
        elsif _c.start_with?("- ")
          cell.content += "\n" unless cell.list_flag

          cell.list_flag = true
          cell.content += "#{content.strip}\n"
        elsif cell.list_flag && !content.strip.empty?
          cell.content = cell.content.strip.chomp("\n")
          cell.content += " #{content.strip}\n"
        elsif content.strip.empty?
          _c = _c.gsub(/\\\s*$/, '\n')
          cell.content += "#{_c}#{NEXT_ELEMENT_LIST_MARK}"
        elsif cell.list_flag && !_c.empty?
          cell.content = cell.content.strip.chomp("#{NEXT_ELEMENT_LIST_MARK}")
          _c = _c.gsub(/\\\s*$/, '\n')
          cell.content += " #{_c}#{NEXT_ELEMENT_LIST_MARK}"
        elsif _c.empty?
          if cell.list_flag
            cell.list_flag = false
            cell.content += "\n\n"
          end
          cell.content += cell.content.end_with?("\n") ? "" : "\n"
        else
          content = content.strip.gsub(/\\\s*$/, "\n")
          cell.content += " #{content}"
          _c = _c.gsub(/\\\s*$/, "\n")
          cell.content += " #{_c}"
        end

        cell
@@ -188,7 +196,7 @@ module Banzai
      def parse_pandoc_table_with_spans(pandoc_table)

        # Split the input into lines
        lines = pandoc_table.strip.split("\n").map(&:strip)
        lines = pandoc_table.rstrip.split("\n").map(&:rstrip)
        
        # Retrieve separator indices
        separator_indices = lines.each_index.select { |i| separator?(lines[i]) }
@@ -272,6 +280,7 @@ module Banzai
          next if row_lines.empty?

          row_lines.each do |line|
            line = line.rstrip
            # First line (normally a separator) of each block
            if separator?(line) && !in_data_row
              in_data_row = true
@@ -409,20 +418,11 @@ module Banzai
            row.each do |cell|
              next if cell.content.nil?

              delimters = ['**', '__']
              delimters.each do |bold_chars|
                while cell.content.include?(bold_chars)
                  cell.content = cell.content.sub(bold_chars, "<strong>")
                                          .sub(bold_chars, "</strong>")
                end
              end
              cell.content = cell.content.gsub(/</, "&lt;")

              while cell.content.include?("_") && cell.content.exclude?("\\_")
                cell.content = cell.content.rstrip.sub("_", "<i>").sub("_", "</i>")
              end

              cell.content = cell.content.rstrip.sub("\\_", "_") while cell.content.include?("\\_")
              cell.content = cell.content.gsub(/(?<espace>^|\s)(?<bold>\*\*|__)(?<text>.+?)\g<bold>(?!\w)/, "\\k<espace><strong>\\k<text></strong>")

              cell.content = cell.content.gsub(/(?<espace>^|\s)(?<italic>\*|_)(?<text>.+?)\g<italic>(?!\w)/, "\\k<espace><i>\\k<text></i>")
              # Convert newlines to HTML breaks
              cell.content = cell.content&.gsub("\n", "<br />")
            end
@@ -483,14 +483,14 @@ module Banzai
                next if cell.rowspan == 0 || cell.colspan == 0

                # Prepare content, in case there's a list
                matches = cell.content&.scan(%r{\s*([-*+]|\d+\.)\s+([^<]+?)(?=<br />|$)})
                matches = cell.content&.scan(/\s*([-*+]|\d+\.)\s+([^#{NEXT_ELEMENT_LIST_MARK}]+?)#{NEXT_ELEMENT_LIST_MARK}\n?/)
                if matches
                  list = "<ul>"
                  matches.each do |match|
                    list += "<li>#{match[1]}</li>"
                  end
                  list += "</ul>"
                  cell.content = cell.content.gsub(%r{(\s*([-*+]|\d+\.)\s+[^<]+?<br />)+}, list)
                  cell.content = cell.content.gsub(/(\s*([-*+]|\d+\.)\s+([^#{NEXT_ELEMENT_LIST_MARK}]+#{NEXT_ELEMENT_LIST_MARK}\n?))+/, list)
                  # Enforce left alignment if cell contains a list
                  cell.alignment = 'align="left"'
                end
@@ -510,14 +510,14 @@ module Banzai
            row.each do |cell|
              next if cell.rowspan == 0 || cell.colspan == 0

              matches = cell.content&.scan(%r{\s*([-*+]|\d+\.)\s+([^<]+?)(?=<br />|$)})
              matches = cell.content&.scan(/\s*([-*+]|\d+\.)\s+([^#{NEXT_ELEMENT_LIST_MARK}]+?)#{NEXT_ELEMENT_LIST_MARK}\n?/)
              if matches
                list = "<ul>"
                matches.each do |match|
                  list += "<li>#{match[1]}</li>"
                end
                list += "</ul>"
                cell.content = cell.content.gsub(%r{(\s*([-*+]|\d+\.)\s+[^<]+?<br />)+}, list)
                puts "List:  #{list}"
                cell.content = cell.content.gsub(/(\s*([-*+]|\d+\.)\s+([^#{NEXT_ELEMENT_LIST_MARK}]+#{NEXT_ELEMENT_LIST_MARK}\n?))+/, list)
                # Enforce left alignment if cell contains a list
                cell.alignment = 'align="left"'
              end