|
Packit Service |
d2f85f |
{-# LANGUAGE FlexibleInstances #-}
|
|
Packit Service |
d2f85f |
{-# LANGUAGE PatternGuards #-}
|
|
Packit Service |
d2f85f |
{-# LANGUAGE TypeSynonymInstances #-}
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
module Text.Pandoc.Readers.Docx.Combine ( smushInlines
|
|
Packit Service |
d2f85f |
, smushBlocks
|
|
Packit Service |
d2f85f |
)
|
|
Packit Service |
d2f85f |
where
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
import Data.List
|
|
Packit Service |
d2f85f |
import Data.Sequence (ViewL (..), ViewR (..), viewl, viewr, (><), (|>))
|
|
Packit Service |
d2f85f |
import qualified Data.Sequence as Seq (null)
|
|
Packit Service |
d2f85f |
import Text.Pandoc.Builder
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
data Modifier a = Modifier (a -> a)
|
|
Packit Service |
d2f85f |
| AttrModifier (Attr -> a -> a) Attr
|
|
Packit Service |
d2f85f |
| NullModifier
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
spaceOutInlinesL :: Inlines -> (Inlines, Inlines)
|
|
Packit Service |
d2f85f |
spaceOutInlinesL ms = (l, stackInlines fs (m' <> r))
|
|
Packit Service |
d2f85f |
where (l, m, r) = spaceOutInlines ms
|
|
Packit Service |
d2f85f |
(fs, m') = unstackInlines m
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
spaceOutInlinesR :: Inlines -> (Inlines, Inlines)
|
|
Packit Service |
d2f85f |
spaceOutInlinesR ms = (stackInlines fs (l <> m'), r)
|
|
Packit Service |
d2f85f |
where (l, m, r) = spaceOutInlines ms
|
|
Packit Service |
d2f85f |
(fs, m') = unstackInlines m
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
spaceOutInlines :: Inlines -> (Inlines, Inlines, Inlines)
|
|
Packit Service |
d2f85f |
spaceOutInlines ils =
|
|
Packit Service |
d2f85f |
let (fs, ils') = unstackInlines ils
|
|
Packit Service |
d2f85f |
contents = unMany ils'
|
|
Packit Service |
d2f85f |
left = case viewl contents of
|
|
Packit Service |
d2f85f |
(Space :< _) -> space
|
|
Packit Service |
d2f85f |
_ -> mempty
|
|
Packit Service |
d2f85f |
right = case viewr contents of
|
|
Packit Service |
d2f85f |
(_ :> Space) -> space
|
|
Packit Service |
d2f85f |
_ -> mempty in
|
|
Packit Service |
d2f85f |
(left, stackInlines fs $ trimInlines . Many $ contents, right)
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
stackInlines :: [Modifier Inlines] -> Inlines -> Inlines
|
|
Packit Service |
d2f85f |
stackInlines [] ms = ms
|
|
Packit Service |
d2f85f |
stackInlines (NullModifier : fs) ms = stackInlines fs ms
|
|
Packit Service |
d2f85f |
stackInlines (Modifier f : fs) ms =
|
|
Packit Service |
d2f85f |
if isEmpty ms
|
|
Packit Service |
d2f85f |
then stackInlines fs ms
|
|
Packit Service |
d2f85f |
else f $ stackInlines fs ms
|
|
Packit Service |
d2f85f |
stackInlines (AttrModifier f attr : fs) ms = f attr $ stackInlines fs ms
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
unstackInlines :: Inlines -> ([Modifier Inlines], Inlines)
|
|
Packit Service |
d2f85f |
unstackInlines ms = case ilModifier ms of
|
|
Packit Service |
d2f85f |
NullModifier -> ([], ms)
|
|
Packit Service |
d2f85f |
_ -> (f : fs, ms') where
|
|
Packit Service |
d2f85f |
f = ilModifier ms
|
|
Packit Service |
d2f85f |
(fs, ms') = unstackInlines $ ilInnards ms
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
ilModifier :: Inlines -> Modifier Inlines
|
|
Packit Service |
d2f85f |
ilModifier ils = case viewl (unMany ils) of
|
|
Packit Service |
d2f85f |
(x :< xs) | Seq.null xs -> case x of
|
|
Packit Service |
d2f85f |
(Emph _) -> Modifier emph
|
|
Packit Service |
d2f85f |
(Strong _) -> Modifier strong
|
|
Packit Service |
d2f85f |
(SmallCaps _) -> Modifier smallcaps
|
|
Packit Service |
d2f85f |
(Strikeout _) -> Modifier strikeout
|
|
Packit Service |
d2f85f |
(Superscript _) -> Modifier superscript
|
|
Packit Service |
d2f85f |
(Subscript _) -> Modifier subscript
|
|
Packit Service |
d2f85f |
(Link attr _ tgt) -> Modifier $ linkWith attr (fst tgt) (snd tgt)
|
|
Packit Service |
d2f85f |
(Span attr _) -> AttrModifier spanWith attr
|
|
Packit Service |
d2f85f |
_ -> NullModifier
|
|
Packit Service |
d2f85f |
_ -> NullModifier
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
ilInnards :: Inlines -> Inlines
|
|
Packit Service |
d2f85f |
ilInnards ils = case viewl (unMany ils) of
|
|
Packit Service |
d2f85f |
(x :< xs) | Seq.null xs -> case x of
|
|
Packit Service |
d2f85f |
(Emph lst) -> fromList lst
|
|
Packit Service |
d2f85f |
(Strong lst) -> fromList lst
|
|
Packit Service |
d2f85f |
(SmallCaps lst) -> fromList lst
|
|
Packit Service |
d2f85f |
(Strikeout lst) -> fromList lst
|
|
Packit Service |
d2f85f |
(Superscript lst) -> fromList lst
|
|
Packit Service |
d2f85f |
(Subscript lst) -> fromList lst
|
|
Packit Service |
d2f85f |
(Link _ lst _) -> fromList lst
|
|
Packit Service |
d2f85f |
(Span _ lst) -> fromList lst
|
|
Packit Service |
d2f85f |
_ -> ils
|
|
Packit Service |
d2f85f |
_ -> ils
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
inlinesL :: Inlines -> (Inlines, Inlines)
|
|
Packit Service |
d2f85f |
inlinesL ils = case viewl $ unMany ils of
|
|
Packit Service |
d2f85f |
(s :< sq) -> (singleton s, Many sq)
|
|
Packit Service |
d2f85f |
_ -> (mempty, ils)
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
inlinesR :: Inlines -> (Inlines, Inlines)
|
|
Packit Service |
d2f85f |
inlinesR ils = case viewr $ unMany ils of
|
|
Packit Service |
d2f85f |
(sq :> s) -> (Many sq, singleton s)
|
|
Packit Service |
d2f85f |
_ -> (ils, mempty)
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
combineInlines :: Inlines -> Inlines -> Inlines
|
|
Packit Service |
d2f85f |
combineInlines x y =
|
|
Packit Service |
d2f85f |
let (xs', x') = inlinesR x
|
|
Packit Service |
d2f85f |
(y', ys') = inlinesL y
|
|
Packit Service |
d2f85f |
in
|
|
Packit Service |
d2f85f |
xs' <> combineSingletonInlines x' y' <> ys'
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
combineSingletonInlines :: Inlines -> Inlines -> Inlines
|
|
Packit Service |
d2f85f |
combineSingletonInlines x y =
|
|
Packit Service |
d2f85f |
let (xfs, xs) = unstackInlines x
|
|
Packit Service |
d2f85f |
(yfs, ys) = unstackInlines y
|
|
Packit Service |
d2f85f |
shared = xfs `intersect` yfs
|
|
Packit Service |
d2f85f |
x_remaining = xfs \\ shared
|
|
Packit Service |
d2f85f |
y_remaining = yfs \\ shared
|
|
Packit Service |
d2f85f |
x_rem_attr = filter isAttrModifier x_remaining
|
|
Packit Service |
d2f85f |
y_rem_attr = filter isAttrModifier y_remaining
|
|
Packit Service |
d2f85f |
in
|
|
Packit Service |
d2f85f |
case null shared of
|
|
Packit Service |
d2f85f |
True | isEmpty xs && isEmpty ys ->
|
|
Packit Service |
d2f85f |
stackInlines (x_rem_attr ++ y_rem_attr) mempty
|
|
Packit Service |
d2f85f |
| isEmpty xs ->
|
|
Packit Service |
d2f85f |
let (sp, y') = spaceOutInlinesL y in
|
|
Packit Service |
d2f85f |
stackInlines x_rem_attr mempty <> sp <> y'
|
|
Packit Service |
d2f85f |
| isEmpty ys ->
|
|
Packit Service |
d2f85f |
let (x', sp) = spaceOutInlinesR x in
|
|
Packit Service |
d2f85f |
x' <> sp <> stackInlines y_rem_attr mempty
|
|
Packit Service |
d2f85f |
| otherwise ->
|
|
Packit Service |
d2f85f |
let (x', xsp) = spaceOutInlinesR x
|
|
Packit Service |
d2f85f |
(ysp, y') = spaceOutInlinesL y
|
|
Packit Service |
d2f85f |
in
|
|
Packit Service |
d2f85f |
x' <> xsp <> ysp <> y'
|
|
Packit Service |
d2f85f |
False -> stackInlines shared $
|
|
Packit Service |
d2f85f |
combineInlines
|
|
Packit Service |
d2f85f |
(stackInlines x_remaining xs)
|
|
Packit Service |
d2f85f |
(stackInlines y_remaining ys)
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
combineBlocks :: Blocks -> Blocks -> Blocks
|
|
Packit Service |
d2f85f |
combineBlocks bs cs
|
|
Packit Service |
d2f85f |
| bs' :> BlockQuote bs'' <- viewr (unMany bs)
|
|
Packit Service |
d2f85f |
, BlockQuote cs'' :< cs' <- viewl (unMany cs) =
|
|
Packit Service |
d2f85f |
Many $ (bs' |> BlockQuote (bs'' <> cs'')) >< cs'
|
|
Packit Service |
d2f85f |
combineBlocks bs cs = bs <> cs
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
instance (Monoid a, Eq a) => Eq (Modifier a) where
|
|
Packit Service |
d2f85f |
(Modifier f) == (Modifier g) = f mempty == g mempty
|
|
Packit Service |
d2f85f |
(AttrModifier f attr) == (AttrModifier g attr') = f attr mempty == g attr' mempty
|
|
Packit Service |
d2f85f |
NullModifier == NullModifier = True
|
|
Packit Service |
d2f85f |
_ == _ = False
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
isEmpty :: (Monoid a, Eq a) => a -> Bool
|
|
Packit Service |
d2f85f |
isEmpty x = x == mempty
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
isAttrModifier :: Modifier a -> Bool
|
|
Packit Service |
d2f85f |
isAttrModifier (AttrModifier _ _) = True
|
|
Packit Service |
d2f85f |
isAttrModifier _ = False
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
smushInlines :: [Inlines] -> Inlines
|
|
Packit Service |
d2f85f |
smushInlines xs = foldl combineInlines mempty xs
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
smushBlocks :: [Blocks] -> Blocks
|
|
Packit Service |
d2f85f |
smushBlocks xs = foldl combineBlocks mempty xs
|