@@ -40,7 +40,7 @@ import Text.Pandoc.Parsing
4040import Data.Maybe ( fromMaybe )
4141import Data.Char ( chr, toUpper )
4242import Data.List ( isPrefixOf, isSuffixOf )
43−import Control.Monad ( when, liftM )
43+import Control.Monad ( when )
4444
4545-- | Parse LaTeX from string and return 'Pandoc' document.
4646readLaTeX :: ParserState -- ^ Parser state, including options for parser
@@ -119,16 +119,17 @@ anyEnvironment = try $ do
119119
120120-- | Process LaTeX preamble, extracting metadata.
121121processLaTeXPreamble :: GenParser Char ParserState ()
122−processLaTeXPreamble =
123− skipMany $ choice [ bibliographic, unknownCommand,
124− commentBlock, skipToken ]
122+processLaTeXPreamble = do
123+ try $ string "\\documentclass"
124+ skipMany $ bibliographic <|> macro <|> commentBlock <|> skipChar
125125
126126-- | Parse LaTeX and return 'Pandoc'.
127127parseLaTeX :: GenParser Char ParserState Pandoc
128128parseLaTeX = do
129+ skipMany $ spaces >> comment
129130 spaces
130− blocks <- try (processLaTeXPreamble >> spaces >> environment "document")
131− <|> (many block >>~ (spaces >> eof))
131+ blocks <- try (processLaTeXPreamble >> environment "document")
132+ <|> (many block >>~ (spaces >> eof))
132133 state <- getState
133134 let blocks' = filter (/= Null) blocks
134135 let title' = stateTitle state
@@ -157,7 +158,6 @@ block = choice [ hrule
157158 , unknownEnvironment
158159 , ignore
159160 , unknownCommand
160− , skipToken
161161 ] <?> "block"
162162
163163--
@@ -407,6 +407,11 @@ unknownEnvironment = try $ do
407407 else anyEnvironment -- otherwise just the contents
408408 return result
409409
410+group :: GenParser Char ParserState Inline
411+group = do
412+ res <- bracketedText '{' '}'
413+ return $ TeX $ "{" ++ res ++ "}"
414+
410415-- \ignore{} is used conventionally in literate haskell for definitions
411416-- that are to be processed by the compiler but not printed.
412417ignore :: GenParser Char ParserState Block
@@ -437,8 +442,12 @@ unknownCommand = try $ do
437442commandsToIgnore :: [String]
438443commandsToIgnore = ["special","pdfannot","pdfstringdef","bibliography"]
439444
440−skipToken :: GenParser Char ParserState Block
441−skipToken = satisfy (/='\\') >> spaces >> return Null
445+skipChar :: GenParser Char ParserState Block
446+skipChar = do
447+ satisfy (/='\\') <|>
448+ (notFollowedBy' (lookAhead $ string "\\begin{document}") >> anyChar)
449+ spaces
450+ return Null
442451
443452commentBlock :: GenParser Char st Block
444453commentBlock = comment >> return Null
@@ -474,6 +483,7 @@ inline = choice [ str
474483 , accentedChar
475484 , nonbreakingSpace
476485 , cite
486+ , group
477487 , specialChar
478488 , rawLaTeXInline'
479489 , escapedChar
@@ -906,7 +916,7 @@ rawLaTeXInline' :: GenParser Char ParserState Inline
906916rawLaTeXInline' = do
907917 notFollowedBy' $ oneOfStrings ["\\begin", "\\end", "\\item", "\\ignore",
908918 "\\section"]
909− rawLaTeXInline <|> liftM TeX (bracketedText '{' '}')
919+ rawLaTeXInline
910920
911921-- | Parse any LaTeX command and return it in a raw TeX inline element.
912922rawLaTeXInline :: GenParser Char ParserState Inline