seonbi-0.1.0: src/Text/Seonbi/Unihan/KHangul.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Text.Seonbi.Unihan.KHangul
( CharacterSet (..)
, HanjaReadings
, HanjaReadingCitation (..)
, KHangulData
, Purpose (..)
, kHangulData
, kHangulData'
) where
import Data.Either
import Data.Aeson
import Data.Attoparsec.Text
import Data.ByteString.Lazy (fromStrict)
import Data.FileEmbed
import Data.Map.Strict
import Data.Set hiding (empty)
import System.FilePath (takeDirectory, (</>))
-- $setup
-- >>> import qualified Text.Show.Unicode
-- >>> :set -interactive-print=Text.Show.Unicode.uprint
-- | Maps all Hanja characters to their possible readings.
type KHangulData = Map Char HanjaReadings
-- | All readings of a Hanja character.
type HanjaReadings = Map Char HanjaReadingCitation
-- | Represents what standard a reading of character belongs to and a purpose
-- of the reading.
data HanjaReadingCitation =
HanjaReadingCitation CharacterSet (Set Purpose) deriving (Eq, Ord, Show)
-- | Represents character set standards for Korean writing system.
data CharacterSet
-- | KS X 1001 (정보 교환용 부호계).
= KS_X_1001
-- | KS X 1002 (정보 교환용 부호 확장 세트).
| KS_X_1002
-- | Represents that a Hanja character is not included in any Korean
-- character set standards.
| NonStandard
deriving (Eq, Ord, Show)
-- | Represents purposes of Hanja characters.
data Purpose
-- | Basic Hanja for educational use (漢文敎育用基礎漢字), a subset of
-- Hanja defined in 1972 by a South Korean standard for educational use.
= Education
-- | Hanja for personal names (人名用漢字).
| PersonalName
deriving (Eq, Ord, Show)
citationParser :: Parser HanjaReadingCitation
citationParser = do
charset' <- option NonStandard charset
purposes <- many' purpose
return $ HanjaReadingCitation charset' $ Data.Set.fromList purposes
where
charset :: Parser CharacterSet
charset = do
d <- digit
case d of
'0' -> return KS_X_1001
'1' -> return KS_X_1002
c -> fail ("Invalid kHangul character set code: " ++ show c)
purpose :: Parser Purpose
purpose = do
l <- letter
case l of
'E' -> return Education
'N' -> return PersonalName
c -> fail ("Invalid kHangul purpose code: " ++ show c)
instance FromJSON HanjaReadingCitation where
parseJSON =
withText "kHangul value (e.g., 0E, 1N, 0EN)" $ \ t ->
case parseOnly (citationParser <* endOfInput) t of
Right cite -> return cite
Left msg -> fail msg
kHangulData' :: Either String KHangulData
kHangulData' = eitherDecode $
fromStrict $(embedFile $ takeDirectory __FILE__ </> "kHangul.json")
-- | Data that map Hanja characters to their corresponding kHangul entries
-- (i.e., Hanja readings and citations).
--
-- >>> import Data.Map.Strict as M
-- >>> let Just entries = M.lookup '天' kHangulData
-- >>> entries
-- fromList [('천',HanjaReadingCitation KS_X_1001 (fromList [Education]))]
kHangulData :: KHangulData
kHangulData = fromRight empty kHangulData'
{- HLINT ignore "Unused LANGUAGE pragma" -}