Class: LLT::FormBuilder

Inherits:
Object
  • Object
show all
Extended by:
Helpers::Constantize, Helpers::Normalizer
Includes:
Helpers::Constantize, Helpers::Initialize, Helpers::Metrical, Helpers::Normalizer
Defined in:
lib/llt/form_builder.rb,
lib/llt/form_builder/version.rb,
lib/llt/form_builder/helpers/verb_segments.rb,
lib/llt/form_builder/helpers/pronoun_segments.rb,
lib/llt/form_builder/helpers/stem_hash_parser.rb,
lib/llt/form_builder/helpers/adjective_like_building.rb

Direct Known Subclasses

DeclinableBuilder, VerbBuilder

Defined Under Namespace

Modules: AdjectiveLikeBuilding Classes: PronounSegments, StemHashParser, VerbSegments

Constant Summary collapse

VERSION =
"0.0.4"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stem) ⇒ FormBuilder

Returns a new instance of FormBuilder.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/llt/form_builder.rb', line 152

def initialize(stem)
  extract_normalized_args!(stem)

  # Used to evaluate if metrical endings and extensions shall be used
  evaluate_metrical_presence(@stem) if @stem # pronouns come without their stem

  @options = stem[:options] || {}
  @validate = @options[:validate] if @options
  @lookup_indices = lookup_indices

  # Use only downcased stem string in the following events,
  # only persons and places are allowed to be capitalized.
  downcase_all_stems unless stays_capitalized
end

Instance Attribute Details

#impersonaliumObject (readonly)

Returns the value of attribute impersonalium.



150
151
152
# File 'lib/llt/form_builder.rb', line 150

def impersonalium
  @impersonalium
end

Class Method Details

.build(*stem_hashes) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/llt/form_builder.rb', line 28

def build(*stem_hashes)
  stem_hashes = StemHashParser.new(stem_hashes).parse
  stem_hashes.flat_map do |stem|
    builder_kl = constant_by_type(stem[:type], suffix: "builder")
    builder_kl.new(stem).compute
  end.compact # adverb might return nil forms
end

.lookup_class(arg = nil) ⇒ Object

Defines the class to use for obtaining additional build information like thematic vowels or stem extension (e.g. an Imperfectum -ba-). Defaults to VerbSegments, most commonly used.

The argument should be a Class name.



41
42
43
# File 'lib/llt/form_builder.rb', line 41

def lookup_class(arg = nil)
  arg ? @lookup_class = arg : @lookup_class ||= VerbSegments
end

.validationsObject

Holds a list of attributes, that will be validated.



46
47
48
# File 'lib/llt/form_builder.rb', line 46

def validations
  @validations ||= []
end

Instance Method Details

#attributes_by_index(index) ⇒ Object

General purpose method to map indices to attributes using the #indices hash. Several subclasses use an easier algorithm due to computational efficiency.



245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/llt/form_builder.rb', line 245

def attributes_by_index(index)
  attrs = {}
  indices.to_a.reverse.each do |type, indices|
    indices.reverse.each_with_index do |ind, i|
      if (index - ind) >= 0
        index -= ind
        attrs[type] = reverse_lookup[type][i]
        break
      end
    end
  end
  attrs.values.reverse
end

#computeObject

The method called by FormBuilder.build to run the building process. Subclasses overwrite this for more complex computations.



175
176
177
# File 'lib/llt/form_builder.rb', line 175

def compute
  regular_forms
end

#corrections(args) ⇒ Object



272
273
# File 'lib/llt/form_builder.rb', line 272

def corrections(args)
end

#cross_indices(arr) ⇒ Object



237
238
239
# File 'lib/llt/form_builder.rb', line 237

def cross_indices(arr)
  arr.inject(:product).map(&:flatten).map { |a| a.inject(:+) }.sort
end

#default_argsObject



326
327
328
# File 'lib/llt/form_builder.rb', line 326

def default_args
  { stem: stem_copy, inflection_class: @inflection_class }
end

#downcase_all_stemsObject



361
362
363
364
# File 'lib/llt/form_builder.rb', line 361

def downcase_all_stems
  @stem.downcase! if @stem
  @options[:stem].downcase! if @options[:stem]
end

#endingsObject



340
341
342
# File 'lib/llt/form_builder.rb', line 340

def endings
  endings_path.get(*endings_attributes)
end

#endings_attributesObject



344
345
346
# File 'lib/llt/form_builder.rb', line 344

def endings_attributes
  []
end

#endings_containerObject



348
349
350
# File 'lib/llt/form_builder.rb', line 348

def endings_container
  @type
end

#endings_lookup(ending, x) ⇒ Object

Can be overwritten by subclasses if special rules are needed.



223
224
225
# File 'lib/llt/form_builder.rb', line 223

def endings_lookup(ending, x)
  x.to_s == ending
end

#endings_namespaceObject



357
358
359
# File 'lib/llt/form_builder.rb', line 357

def endings_namespace
  LLT::Constants::Endings
end

#endings_pathObject



352
353
354
355
# File 'lib/llt/form_builder.rb', line 352

def endings_path
  path = constant_by_type(endings_container, namespace: endings_namespace)
  metrical? ? path::Metrical : path
end

#extensions_and_other_signs(args) ⇒ Object



