module DigraphQuote (digraphTable) where
import Data.Char
import Control.Monad
import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Numeric (readHex)
digraphTable :: QuasiQuoter
digraphTable = QuasiQuoter
{ quoteExp = digraphTableExp
, quotePat = const (fail "Digraph table must be an expression")
, quoteType = const (fail "Digraph table must be an expression")
, quoteDec = const (fail "Digraph table must be an expression")
}
digraphTableExp :: String -> ExpQ
digraphTableExp = stringE . concat <=< traverse parseEntry . lines
parseEntry :: String -> Q String
parseEntry line =
case words line of
[x,y] : ('U':'+':hex) : rest
| [(n,"")] <- readHex hex
, isAllowedTerminator rest -> pure [x,y,chr n]
rest | isAllowedTerminator rest -> pure ""
| otherwise -> fail ("Bad digraph entry: " ++ line)
isAllowedTerminator :: [String] -> Bool
isAllowedTerminator (('-':'-':_):_) = True
isAllowedTerminator [] = True
isAllowedTerminator _ = False