Latin verb conjugation: Part II

Note, because of the macrons present, you may see the letters as ‘?’ or ‘ā’. Due to the nature of my code highlighting I can’t get accented letters and syntax highlighting simultaneously.

[code lang="ruby"]
#!/usr/bin/env ruby -Ku -rjcode
require 'rubygems'
require 'activesupport'

module LatinSpelling
  @@macron_table = {"?" => 'a',"?" => 'e',"?"=>'i',"?"=>'o',"?"=>'u',
                     "\xc5\x8d"=>"o"}

  def get_last_two_chars(input)
    return [ input.chars[-2,1].to_s.chomp, input.chars[-1,1].to_s.chomp ]
  end
  
  def special_char?(x)
    return true if @@macron_table.keys.include?(x.to_s)
  end
  
  def check_macrons(input)
    # Three rules:  Long vowels are shortened when they are followed
    # 1.  by another vowel
    # 2.  by m/r/t at the end of a word
    # 3.  by nt or nd anywhere
    
    if (input.class.to_s == "Array")
      return input.map do |person|
        check_macrons(person)
      end
    end

    if (input.class.to_s == "String")
      # 1.  preceeding another macronized letter
      input = repair_double_macron(input).to_s if input =~ /[?????][?????aeiou]/
    
      # 2.  by m/r/t at the end of a word   
      if input =~ /[mrt]$/
           last_two=get_last_two_chars(input)
           if @@macron_table.keys.include?("#{last_two[0]}")
             last_two[0] = @@macron_table["#{last_two[0]}"] 
             returnString = input.chars[0..(input.jlength()-3)] + last_two.join('').to_s
             input = returnString.to_s
           end # end if @@macron_table
         end # end if input =~/[mrt]/
    
      # 3.  by nt or nd anywhere
      input = repair_nt(input).to_s if input =~ /[?????]n[td]/
    end
      
  
    return input
  end # end check_macrons

  def repair_double_macron(dmString)
    # dmString == "double macron String"
    return dmString if dmString !~ /[?????][?????aeiou]/
    
    dblPosition = dmString =~ /([?????][?????aeiou])/
    
    # puts dblPosition.to_s + dmString.chars[dblPosition..dblPosition] + $1

    base=dmString[0..dblPosition-1]
    rest=dmString.chars[dblPosition+1..99]
    firstDblMacChar=$1.chars[0..0]

    base=base+ @@macron_table[firstDblMacChar.to_s] \
      if @@macron_table.keys.include?(firstDblMacChar)
      
    return base + repair_double_macron(rest)
  end
  
  def repair_nt(ntString)
    return ntString if ntString !~ /n[td]/
    
    ntPosition = ntString =~ /(n[td])/
        
    base=ntString[0..ntPosition-1]
    testchar=base.chars[base.jlength-1..base.jlength-1]
    rest=ntString.chars[base.jlength..99]
    nSuffix=rest.chars[0..1]
    rest=rest.chars[2..99]
    base=base.chars[0..base.jlength-2]
        
    if @@macron_table.keys.include?(testchar)
      base=base + @@macron_table[testchar.to_s] 
    end
    
    return base + nSuffix + repair_nt(rest)
  end
  
  def is_char_macron_letter(c)
    if "?????" =~ /#{c}/
      puts "contains and should be set to #{c}"
      puts c
      puts "hi" + @@macron_table.keys
    end
  end

end

