diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,16 @@
+texmath (0.7.0.1)
+
+  * TeX reader:
+
+    + Improved error reporting.
+    + Optimized parser.
+    + Treat `\ ` as ESpaced rather than ESymbol.
+    + Fixed parsing of `\phantom`.
+    + Internal improvements, including using the parsec3 interface
+      instead of the older parsec2 compatibility interface.
+
+  * Added tests for phantom.
+
 texmath (0.7)
 
   * Changes in Exp type:
diff --git a/src/Text/TeXMath/Readers/MathML.hs b/src/Text/TeXMath/Readers/MathML.hs
--- a/src/Text/TeXMath/Readers/MathML.hs
+++ b/src/Text/TeXMath/Readers/MathML.hs
@@ -170,7 +170,7 @@
   let ts =  [("accent", ESymbol Accent), ("fence", ESymbol objectPosition)]
   let fallback = case opString of
                       [t] -> ESymbol (getSymbolType t)
-                      _   -> if isJust opLookup 
+                      _   -> if isJust opLookup
                                 then ESymbol Ord
                                 else EMathOperator
   let constructor =
@@ -269,7 +269,7 @@
               (Nothing, Nothing) -> empty
               (Just (openFence, conOpen), Nothing) -> conOpen openFence
               (Nothing, Just (closeFence, conClose)) -> conClose closeFence
-              (Just (openFence, conOpen), Just (closeFence, conClose))  -> 
+              (Just (openFence, conOpen), Just (closeFence, conClose))  ->
                 EGrouped [conOpen openFence, conClose closeFence]
     go es'@(last -> Trailing constructor e) = (constructor (go (init es')) e)
     go es' = EDelimited (getFence open) (getFence close) (toEDelim es')
@@ -494,7 +494,7 @@
 tableCell a e = do
   align <- maybe a toAlignment <$> (findAttrQ "columnalign" e)
   case name e of
-    "mtd" -> (,) align . (:[]) <$> row e 
+    "mtd" -> (,) align . (:[]) <$> row e
     _ -> throwError $ "Invalid Element: Only expecting mtd elements " ++ err e
 
 -- Fixup
@@ -521,7 +521,7 @@
 renameAttr :: Attr -> Attr
 renameAttr v@(qName . attrKey -> "accentunder") =
   Attr (unqual "accent") (attrVal v)
-renameAttr a = a 
+renameAttr a = a
 
 filterMathVariant :: MMLState -> MMLState
 filterMathVariant s@(attrs -> as) =
diff --git a/src/Text/TeXMath/Readers/TeX.hs b/src/Text/TeXMath/Readers/TeX.hs
--- a/src/Text/TeXMath/Readers/TeX.hs
+++ b/src/Text/TeXMath/Readers/TeX.hs
@@ -23,41 +23,41 @@
 module Text.TeXMath.Readers.TeX (readTeX)
 where
 
+import Data.List (intercalate)
 import Control.Monad
-import Data.Char (isDigit, isAscii)
+import Data.Char (isDigit, isAscii, isLetter)
 import qualified Data.Map as M
-import Text.ParserCombinators.Parsec hiding (label)
+import Text.Parsec hiding (label)
+import Text.Parsec.String
 import Text.TeXMath.Types
 import Control.Applicative ((<*), (*>), (<*>), (<$>), (<$), pure)
 import qualified Text.TeXMath.Shared as S
 import Text.TeXMath.Readers.TeX.Macros (applyMacros, parseMacroDefinitions)
 import Text.TeXMath.Unicode.ToTeX (getSymbolType)
-import Data.Maybe (fromMaybe)
+import Data.Maybe (fromMaybe, fromJust)
 
-type TP = GenParser Char ()
+type TP = Parser
 
 -- The parser
 
 expr1 :: TP Exp
-expr1 =
-  choice
-  [ inbraces
-  , variable
-  , number
-  , texSymbol
-  , text
-  , styled
-  , root
-  , unary
-  , binary
-  , enclosure
-  , bareSubSup
-  , environment
-  , diacritical
-  , escaped
-  , unicode
-  , ensuremath
-  ] <* ignorable
+expr1 = choice
+          [ inbraces
+          , variable
+          , number
+          , text
+          , styled
+          , root
+          , phantom
+          , binary
+          , bareSubSup
+          , environment
+          , diacritical
+          , unicode
+          , ensuremath
+          , enclosure
+          , texSymbol
+          ] <* ignorable
 
 -- | Parse a formula, returning a list of 'Exp'.
 readTeX :: String -> Either String [Exp]
@@ -65,8 +65,15 @@
   let (ms, rest) = parseMacroDefinitions inp in
   either (Left . show) (Right . id) $ parse formula "formula" (applyMacros ms rest)
 
+ctrlseq :: String -> TP String
+ctrlseq s = lexeme $
+  case s of
+       [c] | not (isLetter c) -> try (string ['\\',c])
+       _ -> try (string ('\\':s) <* (notFollowedBy letter
+                                     <?> ("non-letter after \\" ++ s)))
+
 ignorable :: TP ()
-ignorable = skipMany (comment <|> label <|> skipMany1 space)
+ignorable = skipMany (comment <|> label <|> (skipMany1 space <?> "whitespace"))
 
 comment :: TP ()
 comment = char '%' *> skipMany (noneOf "\n") *> optional newline
@@ -74,9 +81,6 @@
 label :: TP ()
 label = ctrlseq "label" *> braces (skipMany (noneOf "}"))
 
