Could somebody help me work out how to abstract the recursion from this code for me please? I'm trying to write something that takes a pandoc structure, and subdivides the tree whenever it finds a sentence, so:
<span>This sentence. Should split.</span>
becomes:
<span>
<span { sentence }>This sentence.</span>
<span { sentence }> Should split.</span>
</span>
I have a working implementation, but the recursive part is a bit repetitive:
segment :: [Inline] -> [Inline]
segment [] = []
segment [el] = [el]
segment els @ (head:tail) =
case head of
Emph ch -> map (Emph . toList) (segment ch) ++ segment tail
Strong ch -> map (Strong . toList) (segment ch) ++ segment tail
Strikeout ch -> map (Strikeout . toList) (segment ch) ++ segment tail
Superscript ch -> map (Superscript . toList) (segment ch) ++ segment tail
Subscript ch -> map (Subscript . toList) (segment ch) ++ segment tail
SmallCaps ch -> map (SmallCaps. toList) (segment ch) ++ segment tail
Quoted qt ch -> map (Quoted qt . toList) (segment ch) ++ segment tail
Cite cs ch -> map (Cite cs . toList) (segment ch) ++ segment tail
Span attr ch -> map (Span attr . toList) (segment ch) ++ segment tail
_ ->
maybe [sentence els] (\i -> (sentence $ take i els) : segment (drop i els))
$ (1 +) <$> List.findIndex split els
where
sentence = Span ("sentence", [], [])
split :: Inline -> Bool
split (Str str) = endsWith "." str || endsWith "?" str || endsWith "!" str
split _ = False
endsWith :: String -> String -> Bool
endsWith suff str = suff `List.isSuffixOf` str
toList :: a -> [a]
toList = (: [])
I'm trying to work out a way to hand in some f
that will model the part that splits the structure
(i.e the bottom bit), but I'm struggling as the function has to be [Inline] -> [Inline]
, it's also
as if it needs to be Inline -> [Inline] -> [Inline]
as each of the recursive steps need the original
constructor in order to preserve the structure of the document, ie:
<span><strong>This sentence. Should split.</strong></span>
becomes:
<span>
<strong><span { sentence }>This sentence.</span></strong>
<strong><span { sentence }> Should split.</span></strong>
</span>
walk
fromText.Pandoc.Walk
(in packagepandoc-types
). \$\endgroup\$Image
andLink
constructors, which are omitted here. One oftransformOf (each . inlinePrePlate)
andtransformOf (inlinePrePlate . each)
could do that job, though. \$\endgroup\$