    module Data.String.Interpolate.Whitespace where

    import Data.List ( intercalate )

    import Data.String.Interpolate.Types

    -- |
    -- Collapse all the lines given into a single line, collapsing any whitespace
    -- found into a single space and removing begining/trailing whitespace.
    collapseWhitespace :: Lines -> Line
    collapseWhitespace :: Lines -> Line
    collapseWhitespace Lines
    lines =
      let oneliner :: Line
    oneliner = Line -> Lines -> Line
    forall a. [a] -> [[a]] -> [a]
    intercalate [Int -> InterpSegment
    Spaces Int
    1] Lines
    lines
      in Line -> Line
    removeSurroundingWS (Line -> Line) -> Line -> Line
    forall a b. (a -> b) -> a -> b
    $ Line -> Line
    toSingleSpace Line
    oneliner

    toSingleSpace :: Line -> Line
    toSingleSpace :: Line -> Line
    toSingleSpace [] = []
    toSingleSpace (InterpSegment
    x:InterpSegment
    y:Line
    xs) | InterpSegment -> Bool
    isSpace InterpSegment
    x Bool -> Bool -> Bool
    && InterpSegment -> Bool
    isSpace InterpSegment
    y =
      Line -> Line
    toSingleSpace (Int -> InterpSegment
    Spaces Int
    1 InterpSegment -> Line -> Line
    forall a. a -> [a] -> [a]
    : Line
    xs)
    toSingleSpace (InterpSegment
    x:Line
    xs) | InterpSegment -> Bool
    isSpace InterpSegment
    x =
      Int -> InterpSegment
    Spaces Int
    1 InterpSegment -> Line -> Line
    forall a. a -> [a] -> [a]
    : Line -> Line
    toSingleSpace Line
    xs
    toSingleSpace (InterpSegment
    x:Line
    xs) =
      InterpSegment
    x InterpSegment -> Line -> Line
    forall a. a -> [a] -> [a]
    : Line -> Line
    toSingleSpace Line
    xs

    removeSurroundingWS :: Line -> Line
    removeSurroundingWS :: Line -> Line
    removeSurroundingWS =
        (InterpSegment -> Bool) -> Line -> Line
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile InterpSegment -> Bool
    isSpace
      (Line -> Line) -> (Line -> Line) -> Line -> Line
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Line -> Line
    forall a. [a] -> [a]
    reverse
      (Line -> Line) -> (Line -> Line) -> Line -> Line
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (InterpSegment -> Bool) -> Line -> Line
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile InterpSegment -> Bool
    isSpace
      (Line -> Line) -> (Line -> Line) -> Line -> Line
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Line -> Line
    forall a. [a] -> [a]
    reverse

    isSpace :: InterpSegment -> Bool
    isSpace :: InterpSegment -> Bool
    isSpace (Spaces Int
    _) = Bool
    True
    isSpace (Tabs Int
    _)   = Bool
    True
    isSpace InterpSegment
    _other     = Bool
    False