Module: Enolib

Defined in:
lib/enolib/locales/de.rb,
lib/enolib/parse.rb,
lib/enolib/errors.rb,
lib/enolib/lookup.rb,
lib/enolib/parser.rb,
lib/enolib/context.rb,
lib/enolib/register.rb,
lib/enolib/constants.rb,
lib/enolib/locales/en.rb,
lib/enolib/locales/es.rb,
lib/enolib/elements/list.rb,
lib/enolib/elements/empty.rb,
lib/enolib/elements/field.rb,
lib/enolib/errors/parsing.rb,
lib/enolib/grammar_regexp.rb,
lib/enolib/elements/element.rb,
lib/enolib/elements/section.rb,
lib/enolib/elements/fieldset.rb,
lib/enolib/errors/selections.rb,
lib/enolib/errors/validation.rb,
lib/enolib/elements/list_item.rb,
lib/enolib/reporters/reporter.rb,
lib/enolib/elements/element_base.rb,
lib/enolib/elements/fieldset_entry.rb,
lib/enolib/reporters/html_reporter.rb,
lib/enolib/reporters/text_reporter.rb,
lib/enolib/elements/section_element.rb,
lib/enolib/elements/value_element_base.rb,
lib/enolib/reporters/terminal_reporter.rb,
lib/enolib/elements/missing/missing_list.rb,
lib/enolib/elements/missing/missing_empty.rb,
lib/enolib/elements/missing/missing_field.rb,
lib/enolib/elements/missing/missing_section.rb,
lib/enolib/elements/missing/missing_fieldset.rb,
lib/enolib/elements/missing/missing_element_base.rb,
lib/enolib/elements/missing/missing_fieldset_entry.rb,
lib/enolib/elements/missing/missing_section_element.rb,
lib/enolib/elements/missing/missing_value_element_base.rb

Overview

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?

Defined Under Namespace

Modules: Errors, Grammar, Locales, Selections Classes: Context, Element, ElementBase, Empty, Error, Field, Fieldset, FieldsetEntry, HtmlReporter, List, ListItem, MissingElementBase, MissingEmpty, MissingField, MissingFieldset, MissingFieldsetEntry, MissingList, MissingSection, MissingSectionElement, MissingValueElementBase, ParseError, Parser, Reporter, Section, SectionElement, TerminalReporter, TextReporter, ValidationError, ValueElementBase

Constant Summary collapse

HUMAN_INDEXING =
1
PRETTY_TYPES =
{
  document: 'document',
  empty_element: 'empty_element',
  field: 'field',
  fieldset: 'fieldset',
  fieldset_entry: 'fieldset_entry',
  list: 'list',
  list_item: 'list_item',
  multiline_field_begin: 'field',
  section: 'section'
}.freeze

Class Method Summary collapse

Class Method Details

.lookup(input, column: nil, index: nil, line: nil, **options) ⇒ Object



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# 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 = (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) ⇒ Object



4
5
6
7
8
# 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) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 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