module Enolib

TODO: For each value store the representational type as well ? (e.g. string may come from “- foo” or – foonxxxn– foo) and use that for precise error messages?

TODO: Try out possesive quantifiers (careful x{2,}+ does not work in ruby, only xx++ (!)) - benchmark?

GENERATED ON 2019-06-18T08:50:41 - DO NOT EDIT MANUALLY

GENERATED ON 2019-06-18T08:50:41 - DO NOT EDIT MANUALLY

GENERATED ON 2019-06-18T08:50:41 - DO NOT EDIT MANUALLY

Constants

HUMAN_INDEXING
PRETTY_TYPES

Public Class Methods

lookup(input, column: nil, index: nil, line: nil, **options) click to toggle source
# File lib/enolib/lookup.rb, line 250
def self.lookup(input, column: nil, index: nil, line: nil, **options)
  context = Context.new(input, **options)

  match = nil
  if index
    if index < 0 || index > context.input.length
      raise IndexError, "You are trying to look up an index (#{index}) outside of the document's index range (0-#{context.input.length})"
    end

    match = check_in_section_by_index(context.document, index)
  else
    if line < 0 || line >= context.line_count
      raise IndexError, "You are trying to look up a line (#{line}) outside of the document's line range (0-#{context.line_count - 1})"
    end

    match = check_in_section_by_line(context.document, line)
  end

  result = {
    element: Element.new(context, match[:element]),
    range: nil
  }

  instruction = match[:instruction]

  unless instruction
    if index
      instruction = context.meta.find do |candidate|
        index >= candidate[:ranges][:line][RANGE_BEGIN] && index <= candidate[:ranges][:line][RANGE_END]
      end
    else
      instruction = context.meta.find { |candidate| candidate[:line] == line }
    end

    return result unless instruction
  end

  rightmost_match = instruction[:ranges][:line][0]

  unless index
    index = instruction[:ranges][:line][0] + column
  end

  instruction[:ranges].each do |type, range|
    next if type == :line

    if index >= range[RANGE_BEGIN] && index <= range[RANGE_END] && range[RANGE_BEGIN] >= rightmost_match
      result[:range] = type
      # TODO: Provide content of range too as convenience
      rightmost_match = index
    end
  end

  result
end
parse(input, **options) click to toggle source
# File lib/enolib/parse.rb, line 4
def self.parse(input, **options)
  context = Context.new(input, **options)

  Section.new(context, context.document)
end
register(definitions) click to toggle source
# File lib/enolib/register.rb, line 4
def self.register(definitions)
  definitions.each do |name, loader|
    if name == :string
      raise ArgumentError, "You cannot register 'string' as a type/loader with enolib as this conflicts with the native string type accessors."
    end

    ElementBase.send(:define_method, "#{name}_key") { key(loader) }
    ElementBase.send(:define_method, "optional_#{name}_comment") { optional_comment(loader) }
    ElementBase.send(:define_method, "required_#{name}_comment") { required_comment(loader) }
    ValueElementBase.send(:define_method, "optional_#{name}_value") { optional_value(loader) }
    ValueElementBase.send(:define_method, "required_#{name}_value") { required_value(loader) }
    List.send(:define_method, "optional_#{name}_values") { optional_values(loader) }
    List.send(:define_method, "required_#{name}_values") { required_values(loader) }
    MissingElementBase.send(:alias_method, "#{name}_key", :string_key)
    MissingElementBase.send(:alias_method, "optional_#{name}_comment", :optional_string_comment)
    MissingElementBase.send(:alias_method, "required_#{name}_comment", :required_string_comment)
    MissingValueElementBase.send(:alias_method, "optional_#{name}_value", :optional_string_value)
    MissingValueElementBase.send(:alias_method, "required_#{name}_value", :required_string_value)
    MissingList.send(:alias_method, "optional_#{name}_values", :optional_string_values)
    MissingList.send(:alias_method, "required_#{name}_values", :required_string_values)
  end
end