git.iko.soy/typeable/pandoc
on master help sign in
Man reader: handle inline macros like .BI in code blocks.
2d785c1John MacFarlane
src/Text/Pandoc/Readers/Man.hs+58−38
@@ -48,6 +48,7 @@ import Text.Pandoc.Error (PandocError (PandocParsecError))
48import Text.Pandoc.Logging (LogMessage(..))
48import Text.Pandoc.Logging (LogMessage(..))
49import Text.Pandoc.Options
49import Text.Pandoc.Options
50import Text.Pandoc.Parsing
50import Text.Pandoc.Parsing
51+import Text.Pandoc.Walk (query)
51import Text.Pandoc.Shared (crFilter)
52import Text.Pandoc.Shared (crFilter)
52import Text.Pandoc.Readers.Roff -- TODO explicit imports
53import Text.Pandoc.Readers.Roff -- TODO explicit imports
53import Text.Parsec hiding (tokenPrim)
54import Text.Parsec hiding (tokenPrim)
@@ -306,29 +307,33 @@ parseInline = try $ do
306 tok <- mtoken
307 tok <- mtoken
307 case tok of
308 case tok of
308 MLine lparts -> return $ linePartsToInlines lparts
309 MLine lparts -> return $ linePartsToInlines lparts
309− MMacro mname args _pos ->
310+ MMacro mname args pos -> handleInlineMacro mname args pos
311+ _ -> mzero
312+
313+handleInlineMacro :: PandocMonad m
314+ => String -> [Arg] -> SourcePos -> ManParser m Inlines
315+handleInlineMacro mname args _pos = do
310− case mname of
316+ case mname of
311− "UR" -> parseLink args
317+ "UR" -> parseLink args
312− "MT" -> parseEmailLink args
318+ "MT" -> parseEmailLink args
313− "B" -> parseBold args
319+ "B" -> parseBold args
314− "I" -> parseItalic args
320+ "I" -> parseItalic args
315− "br" -> return linebreak
321+ "br" -> return linebreak
316− "BI" -> parseAlternatingFonts [strong, emph] args
322+ "BI" -> parseAlternatingFonts [strong, emph] args
317− "IB" -> parseAlternatingFonts [emph, strong] args
323+ "IB" -> parseAlternatingFonts [emph, strong] args
318− "IR" -> parseAlternatingFonts [emph, id] args
324+ "IR" -> parseAlternatingFonts [emph, id] args
319− "RI" -> parseAlternatingFonts [id, emph] args
325+ "RI" -> parseAlternatingFonts [id, emph] args
320− "BR" -> parseAlternatingFonts [strong, id] args
326+ "BR" -> parseAlternatingFonts [strong, id] args
321− "RB" -> parseAlternatingFonts [id, strong] args
327+ "RB" -> parseAlternatingFonts [id, strong] args
322− "SY" -> return $ strong $ mconcat $ intersperse B.space
328+ "SY" -> return $ strong $ mconcat $ intersperse B.space
323− $ map linePartsToInlines args
329+ $ map linePartsToInlines args
324− "YS" -> return mempty
330+ "YS" -> return mempty
325− "OP" -> case args of
331+ "OP" -> case args of
326− (x:ys) -> return $ B.space <> str "[" <> B.space <>
332+ (x:ys) -> return $ B.space <> str "[" <> B.space <>
327− mconcat (strong (linePartsToInlines x) :
333+ mconcat (strong (linePartsToInlines x) :
328− map ((B.space <>) . linePartsToInlines) ys)
334+ map ((B.space <>) . linePartsToInlines) ys)
329− <> B.space <> str "]"
335+ <> B.space <> str "]"
330− [] -> return mempty
336+ [] -> return mempty
331− _ -> mzero
332 _ -> mzero
337 _ -> mzero
333
338
334parseBold :: PandocMonad m => [Arg] -> ManParser m Inlines
339parseBold :: PandocMonad m => [Arg] -> ManParser m Inlines
@@ -375,24 +380,39 @@ endmacro name = void (mmacro name)
375parseCodeBlock :: PandocMonad m => ManParser m Blocks
380parseCodeBlock :: PandocMonad m => ManParser m Blocks
376parseCodeBlock = try $ do
381parseCodeBlock = try $ do
377 optional bareIP -- some people indent their code
382 optional bareIP -- some people indent their code
378− toks <- (mmacro "nf" *> many (mline <|> memptyLine) <* endmacro "fi")
383+ toks <- (mmacro "nf" *> manyTill codeline (endmacro "fi"))
379− <|> (mmacro "EX" *> many (mline <|> memptyLine) <* endmacro "EE")
384+ <|> (mmacro "EX" *> manyTill codeline (endmacro "EE"))
380− return $ codeBlock (intercalate "\n" . catMaybes $
385+ return $ codeBlock (intercalate "\n" $ catMaybes toks)
381− extractText <$> toks)
382
386
383 where
387 where
384
388
385− extractText :: RoffToken -> Maybe String
389+ codeline = do
390+ tok <- mtoken
391+ case tok of
392+ MMacro mname args pos -> do
393+ (Just . query getText <$> handleInlineMacro mname args pos) <|>
394+ do report $ SkippedContent ('.':mname) pos
395+ return Nothing
396+ MTable _ _ pos -> do
397+ report $ SkippedContent "TABLE" pos
398+ return $ Just "TABLE"
399+ MEmptyLine -> return $ Just ""
386− extractText (MLine ss)
400+ MLine ss
387− | not (null ss)
401+ | not (null ss)
388− , all isFontToken ss = Nothing
402+ , all isFontToken ss -> return Nothing
389− | otherwise = Just $ linePartsToString ss
403+ | otherwise -> return $ Just $ linePartsToString ss
404+
390− where isFontToken FontSize{} = True
405+ isFontToken FontSize{} = True
391− isFontToken Font{} = True
406+ isFontToken Font{} = True
392− isFontToken _ = False
407+ isFontToken _ = False
393− extractText MEmptyLine = Just ""
408+
394− -- string are intercalated with '\n', this prevents double '\n'
409+ getText :: Inline -> String
395− extractText _ = Nothing
410+ getText (Str s) = s
411+ getText Space = " "
412+ getText (Code _ s) = s
413+ getText SoftBreak = "\n"
414+ getText LineBreak = "\n"
415+ getText _ = ""
396
416
397parseHeader :: PandocMonad m => ManParser m Blocks
417parseHeader :: PandocMonad m => ManParser m Blocks
398parseHeader = do
418parseHeader = do