diff --git a/Text/TeXMath/Parser.hs b/Text/TeXMath/Parser.hs
--- a/Text/TeXMath/Parser.hs
+++ b/Text/TeXMath/Parser.hs
@@ -29,9 +29,12 @@
 import qualified Text.ParserCombinators.Parsec.Token as P
 import Text.ParserCombinators.Parsec.Language
 import Text.TeXMath.Types
+import Control.Applicative ((<*), (*>), (<$>))
 
+type TP = GenParser Char ()
+
 texMathDef :: LanguageDef st
-texMathDef = LanguageDef 
+texMathDef = LanguageDef
    { commentStart   = ""
    , commentEnd     = ""
    , commentLine    = "%"
@@ -47,18 +50,18 @@
 
 -- The parser
 
-expr1 :: GenParser Char st Exp
+expr1 :: TP Exp
 expr1 =  choice [
     inbraces
   , variable
   , number
   , texSymbol
   , text
-  , root 
+  , root
   , unary
   , binary
   , enclosure
-  , array
+  , environment
   , diacritical
   , escaped
   , unicode
@@ -70,29 +73,29 @@
 parseFormula inp =
   either (Left . show) (Right . id) $ parse formula "formula" inp
 
-formula :: GenParser Char st [Exp]
+formula :: TP [Exp]
 formula = do
   whiteSpace
   f <- many expr
   eof
   return f
 
-expr :: GenParser Char st Exp
+expr :: TP Exp
 expr = do
   a <- expr1
   limits <- limitsIndicator
   subSup limits a <|> superOrSubscripted limits a <|> return a
 
-limitsIndicator :: GenParser Char st (Maybe Bool)
+limitsIndicator :: TP (Maybe Bool)
 limitsIndicator =
    try (symbol "\\limits" >> return (Just True))
   <|> try (symbol "\\nolimits" >> return (Just False))
   <|> return Nothing
 
-inbraces :: GenParser Char st Exp
+inbraces :: TP Exp
 inbraces = liftM EGrouped (braces $ many $ notFollowedBy (char '}') >> expr)
 
-texToken :: GenParser Char st Exp
+texToken :: TP Exp
 texToken = inbraces <|> inbrackets <|>
              do c <- anyChar
                 spaces
@@ -100,19 +103,19 @@
                             then (ENumber [c])
                             else (EIdentifier [c])
 
-inbrackets :: GenParser Char st Exp
+inbrackets :: TP Exp
 inbrackets = liftM EGrouped (brackets $ many $ notFollowedBy (char ']') >> expr)
 
-number :: GenParser Char st Exp
+number :: TP Exp
 number = lexeme $ liftM ENumber $ many1 digit
 
-enclosure :: GenParser Char st Exp
+enclosure :: TP Exp
 enclosure = basicEnclosure <|> left <|> right <|> scaledEnclosure
 
-basicEnclosure :: GenParser Char st Exp
+basicEnclosure :: TP Exp
 basicEnclosure = choice $ map (\(s, v) -> try (symbol s) >> return v) enclosures
 
-left :: GenParser Char st Exp
+left :: TP Exp
 left = try $ do
   symbol "\\left"
   enc <- basicEnclosure <|> (try (symbol ".") >> return (ESymbol Open "\xFEFF"))
@@ -120,7 +123,7 @@
     (ESymbol Open _) -> tilRight enc <|> return (EStretchy enc)
     _ -> pzero
 
-right :: GenParser Char st Exp
+right :: TP Exp
 right = try $ do
   symbol "\\right"
   enc <- basicEnclosure <|> (try (symbol ".") >> return (ESymbol Close "\xFEFF"))
@@ -131,7 +134,7 @@
 -- We want stuff between \left( and \right) to be in an mrow,
 -- so that the scaling is based just on this unit, and not the
 -- whole containing formula.
-tilRight :: Exp -> GenParser Char st Exp
+tilRight :: Exp -> TP Exp
 tilRight start = try $ do
   contents <- manyTill expr
                (try $ symbol "\\right" >> lookAhead basicEnclosure)
@@ -144,88 +147,98 @@
                      _           -> ""
   return $ EDelimited startChar endChar contents
 
-scaledEnclosure :: GenParser Char st Exp
+scaledEnclosure :: TP Exp
 scaledEnclosure = try $ do
   cmd <- command
   case M.lookup cmd scalers of
        Just  r -> liftM (EScaled r . EStretchy) basicEnclosure
-       Nothing -> pzero 
+       Nothing -> pzero
 
-endLine :: GenParser Char st Char
+endLine :: TP Char
 endLine = try $ do
   symbol "\\\\"
   optional inbrackets  -- can contain e.g. [1.0in] for a line height, not yet supported
   return '\n'
 
-arrayLine :: GenParser Char st ArrayLine
+arrayLine :: TP ArrayLine
 arrayLine = notFollowedBy (try $ char '\\' >> symbol "end" >> return '\n') >>
   sepBy1 (many (notFollowedBy endLine >> expr)) (symbol "&")
 
-array :: GenParser Char st Exp
-array = stdarray <|> eqnarray <|> align <|> cases <|> matrix <|> split
+arrayAlignments :: TP [Alignment]
+arrayAlignments = try $ do
+  as <- braces (many letter)
+  let letterToAlignment 'l' = AlignLeft
+      letterToAlignment 'c' = AlignCenter
+      letterToAlignment 'r' = AlignRight
+      letterToAlignment _   = AlignDefault
+  return $ map letterToAlignment as
 
-matrix :: GenParser Char st Exp
-matrix =  matrixWith "pmatrix" "(" ")"
-      <|> matrixWith "bmatrix" "[" "]"
-      <|> matrixWith "Bmatrix" "{" "}"
-      <|> matrixWith "vmatrix" "\x2223" "\x2223"
-      <|> matrixWith "Vmatrix" "\x2225" "\x2225"
+environment :: TP Exp
+environment = try $ do
+  char '\\'
+  symbol "begin"
+  name <- char '{' *> manyTill anyChar (char '}')
+  spaces
+  let name' = filter (/='*') name
+  case M.lookup name' environments of
+        Just env -> env <* spaces <* char '\\' <* symbol "end"
+                        <* braces (string name) <* spaces
+        Nothing  -> mzero
 
-matrixWith :: String -> String -> String -> GenParser Char st Exp
-matrixWith keywd opendelim closedelim =
-  inEnvironment keywd $ do
-    aligns <- option [] arrayAlignments
-    lines' <- sepEndBy1 arrayLine endLine
-    return $ EDelimited opendelim closedelim [EArray aligns lines']
+environments :: M.Map String (TP Exp)
+environments = M.fromList
+  [ ("array", stdarray)
+  , ("eqnarray", eqnarray)
+  , ("align", align)
+  , ("aligned", align)
+  , ("alignat", inbraces *> spaces *> align)
+  , ("alignedat", inbraces *> spaces *> align)
+  , ("flalign", flalign)
+  , ("flaligned", flalign)
+  , ("cases", cases)
+  , ("pmatrix", matrixWith "(" ")")
+  , ("bmatrix", matrixWith "[" "]")
+  , ("Bmatrix", matrixWith "{" "}")
+  , ("vmatrix", matrixWith "\x2223" "\x2223")
+  , ("Vmatrix", matrixWith "\x2225" "\x2225")
+  , ("split", align)
+  , ("multiline", gather)
+  , ("gather", gather)
+  , ("gathered", gather)
+  ]
 
-stdarray :: GenParser Char st Exp
-stdarray = inEnvironment "array" $ do
+matrixWith :: String -> String -> TP Exp
+matrixWith opendelim closedelim = do
   aligns <- option [] arrayAlignments
-  liftM (EArray aligns) $ sepEndBy1 arrayLine endLine
+  lines' <- sepEndBy1 arrayLine endLine
+  return $ EDelimited opendelim closedelim [EArray aligns lines']
 
-eqnarray :: GenParser Char st Exp
-eqnarray = inEnvironment "eqnarray" $
-  liftM (EArray [AlignRight, AlignCenter, AlignLeft]) $
-    sepEndBy1 arrayLine endLine
+stdarray :: TP Exp
+stdarray = do
+  aligns <- option [] arrayAlignments
+  (EArray aligns) <$> sepEndBy1 arrayLine endLine
 
-align :: GenParser Char st Exp
-align = inEnvironment "align" $
-  liftM (EArray [AlignRight, AlignLeft]) $
-    sepEndBy1 arrayLine endLine
+gather :: TP Exp
+gather = (EArray []) <$> sepEndBy arrayLine endLine
 
-cases :: GenParser Char st Exp
-cases = inEnvironment "cases" $ do
-  rs <- sepEndBy1 arrayLine endLine
-  return $ EDelimited "{" "" [EArray [] rs]
+eqnarray :: TP Exp
+eqnarray = (EArray [AlignRight, AlignCenter, AlignLeft]) <$>
+  sepEndBy1 arrayLine endLine
 
-split :: GenParser Char st Exp
-split = inEnvironment "split" $ do
-  rs <- sepEndBy1 arrayLine endLine
-  return $ EArray [AlignRight, AlignLeft] rs
+align :: TP Exp
+align = (EArray [AlignRight, AlignLeft]) <$>
+  sepEndBy1 arrayLine endLine
 
-arrayAlignments :: GenParser Char st [Alignment]
-arrayAlignments = try $ do
-  as <- braces (many letter)
-  let letterToAlignment 'l' = AlignLeft
-      letterToAlignment 'c' = AlignCenter
-      letterToAlignment 'r' = AlignRight
-      letterToAlignment _   = AlignDefault
-  return $ map letterToAlignment as
+flalign :: TP Exp
+flalign = (EArray [AlignLeft, AlignRight]) <$>
+  sepEndBy1 arrayLine endLine
 
-inEnvironment :: String
-              -> GenParser Char st Exp
-              -> GenParser Char st Exp
-inEnvironment envType p = do
-  try $ do char '\\'
-           symbol "begin"
-           braces $ symbol envType >> optional (symbol "*")
-  result <- p
-  char '\\'
-  symbol "end"
-  braces $ symbol envType >> optional (symbol "*")
-  return result 
+cases :: TP Exp
+cases = do
+  rs <- sepEndBy1 arrayLine endLine
+  return $ EDelimited "{" "" [EArray [] rs]
 
-variable :: GenParser Char st Exp
+variable :: TP Exp
 variable = do
   v <- letter
   spaces
@@ -245,7 +258,7 @@
            "\x2210","\x2A01","\x2A02","\x2A00","\x2A04"]
 isConvertible _ = False
 
-subSup :: Maybe Bool -> Exp -> GenParser Char st Exp
+subSup :: Maybe Bool -> Exp -> TP Exp
 subSup limits a = try $ do
   symbol "_"
   b <- expr1
@@ -256,7 +269,7 @@
             Nothing | isConvertible a -> EDownup a b c
             _          -> ESubsup a b c
 
-superOrSubscripted :: Maybe Bool -> Exp -> GenParser Char st Exp
+superOrSubscripted :: Maybe Bool -> Exp -> TP Exp
 superOrSubscripted limits a = try $ do
   c <- oneOf "^_"
   spaces
@@ -272,19 +285,18 @@
                         _          -> ESub a b
        _   -> pzero
 
-escaped :: GenParser Char st Exp
-escaped = lexeme $ try $ 
+escaped :: TP Exp
+escaped = lexeme $ try $
           char '\\' >>
           liftM (ESymbol Ord . (:[])) (satisfy $ not . isAlphaNum)
 
-unicode :: GenParser Char st Exp
+unicode :: TP Exp
 unicode = lexeme $ liftM (ESymbol Ord . (:[])) $ satisfy (not . isAscii)
 
-ensuremath :: GenParser Char st Exp
-ensuremath = lexeme $ try $
-             string "\\ensuremath" >> inbraces
+ensuremath :: TP Exp
+ensuremath = try $ lexeme (string "\\ensuremath") >> inbraces
 
-command :: GenParser Char st String
+command :: TP String
 command = try $ char '\\' >> liftM ('\\':) (identifier <|> lexeme (count 1 anyChar))
 
 unaryOps :: [String]
@@ -319,12 +331,12 @@
 parseText (x:xs) = x : parseText xs
 parseText [] = []
 
-diacritical :: GenParser Char st Exp
+diacritical :: TP Exp
 diacritical = try $ do
   c <- command
   case M.lookup c diacriticals of
        Just r  -> liftM r texToken
-       Nothing -> pzero 
+       Nothing -> pzero
 
 diacriticals :: M.Map String (Exp -> Exp)
 diacriticals = M.fromList
@@ -351,51 +363,51 @@
                , ("\\underline", \e -> EUnder e (ESymbol Accent "\x00AF"))
                ]
 
-unary :: GenParser Char st Exp
+unary :: TP Exp
 unary = try $ do
   c <- command
-  unless (c `elem` unaryOps) pzero 
+  unless (c `elem` unaryOps) pzero
   a <- texToken
   return $ EUnary c a
 
-text :: GenParser Char st Exp
+text :: TP Exp
 text = try $ do
   c <- command
   case M.lookup c textOps of
        Just f   -> liftM f $ braces (many (noneOf "}" <|> (char '\\' >> char '}')))
-       Nothing  -> pzero 
+       Nothing  -> pzero
 
 -- note: sqrt can be unary, \sqrt{2}, or binary, \sqrt[3]{2}
-root :: GenParser Char st Exp
+root :: TP Exp
 root = try $ do
   try (symbol "\\sqrt") <|> symbol "\\surd"
   a <- inbrackets
   b <- texToken
   return $ EBinary "\\sqrt" b a
 
-binary :: GenParser Char st Exp
+binary :: TP Exp
 binary = try $ do
   c <- command
-  unless (c `elem` binaryOps) pzero 
+  unless (c `elem` binaryOps) pzero
   a <- texToken
   b <- texToken
   return $ EBinary c a b
 
-texSymbol :: GenParser Char st Exp
+texSymbol :: TP Exp
 texSymbol = try $ do
   sym <- operator <|> command
   case M.lookup sym symbols of
        Just s   -> return s
-       Nothing  -> pzero 
+       Nothing  -> pzero
 
 -- The lexer
 lexer :: P.TokenParser st
 lexer = P.makeTokenParser texMathDef
-    
+
 lexeme :: CharParser st a -> CharParser st a
 lexeme = P.lexeme lexer
 
-whiteSpace :: CharParser st () 
+whiteSpace :: CharParser st ()
 whiteSpace = P.whiteSpace lexer
 
 identifier :: CharParser st String
@@ -408,7 +420,7 @@
 symbol :: String -> CharParser st String
 symbol = lexeme . P.symbol lexer
 
-braces :: CharParser st a -> CharParser st a 
+braces :: CharParser st a -> CharParser st a
 braces = lexeme . P.braces lexer
 
 brackets :: CharParser st a -> CharParser st a
@@ -500,32 +512,32 @@
            , ("\\varepsilon", EIdentifier "\x025B")
            , ("\\eta", EIdentifier "\x03B7")
            , ("\\gamma", EIdentifier "\x03B3")
-           , ("\\Gamma", ESymbol Op "\x0393") 
+           , ("\\Gamma", ESymbol Op "\x0393")
            , ("\\iota", EIdentifier "\x03B9")
            , ("\\kappa", EIdentifier "\x03BA")
            , ("\\lambda", EIdentifier "\x03BB")
-           , ("\\Lambda", ESymbol Op "\x039B") 
+           , ("\\Lambda", ESymbol Op "\x039B")
            , ("\\mu", EIdentifier "\x03BC")
            , ("\\nu", EIdentifier "\x03BD")
            , ("\\omega", EIdentifier "\x03C9")
            , ("\\Omega", ESymbol Op "\x03A9")
            , ("\\phi", EIdentifier "\x03C6")
            , ("\\varphi", EIdentifier "\x03D5")
-           , ("\\Phi", ESymbol Op "\x03A6") 
+           , ("\\Phi", ESymbol Op "\x03A6")
            , ("\\pi", EIdentifier "\x03C0")
-           , ("\\Pi", ESymbol Op "\x03A0") 
+           , ("\\Pi", ESymbol Op "\x03A0")
            , ("\\psi", EIdentifier "\x03C8")
            , ("\\Psi", ESymbol Ord "\x03A8")
            , ("\\rho", EIdentifier "\x03C1")
            , ("\\sigma", EIdentifier "\x03C3")
-           , ("\\Sigma", ESymbol Op "\x03A3") 
+           , ("\\Sigma", ESymbol Op "\x03A3")
            , ("\\tau", EIdentifier "\x03C4")
            , ("\\theta", EIdentifier "\x03B8")
            , ("\\vartheta", EIdentifier "\x03D1")
-           , ("\\Theta", ESymbol Op "\x0398") 
+           , ("\\Theta", ESymbol Op "\x0398")
            , ("\\upsilon", EIdentifier "\x03C5")
            , ("\\xi", EIdentifier "\x03BE")
-           , ("\\Xi", ESymbol Op "\x039E") 
+           , ("\\Xi", ESymbol Op "\x039E")
            , ("\\zeta", EIdentifier "\x03B6")
            , ("\\frac12", ESymbol Ord "\x00BD")
            , ("\\frac14", ESymbol Ord "\x00BC")
@@ -734,7 +746,7 @@
            , ("\\sup", EMathOperator "sup")
            , ("\\tan", EMathOperator "tan")
            , ("\\tanh", EMathOperator "tanh")
-           ] 
+           ]
 
 -- MathML has a mathvariant attribute which is unimplemented in Firefox
 --    (see https://bugzilla.mozilla.org/show_bug.cgi?id=114365)
diff --git a/texmath.cabal b/texmath.cabal
--- a/texmath.cabal
+++ b/texmath.cabal
@@ -1,5 +1,5 @@
 Name:                texmath
-Version:             0.6.0.2
+Version:             0.6.0.3
 Cabal-Version:       >= 1.6
 Build-type:          Custom
 Synopsis:            Conversion of LaTeX math formulas to MathML or OMML.
