Commits

Michael Granger committed a01e8cf

Prepping for 2.x release

  • Participants
  • Parent commits 5d7f373

Comments (0)

Files changed (22)

-hoe-deveiate -v'~>0.1'
-linkparser -v'~>1.1'
-wordnet 
+hoe-deveiate -v0.1.1
+linkparser -v1.1.3
+#wordnet

File .tm_properties

+# Settings
+projectDirectory     = "$CWD"
+windowTitle          = "${CWD/^.*\///} «$TM_DISPLAYNAME»"
+excludeInFileChooser = "{$exclude,.hg,pkg}"
+
+TM_RUBY                  = "/Users/mgranger/.rvm/bin/rvm-auto-ruby"
+
+TM_RSPEC_OPTS            = '-rrspec/core/formatters/webkit -Ilib:../Mongrel2/lib'
+TM_RSPEC_FORMATTER       = 'RSpec::Core::Formatters::WebKit'
+
+[ source.ruby ]
+disableIndentCorrections = true
+

File Manifest.txt

 lib/linguistics/languagebehavior.rb
 lib/linguistics/mixins.rb
 lib/linguistics/monkeypatches.rb
-lib/linguistics/utils.rb
 spec/lib/constants.rb
 spec/lib/helpers.rb
 spec/linguistics/en/articles_spec.rb
 = Linguistics
 
-home :: http://deveiate.org/projects/Linguistics
-source :: http://repo.deveiate.org/Linguistics
-issues :: https://bitbucket.org/ged/linguistics
+docs :: http://deveiate.org/code/linguistics
+project :: https://bitbucket.org/ged/linguistics
 github :: https://github.com/ged/linguistics
 
 
 == Description
 
-Linguistics is a framework for building linguistic utilities for Ruby objects
-in any language. It includes a generic language-independant front end, a
-module for mapping language codes into language names, and a module which
-contains various English-language utilities.
+Linguistics is a framework for building linguistic utilities for Ruby
+objects in any language. It includes a generic language-independant
+front end, a module for mapping language codes into language names, and
+a module which contains various English-language utilities.
 
 Here are a few whimsical examples:
 
   
   puts "Head of State".en.quantify( 11 )'
 
