def conjunction( obj, args={} )
config = ConjunctionDefaults.merge( args )
phrases = []
if block_given?
phrases = obj.collect {|item| yield(item) }.compact
else
phrases = obj.collect {|item| item.to_s }
end
return a(phrases[0]) if phrases.length < 2
keyfunc =
if config[:casefold]
proc {|key| key.downcase.strip}
else
proc {|key| key.strip}
end
collector = {}
if config[:combine]
phrases.each_index do |i|
break if phrases[i].nil?
phrase = keyfunc[ phrases[i] ]
if collector.key?( phrase )
collector[ phrase ] += 1
phrases.delete_at( i )
redo
end
collector[ phrase ] = 1
end
else
phrases.uniq.each {|key| collector[ keyfunc[key] ] = 1}
end
if config[:quantsort] && config[:combine]
origorder = {}
phrases.each_with_index {|phrase,i| origorder[ keyfunc[phrase] ] ||= i }
phrases.sort! {|a,b|
(collector[ keyfunc[b] ] <=> collector[ keyfunc[a] ]).nonzero? ||
(origorder[ keyfunc[a] ] <=> origorder[ keyfunc[b] ])
}
end
filter =
if config[:generalize]
proc {|phrase, count| quantify(phrase, count) }
else
proc {|phrase, count|
if count > 1
"%s %s" % [
count < 10 ? count.en.numwords : count.to_s,
plural(phrase, count)
]
else
a( phrase )
end
}
end
phrases.collect! {|phrase| filter[phrase, collector[ keyfunc[phrase] ]] }
phrases[-1].insert( 0, config[:conjunctive] + " " ) unless
config[:conjunctive].strip.empty? or
phrases.length < 2
phrase_count = phrases.length
phrases[-2] << " " << phrases.pop unless config[:penultimate]
sep = config[:separator]
if phrase_count <= 2
sep = ' '
elsif phrases.find {|str| str.include?(config[:separator]) }
sep = config[:altsep]
end
return phrases.join( sep )
end