module Core.Data.String ( trim , lines' , unlines' , endPos , quote , unquote , unescape , escape , indentBullet , indentBlockQuote ) where import Data.List import Core.Data.List import Data.Char -- | Removes leading and trailing whitespace. trim :: String -> String trim = strip isSpace -- | Separates the text by newlines. -- Unlike (regular) @lines@, -- if there's a trailing newline in the text, -- this will include an empty string at the end. lines' :: String -> [String] lines' "" = [""] lines' ('\n' : xs) = "" : lines' xs lines' (x : xs) = overHead (x :) $ lines' xs -- | Joins the texts with a newline. -- Unlike (regular) @unlines@, -- this doesn't add a trailing newline at the end. unlines' :: [String] -> String unlines' = intercalate "\n" -- | The line and column length of the text. endPos :: String -> (Int, Int) endPos text = (endLine, endCol) where endCol = length lastLine lastLine = last lines'' endLine = length lines'' - 1 lines'' = case lines' text of [] -> [""] someLines -> someLines -- | Unescapes the string and surrounds it in quotes. quote :: String -> String quote str = "\"" ++ unescape str ++ "\"" -- | Escapes the string and removes surrounding quotes. -- Expects the string to have surrounding quotes and be escaped. unquote :: String -> String unquote = escape . tail . init -- | Encodes the given string in source code. unescape :: String -> String unescape [] = [] unescape ('"' : xs) = '\\' : '"' : unescape xs unescape ('\b' : xs) = '\\' : 'b' : unescape xs unescape ('\r' : xs) = '\\' : 'r' : unescape xs unescape ('\t' : xs) = '\\' : 't' : unescape xs unescape ('\n' : xs) = '\\' : 'n' : unescape xs unescape ('\\' : xs) = '\\' : '\\' : unescape xs unescape (x : xs) = x : unescape xs -- | Decodes the given string from source code, escape :: String -> String escape [] = [] escape ('\\' : '"' : xs) = '"' : escape xs escape ('\\' : 'b' : xs) = '\b' : escape xs escape ('\\' : 'r' : xs) = '\r' : escape xs escape ('\\' : 't' : xs) = '\t' : escape xs escape ('\\' : 'n' : xs) = '\n' : escape xs escape ('\\' : '\\' : xs) = '\\' : escape xs escape ('\\' : '\n' : xs) = escape xs escape (x : xs) = x : escape xs -- | Formats into a Markdown-style bulleted list item. indentBullet :: String -> String indentBullet subPr = "- " ++ indent subPr -- | Formats into a Markdown-style block quote. indentBlockQuote :: String -> String indentBlockQuote contentPr = "> " ++ indentBlockQuoteRest contentPr indent :: String -> String indent [] = [] indent ('\n' : xs) = "\n " ++ indent xs indent (x : xs) = x : indent xs indentBlockQuoteRest :: String -> String indentBlockQuoteRest [] = [] indentBlockQuoteRest ('\n' : xs) = "\n> " ++ indent xs indentBlockQuoteRest (x : xs) = x : indent xs