@@ -40,7 +40,7 @@ import Text.Pandoc.Parsing
40import Data.Maybe ( fromMaybe )
40import Data.Maybe ( fromMaybe )
41import Data.Char ( chr, toUpper )
41import Data.Char ( chr, toUpper )
42import Data.List ( isPrefixOf, isSuffixOf )
42import Data.List ( isPrefixOf, isSuffixOf )
43−import Control.Monad ( when, liftM )
43+import Control.Monad ( when )
45-- | Parse LaTeX from string and return 'Pandoc' document.
45-- | Parse LaTeX from string and return 'Pandoc' document.
46readLaTeX :: ParserState -- ^ Parser state, including options for parser
46readLaTeX :: ParserState -- ^ Parser state, including options for parser
@@ -119,16 +119,17 @@ anyEnvironment = try $ do
120-- | Process LaTeX preamble, extracting metadata.
120-- | Process LaTeX preamble, extracting metadata.
121processLaTeXPreamble :: GenParser Char ParserState ()
121processLaTeXPreamble :: GenParser Char ParserState ()
122−processLaTeXPreamble =
122+processLaTeXPreamble = do
123+ try $ string "\\documentclass"
123− skipMany $ choice [ bibliographic, unknownCommand,
124+ skipMany $ bibliographic <|> macro <|> commentBlock <|> skipChar
124− commentBlock, skipToken ]
126-- | Parse LaTeX and return 'Pandoc'.
126-- | Parse LaTeX and return 'Pandoc'.
127parseLaTeX :: GenParser Char ParserState Pandoc
127parseLaTeX :: GenParser Char ParserState Pandoc
128parseLaTeX = do
128parseLaTeX = do
129+ skipMany $ spaces >> comment
130− blocks <- try (processLaTeXPreamble >> spaces >> environment "document")
131+ blocks <- try (processLaTeXPreamble >> environment "document")
131− <|> (many block >>~ (spaces >> eof))
132+ <|> (many block >>~ (spaces >> eof))
132 state <- getState
133 state <- getState
133 let blocks' = filter (/= Null) blocks
134 let blocks' = filter (/= Null) blocks
134 let title' = stateTitle state
135 let title' = stateTitle state
@@ -157,7 +158,6 @@ block = choice [ hrule
157 , unknownEnvironment
158 , unknownEnvironment
159 , unknownCommand
160 , unknownCommand
161 ] <?> "block"
161 ] <?> "block"
@@ -407,6 +407,11 @@ unknownEnvironment = try $ do
407 else anyEnvironment -- otherwise just the contents
407 else anyEnvironment -- otherwise just the contents
408 return result
408 return result
410+group :: GenParser Char ParserState Inline
412+ res <- bracketedText '{' '}'
413+ return $ TeX $ "{" ++ res ++ "}"
410-- \ignore{} is used conventionally in literate haskell for definitions
415-- \ignore{} is used conventionally in literate haskell for definitions
411-- that are to be processed by the compiler but not printed.
416-- that are to be processed by the compiler but not printed.
412ignore :: GenParser Char ParserState Block
417ignore :: GenParser Char ParserState Block
@@ -437,8 +442,12 @@ unknownCommand = try $ do
437commandsToIgnore :: [String]
442commandsToIgnore :: [String]
438commandsToIgnore = ["special","pdfannot","pdfstringdef","bibliography"]
443commandsToIgnore = ["special","pdfannot","pdfstringdef","bibliography"]
440−skipToken :: GenParser Char ParserState Block
445+skipChar :: GenParser Char ParserState Block
447+ satisfy (/='\\') <|>
448+ (notFollowedBy' (lookAhead $ string "\\begin{document}") >> anyChar)
441−skipToken = satisfy (/='\\') >> spaces >> return Null
450+ return Null
443commentBlock :: GenParser Char st Block
452commentBlock :: GenParser Char st Block
444commentBlock = comment >> return Null
453commentBlock = comment >> return Null
@@ -474,6 +483,7 @@ inline = choice [ str
474 , accentedChar
483 , accentedChar
475 , nonbreakingSpace
484 , nonbreakingSpace
477 , specialChar
487 , specialChar
478 , rawLaTeXInline'
488 , rawLaTeXInline'
479 , escapedChar
489 , escapedChar
@@ -906,7 +916,7 @@ rawLaTeXInline' :: GenParser Char ParserState Inline
906rawLaTeXInline' = do
916rawLaTeXInline' = do
907 notFollowedBy' $ oneOfStrings ["\\begin", "\\end", "\\item", "\\ignore",
917 notFollowedBy' $ oneOfStrings ["\\begin", "\\end", "\\item", "\\ignore",
908 "\\section"]
918 "\\section"]
909− rawLaTeXInline <|> liftM TeX (bracketedText '{' '}')
919+ rawLaTeXInline
911-- | Parse any LaTeX command and return it in a raw TeX inline element.
921-- | Parse any LaTeX command and return it in a raw TeX inline element.
912rawLaTeXInline :: GenParser Char ParserState Inline
922rawLaTeXInline :: GenParser Char ParserState Inline