~alcinnz/bureaucromancy

ref: 1030d237866bf99999711515fa46dd9fdf729324 bureaucromancy/src/Text/HTML/Form/I18n.hs -rw-r--r-- 1.8 KiB
1030d237 — Adrian Cochrane Internationalize form validation. 11 months ago
                                                                                
122e87dc Adrian Cochrane
c50beaf3 Adrian Cochrane
122e87dc Adrian Cochrane
3704ec29 Adrian Cochrane
122e87dc Adrian Cochrane
3704ec29 Adrian Cochrane
122e87dc Adrian Cochrane
3704ec29 Adrian Cochrane
c50beaf3 Adrian Cochrane
122e87dc Adrian Cochrane
3704ec29 Adrian Cochrane
122e87dc Adrian Cochrane
3704ec29 Adrian Cochrane
122e87dc Adrian Cochrane
3704ec29 Adrian Cochrane
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
{-# LANGUAGE TemplateHaskell #-}
module Text.HTML.Form.I18n(strings, langs, i18n, i18n', i18n2, stringsJSON) where

import Data.FileEmbed (embedDir, makeRelativeToProject)
import Data.Text.Encoding (decodeUtf8Lenient)
import Data.Text (unpack, pack, strip, replace)
import Data.ByteString (ByteString)
import System.FilePath (dropExtension)

import qualified Data.Aeson.KeyMap as KM
import Data.Aeson.Key as K
import Data.Aeson (Value(String, Object))

import Data.List (isPrefixOf)
import Data.Maybe (fromMaybe)

files :: [(FilePath, ByteString)]
files = $(embedDir =<< makeRelativeToProject "i18n")
bs2str :: ByteString -> String
bs2str = unpack . decodeUtf8Lenient

strings :: String -> [(String, String)]
strings = fromMaybe [] .
        flip lookup [(dropExtension k, parseKVs $ bs2str v) | (k, v) <- files]
langs :: [String]
langs = map dropExtension $ map fst files

i18n :: String -> String -> String
i18n lang key = fromMaybe key $ lookup key $ strings lang

i18n' :: Show a => String -> String -> a -> String
i18n' lang key subs = replace' "%0" (show subs) $ i18n lang key
i18n2 :: (Show a, Show b) => String -> String -> a -> b -> String
i18n2 lang key subs1 subs2 = replace' "%1" (show subs2) $ i18n' lang key subs1

stringsJSON :: String -> Value
stringsJSON = Object . KM.fromList . map inner . strings
  where inner (k, v) = (K.fromString k, String $ pack v)

------
--- Support
------

parseKVs :: String -> [(String, String)]
parseKVs = map inner . filter (isPrefixOf "#") . filter null . map strip' . lines
  where inner line = let (k, v) = break (==':') line in (strip' k, strip' v)

-- | Removes any whitespace at the start or end of a string
strip' :: String -> String
strip' = unpack . strip . pack

-- | Substitutes one string for another
replace' :: String -> String -> String -> String
replace' needle alt = unpack . replace (pack needle) (pack alt) . pack