Commits

Eric Rochester committed c282dfc Merge

Merged monad-stack.

  • Participants
  • Parent commits 86fad13, 68a99b2
  • Branches develop

Comments (0)

Files changed (45)

 *.hc
 *.o
 *.orig
+*.log
 .DS_Store
 .bundle/
 .sass-cache/
 flot/
 American National Corpus v1/
 anc/
+sample/
 texts/
 data/
-*.log
+utils/
+bin/bakers12
 
 ## Notes
 
-1. Tokenizer and application framework (*done*);
+1. Tokenizer and application framework;
 1. Type/token ratios, graph of changing ratio over the course of a text or
-   corpus (*done*);
-1. Snap server (*done*);
-1. Frequency report (*done*);
-1. HTML 5, CoffeeScript, Compass/SASS (*done*);
-1. XML tokenizer (*done*);
+   corpus;
+1. Snap server;
+1. Frequency report;
+1. HTML 5, CoffeeScript, Compass/SASS;
+1. XML tokenizer;
 1. Re-work tokenizer to match ANC;
 1. Persistence in Level DB or SQLite in RDF;
 1. Corpus management;
   case target
   when 'development'
     flags = %{-f development --enable-tests}
+  when 'profiling'
+    flags = %{-f profiling --enable-library-profiling --ghc-option=-auto-all}
+  when 'production'
+    flags = %{--ghc-option=-dno-debug-output}
   else
     flags = ''
   end
   task :build do
     sh %{cabal build}
   end
+
+  desc 'This creates the documentation. (This fails unless the "Executable" section is removed from bakers12.cabal.)'
+  task :docs do
+    sh %{cabal haddock --hyperlink-source}
+  end
+
+  desc 'This runs hlint on the library.'
+  task :lint do
+    sh %{hlint lib}
+  end
 end
 
 namespace :release do

File bakers12.cabal

 -- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
 
 Name:		bakers12
-Version:	0.1
+Version:	0.0.0
 Synopsis:	This is a boot-camp style series of thirteen one-day coding projects. The aim is to experiment with NLP in Haskell.
 Homepage:	https://bitbucket.org/erochest/bakers12
 License:	BSD3
   , bakers12/templates/echo.tpl
   , bakers12/templates/index.tpl
 data-files:
-  bakers12/resource-dir-marker,
-  bakers12/static/*.html,
-  bakers12/static/*.png,
-  bakers12/static/*.xml,
-  bakers12/static/*.ico,
-  bakers12/static/*.txt,
-  bakers12/static/images/*.png,
-  bakers12/static/js/libs/flot/*.min.js,
-  bakers12/static/js/libs/flot/*.flot.min.js,
-  bakers12/static/js/libs/jquery-1.6.3.min.js,
-  bakers12/static/js/libs/modernizr-2.0.6.min.js,
-  bakers12/static/js/*.js,
-  bakers12/static/stylesheets/*.css,
-  bakers12/templates/*.tpl
+    bakers12/resource-dir-marker
+  , bakers12/static/*.html
+  , bakers12/static/*.png
+  , bakers12/static/*.xml
+  , bakers12/static/*.ico
+  , bakers12/static/*.txt
+  , bakers12/static/images/*.png
+  , bakers12/static/js/libs/flot/*.min.js
+  , bakers12/static/js/libs/flot/*.flot.min.js
+  , bakers12/static/js/libs/jquery-1.6.3.min.js
+  , bakers12/static/js/libs/modernizr-2.0.6.min.js
+  , bakers12/static/js/*.js
+  , bakers12/static/stylesheets/*.css
+  , bakers12/templates/*.tpl
 
 Flag development
   Description:	Whether to build in development mode.
   Default:	False
 
+Flag profiling
+  Description:  Whether to build for profiling.
+  Default:      False
+
 Library
-  hs-source-dirs:  src
+  hs-source-dirs:  lib
 
   exposed-modules:
-    Text.Bakers12.Tokenizer
-    Text.Bakers12.Tokenizer.ByteString
-    Text.Bakers12.Tokenizer.String
-    Text.Bakers12.Tokenizer.Text
-    Text.Bakers12.Tokenizer.Types
-    Text.Bakers12.Tokenizer.Xml
-    Text.Bakers12.Stats
+      System.Bakers12.Enumerators
+    , Text.Bakers12.Csv
+    , Text.Bakers12.Csv.Enumerators
+    , Text.Bakers12.Csv.Types
+    , Text.Bakers12.Csv.Utils
+    , Text.Bakers12.JSON.Enumerators
+    , Text.Bakers12.Tokenizer
+    , Text.Bakers12.Tokenizer.Csv
+    , Text.Bakers12.Tokenizer.JSON
+    , Text.Bakers12.Tokenizer.Minimal
+    , Text.Bakers12.Tokenizer.PennTreebank
+    , Text.Bakers12.Tokenizer.Types
 
-  -- other-modules:
+  other-modules:
 
   Build-depends:
-    base >= 4.3 && < 5,
-    mtl >= 2.0.1.0 && < 3,
-    bytestring >= 0.9.1.10 && < 0.10,
-    text >= 0.11.0.6 && < 0.12,
-    containers >= 0.4.0.0 && < 1,
-    hxt >= 9.1.4 && < 10
+      base >=3 && <5
+    , mtl >=2 && <3
+    , transformers >=0.2 && <1
+    , filepath >=1.2 && <2
+    , directory >=1.1 && <2
+    , text >=0.10 && <1
+    , enumerator >=0.4 && <5
+    , aeson >=0.5 && <0.6
 
   extensions: TypeSynonymInstances
 
   if flag(development)
     cpp-options -DDEVELOPMENT
-    build-depends: hint >= 0.3.2 && < 0.4
-    ghc-options: -threaded -w
+    -- build-depends: hint >= 0.3.2 && < 0.4
+    ghc-options: -DDEVELOPMENT -threaded -w -Wall
   else
-    if impl(ghc >= 6.12.0)
-      ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2
-                   -fno-warn-orphans -fno-warn-unused-do-bind
+    if flag(profiling)
+      cpp-options -DDEVELOPMENT
+      -- build-depends: hint >= 0.3.2 && < 0.4
+      ghc-options: -DDEVELOPMENT -threaded -w -O -rtsopts -prof
     else
-      ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2
-                   -fno-warn-orphans
+      if impl(ghc >= 6.12.0)
+        ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2
+                     -fno-warn-orphans -fno-warn-unused-do-bind -rtsopts
+      else
+        ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2
+                     -fno-warn-orphans -rtsopts
 
 Executable bakers12
   hs-source-dirs:  src
   Main-is:	   Bakers12.hs
   
   Build-depends:
-    base >= 4.3 && < 5,
-    cmdargs >= 0.8,
-    mtl >= 2.0.1.0 && < 3,
-    filepath >= 1.2.0.0 && < 2,
-    directory >= 1.1.0.0 && < 2,
-    containers >= 0.4.0.0 && < 1,
-    bytestring >= 0.9.1 && < 0.10,
-    heist >= 0.5 && < 0.6,
-    MonadCatchIO-transformers >= 0.2.1 && < 0.3,
-    snap == 0.5.*,
-    snap-core == 0.5.*,
-    snap-server == 0.5.*,
-    text >= 0.11 && < 0.12,
-    time >= 1.1 && < 1.3,
-    xmlhtml == 0.1.*,
-    transformers >= 0.2.2.0 && < 1,
-    process >= 1.0.1.5 && < 2,
-    hxt >= 9.1.4 && < 10,
-    bakers12
+      base >=3 && <5
+    , mtl >=2 && <3
+    , cmdargs >=0.9 && <1
+    , enumerator >=0.4 && <5
+    , text >=0.10 && <1
+    , bakers12
 
-  extensions: DeriveDataTypeable TypeSynonymInstances MultiParamTypeClasses
+  extensions:
+      TypeSynonymInstances
 
-  -- Modules not exported by this package.
   Other-modules:
-    System.Bakers12.Utils,
-    Paths_bakers12
-  
-  -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.
-  -- Build-tools:	   
+      Paths_bakers12
+    , Bakers12.Cli
+    , Bakers12.Modes
+    , Bakers12.Modes.Tokenizer
 
   if flag(development)
     cpp-options -DDEVELOPMENT
-    build-depends: hint >= 0.3.2 && < 0.4
-    ghc-options: -DDEVELOPMENT -threaded -w
+    -- build-depends: hint >= 0.3.2 && < 0.4
+    ghc-options: -DDEVELOPMENT -threaded -w -O
   else
-    if impl(ghc >= 6.12.0)
-      ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2
-                   -fno-warn-orphans -fno-warn-unused-do-bind
+    if flag(profiling)
+      cpp-options -DDEVELOPMENT
+      -- build-depends: hint >= 0.3.2 && < 0.4
+      ghc-options: -DDEVELOPMENT -threaded -w -O -rtsopts -prof
     else
-      ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2
-                   -fno-warn-orphans
+      if impl(ghc >= 6.12.0)
+        ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2
+                     -fno-warn-orphans -fno-warn-unused-do-bind -rtsopts
+      else
+        ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2
+                     -fno-warn-orphans -rtsopts
 
 Test-Suite test-bakers12
   type:                  exitcode-stdio-1.0
   hs-source-dirs:	 tests
   main-is:               TestBakers12.hs
   build-depends:
-    base >= 4.3 && < 5,
-    test-framework >= 0.3.3 && < 0.5,
-    test-framework-quickcheck2 >= 0.2.9 && < 0.3,
-    test-framework-hunit >= 0.2.6 && < 0.3,
-    QuickCheck >= 2.4.0.1,
-    HUnit >= 1.2 && < 2,
-    text >= 0.11 && < 0.12,
-    containers >= 0.4.0.0 && < 1,
-    bakers12
+      base >=3 && <5
+    , mtl >=2 && <3
+    , test-framework >=0.4 && <0.5
+    , test-framework-hunit >=0.2.6 && <0.3
+    , test-framework-quickcheck2 >=0.2.9 && <0.3
+    , HUnit >=1.2 && <2
+    , QuickCheck >=2.4 && <3
+    , text >=0.10 && <1
+    , filepath >=1.2 && <2
+    , directory >=1.1 && <2
+    , enumerator >=0.4 && <5
+    , bakers12
   ghc-options:		 -Wall -rtsopts
 
 source-repository head

File bakers12/static/js/script.js

 (function() {
+
   $(function() {
     $('#ratiograph').each(function(idx, ratioGraph) {
       return $.plot(ratioGraph, [
       });
     });
   });
+
 }).call(this);

File bakers12/static/stylesheets/ie.css

 body.bp {
   text-align: center;
 }
-/* line 44, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 44, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 * html body.bp legend {
   margin: 0px -8px 16px 0;
   padding: 0;
 }
-/* line 48, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 48, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 html > body.bp p code {
   *white-space: normal;
 }
-/* line 60, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 60, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp .container {
   text-align: left;
 }
-/* line 62, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 62, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp sup {
   vertical-align: text-top;
 }
-/* line 64, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 64, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp sub {
   vertical-align: text-bottom;
 }
-/* line 66, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 66, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp hr {
   margin: -8px auto 11px;
 }
-/* line 68, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 68, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp img {
   -ms-interpolation-mode: bicubic;
 }
-/* line 70, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 70, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp fieldset {
   padding-top: 0;
 }
-/* line 72, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 72, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp legend {
   margin-top: -0.2em;
   margin-bottom: 1em;
   margin-left: -0.5em;
 }
-/* line 76, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 76, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp fieldset, body.bp #IE8#HACK {
   padding-top: 1.4em;
 }
-/* line 77, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 77, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp legend, body.bp #IE8#HACK {
   margin-top: 0;
   margin-bottom: 0;
 }
-/* line 78, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 78, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp textarea {
   overflow: auto;
 }
-/* line 80, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 80, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp label {
   position: relative;
   top: -0.25em;
 }
-/* line 84, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 84, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp input.text {
   margin: 0.5em 0;
   background-color: white;
   border: 1px solid #bbbbbb;
 }
-/* line 88, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 88, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp input.text:focus {
   border: 1px solid #666666;
 }
-/* line 90, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 90, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp input.title {
   margin: 0.5em 0;
   background-color: white;
   border: 1px solid #bbbbbb;
 }
-/* line 94, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 94, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp input.title:focus {
   border: 1px solid #666666;
 }
-/* line 96, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 96, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp input.checkbox {
   position: relative;
   top: 0.25em;
 }
-/* line 99, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 99, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp input.radio {
   position: relative;
   top: 0.25em;
 }
-/* line 102, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 102, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp input.button {
   position: relative;
   top: 0.25em;
 }
-/* line 105, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 105, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp textarea {
   margin: 0.5em 0;
 }
-/* line 107, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 107, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp select {
   margin: 0.5em 0;
 }
-/* line 109, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
+/* line 109, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_ie.scss */
 body.bp button {
   position: relative;
   top: 0.25em;

File bakers12/static/stylesheets/print.css

   background: none;
   font-size: 10pt;
 }