+
+== Usage
+
+The Linguistics module comes with a language-independant mechanism for
+extending core Ruby classes with linguistic methods.
+
+It consists of three parts: a core linguistics module which contains the
+class-extension framework for languages, a generic inflector class that
+serves as an extension point for linguistic methods on Ruby objects, and
+one or more language-specific modules which contain the actual
+linguistic functions.
+
+The module works by adding a single instance method for each language
+named after the language's two-letter code (or three-letter code, if no
+two-letter code is defined by ISO639) to various Ruby classes. This
+allows many language-specific methods to be added to objects without
+cluttering up the interface or risking collision between them, albeit at
+the cost of three or four more characters per method invocation. For
+example:
+
+	Linguistics::use( :en )
+	"goose".en.plural
+	# => "geese"
+
+
+=== Adding Language Modules
+
+To add a new language to the framework, define a module that will act as
+the top-level namespace for all your linguistic functions, and then
+register it as being available, like so:
+
+	module Linguistics::TLH
+	
+		# Add Klingon to the list of default languages
+		Linguistics.register_language( :tlh, self )
+
+	end
+
+The first argument is either the two- or three-letter [ISO 639.2]
+(http://www.loc.gov/standards/iso639-2/php/code_list.php) language code
+for the language you're registering.
+
+The second is the container module itself.
+
+After you register your language, each class that Linguistics is told to
+extend will have a method for your language code/s:
+
+	irb> Linguistics.use( :tlh, :classes => Object )
+	# => [Object]
+	irb> Object.new.tlh
+	# => #<(Klingon; tlhIngan-Hol-language inflector) for <Object:0x402d9674> >
+
+If you use RSpec 2, you can test out any API requirements of the module
+by requiring  'linguistics/languagebehavior' and adding a shared
+behavior to your spec:
+
+	require 'rspec'
+    require 'linguistics/languagebehavior'
+	
+	describe Linguistics::TLH do
+	
+	  it_should_behave_like "a Linguistics language module"
+	
+	  # ... any other specs for your module
+	
+	end
+
+If you wish to use the logging subsystem set up by Linguistics, you can
+do so one of two ways: by logging to the logger directly:
+
+	Linguistics.log.debug "Registering Klingon language extension"
+
+or by mixing the `Linguistics::Loggable' module into your class/module,
+which will give you a 'log' method that prepends the object class on
+each log message so it's easy to filter out the ones you want:
+
+	require 'linguistics/mixins'
+	class Linguistics::TLH::Generator
+		include Linguistics::Loggable
+
+		def generate_it
+			self.log.debug "starting generation..."
+		end
+	end
+
+
+
+== English Language Module
+
+Linguistics comes with an English-language module; see the API
+documentation for Linguistics::EN for more information about it.
+
+
+== Authors
+
+* Michael Granger <ged@FaerieMUD.org>
+* Martin Chase <stillflame@FaerieMUD.org>
+
+
+== Contributors
+
+* Robert Berry (bdigital on github) - English conjugation ported from
+  MorphAdorner
+
+
 == Requirements
 
-* Ruby >= 1.9.2
+* Ruby >= 1.9.3
 
-It may work under earlier versions, but I'll only be testing it on 1.9.2 or later.
+It may work under earlier versions, but I'll only be testing it on 1.9.3
+or later.
 
 
 == Optional
   lexical refrence system.
 
 
-== Usage
+== Contributing
 
-The Linguistics module comes with a language-independant mechanism for
-extending core Ruby classes with linguistic methods.
+You can check out the current development source with Mercurial via its
+{project page}[http://deveiate.org/projects/Linguistics]. Or if you prefer
+Git, via {its Github mirror}[https://github.com/ged/linguistics].
 
-It consists of three parts: a core linguistics module which contains the
-class-extension framework for languages, a generic inflector class that serves
-as an extension point for linguistic methods on Ruby objects, and one or more
-language-specific modules which contain the actual linguistic functions.
+After checking out the source, run:
 
-The module works by adding a single instance method for each language named
-after the language's two-letter code (or three-letter code, if no two-letter
-code is defined by ISO639) to various Ruby classes. This allows many
-language-specific methods to be added to objects without cluttering up the
-interface or risking collision between them, albeit at the cost of three or four
-more characters per method invocation. For example:
+    $ rake newb
 
-	Linguistics::use( :en )
-	"goose".en.plural
-	# => "geese"
+This task will install any missing dependencies, run the tests/specs, and
+generate the API documentation.
 
 
-=== Adding Language Modules
+== License
 
-To add a new language to the framework, define a module that will act as the top-level namespace for all your linguistic functions, and then register it as being available, like so:
+Copyright (c) 2003-2012, Michael Granger
+All rights reserved.
 
-	module Linguistics::TLH
-	
-		# Add Klingon to the list of default languages
-		Linguistics.register_language( :tlh, self )
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
 
-	end
+* Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
 
-The first argument is either the two- or three-letter [ISO 639.2] (http://www.loc.gov/standards/iso639-2/php/code_list.php) language code for the language you're registering.
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
 
-The second is the container module itself.
+* Neither the name of the author/s, nor the names of the project's
+  contributors may be used to endorse or promote products derived from this
+  software without specific prior written permission.
 
-After you register your language, each class that Linguistics is told to extend will have a method for your language code/s:
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-	irb> Linguistics.use( :tlh, :classes => Object )
-	# => [Object]
-	irb> Object.new.tlh
-	# => #<(Klingon; tlhIngan-Hol-language inflector) for <Object:0x402d9674> >
 
-If you use RSpec 2, you can test out any API requirements of the module by requiring  'linguistics/languagebehavior' and adding a shared behavior to your spec:
 
-	require 'rspec'
-    require 'linguistics/languagebehavior'
-	
-	describe Linguistics::TLH do
-	
-	  it_should_behave_like "a Linguistics language module"
-	
-	  # ... any other specs for your module
-	
-	end
-
-If you wish to use the logging subsystem set up by Linguistics, you can do so one of two ways: by logging to the logger directly:
-
-	Linguistics.log.debug "Registering Klingon language extension"
-
-or by mixing the `Linguistics::Loggable' module into your class/module, which will give you a 'log' method that prepends the object class on each log message so it's easy to filter out the ones you want:
-
-	require 'linguistics/mixins'
-	class Linguistics::TLH::Generator
-		include Linguistics::Loggable
-
-		def generate_it
-			self.log.debug "starting generation..."
-		end
-	end
-
-
-
-== English Language Module
-
-Linguistics comes with an English-language module; see the API documentation for
-Linguistics::EN for more information about it.
-
-
-== Authors
-
-* Michael Granger <ged@FaerieMUD.org>
-* Martin Chase <stillflame@FaerieMUD.org>
-
-
-== Contributors
-
-* Robert Berry (bdigital on github) - English conjugation ported from MorphAdorner
-
-
 			"gems of the same name."
 		  ].join( "\n" )
 