-ctrlseq :: String -> TP String
-ctrlseq s = try $ string ('\\':s) <* notFollowedBy letter <* spaces
-
 unGrouped :: Exp -> [Exp]
 unGrouped (EGrouped xs) = xs
 unGrouped x = [x]
@@ -101,11 +105,11 @@
 --
 --     - False otherwise
 operatorname :: TP (Exp, Bool)
-operatorname = try $ do
+operatorname = do
     ctrlseq "operatorname"
     convertible <- (char '*' >> spaces >> return True) <|> return False
     op <- expToOperatorName <$> texToken
-    maybe pzero (\s -> return (EMathOperator s, convertible)) op
+    maybe mzero (\s -> return (EMathOperator s, convertible)) op
 
 -- | Converts identifiers, symbols and numbers to a flat string.
 -- Returns Nothing if the expression contains anything else.
@@ -137,16 +141,16 @@
   <|> return Nothing
 
 binomCmd :: TP String
-binomCmd = choice $ map (ctrlseq . fst) binomCmds
+binomCmd = oneOfCommands (map fst binomCmds)
 
 binomCmds :: [(String, Exp -> Exp -> Exp)]
-binomCmds = [ ("choose", \x y ->
+binomCmds = [ ("\\choose", \x y ->
                 EDelimited "(" ")" [Right (EFraction NoLineFrac x y)])
-            , ("brack", \x y ->
+            , ("\\brack", \x y ->
                 EDelimited "[" "]" [Right (EFraction NoLineFrac x y)])
-            , ("brace", \x y ->
+            , ("\\brace", \x y ->
                 EDelimited "{" "}" [Right (EFraction NoLineFrac x y)])
-            , ("bangle", \x y ->
+            , ("\\bangle", \x y ->
                 EDelimited "\x27E8" "\x27E9" [Right (EFraction NoLineFrac x y)])
             ]
 
@@ -162,7 +166,7 @@
                 else many (notFollowedBy binomCmd >> p)
   let withCmd :: String -> TP Exp
       withCmd cmd =
-         case lookup (drop 1 cmd) binomCmds of
+         case lookup cmd binomCmds of
               Just f  -> f <$> (asGroup <$> pure initial)
                            <*> (asGroup <$> many p)
               Nothing -> fail $ "Unknown command " ++ cmd
@@ -178,13 +182,16 @@
 inbraces = braces (manyExp expr)
 
 texToken :: TP Exp
-texToken = texSymbol <|> inbraces <|> inbrackets <|>
-             do c <- anyChar
-                spaces
-                return $ if isDigit c
-                            then (ENumber [c])
-                            else (EIdentifier [c])
+texToken = texSymbol <|> inbraces <|> inbrackets <|> texChar
 
+texChar :: TP Exp
+texChar =
+  do
+    c <- noneOf "\n\t\r \\{}" <* spaces
+    return $ if isDigit c
+              then ENumber [c]
+              else EIdentifier [c]
+
 inbrackets :: TP Exp
 inbrackets = (brackets $ manyExp $ notFollowedBy (char ']') >> expr)
 
@@ -194,17 +201,18 @@
 enclosure :: TP Exp
 enclosure = basicEnclosure <|> scaledEnclosure <|> delimited
 
+-- Expensive
 basicEnclosure :: TP Exp
-basicEnclosure = choice $ map (\(s, v) -> try (symbol s) >> return v) enclosures
+basicEnclosure = choice (map (\(s, v) -> symbol s >> return v) enclosures)
 
 fence :: String -> TP String
-fence cmd = try $ do
+fence cmd = do
   symbol cmd
   enc <- basicEnclosure <|> (try (symbol ".") >> return (ESymbol Open ""))
   case enc of
        ESymbol Open x  -> return x
        ESymbol Close x -> return x
-       _ -> pzero
+       _ -> mzero
 
 middle :: TP String
 middle = fence "\\middle"
@@ -213,21 +221,21 @@
 right = fence "\\right"
 
 delimited :: TP Exp
-delimited = try $ do
-  openc <- fence "\\left"
+delimited = do
+  openc <- try $ fence "\\left"
   contents <- concat <$>
               many (try $ ((:[]) . Left <$> middle)
                       <|> (map Right . unGrouped <$>
-                             many1Exp (notFollowedBy right >> expr)))
+                             many1Exp (notFollowedBy right *> expr)))
   closec <- right <|> return ""
   return $ EDelimited openc closec contents
 
 scaledEnclosure :: TP Exp
-scaledEnclosure = try $ do
-  cmd <- command
+scaledEnclosure = do
+  cmd <- oneOfCommands (map fst S.scalers)
   case S.getScalerValue cmd of
        Just  r -> EScaled r <$> basicEnclosure
-       Nothing -> pzero
+       Nothing -> mzero
 
 endLine :: TP Char
 endLine = try $ do
@@ -251,15 +259,19 @@
   return $ map letterToAlignment as
 
 environment :: TP Exp
-environment = try $ do
+environment = do
   ctrlseq "begin"
-  name <- char '{' *> manyTill anyChar (char '}')
+  name <- braces (oneOfStrings (M.keys environments) <* optional (char '*'))
   spaces
-  let name' = filter (/='*') name
-  case M.lookup name' environments of
-        Just env -> env <* spaces <* ctrlseq "end"
-                        <* braces (string name) <* spaces
-        Nothing  -> mzero
+  case M.lookup name environments of
+        Just env -> do
+          result <- env
+          spaces
+          ctrlseq "end"
+          braces (string name <* optional (char '*'))
+          spaces
+          return result
+        Nothing  -> mzero  -- should not happen
 
 environments :: M.Map String (TP Exp)
 environments = M.fromList
@@ -387,22 +399,7 @@
                           | convertible || isConvertible a -> EUnder True a b
                           | isUnderover a -> EUnder False a b
                         _          -> ESub a b
-       _   -> pzero
-
-escaped :: TP Exp
-escaped = lexeme $ try $
-          char '\\' >>
-          (ESymbol Ord . (:[])) <$> (satisfy isEscapable)
-   where isEscapable '{' = True
-         isEscapable '}' = True
-         isEscapable '$' = True
-         isEscapable '%' = True
-         isEscapable '&' = True
-         isEscapable '_' = True
-         isEscapable '#' = True
-         isEscapable '^' = True  -- actually only if followed by {}
-         isEscapable ' ' = True
-         isEscapable _   = False
+       _   -> mzero
 
 unicode :: TP Exp
 unicode = lexeme $
@@ -411,14 +408,7 @@
     return (ESymbol (getSymbolType c) [c])
 
 ensuremath :: TP Exp
-ensuremath = try $ lexeme (string "\\ensuremath") >> inbraces
-
-command :: TP String
-command = try $ do
-  char '\\'
-  res <- many1 letter <|> count 1 (satisfy (/='\n'))
-  spaces
-  return ('\\':res)
+ensuremath = ctrlseq "ensuremath" *> inbraces
 
 -- Note: cal and scr are treated the same way, as unicode is lacking such two different sets for those.
 styleOps :: M.Map String ([Exp] -> Exp)
@@ -447,26 +437,19 @@
           ]
 
 diacritical :: TP Exp
-diacritical = try $ do
-  c <- command
+diacritical = do
+  c <- oneOfCommands (map snd S.diacriticals)
   case S.getDiacriticalCons c of
        Just r  -> r <$> texToken
-       Nothing -> pzero
+       Nothing -> mzero
 
 
-unary :: TP Exp
-unary = try $ do
-  c <- command
-  a <- texToken
-  case c of
-       "\\phantom" -> return $ EPhantom a
-       "\\sqrt"    -> return $ ESqrt a
-       "\\surd"    -> return $ ESqrt a
-       _ -> mzero
+phantom :: TP Exp
+phantom = EPhantom <$> (ctrlseq "phantom" *> texToken)
 
 text :: TP Exp
-text = try $ do
-  c <- command
+text = do
+  c <- oneOfCommands (M.keys textOps)
   maybe mzero (<$> (bracedText <* spaces)) $ M.lookup c textOps
 
 textOps :: M.Map String (String -> Exp)
@@ -480,27 +463,25 @@
           ]
 
 styled :: TP Exp
-styled = try $ do
-  c <- command
+styled = do
+  c <- oneOfCommands (M.keys styleOps)
   case M.lookup c styleOps of
        Just f   -> do
          x <- inbraces
          return $ case x of
                        EGrouped xs -> f xs
                        _           -> f [x]
-       Nothing  -> pzero
+       Nothing  -> mzero
 
 -- note: sqrt can be unary, \sqrt{2}, or binary, \sqrt[3]{2}
 root :: TP Exp
-root = try $ do
+root = do
   ctrlseq "sqrt" <|> ctrlseq "surd"
-  a <- inbrackets
-  b <- texToken
-  return $ ERoot a b
+  (ERoot <$> inbrackets <*> texToken) <|> (ESqrt <$> texToken)
 
 binary :: TP Exp
-binary = try $ do
-  c <- command
+binary = do
+  c <- oneOfCommands binops
   a <- texToken
   b <- texToken
   case c of
@@ -512,16 +493,62 @@
      "\\dfrac"    -> return $ EFraction DisplayFrac a b
      "\\binom"    -> return $ EDelimited "(" ")"
                               [Right (EFraction NoLineFrac a b)]
-     _            -> pzero
+     _            -> fail "Unrecognised binary operator"
+  where
+    binops = ["\\overset", "\\stackrel", "\\underset", "\\frac", "\\tfrac", "\\dfrac", "\\binom"]
 
 texSymbol :: TP Exp
-texSymbol = try $ do
-  negated <- (ctrlseq "not" >> return True) <|> return False
-  sym <- operator <|> command
-  case M.lookup sym symbols of
-       Just s   -> if negated then neg s else return s
-       Nothing  -> pzero
+texSymbol = do
+  negated <- (try (ctrlseq "not") >> return True) <|> return False
+  sym <- operator <|> tSymbol
+  if negated then neg sym else return sym
 
+oneOfCommands :: [String] -> TP String
+oneOfCommands cmds = try $ do
+  cmd <- oneOfStrings cmds
+  case cmd of
+    ['\\',c] | not (isLetter c) -> return ()
+    _ -> notFollowedBy letter <?> ("non-letter after " ++ cmd)
+  spaces
+  return cmd
+
+oneOfStrings' :: (Char -> Char -> Bool) -> [String] -> TP String
+oneOfStrings' _ []         = mzero
+oneOfStrings' matches strs = try $ do
+    c <- anyChar
+    let strs' = [xs | (x:xs) <- strs, x `matches` c]
+    case strs' of
+      []  -> mzero
+      _   -> (c:) <$> oneOfStrings' matches strs'
+                     <|> if "" `elem` strs'
+                          then return [c]
+                          else mzero
+
+-- | Parses one of a list of strings.  If the list contains
+-- two strings one of which is a prefix of the other, the longer
+-- string will be matched if possible.
+oneOfStrings :: [String] -> TP String
+oneOfStrings strs = oneOfStrings' (==) strs <??> (intercalate ", " $ map show strs)
+
+-- | Like '(<?>)', but moves position back to the beginning of the parse
+-- before reporting the error.
+(<??>) :: Monad m => ParsecT s u m a -> String -> ParsecT s u m a
+(<??>) p expected = do
+  pos <- getPosition
+  p <|> (setPosition pos >> mzero <?> expected)
+
+infix 0 <??>
+
+tSymbol :: TP Exp
+tSymbol = do
+  sym <- oneOfCommands (M.keys symbols)
+  return $ fromJust (M.lookup sym symbols)
+
+operator :: TP Exp
+operator = do
+  sym <- lexeme (oneOfStrings $ M.keys operators)
+  return $ fromJust (M.lookup sym operators)
+
 neg :: Exp -> TP Exp
 neg (ESymbol Rel x) = ESymbol Rel `fmap`
   case x of
@@ -530,8 +557,8 @@
        "\x2286" -> return "\x2288"
        "\x2287" -> return "\x2289"
        "\x2208" -> return "\x2209"
-       _        -> pzero
-neg _ = pzero
+       _        -> mzero
+neg _ = mzero
 
 lexeme :: TP a -> TP a
 lexeme p = p <* spaces
@@ -542,9 +569,6 @@
 brackets :: TP a -> TP a
 brackets p = lexeme $ char '[' *> spaces *> p <* spaces <* char ']'
 
-operator :: TP String
-operator = lexeme $ many1 (char '\'') <|> ((:[]) <$> opLetter)
-   where opLetter = oneOf ":_+*/=^-(),;.?'~[]<>!"
 
 symbol :: String -> TP String
 symbol s = lexeme $ try $ string s
@@ -582,8 +606,8 @@
              , ("\\urcorner", ESymbol Close "\x231D")
              ]
 
