<commit_before>module Asciidoctor
# Public: Methods for parsing Asciidoc documents and rendering them
# using erb templates.
#
# There are several strategies for getting the title of the document:
#
# doctitle - value of title attribute, if assigned and non-empty,
#            otherwise title of first section in document, if present
#            otherwise nil
# name - an alias of doctitle
# title - value of the title attribute, or nil if not present
# first_section.title - title of first section in document, if present
# header.title - title of section level 0
#
# Keep in mind that you'll want to honor these document settings:
#
# notitle  - The h1 heading should not be shown
# noheader - The header block (h1 heading, author, revision info) should not be shown
class Document < AbstractBlock

  Footnote = Struct.new(:index, :id, :text)
  AttributeEntry = Struct.new(:name, :value, :negate) do
    def initialize(name, value, negate = nil)
      super(name, value, negate.nil? ? value.nil? : false)
    end

    def save_to(block_attributes)
      (block_attributes[:attribute_entries] ||= []) << self
    end

    #def save_to_next_block(document)
    #  (document.attributes[:pending_attribute_entries] ||= []) << self
    #end
  end

  # Public A read-only integer value indicating the level of security that
  # should be enforced while processing this document. The value must be
  # set in the Document constructor using the :safe option.
  #
  # A value of 0 (UNSAFE) disables any of the security features enforced
  # by Asciidoctor (Ruby is still subject to its own restrictions).
  #
  # A value of 1 (SAFE) closely parallels safe mode in AsciiDoc. In particular,
  # it prevents access to files which reside outside of the parent directory
  # of the source file and disables any macro other than the include macro.
  #
  # A value of 10 (SERVER) disallows the document from setting attributes that
  # would affect the rendering of the document, in addition to all the security
  # features of SafeMode::SAFE. For instance, this value disallows changing the
  # backend or the source-highlighter using an attribute defined in the source
  # document. This is the most fundamental level of security for server-side
  # deployments (hence the name).
  #
  # A value of 20 (SECURE) disallows the document from attempting to read files
  # from the file system and including the contents of them into the document,
  # in addition to all the security features of SafeMode::SECURE. In
  # particular, it disallows use of the include::[] macro and the embedding of
  # binary content (data uri), stylesheets and JavaScripts referenced by the
  # document. (Asciidoctor and trusted extensions may still be allowed to embed
  # trusted content into the document).
  #
  # Since Asciidoctor is aiming for wide adoption, 20 (SECURE) is the default
  # value and is recommended for server-side deployments.
  #
  # A value of 100 (PARANOID) is planned to disallow the use of passthrough
  # macros and prevents the document from setting any known attributes in
  # addition to all the security features of SafeMode::SECURE. Please note that
  # this level is not currently implemented (and therefore not enforced)!
  attr_reader :safe

  # Public: Get the Hash of document references
  attr_reader :references

  # Public: Get the Hash of document counters
  attr_reader :counters

  # Public: Get the Hash of callouts
  attr_reader :callouts

  # Public: The section level 0 block
  attr_reader :header

  # Public: Base directory for rendering this document. Defaults to directory of the source file.
  # If the source is a string, defaults to the current directory.
  attr_reader :base_dir

  # Public: A reference to the parent document of this nested document.
  attr_reader :parent_document

  # Public: The extensions registry
  attr_reader :extensions

  # Public: Initialize an Asciidoc object.
  #
  # data    - The Array of Strings holding the Asciidoc source document. (default: [])
  # options - A Hash of options to control processing, such as setting the safe mode (:safe),
  #           suppressing the header/footer (:header_footer) and attribute overrides (:attributes)
  #           (default: {})
  #
  # Examples
  #
  #   data = File.readlines(filename)
  #   doc  = Asciidoctor::Document.new(data)
  #   puts doc.render
  def initialize(data = [], options = {})
    super(self, :document)

    if options[:parent]
      @parent_document = options.delete(:parent)
      options[:base_dir] ||= @parent_document.base_dir
      # QUESTION should we support setting attribute in parent document from nested document?
      # NOTE we must dup or else all the assignments to the overrides clobbers the real attributes
      @attribute_overrides = @parent_document.attributes.dup
      @safe = @parent_document.safe
      @renderer = @parent_document.renderer
      initialize_extensions = false
      @extensions = @parent_document.extensions
    else
      @parent_document = nil
      # copy attributes map and normalize keys
      # attribute overrides are attributes that can only be set from the commandline
      # a direct assignment effectively makes the attribute a constant
      # a nil value or name with leading or trailing ! will result in the attribute being unassigned
      @attribute_overrides = (options[:attributes] || {}).inject({}) do |collector,(key,value)|
        if key.start_with?('!')
          key = key[1..-1]
          value = nil
        elsif key.end_with?('!')
          key = key[0..-2]
          value = nil
        end
        collector[key.downcase] = value
        collector
      end
      @safe = nil
      @renderer = nil
      initialize_extensions = Asciidoctor.const_defined?('Extensions')
      @extensions = nil # initialize furthur down
    end

    @header = nil
    @references = {
      :ids => {},
      :footnotes => [],
      :links => [],
      :images => [],
      :indexterms => [],
      :includes => Set.new,
    }
    @counters = {}
    @callouts = Callouts.new<commit_msg>resolves #636 ensure Extensions constant is Asciidoctor::Extensions<commit_after>module Asciidoctor
