diff --git a/Cookbook/Essential/IO.hs b/Cookbook/Essential/IO.hs
--- a/Cookbook/Essential/IO.hs
+++ b/Cookbook/Essential/IO.hs
@@ -1,21 +1,33 @@
 --Cookbook.Essential.IO
 --IO is the only Cookbook library to import System modules. As the name states, Cookbook.IO makes IO
 --easier and less error-prone by wrapping common IO "gotchas" in a function.
-module Cookbook.Essential.IO(filelines,prompt) where
+module Cookbook.Essential.IO(filelines,prompt,inhome,getHomePath) where
 
-import  System.IO
+import qualified System.IO as LIO
+import  qualified System.IO.Strict as SIO
 import System.Environment
+import System.Directory
 
 -- | Returns the lines of a file, wrapped in an IO.
 filelines :: String -> IO ([String])
 filelines x = do
-  y <- openFile x ReadMode
-  yc <- hGetContents y
+  y <- LIO.openFile x LIO.ReadMode
+  yc <- SIO.hGetContents y
   return (lines yc)
 
 -- | Prompts the user for a string
 prompt :: String -> IO (String)
 prompt x = do
     putStr x
-    hFlush stdout
+    LIO.hFlush LIO.stdout
     getLine
+
+inhome :: String -> LIO.IOMode -> IO (LIO.Handle)
+inhome x  c = do
+  home <- getHomeDirectory
+  LIO.openFile (home ++ x) c
+
+getHomePath :: String -> IO (String)
+getHomePath x = do
+  home <- getHomeDirectory
+  return (home ++ x)
diff --git a/Cookbook/Ingredients/Functional/Break.hs b/Cookbook/Ingredients/Functional/Break.hs
--- a/Cookbook/Ingredients/Functional/Break.hs
+++ b/Cookbook/Ingredients/Functional/Break.hs
@@ -4,7 +4,7 @@
 --untrue value. As an addition to this library are functions relating to
 --mapping predicates over lists to yield either a different result or one solution.
 
-module Cookbook.Ingredients.Functional.Break(removeBreak, filterBreak,btr,imbreak) where
+module Cookbook.Ingredients.Functional.Break(removeBreak, filterBreak,btr,imbreak,splitBool) where
 
 -- | When the predicate returns false, removeBreak returns the rest of the list.
 removeBreak :: (a -> Bool) -> [a] -> [a]
@@ -23,3 +23,10 @@
 -- | Conditionally transform input based on the predicate. When it is true, fst of the tupple is used, snd otherwise.
 btr :: (a -> Bool) -> (b,b) -> [a] -> [b]
 btr f (a,b) = map (\c -> if f c then a else b)
+
+
+splitBool :: (Eq a) => (a -> Bool) -> [a] -> [[a]]
+splitBool _ [] = []
+splitBool f c = filter (/= []) (fP: if fP /= [] then (splitBool f tP) else [])
+  where fP = filterBreak f c
+        tP = removeBreak f c
diff --git a/Cookbook/Ingredients/Lists/Access.hs b/Cookbook/Ingredients/Lists/Access.hs
--- a/Cookbook/Ingredients/Lists/Access.hs
+++ b/Cookbook/Ingredients/Lists/Access.hs
@@ -1,7 +1,7 @@
 --Cookbook.Ingredients.Lists.Access
 --Access is a library for generating statistics about a list. The lists are not changed as a result
 --of executing any Access function.
-module Cookbook.Ingredients.Lists.Access(count,contains,qsort,pull,refpos,areAll,isBefore) where
+module Cookbook.Ingredients.Lists.Access(count,contains,qsort,pull,refpos,areAll,isBefore,surrounds) where
 
 import qualified Cookbook.Ingredients.Functional.Break as Br
 
@@ -40,3 +40,6 @@
 -- | Is the list a prefix of another?
 isBefore :: (Eq a) => [a] -> [a] -> Bool
 isBefore li tf = take (length tf) li == tf
+
+surrounds :: (Eq a) => (a,a) -> [a] -> Bool
+surrounds (b,c) a = (head a, last a) == (b,c)
diff --git a/Cookbook/Ingredients/Lists/Modify.hs b/Cookbook/Ingredients/Lists/Modify.hs
--- a/Cookbook/Ingredients/Lists/Modify.hs
+++ b/Cookbook/Ingredients/Lists/Modify.hs
@@ -1,11 +1,13 @@
 --Cookbook.Ingredients.Lists.Modify
 --Library for altering the contents of a list.
 