-/* line 45, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 45, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp .container {
   background: none;
 }
-/* line 47, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 47, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp hr {
   background: #cccccc;
   color: #cccccc;
   padding: 0;
   border: none;
 }
-/* line 55, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 55, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp hr.space {
   background: white;
   color: white;
 }
-/* line 58, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 58, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp h1, body.bp h2, body.bp h3, body.bp h4, body.bp h5, body.bp h6 {
   font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
 }
-/* line 60, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 60, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp code {
   font-size: 0.9em;
   font-family: "andale mono", "lucida console", monospace;
 }
-/* line 65, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 65, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp a img {
   border: none;
 }
-/* line 68, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 68, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp a:link, body.bp a:visited {
   background: transparent;
   font-weight: 700;
   text-decoration: underline;
 }
-/* line 72, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 72, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp p img.top {
   margin-top: 0;
 }
-/* line 74, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 74, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp blockquote {
   margin: 1.5em;
   padding: 1em;
   font-style: italic;
   font-size: 0.9em;
 }
-/* line 79, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 79, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp .small {
   font-size: 0.9em;
 }
-/* line 81, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 81, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp .large {
   font-size: 1.1em;
 }
-/* line 83, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 83, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp .quiet {
   color: #999999;
 }
-/* line 85, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_print.scss */
+/* line 85, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_print.scss */
 body.bp .hide {
   display: none;
 }

File bakers12/static/stylesheets/screen.css

-/* line 4, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
+/* line 4, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
 html {
   margin: 0;
   padding: 0;
   border: 0;
 }
 
-/* line 18, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
+/* line 18, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
 .bp-reset-element, body, h1, h2, h3, h4, h5, h6, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary, blockquote, q, th, td, caption, table,
 div, span, object, iframe, p,
 pre, a, abbr, acronym, address,
   vertical-align: baseline;
 }
 
-/* line 20, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
+/* line 20, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
 article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary {
   display: block;
 }
 
-/* line 21, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
+/* line 21, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
 blockquote, q {
   quotes: "" "";
 }
-/* line 67, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
+/* line 67, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
 blockquote:before, blockquote:after, q:before, q:after {
   content: "";
 }
 
-/* line 22, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
+/* line 22, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
 th, td, caption {
   float: none !important;
   text-align: left;
   vertical-align: middle;
 }
 
-/* line 23, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
+/* line 23, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
 table {
   border-collapse: separate;
   border-spacing: 0;
   vertical-align: middle;
 }
 
-/* line 24, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
+/* line 24, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/reset/_utilities.scss */
 a img {
   border: none;
 }
   color: #333333;
   font-size: 75%;
 }
-/* line 51, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 51, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp h1, body.bp h2, body.bp h3, body.bp h4, body.bp h5, body.bp h6 {
   font-weight: normal;
   color: #222222;
 }
-/* line 52, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 52, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp h1 img, body.bp h2 img, body.bp h3 img, body.bp h4 img, body.bp h5 img, body.bp h6 img {
   margin: 0;
 }
-/* line 53, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 53, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp h1 {
   font-size: 3em;
   line-height: 1;
   margin-bottom: 0.50em;
 }
-/* line 54, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 54, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp h2 {
   font-size: 2em;
   margin-bottom: 0.75em;
 }
-/* line 55, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 55, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp h3 {
   font-size: 1.5em;
   line-height: 1;
   margin-bottom: 1.00em;
 }
-/* line 56, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 56, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp h4 {
   font-size: 1.2em;
   line-height: 1.25;
   margin-bottom: 1.25em;
 }
-/* line 57, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 57, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp h5 {
   font-size: 1em;
   font-weight: bold;
   margin-bottom: 1.50em;
 }
-/* line 58, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 58, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp h6 {
   font-size: 1em;
   font-weight: bold;
 }
-/* line 59, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 59, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp p {
   margin: 0 0 1.5em;
 }
-/* line 60, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 60, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp p .left {
   display: inline;
   float: left;
   margin: 1.5em 1.5em 1.5em 0;
   padding: 0;
 }
-/* line 61, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 61, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp p .right {
   display: inline;
   float: right;
   margin: 1.5em 0 1.5em 1.5em;
   padding: 0;
 }
-/* line 62, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 62, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp a {
   text-decoration: underline;
   color: #0066cc;
 }
-/* line 18, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */
+/* line 18, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */
 body.bp a:visited {
   color: #004c99;
 }
