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