-module Cookbook.Ingredients.Lists.Modify(rev,rm,splitOn,snipe,insert,between) where
+module Cookbook.Ingredients.Lists.Modify(rev,rm,splitOn,snipe,insert,between,linesBetween) where
 
 import qualified Cookbook.Essential.Continuous as Cnt
 import qualified Cookbook.Essential.Common as Cm
 
+import qualified Cookbook.Ingredients.Functional.Break as Br
+import qualified Cookbook.Ingredients.Lists.Access as Ac
 -- | Reverses a list
 rev :: [a] -> [a]
 rev [] = []
@@ -29,7 +31,11 @@
 insert x (t,c) = (take c x) ++ t ++ (Cm.sub x c)
 
 -- | Find out what is in between two elements of a list
-between a (c,d) = Cnt.after (Cnt.before a d) c
+between :: (Eq a) => [a] -> (a,a) -> [a]
+between a (c,d) = Cnt.after (take (last $ Cm.positions a d) a) c
+
+linesBetween :: (Eq a) => [[a]] -> ([a],[a]) -> [[a]]
+linesBetween a (c,d) = tail $ Br.filterBreak (\e -> not $ Ac.contains e d) $ Br.removeBreak (\e -> not $ Ac.contains e c) a
 
 -- | Intersperse elements into a list.
 intersperse :: [a] -> a -> [a]
diff --git a/Cookbook/Ingredients/Tupples/Look.hs b/Cookbook/Ingredients/Tupples/Look.hs
--- a/Cookbook/Ingredients/Tupples/Look.hs
+++ b/Cookbook/Ingredients/Tupples/Look.hs
@@ -1,7 +1,7 @@
 --Cookbook.Ingredients.Tupples.Look
 --This library is for manipulating and searching lists of two-element tupples.
 
-module Cookbook.Ingredients.Tupples.Look(look,lookList,swp) where
+module Cookbook.Ingredients.Tupples.Look(look,lookList,swp,rmLook,group) where
 
 -- | Returns the second element of the first tupple where the first element matches input.
 look :: (Eq a) => [(a,b)] -> a -> (Maybe b)
@@ -15,3 +15,14 @@
 -- | Swap the order of a second-degree tupple.
 swp :: (a,b) -> (b,a)
 swp    (a,b)  = (b,a)
+
+-- | Reverse this.look. Will remove any matches.
+rmLook :: (Eq a) => [(a,b)] -> a -> [(a,b)]
+rmLook [] _ = []
+rmLook ((a,b):cs) d = if a == d then cs else (a,b) : rmLook cs d
+
+-- | Turn a list into as many bifold tupples as possible.
+group :: [a] -> [(a,a)]
+group [] = []
+group [x] = []
+group (x:y:z) = (x,y) : group z
diff --git a/Cookbook/Project/Configuration/Configuration.hs b/Cookbook/Project/Configuration/Configuration.hs
--- a/Cookbook/Project/Configuration/Configuration.hs
+++ b/Cookbook/Project/Configuration/Configuration.hs
@@ -1,3 +1,5 @@
+--Cookbook.Project.Configuration.Configuration (Cf)
+-- Cf is a library for reading very simple configuration files.
 module Cookbook.Project.Configuration.Configuration(conf) where
 import qualified Cookbook.Ingredients.Lists.Modify as Md
 import qualified Cookbook.Ingredients.Tupples.Look as Lk
diff --git a/Cookbook/Project/Groups/Groups.hs b/Cookbook/Project/Groups/Groups.hs
--- a/Cookbook/Project/Groups/Groups.hs
+++ b/Cookbook/Project/Groups/Groups.hs
@@ -5,7 +5,7 @@
 
 import qualified Cookbook.Ingredients.Lists.Modify as Md
 import qualified Cookbook.Ingredients.Tupples.Look as Lk
-import qualified Cookbook.Essential.Continuous as Ct
+import qualified Cookbook.Essential.Continuous     as Ct
 
 type Constructor = (String,[String])
 