-/* line 21, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */
+/* line 21, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */
 body.bp a:focus {
   color: #0099ff;
 }
-/* line 24, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */
+/* line 24, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */
 body.bp a:hover {
   color: #0099ff;
 }
-/* line 27, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */
+/* line 27, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/typography/links/_link-colors.scss */
 body.bp a:active {
   color: #bf00ff;
 }
-/* line 63, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 63, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp blockquote {
   margin: 1.5em;
   color: #666666;
   font-style: italic;
 }
-/* line 64, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 64, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp strong, body.bp dfn {
   font-weight: bold;
 }
-/* line 65, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 65, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp em, body.bp dfn {
   font-style: italic;
 }
-/* line 66, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 66, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp sup, body.bp sub {
   line-height: 0;
 }
-/* line 67, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 67, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp abbr, body.bp acronym {
   border-bottom: 1px dotted #666666;
 }
-/* line 68, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 68, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp address {
   margin: 0 0 1.5em;
   font-style: italic;
 }
-/* line 69, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 69, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp del {
   color: #666666;
 }
-/* line 70, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 70, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp pre {
   margin: 1.5em 0;
   white-space: pre;
 }
-/* line 71, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 71, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp pre, body.bp code, body.bp tt {
   font: 1em "andale mono", "lucida console", monospace;
   line-height: 1.5;
 }
-/* line 72, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 72, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp li ul, body.bp li ol {
   margin: 0;
 }
-/* line 73, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 73, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp ul, body.bp ol {
   margin: 0 1.5em 1.5em 0;
   padding-left: 1.5em;
 }
-/* line 74, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 74, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp ul {
   list-style-type: disc;
 }
-/* line 75, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 75, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp ol {
   list-style-type: decimal;
 }
-/* line 76, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 76, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp dl {
   margin: 0 0 1.5em 0;
 }
-/* line 77, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 77, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp dl dt {
   font-weight: bold;
 }
-/* line 78, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 78, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp dd {
   margin-left: 1.5em;
 }
-/* line 79, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 79, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp table {
   margin-bottom: 1.4em;
   width: 100%;
 }
-/* line 80, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 80, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp th {
   font-weight: bold;
 }
-/* line 81, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 81, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp thead th {
   background: #c3d9ff;
 }
-/* line 82, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 82, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp th, body.bp td, body.bp caption {
   padding: 4px 10px 4px 5px;
 }
-/* line 85, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 85, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp table.striped tr:nth-child(even) td,
 body.bp table tr.even td {
   background: #e5ecf9;
 }
-/* line 86, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 86, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp tfoot {
   font-style: italic;
 }
-/* line 87, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 87, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp caption {
   background: #eeeeee;
 }
-/* line 88, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 88, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp .quiet {
   color: #666666;
 }
-/* line 89, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
+/* line 89, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_typography.scss */
 body.bp .loud {
   color: #111111;
 }
-/* line 9, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
+/* line 9, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
 body.bp .clear {
   clear: both;
 }
-/* line 12, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
+/* line 12, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
 body.bp .nowrap {
   white-space: nowrap;
 }
-/* line 16, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
+/* line 16, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
 body.bp .clearfix {
   overflow: hidden;
   *zoom: 1;
 }
-/* line 18, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
+/* line 18, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
 body.bp .small {
   font-size: 0.8em;
   margin-bottom: 1.875em;
   line-height: 1.875em;
 }
-/* line 22, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
+/* line 22, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
 body.bp .large {
   font-size: 1.2em;
   line-height: 2.5em;
   margin-bottom: 1.25em;
 }
-/* line 26, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
+/* line 26, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
 body.bp .first {
   margin-left: 0;
   padding-left: 0;
 }
-/* line 29, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
+/* line 29, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
 body.bp .last {
   margin-right: 0;
   padding-right: 0;
 }
-/* line 32, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
+/* line 32, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
 body.bp .top {
   margin-top: 0;
   padding-top: 0;
 }
-/* line 35, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
+/* line 35, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_utilities.scss */
 body.bp .bottom {
   margin-bottom: 0;
   padding-bottom: 0;
 }
