wcwidth (empty) → 0.0.0
raw patch · 5 files changed
+246/−0 lines, 5 filesdep +basedep +bytestringdep +bytestringparser-temporarysetup-changed
Dependencies added: base, bytestring, bytestringparser-temporary, containers, setlocale, utf8-string
Files
- Data/Char/WCWidth.hs +74/−0
- LICENSE +28/−0
- Setup.hs +4/−0
- WCWidthTableaux.hs +101/−0
- wcwidth.cabal +39/−0
+ Data/Char/WCWidth.hs view
@@ -0,0 +1,74 @@+++{-# LANGUAGE ForeignFunctionInterface+ #-}+++{-| A binding for the native 'wcwidth'. It's important that you 'setLocale'+ before using it, like this:++ > #!/usr/bin/env runhaskell+ >+ > import Text.Printf+ > + > import System.Locale.SetLocale+ > import Data.Char.WCWidth+ >+ > main = do+ > setLocale LC_ALL (Just "")+ > sequence_ [ display c | c <- chars ]+ > where+ > chars = [minBound..'A']+ > display c = printf "%04x %2d %s\n" (fromEnum c) (wcwidth c) (show c)++ The program file @WCWidthTableaux.hs@ contains a more extensive example of+ using 'wcwidth'.++ Note that this binding to the native implementation gets certain+ characters wrong in obvious ways as well as ways that are problematic for+ indentation based languages. The ASCII tab should be assigned a width of+ 8, not -1; and one is likely to find -1 assigned to numerous obscure+ characters (for example, symbols from the Book of Changes).++ -}+++module Data.Char.WCWidth+ ( wcwidth+ , widths+ , ranges+ ) where++import Foreign.C+import Data.List+++++{-| Widths of all characters. + -}+widths :: [ (Char, Int) ]+widths = [ (c, wcwidth c) | c <- [minBound..maxBound] ] +++{-| Characters broken into contiguous ranges with the same width.+ -}+ranges :: [ ((Char, Char), Int) ]+ranges = reverse (foldl' aggregate start (tail widths))+ where+ start = aggregate [] (head widths)+ aggregate [] (c, w) = [((c, c), w)]+ aggregate (((a, z), i) : t) (c, w)+ | i == w = ((a, c), i) : t+ | otherwise = ((c, c), w) : ((a, z), i) : t+++{-| Binding to the native 'wcwidth'. + -}+wcwidth :: Char -> Int+wcwidth = fromEnum . native . toEnum . fromEnum+++foreign import ccall unsafe "wchar.h wcwidth" native :: CWchar -> CInt++
+ LICENSE view
@@ -0,0 +1,28 @@++ ©2009 Jason Dusek.++ Redistribution and use in source and binary forms, with or without+ modification, are permitted provided that the following conditions are met:++ . Redistributions of source code must retain the above copyright notice,+ this list of conditions and the following disclaimer.++ . Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.++ . Names of the contributors to this software may not be used to endorse or+ promote products derived from this software without specific prior written+ permission.++ This software is provided by the contributors "as is" and any express or+ implied warranties, including, but not limited to, the implied warranties of+ merchantability and fitness for a particular purpose are disclaimed. In no+ event shall the contributors be liable for any direct, indirect, incidental,+ special, exemplary, or consequential damages (including, but not limited to,+ procurement of substitute goods or services; loss of use, data, or profits;+ or business interruption) however caused and on any theory of liability,+ whether in contract, strict liability, or tort (including negligence or+ otherwise) arising in any way out of the use of this software, even if+ advised of the possibility of such damage. +
+ Setup.hs view
@@ -0,0 +1,4 @@+import Distribution.Simple++main = defaultMain+
+ WCWidthTableaux.hs view
@@ -0,0 +1,101 @@+#!/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 (UTF8.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++
+ wcwidth.cabal view
@@ -0,0 +1,39 @@+name : wcwidth+version : 0.0.0+category : Text+license : BSD3+license-file : LICENSE+author : Jason Dusek+maintainer : wcwidth@solidsnack.be +homepage : http://github.com/solidsnack/width/+synopsis : Native wcwidth.+description :+ Bindings for your system's native wcwidth and a command line tool to examine+ the widths assigned by it. The command line tool can compile a width table+ to Haskell code that assigns widths to the Char type.+++cabal-version : >= 1.6.0+build-type : Simple+++library+ build-depends : base >= 2 && < 4+ , containers+ exposed-modules : Data.Char.WCWidth+ extensions : StandaloneDeriving+ ForeignFunctionInterface+++executable wcwidth-tools+ main-is : WCWidthTableaux.hs+ build-depends : base >= 2 && < 4+ , containers+ , bytestring+ , setlocale >= 0.0.3+ , utf8-string >= 0.3+ , bytestringparser-temporary >= 0.4.1+ extensions : StandaloneDeriving+ ForeignFunctionInterface++