@@ -199,8 +199,23 @@ blockCommand = try $ do
199inBrackets :: Inlines -> Inlines
199inBrackets :: Inlines -> Inlines
200inBrackets x = (str "[") <> x <> (str "]")
200inBrackets x = (str "[") <> x <> (str "]")
202+-- eat an optional argument and one or more arguments in braces
203+ignoreInlines :: String -> (String, LP Inlines)
204+ignoreInlines name = (name, doraw <|> (mempty <$ optargs))
205+ where optargs = optional opt *> skipMany (optional sp *> braced)
207+ doraw = (rawInline "latex" . (contseq ++) . snd) <$>
208+ (getState >>= guard . stateParseRaw >> (withRaw optargs))
210+ignoreBlocks :: String -> (String, LP Blocks)
211+ignoreBlocks name = (name, doraw <|> (mempty <$ optargs))
212+ where optargs = optional opt *> skipMany (optional sp *> braced)
214+ doraw = (rawBlock "latex" . (contseq ++) . snd) <$>
215+ (getState >>= guard . stateParseRaw >> (withRaw optargs))
202blockCommands :: M.Map String (LP Blocks)
217blockCommands :: M.Map String (LP Blocks)
203−blockCommands = M.fromList
218+blockCommands = M.fromList $
204 [ ("par", pure mempty)
219 [ ("par", pure mempty)
205 , ("title", mempty <$ (tok >>= addTitle))
220 , ("title", mempty <$ (tok >>= addTitle))
206 , ("subtitle", mempty <$ (tok >>= addSubtitle))
221 , ("subtitle", mempty <$ (tok >>= addSubtitle))
@@ -209,11 +224,7 @@ blockCommands = M.fromList
209 , ("address", mempty <$ (tok >>= addTitle))
224 , ("address", mempty <$ (tok >>= addTitle))
210 , ("signature", mempty <$ authors)
225 , ("signature", mempty <$ authors)
211 , ("date", mempty <$ (tok >>= addDate))
226 , ("date", mempty <$ (tok >>= addDate))
212− , ("maketitle", pure mempty)
227+ -- sectioning
213− -- \ignore{} is used conventionally in literate haskell for definitions
214− -- that are to be processed by the compiler but not printed.
215− , ("ignore", mempty <$ tok)
216− , ("hyperdef", mempty <$ (tok *> tok))
217 , ("chapter", updateState (\s -> s{ stateHasChapters = True }) *> section 0)
228 , ("chapter", updateState (\s -> s{ stateHasChapters = True }) *> section 0)
218 , ("section", section 1)
229 , ("section", section 1)
219 , ("subsection", section 2)
230 , ("subsection", section 2)
@@ -221,23 +232,27 @@ blockCommands = M.fromList
221 , ("paragraph", section 4)
232 , ("paragraph", section 4)
222 , ("subparagraph", section 5)
233 , ("subparagraph", section 5)
223 , ("opening", (para . trimInlines) <$> tok)
234 , ("opening", (para . trimInlines) <$> tok)
224− , ("closing", (para . trimInlines) <$> tok)
235+ , ("closing", closing)
225 , ("rule", optional opt *> tok *> tok *> pure horizontalRule)
236 , ("rule", optional opt *> tok *> tok *> pure horizontalRule)
226 , ("begin", mzero) -- these are here so they won't be interpreted as inline
237 , ("begin", mzero) -- these are here so they won't be interpreted as inline
227 , ("end", mzero)
238 , ("end", mzero)
228 , ("item", loose_item)
239 , ("item", loose_item)
229 , ("documentclass", optional opt *> braced *> preamble)
240 , ("documentclass", optional opt *> braced *> preamble)
241+ ] ++ map ignoreBlocks
242+ -- these commands will be ignored unless --parse-raw is specified,
243+ -- in which case they will appear as raw latex blocks
244+ [ "newcommand", "renewcommand", "newenvironment", "renewenvironment"
230− -- should be parsed by macro, but we need this
245+ -- newcommand, etc. should be parsed by macro, but we need this
231− -- here so these aren't parsed as inline
246+ -- here so these aren't parsed as inline commands to ignore
232− , ("newcommand", mempty <$ (tok *> optional opt *> tok))
233− , ("renewcommand", mempty <$ (tok *> optional opt *> tok))
234− , ("newenvironment", mempty <$ (tok *> tok *> tok))
235− , ("renewenvironment", mempty <$ (tok *> tok *> tok))
236− , ("special", pure mempty)
237− , ("pdfannot", pure mempty)
238− , ("pdfstringdef", pure mempty)
247+ , "special", "pdfannot", "pdfstringdef"
239− , ("index", pure mempty)
248+ , "bibliography", "maketitle", "makeindex", "makeglossary"
240− , ("bibliography", pure mempty)
249+ , "addcontentsline", "addtocontents", "addtocounter"
250+ -- \ignore{} is used conventionally in literate haskell for definitions
251+ -- that are to be processed by the compiler but not printed.
255+ , "markboth", "markright", "markleft"
243addTitle :: Inlines -> LP ()
258addTitle :: Inlines -> LP ()
@@ -288,7 +303,7 @@ isBlockCommand :: String -> Bool
288isBlockCommand s = maybe False (const True) $ M.lookup s blockCommands
303isBlockCommand s = maybe False (const True) $ M.lookup s blockCommands
290inlineCommands :: M.Map String (LP Inlines)
305inlineCommands :: M.Map String (LP Inlines)
291−inlineCommands = M.fromList
306+inlineCommands = M.fromList $
292 [ ("emph", emph <$> tok)
307 [ ("emph", emph <$> tok)
293 , ("textit", emph <$> tok)
308 , ("textit", emph <$> tok)
294 , ("textsc", smallcaps <$> tok)
309 , ("textsc", smallcaps <$> tok)
@@ -307,6 +322,8 @@ inlineCommands = M.fromList
307 , ("(", mathInline $ manyTill anyChar (try $ string "\\)"))
322 , ("(", mathInline $ manyTill anyChar (try $ string "\\)"))
308 , ("[", mathDisplay $ manyTill anyChar (try $ string "\\]"))
323 , ("[", mathDisplay $ manyTill anyChar (try $ string "\\]"))
309 , ("ensuremath", mathInline $ braced)
324 , ("ensuremath", mathInline $ braced)
310 , ("$", lit "$")
327 , ("$", lit "$")
311 , ("%", lit "%")
328 , ("%", lit "%")
312 , ("&", lit "&")
329 , ("&", lit "&")
@@ -339,7 +356,6 @@ inlineCommands = M.fromList
339 , ("pounds", lit "£")
356 , ("pounds", lit "£")
340 , ("euro", lit "€")
357 , ("euro", lit "€")
341 , ("copyright", lit "©")
358 , ("copyright", lit "©")
343 , ("`", option (str "`") $ try $ tok >>= accent grave)
359 , ("`", option (str "`") $ try $ tok >>= accent grave)
344 , ("'", option (str "'") $ try $ tok >>= accent acute)
360 , ("'", option (str "'") $ try $ tok >>= accent acute)
345 , ("^", option (str "^") $ try $ tok >>= accent hat)
361 , ("^", option (str "^") $ try $ tok >>= accent hat)
@@ -352,6 +368,7 @@ inlineCommands = M.fromList
352 , (",", pure mempty)
368 , (",", pure mempty)
353 , ("@", pure mempty)
369 , ("@", pure mempty)
354 , (" ", lit "\160")
370 , (" ", lit "\160")
371+ , ("ps", pure $ str "PS." <> space)
355 , ("bar", lit "|")
372 , ("bar", lit "|")
356 , ("textless", lit "<")
373 , ("textless", lit "<")
357 , ("textgreater", lit ">")
374 , ("textgreater", lit ">")
@@ -417,7 +434,10 @@ inlineCommands = M.fromList
417 , ("citeauthor", (try (tok *> optional sp *> controlSeq "citetext") *>
434 , ("citeauthor", (try (tok *> optional sp *> controlSeq "citetext") *>
418 complexNatbibCitation AuthorInText)
435 complexNatbibCitation AuthorInText)
419 <|> citation AuthorInText False)
436 <|> citation AuthorInText False)
420− ]
437+ ] ++ map ignoreInlines
438+ -- these commands will be ignored unless --parse-raw is specified,
439+ -- in which case they will appear as raw latex blocks:
422unescapeURL :: String -> String
442unescapeURL :: String -> String
423unescapeURL ('\\':x:xs) | isEscapable x = x:unescapeURL xs
443unescapeURL ('\\':x:xs) | isEscapable x = x:unescapeURL xs
@@ -573,7 +593,8 @@ handleIncludes ('\\':xs) =
573 yss <- mapM getfile fs
593 yss <- mapM getfile fs
574 (intercalate "\n" yss ++) `fmap`
594 (intercalate "\n" yss ++) `fmap`
575 handleIncludes rest
595 handleIncludes rest
576− _ -> case runParser verbatimEnv defaultParserState "input" ('\\':xs) of
596+ _ -> case runParser (verbCmd <|> verbatimEnv) defaultParserState
597+ "input" ('\\':xs) of
577 Right (r, rest) -> (r ++) `fmap` handleIncludes rest
598 Right (r, rest) -> (r ++) `fmap` handleIncludes rest
578 _ -> ('\\':) `fmap` handleIncludes xs
599 _ -> ('\\':) `fmap` handleIncludes xs
579handleIncludes (x:xs) = (x:) `fmap` handleIncludes xs
600handleIncludes (x:xs) = (x:) `fmap` handleIncludes xs
@@ -589,6 +610,15 @@ include = do
589 else map (flip replaceExtension ".sty") fs
610 else map (flip replaceExtension ".sty") fs
590 return (fs', rest)
611 return (fs', rest)
613+verbCmd :: LP (String, String)
615+ (_,r) <- withRaw $ do
618+ manyTill anyChar (char c)
592verbatimEnv :: LP (String, String)
622verbatimEnv :: LP (String, String)
593verbatimEnv = do
623verbatimEnv = do
594 (_,r) <- withRaw $ do
624 (_,r) <- withRaw $ do
@@ -659,12 +689,19 @@ letter_contents = do
659 -- add signature (author) and address (title)
689 -- add signature (author) and address (title)
660 let addr = case stateTitle st of
690 let addr = case stateTitle st of
661 [] -> mempty
691 [] -> mempty
662− x -> para $ fromList x
692+ x -> para $ trimInlines $ fromList x
693+ updateState $ \s -> s{ stateAuthors = [], stateTitle = [] }
694+ return $ addr <> bs -- sig added by \closing
663 let sigs = case stateAuthors st of
700 let sigs = case stateAuthors st of
664 [] -> mempty
701 [] -> mempty
702+ xs -> para $ trimInlines $ fromList
665− xs -> para $ fromList $ intercalate [LineBreak] xs
703+ $ intercalate [LineBreak] xs
666− updateState $ \s -> s{ stateAuthors = [], stateTitle = [] }
667− return $ addr <> bs <> sigs
704+ return $ para (trimInlines contents) <> sigs
669item :: LP Blocks
706item :: LP Blocks
670item = blocks *> controlSeq "item" *> optional opt *> blocks
707item = blocks *> controlSeq "item" *> optional opt *> blocks