-/* line 25, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_debug.scss */
+/* line 25, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_debug.scss */
 body.bp .showgrid {
   background-image: -webkit-gradient(linear, 50% 100%, 50% 0%, color-stop(5%, rgba(0, 0, 0, 0.5)), color-stop(5%, rgba(0, 0, 0, 0))), -webkit-gradient(linear, 0% 50%, 960 50%, color-stop(0%, rgba(0, 0, 0, 0)), color-stop(0%, rgba(100, 100, 225, 0.25)), color-stop(3.125%, rgba(100, 100, 225, 0.25)), color-stop(3.125%, rgba(0, 0, 0, 0)), color-stop(4.167%, rgba(0, 0, 0, 0)), color-stop(4.167%, rgba(100, 100, 225, 0.25)), color-stop(7.292%, rgba(100, 100, 225, 0.25)), color-stop(7.292%, rgba(0, 0, 0, 0)), color-stop(8.333%, rgba(0, 0, 0, 0)), color-stop(8.333%, rgba(100, 100, 225, 0.25)), color-stop(11.458%, rgba(100, 100, 225, 0.25)), color-stop(11.458%, rgba(0, 0, 0, 0)), color-stop(12.5%, rgba(0, 0, 0, 0)), color-stop(12.5%, rgba(100, 100, 225, 0.25)), color-stop(15.625%, rgba(100, 100, 225, 0.25)), color-stop(15.625%, rgba(0, 0, 0, 0)), color-stop(16.667%, rgba(0, 0, 0, 0)), color-stop(16.667%, rgba(100, 100, 225, 0.25)), color-stop(19.792%, rgba(100, 100, 225, 0.25)), color-stop(19.792%, rgba(0, 0, 0, 0)), color-stop(20.833%, rgba(0, 0, 0, 0)), color-stop(20.833%, rgba(100, 100, 225, 0.25)), color-stop(23.958%, rgba(100, 100, 225, 0.25)), color-stop(23.958%, rgba(0, 0, 0, 0)), color-stop(25%, rgba(0, 0, 0, 0)), color-stop(25%, rgba(100, 100, 225, 0.25)), color-stop(28.125%, rgba(100, 100, 225, 0.25)), color-stop(28.125%, rgba(0, 0, 0, 0)), color-stop(29.167%, rgba(0, 0, 0, 0)), color-stop(29.167%, rgba(100, 100, 225, 0.25)), color-stop(32.292%, rgba(100, 100, 225, 0.25)), color-stop(32.292%, rgba(0, 0, 0, 0)), color-stop(33.333%, rgba(0, 0, 0, 0)), color-stop(33.333%, rgba(100, 100, 225, 0.25)), color-stop(36.458%, rgba(100, 100, 225, 0.25)), color-stop(36.458%, rgba(0, 0, 0, 0)), color-stop(37.5%, rgba(0, 0, 0, 0)), color-stop(37.5%, rgba(100, 100, 225, 0.25)), color-stop(40.625%, rgba(100, 100, 225, 0.25)), color-stop(40.625%, rgba(0, 0, 0, 0)), color-stop(41.667%, rgba(0, 0, 0, 0)), color-stop(41.667%, rgba(100, 100, 225, 0.25)), color-stop(44.792%, rgba(100, 100, 225, 0.25)), color-stop(44.792%, rgba(0, 0, 0, 0)), color-stop(45.833%, rgba(0, 0, 0, 0)), color-stop(45.833%, rgba(100, 100, 225, 0.25)), color-stop(48.958%, rgba(100, 100, 225, 0.25)), color-stop(48.958%, rgba(0, 0, 0, 0)), color-stop(50%, rgba(0, 0, 0, 0)), color-stop(50%, rgba(100, 100, 225, 0.25)), color-stop(53.125%, rgba(100, 100, 225, 0.25)), color-stop(53.125%, rgba(0, 0, 0, 0)), color-stop(54.167%, rgba(0, 0, 0, 0)), color-stop(54.167%, rgba(100, 100, 225, 0.25)), color-stop(57.292%, rgba(100, 100, 225, 0.25)), color-stop(57.292%, rgba(0, 0, 0, 0)), color-stop(58.333%, rgba(0, 0, 0, 0)), color-stop(58.333%, rgba(100, 100, 225, 0.25)), color-stop(61.458%, rgba(100, 100, 225, 0.25)), color-stop(61.458%, rgba(0, 0, 0, 0)), color-stop(62.5%, rgba(0, 0, 0, 0)), color-stop(62.5%, rgba(100, 100, 225, 0.25)), color-stop(65.625%, rgba(100, 100, 225, 0.25)), color-stop(65.625%, rgba(0, 0, 0, 0)), color-stop(66.667%, rgba(0, 0, 0, 0)), color-stop(66.667%, rgba(100, 100, 225, 0.25)), color-stop(69.792%, rgba(100, 100, 225, 0.25)), color-stop(69.792%, rgba(0, 0, 0, 0)), color-stop(70.833%, rgba(0, 0, 0, 0)), color-stop(70.833%, rgba(100, 100, 225, 0.25)), color-stop(73.958%, rgba(100, 100, 225, 0.25)), color-stop(73.958%, rgba(0, 0, 0, 0)), color-stop(75%, rgba(0, 0, 0, 0)), color-stop(75%, rgba(100, 100, 225, 0.25)), color-stop(78.125%, rgba(100, 100, 225, 0.25)), color-stop(78.125%, rgba(0, 0, 0, 0)), color-stop(79.167%, rgba(0, 0, 0, 0)), color-stop(79.167%, rgba(100, 100, 225, 0.25)), color-stop(82.292%, rgba(100, 100, 225, 0.25)), color-stop(82.292%, rgba(0, 0, 0, 0)), color-stop(83.333%, rgba(0, 0, 0, 0)), color-stop(83.333%, rgba(100, 100, 225, 0.25)), color-stop(86.458%, rgba(100, 100, 225, 0.25)), color-stop(86.458%, rgba(0, 0, 0, 0)), color-stop(87.5%, rgba(0, 0, 0, 0)), color-stop(87.5%, rgba(100, 100, 225, 0.25)), color-stop(90.625%, rgba(100, 100, 225, 0.25)), color-stop(90.625%, rgba(0, 0, 0, 0)), color-stop(91.667%, rgba(0, 0, 0, 0)), color-stop(91.667%, rgba(100, 100, 225, 0.25)), color-stop(94.792%, rgba(100, 100, 225, 0.25)), color-stop(94.792%, rgba(0, 0, 0, 0)), color-stop(95.833%, rgba(0, 0, 0, 0)), color-stop(95.833%, rgba(100, 100, 225, 0.25)), color-stop(98.958%, rgba(100, 100, 225, 0.25)), color-stop(98.958%, rgba(0, 0, 0, 0)), color-stop(100%, rgba(0, 0, 0, 0)));
   background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0.5) 5%, rgba(0, 0, 0, 0) 5%), -webkit-linear-gradient(left, rgba(0, 0, 0, 0) 0px, rgba(100, 100, 225, 0.25) 0px, rgba(100, 100, 225, 0.25) 30px, rgba(0, 0, 0, 0) 30px, rgba(0, 0, 0, 0) 40px, rgba(100, 100, 225, 0.25) 40px, rgba(100, 100, 225, 0.25) 70px, rgba(0, 0, 0, 0) 70px, rgba(0, 0, 0, 0) 80px, rgba(100, 100, 225, 0.25) 80px, rgba(100, 100, 225, 0.25) 110px, rgba(0, 0, 0, 0) 110px, rgba(0, 0, 0, 0) 120px, rgba(100, 100, 225, 0.25) 120px, rgba(100, 100, 225, 0.25) 150px, rgba(0, 0, 0, 0) 150px, rgba(0, 0, 0, 0) 160px, rgba(100, 100, 225, 0.25) 160px, rgba(100, 100, 225, 0.25) 190px, rgba(0, 0, 0, 0) 190px, rgba(0, 0, 0, 0) 200px, rgba(100, 100, 225, 0.25) 200px, rgba(100, 100, 225, 0.25) 230px, rgba(0, 0, 0, 0) 230px, rgba(0, 0, 0, 0) 240px, rgba(100, 100, 225, 0.25) 240px, rgba(100, 100, 225, 0.25) 270px, rgba(0, 0, 0, 0) 270px, rgba(0, 0, 0, 0) 280px, rgba(100, 100, 225, 0.25) 280px, rgba(100, 100, 225, 0.25) 310px, rgba(0, 0, 0, 0) 310px, rgba(0, 0, 0, 0) 320px, rgba(100, 100, 225, 0.25) 320px, rgba(100, 100, 225, 0.25) 350px, rgba(0, 0, 0, 0) 350px, rgba(0, 0, 0, 0) 360px, rgba(100, 100, 225, 0.25) 360px, rgba(100, 100, 225, 0.25) 390px, rgba(0, 0, 0, 0) 390px, rgba(0, 0, 0, 0) 400px, rgba(100, 100, 225, 0.25) 400px, rgba(100, 100, 225, 0.25) 430px, rgba(0, 0, 0, 0) 430px, rgba(0, 0, 0, 0) 440px, rgba(100, 100, 225, 0.25) 440px, rgba(100, 100, 225, 0.25) 470px, rgba(0, 0, 0, 0) 470px, rgba(0, 0, 0, 0) 480px, rgba(100, 100, 225, 0.25) 480px, rgba(100, 100, 225, 0.25) 510px, rgba(0, 0, 0, 0) 510px, rgba(0, 0, 0, 0) 520px, rgba(100, 100, 225, 0.25) 520px, rgba(100, 100, 225, 0.25) 550px, rgba(0, 0, 0, 0) 550px, rgba(0, 0, 0, 0) 560px, rgba(100, 100, 225, 0.25) 560px, rgba(100, 100, 225, 0.25) 590px, rgba(0, 0, 0, 0) 590px, rgba(0, 0, 0, 0) 600px, rgba(100, 100, 225, 0.25) 600px, rgba(100, 100, 225, 0.25) 630px, rgba(0, 0, 0, 0) 630px, rgba(0, 0, 0, 0) 640px, rgba(100, 100, 225, 0.25) 640px, rgba(100, 100, 225, 0.25) 670px, rgba(0, 0, 0, 0) 670px, rgba(0, 0, 0, 0) 680px, rgba(100, 100, 225, 0.25) 680px, rgba(100, 100, 225, 0.25) 710px, rgba(0, 0, 0, 0) 710px, rgba(0, 0, 0, 0) 720px, rgba(100, 100, 225, 0.25) 720px, rgba(100, 100, 225, 0.25) 750px, rgba(0, 0, 0, 0) 750px, rgba(0, 0, 0, 0) 760px, rgba(100, 100, 225, 0.25) 760px, rgba(100, 100, 225, 0.25) 790px, rgba(0, 0, 0, 0) 790px, rgba(0, 0, 0, 0) 800px, rgba(100, 100, 225, 0.25) 800px, rgba(100, 100, 225, 0.25) 830px, rgba(0, 0, 0, 0) 830px, rgba(0, 0, 0, 0) 840px, rgba(100, 100, 225, 0.25) 840px, rgba(100, 100, 225, 0.25) 870px, rgba(0, 0, 0, 0) 870px, rgba(0, 0, 0, 0) 880px, rgba(100, 100, 225, 0.25) 880px, rgba(100, 100, 225, 0.25) 910px, rgba(0, 0, 0, 0) 910px, rgba(0, 0, 0, 0) 920px, rgba(100, 100, 225, 0.25) 920px, rgba(100, 100, 225, 0.25) 950px, rgba(0, 0, 0, 0) 950px, rgba(0, 0, 0, 0) 960px);
   background-size: 100% 18px, auto;
   background-position: left top;
 }
-/* line 4, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 4, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .feedback, body.bp .error, body.bp .alert, body.bp .notice, body.bp .success, body.bp .info {
   padding: 0.8em;
   margin-bottom: 1em;
   border: 2px solid #dddddd;
 }
-/* line 5, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 5, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .error, body.bp .alert {
   background: #fbe3e4;
   color: #8a1f11;
   border-color: #fbc2c4;
 }
-/* line 27, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 27, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .error a, body.bp .alert a {
   color: #8a1f11;
 }
-/* line 7, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 7, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .notice {
   background: #fff6bf;
   color: #514721;
   border-color: #ffd324;
 }
-/* line 36, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 36, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .notice a {
   color: #514721;
 }
-/* line 8, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 8, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .success {
   background: #e6efc2;
   color: #264409;
   border-color: #c6d880;
 }
-/* line 45, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 45, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .success a {
   color: #264409;
 }
-/* line 9, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 9, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .info {
   background: #d5edf8;
   color: #205791;
   border-color: #92cae4;
 }
-/* line 54, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 54, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .info a {
   color: #205791;
 }
-/* line 10, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 10, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .hide {
   display: none;
 }
-/* line 11, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 11, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .highlight {
   background: yellow;
 }
-/* line 12, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 12, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .added {
   background: #006600;
   color: white;
 }
-/* line 13, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
+/* line 13, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_interaction.scss */
 body.bp .removed {
   background: #990000;
   color: white;
 }
 
