module Language.LaTeX.Slicer
(marknote, mark, marker, (^$), slice)
where
import Data.Monoid
import Control.Monad.Writer
import Language.LaTeX.Types
import Language.LaTeX.Builder.MonoidUtils
import qualified Language.LaTeX.Builder.Internal as BI
import qualified Data.Generics.Uniplate.Data as U
marknote :: ParItm
marknote = ParNote (MkKey "slicemark") BI.nilNote ΓΈ
mark :: ParItemW
mark = tell $ return marknote
marker :: Writer ParItem a -> Writer ParItem a
marker f = do mark
x <- f
mark
return x
infixr 0 ^$
(^$) :: (b -> Writer ParItem a) -> b -> Writer ParItem a
f ^$ x = marker (f x)
slice :: Functor f => f ParItm -> f ParItm
slice = fmap $ mconcat . mconcat . comb [maySlice1, maySlice2, id] . uncatParItm
where notMark = (/= marknote)
isMarked = any (== marknote) . U.universe
maySlice1 = takeWhile notMark . drop 1 . dropWhile notMark
maySlice2 = filter isMarked
comb fs xs = take 1 . filter (not . null) . map ($xs) $ fs