275
276
# File 'lib/llt/form_builder.rb', line 275

def extensions_and_other_signs(args)
end

#form_classObject



336
337
338
# File 'lib/llt/form_builder.rb', line 336

def form_class
  constant_by_type(namespace: LLT::Form)
end

#indices_by_ending(ending) ⇒ Object



218
219
220
# File 'lib/llt/form_builder.rb', line 218

def indices_by_ending(ending)
  endings.select_indices { |x| endings_lookup(ending, x) }
end

#init_keysObject



167
168
169
170
171
# File 'lib/llt/form_builder.rb', line 167

def init_keys
  # normalized values need to be used here!
  # call a normalize method on this array, which needs to be built
  %i{ type stem inflection_class nom deponens sexus impersonalium persona place }
end

#keep_given_value(args, validator, classification = nil) ⇒ true

Used especially with archaic forms, where a special validation rule is present, like audiundi. It enters the FB process with thematic u (archaic) which is looked up as e but passes the validation. Still we want to present the new forms like they were requested, with their archaic appearance. Only call this after you pass validation!

Parameters:

  • args (Hash)
    • arguments used for form building

  • validator (Symbol)
    • key that is used for validation

  • classification (Symbol) (defaults to: nil)
    • adds info why this value should be kept,

    e.g. an archaic form

Returns:

  • (true)


318
319
320
321
322
323
324
# File 'lib/llt/form_builder.rb', line 318

def keep_given_value(args, validator, classification = nil)
  # work in the classification first, as it might be nil
  # and we want the method to return true, as it will get
  # most frequently called at the end of a passing validation!
  args[:classification] = classification
  args[validator] = @options[validator]
end

#lookup_indicesObject

Computes a one-dimensional array of indices.

LLT::Constants::Endings provides endings for all valid Latin forms. Their index defines additional attributes.

Contrived Example:

The row %w{ o s t mus tis nt } presents personal endings
for verbs. Index 0 (o) maps to persona: 1, numerus: 1,
index 3 (mus) maps to persona: 1, numerus: 2.

All FormBuilder subclasses need to implement #indices, consisting of a hash that reveals the meaning of an index.

An implementation for the personal endings presented above would be

{ persona: [0, 1, 2], numerus: [0, 3] }

This tells us that there are 3 different values for persona - changing on every first, second and third position - and 2 values for numerus - changing on every fourth position in the endings array.

Depending on the presence of options in the given stem_hash, only selected indices are returned.



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/llt/form_builder.rb', line 201

def lookup_indices
  if ending = @options[:ending]
    indices_by_ending(ending)
  else
    arr = indices.map do |attr, index_values|
      if opt_val = @options[attr]
        index = value_as_index(opt_val)
        [index_values[index - 1]].compact
      else
        index_values.compact
      end
    end

    cross_indices(arr)
  end
end

#needs_validation?Boolean

Returns:

  • (Boolean)


299
300
301
# File 'lib/llt/form_builder.rb', line 299

def needs_validation?
  @validate && validations.any?
end

#new_form(args) ⇒ Object



265
266
267
268
269
270
# File 'lib/llt/form_builder.rb', line 265

def new_form(args)
  args = args.merge(default_args)
  extensions_and_other_signs(args)
  corrections(args)
  form_class.new(args) if valid?(args)
end

#prefixObject

used by VerbBuilder, PppBuilder (for irregulars) GerundiveBuilder and GerundBuilder



284
285
286
287
# File 'lib/llt/form_builder.rb', line 284

def prefix
  p = @options[:prefix].to_s
  p unless p.empty?
end

#reverse_lookupObject



259
260
261
262
263
# File 'lib/llt/form_builder.rb', line 259

def reverse_lookup
  @rl ||= indices.each_with_object({}) do |(type, values), h|
    h[type] = t.norm_values_for(type).take(values.size).reverse
  end
end

#stays_capitalizedObject



366
367
368
# File 'lib/llt/form_builder.rb', line 366

def stays_capitalized
  false
end

#stem_copyObject



330
331
332
333
334
# File 'lib/llt/form_builder.rb', line 330

def stem_copy
  # solely needed for irregular verbs, they might come without
  # a stem value, which will be set in the course of events
  @stem ? @stem.clone : ""
end

#valid?(args) ⇒ Boolean

Returns:

  • (Boolean)


289
290
291
292
293
294
295
296
297
# File 'lib/llt/form_builder.rb', line 289

def valid?(args)
  if needs_validation?
    validations.all? do |validator|
      validation_rule(args, validator)
    end
  else
    true
  end
end

#validation_rule(args, validator) ⇒ Object



303
304
305
# File 'lib/llt/form_builder.rb', line 303

def validation_rule(args, validator)
  args[validator].to_s == @options[validator].to_s
end

#validationsObject



278
279
280
# File 'lib/llt/form_builder.rb', line 278

def validations
  self.class.validations
end

#value_as_index(val) ⇒ Object

LLT::Constants::Terminology provides a numeric representation of every valid value, e.g. tempus: :praesens == tempus: 1



229
230
231
232
233
234
235
# File 'lib/llt/form_builder.rb', line 229

def value_as_index(val)
  if val.kind_of?(Fixnum)
    val
  else
    t.send(val, :numeric)
  end
end