{-|
Description : Handling Unicode newlines
-}
module Language.Haskell.Formatter.Internal.Newline
       (newlines, joinSeparatedLines, splitSeparatedLines) where
import qualified Data.List as List
import qualified Language.Haskell.Formatter.Toolkit.Splitter as Splitter

{-| Unicode newline strings ordered by descending length. This corresponds to
    the set of newlines from
    <http://www.unicode.org/standard/reports/tr13/tr13-5.html>. -}
newlines :: [String]
newlines :: [String]
newlines = [String
"\CR\LF", String
"\LF", String
"\VT", String
"\FF", String
"\CR", String
"\x85", String
"\x2028", String
"\x2029"]

{-| Concatenates strings with default newlines @\"\\n\"@ between.

    Unlike 'unlines', this does not append a newline to the last string.

    >>> joinSeparatedLines ["apple", "pine"]
    "apple\npine" -}
joinSeparatedLines :: [String] -> String
joinSeparatedLines :: [String] -> String
joinSeparatedLines = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
List.intercalate String
defaultNewline
  where defaultNewline :: String
defaultNewline = String
"\LF"

{-| Breaks a string up into its lines at 'newlines'. The resulting strings do
    not contain 'newlines'.

    Unlike 'lines', this interprets a newline as a separator, not a terminator.
    Thus, if the input string ends with a newline, the output list ends with the
    empty string.

    >>> splitSeparatedLines "0\n1\r2\r\n3\n\r4"
    ["0","1","2","3","","4"]

    prop> last (splitSeparatedLines $ s ++ "\LF") == "" -}
splitSeparatedLines :: String -> [String]
splitSeparatedLines :: String -> [String]
splitSeparatedLines = [String] -> String -> [String]
forall a. Eq a => [[a]] -> [a] -> [[a]]
Splitter.separate [String]
newlines