I wrote a filter for pandas that converts :-)
to ☺
but not in inline code or code blocks. Pandoc makes it so the applyExceptOnCodeBlock smileyfy
function trickles through the whole tree. But since I operate on Block
s and Inline
s I need to handle every data constructor for Block
that takes Inline
s.
import Text.Pandoc.JSON
import Text.Pandoc.Walk
import Data.List (intercalate)
import Data.List.Split (splitOn)
main :: IO ()
main = toJSONFilter $ applyExceptOnCodeBlock smileyfy
smileyfy :: String -> String
smileyfy = intercalate "☺" . splitOn ":-)"
applyExceptOnCodeInline :: (String -> String) -> Inline -> Inline
applyExceptOnCodeInline f (Str s) = Str (f s)
applyExceptOnCodeInline f (Code attr s) = Code attr s -- for code nothing shall happen
applyExceptOnCodeInline _ x = x
applyExceptOnCodeBlock :: (String -> String) -> Block -> Block
applyExceptOnCodeBlock f (Plain is) = Plain $ applyExceptOnCodeInline f <$> is
applyExceptOnCodeBlock f (Para is) = Para $ applyExceptOnCodeInline f <$> is
applyExceptOnCodeBlock f (LineBlock iss) = LineBlock $ (fmap . fmap) (applyExceptOnCodeInline f) iss
applyExceptOnCodeBlock f (RawBlock format s) = RawBlock format $ f s
applyExceptOnCodeBlock f (DefinitionList [(is, bss)]) = DefinitionList [(applyExceptOnCodeInline f <$> is
,fmap (fmap (applyExceptOnCodeBlock f)) bss)]
applyExceptOnCodeBlock f (Header i attr is) = Header i attr $ applyExceptOnCodeInline f <$> is
applyExceptOnCodeBlock f (Table is as ds tcs tcss) = Table (applyExceptOnCodeInline f <$> is) as ds tcs tcss
applyExceptOnCodeBlock _ x = x --this covers CodeBlock as well
And thus it looks very convoluted. Is there a clearer way to express this?