packages feed

api-opentheory-unicode (empty) → 1.0

raw patch · 5 files changed

+252/−0 lines, 5 filesdep +basedep +bytestringdep +directorysetup-changed

Dependencies added: base, bytestring, directory, opentheory-unicode

Files

+ LICENSE view
@@ -0,0 +1,17 @@+Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,6 @@+module Main(main)++import Distribution.Simple++main :: IO ()+main = defaultMain
+ api-opentheory-unicode.cabal view
@@ -0,0 +1,39 @@+name: api-opentheory-unicode+version: 1.0+category: Text+synopsis: OpenTheory unicode character API+license: MIT+license-file: LICENSE+cabal-version: >= 1.8.0.2+build-type: Simple+author: Joe Leslie-Hurd <joe@gilith.com>+maintainer: Joe Leslie-Hurd <joe@gilith.com>+description:+  This package provides an API to the unicode character package+  opentheory-unicode which is automatically generated by OpenTheory.++Library+  build-depends:+    base >= 4.0 && < 5.0,+    bytestring >= 0.9 && < 1.0,+    opentheory-unicode >= 1.0 && < 2.0++  hs-source-dirs: src++  ghc-options: -Wall++  exposed-modules:+    Unicode++executable api-opentheory-unicode-test+  build-depends:+    base >= 4.0 && < 5.0,+    bytestring >= 0.9 && < 1.0,+    directory >= 1.0 && < 2.0,+    opentheory-unicode >= 1.0 && < 2.0++  hs-source-dirs: src, testsrc++  ghc-options: -Wall++  main-is: Main.hs
+ src/Unicode.hs view
@@ -0,0 +1,81 @@+{- |+module: Unicode+description: Unicode character API+license: MIT++maintainer: Joe Leslie-Hurd <joe@gilith.com>+stability: provisional+portability: portable+-}+module Unicode+  ( toString,+    newline,+    decode,+    encode,+    reencode,+    hDecode,+    hEncode,+    hReencode,+    decodeFile,+    encodeFile,+    reencodeFile )+where++import qualified Data.ByteString.Lazy as ByteString+import qualified Data.Char as Char+import qualified Data.Word as Word+import qualified System.IO as IO++import qualified OpenTheory.Unicode.UTF8 as UTF8+import OpenTheory.Unicode++toString :: Unicode -> String+toString = show . Char.chr . fromIntegral . unUnicode++newline :: [Unicode]+newline = [Unicode 10]++decode :: IO [Either Word.Word8 Unicode]+decode =+    do b <- ByteString.getContents+       return (UTF8.decode (ByteString.unpack b))++encode :: [Unicode] -> IO ()+encode c =+    let b = ByteString.pack (UTF8.encode c) in+    ByteString.putStr b++reencode :: [Either Word.Word8 Unicode] -> IO ()+reencode c =+    let b = ByteString.pack (UTF8.reencode c) in+    ByteString.putStr b++hDecode :: IO.Handle -> IO [Either Word.Word8 Unicode]+hDecode h =+    do b <- ByteString.hGetContents h+       return (UTF8.decode (ByteString.unpack b))++hEncode :: IO.Handle -> [Unicode] -> IO ()+hEncode h c =+    let b = ByteString.pack (UTF8.encode c) in+    ByteString.hPut h b++hReencode :: IO.Handle -> [Either Word.Word8 Unicode] -> IO ()+hReencode h c =+    let b = ByteString.pack (UTF8.reencode c) in+    ByteString.hPut h b++decodeFile :: FilePath -> IO [Either Word.Word8 Unicode]+decodeFile f =+    do b <- ByteString.readFile f+       return (UTF8.decode (ByteString.unpack b))++encodeFile :: FilePath -> [Unicode] -> IO ()+encodeFile f c =+    let b = ByteString.pack (UTF8.encode c) in+    ByteString.writeFile f b++reencodeFile :: FilePath -> [Either Word.Word8 Unicode] -> IO ()+reencodeFile f c =+    let b = ByteString.pack (UTF8.reencode c) in+    ByteString.writeFile f b
+ testsrc/Main.hs view
@@ -0,0 +1,109 @@+{- |+module: Main+description: Testing the Unicode character library and API+license: MIT++maintainer: Joe Leslie-Hurd <joe@gilith.com>+stability: provisional+portability: portable+-}+module Main+  ( main )+where++import qualified Data.List as List+import qualified Data.Either as Either+import qualified Data.Word as Word+import qualified System.Directory as Directory++import Unicode+import qualified OpenTheory.Unicode as Unicode++demoLength :: Int+demoLength = 7621++testLength :: Int+testLength = 79++noInvalid :: [Either Word.Word8 Unicode.Unicode] -> Bool+noInvalid = all (Either.either (const False) (const True))++getTestFiles :: FilePath -> IO [FilePath]+getTestFiles d =+    do fs <- Directory.getDirectoryContents d+       let fs' = filter (List.isPrefixOf "test") fs+       return (map (\f -> d ++ "/" ++ f) fs')++readTestCharFile :: Maybe Int -> FilePath -> IO ()+readTestCharFile x f =+    do l <- decodeFile f+       let a = noInvalid l+       case x of+         Nothing ->+             if a+               then error $ "invalid file " ++ f ++ " was successfully decoded"+               else return ()+         Just n ->+             if not a+               then error $ "valid file " ++ f ++ " could not be decoded"+               else+                 if length l == n+                   then return ()+                   else+                     error $ "valid file " ++ f ++ " has bad line length: " +++                             show (length l)++readValidCharFile :: Int -> FilePath -> IO ()+readValidCharFile n = readTestCharFile (Just n)++readInvalidCharFile :: FilePath -> IO ()+readInvalidCharFile = readTestCharFile Nothing++partitionTestCharFile :: IO ()+partitionTestCharFile =+    do skip <- Directory.doesFileExist "test/valid/test061.txt"+       if skip+         then return ()+         else+           do putStrLn "\nsplitting UTF-8 test file into valid and invalid lines"+              cs <- decodeFile "test/test.txt"+              mapM_ outputLine (filter testLine (readLines 1 cs))+  where+    isNewline :: Either Word.Word8 Unicode.Unicode -> Bool+    isNewline (Left _) = False+    isNewline (Right c) = let n = Unicode.unUnicode c in n == 10 || n == 13++    chopNewline :: [Either Word.Word8 Unicode.Unicode] ->+                   [Either Word.Word8 Unicode.Unicode]+    chopNewline [] = []+    chopNewline (_ : cs) = cs++    readLines :: Int -> [Either Word.Word8 Unicode.Unicode] ->+                 [(Int,[Either Word.Word8 Unicode.Unicode])]+    readLines _ [] = []+    readLines lineno inp =+        let (line,inp') = List.span (not . isNewline) inp in+        let inp'' = chopNewline inp' in+        (lineno,line) : readLines (lineno + 1) inp''++    testLine :: (Int,[Either Word.Word8 Unicode.Unicode]) -> Bool+    testLine (lineno,line) = not (lineno < 61 || null line)++    outputLine :: (Int,[Either Word.Word8 Unicode.Unicode]) -> IO ()+    outputLine (lineno,line) =+        let valid = noInvalid line in+        let n = show lineno in+        let f = "test/" ++ (if valid then "valid" else "invalid") +++                "/test" ++ replicate (3 - length n) '0' ++ n ++ ".txt" in+        reencodeFile f line++main :: IO ()+main =+    do partitionTestCharFile+       readValidCharFile demoLength "test/demo.txt"+       validTestFiles <- getTestFiles "test/valid"+       invalidTestFiles <- getTestFiles "test/invalid"+       mapM_ (readValidCharFile testLength) validTestFiles+       mapM_ readInvalidCharFile invalidTestFiles+       putStrLn "  all tests pass"+       return ()