diff --git a/Cookbook/Project/Scribe/Scribe.hs b/Cookbook/Project/Scribe/Scribe.hs
new file mode 100644
--- /dev/null
+++ b/Cookbook/Project/Scribe/Scribe.hs
@@ -0,0 +1,105 @@
+--Cookbook.Project.Scribe
+--Scribe is a tool for communicating with SCRIBE databases.
+module Cookbook.Project.Scribe.Scribe(
+  Frame(..),Column,Row,Table,Database,
+  isRow,isColumn,isFrame,isTable,
+  makeName,
+  parseFrame,parseColumn,parseRow,parseTable,
+  readColumn,readRow,readTable,readDatabase,
+  getTable,getRow,getColumn,getFrame,
+  qGetRow,qGetColumn,qGetFrame) where
+
+import qualified Cookbook.Essential.Common             as Cm
+import qualified Cookbook.Essential.Continuous         as Ct
+import qualified Cookbook.Ingredients.Lists.Modify     as Md
+import qualified Cookbook.Ingredients.Lists.Access     as Ac
+import qualified Cookbook.Ingredients.Tupples.Look     as Lk
+import qualified Cookbook.Ingredients.Functional.Break as Br
+import qualified Cookbook.Recipes.Sanitize             as St
+
+--Data
+data Frame = Frame {keyval :: String, entry :: String} | Promise {keyval :: String, link :: String}  deriving (Eq,Show)
+
+--Type synonyms
+type Column = (String,[Frame])
+type Row = (String,[Column])
+type Table = (String,[Row])
+type Database = [Table]
+
+--Standard information
+isRow     x = and [x `Ac.contains` "row",    length x > 4]
+isColumn  x = and [x `Ac.contains` "column", length x > 4]
+isFrame   x = and $ map ((flip elem) x) "<>"
+isTable   x = and [x `Ac.contains` "table",length x > 4]
+
+makeName :: String -> String -> String
+makeName a b = St.blacklist (Ct.after a b) "{ "
+
+--Parsing
+parseFrame :: String -> Frame
+parseFrame x | not $ isFrame x = error (x ++ " was passed to parseFrame, but does not conform to standard.")
+parseFrame x
+  | ('-','-') `Ac.surrounds` inner = Promise {keyval = Md.between inner ('-','-'), link = Ct.after x '>'}
+  | otherwise = Frame {keyval = inner, entry = Ct.after x '>'} -- Surrounded in <-->? It's a link.
+  where inner = Md.between x ('<','>')
+
+parseColumn :: (String,[String]) -> Column -- Expects the column declaration, and the relevant lines.
+parseColumn (a,b) = (makeName a "column ",map parseFrame b)
+
+parseRow :: (String,[(String,[String])]) -> Row
+parseRow (a,b) = (makeName a "row ",map parseColumn b)
+
+parseTable :: (String,[(String,[(String,[String])])]) -> Table
+parseTable (a,b) = (makeName a "table ",map parseRow b)
+
+--Reading
+readColumn :: [String] -> (String,[String])
+readColumn [] = error "Column either does not exist or does not conform to standards."
+readColumn (x:xs) | not  $ isColumn x = readColumn xs
+readColumn (x:xs) = (x,Md.linesBetween (x:xs) ("{","}"))
+
+readRow :: [String] -> (String,[(String,[String])])
+readRow [] = error "Row either does not exist or does not conform to standards."
+readRow (x:xs) | not $ isRow x = readRow xs
+readRow (x:xs) = (x, map readColumn splitup)
+  where splitup = Br.splitBool (\c -> not $ c `Ac.contains` "}") rowScope
+        rowScope = Md.linesBetween (x:xs) ("{","}}")
+
+readTable :: [String] -> (String,[(String,[(String,[String])])])
+readTable [] = error "Table either does not exist or does not conform to standards."
+readTable (x:xs) | not $ isTable x = readTable xs
+readTable (x:xs) = (x,map readRow splitup)
+  where splitup = Br.splitBool (\c -> not $ c `Ac.contains` "}}") tableScope;
+        tableScope = Md.linesBetween (x:xs) ("{","}}}")
+
+--Final functions
+readDatabase :: [String] -> Database
+readDatabase (x:xs)
+  | isTable x = parseTable (readTable (x:xs)) : readDatabase (Ct.after xs "}}}")
+  | otherwise = readDatabase xs
+
+--Accessors
+getTable :: String -> Database -> Table
+getTable a b = (a,(head $ Lk.lookList b a))
+
+getRow :: (String,String) -> Database -> Row
+getRow (a,b) c = (b,head $ Lk.lookList (snd (getTable a c)) b)
+
+getColumn :: (String,String,String) -> Database -> Column
+getColumn (a,b,c) d = (c,head $ Lk.lookList (snd (getRow (a,b) d)) c)
+
+getFrame :: (String,String,String,String) -> Database -> Frame
+getFrame (a,b,c,d) e = let frames = (snd $ getColumn (a,b,c) e) in head $ Lk.lookList (zip (map keyval frames) frames) d
+
+--Shorthand accessors
+qGetRow :: String -> Database -> Row
+qGetRow x z= getRow (a,b) z
+  where (a,b) = let (f:g:[]) = Md.splitOn x '.' in (f,g)
+
+qGetColumn :: String -> Database -> Column
+qGetColumn x z = getColumn (a,b,c) z
+  where (a,b,c) = let (f:g:h:[]) = Md.splitOn x '.' in (f,g,h)
+
+qGetFrame :: String -> Database -> Frame
+qGetFrame x z = getFrame (a,b,c,d) z
+  where (a,b,c,d) = let (f:g:h:j:[]) = Md.splitOn x '.' in (f,g,h,j)
diff --git a/Cookbook/Recipes/Text.hs b/Cookbook/Recipes/Text.hs
new file mode 100644
--- /dev/null
+++ b/Cookbook/Recipes/Text.hs
@@ -0,0 +1,13 @@
+--Cookbook.Recipes.Text
+--A library with the sole purpose of manipulating lists of strings.
+
+module Cookbook.Recipes.Text(linesBetween) where
+
+import qualified Cookbook.Essential.Continuous as Ct
+import qualified Cookbook.Ingredients.Tupples.Look as Lk
+import qualified Cookbook.Ingredients.Lists.Access as Ac
+import qualified Cookbook.Ingredients.Functional.Break as Br
+
+linesBetween :: [String] -> (String,String) -> [String]
+linesBetween x (c,d) = tail $ Br.filterBreak ( notContaining d) $ Br.removeBreak ( notContaining c) x
+  where notContaining e l = not $ l `Ac.contains` e
diff --git a/cookbook.cabal b/cookbook.cabal
--- a/cookbook.cabal
+++ b/cookbook.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             1.1.0.1
+version:             1.3.0.0
 
 -- A short (one-line) description of the package.
 synopsis:            A delicious set of interdependant libraries.