class Verb < Object
  include LatinSpelling
  attr_reader :firstpersonform, :infinitive, 
              :perfectstem, :passperfpart, :stem, :conjugation, :singular_string, :plural_string
  attr_writer :singular_string, :plural_string            

  def initialize(initString)
    (@firstpersonform, @infinitive, @perfectstem, @passperfpart)=initString.split(/,\s+/)
    pparts=initString.split(/,\s+/)
    @passive_endings = ["r", "ris", "tur", "mur", "min\xc4\xab", "ntur"]
    @personages = ["First Singular", "Second Singular", "Third Singular",
                   "First Plural", "Second Plural", "Third Plural"]
    @conjugation = evaluate_conjugation
    @singular_string= @plural_string = String.new
  end

  def active_present
    oneTwoEndings=%w(s t mus tis nt)
    if @conjugation == "1" or @conjugation == "2"
      check_macrons([firstpersonform, oneTwoEndings.collect{|x| stem + x}]).flatten
    end
  end
  
  def active_imperfect   
    oneTwoEndings=%w(bam b?s bat b?mus b?tis bant)
    if @conjugation == "1" or @conjugation == "2"
      check_macrons([oneTwoEndings.collect{|x| stem + x}]).flatten
    end
  end

  def active_future
    oneTwoEndings=%w(b? bis bit bimus bitis bunt)
    if @conjugation == "1" or @conjugation=="2"
      check_macrons([oneTwoEndings.collect{|x| stem + x}]).flatten
    end    
  end
  
  def evaluate_conjugation
    if @infinitive =~ /?re$/
      return "1"
    end
    
    if @infinitive =~ /?re$/
      return "2"
    end    

    if @infinitive =~ /ere$/
      if @firstpersonform =~ /i?/
        return "3-io"
      else     
        return "3"
      end
    end
    
    if @infinitive =~ /?re$/
      return "4"
    end    
    
  end
  
  def stem
    # For efficiency, if the iVar @stem is defined, don't go through this structure
    return @stem unless @stem.nil?
      
    if @infinitive =~ /?re$/
      return @stem = @infinitive.gsub(/(.*)?re$/,'\\1?')
    end
    if @infinitive =~ /?re$/
      return @stem = @infinitive.gsub(/(.*)?re$/,'\\1?')
    end    
  end

  def to_s
    return "[#{self.firstpersonform} #{self.infinitive}" + 
             " #{self.perfectstem} #{self.passperfpart} {#{@conjugation}}]\n\n"
  end
  
  def present_passive
    local_pe=@passive_endings.clone
    return check_macrons([@firstpersonform + "r", local_pe[1..-1].map{|x| self.stem + x}].flatten!)
  end

  def imperfect_passive
    imperfect_stem = self.stem + "b\xc4\x81"
    return check_macrons(@passive_endings.map{|x| "#{imperfect_stem}#{x}"})
  end
  
  def future_passive
    fp_stem=self.stem+"bi"
    standards = @passive_endings[2..-1].map{|x| fp_stem + x}
    return [@stem + "b\xc5\x8d", @stem + "beris", standards].flatten!
  end
  
  def perfect_present
    substem=perfectstem.chars[0..perfectstem.jlength-2]
    endings=%w(ist? it imus istis ?runt)
    return [perfectstem, endings.collect{|x| substem+x}].flatten
  end
  
  def perfect_past
     substem=perfectstem.chars[0..perfectstem.jlength-2]
     endings=%w(eram er?s erat er?mus er?tis erant)
     return [endings.collect{|x| substem+x}].flatten     
  end
  
  def perfect_future
    substem=perfectstem.chars[0..perfectstem.jlength-2]
    endings=%w(er? eris erit erimus eritis erint)
    return [endings.collect{|x| substem+x}].flatten
  end
  
  def pass_perf_present
    endings=%w(sum es est sumus estis sunt)    
  end

  def pass_perf_past
    return %w(eram er?s erat er?mus er?tis erant)
  end

  def pass_perf_future
    return %w(er? eris erit erimus eritis erint)
  end
  
  def passive_system
    puts "Passive System"
    p_sys_hash= { :label=>@personages,
                  :present => self.present_passive,
                  :imperfect => self.imperfect_passive,
                  :future => self.future_passive}

    0.upto(5) do |index|
      printf("%-15s %-10s %-16s %s\n", 
                      p_sys_hash[:label][index],
                       p_sys_hash[:present][index],
                       p_sys_hash[:imperfect][index],
                       p_sys_hash[:future][index]
                      )
    end
    puts "\n\n"
  end
  
  def active_system
    puts "Active System"
    p_sys_hash= { :label=>@personages,
                  :present => self.active_present,
                  :imperfect => self.active_imperfect,
                  :future => self.active_future}

    0.upto(5) do |index|
      printf("%-15s %-10s %-16s %s\n", 
                      p_sys_hash[:label][index],
                       p_sys_hash[:present][index],
                       p_sys_hash[:imperfect][index],
                       p_sys_hash[:future][index]
                      )
    end
    puts "\n\n"
  end

    def perfect_system
      puts "Perfect System"
      p_sys_hash= { :label=>@personages,
                    :present => self.perfect_present,
                    :imperfect => self.perfect_past,
                    :future => self.perfect_future}

      0.upto(5) do |index|
        printf("%-15s %-10s %-16s %s\n", 
                        p_sys_hash[:label][index],
                         p_sys_hash[:present][index],
                                       p_sys_hash[:imperfect][index],
                                       p_sys_hash[:future][index]
                        )
      end
      puts "\n\n"
    end

    def pass_perfect_system
      puts "Passive Perfect System"
      
      substem=passperfpart.chars[0..perfectstem.jlength-2].to_s

      singular_endings=%w(a um)
      plural_endings=%w(? ae a)
 
      @singular_string= passperfpart + ', ' + singular_endings.collect{|x| substem + x}.join(', ')
      @plural_string=plural_endings.collect{|x| substem + x}.join(', ')

      prefixes=Array.new
      3.times{ prefixes.push(@singular_string)}
      3.times{ prefixes.push(@plural_string)}      

      p_sys_hash= { :label=>@personages,
                    :prefix=>prefixes,
                    :present => self.pass_perf_present,
                    :imperfect => self.pass_perf_past,
                    :future => self.pass_perf_future}

      0.upto(5) do |index|
        printf("%10s %10s %8s %8s %8s\n", 
                        p_sys_hash[:label][index],
                        p_sys_hash[:prefix][index],
                         p_sys_hash[:present][index],
                                       p_sys_hash[:imperfect][index],
                                       p_sys_hash[:future][index]
                        )
      end
    end
    
    def full_conjugation
      active_system
      perfect_system
      passive_system
      pass_perfect_system

    end
