<commit_before># frozen_string_literal: true

module Jekyll
  module Tags
    class IncludeTag < Liquid::Tag
      VALID_SYNTAX = %r!
        ([\w-]+)\s*=\s*
        (?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))
      !x.freeze
      VARIABLE_SYNTAX = %r!
        (?<variable>[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+)
        (?<params>.*)
      !mx.freeze

      FULL_VALID_SYNTAX = %r!\A\s*(?:#{VALID_SYNTAX}(?=\s|\z)\s*)*\z!.freeze
      VALID_FILENAME_CHARS = %r!^[\w/\.-]+$!.freeze
      INVALID_SEQUENCES = %r![./]{2,}!.freeze

      def initialize(tag_name, markup, tokens)
        super
        matched = markup.strip.match(VARIABLE_SYNTAX)
        if matched
          @file = matched["variable"].strip
          @params = matched["params"].strip
        else
          @file, @params = markup.strip.split(%r!\s+!, 2)
        end
        validate_params if @params
        @tag_name = tag_name
      end

      def syntax_example
        "{% #{@tag_name} file.ext param='value' param2='value' %}"
      end

      def parse_params(context)
        params = {}
        markup = @params

        while (match = VALID_SYNTAX.match(markup))
          markup = markup[match.end(0)..-1]

          value = if match[2]
                    match[2].gsub('\\"', '"')
                  elsif match[3]
                    match[3].gsub("\\'", "'")
                  elsif match[4]
                    context[match[4]]
                  end

          params[match[1]] = value
        end
        params
      end

      def validate_file_name(file)
        if file =~ INVALID_SEQUENCES || file !~ VALID_FILENAME_CHARS
          raise ArgumentError, <<~MSG
            Invalid syntax for include tag. File contains invalid characters or sequences:

              #{file}

            Valid syntax:

              #{syntax_example}

          MSG
        end
      end

      def validate_params
        unless FULL_VALID_SYNTAX.match?(@params)
          raise ArgumentError, <<~MSG
            Invalid syntax for include tag:

            #{@params}

            Valid syntax:

            #{syntax_example}

          MSG
        end
      end

      # Grab file read opts in the context
      def file_read_opts(context)
        context.registers[:site].file_read_opts
      end

      # Render the variable if required
      def render_variable(context)
        Liquid::Template.parse(@file).render(context) if @file =~ VARIABLE_SYNTAX
      end

      def tag_includes_dirs(context)
        context.registers[:site].includes_load_paths.freeze
      end

      def locate_include_file(context, file, safe)
        includes_dirs = tag_includes_dirs(context)<commit_msg>Replace `String#=~` with `String#match?` (#7718)<commit_after># frozen_string_literal: true

module Jekyll
  module Tags
    class IncludeTag < Liquid::Tag
      VALID_SYNTAX = %r!
        ([\w-]+)\s*=\s*
        (?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))
      !x.freeze
      VARIABLE_SYNTAX = %r!
        (?<variable>[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+)
        (?<params>.*)
      !mx.freeze

      FULL_VALID_SYNTAX = %r!\A\s*(?:#{VALID_SYNTAX}(?=\s|\z)\s*)*\z!.freeze
      VALID_FILENAME_CHARS = %r!^[\w/\.-]+$!.freeze
      INVALID_SEQUENCES = %r![./]{2,}!.freeze

      def initialize(tag_name, markup, tokens)
        super
        matched = markup.strip.match(VARIABLE_SYNTAX)
        if matched
          @file = matched["variable"].strip
          @params = matched["params"].strip
        else
          @file, @params = markup.strip.split(%r!\s+!, 2)
        end
        validate_params if @params
        @tag_name = tag_name
      end

      def syntax_example
        "{% #{@tag_name} file.ext param='value' param2='value' %}"
      end

      def parse_params(context)
        params = {}
        markup = @params

        while (match = VALID_SYNTAX.match(markup))
          markup = markup[match.end(0)..-1]

          value = if match[2]
                    match[2].gsub('\\"', '"')
                  elsif match[3]
                    match[3].gsub("\\'", "'")
                  elsif match[4]
                    context[match[4]]
                  end

          params[match[1]] = value
        end
        params
      end

      def validate_file_name(file)
        if file.match?(INVALID_SEQUENCES) || !file.match?(VALID_FILENAME_CHARS)
          raise ArgumentError, <<~MSG
            Invalid syntax for include tag. File contains invalid characters or sequences:

              #{file}

            Valid syntax:

              #{syntax_example}

          MSG
        end
      end

      def validate_params
        unless FULL_VALID_SYNTAX.match?(@params)
          raise ArgumentError, <<~MSG
            Invalid syntax for include tag:

            #{@params}

            Valid syntax:

            #{syntax_example}

          MSG
        end
      end

      # Grab file read opts in the context
      def file_read_opts(context)
        context.registers[:site].file_read_opts
      end

      # Render the variable if required
      def render_variable(context)
        Liquid::Template.parse(@file).render(context) if @file.match?(VARIABLE_SYNTAX)
      end

      def tag_includes_dirs(context)
        context.registers[:site].includes_load_paths.freeze
      end

      def locate_include_file(context, file, safe)
        includes_dirs = tag_includes_dirs(context)
{'fraction_non_alphanumeric': 0.15182669359280337, 'fraction_numerical': 0.005140444281255737, 'mean_word_length': 1.7967145790554415, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 7, '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': '4481391', 'n_tokens_mistral': 1816, 'n_tokens_neox': 1685, 'n_words': 328}