packages feed

natural-sort (empty) → 0.1

raw patch · 4 files changed

+176/−0 lines, 4 filesdep +basedep +bytestringdep +parsecsetup-changed

Dependencies added: base, bytestring, parsec, text

Files

+ Algorithms/NaturalSort.hs view
@@ -0,0 +1,114 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.NaturalSort+-- Copyright   :  (c) 2010 John Millikin+-- License     :  BSD3+--+-- Maintainer  :  jmillikin@gmail.com+-- Portability :  portable+--+-- Human-friendly text collation+--+-----------------------------------------------------------------------------+{-# LANGUAGE TypeSynonymInstances #-}+module Algorithms.NaturalSort+	( SortKey+	, NaturalSort (..)+	, compare+	) where+import Prelude hiding (compare)+import qualified Prelude as Prelude+import Data.Char (isDigit)+import Data.Function (on)+import qualified Data.ByteString as B+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Text.Parsec as P++data SortChunk+	= Integer Integer+	| Text T.Text+	| Collated B.ByteString (T.Text -> B.ByteString)++instance Show SortChunk where+	show (Integer x) = show x+	show (Text x) = show x+	show (Collated x _) = show x++instance Ord SortChunk where+	-- Basic comparisons+	compare (Integer x) (Integer y) = Prelude.compare x y+	compare (Text x) (Text y) = Prelude.compare x y+	compare (Collated x _) (Collated y _) = Prelude.compare x y+	+	-- Text <-> ByteString+	compare (Text x) (Collated y f) = Prelude.compare (f x) y+	compare (Collated x f) (Text y) = Prelude.compare x (f y)+	+	-- Integer < *+	compare (Integer _) _ = LT+	compare _ (Integer _) = GT++instance Eq SortChunk where+	(Integer x) == (Integer y) = x == y+	(Text x) == (Text y) = x == y+	(Collated x _) == (Collated y _) = x == y+	+	(Text x) == (Collated y f) = f x == y+	(Collated x f) == (Text y) = x == f y+	+	_ == _ = False++data SortKey = SortKey [SortChunk]+	deriving (Show, Eq, Ord)++class NaturalSort a where+	-- | Split a sortable type into textual and numeric sections, with no+	-- collation transformation.+	-- +	-- If advanced collation is required, either pre-transform the input+	-- (using eg 'T.toLower') or use 'sortKeyCollated'.+	-- +	sortKey :: a -> SortKey+	+	-- | Split a sortable type into textual and numeric sections, using+	-- a custom collation transformation. This is useful for providing+	-- language- or use-specific ordering.+	-- +	sortKeyCollated :: (T.Text -> B.ByteString) -> a -> SortKey++instance NaturalSort String where+	sortKey = parseText Nothing+	sortKeyCollated f = parseText (Just f)++instance NaturalSort TL.Text where+	sortKey = sortKey . TL.unpack+	sortKeyCollated = (. TL.unpack) . sortKeyCollated++instance NaturalSort T.Text where+	sortKey = parseText Nothing . T.unpack+	sortKeyCollated = (. T.unpack) . sortKeyCollated++-- | Compare two values, using their natural ordering.+compare :: NaturalSort a => a -> a -> Ordering+compare = Prelude.compare `on` sortKey++parseText :: Maybe (T.Text -> B.ByteString) -> String -> SortKey+parseText toBytes string = parsed where+	parsed = case P.parse parser "" string of+		Right key -> key+		+		-- This should never happen; the parser has no failure+		-- conditions, unless somehow something broke within Parsec+		-- itself.+		Left err -> error $ "sortKey failed: " ++ show err+	+	parser = fmap SortKey $ P.manyTill chunk P.eof where+		chunk = P.choice [int, text]+		int = fmap (Integer . read) $ P.many1 P.digit+		text = fmap toText $ P.many1 notDigit+		notDigit = P.satisfy (not . isDigit)+	+	toText chars = let text = T.pack chars in case toBytes of+		Nothing -> Text text+		Just f -> Collated (f text) f
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ license.txt view
@@ -0,0 +1,26 @@+Copyright (c) 2010 John Millikin+All rights reserved.++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.+- Neither the names of the copyright owners nor the names of the +  contributors may be used to endorse or promote products derived +  from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT+OWNER OR 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.
+ natural-sort.cabal view
@@ -0,0 +1,34 @@+name: natural-sort+version: 0.1+synopsis: User-friendly text collation+description:+  The built-in comparisons for textual data are based on Unicode ordinals. This+  does not match most every-day sorting algorithms. For example,+  \"z10.txt\" is sorted after \"z2.txt\" by users, but before it by naïve+  algorithms.+  .+  This package provides an implementation of \"natural sort\", which more+  closely matches user expectations.+  .+  See also: <http://www.davekoelle.com/alphanum.html>++license: BSD3+license-File: license.txt+author: John Millikin <jmillikin@gmail.com>+maintainer: John Millikin <jmillikin@gmail.com>+copyright: 2010 John Millikin <jmillikin@gmail.com>+build-type: Simple+cabal-version: >=1.2+category: Algorithms++library+  build-depends:+      base >= 2 && < 5+    , parsec >= 3+    , text+    , bytestring++  exposed-modules:+    Algorithms.NaturalSort++  ghc-options: -Wall