------------------------------------------------------------------------------ -- | This library provides functions to categorize a list of entities -- into a HTML page with an index access (e.g., "A-Z") to these entities. ------------------------------------------------------------------------------ module HTML.CategorizedList ( list2CategorizedHtml, categorizeByItemKey, stringList2ItemList ) where import Data.Char import Data.List import HTML.Base import Network.URL ( string2urlencoded ) -- | General categorization of a list of entries. -- -- The item will occur in every category for which the boolean function -- categoryFun yields True. list2CategorizedHtml :: (HTML h, Show b) => [(a,[h])] -- ^ the list of key-item pairs which are supposed to be -- categorized with respect to key -> [(b,String)] -- ^ list of key-category pairs to which the items can be -- sorted in -> (a -> b -> Bool) -- ^ uses the keys of the items and the keys of the -- categories to distribute the items among -- the categories -> [h] -- ^ HTML containing inner links between the categories list2CategorizedHtml itemL categoryL categoryFun = categories2LinkList categoryL : map (\ (categoryKey,categoryString) -> anchor (string2urlencoded (show categoryKey)) (h2 [htxt categoryString] : concatMap (\ (_,item)->item++[breakline]) (filter (\ (itemKey,_) -> categoryFun itemKey categoryKey) itemL) ++ [categories2LinkList categoryL]) ) categoryL -- the navigation list categories2LinkList :: (HTML h, Show a) => [(a,String)] -> h categories2LinkList categoryL = par [center (concatMap (\ (categoryKey,categoryString) -> [href ('#':(string2urlencoded (show categoryKey))) [htxt categoryString], nbsp]) categoryL)] -- | Categorizes a list of entries with respect to the initial keys. -- -- The categories are named as all initial characters of the keys of the items. categorizeByItemKey :: HTML h => [(String,[h])] -- ^ the list of key-item pairs which are supposed to be -- categorized with respect to key -> [h] -- ^ HTML containing inner links between the categories categorizeByItemKey itemL = list2CategorizedHtml itemL (map (\c -> (toUpper c,[toUpper c])) (listHeads (map fst itemL))) categorizeStringHead -- | Converts a string list into an key-item list. -- The strings are used as keys and for the simple text layout. stringList2ItemList :: HTML h => [String] -> [(String,[h])] stringList2ItemList = map (\str -> (str,[htxt str])) -- yields every listHead only once listHeads :: [String] -> [Char] listHeads = nubBy isUpperEqual . foldr (\xs ys -> if xs==[] then ys else head xs:ys) [] -- categoryFun for categorizeByItemKey categorizeStringHead :: String -> Char -> Bool categorizeStringHead [] _ = False categorizeStringHead (c:_) c' = isUpperEqual c c' isUpperEqual :: Char -> Char -> Bool isUpperEqual c c' = toUpper c == toUpper c' -- just for testing ---------------------------------------- main :: IO HtmlPage main = return $ page "CatTest" (categorizeByItemKey (stringList2ItemList testList)) testList :: [String] testList = ["bbcd", "acde", "ab", "cde", "b", "xt", "gbbcd", "uacde", "Oab", "Qcde", "Tb", "mxt", "mxtr"] -- To test, export `main` and run: -- > cypm exec curry2cgi -o ~/public_html/cgi-bin/cat.cgi HTML.CategorizedList