git.iko.soy/typeable/pandoc
on master help sign in
codeblock handling
commit34f9ac9dbf8615e5dc8a8f803385d929bfa585c1 authorYan Pas <yanp.bugz@gmail.com> dateWed 9 May 2018, 19:25 (8 years ago) parent83902ff
1 file changed+61−21
src/Text/Pandoc/Readers/Man.hs+61−21
src/Text/Pandoc/Readers/Man.hs+61−21
@@ -35,7 +35,7 @@ module Text.Pandoc.Readers.Man where
3535import Control.Monad.Except (throwError)
3636import Data.Default (Default)
3737import Data.Map (insert)
38−import Data.Maybe (isJust, maybeToList)
38+import Data.Maybe (isJust, fromMaybe)
3939import Data.List (intersperse, intercalate)
4040import qualified Data.Text as T
4141
@@ -109,9 +109,13 @@ parseMacro = do
109109 macroName <- many1 (letter <|> oneOf ['\\', '"'])
110110 args <- parseArgs
111111 let joinedArgs = concat $ intersperse " " args
112− let toBold = return $ Plain [Strong [Str joinedArgs]]
113− let toBoldItalic = return $ Plain [Strong [Emph [Str joinedArgs]]]
114− let toItalic = return $ Plain [Emph [Str joinedArgs]]
112+ ManState { rState = rst } <- getState
113+ let toTextF transf = if inCodeBlock rst then [Code nullAttr joinedArgs] else transf [Str joinedArgs]
114+ let toText = return . Plain . toTextF
115+ let toBold = toText (\s -> [Strong s])
116+ let toItalic = toText (\s -> [Emph s])
117+ let toBoldItalic = toText (\s -> [Strong [Emph s]])
118+
115119 case macroName of
116120 "\\\"" -> return Null -- comment
117121 "TH" -> macroTitle (if null args then "" else head args) -- man-title
@@ -120,14 +124,14 @@ parseMacro = do
120124 "nf" -> macroCodeBlock True >> return Null
121125 "fi" -> macroCodeBlock False >> return Null
122126 "B" -> toBold
123− "BR" -> return $ linkToMan joinedArgs
127+ "BR" -> return $ macroBR joinedArgs (inCodeBlock rst)
124128 "BI" -> toBoldItalic
125129 "IB" -> toBoldItalic
126130 "I" -> toItalic
127131 "IR" -> toItalic
128132 "RI" -> toItalic
129133 "SH" -> return $ Header 2 nullAttr [Str joinedArgs]
130− "sp" -> return $ Plain [LineBreak]
134+ "sp" -> return $ if inCodeBlock rst then Null else Plain [LineBreak]
131135 _ -> unkownMacro macroName
132136
133137 where
@@ -148,10 +152,14 @@ parseMacro = do
148152 macroCodeBlock :: PandocMonad m => Bool -> ManParser m ()
149153 macroCodeBlock insideCB = modifyRoffState (\rst -> rst{inCodeBlock = insideCB}) >> return ()
150154
151− linkToMan :: String -> Block
155+ macroBR :: String -> Bool -> Block
156+ macroBR txt inCode | inCode = Plain [Code nullAttr txt]
157+ | otherwise = fromMaybe (Plain [Strong [Str txt]]) (linkToMan txt)
158+
159+ linkToMan :: String -> Maybe Block
152160 linkToMan txt = case runParser linkParser () "" txt of
153− Right lnk -> Plain [lnk]
154− Left _ -> Plain [Emph [Str txt]]
161+ Right lnk -> Just $ Plain [lnk]
162+ Left _ -> Nothing
155163 where
156164 linkParser :: Parsec String () Inline
157165 linkParser = do
@@ -199,8 +207,8 @@ parseMacro = do
199207
200208roffInline :: RoffState -> String -> [Inline]
201209roffInline rst str
202− | null str = []
203− | inCodeBlock rst = [Code nullAttr str, LineBreak]
210+ | null str && (not $ inCodeBlock rst) = []
211+ | inCodeBlock rst = [Code nullAttr str]
204212 | otherwise = case fontKind rst of
205213 Regular -> [Str str]
206214 Italic -> [Emph [Str str]]
@@ -245,19 +253,51 @@ parseLine = do
245253 ]
246254 >> return Nothing
247255
256+finds :: (a -> Bool) -> [a] -> ([a], [a])
257+finds predic els = let matched = finds' els
258+ in (matched, drop (length matched) els) where
259+ finds' [] = []
260+ finds' (e:es) | predic e = e : finds' es
261+ | otherwise = []
262+
263+-- | return (matched, notmatched, others)
264+findsBoth :: (a -> Bool) -> [a] -> ([a], [a], [a])
265+findsBoth predic els =
266+ let (matched, els') = finds predic els
267+ (notmatched, els'') = finds (not . predic) els'
268+ in (matched, notmatched, els'')
269+
248270createParas :: [Block] -> [Block]
249271createParas bs = inner bs [] where
250272 inner :: [Block] -> [Inline] -> [Block]
251− inner [] inls = maybeToList $ inlinesToPara inls
252− inner (Plain einls : oth) inls = inner oth (inls ++ einls)
253− inner (block : oth) inls = case inlinesToPara inls of
254− Just par -> par : block : inner oth []
255− Nothing -> block : inner oth []
256−
257− inlinesToPara :: [Inline] -> Maybe Block
258− inlinesToPara [] = Nothing
259− inlinesToPara inls = Just $ Para (intersperse (Str " ") inls)
260−
273+ inner [] inls = plainInlinesToPara inls
274+ inner (Plain einls : oth) inls = inner oth (inls ++ joinCode einls)
275+ inner (block : oth) inls = (plainInlinesToPara inls ++ [block]) ++ inner oth []
276+
277+ joinCode :: [Inline] -> [Inline]
278+ joinCode inls =
279+ let (codes, notcodes) = finds isCode inls
280+ codeStr (Code _ s) = s
281+ codeStr _ = ""
282+ joined = Code nullAttr (concat $ codeStr <$> codes)
283+ in if null codes
284+ then notcodes
285+ else joined : notcodes
286+
287+ plainInlinesToPara :: [Inline] -> [Block]
288+ plainInlinesToPara [] = []
289+ plainInlinesToPara inls =
290+ let (cds, ncds, oth) = findsBoth isCode inls
291+ codeToStr (Code _ s) = s
292+ codeToStr _ = ""
293+ cbs = if null cds
294+ then []
295+ else [CodeBlock nullAttr (intercalate "\n" $ codeToStr <$> cds)]
296+ paras = [Para (intersperse (Str " ") ncds)]
297+ in cbs ++ paras ++ plainInlinesToPara oth
298+
299+ isCode (Code _ _) = True
300+ isCode _ = False
261301
262302parseMan :: PandocMonad m => ManParser m Pandoc
263303parseMan = do