{-
pandoc-crossref is a pandoc filter for numbering figures,
equations, tables and cross-references to them.
Copyright (C) 2015  Nikolay Yakimov <root@livid.pp.ru>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-}

{-# LANGUAGE OverloadedStrings #-}
module Text.Pandoc.CrossRef.References.List (listOf) where

import Text.Pandoc.Definition
import Data.Accessor.Monad.Trans.State
import Control.Arrow
import Data.List
import qualified Data.Map as M
import qualified Data.Text as T

import Text.Pandoc.CrossRef.References.Types
import Text.Pandoc.CrossRef.Util.Util
import Text.Pandoc.CrossRef.Util.Options

listOf :: Options -> [Block] -> WS [Block]
listOf :: Options -> [Block] -> WS [Block]
listOf Options{outFormat :: Options -> Maybe Format
outFormat=Maybe Format
f} [Block]
x | Maybe Format -> Bool
isLatexFormat Maybe Format
f = [Block] -> WS [Block]
forall (m :: * -> *) a. Monad m => a -> m a
return [Block]
x
listOf Options
opts (RawBlock Format
fmt Text
"\\listoffigures":[Block]
xs)
  | Format -> Bool
isLaTeXRawBlockFmt Format
fmt
  = T References RefMap -> StateT References Identity RefMap
forall (m :: * -> *) r a. Monad m => T r a -> StateT r m a
get T References RefMap
imgRefs StateT References Identity RefMap
-> (RefMap -> WS [Block]) -> WS [Block]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Options -> (Options -> [Block]) -> [Block] -> RefMap -> WS [Block]
makeList Options
opts Options -> [Block]
lofTitle [Block]
xs
listOf Options
opts (RawBlock Format
fmt Text
"\\listoftables":[Block]
xs)
  | Format -> Bool
isLaTeXRawBlockFmt Format
fmt
  = T References RefMap -> StateT References Identity RefMap
forall (m :: * -> *) r a. Monad m => T r a -> StateT r m a
get T References RefMap
tblRefs StateT References Identity RefMap
-> (RefMap -> WS [Block]) -> WS [Block]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Options -> (Options -> [Block]) -> [Block] -> RefMap -> WS [Block]
makeList Options
opts Options -> [Block]
lotTitle [Block]
xs
listOf Options
opts (RawBlock Format
fmt Text
"\\listoflistings":[Block]
xs)
  | Format -> Bool
isLaTeXRawBlockFmt Format
fmt
  = T References RefMap -> StateT References Identity RefMap
forall (m :: * -> *) r a. Monad m => T r a -> StateT r m a
get T References RefMap
lstRefs StateT References Identity RefMap
-> (RefMap -> WS [Block]) -> WS [Block]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Options -> (Options -> [Block]) -> [Block] -> RefMap -> WS [Block]
makeList Options
opts Options -> [Block]
lolTitle [Block]
xs
listOf Options
_ [Block]
x = [Block] -> WS [Block]
forall (m :: * -> *) a. Monad m => a -> m a
return [Block]
x

makeList :: Options -> (Options -> [Block]) -> [Block] -> M.Map T.Text RefRec -> WS [Block]
makeList :: Options -> (Options -> [Block]) -> [Block] -> RefMap -> WS [Block]
makeList Options
opts Options -> [Block]
titlef [Block]
xs RefMap
refs
  = [Block] -> WS [Block]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Block] -> WS [Block]) -> [Block] -> WS [Block]
forall a b. (a -> b) -> a -> b
$
      Options -> [Block]
titlef Options
opts [Block] -> [Block] -> [Block]
forall a. [a] -> [a] -> [a]
++
      (if Options -> Int
chaptersDepth Options
opts Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
        then Attr -> [Block] -> Block
Div (Text
"", [Text
"list"], []) ((Text, RefRec) -> Block
forall a. (a, RefRec) -> Block
itemChap ((Text, RefRec) -> Block) -> [(Text, RefRec)] -> [Block]
forall a b. (a -> b) -> [a] -> [b]
`map` [(Text, RefRec)]
refsSorted)
        else ListAttributes -> [[Block]] -> Block
OrderedList ListAttributes
style ((Text, RefRec) -> [Block]
forall a. (a, RefRec) -> [Block]
item ((Text, RefRec) -> [Block]) -> [(Text, RefRec)] -> [[Block]]
forall a b. (a -> b) -> [a] -> [b]
`map` [(Text, RefRec)]
refsSorted))
      Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
xs
  where
    refsSorted :: [(Text, RefRec)]
refsSorted = ((Text, RefRec) -> (Text, RefRec) -> Ordering)
-> [(Text, RefRec)] -> [(Text, RefRec)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (Text, RefRec) -> (Text, RefRec) -> Ordering
forall a a. (a, RefRec) -> (a, RefRec) -> Ordering
compare' ([(Text, RefRec)] -> [(Text, RefRec)])
-> [(Text, RefRec)] -> [(Text, RefRec)]
forall a b. (a -> b) -> a -> b
$ RefMap -> [(Text, RefRec)]
forall k a. Map k a -> [(k, a)]
M.toList RefMap
refs
    compare' :: (a, RefRec) -> (a, RefRec) -> Ordering
compare' (a
_,RefRec{refIndex :: RefRec -> Index
refIndex=Index
i}) (a
_,RefRec{refIndex :: RefRec -> Index
refIndex=Index
j}) = Index -> Index -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Index
i Index
j
    item :: (a, RefRec) -> [Block]
item = (Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:[]) (Block -> [Block])
-> ((a, RefRec) -> Block) -> (a, RefRec) -> [Block]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> Block
Plain ([Inline] -> Block)
-> ((a, RefRec) -> [Inline]) -> (a, RefRec) -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RefRec -> [Inline]
refTitle (RefRec -> [Inline])
-> ((a, RefRec) -> RefRec) -> (a, RefRec) -> [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, RefRec) -> RefRec
forall a b. (a, b) -> b
snd
    itemChap :: (a, RefRec) -> Block
itemChap = [Inline] -> Block
Para ([Inline] -> Block)
-> ((a, RefRec) -> [Inline]) -> (a, RefRec) -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Inline] -> [Inline] -> [Inline])
-> ([Inline], [Inline]) -> [Inline]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((([Inline] -> [Inline])
-> ([Inline] -> [Inline]) -> [Inline] -> [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Inline
Space Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:)) (([Inline] -> [Inline]) -> [Inline] -> [Inline])
-> ([Inline] -> [Inline] -> [Inline])
-> [Inline]
-> [Inline]
-> [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> [Inline] -> [Inline]
forall a. [a] -> [a] -> [a]
(++)) (([Inline], [Inline]) -> [Inline])
-> ((a, RefRec) -> ([Inline], [Inline])) -> (a, RefRec) -> [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Index -> [Inline]
numWithChap (Index -> [Inline]) -> (RefRec -> Index) -> RefRec -> [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RefRec -> Index
refIndex (RefRec -> [Inline])
-> (RefRec -> [Inline]) -> RefRec -> ([Inline], [Inline])
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& RefRec -> [Inline]
refTitle) (RefRec -> ([Inline], [Inline]))
-> ((a, RefRec) -> RefRec) -> (a, RefRec) -> ([Inline], [Inline])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, RefRec) -> RefRec
forall a b. (a, b) -> b
snd
    numWithChap :: Index -> [Inline]
numWithChap = [Inline] -> Index -> [Inline]
chapPrefix (Options -> [Inline]
chapDelim Options
opts)
    style :: ListAttributes
style = (Int
1,ListNumberStyle
DefaultStyle,ListNumberDelim
DefaultDelim)