-/* line 18, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 18, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp label {
   font-weight: bold;
 }
-/* line 19, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 19, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp fieldset {
   padding: 1.4em;
   margin: 0 0 1.5em 0;
 }
-/* line 20, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 20, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp legend {
   font-weight: bold;
   font-size: 1.2em;
 }
-/* line 26, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 26, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp input.text, form.bp input.title, form.bp input[type=email], form.bp input[type=text], form.bp input[type=password] {
   margin: 0.5em 0;
   background-color: white;
   padding: 5px;
 }
-/* line 27, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 27, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp input.title {
   font-size: 1.5em;
 }
-/* line 29, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 29, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp textarea {
   margin: 0.5em 0;
   padding: 5px;
 }
-/* line 30, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 30, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp select {
   margin: 0.5em 0;
 }
-/* line 55, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 55, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp fieldset {
   border: 1px solid #cccccc;
 }
-/* line 58, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 58, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp input.text, form.bp input.title, form.bp input[type=email], form.bp input[type=text], form.bp input[type=password],
 form.bp textarea {
   background-color: #fff;
   border: 1px solid #bbbbbb;
 }
-/* line 61, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 61, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp input.text:focus, form.bp input.title:focus, form.bp input[type=email]:focus, form.bp input[type=text]:focus, form.bp input[type=password]:focus,
 form.bp textarea:focus {
   border-color: #666666;
 }
-/* line 65, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 65, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp select {
   background-color: #fff;
   border-width: 1px;
   border-style: solid;
 }
-/* line 44, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 44, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp input.text, form.bp input.title, form.bp input[type=email], form.bp input[type=text], form.bp input[type=password] {
   width: 300px;
 }
-/* line 46, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 46, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp textarea {
   width: 390px;
   height: 250px;
 }
-/* line 39, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
+/* line 39, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
 form.bp .box {
   padding: 1.5em;
   margin-bottom: 1.5em;
   background: #e5ecf9;
 }
-/* line 42, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
+/* line 42, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
 form.bp .border {
   padding-right: 4px;
   margin-right: 5px;
   border-right: 1px solid #dddddd;
 }
-/* line 45, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
+/* line 45, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
 form.bp .colborder {
   padding-right: 24px;
   margin-right: 25px;
   border-right: 1px solid #dddddd;
 }
-/* line 47, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
+/* line 47, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
 form.bp hr {
   background: #dddddd;
   color: #dddddd;
   margin: 0 0 1.45em;
   border: none;
 }
-/* line 49, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
+/* line 49, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
 form.bp hr.space {
   background: #dddddd;
   color: #dddddd;
   color: white;
   visibility: hidden;
 }
-/* line 51, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
+/* line 51, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_scaffolding.scss */
 form.bp form.inline {
   line-height: 3;
 }
-/* line 6, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_form.scss */
+/* line 6, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_form.scss */
 form.bp form.inline p {
   margin-bottom: 0;
 }
   margin-right: 10px;
   width: 950px;
 }
-/* line 147, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_grid.scss */
+/* line 147, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_grid.scss */
 * html body.two-col #header, * html body.two-col #footer {
   overflow-x: hidden;
 }
   margin-right: 10px;
   width: 310px;
 }
-/* line 147, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_grid.scss */
+/* line 147, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_grid.scss */
 * html body.two-col #sidebar {
   overflow-x: hidden;
 }
   margin-right: 0;
   width: 630px;
 }
-/* line 147, /Users/err8n/.rvm/gems/ruby-1.9.2-p290/gems/compass-0.11.5/frameworks/blueprint/stylesheets/blueprint/_grid.scss */
+/* line 147, /home/eric/.rvm/gems/ruby-1.9.3-p0/gems/compass-0.11.7/frameworks/blueprint/stylesheets/blueprint/_grid.scss */
 * html body.two-col #content {
   overflow-x: hidden;
 }

File bin/pytokenize.py

 
 
 Token = namedtuple('Token', 'text source raw offset length')
-reTOKEN = re.compile(r"\w+('+\w+)?")
+reTOKEN = re.compile(r"(\w+('+\w+)?)|(\S)")
 
 
 def get_files(args):
         for line in fin:
             for match in reTOKEN.finditer(line):
                 raw = match.group(0)
