module Data.API.Doc.Subst
    ( Dict
    , subst
    , prep
    , mkDict
    , extDict
    )
    where

import qualified Data.Map               as Map
import           Text.Regex
import           Safe


type Dict = Map.Map String String


subst_re :: Regex
subst_re :: Regex
subst_re = String -> Bool -> Bool -> Regex
mkRegexWithOpts String
"<<[a-zA-Z0-9_'-]+>>" Bool
True Bool
True

subst :: Dict -> String -> String
subst :: Dict -> String -> String
subst Dict
dct String
str =
    case Regex -> String -> Maybe (String, String, String, [String])
matchRegexAll Regex
subst_re String
str of
      Maybe (String, String, String, [String])
Nothing               -> String
str
      Just (String
pre,String
var_,String
pst,[String]
_) -> String
pre String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
rpl String -> String -> String
forall a. [a] -> [a] -> [a]
++ Dict -> String -> String
subst Dict
dct String
pst
          where
            rpl :: String
rpl = String -> (String -> String) -> Maybe String -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String
"<<"String -> String -> String
forall a. [a] -> [a] -> [a]
++String
varString -> String -> String
forall a. [a] -> [a] -> [a]
++String
">>") String -> String
forall a. a -> a
id (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ String -> Dict -> Maybe String
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup String
var Dict
dct

            var :: String
var = String -> String
forall a. [a] -> [a]
chp (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. [a] -> [a]
reverse (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. [a] -> [a]
chp (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. [a] -> [a]
reverse String
var_
            
            chp :: [a] -> [a]
chp = String -> [a] -> [a]
forall a. Partial => String -> [a] -> [a]
tailNote String
"subst.chp" ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [a] -> [a]
forall a. Partial => String -> [a] -> [a]
tailNote String
"subst.chp"

prep :: Dict -> [String] -> String
prep :: Dict -> [String] -> String
prep Dict
dct = [String] -> String
unlines ([String] -> String)
-> ([String] -> [String]) -> [String] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Dict -> String -> String
subst Dict
dct) 

mkDict :: [(String,String)] -> Dict
mkDict :: [(String, String)] -> Dict
mkDict = [(String, String)] -> Dict
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList

extDict :: [(String,String)] -> Dict -> Dict
extDict :: [(String, String)] -> Dict -> Dict
extDict [(String, String)]
al Dict
dct = ((String, String) -> Dict -> Dict)
-> Dict -> [(String, String)] -> Dict
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((String -> String -> Dict -> Dict)
-> (String, String) -> Dict -> Dict
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry String -> String -> Dict -> Dict
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert) Dict
dct [(String, String)]
al