-	self.require_ruby_version( '>=1.9.2' )
+	self.require_ruby_version( '>=1.9.3' )
 	self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
 	self.check_history_on_release = true if self.respond_to?( :check_history_on_release= )
 
 end
 
 ENV['VERSION'] ||= hoespec.spec.version.to_s
-
-task 'hg:precheckin' => :spec
-
-### Make the ChangeLog update if the repo has changed since it was last built
-file '.hg/branch'
-file 'ChangeLog' => '.hg/branch' do |task|
-	content = begin
-		$stderr.puts "Updating the changelog..."
-		make_changelog()
-	rescue NoMethodError
-		abort "This task requires the hoe-mercurial plugin (gem install hoe-mercurial)."
-	end
-
-	File.open( task.name, 'w', 0644 ) do |fh|
-		fh.print( content )
-	end
-end
-
-# Rebuild the ChangeLog immediately before release
-task :prerelease => 'ChangeLog'
-
+ 
+task 'hg:precheckin' => [ :check_history, :check_manifest, :spec ]
+ 

File lib/linguistics.rb

 #!/usr/bin/ruby
 # coding: utf-8
 
-# An interface for extending core Ruby classes with linguistic methods.
-# 
-# @version 2.0.0
-#
-# 
-# @author Michael Granger <ged@FaerieMUD.org>
-# 
+require 'loggability'
+
+# An interface for extending core Ruby classes with natural-language methods.
 module Linguistics
+	extend Loggability
+
+	# Loggability API -- set up a logger for Linguistics objects
+	log_as :linguistics
+
 
 	# Release version
 	VERSION = '2.0.0'
 
 
 	require 'linguistics/monkeypatches'
-	require 'linguistics/utils'
 	require 'linguistics/mixins'
 	require 'linguistics/iso639'
 	require 'linguistics/inflector'
 	end
 
 
-	### Logging
-	@default_logger = Logger.new( $stderr )
-	@default_logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
-
-	@default_log_formatter = Linguistics::LogFormatter.new( @default_logger )
-	@default_logger.formatter = @default_log_formatter
-
-	@logger = @default_logger
-
-	class << self
-		# The log formatter that will be used when the logging subsystem is reset
-		attr_accessor :default_log_formatter
-
-		# The logger that will be used when the logging subsystem is reset
-		attr_accessor :default_logger
-
-		# The logger that's currently in effect
-		attr_accessor :logger
-		alias_method :log, :logger
-		alias_method :log=, :logger=
-	end
-
-
-	### Reset the global logger object to the default
-	def self::reset_logger
-		self.logger = self.default_logger
-		self.logger.level = Logger::WARN
-		self.logger.formatter = self.default_log_formatter
-	end
-
-
-	### Returns +true+ if the global logger has not been set to something other than
-	### the default one.
-	def self::using_default_logger?
-		return self.logger == self.default_logger
-	end
-
-
 	### Return the library's version string
 	def self::version_string( include_buildnum=false )
 		vstring = "%s %s" % [ self.name, VERSION ]
 	end
 
 
-	###############
-	module_function
-	###############
-
 	### Add linguistics functions for the specified languages to Ruby's core
 	### classes. The interface to all linguistic functions for a given language
 	### is through a method which is the same the language's international 2- or
 	###   the Class objects in Linguistics::DEFAULT_EXT_CLASSES (an Array) are
 	###   extended.
 	### [<b>:proxy</b>]
-	###   
-	def use( *languages )
+	###
+	def self::use( *languages )
 		config = {}
 		config = languages.pop if languages.last.is_a?( Hash )
 
 
 	### Try to load the module that implements the given language, returning
 	### the Module object if successful.
-	def load_language( lang )
+	def self::load_language( lang )
 		unless mod = self.languages[ lang.to_sym ]
 
 			Linguistics.log.debug "Trying to load language %p" % [ lang ]
 
 	### Create a mixin module/class pair that act as the per-object interface to
 	### the given language +mod+'s inflector.