+                if not raw:
+                    raw = match.group(2)
+                if not raw:
+                    continue
                 (start, end) = match.span()
 
                 yield Token(

File lib/System/Bakers12/Enumerators.hs

+
+-- | Some utility Enumeratees used by the command-line program.
+
+module System.Bakers12.Enumerators
+    ( removeMissingFiles
+    , expandDirectories
+    , enumDirectory
+    ) where
+
+import           Control.Applicative
+import           Control.Monad
+import           Control.Monad.IO.Class
+import           Control.Monad.Trans (lift)
+import qualified Data.Enumerator as E
+import qualified Data.Enumerator.List as EL
+import           System.Directory
+import           System.FilePath
+
+
+-- | This is an Enumeratee that removes missing files from a stream of file
+-- names.
+removeMissingFiles :: MonadIO m => E.Enumeratee FilePath FilePath m b
+removeMissingFiles = EL.filterM (liftIO . exists)
+    where exists :: FilePath -> IO Bool
+          exists f = do
+            isFile <- doesFileExist f
+            isDir  <- doesDirectoryExist f
+            return (isFile || isDir)
+
+-- | This is an Enumeratee that expands directory names into all the files in
+-- that directory tree.
+expandDirectories :: MonadIO m => E.Enumeratee FilePath FilePath m b
+expandDirectories cont@(E.Continue k) = do
+    maybeFP <- EL.head
+    case maybeFP of
+        Just filePath -> do
+            isFile <- liftIO $ doesFileExist filePath
+            isDir  <- liftIO $ doesDirectoryExist filePath
+            case (isFile, isDir) of
+                (True, False)  -> do
+                    next <- lift $ E.runIteratee $ k $ E.Chunks [filePath]
+                    expandDirectories next
+                (False, True)  -> do
+                    next <- lift $ E.runIteratee $ k $ E.Chunks []
+                    expandDirectories next E.>>== enumDirectory filePath
+                _              -> do
+                    next <- lift $ E.runIteratee $ k $ E.Chunks []
+                    expandDirectories next
+        Nothing -> return cont
+expandDirectories step = return step
+
+-- | This returns an Enumerator that walks over a directory tree.
+--
+-- This is taken from http://www.mew.org/~kazu/proj/enumerator/.
+enumDirectory :: MonadIO m => FilePath -> E.Enumerator FilePath m b
+enumDirectory dirname = list
+    where
+        list (E.Continue k) = do
+            (files, dirs) <- liftIO getFilesDirs
+            if null dirs
+                then k (E.Chunks files)
+                else k (E.Chunks files) E.>>== walk dirs
+        list step = E.returnI step
+
+        walk dirs = foldr1 (E.<==<) $ map enumDirectory dirs
+
+        getFilesDirs = do
+            cnts <- map (dirname </>) <$> getValidContents dirname
+            (,) <$> filterM doesFileExist cnts
+                <*> filterM isSearchableDir cnts
+
+-- | This is also from http://www.mew.org/~kazu/proj/enumerator/, although it
+-- may have originally come from Real World Haskell.
+getValidContents :: FilePath -> IO [String]
+getValidContents path =
+    filter (`notElem` [".", ".."]) <$> getDirectoryContents path
+
+-- | Another function from http://www.mew.org/~kazu/proj/enumerator/ or RWH.
+isSearchableDir :: FilePath -> IO Bool
+isSearchableDir dirname =
+    (&&) <$> doesDirectoryExist dirname
+         <*> (searchable <$> getPermissions dirname)
+

File lib/Text/Bakers12/Csv.hs

+
+-- | This allows you to generate CSV from a number of data types. The
+-- conversion functions work in the context of a Data.Text.Lazy.Builder.
+
+module Text.Bakers12.Csv
+    ( CSVRow
+    , ToCSV(..)
+    , toCSVE
+    , escape
+    ) where
+
+import           Text.Bakers12.Csv.Enumerators
+import           Text.Bakers12.Csv.Types (CSVRow, ToCSV(..))
+import           Text.Bakers12.Csv.Utils
+

File lib/Text/Bakers12/Csv/Enumerators.hs

+
+-- | This defines some enumerators to take a stream of ToCSV instances and
+-- output a ByteString of CSV.
+
+module Text.Bakers12.Csv.Enumerators
+    ( toCSVE
+    ) where
+
+import           Control.Monad.Trans (lift)
+import           Data.Enumerator hiding (map)
+import qualified Data.Enumerator.List as EL
+import qualified Data.Text as T
+import           Text.Bakers12.Csv.Types
+
+-- | This takes a stream of ToCSV and outputs the Text of the CSV.
+toCSVE :: (ToCSV a, Monad m) => Enumeratee a T.Text m b
+toCSVE cont@(Continue k) = do
+    maybeItem <- EL.head
+    case maybeItem of
+        Just item -> do
+            next <- lift $ runIteratee $ k $ Chunks [toCSVText item]
+            toCSVE next
+        Nothing -> return cont
+toCSVE step = return step
+

File lib/Text/Bakers12/Csv/Types.hs

+
+-- | This handles the types required for Text.Bakers12.Csv conversion.
+
+module Text.Bakers12.Csv.Types
+    ( CSVRow
+    , ToCSV(..)
+    ) where
+
+import qualified Data.Text as T
+import           Text.Bakers12.Csv.Utils
+
+-- | This is the type of a row of CSV data.
+type CSVRow = [T.Text]
+
+-- | A type that can be converted to CSV.
+class ToCSV a where
+
+    -- | This handles actually converting a list of CSV 
+    toCSV :: a -> CSVRow
+
+    -- | This converts it to a Text. This has a default implementation, but you
+    -- can speed things up by defining it yourself (and not escaping every
+    -- field, for instance).
+    toCSVText :: a -> T.Text
+    toCSVText item = buildRow . map escape $ toCSV item
+
+instance ToCSV CSVRow where
+    toCSV = id
+

File lib/Text/Bakers12/Csv/Utils.hs

+
+-- | Utilities for working with CSV data.
+
+module Text.Bakers12.Csv.Utils
+    ( escape
+    , buildRow
+    ) where
+
+import qualified Data.Char as C
+import           Data.Monoid (mappend)
+import qualified Data.List as L
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+import qualified Data.Text.Lazy.Builder as TB
+
+-- | This handles escaping values.
+escape :: T.Text -> TB.Builder
+escape input = if T.any (not . C.isAlphaNum) input
+               then quote `mappend` (TB.fromText escaped `mappend` quote)
+               else TB.fromText input
+    where
+        quote   = TB.singleton '"'
+        escaped = T.replace (T.singleton '"') (T.pack "\"\"") input
+
+-- | This takes a list of Builders, one for each field, and assembles them into
+-- a CSV row. Basically, it just adds commas and a newline.
+buildRow :: [TB.Builder] -> T.Text
+buildRow row = TL.toStrict $ TB.toLazyText line
+    where 
+        comma = TB.singleton ','
+        nl    = TB.singleton '\n'
+        line  = foldr mappend nl . L.intersperse comma $ row
+

File lib/Text/Bakers12/JSON/Enumerators.hs

+{-# LANGUAGE OverloadedStrings #-}
+
+-- | This provides an enumerator interface over the aeson JSON library.
+
+module Text.Bakers12.JSON.Enumerators
+    ( toJSONE
+    ) where
+
+import           Control.Monad.Trans (lift)
+import           Data.Aeson (ToJSON(..))
+import           Data.Aeson.Encode (fromValue)
+import           Data.Enumerator hiding (map)
+import qualified Data.Enumerator.List as EL
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+import qualified Data.Text.Lazy.Builder as TLB
+
+-- | This takes a stream of ToJSON objects and interprets them as an array.  To
+-- do this, it breaks strict monad laws by outputting a '[' before starting to
+-- process the stream and by outputting a ']' when the stream is done.
+toJSONE :: (ToJSON a, Monad m) => Enumeratee a T.Text m b
+toJSONE = loop 0
+    where
+        loop n cont@(Continue k) = do
+            maybeItem <- EL.head
+
+            -- Ugly, ugly, ugly. There's probably something monadic I can do to
+            -- pretty it up.
+            case maybeItem of
+                Just item -> do
+                    let chunks = Chunks [prefix n, jsonize item]
+                    next <- lift $ runIteratee $ k $ chunks
+                    loop (n + 1) next
+                Nothing   ->
+                    case (suffix n) of
+                        Just close -> do
+                            next <- lift $ runIteratee $ k $ Chunks [close]
+                            loop 0 next
+                        Nothing    -> return cont
+
+        loop _ step = return step
+
+        prefix :: Int -> T.Text
+        prefix 0 = "["
+        prefix _ = ","
+
+        suffix :: Int -> Maybe T.Text
+        suffix 0 = Nothing
+        suffix _ = Just "]"
+
+        jsonize = TL.toStrict . TLB.toLazyText . fromValue . toJSON
+

File lib/Text/Bakers12/Tokenizer.hs

+
+{-|
+ - Module      : Text.Bakers12.Tokenizer
+ - License     : Apache 2.0
+ - Maintainer  : erochest@gmail.com
+ - Portability : GHC
+ - 
+ - This implements the tokenizer. It returns all tokens, without throwing any
+ - text away. That way, the unprocessed token stream can be used to re-create
+ - the input.
+ - 
+ - The processing uses the
+ - [enumerator](http://hackage.haskell.org/package/enumerator) library to
+ - produce a stream of tokens from a stream of input.
+ - 
+ - The `tokenize` and `tokenizeFile` functions hide this by accumulating the
+ - output tokens into a list and returning that.
+ -}
+
+module Text.Bakers12.Tokenizer
+    ( Token(..)
+    , TokenType(..)
+    , tokenize
+    , tokenizeFile
+    , tokenizeFileStream
+    , tokenizeStream
+    , tokenizeE
+    ) where
+
+import           Control.Exception (SomeException)
+import           Control.Monad (liftM)
+import           Control.Monad.Trans (lift)
+import qualified Data.Char as C
+import qualified Data.Enumerator as E
+import qualified Data.Enumerator.Binary as EB
+import qualified Data.Enumerator.List as EL
+import qualified Data.Enumerator.Text as ET
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as LT
+import           Text.Bakers12.Tokenizer.Types
+
+-- | This reads text from an instance of Data.Text.Text and returns a list of
+-- Token instances.
+tokenize :: FilePath -> T.Text -> Either SomeException [Token]
+tokenize source input =
+    E.runLists [[input]] (tokenizeStream source 0 E.=$ EL.consume)
+
+-- | This reads the input from a file and returns a list of Token instances.
+tokenizeFile :: FilePath -> IO (Either SomeException [Token])
+tokenizeFile inputFile =
+    E.run (tokenizeFileStream inputFile E.$$ EL.consume)
+
+-- | This creates an Enumerator that reads from a file and produces Tokens.
+--
+-- This assumes that the files are UTF8.
+tokenizeFileStream :: FilePath -> E.Enumerator Token IO b
+tokenizeFileStream inputFile =
+    EB.enumFile inputFile E.$=
+    ET.decode ET.utf8 E.$=
+    tokenizeStream inputFile 0
+
+-- | This is an Enumeratee that takes a FilePath and returns a Enumerator of
+-- Tokens.
+tokenizeE :: E.Enumeratee FilePath Token IO b
+tokenizeE cont@(E.Continue _) = do
+    maybeFP <- EL.head
+    case maybeFP of
+        Just filePath -> tokenizeFileStream filePath cont E.>>== tokenizeE
+        Nothing -> return cont
+tokenizeE step = return step
+
+-- | This is an Enumeratee that takes a stream of Char and transforms it into a
+-- stream of Token.
+tokenizeStream :: Monad m =>
+                  FilePath -> Integer -> E.Enumeratee T.Text Token m b
+tokenizeStream source offset cont@(E.Continue k) = do
+    maybeC <- ET.head
+    case maybeC of
+        Just c  -> do
+            token <- tokenize' source offset c
+            next  <- lift $ E.runIteratee $ k $ E.Chunks [token]
+            tokenizeStream source (offset + fromIntegral (tokenLength token)) next
+        Nothing -> return cont
+tokenizeStream _ _ step = return step
+
+-- | This takes a character and dispatches the handle the tokenizing the rest
+-- of the token from it.
+tokenize' :: Monad m => FilePath -> Integer -> Char -> E.Iteratee T.Text m Token
+tokenize' source offset c
+    | C.isAlpha c       = tokenFromTaken source offset AlphaToken c C.isAlpha
+    | C.isNumber c      = tokenFromTaken source offset NumberToken c C.isNumber
+    | isSeparator c     = tokenFromTaken source offset SeparatorToken c isSeparator
+    | C.isPunctuation c = return . makeToken source offset PunctuationToken $ T.singleton c
+    | C.isSymbol c      = return . makeToken source offset SymbolToken $ T.singleton c
+    | C.isMark c        = return . makeToken source offset MarkToken $ T.singleton c
+    | otherwise         = return . makeToken source offset UnknownToken $ T.singleton c
+
+-- | This is an augmented separator predicate that also tests for spaces.
+isSeparator :: Char -> Bool
+isSeparator c = C.isSpace c || C.isSeparator c
+
+-- | This runs takeWhile with the predicate, conses the initial element to the
+-- front, and creates a Token of the given type.
+tokenFromTaken :: Monad m   
+               => FilePath                      -- ^ tokenSource
+               -> Integer                       -- ^ tokenOffset
+               -> TokenType                     -- ^ tokenType
+               -> Char                          -- ^ Initial character.
+               -> (Char -> Bool)                -- ^ Predicate for taking the
+                                                -- rest of the token.
+               -> E.Iteratee T.Text m Token
+tokenFromTaken source offset tType initial predicate =
+    liftM (makeToken source offset tType . LT.toStrict . LT.cons initial)
+          (ET.takeWhile predicate)
+
+-- | In the context of an Enumerator, this takes a [Char] list and returns a
+-- Token.
+makeToken :: FilePath -> Integer -> TokenType -> T.Text -> Token
+makeToken source offset tType raw =
+    Token normalized raw rawLength tType source offset
+    where
+        normalized = normalizeToken raw
+        rawLength  = T.length raw
+
+-- | This takes a raw token Text and returns a normalized version. Currently,
+-- this just lower-cases everything.
+normalizeToken :: T.Text -> T.Text
+normalizeToken = T.map C.toLower
+

File lib/Text/Bakers12/Tokenizer/Csv.hs

+
+-- | This turns a Token into a CSVRow
+
+module Text.Bakers12.Tokenizer.Csv
+    (
+    ) where
+
+import qualified Data.Text as T
+import qualified Data.Text.Lazy.Builder as TB
+import qualified Data.Text.Lazy.Builder.Int as TBI
+import           Text.Bakers12.Csv.Types
+import           Text.Bakers12.Csv.Utils
+import           Text.Bakers12.Tokenizer.Types
+
+instance ToCSV Token where
+    toCSV (Token text raw len typ src offs) =
+        [ text
+        , raw
+        , showText len
+        , showText typ
+        , T.pack src
+        , showText offs
+        ]
+        where
+            showText :: Show a => a -> T.Text
+            showText = T.pack . show
+
+    toCSVText (Token text raw len typ src offs) = buildRow row
+        where
+            row = [ escape text
+                  , escape raw
+                  , TBI.decimal len
+                  , fromShow typ
+                  , TB.fromString src
+                  , TBI.decimal offs
+                  ] 
+            fromShow = TB.fromString . show

File lib/Text/Bakers12/Tokenizer/JSON.hs

+{-# LANGUAGE OverloadedStrings #-}
+
+-- | This just defines Token and TokenType as instances of ToJSON.
+
+module Text.Bakers12.Tokenizer.JSON
+    () where
+
+import Data.Aeson (ToJSON(..), object, (.=))
+import Text.Bakers12.Tokenizer.Types (Token(..), TokenType(..))
+
+instance ToJSON Token where
+    toJSON (Token text raw len typ src offs) =
+        object [ "text"   .= text
+               , "raw"    .= raw
+               , "length" .= len
+               , "type"   .= typ
+               , "source" .= src
+               , "offset" .= offs
+               ]
+
+instance ToJSON TokenType where
+    toJSON = toJSON . show
+

File lib/Text/Bakers12/Tokenizer/Minimal.hs

+
+-- |
+-- Module: Text.Bakers12.Tokenizer.Minimal
+-- License: Apache 2.0
+-- Maintainer: erochest@gmail.com
+-- Portability: GHC
+--
+-- This is a minimal tokenizer. It just removes whitespace and separators from
+-- the token stream.
+
+module Text.Bakers12.Tokenizer.Minimal
+    ( Token(..)
+    , TokenType(..)
+    , tokenize
+    , tokenizeFile
+    , tokenizeFileStream
+    , minimalFilter
+    ) where
+
+import           Control.Exception (SomeException)
+import qualified Data.Enumerator as E
+import qualified Data.Enumerator.List as EL
+import qualified Data.Text as T
+import qualified Text.Bakers12.Tokenizer as B12
+import           Text.Bakers12.Tokenizer.Types hiding (append, concat)
+
+-- | This reads text from an instsance of Data.Text.Text and returns a list of
+-- Token instances.
+tokenize :: FilePath -> T.Text -> Either SomeException [Token]
+tokenize source input =
+    E.runLists [[input]] process
+    where process = B12.tokenizeStream source 0 E.=$ minimalFilter E.=$ EL.consume
+
+-- | This reads the input from a file and returns a list of Token instances.
+tokenizeFile :: FilePath -> IO (Either SomeException [Token])
+tokenizeFile inputFile =
+    E.run (B12.tokenizeFileStream inputFile E.$= minimalFilter E.$$ EL.consume)
+
+-- | This creates an Enumerator that reads from a file and produces Tokens.
+--
+-- This assumes the files are UTF8.
+tokenizeFileStream :: FilePath -> E.Enumerator Token IO b
+tokenizeFileStream inputFile =
+    B12.tokenizeFileStream inputFile E.$= minimalFilter
+
+-- | This is an enumeratee that filters a token stream created by
+-- Text.Bakers12.Tokenizer and basically just removes the whitespace and
+-- separator characters from it.
+minimalFilter :: Monad m => E.Enumeratee Token Token m b
+minimalFilter = EL.filter ((SeparatorToken /=) . tokenType)
+

File lib/Text/Bakers12/Tokenizer/PennTreebank.hs

+
+-- |
+-- Module: Text.Bakers12.Tokenizer.PennTreebank
+-- License : Apache 2.0
+-- Maintainer: erochest@gmail.com
+-- Portability: GHC
+--
+-- This filters the tokens output by Text.Bakers12.Tokenizer to make them
+-- conform to the Penn Treebank tokenizer, more or less.
+--
+-- /More or less/ because this doesn't attempt to handle end-of-sentence
+-- punctuation correctly. The original tokenizer required that each sentence be
+-- on its own line. This doesn't use that.
+
+module Text.Bakers12.Tokenizer.PennTreebank
+    ( Token(..)
+    , TokenType(..)
+    , tokenize
+    , tokenizeFile
+    , tokenizeFileStream
+    , pennFilter
+    ) where
+
+import           Control.Exception (SomeException)
+import           Control.Monad.Trans (lift)
+import qualified Data.Enumerator as E
+import qualified Data.Enumerator.List as EL
+import qualified Data.List as L
+import qualified Data.Text as T
+import qualified Text.Bakers12.Tokenizer as B12
+import           Text.Bakers12.Tokenizer.Types hiding (append, concat)
+import qualified Text.Bakers12.Tokenizer.Types as Tkn
+
+-- | This reads text from an instance of Data.Text.Text and returns a list of
+-- Token instances.
+tokenize :: FilePath -> T.Text -> Either SomeException [Token]
+tokenize source input =
+    E.runLists [[input]] process
+    where process = B12.tokenizeStream source 0 E.=$ pennFilter E.=$ EL.consume
+
+-- | This reads the input from a file and returns a list of Token instances.
+tokenizeFile :: FilePath -> IO (Either SomeException [Token])
+tokenizeFile inputFile =
+    E.run (B12.tokenizeFileStream inputFile E.$= pennFilter E.$$ EL.consume)
+
+-- | This creates an Enumerator that reads from a file and produces Tokens.
+--
+-- This assumes that the files are UTF8.
+tokenizeFileStream :: FilePath -> E.Enumerator Token IO b
+tokenizeFileStream inputFile =
+    B12.tokenizeFileStream inputFile E.$= pennFilter
+
+{- -- | This does some debugging tokenization. -}
+{- tokenizeD :: FilePath -> T.Text -> IO (Either SomeException ()) -}
+{- tokenizeD source input = -}
+    {- E.run process -}
+    {- where process = E.enumList 1 [input] E.$= B12.tokenizeStream source 0 -}
+                    {- E.$= pennFilterIO -}
+                    {- E.$$ E.printChunks True -}
+                    {- -- E.$$ EL.consume -}
+
+{- -- | This is an enumeratee that filters a token stream created by -}
+{- -- Text.Bakers12.Tokenizer and makes it conform to the Penn Treebank tokenizer, -}
+{- -- more or less. -}
+{- pennFilterIO :: E.Enumeratee Token Token IO b -}
+{- pennFilterIO cont@(E.Continue k) = do -}
+    {- toDrop <- EL.takeWhile isSeparator -}
+    {- lift . putStrLn . ("DROP " ++) $ show toDrop -}
+    {- chunk <- EL.takeWhile (not . isSeparator) -}
+    {- lift . putStrLn . ("TAKE " ++) $ show chunk -}
+    {- if null chunk -}
+    {- then return cont -}
+    {- else do -}
+        {- next  <- lift . E.runIteratee . k . E.Chunks $ penn chunk -}
+        {- pennFilterIO next -}
+    {- where isSeparator = (SeparatorToken ==) . tokenType -}
+{- pennFilterIO step = return step -}
+
+-- | This is an enumeratee that filters a token stream created by
+-- Text.Bakers12.Tokenizer and makes it conform to the Penn Treebank tokenizer,
+-- more or less.
+pennFilter :: Monad m => E.Enumeratee Token Token m b
+pennFilter cont@(E.Continue k) = do
+    EL.dropWhile isSeparator
+    chunk <- EL.takeWhile (not . isSeparator)
+    case chunk of
+        [] -> return cont
+        _  -> do
+            next  <- lift . E.runIteratee . k . E.Chunks $ penn chunk
+            pennFilter next
+    where isSeparator = (SeparatorToken ==) . tokenType
+pennFilter step = return step
+
+-- | This actually handles breaking everything apart and putting it back
+-- together.
+penn :: [Token] -> [Token]
+penn (t:ts)
+    | tokenText t == T.pack "\"" && L.all (not . isReadable) ts =
+        t { tokenText = T.pack "''" } : penn ts
+    | tokenText t == T.pack "\"" = t { tokenText = T.pack "``" } : penn ts
+    -- brackets of various sorts.
+    | T.singleton '(' == tokenText t = t { tokenText = T.pack "-LRB-" } : penn ts
+    | T.singleton ')' == tokenText t = t { tokenText = T.pack "-RRB-" } : penn ts
+    | T.singleton '[' == tokenText t = t { tokenText = T.pack "-LSB-" } : penn ts
+    | T.singleton ']' == tokenText t = t { tokenText = T.pack "-RSB-" } : penn ts
+    | T.singleton '{' == tokenText t = t { tokenText = T.pack "-LCB-" } : penn ts
+    | T.singleton '}' == tokenText t = t { tokenText = T.pack "-RCB-" } : penn ts
+    -- Run-ons.
+    | tokenText t `elem` runOns = tsplit 3 t ++ penn ts
+    where tsplit n tkn = let (t1, t2) = Tkn.splitAt n tkn
+                         in  [t1, t2]
+          runOns = map T.pack ["cannot", "gimme", "gonna", "gotta", "lemme", "wanna"]
+penn (t1:t2:ts)
+    | (tokenText t1 == dash) && (tokenText t2 == dash) =
+        Tkn.append t1 t2 : penn ts
+    | squote == tokenText t1 && tokenText t2 `elem` contractions =
+        Tkn.append t1 t2 : penn ts
+    | squote == tokenText t1 && tokenText t2 `elem` tcontractions =
+        let (ttoken, trest) = Tkn.splitAt 1 t2
+        in  Tkn.append t1 ttoken : trest : penn ts
+    where dash          = T.singleton '-'
+          squote        = T.pack "'"
+          contractions  = map T.pack ["s", "ll", "m", "d", "re", "ve"]
+          tcontractions = map T.pack ["tis", "twas"]
+penn (t1:t2:t3:ts)
+    | L.all (dot ==) . map tokenText $ take3 =
+        Tkn.concat take3 : penn ts
+    | T.last (tokenText t1) == n && tokenText t2 == squote && tokenText t3 == t =
+        t1 { tokenText = T.init $ tokenText t1 } : nt : penn ts
+    | tokenText t1 == d && tokenText t2 == squote && tokenText t3 == ye =
+        Tkn.append t1 t2 : t3 : penn ts
+    | tokenText t1 == more && tokenText t2 == squote && tokenText t3 == textn =
+        t1 : Tkn.append t2 t3 : penn ts
+    where dot    = T.singleton '.'
+          squote = T.pack "'"
+          d      = T.singleton 'd'
+          n      = 'n'
+          textn  = T.singleton n
+          t      = T.singleton 't'
+          ye     = T.pack "ye"
+          more   = T.pack "more"
+          nt     = t2 { tokenText   = T.pack "n't"
+                      , tokenRaw    = T.pack "n't"
+                      , tokenLength = 3
+                      , tokenOffset = tokenOffset t2 - 1
+                      }
+          take3  = [t1, t2, t3]
+penn (t:ts) = t : penn ts
+penn []     = []
+

File lib/Text/Bakers12/Tokenizer/Types.hs

+
+-- |
+-- Module      : Text.Bakers12.Tokenizer.Types
+-- License     : Apache 2.0
+-- Maintainer  : erochest@gmail.com
+-- Portability : GHC
+--
+-- This defines the types for the tokenizers. Especially, this defines the
+-- Token and TokenType data types.
+
+module Text.Bakers12.Tokenizer.Types
+    ( Token(..)
+    , TokenType(..)
+    , empty
+    , isReadable
+    , append
+    , concat
+    , splitAt
+    ) where
+
+import qualified Data.List as L
+import qualified Data.Text as T
+import           Prelude hiding (concat, splitAt)
+
+-- * Token Type
+
+-- | This contains data from one token instance.
+data Token = Token
+    { tokenText   :: T.Text         -- ^ The normalized token text.
+    , tokenRaw    :: T.Text         -- ^ The raw token text.
+    , tokenLength :: Int            -- ^ The length of the raw token.
+    , tokenType   :: TokenType      -- ^ The type of data contained in the
+                                    -- token.
+    , tokenSource :: FilePath       -- ^ The source (sometimes a file) that
+                                    -- the token was found in.
+    , tokenOffset :: Integer        -- ^ The character offset of the start of
+                                    -- the token in the source (zero-indexed).
+    }
+    deriving (Eq, Show)
+
+-- | This has the types of information that a token can contain.
+data TokenType =
+      AlphaToken                    -- ^ Unicode alphabetic characters.
+    | NumberToken                   -- ^ Unicode numeric characters.
+    | SeparatorToken                -- ^ Unicode space or Unicode separator
+                                    -- character.
+    | PunctuationToken              -- ^ One Unicode punctuation character.
+    | SymbolToken                   -- ^ One Unicode symbol character.
+    | MarkToken                     -- ^ One Unicode mark character.
+    | UnknownToken                  -- ^ None of the categories above.
+    deriving (Eq, Show)
+
+-- | This is an empty token.
+empty :: Token
+empty = Token T.empty T.empty 0 UnknownToken "" 0
+
+-- | This tests whether a token is "readable." I.e., whether its type is
+-- AlphaToken or NumberToken.
+isReadable :: Token -> Bool
+isReadable token = tType == AlphaToken || tType == NumberToken
+    where tType = tokenType token
+
+-- | This takes two tokens (presumably right next to each other in the input
+-- stream, although this doesn't verify that) and concatenates them by
+-- concatenating their text and raw data and their lengths.
+append :: Token -> Token -> Token
+append a b =
+    a { tokenText   = T.append (tokenText a) (tokenText b)
+      , tokenRaw    = T.append (tokenRaw a) (tokenRaw b)
+      , tokenLength = tokenLength a + tokenLength b
+      }
+
+-- | This takes a list of tokens and appends them. Like append above, it
+-- assumes that the tokens occur right next to each other.
+--
+-- The implementation of this could use fold, but I thought that using T.concat
+-- and not constructing any intermediate Tokens would be faster.
+concat :: [Token] -> Token
+concat []       = empty
+concat [t]      = t
+concat [t1, t2] = append t1 t2
+concat ts@(a:_) =
+    a { tokenText   = T.concat texts
+      , tokenRaw    = T.concat raws
+      , tokenLength = sum lengths
+      }
+    where
+        -- Another small optimization, so we don't have to walk the input list
+        -- more than once. If these operations can be fused, that would be
+        -- best, but even just walking the list twice is better than walking it
+        -- three times. (Best would be to write unzipWith3 or something, which
+        -- would insure that the list was only walked twice. Someday.)
+        (texts, raws, lengths) = L.unzip3 . map getFields $ ts
+        getFields t = (tokenText t, tokenRaw t, tokenLength t)
+