<commit_before># -*- encoding: utf-8 -*-

require 'cgi'


module Facwparser
  module Element
    class ElementBase
      attr_reader :source, :children
      def initialize(source)
        @source   = source
        @children = nil
      end
      def ==(other)
        self.class == other.class && self.source == other.source
      end

      def render_html(options)
        raise "TODO: render_html is not implemented: " + self.class.to_s + "\n"
      end
    end

    class P < ElementBase
      def append(source)
        @source += source
      end
      def render_html(options)
        @children ||= Parser.parse_value(source, options)
        "<p>\n" + @children.map { |c| c.render_html(options) }.join("\n")  + "<p>\n"
      end
    end
    class HorizontalRule < ElementBase
      def render_html(options)
        "<hr>\n"
      end
    end
    class Heading < ElementBase
      attr_reader :level, :value
      def initialize(source, level, value)
        super(source)
        @level = level
        @value = value
      end
      def render_html(options)
        "<h#{level}>#{CGI.escapeHTML value}</h#{level}>\n"
      end
    end
    class List < ElementBase
      attr_reader :type
      def initialize(type)
        super('')
        @type = type
      end
      def push(item)
        @children ||= []
        @children.push(item)
        self
      end
      def render_html(options)
        case @type
        when '#'
          return "<ol>\n" + @children.map{ |c| c.render_html(options) }.join(" ") + "</ol>\n"
        else
          return "<ul>\n" + @children.map{ |c| c.render_html(options) }.join(" ") + "</ul>\n"
        end
      end
    end
    class ListItem < ElementBase
      attr_reader :symbols, :level, :value
      def initialize(source, symbols, value)
        super(source)
        @symbols = symbols
        @level   = symbols.size
        @value = value
      end
      def render_html(options)
        @children = Parser.parse_value value, options
        "<li>" + @children.map {|c| c.render_html(options) }.join(" ") + "</li>\n"
      end
    end
    class Table < ElementBase
      def initialize()
        super('')
      end
      def push(item)
        @children ||= []
        @children.push(item)
        self
      end
      def render_html(options)
        "<table><thead>\n" + @children[0].render_html(options) +
        "\n</thead>\n<tbody>\n" +
        @children.drop(1).map{|c| c.render_html(options)}.join("\n") +
        "\n</tbody></table>\n"
      end
    end
    class TableHeaders < ElementBase
      attr_reader :elements
      def initialize(source)
        super(source)
        @elements = source.split('||')[1..-2]
      end
      def render_html(options)
        "<tr>" +
          @elements.map { |e| '<th>' + CGI.escapeHTML(e.strip) + '</th>'}.join() +
        "</tr>"
      end
    end
    class TableData < ElementBase
      attr_reader :elements
      def initialize(source)
        super(source)
        @elements = source.split('|')[1..-2]
      end
      def render_html(options)
        "<tr>" +
          @elements.map { |e| '<td>' + CGI.escapeHTML(e.strip) + '</td>'}.join() +
        "</tr>"
      end
    end

    class MacroBase < ElementBase
    end
    class TocMacro < MacroBase
      def initialize(source, options = nil)
        super(source)
        @options = options
      end
      def render_html(options)
        "TODO: table of contents Macro\n"
      end
    end
    class PagetreeMacro < MacroBase
      def initialize(source, options = nil)
        super(source)
        @options = options
      end
      def render_html(options)
        "TODO: pagetree macro\n"
      end
    end
    class NoformatMacro < MacroBase
      def initialize(source, value)
        super(source)
        @value = value
      end
      def render_html(options)
        "<pre>\n#{CGI.escapeHTML @value}\n</pre>\n"
      end
    end
    class CodeMacro < MacroBase
      def initialize(source, options, value)
        super(source)
        @options = options
        @value = value
      end
      def render_html(options)
        "<code class=\"code_#{CGI.escapeHTML(@options[1..-1])}\"><pre>\n#{CGI.escapeHTML @value}\n</pre></code>\n"
      end
    end

    class InlineElementBase < ElementBase
      attr_reader :text
      def initialize(source, text)
        super(source)
        @text = text
      end
      def ==(other)
        super(other) && self.text == other.text
      end
    end

    class A < InlineElementBase
      def render_html(options)
        if @text =~ /\A(.+)\|((?:https?|ftp|file):.+)\z/
          return '<a href="' + CGI.escapeHTML($2) +'">' + CGI.escapeHTML($1) + '</a>'
        elsif @text =~ /\A(?:https?|ftp|file):.+\z/
          return '<a href="' + CGI.escapeHTML(@text) +'">' + CGI.escapeHTML(@text) + '</a>'
        else
          return '[' + CGI.escapeHTML(@text) + ']'
        end
      end
    end

    class Bold < InlineElementBase
      def render_html(options)
        "<em>#{CGI.escapeHTML(@text)}</em>"
      end
    end

    class Italic < InlineElementBase
      def render_html(options)
        "<i>#{CGI.escapeHTML(@text)}</i>"
      end
    end

    class Strike < InlineElementBase<commit_msg>parse links in table data.<commit_after># -*- encoding: utf-8 -*-

require 'cgi'