end


puts x=Verb.new("laud?, laud?re, laud?v?, laudatus")
x.full_conjugation

puts y=Verb.new("mone?, mon?re, monu?, monitus")
y.full_conjugation

[/code]

Output:


[laudō laudāre laudāvī laudatus {1}]

Active System
First Singular  laudō     laudābam        laudābō
Second Singular laudās    laudābās       laudābis
Third Singular  laudat     laudābat        laudābit
First Plural    laudāmus  laudābāmus     laudābimus
Second Plural   laudātis  laudābātis     laudābitis
Third Plural    laudant    laudābant       laudābunt


Perfect System
First Singular  laudāvī  laudāveram      laudāverō
Second Singular laudāvistī laudāverās     laudāveris
Third Singular  laudāvit  laudāverat      laudāverit
First Plural    laudāvimus laudāverāmus   laudāverimus
Second Plural   laudāvistis laudāverātis   laudāveritis
Third Plural    laudāvērunt laudāverant     laudāverint


Passive System
First Singular  laudor     laudābar        laudābō
Second Singular laudāris  laudābāris     laudāberis
Third Singular  laudātur  laudābātur     laudābitur
First Plural    laudāmur  laudābāmur     laudābimur
Second Plural   laudāminī laudābāminī   laudābiminī
Third Plural    laudantur  laudābantur     laudābintur


Passive Perfect System
First Singular laudatus, laudata, laudatum      sum     eram     erō
Second Singular laudatus, laudata, laudatum       es    erās     eris
Third Singular laudatus, laudata, laudatum      est     erat     erit
First Plural laudatī, laudatae, laudata    sumus  erāmus   erimus
Second Plural laudatī, laudatae, laudata    estis  erātis   eritis
Third Plural laudatī, laudatae, laudata     sunt    erant    erint
[moneō monēre monuī monitus {2}]

Active System
First Singular  moneō     monēbam         monēbō
Second Singular monēs     monēbās        monēbis
Third Singular  monet      monēbat         monēbit
First Plural    monēmus   monēbāmus      monēbimus
Second Plural   monētis   monēbātis      monēbitis
Third Plural    monent     monēbant        monēbunt


Perfect System
First Singular  monuī     monueram         monuerō
Second Singular monuistī  monuerās        monueris
Third Singular  monuit     monuerat         monuerit
First Plural    monuimus   monuerāmus      monuerimus
Second Plural   monuistis  monuerātis      monueritis
Third Plural    monuērunt monuerant        monuerint


Passive System
First Singular  moneor     monēbar         monēbō
Second Singular monēris   monēbāris      monēberis
Third Singular  monētur   monēbātur      monēbitur
First Plural    monēmur   monēbāmur      monēbimur
Second Plural   monēminī monēbāminī    monēbiminī
Third Plural    monentur   monēbantur      monēbintur


Passive Perfect System
First Singular monitus, monia, monium      sum     eram     erō
Second Singular monitus, monia, monium       es    erās     eris
Third Singular monitus, monia, monium      est     erat     erit
First Plural moniī, moniae, monia    sumus  erāmus   erimus
Second Plural moniī, moniae, monia    estis  erātis   eritis
Third Plural moniī, moniae, monia     sunt    erant    erint