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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
#!/usr/bin/env runhaskell
{-# LANGUAGE StandaloneDeriving
#-}
import Data.Char
import Data.List
import System.Environment.UTF8
import System.IO
import System.Exit
import Text.Printf
import System.Locale.SetLocale
import qualified System.IO.UTF8 as UTF8
import Data.Char.WCWidth
import CompileRanges (compile_ranges)
usage name = unlines
[ "USAGE: " ++ name ++ " > table"
, " " ++ name ++ " --table > table"
, " " ++ name ++ " --ranges > ranges"
, " " ++ name ++ " --compile < ranges > Data/Char/Cols/Generated.hs"
, " " ++ name ++ " -h,--help"
, ""
, " This program polls your local wcwidth implementation for character width"
, " information and generates tables or a chart of ranges."
, ""
]
main = do
setLocale LC_ALL (Just "")
usage' <- fmap usage getProgName
programs <- fmap ((Table:) . fmap program) getArgs
case (head . sort) programs of
Usage -> putStrLn usage' >> exitSuccess
Compile -> compile_ranges stdin stdout
Ranges -> (rolling_print range_entry) ranges
Table -> (rolling_print table_entry) widths
Error s -> do
hPutStrLn stderr s
hPutStrLn stderr usage'
exitFailure
where
rolling_print f = sequence_ . fmap (putStrLn . f)
range_entry ((a,b),w) = printf fmt a' b' w count s
where
count = 1 + fromEnum b - fromEnum a
fmt = "0x%08x..0x%08x %2d %6d %s"
(a', b') = (fromEnum a, fromEnum b)
s = represent a ++ " .. " ++ represent b
table_entry (c,cols) = printf "0x%08x %2d %s" c' cols c''
where
c' = fromEnum c
c'' = represent c
represent c
| ' ' == c = "\\SP"
| '\xA0' == c = " "
| isControl c = display c
| isSpace c = '\\' : show (fromEnum c)
| isPrint c = [c]
| otherwise = display c
where
display = reverse . drop 1 . reverse . drop 1 . show
program opt = case opt of
"-h" -> Usage
"--help" -> Usage
"--compile" -> Compile
"--ranges" -> Ranges
"--table" -> Table
s -> Error ("No such option/arg: " ++ s)
data Program = Usage | Compile | Error String | Ranges | Table
deriving instance Eq Program
instance Ord Program where
compare a b
| a == b = EQ
| otherwise = case a of
Usage -> LT
Compile -> LT
Ranges -> LT
Table -> GT
Error s -> case b of
Error t -> compare s t
_ -> LT
|