module Facwparser
  module Element
    class ElementBase
      attr_reader :source, :children
      def initialize(source)
        @source   = source
        @children = nil
      end
      def ==(other)
        self.class == other.class && self.source == other.source
      end

      def render_html(options)
        raise "TODO: render_html is not implemented: " + self.class.to_s + "\n"
      end
    end

    class P < ElementBase
      def append(source)
        @source += source
      end
      def render_html(options)
        @children ||= Parser.parse_value(source, options)
        "<p>\n" + @children.map { |c| c.render_html(options) }.join("\n")  + "<p>\n"
      end
    end
    class HorizontalRule < ElementBase
      def render_html(options)
        "<hr>\n"
      end
    end
    class Heading < ElementBase
      attr_reader :level, :value
      def initialize(source, level, value)
        super(source)
        @level = level
        @value = value
      end
      def render_html(options)
        "<h#{level}>#{CGI.escapeHTML value}</h#{level}>\n"
      end
    end
    class List < ElementBase
      attr_reader :type
      def initialize(type)
        super('')
        @type = type
      end
      def push(item)
        @children ||= []
        @children.push(item)
        self
      end
      def render_html(options)
        case @type
        when '#'
          return "<ol>\n" + @children.map{ |c| c.render_html(options) }.join(" ") + "</ol>\n"
        else
          return "<ul>\n" + @children.map{ |c| c.render_html(options) }.join(" ") + "</ul>\n"
        end
      end
    end
    class ListItem < ElementBase
      attr_reader :symbols, :level, :value
      def initialize(source, symbols, value)
        super(source)
        @symbols = symbols
        @level   = symbols.size
        @value = value
      end
      def render_html(options)
        @children = Parser.parse_value value, options
        "<li>" + @children.map {|c| c.render_html(options) }.join(" ") + "</li>\n"
      end
    end
    class Table < ElementBase
      def initialize()
        super('')
      end
      def push(item)
        @children ||= []
        @children.push(item)
        self
      end
      def render_html(options)
        "<table><thead>\n" + @children[0].render_html(options) +
        "\n</thead>\n<tbody>\n" +
        @children.drop(1).map{|c| c.render_html(options)}.join("\n") +
        "\n</tbody></table>\n"
      end
    end
    class TableHeaders < ElementBase
      attr_reader :elements
      def initialize(source)
        super(source)
        @elements = source.split('||')[1..-2]
      end
      def render_html(options)
        "<tr>" +
          @elements.map { |e| '<th>' + Parser.parse_value(e, options).map { |c| c.render_html(options) }.join(" ") + '</th>'}.join() +
        "</tr>"
      end
    end
    class TableData < ElementBase
      attr_reader :elements
      def initialize(source)
        super(source)
        @elements = []
        element = ''
        s = StringScanner.new(source[1..-2])
        in_link = false
        while s.rest?
          case
          when s.scan(/[^|\[\]]+/) || s.scan(/\\\[/) || s.scan(/\\\]/) || s.scan(/\\\|/)
            element += s[0]
          when s.scan(/\[/)
            in_link = true
            element += s[0]
          when s.scan(/\]/)
            in_link = false
            element += s[0]
          when s.scan(/\|/)
            if in_link
              element += s[0]
            else
              @elements << element
              element = ''
            end
          else
            element += s.rest
            break
          end
        end
        @elements << element if !element.empty?
      end
      def render_html(options)
        "<tr>" +
          @elements.map { |e| '<td>' + Parser.parse_value(e, options).map { |c| c.render_html(options) }.join(" ") + '</td>'}.join() +
        "</tr>"
      end
    end

    class MacroBase < ElementBase
    end
    class TocMacro < MacroBase
      def initialize(source, options = nil)
        super(source)
        @options = options
      end
      def render_html(options)
        "TODO: table of contents Macro\n"
      end
    end
    class PagetreeMacro < MacroBase
      def initialize(source, options = nil)
        super(source)
        @options = options
      end
      def render_html(options)
        "TODO: pagetree macro\n"
      end
    end
    class NoformatMacro < MacroBase
      def initialize(source, value)
        super(source)
        @value = value
      end
      def render_html(options)
        "<pre>\n#{CGI.escapeHTML @value}\n</pre>\n"
      end
    end
    class CodeMacro < MacroBase
      def initialize(source, options, value)
        super(source)
        @options = options
        @value = value
      end
      def render_html(options)
        "<code class=\"code_#{CGI.escapeHTML(@options[1..-1])}\"><pre>\n#{CGI.escapeHTML @value}\n</pre></code>\n"
      end
    end

    class InlineElementBase < ElementBase
      attr_reader :text
      def initialize(source, text)
        super(source)
        @text = text
      end
      def ==(other)
        super(other) && self.text == other.text
      end
    end

    class A < InlineElementBase
      def render_html(options)
        if @text =~ /\A(.+)\|((?:https?|ftp|file):.+)\z/
          return '<a href="' + CGI.escapeHTML($2) +'">' + CGI.escapeHTML($1) + '</a>'
        elsif @text =~ /\A(?:https?|ftp|file):.+\z/
          return '<a href="' + CGI.escapeHTML(@text) +'">' + CGI.escapeHTML(@text) + '</a>'
        else
          return '[' + CGI.escapeHTML(@text) + ']'
        end
      end
    end

    class Bold < InlineElementBase
      def render_html(options)
        "<b>#{CGI.escapeHTML(@text)}</b>"
      end
    end

    class Italic < InlineElementBase
      def render_html(options)
        "<i>#{CGI.escapeHTML(@text)}</i>"
      end
    end

    class Strike < InlineElementBase
{'fraction_non_alphanumeric': 0.1411451398135819, 'fraction_numerical': 0.00230803373280071, 'mean_word_length': 1.8320764203117144, 'pattern_counts': {'":': 0, '<': 121, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4006586', 'n_tokens_mistral': 3547, 'n_tokens_neox': 3524, 'n_words': 810}