-symbols :: M.Map String Exp
-symbols = M.fromList [
+operators :: M.Map String Exp
+operators = M.fromList [
              ("+", ESymbol Bin "+")
            , ("-", ESymbol Bin "\x2212")
            , ("*", ESymbol Bin "*")
@@ -592,7 +616,6 @@
            , (".", ESymbol Ord ".")
            , (";", ESymbol Pun ";")
            , (":", ESymbol Rel ":")
-           , ("\\colon", ESymbol Pun ":")
            , ("?", ESymbol Ord "?")
            , (">", ESymbol Rel ">")
            , ("<", ESymbol Rel "<")
@@ -603,11 +626,22 @@
            , ("''''", ESymbol Ord "\x2057")
            , ("=", ESymbol Rel "=")
            , (":=", ESymbol Rel ":=")
+           , ("/", ESymbol Ord "/")
+           , ("~", ESpace 0.333) ]
+
+symbols :: M.Map String Exp
+symbols = M.fromList
+           [ ("\\$", ESymbol Ord "$")
+           , ("\\%", ESymbol Ord "%")
+           , ("\\&", ESymbol Ord "&")
+           , ("\\_", ESymbol Ord "_")
+           , ("\\#", ESymbol Ord "#")
+           , ("\\^", ESymbol Ord "^")
            , ("\\mid", ESymbol Bin "\x2223")
+           , ("\\colon", ESymbol Pun ":")
            , ("\\parallel", ESymbol Rel "\x2225")
            , ("\\backslash", ESymbol Bin "\x2216")
-           , ("/", ESymbol Ord "/")
-           , ("\\setminus",	ESymbol Bin "\\")
+           , ("\\setminus", ESymbol Bin "\\")
            , ("\\times", ESymbol Bin "\x00D7")
            , ("\\alpha", EIdentifier "\x03B1")
            , ("\\beta", EIdentifier "\x03B2")
@@ -807,7 +841,7 @@
            , ("\\>", ESpace 0.222)
            , ("\\:", ESpace 0.222)
            , ("\\;", ESpace 0.278)
-           , ("~", ESpace 0.333)
+           , ("\\ ", ESpace 0.222)
            , ("\\quad", ESpace 1)
            , ("\\qquad", ESpace 2)
            , ("\\arccos", EMathOperator "arccos")
@@ -848,6 +882,7 @@
 
 textual :: TP String
 textual = regular <|> sps <|> ligature <|> textCommand <|> bracedText
+            <?> "text"
 
 sps :: TP String
 sps = " " <$ skipMany1 (oneOf " \t\n")
@@ -865,10 +900,10 @@
        <|> try ("\xA0"   <$ string "~")
 
 textCommand :: TP String
-textCommand = try $ do
-  ('\\':cmd) <- command
+textCommand = do
+  cmd <- oneOfCommands (M.keys textCommands)
   case M.lookup cmd textCommands of
-       Nothing -> fail ("Unknown command \\" ++ cmd)
+       Nothing -> fail ("Unknown control sequence " ++ cmd)
        Just c  -> c
 
 bracedText :: TP String
@@ -884,40 +919,40 @@
 
 textCommands :: M.Map String (TP String)
 textCommands = M.fromList
-  [ ("#", return "#")
-  , ("$", return "$")
-  , ("%", return "%")
-  , ("&", return "&")
-  , ("_", return "_")
-  , ("{", return "{")
-  , ("}", return "}")
-  , ("ldots", return "\x2026")
-  , ("textasciitilde", return "~")
-  , ("textasciicircum", return "^")
-  , ("textbackslash", return "\\")
-  , ("char", parseC)
-  , ("aa", return "å")
-  , ("AA", return "Å")
-  , ("ss", return "ß")
-  , ("o", return "ø")
-  , ("O", return "Ø")
-  , ("L", return "Ł")
-  , ("l", return "ł")
-  , ("ae", return "æ")
-  , ("AE", return "Æ")
-  , ("oe", return "œ")
-  , ("OE", return "Œ")
-  , ("`", option "`" $ grave <$> tok)
-  , ("'", option "'" $ acute <$> tok)
-  , ("^", option "^" $ circ  <$> tok)
-  , ("~", option "~" $ tilde <$> tok)
-  , ("\"", option "\"" $ try $ umlaut <$> tok)
-  , (".", option "." $ try $ dot <$> tok)
-  , ("=", option "=" $ try $ macron <$> tok)
-  , ("c", option "c" $ try $ cedilla <$> tok)
-  , ("v", option "v" $ try $ hacek <$> tok)
-  , ("u", option "u" $ try $ breve <$> tok)
-  , (" ", return " ")
+  [ ("\\#", return "#")
+  , ("\\$", return "$")
+  , ("\\%", return "%")
+  , ("\\&", return "&")
+  , ("\\_", return "_")
+  , ("\\{", return "{")
+  , ("\\}", return "}")
+  , ("\\ldots", return "\x2026")
+  , ("\\textasciitilde", return "~")
+  , ("\\textasciicircum", return "^")
+  , ("\\textbackslash", return "\\")
+  , ("\\char", parseC)
+  , ("\\aa", return "å")
+  , ("\\AA", return "Å")
+  , ("\\ss", return "ß")
+  , ("\\o", return "ø")
+  , ("\\O", return "Ø")
+  , ("\\L", return "Ł")
+  , ("\\l", return "ł")
+  , ("\\ae", return "æ")
+  , ("\\AE", return "Æ")
+  , ("\\oe", return "œ")
+  , ("\\OE", return "Œ")
+  , ("\\`", option "`" $ grave <$> tok)
+  , ("\\'", option "'" $ acute <$> tok)
+  , ("\\^", option "^" $ circ  <$> tok)
+  , ("\\~", option "~" $ tilde <$> tok)
+  , ("\\\"", option "\"" $ try $ umlaut <$> tok)
+  , ("\\.", option "." $ try $ dot <$> tok)
+  , ("\\=", option "=" $ try $ macron <$> tok)
+  , ("\\c", option "c" $ try $ cedilla <$> tok)
+  , ("\\v", option "v" $ try $ hacek <$> tok)
+  , ("\\u", option "u" $ try $ breve <$> tok)
+  , ("\\ ", return " ")
   ]
 
 parseC :: TP String
diff --git a/src/Text/TeXMath/Shared.hs b/src/Text/TeXMath/Shared.hs
--- a/src/Text/TeXMath/Shared.hs
+++ b/src/Text/TeXMath/Shared.hs
@@ -22,8 +22,10 @@
   , getLaTeXTextCommand
   , getScalerCommand
   , getScalerValue
+  , scalers
   , getDiacriticalCommand
   , getDiacriticalCons
+  , diacriticals
   , getOperator
   , readLength
   ) where
@@ -192,6 +194,7 @@
   | s `elem` base    = True
   | otherwise = True
 
+-- | Mapping between LaTeX scaling commands and the scaling factor
 scalers :: [(String, Double)]
 scalers =
           [ ("\\bigg", 2.2)
@@ -214,6 +217,8 @@
 unavailable :: [String]
 unavailable = ["\\overbracket", "\\underbracket"]
 
+
+-- | Mapping between unicode combining character and LaTeX accent command
 diacriticals :: [(String, String)]
 diacriticals =
                [ ("\x00B4", "\\acute")
diff --git a/src/Text/TeXMath/Writers/MathML.hs b/src/Text/TeXMath/Writers/MathML.hs
--- a/src/Text/TeXMath/Writers/MathML.hs
+++ b/src/Text/TeXMath/Writers/MathML.hs
@@ -133,12 +133,12 @@
 op :: String -> Element
 op s = accentCons $ unode "mo" s
   where
-    accentCons = 
+    accentCons =
       case (elem "accent") . properties <$> getMathMLOperator s FPostfix of
             Nothing -> id
             Just False -> id
             Just True -> withAttribute "accent" "false"
-            
+
 
 showExp :: TextType -> Exp -> Element
 showExp tt e =
diff --git a/src/Text/TeXMath/Writers/OMML.hs b/src/Text/TeXMath/Writers/OMML.hs
--- a/src/Text/TeXMath/Writers/OMML.hs
+++ b/src/Text/TeXMath/Writers/OMML.hs
@@ -147,7 +147,7 @@
                                     [ mnodeA "begChr" start ()
                                     , mnodeA "endChr" end ()
                                     , mnode "grow" () ]
-                                  , mnode "e" $ concatMap 
+                                  , mnode "e" $ concatMap
                                     (either ((:[]) . str props) (showExp props)) xs
                                   ] ]
 
diff --git a/tests/readers/tex/14.native b/tests/readers/tex/14.native
--- a/tests/readers/tex/14.native
+++ b/tests/readers/tex/14.native
@@ -1,1 +1,1 @@
-[EFraction NormalFrac (EIdentifier "a") (EIdentifier "b"),ESymbol Ord " ",EFraction InlineFrac (EIdentifier "a") (EIdentifier "b")]
+[EFraction NormalFrac (EIdentifier "a") (EIdentifier "b"),ESpace 0.222,EFraction InlineFrac (EIdentifier "a") (EIdentifier "b")]
diff --git a/tests/readers/tex/phantom.native b/tests/readers/tex/phantom.native
new file mode 100644
--- /dev/null
+++ b/tests/readers/tex/phantom.native
@@ -0,0 +1,1 @@
+[EDelimited "(" ")" [Right (EPhantom (EFraction NormalFrac (ENumber "1") (ENumber "2")))]]
diff --git a/tests/readers/tex/sphere_volume.native b/tests/readers/tex/sphere_volume.native
--- a/tests/readers/tex/sphere_volume.native
+++ b/tests/readers/tex/sphere_volume.native
@@ -1,1 +1,1 @@
-[EIdentifier "S",ESymbol Rel "=",ESymbol Open "{",ENumber "0",ESymbol Rel "\8804",EIdentifier "\981",ESymbol Rel "\8804",ENumber "2",EIdentifier "\960",ESymbol Pun ",",ESymbol Ord " ",ENumber "0",ESymbol Rel "\8804",EIdentifier "\952",ESymbol Rel "\8804",EIdentifier "\960",ESymbol Pun ",",ESymbol Ord " ",ENumber "0",ESymbol Rel "\8804",EIdentifier "\961",ESymbol Rel "\8804",EIdentifier "R",ESymbol Close "}",EArray [AlignRight,AlignLeft] [[[EStyled TextNormal [EIdentifier "V",EIdentifier "o",EIdentifier "l",EIdentifier "u",EIdentifier "m",EIdentifier "e"]],[ESymbol Rel "=",EUnder False (ESymbol Op "\8749") (EIdentifier "S"),ESpace (-0.167),ESuper (EIdentifier "\961") (ENumber "2"),EMathOperator "sin",EIdentifier "\952",ESpace 0.167,EStyled TextNormal [EIdentifier "d"],EIdentifier "\961",ESpace 0.167,EStyled TextNormal [EIdentifier "d"],EIdentifier "\952",ESpace 0.167,EStyled TextNormal [EIdentifier "d"],EIdentifier "\981"]],[[],[ESymbol Rel "=",ESubsup (ESymbol Op "\8747") (ENumber "0") (EGrouped [ENumber "2",EIdentifier "\960"]),ESpace (-0.167),EStyled TextNormal [EIdentifier "d"],EIdentifier "\981",ESpace 0.167,ESubsup (ESymbol Op "\8747") (ENumber "0") (EIdentifier "\960"),ESpace (-0.167),EMathOperator "sin",EIdentifier "\952",ESpace 0.167,EStyled TextNormal [EIdentifier "d"],EIdentifier "\952",ESpace 0.167,ESubsup (ESymbol Op "\8747") (ENumber "0") (EIdentifier "R"),ESpace (-0.167),ESuper (EIdentifier "\961") (ENumber "2"),EStyled TextNormal [EIdentifier "d"],EIdentifier "\961"]],[[],[ESymbol Rel "=",EIdentifier "\981",ESubsup (EScaled 1.6 (ESymbol Open "|")) (ENumber "0") (EGrouped [ENumber "2",EIdentifier "\960"]),ESymbol Ord " ",ESymbol Open "(",ESymbol Bin "\8722",EMathOperator "cos",EIdentifier "\952",ESymbol Close ")",ESubsup (EScaled 1.6 (ESymbol Open "|")) (ENumber "0") (EIdentifier "\960"),ESymbol Ord " ",EFraction InlineFrac (ENumber "1") (ENumber "3"),ESuper (EIdentifier "\961") (ENumber "3"),ESubsup (EScaled 1.6 (ESymbol Open "|")) (ENumber "0") (EIdentifier "R")]],[[],[ESymbol Rel "=",ENumber "2",EIdentifier "\960",ESymbol Bin "\215",ENumber "2",ESymbol Bin "\215",EFraction InlineFrac (ENumber "1") (ENumber "3"),ESuper (EIdentifier "R") (ENumber "3")]],[[],[ESymbol Rel "=",EFraction InlineFrac (ENumber "4") (ENumber "3"),EIdentifier "\960",ESuper (EIdentifier "R") (ENumber "3")]]]]
+[EIdentifier "S",ESymbol Rel "=",ESymbol Open "{",ENumber "0",ESymbol Rel "\8804",EIdentifier "\981",ESymbol Rel "\8804",ENumber "2",EIdentifier "\960",ESymbol Pun ",",ESpace 0.222,ENumber "0",ESymbol Rel "\8804",EIdentifier "\952",ESymbol Rel "\8804",EIdentifier "\960",ESymbol Pun ",",ESpace 0.222,ENumber "0",ESymbol Rel "\8804",EIdentifier "\961",ESymbol Rel "\8804",EIdentifier "R",ESymbol Close "}",EArray [AlignRight,AlignLeft] [[[EStyled TextNormal [EIdentifier "V",EIdentifier "o",EIdentifier "l",EIdentifier "u",EIdentifier "m",EIdentifier "e"]],[ESymbol Rel "=",EUnder False (ESymbol Op "\8749") (EIdentifier "S"),ESpace (-0.167),ESuper (EIdentifier "\961") (ENumber "2"),EMathOperator "sin",EIdentifier "\952",ESpace 0.167,EStyled TextNormal [EIdentifier "d"],EIdentifier "\961",ESpace 0.167,EStyled TextNormal [EIdentifier "d"],EIdentifier "\952",ESpace 0.167,EStyled TextNormal [EIdentifier "d"],EIdentifier "\981"]],[[],[ESymbol Rel "=",ESubsup (ESymbol Op "\8747") (ENumber "0") (EGrouped [ENumber "2",EIdentifier "\960"]),ESpace (-0.167),EStyled TextNormal [EIdentifier "d"],EIdentifier "\981",ESpace 0.167,ESubsup (ESymbol Op "\8747") (ENumber "0") (EIdentifier "\960"),ESpace (-0.167),EMathOperator "sin",EIdentifier "\952",ESpace 0.167,EStyled TextNormal [EIdentifier "d"],EIdentifier "\952",ESpace 0.167,ESubsup (ESymbol Op "\8747") (ENumber "0") (EIdentifier "R"),ESpace (-0.167),ESuper (EIdentifier "\961") (ENumber "2"),EStyled TextNormal [EIdentifier "d"],EIdentifier "\961"]],[[],[ESymbol Rel "=",EIdentifier "\981",ESubsup (EScaled 1.6 (ESymbol Open "|")) (ENumber "0") (EGrouped [ENumber "2",EIdentifier "\960"]),ESpace 0.222,ESymbol Open "(",ESymbol Bin "\8722",EMathOperator "cos",EIdentifier "\952",ESymbol Close ")",ESubsup (EScaled 1.6 (ESymbol Open "|")) (ENumber "0") (EIdentifier "\960"),ESpace 0.222,EFraction InlineFrac (ENumber "1") (ENumber "3"),ESuper (EIdentifier "\961") (ENumber "3"),ESubsup (EScaled 1.6 (ESymbol Open "|")) (ENumber "0") (EIdentifier "R")]],[[],[ESymbol Rel "=",ENumber "2",EIdentifier "\960",ESymbol Bin "\215",ENumber "2",ESymbol Bin "\215",EFraction InlineFrac (ENumber "1") (ENumber "3"),ESuper (EIdentifier "R") (ENumber "3")]],[[],[ESymbol Rel "=",EFraction InlineFrac (ENumber "4") (ENumber "3"),EIdentifier "\960",ESuper (EIdentifier "R") (ENumber "3")]]]]
diff --git a/tests/src/phantom.tex b/tests/src/phantom.tex
new file mode 100644
--- /dev/null
+++ b/tests/src/phantom.tex
@@ -0,0 +1,1 @@
+\left(\phantom{\frac{1}{2}}\right)
diff --git a/tests/writers/14.mml b/tests/writers/14.mml
--- a/tests/writers/14.mml
+++ b/tests/writers/14.mml
@@ -5,7 +5,7 @@
       <mi>a</mi>
       <mi>b</mi>
     </mfrac>
-    <mo> </mo>
+    <mspace width="0.222em" />
     <mstyle displaystyle="false">
       <mfrac>
         <mi>a</mi>
diff --git a/tests/writers/14.omml b/tests/writers/14.omml
--- a/tests/writers/14.omml
+++ b/tests/writers/14.omml
@@ -29,7 +29,7 @@
       <m:rPr>
         <m:sty m:val="p" />
       </m:rPr>
-      <m:t> </m:t>
+      <m:t> </m:t>
     </m:r>
     <m:f>
       <m:fPr>
diff --git a/tests/writers/14.tex b/tests/writers/14.tex
--- a/tests/writers/14.tex
+++ b/tests/writers/14.tex
@@ -1,1 +1,1 @@
-\frac{a}{b}\ \tfrac{a}{b}
+\frac{a}{b}\:\tfrac{a}{b}
diff --git a/tests/writers/phantom.mml b/tests/writers/phantom.mml
new file mode 100644
--- /dev/null
+++ b/tests/writers/phantom.mml
@@ -0,0 +1,13 @@
+<?xml version='1.0' ?>
+<math display="block" xmlns="http://www.w3.org/1998/Math/MathML">
+  <mrow>
+    <mo stretchy="true" form="prefix">(</mo>
+    <mphantom>
+      <mfrac>
+        <mn>1</mn>
+        <mn>2</mn>
+      </mfrac>
+    </mphantom>
+    <mo stretchy="true" form="postfix">)</mo>
+  </mrow>
+</math>
diff --git a/tests/writers/phantom.omml b/tests/writers/phantom.omml
new file mode 100644
--- /dev/null
+++ b/tests/writers/phantom.omml
@@ -0,0 +1,45 @@
+<?xml version='1.0' ?>
+<m:oMathPara>
+  <m:oMathParaPr>
+    <m:jc m:val="center" />
+  </m:oMathParaPr>
+  <m:oMath>
+    <m:d>
+      <m:dPr>
+        <m:begChr m:val="(" />
+        <m:endChr m:val=")" />
+        <m:grow />
+      </m:dPr>
+      <m:e>
+        <m:phant>
+          <m:phantPr>
+            <m:show m:val="0" />
+          </m:phantPr>
+          <m:e>
+            <m:f>
+              <m:fPr>
+                <m:type m:val="bar" />
+              </m:fPr>
+              <m:num>
+                <m:r>
+                  <m:rPr>
+                    <m:sty m:val="p" />
+                  </m:rPr>
+                  <m:t>1</m:t>
+                </m:r>
+              </m:num>
+              <m:den>
+                <m:r>
+                  <m:rPr>
+                    <m:sty m:val="p" />
+                  </m:rPr>
+                  <m:t>2</m:t>
+                </m:r>
+              </m:den>
+            </m:f>
+          </m:e>
+        </m:phant>
+      </m:e>
+    </m:d>
+  </m:oMath>
+</m:oMathPara>
diff --git a/tests/writers/phantom.tex b/tests/writers/phantom.tex
new file mode 100644
--- /dev/null
+++ b/tests/writers/phantom.tex
@@ -0,0 +1,1 @@
+\left( \phantom{\frac{1}{2}} \right)
diff --git a/tests/writers/sphere_volume.mml b/tests/writers/sphere_volume.mml
--- a/tests/writers/sphere_volume.mml
+++ b/tests/writers/sphere_volume.mml
@@ -11,14 +11,14 @@
     <mn>2</mn>
     <mi>π</mi>
     <mo>,</mo>
-    <mo> </mo>
+    <mspace width="0.222em" />
     <mn>0</mn>
     <mo>≤</mo>
     <mi>θ</mi>
     <mo>≤</mo>
     <mi>π</mi>
     <mo>,</mo>
-    <mo> </mo>
+    <mspace width="0.222em" />
     <mn>0</mn>
     <mo>≤</mo>
     <mi>ρ</mi>
@@ -128,7 +128,7 @@
               <mi>π</mi>
             </mrow>
           </msubsup>
-          <mo> </mo>
+          <mspace width="0.222em" />
           <mo stretchy="false" form="prefix">(</mo>
           <mo>−</mo>
           <mi>cos</mi>
@@ -139,7 +139,7 @@
             <mn>0</mn>
             <mi>π</mi>
           </msubsup>
-          <mo> </mo>
+          <mspace width="0.222em" />
           <mstyle displaystyle="false">
             <mfrac>
               <mn>1</mn>
diff --git a/tests/writers/sphere_volume.omml b/tests/writers/sphere_volume.omml
--- a/tests/writers/sphere_volume.omml
+++ b/tests/writers/sphere_volume.omml
@@ -68,7 +68,7 @@
       <m:rPr>
         <m:sty m:val="p" />
       </m:rPr>
-      <m:t> </m:t>
+      <m:t> </m:t>
     </m:r>
     <m:r>
       <m:rPr>
@@ -110,7 +110,7 @@
       <m:rPr>
         <m:sty m:val="p" />
       </m:rPr>
-      <m:t> </m:t>
+      <m:t> </m:t>
     </m:r>
     <m:r>
       <m:rPr>
@@ -557,7 +557,7 @@
             <m:rPr>
               <m:sty m:val="p" />
             </m:rPr>
-            <m:t> </m:t>
+            <m:t> </m:t>
           </m:r>
           <m:r>
             <m:rPr>
@@ -619,7 +619,7 @@
             <m:rPr>
               <m:sty m:val="p" />
             </m:rPr>
-            <m:t> </m:t>
+            <m:t> </m:t>
           </m:r>
           <m:f>
             <m:fPr>
diff --git a/tests/writers/sphere_volume.tex b/tests/writers/sphere_volume.tex
--- a/tests/writers/sphere_volume.tex
+++ b/tests/writers/sphere_volume.tex
@@ -1,7 +1,7 @@
-S = \{ 0 \leq \phi \leq 2\pi,\ 0 \leq \theta \leq \pi,\ 0 \leq \rho \leq R\}\begin{aligned}
+S = \{ 0 \leq \phi \leq 2\pi,\: 0 \leq \theta \leq \pi,\: 0 \leq \rho \leq R\}\begin{aligned}
 \mathrm{Volume} & = \iiint\limits_{S}\!\rho^{2}\sin\theta\,\mathrm{d}\rho\,\mathrm{d}\theta\,\mathrm{d}\phi \\
  & = \int_{0}^{2\pi}\!\mathrm{d}\phi\,\int_{0}^{\pi}\!\sin\theta\,\mathrm{d}\theta\,\int_{0}^{R}\!\rho^{2}\mathrm{d}\rho \\
- & = \phi\Big|_{0}^{2\pi}\ ( - \cos\theta)\Big|_{0}^{\pi}\ \tfrac{1}{3}\rho^{3}\Big|_{0}^{R} \\
+ & = \phi\Big|_{0}^{2\pi}\:( - \cos\theta)\Big|_{0}^{\pi}\:\tfrac{1}{3}\rho^{3}\Big|_{0}^{R} \\
  & = 2\pi \times 2 \times \tfrac{1}{3}R^{3} \\
  & = \tfrac{4}{3}\pi R^{3} \\
 \end{aligned}
diff --git a/texmath.cabal b/texmath.cabal
--- a/texmath.cabal
+++ b/texmath.cabal
@@ -1,5 +1,5 @@
 Name:                texmath
-Version:             0.7
+Version:             0.7.0.1
 Cabal-Version:       >= 1.10
 Build-type:          Simple
 Synopsis:            Conversion between formats used to represent mathematics.
