
Stefan, On Thu, Jun 11, 2015 at 03:53:41PM +1000, Thomas Koster wrote:
My program needs to escape and unescape "special characters" in text (Data.Text.Text), using my own definition of "special character" (isSpecial :: Char -> Bool). I am looking for a library that provides functions that implement or help me implement this functionality. I don't really care exactly how the special characters are escaped, but my preference is to prefix them with backslashes.
On 11 June 2015 at 16:55, Stefan Höck
The answer to your question depends on whether your program needs additional functionality. If the only thing you need to do is taking special characters and escaping them with an escape character plus a substitute character, this can be done with very little code using functions from Data.Text:
import Data.Text (Text) import qualified Data.Text as T
-- Character used for escaping ec :: Char ec = '$'
-- Replace a character to be escaped with its substitute escapeChar :: Char -> Char escapeChar = id
-- Inverse of escapeChar unescapeChar :: Char -> Char unescapeChar = id
-- True if given char needs to be escaped isSpecial :: Char -> Bool isSpecial = ('?' ==)
-- Escape chars in a given text escape :: Text -> Text escape = T.concatMap handleChar where handleChar c | isSpecial c = T.pack [ec, escapeChar c] | otherwise = T.singleton c
-- Unescape chars in a given text unescape :: Text -> Text unescape t = case T.break (ec ==) t of (a,b) | T.null b -> a | otherwise -> let b' = T.tail b e = unescapeChar $ T.head b' in T.append a $ T.cons e $ unescape (T.tail b')
Thank you for your response. Yes, this is all I need to do. I had completed about two thirds of a similar implementation before becoming concerned that I was spending too much time reinventing this particular wheel and that there may be much easier and/or shorter ways to do this using a library written by a wheel surgeon. The only substantial difference is that my own version uses and returns a Data.Text.Lazy.Builder so that texts can be streamed and spliced into larger texts without copying (I am also using Chris Done's formatting library [1]), but only if I get it right, of course, which is another reason why I started to look around for libraries by Haskellers more experienced than I.
If on the other hand you want to escape special characters with blocks of text (instead of single characters as in my code) you probably also need a second character to mark the end of an escape. Even then, the code should not get much more involved than the example above.
I don't need more functionality re the escaping itself; your implementation is a valid example that provides the essence of what I need. [1] https://hackage.haskell.org/package/formatting -- Thomas Koster