packages feed

descript-lang-0.2.0.0: src/Core/Data/String.hs

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