razom-text-util-0.1.2.0: src/Text/Razom/Value.hs
{- This file is part of razom-text-util.
-
- Written in 2015 by fr33domlover <fr33domlover@rel4tion.org>.
-
- ♡ Copying is an act of love. Please copy, reuse and share.
-
- The author(s) have dedicated all copyright and related and neighboring
- rights to this software to the public domain worldwide. This software is
- distributed without any warranty.
-
- You should have received a copy of the CC0 Public Domain Dedication along
- with this software. If not, see
- <http://creativecommons.org/publicdomain/zero/1.0/>.
-}
module Text.Razom.Value
( literal
, escapeMinimal
, unescapeMinimal
)
where
import Text.Razom.Char
import Text.Razom.Types
import Text.Regex.Applicative
-- | Matches a delimited generic value literal and returns it, without
-- delimiters and still escaped (since unescaping may be type-specific).
--
-- >>> match literal "{{1\\}2\\\\3}}"
-- Just "1\\}2\\\\3"
literal :: Regex String
literal = string "{{" *> lbody <* string "}}"
where
lbody = snd <$> withMatched (many lpart)
lpart = Nothing <$ lchar <|> Nothing <$ sym '\\' <* psym isGraphical
lchar = psym $ \ c -> isGraphical c && c /= '\\' && c /= '}'
-- | Given a value literal in unescaped form, do minimal default escapes: for
-- the escape character itself (backslash) and for the closing delimiter
-- character (@'{'@).
escapeMinimal :: String -> String
escapeMinimal [] = []
escapeMinimal ('\\':cs) = '\\' : '\\' : escapeMinimal cs
escapeMinimal ('}':cs) = '\\' : '}' : escapeMinimal cs
escapeMinimal (c:cs) = c : escapeMinimal cs
-- | Given an escaped value literal, do minimal default unescapes: for the
-- escape character and for the closing delimiter.
unescapeMinimal :: String -> String
unescapeMinimal [] = []
unescapeMinimal ('\\':'\\':cs) = '\\' : unescapeMinimal cs
unescapeMinimal ('\\':'}':cs) = '}' : unescapeMinimal cs
unescapeMinimal ('\\':c:cs) = '\\' : c : unescapeMinimal cs
unescapeMinimal (c:cs) = c : unescapeMinimal cs