on master help sign in
Add support for toLower.
599c8d1Bryan O'Sullivan
Data/Text.hs+9
@@ -57,6 +57,7 @@ module Data.Text
57
57
58 -- * Case conversion
58 -- * Case conversion
59 , toUpper
59 , toUpper
60+ , toLower
60
61
61 -- * Folds
62 -- * Folds
62 , foldl
63 , foldl
@@ -392,6 +393,14 @@ toUpper :: Text -> Text
392toUpper t = unstream (S.toUpper (stream t))
393toUpper t = unstream (S.toUpper (stream t))
393{-# INLINE toUpper #-}
394{-# INLINE toUpper #-}
394
395
396+-- | /O(n)/ Convert a string to lower case, using simple case
397+-- conversion. The result string may be longer than the input string.
398+-- For instance, the German eszett (U+00DF) maps to the two-letter
399+-- sequence SS.
400+toLower :: Text -> Text
401+toLower t = unstream (S.toLower (stream t))
402+{-# INLINE toLower #-}
403+
395-- | /O(n)/ The 'transpose' function transposes the rows and columns
404-- | /O(n)/ The 'transpose' function transposes the rows and columns
396-- of its 'Text' argument. Note that this function uses 'pack',
405-- of its 'Text' argument. Note that this function uses 'pack',
397-- 'unpack', and the list version of transpose, and is thus not very
406-- 'unpack', and the list version of transpose, and is thus not very
Data/Text/Fusion/CaseMapping.hs+7
@@ -1,4 +1,6 @@
1{-# LANGUAGE Rank2Types #-}
1{-# LANGUAGE Rank2Types #-}
2+-- AUTOMATICALLY GENERATED - DO NOT EDIT
3+-- Generated by scripts/SpecialCasing.hs
2module Data.Text.Fusion.CaseMapping where
4module Data.Text.Fusion.CaseMapping where
3import Data.Char
5import Data.Char
4import Data.Text.Fusion.Internal
6import Data.Text.Fusion.Internal
@@ -210,3 +212,8 @@ upperMapping '\x1fc7' s = Yield '\x0397' (s :!: '\x0342' :!: '\x0399')
210-- GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
212-- GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
211upperMapping '\x1ff7' s = Yield '\x03a9' (s :!: '\x0342' :!: '\x0399')
213upperMapping '\x1ff7' s = Yield '\x03a9' (s :!: '\x0342' :!: '\x0399')
212upperMapping c s = Yield (toUpper c) (s :!: '\0' :!: '\0')
214upperMapping c s = Yield (toUpper c) (s :!: '\0' :!: '\0')
215+lowerMapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char
216+{-# INLINE lowerMapping #-}
217+-- LATIN CAPITAL LETTER I WITH DOT ABOVE
218+lowerMapping '\x0130' s = Yield '\x0069' (s :!: '\x0307' :!: '\x0000')
219+lowerMapping c s = Yield (toLower c) (s :!: '\0' :!: '\0')
Data/Text/Fusion/Common.hs+22−9
@@ -1,4 +1,4 @@
1−{-# LANGUAGE BangPatterns #-}
1+{-# LANGUAGE BangPatterns, Rank2Types #-}
2-- |
2-- |
3-- Module : Data.Text.Fusion.Common
3-- Module : Data.Text.Fusion.Common
4-- Copyright : (c) Bryan O'Sullivan 2009
4-- Copyright : (c) Bryan O'Sullivan 2009
@@ -37,6 +37,7 @@ module Data.Text.Fusion.Common
37
37
38 -- ** Case conversion
38 -- ** Case conversion
39 , toUpper
39 , toUpper
40+ , toLower
40
41
41 -- * Folds
42 -- * Folds
42 , foldl
43 , foldl
@@ -99,7 +100,7 @@ import Prelude (Bool(..), Char, Either(..), Eq(..), Int, Integral, Maybe(..),
99import qualified Data.List as L
100import qualified Data.List as L
100import qualified Prelude as P
101import qualified Prelude as P
101import Data.Text.Fusion.Internal
102import Data.Text.Fusion.Internal
102−import Data.Text.Fusion.CaseMapping (upperMapping)
103+import Data.Text.Fusion.CaseMapping (lowerMapping, upperMapping)
103
104
104singleton :: Char -> Stream Char
105singleton :: Char -> Stream Char
105singleton c = Stream next False 1 -- HINT maybe too low
106singleton c = Stream next False 1 -- HINT maybe too low
@@ -299,22 +300,34 @@ intersperse c (Stream next0 s0 len) = Stream next (s0 :!: N :!: S1) len -- HINT
299-- ----------------------------------------------------------------------------
300-- ----------------------------------------------------------------------------
300-- ** Case conversions (folds)
301-- ** Case conversions (folds)
301
302
302−-- | /O(n)/ Convert a string to upper case, using simple case
303+caseConvert :: (forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char)
303−-- conversion. The result string may be longer than the input string.
304−-- For instance, the German eszett (U+00DF) maps to the two-letter
305−-- sequence SS.
306−toUpper :: Stream Char -> Stream Char
304+ -> Stream Char -> Stream Char
307−toUpper (Stream next0 s0 len) = Stream next (s0 :!: '\0' :!: '\0') len
305+caseConvert remap (Stream next0 s0 len) = Stream next (s0 :!: '\0' :!: '\0') len
308 where
306 where
309 {-# INLINE next #-}
307 {-# INLINE next #-}
310 next (s :!: '\0' :!: _) =
308 next (s :!: '\0' :!: _) =
311 case next0 s of
309 case next0 s of
312 Done -> Done
310 Done -> Done
313 Skip s' -> Skip (s' :!: '\0' :!: '\0')
311 Skip s' -> Skip (s' :!: '\0' :!: '\0')
314− Yield c s' -> upperMapping c s'
312+ Yield c s' -> remap c s'
315 next (s :!: a :!: b) = Yield a (s :!: b :!: '\0')
313 next (s :!: a :!: b) = Yield a (s :!: b :!: '\0')
314+
315+-- | /O(n)/ Convert a string to upper case, using simple case
316+-- conversion. The result string may be longer than the input string.
317+-- For instance, the German eszett (U+00DF) maps to the two-letter
318+-- sequence SS.
319+toUpper :: Stream Char -> Stream Char
320+toUpper = caseConvert upperMapping
316{-# INLINE [0] toUpper #-}
321{-# INLINE [0] toUpper #-}
317
322
323+-- | /O(n)/ Convert a string to lower case, using simple case
324+-- conversion. The result string may be longer than the input string.
325+-- For instance, the German eszett (U+00DF) maps to the two-letter
326+-- sequence SS.
327+toLower :: Stream Char -> Stream Char
328+toLower = caseConvert lowerMapping
329+{-# INLINE [0] toLower #-}
330+
318-- ----------------------------------------------------------------------------
331-- ----------------------------------------------------------------------------
319-- * Reducing Streams (folds)
332-- * Reducing Streams (folds)
320
333
Data/Text/Lazy.hs+9
@@ -60,6 +60,7 @@ module Data.Text.Lazy
60
60
61 -- ** Case conversion
61 -- ** Case conversion
62 , toUpper
62 , toUpper
63+ , toLower
63
64
64 -- * Folds
65 -- * Folds
65 , foldl
66 , foldl
@@ -378,6 +379,14 @@ toUpper :: Text -> Text
378toUpper t = unstream (S.toUpper (stream t))
379toUpper t = unstream (S.toUpper (stream t))
379{-# INLINE toUpper #-}
380{-# INLINE toUpper #-}
380
381
382+-- | /O(n)/ Convert a string to lower case, using simple case
383+-- conversion. The result string may be longer than the input string.
384+-- For instance, the German eszett (U+00DF) maps to the two-letter
385+-- sequence SS.
386+toLower :: Text -> Text
387+toLower t = unstream (S.toLower (stream t))
388+{-# INLINE toLower #-}
389+
381-- | /O(n)/ 'foldl', applied to a binary operator, a starting value
390-- | /O(n)/ 'foldl', applied to a binary operator, a starting value
382-- (typically the left-identity of the operator), and a 'Text',
391-- (typically the left-identity of the operator), and a 'Text',
383-- reduces the 'Text' using the binary operator, from left to right.
392-- reduces the 'Text' using the binary operator, from left to right.
scripts/SpecialCasing.hs+16−9
@@ -4,7 +4,7 @@ import Data.Char
4import Numeric
4import Numeric
5import System.Environment
5import System.Environment
6import System.IO
6import System.IO
7−import Text.ParserCombinators.Parsec hiding (many, optional, upper, (<|>))
7+import Text.ParserCombinators.Parsec hiding (many, optional, upper, lower, (<|>))
8import Text.ParserCombinators.Parsec.Combinator
8import Text.ParserCombinators.Parsec.Combinator
9
9
10instance Applicative (GenParser s a) where
10instance Applicative (GenParser s a) where
@@ -41,18 +41,24 @@ entries = many comment *> many (entry <* many comment)
41parseFile :: FilePath -> IO (Either ParseError [Case])
41parseFile :: FilePath -> IO (Either ParseError [Case])
42parseFile name = parse entries name <$> readFile name
42parseFile name = parse entries name <$> readFile name
43
43
44−upperFunc ms = typ ++ (map nice . filter p $ ms) ++ [last]
44+mapFunc which access twiddle ms = typ ++ (map nice . filter p $ ms) ++ [last]
45 where
45 where
46− typ = ["upperMapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char"
46+ typ = [which ++ "Mapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char"
47− ,"{-# INLINE upperMapping #-}"]
47+ ,"{-# INLINE " ++ which ++ "Mapping #-}"]
48− last = "upperMapping c s = Yield (toUpper c) (s :!: '\\0' :!: '\\0')"
48+ last = which ++ "Mapping c s = Yield (to" ++ ucFirst which ++ " c) (s :!: '\\0' :!: '\\0')"
49+ nice c = "-- " ++ name c ++ "\n" ++
49− nice c = "-- " ++ name c ++ "\nupperMapping " ++ showC (code c) ++ " s = Yield " ++ x ++ " (s :!: " ++ y ++ " :!: " ++ z ++ ")"
50+ which ++ "Mapping " ++ showC (code c) ++ " s = Yield " ++ x ++ " (s :!: " ++ y ++ " :!: " ++ z ++ ")"
50− where [x,y,z] = (map showC . take 3) (upper c ++ repeat '\0')
51+ where [x,y,z] = (map showC . take 3) (access c ++ repeat '\0')
51− p c = [code c] /= upper c && null (conditions c)
52+ p c = [k] /= a && a /= [twiddle k] && null (conditions c)
53+ where a = access c
54+ k = code c
52 showC c = "'\\x" ++ d ++ "'"
55 showC c = "'\\x" ++ d ++ "'"
53 where h = showHex (ord c) ""
56 where h = showHex (ord c) ""
54 d = replicate (4 - length h) '0' ++ h
57 d = replicate (4 - length h) '0' ++ h
55
58
59+ucFirst (c:cs) = toUpper c : cs
60+ucFirst [] = []
61+
56main = do
62main = do
57 args <- getArgs
63 args <- getArgs
58 let (iname, oname) = case args of
64 let (iname, oname) = case args of
@@ -71,5 +77,6 @@ main = do
71 ,"import Data.Char"
77 ,"import Data.Char"
72 ,"import Data.Text.Fusion.Internal"
78 ,"import Data.Text.Fusion.Internal"
73 ,""]
79 ,""]
74− mapM_ (hPutStrLn h) (upperFunc ms)
80+ mapM_ (hPutStrLn h) (mapFunc "upper" upper toUpper ms)
81+ mapM_ (hPutStrLn h) (mapFunc "lower" lower toLower ms)
75 hClose h
82 hClose h