# Public: Methods for parsing Asciidoc documents and rendering them
# using erb templates.
#
# There are several strategies for getting the title of the document:
#
# doctitle - value of title attribute, if assigned and non-empty,
#            otherwise title of first section in document, if present
#            otherwise nil
# name - an alias of doctitle
# title - value of the title attribute, or nil if not present
# first_section.title - title of first section in document, if present
# header.title - title of section level 0
#
# Keep in mind that you'll want to honor these document settings:
#
# notitle  - The h1 heading should not be shown
# noheader - The header block (h1 heading, author, revision info) should not be shown
class Document < AbstractBlock

  Footnote = Struct.new(:index, :id, :text)
  AttributeEntry = Struct.new(:name, :value, :negate) do
    def initialize(name, value, negate = nil)
      super(name, value, negate.nil? ? value.nil? : false)
    end

    def save_to(block_attributes)
      (block_attributes[:attribute_entries] ||= []) << self
    end

    #def save_to_next_block(document)
    #  (document.attributes[:pending_attribute_entries] ||= []) << self
    #end
  end

  # Public A read-only integer value indicating the level of security that
  # should be enforced while processing this document. The value must be
  # set in the Document constructor using the :safe option.
  #
  # A value of 0 (UNSAFE) disables any of the security features enforced
  # by Asciidoctor (Ruby is still subject to its own restrictions).
  #
  # A value of 1 (SAFE) closely parallels safe mode in AsciiDoc. In particular,
  # it prevents access to files which reside outside of the parent directory
  # of the source file and disables any macro other than the include macro.
  #
  # A value of 10 (SERVER) disallows the document from setting attributes that
  # would affect the rendering of the document, in addition to all the security
  # features of SafeMode::SAFE. For instance, this value disallows changing the
  # backend or the source-highlighter using an attribute defined in the source
  # document. This is the most fundamental level of security for server-side
  # deployments (hence the name).
  #
  # A value of 20 (SECURE) disallows the document from attempting to read files
  # from the file system and including the contents of them into the document,
  # in addition to all the security features of SafeMode::SECURE. In
  # particular, it disallows use of the include::[] macro and the embedding of
  # binary content (data uri), stylesheets and JavaScripts referenced by the
  # document. (Asciidoctor and trusted extensions may still be allowed to embed
  # trusted content into the document).
  #
  # Since Asciidoctor is aiming for wide adoption, 20 (SECURE) is the default
  # value and is recommended for server-side deployments.
  #
  # A value of 100 (PARANOID) is planned to disallow the use of passthrough
  # macros and prevents the document from setting any known attributes in
  # addition to all the security features of SafeMode::SECURE. Please note that
  # this level is not currently implemented (and therefore not enforced)!
  attr_reader :safe

  # Public: Get the Hash of document references
  attr_reader :references

  # Public: Get the Hash of document counters
  attr_reader :counters

  # Public: Get the Hash of callouts
  attr_reader :callouts

  # Public: The section level 0 block
  attr_reader :header

  # Public: Base directory for rendering this document. Defaults to directory of the source file.
  # If the source is a string, defaults to the current directory.
  attr_reader :base_dir

  # Public: A reference to the parent document of this nested document.
  attr_reader :parent_document

  # Public: The extensions registry
  attr_reader :extensions

  # Public: Initialize an Asciidoc object.
  #
  # data    - The Array of Strings holding the Asciidoc source document. (default: [])
  # options - A Hash of options to control processing, such as setting the safe mode (:safe),
  #           suppressing the header/footer (:header_footer) and attribute overrides (:attributes)
  #           (default: {})
  #
  # Examples
  #
  #   data = File.readlines(filename)
  #   doc  = Asciidoctor::Document.new(data)
  #   puts doc.render
  def initialize(data = [], options = {})
    super(self, :document)

    if options[:parent]
      @parent_document = options.delete(:parent)
      options[:base_dir] ||= @parent_document.base_dir
      # QUESTION should we support setting attribute in parent document from nested document?
      # NOTE we must dup or else all the assignments to the overrides clobbers the real attributes
      @attribute_overrides = @parent_document.attributes.dup
      @safe = @parent_document.safe
      @renderer = @parent_document.renderer
      initialize_extensions = false
      @extensions = @parent_document.extensions
    else
      @parent_document = nil
      # copy attributes map and normalize keys
      # attribute overrides are attributes that can only be set from the commandline
      # a direct assignment effectively makes the attribute a constant
      # a nil value or name with leading or trailing ! will result in the attribute being unassigned
      @attribute_overrides = (options[:attributes] || {}).inject({}) do |collector,(key,value)|
        if key.start_with?('!')
          key = key[1..-1]
          value = nil
        elsif key.end_with?('!')
          key = key[0..-2]
          value = nil
        end
        collector[key.downcase] = value
        collector
      end
      @safe = nil
      @renderer = nil
      initialize_extensions = Asciidoctor.const_defined?(:Extensions) &&
          Asciidoctor.const_get(:Extensions) == Asciidoctor::Extensions
      @extensions = nil # initialize furthur down
    end

    @header = nil
    @references = {
      :ids => {},
      :footnotes => [],
      :links => [],
      :images => [],
      :indexterms => [],
      :includes => Set.new,
    }
    @counters = {}
    @callouts = Callouts.new
{'fraction_non_alphanumeric': 0.07496325330720235, 'fraction_numerical': 0.0033480320104523928, 'mean_word_length': 3.2732030704815074, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, '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': '5080243', 'n_tokens_mistral': 3336, 'n_tokens_neox': 3231, 'n_words': 1413}