Class: Jido::Conjugator
- Inherits:
-
Object
- Object
- Jido::Conjugator
- Defined in:
- lib/jido/conjugator.rb
Overview
This is it, folks.
Instance Attribute Summary collapse
-
#lang ⇒ Object
readonly
The language used in this Conjugator instance.
Instance Method Summary collapse
-
#check_for_list_option(option_name) ⇒ Object
Interpret the provided option when a list is expected.
-
#conjugate(verb) ⇒ Object
Hmm..
-
#fallbacks ⇒ Object
Get the fallbacks for this language, in case an exact match for a given verb is not found.
-
#forms ⇒ Object
Get the possible verb form IDs for any conjugated verb.
-
#forms=(forms) ⇒ Object
Set the forms to conjugate.
-
#forms_except=(forms_except) ⇒ Object
Set the forms to not conjugate.
-
#get_fallback_for_verb(verb) ⇒ Object
Find a fallback verbset whose regex matches the given verb.
-
#initialize(lang, options = {}) ⇒ Conjugator
constructor
Create a Jido::Conjugator instance.
-
#inspect ⇒ Object
Return a string describing the instance.
-
#options=(options) ⇒ Object
Change the options for this Conjugator instance.
-
#paradigms ⇒ Object
Get the possible paradigm IDs for any conjugated verb.
-
#paradigms=(paradigms) ⇒ Object
See Conjugator#paradigms for the expected structure of the parameter.
-
#paradigms_except=(paradigms_except) ⇒ Object
See Conjugator#paradigms for the expected structure of the parameter.
-
#search_current_el(xpath) ⇒ Object
Search each parent of some verb for a given element.
-
#store_parents(el) ⇒ Object
Find all parents of a given verb / verbset, and store them in
@current_el_parents
(if a verb / verbset #1 inherits a verb / verbset #2, then #2 is the parent of #1).
Constructor Details
#initialize(lang, options = {}) ⇒ Conjugator
Create a Jido::Conjugator instance. Load and parse the corresponding XML data file, and parse any provided options.
Accepted options (keys of the ‘options` hash should be symbols, not strings):
-
:forms
: Only return conjugations for the given verb forms / tenses.Jido::Conjugator.new 'fr', :forms => %w{prs futant}
-
:paradigms
: Only return conjugations for the given paradigms.Jido::Conjugator.new 'fr', :paradigms => [{:person => '1', :quant => 'sg'}]
-
:forms_except
: Return all conjugations except those for the given verb forms / tenses.Jido::Conjugator.new 'fr', :forms_except => 'prs'
-
:paradigms_except
: Return all conjugations except those for the given paradigms.Jido::Conjugator.new 'fr', :paradigms_except => [{:person => '3', :quant => 'pl'}]
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/jido/conjugator.rb', line 26 def initialize lang, = {} @lang = lang data_file_path = File.join(File.dirname(__FILE__), 'data', lang + '.xml') data_file = nil begin data_file = open data_file_path, 'r' rescue IOError raise "There was an error loading the data file for the given language." end @data = Nokogiri.XML data_file, nil, 'UTF-8' data_file.close self. = end |
Instance Attribute Details
#lang ⇒ Object (readonly)
The language used in this Conjugator instance. Verbs given to this instance are expected to be in this language. This instance will conjugate verbs according to rules of this language.
12 13 14 |
# File 'lib/jido/conjugator.rb', line 12 def lang @lang end |
Instance Method Details
#check_for_list_option(option_name) ⇒ Object
Interpret the provided option when a list is expected. Used to provide functionality like:
jido.conjugate 'be', :form => 'prs'
jido.conjugate 'be', :form => %w{prs pst prf}
58 59 60 61 62 63 64 65 |
# File 'lib/jido/conjugator.rb', line 58 def check_for_list_option option_name return nil if @options[option_name].nil? return [@options[option_name]] if @options[option_name].is_a?(String) or @options[option_name].is_a(Hash) return @options[option_name] if @options[option_name].is_a?(Array) raise "Invalid data type provided for option #{option_name}: a list was expected. Please provide a single string element or an array of strings." end |
#conjugate(verb) ⇒ Object
Hmm.. what does this do.. ?
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/jido/conjugator.rb', line 139 def conjugate verb @current_el = @data.at_xpath "/verbs/verb[@word='#{verb}']" @current_el = get_fallback_for_verb(verb) if @current_el.nil? return false if @current_el.nil? ret = {} @current_el_parents = [] # array of parents of the element, sorted by priority - parents earlier in the array will be picked over later ones store_parents @current_el # populate the parents array group = nil; group_search = nil forms.each do |form| next if @forms_except.include?(form) ret[form] = {} group_search = "group[@id='#{form}']" group = search_current_el group_search # grab modifier elements and extract their values group_prepend_el = group.at_xpath('prepend'); group_append_el = group.at_xpath('append'); group_mod_el = group.at_xpath('mod'); group_endlength_el = group.at_xpath('endlength') group_prepend = group_prepend_el.nil? ? nil : group_prepend_el.text group_append = group_append_el.nil? ? nil : group_append_el.text group_mod = group_mod_el.nil? ? nil : {:match => group_mod_el['match'], :search => group_mod_el['search'], :replace => group_mod_el['replace']} group_endlength = group_endlength_el.nil? ? nil : group_endlength_el.text.to_i pdgmgroup = nil; pdgmgroup_search = nil paradigm = nil; paradigm_search = nil paradigms.each do |paradigm| next if @paradigms_except.include?(paradigm) pdgmgroup_search = "group[@id='#{form}']/pdgmgroup[@id='#{paradigm[:person]}']" pdgmgroup = search_current_el pdgmgroup_search # skip this paradigm group if the "ignore" attribute is set next unless pdgmgroup['ignore'].nil? # grab modifier elements and extract their values # if unset, try to inherit from parent group pdgmgroup_prepend_el = pdgmgroup.at_xpath('prepend'); pdgmgroup_append_el = pdgmgroup.at_xpath('append'); pdgmgroup_mod_el = pdgmgroup.at_xpath('mod'); pdgmgroup_endlength_el = pdgmgroup.at_xpath('endlength') pdgmgroup_prepend = pdgmgroup_prepend_el.nil? ? group_prepend : pdgmgroup_prepend_el.text pdgmgroup_append = pdgmgroup_append_el.nil? ? group_append : pdgmgroup_append_el.text pdgmgroup_mod = pdgmgroup_mod_el.nil? ? group_mod : {:match => pdgmgroup_mod_el['match'], :search => pdgmgroup_mod_el['search'], :replace => pdgmgroup_mod_el['replace']} pdgmgroup_endlength = pdgmgroup_endlength_el.nil? ? group_endlength : pdgmgroup_endlength_el.text.to_i paradigm_search = "group[@id='#{form}']/pdgmgroup[@id='#{paradigm[:person]}']/paradigm[@id='#{paradigm[:quant]}']" paradigm_el = search_current_el paradigm_search # skip this paradigm if the "ignore" attribute is set next unless paradigm_el['ignore'].nil? # grab modifier elements and extract their values # if unset, try to inherit from parent paradigm group paradigm_prepend_el = paradigm_el.at_xpath('prepend'); paradigm_append_el = paradigm_el.at_xpath('append'); paradigm_mod_el = paradigm_el.at_xpath('mod'); paradigm_endlength_el = paradigm_el.at_xpath('endlength') prepend = paradigm_prepend_el.nil? ? pdgmgroup_prepend : paradigm_prepend_el.text append = paradigm_append_el.nil? ? pdgmgroup_append : paradigm_append_el.text mod = paradigm_mod_el.nil? ? pdgmgroup_mod : {:match => paradigm_mod_el['match'], :search => paradigm_mod_el['search'], :replace => paradigm_mod_el['replace']} endlength = paradigm_endlength_el.nil? ? pdgmgroup_endlength : paradigm_endlength_el.text.to_i endlength = 0 if endlength.nil? or endlength < 0 # make a copy of verb to run the modifiers on modded_verb = verb # chop n chars from the end of the string, based on the <endlength> modifier modded_verb = modded_verb[0 ... ( modded_verb.length - endlength )] unless endlength.nil? # <mod> modifier (regex replacement) unless mod.nil? case mod[:match] when 'first' then modded_verb.sub!(mod[:search], mod[:replace]) when 'all' then modded_verb.gsub!(mod[:search], mod[:replace]) end end # <append> and <prepend> modifiers modded_verb = ( prepend.nil? ? '' : prepend ) + modded_verb + ( append.nil? ? '' : append ) ret[form][paradigm[:person] + paradigm[:quant]] = modded_verb end end @current_el = nil @current_el_inheritor = nil ret end |
#fallbacks ⇒ Object
Get the fallbacks for this language, in case an exact match for a given verb is not found.
97 98 99 100 101 102 103 104 105 106 |
# File 'lib/jido/conjugator.rb', line 97 def fallbacks if @fallbacks.nil? @fallbacks = [] @data.xpath('/verbs/meta/fallbacks/fallback').each do |fallback| @fallbacks << {:regex => fallback['regex'], :ref => fallback['ref']} end end @fallbacks end |
#forms ⇒ Object
69 70 71 72 73 74 75 76 77 78 |
# File 'lib/jido/conjugator.rb', line 69 def forms if @forms.nil? @forms = [] @data.xpath('/verbs/meta/forms/form').each do |form| @forms << form.text end end @forms end |
#forms=(forms) ⇒ Object
Set the forms to conjugate. Use Conjugator#forms to find possible values for a certain instance.
jido.forms = %w{prs pst imp} # conjugate only for present, past, and imperfect tenses
jido.forms = 'futant' # conjugate only for future anterior tense
jido.forms = jido.forms[0..4] # conjugate for the first 5 forms stored in the conjugator
84 85 86 87 |
# File 'lib/jido/conjugator.rb', line 84 def forms= forms @options[:forms] = forms @forms = check_for_list_option :forms end |
#forms_except=(forms_except) ⇒ Object
Set the forms to not conjugate. Use Conjugator#forms to find possible values for a certain instance.
jido.forms_except = 'prs' # conjugate for all forms but the present tense
91 92 93 94 |
# File 'lib/jido/conjugator.rb', line 91 def forms_except= forms_except @options[:forms_except] = forms_except @forms_except = check_for_list_option :forms_except end |
#get_fallback_for_verb(verb) ⇒ Object
Find a fallback verbset whose regex matches the given verb. Used when an exact verb element cannot be matched with an input verb (that is, in most cases).
258 259 260 261 262 263 264 265 266 267 |
# File 'lib/jido/conjugator.rb', line 258 def get_fallback_for_verb verb fallbacks.each do |fallback| if verb.match fallback[:regex] ret = @data.at_xpath "/verbs/verbset[@id='#{fallback[:ref]}']" return ret end end false end |
#inspect ⇒ Object
Return a string describing the instance.
270 271 272 |
# File 'lib/jido/conjugator.rb', line 270 def inspect "#<Conjugator @lang=\"#{@lang}\">" end |
#options=(options) ⇒ Object
Change the options for this Conjugator instance. See Conjugator::new for possible options.
46 47 48 49 50 51 52 |
# File 'lib/jido/conjugator.rb', line 46 def @options = @forms = check_for_list_option :forms @forms_except = check_for_list_option(:forms_except) || [ ] @paradigms = check_for_list_option :paradigms @paradigms_except = check_for_list_option(:paradigms_except) || [ ] end |
#paradigms ⇒ Object
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/jido/conjugator.rb', line 114 def paradigms if @paradigms.nil? @paradigms = [] @data.xpath('/verbs/meta/paradigms/paradigm').each do |paradigm| @paradigms << {:person => paradigm['person'], :quant => paradigm['quant']} end end @paradigms end |
#paradigms=(paradigms) ⇒ Object
See Conjugator#paradigms for the expected structure of the parameter.
jido.paradigms = [{:person => '1', :quant => 'sg'}, {:person => '3', :quant => 'pl'}] # conjugate for only 1SG and 3PL
127 128 129 130 |
# File 'lib/jido/conjugator.rb', line 127 def paradigms= paradigms @options[:paradigms] = paradigms @paradigms = check_for_list_option :paradigms end |
#paradigms_except=(paradigms_except) ⇒ Object
See Conjugator#paradigms for the expected structure of the parameter.
133 134 135 136 |
# File 'lib/jido/conjugator.rb', line 133 def paradigms_except= paradigms_except @options[:paradigms_except] = paradigms_except @paradigms_except = check_for_list_option :paradigms_except end |
#search_current_el(xpath) ⇒ Object
Search each parent of some verb for a given element. Used for rule inheritance.
242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/jido/conjugator.rb', line 242 def search_current_el xpath # try to find the rule in the current verb desired_el = @current_el.at_xpath xpath return desired_el unless desired_el.nil? # check all the verb's parents, walking up the hierarchy @current_el_parents.each do |parent| desired_el = parent.at_xpath xpath return desired_el unless desired_el.nil? end nil end |
#store_parents(el) ⇒ Object
Find all parents of a given verb / verbset, and store them in @current_el_parents
(if a verb / verbset #1 inherits a verb / verbset #2, then #2 is the parent of #1)
Structure note: verbs are final objects. Verbs cannot be inherited; they are always at the bottom of a hierarchy. Verbsets can inherit / be inherited by other verbsets, and verbs can inherit verbsets. In other words.. <strong>verb = final class, verb set = abstract class</strong>.
Yay, recursion :)
232 233 234 235 236 237 238 |
# File 'lib/jido/conjugator.rb', line 232 def store_parents el return if el['inherit'].nil? inherited_el = @data.at_xpath "/verbs/verbset[@id='#{el['inherit']}']" @current_el_parents << inherited_el store_parents inherited_el end |