{-# LANGUAGE OverloadedStrings #-} -- | -- Module : HsIndex.Show -- Copyright : Jean-Luc JOULIN 2018-2019 -- License : General Public Licence (GPLv3) -- Maintainer : Jean-Luc JOULIN -- Stability : alpha -- Portability : portable -- The functions to display data types. -- This module provide functions to module HsIndex.Show ( -- * Function to show the whole index. showIndex , showHeading1 , showHeading2 -- * Function to show a style. , showStyle , showLangDef ) where import HsIndex.Types import Data.List import Data.Char import qualified Data.Text as T -- | Convert a 'IndexStyle' into String -- -- This string is readable by hsindex. -- showStyle style = unlines [ "preamble " ++ show (idxPreamble style) , "postamble " ++ show (idxPostamble style) , "headings_flag " ++ showStyleHeading (idxHeadingFlag0 style) , "heading_prefix " ++ show (idxHeadingPreL0 style) , "heading_suffix " ++ show (idxHeadingSufL0 style) , "headings_flag1 " ++ showStyleHeading (idxHeadingFlag1 style) , "heading_prefix1 " ++ show (idxHeadingPreL1 style) , "heading_suffix1 " ++ show (idxHeadingSufL1 style) , "symhead_positive " ++ show (idxSymhead style) , "numhead_positive " ++ show (idxNumhead style) , "group_skip " ++ show (idxGroupSkip0 style) , "group_skip1 " ++ show (idxGroupSkip1 style) , "item_0 " ++ show (idxItem0 style) , "item_1 " ++ show (idxItem1 style) , "item_2 " ++ show (idxItem2 style) , "item_01 " ++ show (idxItem01 style) , "item_12 " ++ show (idxItem12 style) , "delim_0 " ++ show (idxDelim0 style) , "delim_1 " ++ show (idxDelim1 style) , "delim_2 " ++ show (idxDelim2 style) , "delim_n " ++ show (idxDelimn style) , "delim_r " ++ show (idxDelimr style) , "encap_infix " ++ show (idxEncapPre style) , "encap_suffix " ++ show (idxEncapSuf style) ] -- | Convert 'Heading' into 'String'. showStyleHeading None = "None" showStyleHeading UpperCase = "UpperCase" showStyleHeading LowerCase = "LowerCase" showLangDef def = unlines $ ["LETTERS", lstLetters def] ++ if null (lstNumbers def) then [] else ["NUMBERS", lstNumbers def] ++ case lstSymbols def of Nothing -> [] Just sym -> ["SYMBOLS", sym] ++ if null (lstSubs def) then [] else ["SUBSTITUTIONS"] ++ subS (lstSubs def) where subS [] = [] subS ((a, b) : xs) = (a : "->" ++ b) : subS xs -- | convert an index into a 'Text' showIndex :: IndexStyle -- ^ The index style. -> Bool -- ^ Automatic conversion to pages ranges -> [IndexSection] -- ^ The list of section of the index. -> T.Text -- ^ The output string in the LaTeX format. showIndex style rng lst = T.concat [idxPreamble style, showIndexSections style rng lst, idxPostamble style] -- | convert list of 'IndexSection' into a 'Text' readable with LaTeX. showIndexSections :: IndexStyle -- ^ The index style. -> Bool -- ^ Automatic conversion to pages ranges -> [IndexSection] -- ^ The list of section of the index. -> T.Text -- ^ The output string in the LaTeX format. showIndexSections style _ [] = T.empty showIndexSections style rng lst = T.intercalate (idxGroupSkip0 style) (map (showIndexSection style rng) lstf) where lstf = filter (\(IndexSection tit sub) -> not (null sub)) lst showIndexSection :: IndexStyle -> Bool -> IndexSection -> T.Text showIndexSection style rng (IndexSection "" sub) = showIndexSubSections style rng sub showIndexSection style rng (IndexSection tit []) = T.concat [idxHeadingPreL0 style, tit, idxHeadingSufL0 style] showIndexSection style rng (IndexSection tit sub) = T.concat [ idxHeadingPreL0 style , tit , idxHeadingSufL0 style , showIndexSubSections style rng sub ] -- | convert list of 'IndexSubSection' into a 'Text' readable with LaTeX. showIndexSubSections :: IndexStyle -- ^ The index style. -> Bool -- ^ Automatic conversion to pages ranges -> [IndexSubSection] -- ^ The list of subsection of the index. -> T.Text -- ^ The output string in the LaTeX format. showIndexSubSections style _ [] = "" showIndexSubSections style rng lst = T.intercalate (idxGroupSkip1 style) (map (showIndexSubSection style rng) lstf) where lstf = filter (\(IndexSubSection tit ent) -> not (null ent)) lst showIndexSubSection :: IndexStyle -> Bool -> IndexSubSection -> T.Text showIndexSubSection style rng (IndexSubSection "" ent) = showIndexItems style rng ent showIndexSubSection style _ (IndexSubSection tit []) = T.concat [idxHeadingPreL1 style, tit, idxHeadingSufL1 style] showIndexSubSection style rng (IndexSubSection tit ent) = T.concat [ idxHeadingPreL1 style , tit , idxHeadingSufL1 style , showIndexItems style rng ent ] -- | Convert a list of 'IndexItem' into a 'Text' readable with LaTeX. showIndexItems :: IndexStyle -- ^ The index style. -> Bool -- ^ Automatic conversion to pages ranges -> [IndexItem] -- ^ The list of items of the index. -> T.Text -- ^ The output string in the LaTeX format. showIndexItems style _ [] = "" showIndexItems style rng (IndexItem n _ com p [] : xs) = T.concat [ idxItem0 style , n , idxDelim0 style , showPageRange style com (if rng then 3 else 1000) p , showIndexItems style rng xs ] showIndexItems style rng (IndexItem n _ _ [] sub : xs) = T.concat [ idxItem0 style , n , showIndexSubItems style rng sub , showIndexItems style rng xs ] showIndexItems style rng (IndexItem n _ com p sub : xs) = T.concat [ idxItem0 style , n , idxDelim0 style , showPageRange style com (if rng then 3 else 1000) p , showIndexSubItems style rng sub , showIndexItems style rng xs ] -- | Convert an 'IndexSubItem' into a 'Text' readable with LaTeX. -- -- This function is a transition between entry and its subentries. showIndexSubItems :: IndexStyle -- ^ The index style. -> Bool -- ^ Automatic conversion to pages ranges -> [IndexSubItem] -- ^ The list of subitems of the index. -> T.Text -- ^ The output string in the LaTeX format. showIndexSubItems style _ [] = "" showIndexSubItems style rng (IndexSubItem n _ com p [] : xs) = T.concat [ idxItem01 style , n , idxDelim1 style , showPageRange style com (if rng then 3 else 1000) p , showIndexSubItems' style rng xs ] showIndexSubItems style rng (IndexSubItem n _ _ [] subsub : xs) = T.concat [ idxItem01 style , n , showIndexSubSubItems style rng subsub , showIndexSubItems' style rng xs ] showIndexSubItems style rng (IndexSubItem n _ com p subsub : xs) = T.concat [ idxItem01 style , n , idxDelim1 style , showPageRange style com (if rng then 3 else 1000) p , showIndexSubSubItems style rng subsub , showIndexSubItems' style rng xs ] -- | Convert an 'IndexItem' into a 'Text' readable with LaTeX. showIndexSubItems' :: IndexStyle -> Bool -> [IndexSubItem] -> T.Text showIndexSubItems' style _ [] = "" showIndexSubItems' style rng (IndexSubItem n _ com p [] : xs) = T.concat [ idxItem1 style , n , idxDelim1 style , showPageRange style com (if rng then 3 else 1000) p , showIndexSubItems' style rng xs ] showIndexSubItems' style rng (IndexSubItem n _ _ [] subsub : xs) = T.concat [ idxItem1 style , n , showIndexSubSubItems style rng subsub , showIndexSubItems' style rng xs ] showIndexSubItems' style rng (IndexSubItem n _ com p subsub : xs) = T.concat [ idxItem1 style , n , idxDelim1 style , showPageRange style com (if rng then 3 else 1000) p , showIndexSubSubItems style rng subsub , showIndexSubItems' style rng xs ] -- | Convert an 'IndexSubSubItem' into a 'Text' readable with LaTeX. -- -- This function is a transition between subentries and its subsubentries. showIndexSubSubItems :: IndexStyle -- ^ The index style. -> Bool -- ^ Automatic conversion to pages ranges -> [IndexSubSubItem] -- ^ The list of subsubitems of the index. -> T.Text -- ^ The output string in the LaTeX format. showIndexSubSubItems style _ [] = "" showIndexSubSubItems style rng (IndexSubSubItem n _ com p : xs) = T.concat [ idxItem12 style , n , idxDelim2 style , showPageRange style com (if rng then 3 else 1000) p , showIndexSubSubItems' style rng xs ] -- | Convert an 'IndexSubSubItem' into a 'Text' usable with LaTeX. showIndexSubSubItems' :: IndexStyle -> Bool -> [IndexSubSubItem] -> T.Text showIndexSubSubItems' style _ [] = "" showIndexSubSubItems' style rng (IndexSubSubItem n _ com p : xs) = T.concat [ idxItem2 style , n , idxDelim2 style , showPageRange style com (if rng then 3 else 1000) p , showIndexSubSubItems' style rng xs ] -- | Return the string of the heading (Layer 1) according to the style and -- the equivalent name of an item. showHeading1 :: IndexStyle -- ^ The index style. -> (Section, T.Text) -- ^ The equivalent name. -> T.Text showHeading1 sty (Letters, a) | idxHeadingFlag0 sty == UpperCase = T.toUpper (T.take 1 a) | idxHeadingFlag0 sty == LowerCase = T.toLower (T.take 1 a) | otherwise = T.empty showHeading1 sty (Numbers, a) | idxHeadingFlag0 sty == UpperCase = idxNumhead sty | idxHeadingFlag0 sty == LowerCase = idxNumhead sty | otherwise = T.empty showHeading1 sty (Symbols, a) | idxHeadingFlag0 sty == UpperCase = idxSymhead sty | idxHeadingFlag0 sty == LowerCase = idxSymhead sty | otherwise = T.empty -- | Return the string of the heading (Layer 1) according to the style and -- the equivalent name of an item. showHeading2 :: IndexStyle -- ^ The index style. -> (Section, T.Text) -- ^ The equivalent name. -> T.Text showHeading2 sty (Letters, a) | idxHeadingFlag1 sty == UpperCase = T.toUpper (T.take 2 a) | idxHeadingFlag1 sty == LowerCase = T.toLower (T.take 2 a) | otherwise = T.empty showHeading2 sty (Numbers, a) | idxHeadingFlag1 sty == UpperCase = T.take 1 a | idxHeadingFlag1 sty == LowerCase = T.take 1 a | otherwise = T.empty showHeading2 sty (Symbols, a) | idxHeadingFlag1 sty == UpperCase = T.take 1 a | idxHeadingFlag1 sty == LowerCase = T.take 1 a | otherwise = T.empty groupedBySuccessors [] = [] groupedBySuccessors lst@(x : xs) = map fst ok : groupedBySuccessors (map fst nok) where lstC = [x ..] (ok, nok) = span (\(a, b) -> a == b) $ zip lst lstC showPageRange style com n nums = if com == T.empty then T.intercalate (idxDelimn style) (map showRange grps) else T.intercalate (idxDelimn style) (map showRangeCom grps) where showRangeCom gr = if length gr >= n then T.concat ["\\", com, idxEncapPre style, T.pack $ show (head gr), idxDelimr style, T.pack $ show (last gr), idxEncapSuf style] else T.intercalate (idxDelimn style) (map (\v -> T.concat ["\\", com, idxEncapPre style, T.pack $ show v, idxEncapSuf style]) gr) showRange gr = if length gr >= n then T.concat [T.pack $ show (head gr), idxDelimr style, T.pack $ show (last gr)] else T.intercalate (idxDelimn style) (map (\v -> T.concat [T.pack $ show v]) gr) grps = groupedBySuccessors nums