@@ -39,6 +39,7 @@
 
 category:            Development
 
+
 build-type:          Simple
 
 -- Constraint on the version of Cabal needed to build this package.
@@ -47,11 +48,11 @@
 
 library
   -- Modules exported by the library.
-  exposed-modules:     Cookbook.Essential.Common, Cookbook.Essential.Continuous, Cookbook.Essential.IO, Cookbook.Recipes.DiffStat, Cookbook.Project.Configuration.Configuration, Cookbook.Ingredients.Functional.Break, Cookbook.Ingredients.Lists.Access, Cookbook.Ingredients.Lists.Modify, Cookbook.Ingredients.Lists.Stats, Cookbook.Ingredients.Tupples.Look, Cookbook.Ingredients.Tupples.Assemble, Cookbook.Recipes.Detect, Cookbook.Project.Groups.Groups, Cookbook.Recipes.Sanitize, Cookbook.Ingredients.Lists.Replace
+  exposed-modules:     Cookbook.Essential.Common, Cookbook.Essential.Continuous, Cookbook.Essential.IO, Cookbook.Recipes.DiffStat, Cookbook.Recipes.Text, Cookbook.Project.Configuration.Configuration, Cookbook.Project.Scribe.Scribe, Cookbook.Ingredients.Functional.Break, Cookbook.Ingredients.Lists.Access, Cookbook.Ingredients.Lists.Modify, Cookbook.Ingredients.Lists.Stats, Cookbook.Ingredients.Tupples.Look, Cookbook.Ingredients.Tupples.Assemble, Cookbook.Recipes.Detect, Cookbook.Project.Groups.Groups, Cookbook.Recipes.Sanitize, Cookbook.Ingredients.Lists.Replace
   
   -- Modules included in this library but not exported.
   -- other-modules:       
   
   -- Other library packages from which modules are imported.
-  build-depends:       base ==4.6.*
+  build-depends:       base ==4.6.*, directory, strict
   
