{-# LANGUAGE ViewPatterns #-} -- | -- -- Module: Language.Egison.Pretty.Pattern.External -- Description: Externally privided printers -- Stability: experimental -- -- This module defines a set of combinators that access to externally provided printers module Language.Egison.Pretty.Pattern.External ( name , varName , valueExpr ) where import Data.Text ( Text , unpack ) import Language.Egison.Pretty.Pattern.Prim ( Doc , text , parens ) import Language.Egison.Pretty.Pattern.Print ( Print , askMode ) import Language.Egison.Pretty.Pattern.PrintMode ( PrintMode(..) ) -- | Check whether the string is surrounded by something. -- -- >>> let parens = ('(', ')') -- >>> surroundedBy parens "(Hello, World)" -- True -- -- >>> surroundedBy parens "Hello, World" -- False -- -- >>> surroundedBy parens "(Hello)(World)" -- False surroundedBy :: (Char, Char) -> String -> Bool surroundedBy (begin, end) (h : (reverse -> (l : body))) | h == begin && l == end = foldr go 0 body == 0 where go :: Char -> Int -> Int go c | c == begin = (+) 1 | c == end = (-) 1 | otherwise = id surroundedBy _ _ = False lexicalChunk :: Text -> Doc lexicalChunk txt | containsDelimiter str && not (checkSurrounding str) = parens $ text txt | otherwise = text txt where containsDelimiter x = elem ' ' x || elem ',' x || elem ')' x || elem ']' x checkSurrounding x = surroundedBy ('(', ')') x || surroundedBy ('[', ']') x str = unpack txt varName :: v -> Print n v e Doc varName v = do PrintMode { varNamePrinter } <- askMode pure . lexicalChunk $ varNamePrinter v name :: n -> Print n v e Doc name n = do PrintMode { namePrinter } <- askMode pure . lexicalChunk $ namePrinter n valueExpr :: e -> Print n v e Doc valueExpr e = do PrintMode { valueExprPrinter } <- askMode pure . lexicalChunk $ valueExprPrinter e