-	def make_inflector_mixin( lang, mod )
+	def self::make_inflector_mixin( lang, mod )
 		language = LANGUAGE_CODES[ lang.to_sym ] or
 			raise "Unknown ISO639-2 language code '#{lang}'"
 
 
 	### Register a module as providing linguistic functions for the specified +language+ (a two- 
 	### or three-letter ISO639-2 language codes as a Symbol)
-	def register_language( language, mod )
+	def self::register_language( language, mod )
 		language_entry = LANGUAGE_CODES[ language.to_sym ] or
 			raise "Unknown ISO639-2 language code '#{language}'"
 		Linguistics.log.info "Registering %s for language %p" % [ mod, language_entry ]

File lib/linguistics/en/conjugation.rb

 #!/usr/bin/ruby
 
+require 'loggability'
 require 'linguistics/en' unless defined?( Linguistics::EN )
 
 # This file contains functions for conjugating verbs.
 # THE SOFTWARE.
 # 
 module Linguistics::EN::Conjugation
+	extend Loggability
+
+	# Use the Linguistics module's logger
+	log_to :linguistics
+
 
 	# Hash of irregular verb infinitives, read from the DATA section of the file
 	IRREGULAR_VERBS = {}
 	### Inclusion hook -- load the verb data when the module is first included.
 	def self::included( mod )
 		if IRREGULAR_VERBS.empty?
