{- 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 (some 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