-			Linguistics.log.debug "Loading conjunctions data."
+			self.log.debug "Loading conjunctions data."
 			data = File.read( __FILE__ ).split( /^__END__$/ ).last
 			irrverb_data, doublverb_data = data.split( /^#\n# Doubling Verbs.*\n#\n/, 2 )
 			IRREGULAR_VERBS.replace( self.load_irregular_verbs(irrverb_data) )
-			Linguistics.log.debug "  loaded %d irregular verbs" % [ IRREGULAR_VERBS.length ]
+			self.log.debug "  loaded %d irregular verbs" % [ IRREGULAR_VERBS.length ]
 
 			DOUBLING_VERBS.replace( self.load_doubling_verbs(doublverb_data) )
-			Linguistics.log.debug "  loaded %d doubling verbs" % [ DOUBLING_VERBS.length ]
+			self.log.debug "  loaded %d doubling verbs" % [ DOUBLING_VERBS.length ]
 		end
 
 		super
 	### @param [String] data  the irregular verb data from the DATA section of this file.
 	### @return [Hash]
 	def self::load_irregular_verbs( data )
-		Linguistics.log.debug "  loading irregular verbs from %d bytes of data." % [ data.length ]
+		self.log.debug "  loading irregular verbs from %d bytes of data." % [ data.length ]
 		results = {}
 
 		data.each_line do |line|
 			if line =~ /^(#|\s*$)/ # Skip comments and blank lines
-				Linguistics.log.debug "  skipping line: %p" % [ line ]
+				self.log.debug "  skipping line: %p" % [ line ]
 				next
 			end
 
 			infinitive, person, tense, conjugation = line.chomp.split( /\s+/, 4 )
-			Linguistics.log.debug "  line split into: %p" %
+			self.log.debug "  line split into: %p" %
 				[[ infinitive, person, tense, conjugation ]]
 
 			raise "malformed line: %p" % [ line ] unless infinitive && person && tense && conjugation
 			results[ infinitive ][ person.to_sym ][ tense.to_sym ] = conjugation
 		end
 
-		Linguistics.log.debug "  %d infinitives loaded." % [ results.length ]
+		self.log.debug "  %d infinitives loaded." % [ results.length ]
 		return results
 	end
 
 	### @param [String] data  the doubling verbs, one on each line
 	### @return [Array]
 	def self::load_doubling_verbs( data )
-		Linguistics.log.debug "  loading doubling verbs."
+		self.log.debug "  loading doubling verbs."
 		results = []
 
 		data.each_line do |line|
 			results << line.chomp
 		end
 
-		Linguistics.log.debug "  %d doubling verbs loaded." % [ results.length ]
+		self.log.debug "  %d doubling verbs loaded." % [ results.length ]
 		return results
 	end
 

File lib/linguistics/en/wordnet.rb

 module Linguistics::EN::WordNet
 
 	@has_wordnet	= false
-	@wn_error		= nil
-	@wn_lexicon		= nil
+	@error		= nil
+	@lexicon		= nil
 
 	# Load WordNet if possible, saving the error that occurs if anything goes wrong.
 	begin
 		WordNet.logger = Linguistics.logger
 		@has_wordnet = true
 	rescue LoadError => err
-		@wn_error = err
+		@error = err
 	end
 
 
 
 		### If #has_wordnet? returns +false+, this can be called to fetch the
 		### exception which was raised when WordNet was loaded.
-		def wn_error ; @wn_error; end
+		def error ; @error; end
 
 	end # module SingletonMethods
 	extend SingletonMethods
 
 	### The instance of the WordNet::Lexicon used for all Linguistics WordNet
 	### functions.
-	def self::wn_lexicon
-		if @wn_error
+	def self::lexicon
+		if @error
 			raise NotImplementedError,
 				"WordNet functions are not loaded: %s" %
-				@wn_error.message
+				@error.message
 		end
 
-		@wn_lexicon ||= WordNet::Lexicon::new
+		@lexicon ||= WordNet::Lexicon::new
+	end
+
+
+	### Set the WordNet::Lexicon used by the linguistic functions.
+	def self::lexicon=( newlex )
+		@lexicon = newlex
 	end
 
 
 	### Make a function that calls the method +meth+ on the synset of an input
 	### word.
 	def self::def_synset_function( name )
-		define_method( name ) do |word, pos=nil, sense=nil|
-			sense ||= 1
-
-			syn = self.en.synset( word.to_s, pos, sense )
-			return syn.nil? ? nil : syn.send( name )
+		define_method( name ) do |*criteria|
+			syn = self.en.synset( *criteria ) or return nil
+			return syn.send( name )
 		end
 	end
 
 
 	### Look up the synset associated with the given word or collocation in the
 	### WordNet lexicon and return a WordNet::Synset object.
-	def synset( pos=nil, sense=1 )
-		word = self.obj.to_s
-
-		lex = Linguistics::EN::WordNet.wn_lexicon
-
-		if pos.is_a?( Fixnum )
-			sense = pos
-			pos = nil
-		end
-		postries = pos ? [pos] : [:noun, :verb, :adjective, :adverb, :other]
-		syn = nil
-
-		postries.each do |try|
-			break if syn = lex.lookup_synsets( word.to_s, try, sense )
-		end
-
-		return syn
+	def synset( *args )
+		return Linguistics::EN::WordNet.lexicon[ self.obj.to_s, *args ]
 	end
 
 
 	### Look up all the synsets associated with the given word or collocation in
 	### the WordNet lexicon and return an Array of WordNet::Synset objects. If
 	### +pos+ is +nil+, return synsets for all parts of speech.
-	def synsets( word, pos=nil )
-		lex = Linguistics::EN::wn_lexicon
-		postries = pos ? [pos] : [:noun, :verb, :adjective, :adverb, :other]
-		syns = []
-
-		postries.each do |try|
-			syns << lex.lookup_synsets( word.to_s, try )
-		end
-
-		return syns.flatten.compact
+	def synsets( *args )
+		return Linguistics::EN.lexicon.lookup_synsets( self.obj.to_s, *args )
 	end
 
 

File lib/linguistics/utils.rb

-#!/usr/bin/ruby
-# coding: utf-8
-
-require 'logger'
-require 'erb'
-require 'bigdecimal'
-require 'date'
-
-require 'linguistics' unless defined?( Linguistics )
-
-
-module Linguistics # :nodoc:
-
-	### A collection of ANSI color utility functions
-	module ANSIColorUtilities
-
-		# Set some ANSI escape code constants (Shamelessly stolen from Perl's
-		# Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
-		ANSI_ATTRIBUTES = {
-			'clear'      => 0,
-			'reset'      => 0,
-			'bold'       => 1,
-			'dark'       => 2,
-			'underline'  => 4,
-			'underscore' => 4,
-			'blink'      => 5,
-			'reverse'    => 7,
-			'concealed'  => 8,
-
-			'black'      => 30,   'on_black'   => 40,
-			'red'        => 31,   'on_red'     => 41,
-			'green'      => 32,   'on_green'   => 42,
-			'yellow'     => 33,   'on_yellow'  => 43,
-			'blue'       => 34,   'on_blue'    => 44,
-			'magenta'    => 35,   'on_magenta' => 45,
-			'cyan'       => 36,   'on_cyan'    => 46,
-			'white'      => 37,   'on_white'   => 47
-		}
-
-		###############
-		module_function
-		###############
-
-		### Create a string that contains the ANSI codes specified and return it
-		def ansi_code( *attributes )
-			attributes.flatten!
-			attributes.collect! {|at| at.to_s }
-			return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM']
-			attributes = ANSI_ATTRIBUTES.values_at( *attributes ).compact.join(';')
-
-			if attributes.empty? 
-				return ''
-			else
-				return "\e[%sm" % attributes
-			end
-		end
-
-
-		### Colorize the given +string+ with the specified +attributes+ and return it, handling 
-		### line-endings, color reset, etc.
-		def colorize( *args )
-			string = ''
-
-			if block_given?
-				string = yield
-			else
-				string = args.shift
-			end
-
-			ending = string[/(\s)$/] || ''
-			string = string.rstrip
-
-			return ansi_code( args.flatten ) + string + ansi_code( 'reset' ) + ending
-		end
-
-	end # module ANSIColorUtilities
-
-
-	# 
-	# A alternate formatter for Logger instances.
-	# 
-	#   require 'linguistics/utils'
-	#   Linguistics.logger.formatter = Linguistics::LogFormatter.new( Linguistics.logger )
-	# 
-	class LogFormatter < Logger::Formatter
-
-		# The format to output unless debugging is turned on
-		DEFAULT_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"
-
-		# The format to output if debugging is turned on
-		DEFAULT_DEBUG_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"
-
-
-		### Initialize the formatter with a reference to the logger so it can check for log level.
-		def initialize( logger, format=DEFAULT_FORMAT, debug=DEFAULT_DEBUG_FORMAT ) # :notnew:
-			@logger       = logger
-			@format       = format
-			@debug_format = debug
-
-			super()
-		end
-
-		######
-		public
-		######
-
-		# The Logger object associated with the formatter
-		attr_accessor :logger
-
-		# The logging format string
-		attr_accessor :format
-
-		# The logging format string that's used when outputting in debug mode
-		attr_accessor :debug_format
-
-
-		### Log using either the DEBUG_FORMAT if the associated logger is at ::DEBUG level or
-		### using FORMAT if it's anything less verbose.
-		def call( severity, time, progname, msg )
-			args = [
-				time.strftime( '%Y-%m-%d %H:%M:%S' ),                         # %1$s
-				time.usec,                                                    # %2$d
-				Process.pid,                                                  # %3$d
-				Thread.current == Thread.main ? 'main' : Thread.object_id,    # %4$s
-				severity,                                                     # %5$s
-				progname,                                                     # %6$s
-				msg                                                           # %7$s
-			]
-
-			if @logger.level == Logger::DEBUG
-				return self.debug_format % args
-			else
-				return self.format % args
-			end
-		end
-	end # class LogFormatter
-
-
-	# 
-	# A ANSI-colorized formatter for Logger instances.
-	# 
-	#   require 'linguistics/utils'
-	#   Linguistics.logger.formatter = Linguistics::ColorLogFormatter.new( Linguistics.logger )
-	#
-	class ColorLogFormatter < Logger::Formatter
-		extend Linguistics::ANSIColorUtilities
-
-		# Color settings
-		LEVEL_FORMATS = {
-			:debug => colorize( :bold, :black ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"},
-			:info  => colorize( :normal ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
-			:warn  => colorize( :bold, :yellow ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
-			:error => colorize( :red ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
-			:fatal => colorize( :bold, :red, :on_white ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
-		}
-
-
-		### Initialize the formatter with a reference to the logger so it can check for log level.
-		def initialize( logger, settings={} ) # :notnew:
-			settings = LEVEL_FORMATS.merge( settings )
-
-			@logger   = logger
-			@settings = settings
-
-			super()
-		end
-
-		######
-		public
-		######
-
-		# The Logger object associated with the formatter
-		attr_accessor :logger
-
-		# The formats, by level
-		attr_accessor :settings
-
-
-		### Log using the format associated with the severity
-		def call( severity, time, progname, msg )
-			args = [
-				time.strftime( '%Y-%m-%d %H:%M:%S' ),                         # %1$s
-				time.usec,                                                    # %2$d
-				Process.pid,                                                  # %3$d
-				Thread.current == Thread.main ? 'main' : Thread.object_id,    # %4$s
-				severity,                                                     # %5$s
-				progname,                                                     # %6$s
-				msg                                                           # %7$s
-			]
-
-			return self.settings[ severity.downcase.to_sym ] % args
-		end
-	end # class LogFormatter
-
-
-	# 
-	# An alternate formatter for Logger instances that outputs +div+ HTML
-	# fragments.
-	# 
-	#   require 'linguistics/utils'
-	#   Linguistics.logger.formatter = Linguistics::HtmlLogFormatter.new( Linguistics.logger )
-	# 
-	class HtmlLogFormatter < Logger::Formatter
-		include ERB::Util  # for html_escape()
-
-		# The default HTML fragment that'll be used as the template for each log message.
-		HTML_LOG_FORMAT = %q{
-		<div class="log-message %5$s">
-			<span class="log-time">%1$s.%2$06d</span>
-			[
-				<span class="log-pid">%3$d</span>
-				/
-				<span class="log-tid">%4$s</span>
-			]
-			<span class="log-level">%5$s</span>
-			:
-			<span class="log-name">%6$s</span>
-			<span class="log-message-text">%7$s</span>
-		</div>
-		}
-
-		### Override the logging formats with ones that generate HTML fragments
-		def initialize( logger, format=HTML_LOG_FORMAT ) # :notnew:
-			@logger = logger
-			@format = format
-			super()
-		end
-
-
-		######
-		public
-		######
-
-		# The HTML fragment that will be used as a format() string for the log
-		attr_accessor :format
-
-
-		### Return a log message composed out of the arguments formatted using the
-		### formatter's format string
-		def call( severity, time, progname, msg )
-			args = [
-				time.strftime( '%Y-%m-%d %H:%M:%S' ),                         # %1$s
-				time.usec,                                                    # %2$d
-				Process.pid,                                                  # %3$d
-				Thread.current == Thread.main ? 'main' : Thread.object_id,    # %4$s
-				severity.downcase,                                                     # %5$s
-				progname,                                                     # %6$s
-				html_escape( msg ).gsub(/\n/, '<br />')                       # %7$s
-			]
-
-			return self.format % args
-		end
-
-	end # class HtmlLogFormatter
-
-end # module Linguistics
-
-# vim: set nosta noet ts=4 sw=4:
-

File spec/lib/helpers.rb

 
 require 'rspec'
 require 'spec/lib/constants'
+require 'loggability/spechelpers'
 
 
-### RSpec helper functions.
-module Linguistics::SpecHelpers
-	include Linguistics::TestConstants
-
-
-	class ArrayLogger
-		### Create a new ArrayLogger that will append content to +array+.
-		def initialize( array )
-			@array = array
-		end
-
-		### Write the specified +message+ to the array.
-		def write( message )
-			@array << message
-		end
-
-		### No-op -- this is here just so Logger doesn't complain
-		def close; end
-
-	end # class ArrayLogger
-
-
-	unless defined?( LEVEL )
-		LEVEL = {
-			:debug => Logger::DEBUG,
-			:info  => Logger::INFO,
-			:warn  => Logger::WARN,
-			:error => Logger::ERROR,
-			:fatal => Logger::FATAL,
-		  }
-	end
-
-	###############
-	module_function
-	###############
-
-	### Reset the logging subsystem to its default state.
-	def reset_logging
-		Linguistics.reset_logger
-	end
-
-
-	### Alter the output of the default log formatter to be pretty in SpecMate output
-	def setup_logging( level=Logger::FATAL )
-
-		# Turn symbol-style level config into Logger's expected Fixnum level
-		if Linguistics::Loggable::LEVEL.key?( level )
-			level = Linguistics::Loggable::LEVEL[ level ]
-		end
-
-		logger = Logger.new( $stderr )
-		Linguistics.logger = logger
-		Linguistics.logger.level = level
-
-		# Only do this when executing from a spec in TextMate
-		if ENV['HTML_LOGGING'] || (ENV['TM_FILENAME'] && ENV['TM_FILENAME'] =~ /_spec\.rb/)
-			Thread.current['logger-output'] = []
-			logdevice = ArrayLogger.new( Thread.current['logger-output'] )
-			Linguistics.logger = Logger.new( logdevice )
-			# Linguistics.logger.level = level
-			Linguistics.logger.formatter = Linguistics::HtmlLogFormatter.new( logger )
-		end
-	end
-
-end
-
 ### Mock with RSpec
 RSpec.configure do |c|
 	c.mock_with( :rspec )
-	c.include( Linguistics::SpecHelpers )
+	c.include( Loggability::SpecHelpers )
 end
 
 # vim: set nosta noet ts=4 sw=4:

File spec/linguistics/en/articles_spec.rb

 
 
 describe Linguistics::EN::Articles do
-	include Linguistics::SpecHelpers
 
 	before( :all ) do
 		setup_logging( :fatal )

File spec/linguistics/en/conjugation_spec.rb

 	end
 
 	it "conjugates 'be' in first person singular as 'was'" do
-		pending "figuring out how this is supposed to work" do
+		# pending "figuring out how this is supposed to work" do
 			"be".en.past_tense( :first_person ).should == 'was'
-		end
+		# end
 	end
 
 	it "conjugates 'be' in third person singular as 'were'" do

File spec/linguistics/en/conjunctions_spec.rb

 
 
 describe Linguistics::EN::Conjunctions do
-	include Linguistics::SpecHelpers
 
 	before( :all ) do
 		Linguistics.use( :en )

File spec/linguistics/en/infinitives_spec.rb

 
 
 describe Linguistics::EN::Infinitives do
-	include Linguistics::SpecHelpers
 
 	before( :all ) do
 		setup_logging( :fatal )

File spec/linguistics/en/linkparser_spec.rb

 
 
 describe Linguistics::EN::LinkParser do
-	include Linguistics::SpecHelpers
 
 	before( :all ) do
 		setup_logging( :fatal )

File spec/linguistics/en/numbers_spec.rb

 
 
 describe Linguistics::EN::Numbers do
-	include Linguistics::SpecHelpers
 
 	before( :all ) do
 		setup_logging( :fatal )

File spec/linguistics/en/participles_spec.rb

 
 
 describe Linguistics::EN::Participles do
-	include Linguistics::SpecHelpers
 
 	before( :all ) do
 		setup_logging( :fatal )

File spec/linguistics/en/pluralization_spec.rb

 
 
 describe Linguistics::EN::Pluralization do
-	include Linguistics::SpecHelpers
 
 	before( :all ) do
 		setup_logging( :fatal )

File spec/linguistics/en/titlecase_spec.rb

 
 
 describe Linguistics::EN::TitleCase do
-	include Linguistics::SpecHelpers
 
 	before( :all ) do
 		setup_logging( :fatal )

File spec/linguistics/en/wordnet_spec.rb

 			if Linguistics::EN.has_wordnet?
 				error = LoadError.new( "no such file to load -- wordnet" )
 				Linguistics::EN::WordNet.instance_variable_set( :@has_wordnet, false )
-				Linguistics::EN::WordNet.instance_variable_set( :@wn_error, error )
+				Linguistics::EN::WordNet.instance_variable_set( :@error, error )
 			end
 		end
 

File spec/linguistics/en_spec.rb

 
 
 describe Linguistics::EN do
-	include Linguistics::SpecHelpers
 
 	before( :all ) do
 		setup_logging( :fatal )

File spec/linguistics_spec.rb

 
 
 describe Linguistics do
-	include Linguistics::SpecHelpers
 
 	before( :all ) do
-		@original_logger = Linguistics.default_logger
-		@original_log_formatter = Linguistics.default_log_formatter
-		setup_logging( :fatal )
+		setup_logging()
 	end
 
 	after( :each ) do
-		Linguistics.default_logger = @original_logger
-		Linguistics.default_log_formatter = @original_log_formatter
 		reset_logging()
 	end
 
 	end
 
 
-	describe " logging subsystem" do
-		before(:each) do
-			Linguistics.reset_logger
-		end
-
-		after(:each) do
-			Linguistics.reset_logger
-		end
-
-
-		it "knows if its default logger is replaced" do
-			Linguistics.reset_logger
-			Linguistics.should be_using_default_logger
-			Linguistics.logger = Logger.new( $stderr )
-			Linguistics.should_not be_using_default_logger
-		end
-
-		it "has the default logger instance after being reset" do
-			Linguistics.logger.should equal( Linguistics.default_logger )
-		end
-
-		it "has the default log formatter instance after being reset" do
-			Linguistics.logger.formatter.should equal( Linguistics.default_log_formatter )
-		end
-
-	end
-
-
-	describe " logging subsystem with new defaults" do
-		it "uses the new defaults when the logging subsystem is reset" do
-			logger = double( "dummy logger" )
-			formatter = double( "dummy logger" )
-
-			Linguistics.default_logger = logger
-			Linguistics.default_log_formatter = formatter
-
-			logger.should_receive( :formatter= ).with( formatter )
-			logger.should_receive( :level= ).with( Logger::WARN )
-
-			Linguistics.reset_logger
-			Linguistics.logger.should equal( logger )
-		end
-
-	end
-
-
 	describe "language-loading functions" do
 
 		it "load a language's linguistic functions via variants of its ISO639 code" do