{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{- |
   Module      : Text.Pandoc.Readers.Docx.Lists
   Copyright   : Copyright (C) 2014-2020 Jesse Rosenthal
   License     : GNU GPL, version 2 or above

   Maintainer  : Jesse Rosenthal <jrosenthal@jhu.edu>
   Stability   : alpha
   Portability : portable

Functions for converting flat docx paragraphs into nested lists.
-}

module Text.Pandoc.Readers.Docx.Lists ( blocksToBullets
                                      , blocksToDefinitions
                                      , listParagraphDivs
                                      , listParagraphStyles
                                      ) where

import Data.List
import Data.Char (isDigit)
import Data.Maybe
import Data.String (fromString)
import qualified Data.Text as T
import Text.Pandoc.Walk (walk)
import Text.Pandoc.JSON
import Text.Pandoc.Readers.Docx.Parse (ParaStyleName)
import Text.Pandoc.Shared (trim, safeRead)

isListItem :: Block -> Bool
isListItem :: Block -> Bool
isListItem (Div (Text
_, [Text]
classes, [(Text, Text)]
_) [Block]
_) | Text
"list-item" Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes = Bool
True
isListItem Block
_                       = Bool
False

getLevel :: Block -> Maybe Integer
getLevel :: Block -> Maybe Integer
getLevel (Div (Text
_, [Text]
_, [(Text, Text)]
kvs) [Block]
_) =  Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"level" [(Text, Text)]
kvs Maybe Text -> (Text -> Maybe Integer) -> Maybe Integer
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Maybe Integer
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead
getLevel Block
_                   = Maybe Integer
forall a. Maybe a
Nothing

getLevelN :: Block -> Integer
getLevelN :: Block -> Integer
getLevelN Block
b = Integer -> Maybe Integer -> Integer
forall a. a -> Maybe a -> a
fromMaybe (-Integer
1) (Block -> Maybe Integer
getLevel Block
b)

getNumId :: Block -> Maybe Integer
getNumId :: Block -> Maybe Integer
getNumId (Div (Text
_, [Text]
_, [(Text, Text)]
kvs) [Block]
_) =  Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"num-id" [(Text, Text)]
kvs Maybe Text -> (Text -> Maybe Integer) -> Maybe Integer
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Maybe Integer
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead
getNumId Block
_                   = Maybe Integer
forall a. Maybe a
Nothing

getNumIdN :: Block -> Integer
getNumIdN :: Block -> Integer
getNumIdN Block
b = Integer -> Maybe Integer -> Integer
forall a. a -> Maybe a -> a
fromMaybe (-Integer
1) (Block -> Maybe Integer
getNumId Block
b)

getText :: Block -> Maybe T.Text
getText :: Block -> Maybe Text
getText (Div (Text
_, [Text]
_, [(Text, Text)]
kvs) [Block]
_) = Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"text" [(Text, Text)]
kvs
getText Block
_                   = Maybe Text
forall a. Maybe a
Nothing

data ListType = Itemized | Enumerated ListAttributes

listStyleMap :: [(T.Text, ListNumberStyle)]
listStyleMap :: [(Text, ListNumberStyle)]
listStyleMap = [(Text
"upperLetter", ListNumberStyle
UpperAlpha),
                (Text
"lowerLetter", ListNumberStyle
LowerAlpha),
                (Text
"upperRoman", ListNumberStyle
UpperRoman),
                (Text
"lowerRoman", ListNumberStyle
LowerRoman),
                (Text
"decimal", ListNumberStyle
Decimal)]

listDelimMap :: [(T.Text, ListNumberDelim)]
listDelimMap :: [(Text, ListNumberDelim)]
listDelimMap = [(Text
"%)", ListNumberDelim
OneParen),
                (Text
"(%)", ListNumberDelim
TwoParens),
                (Text
"%.", ListNumberDelim
Period)]

getListType :: Block -> Maybe ListType
getListType :: Block -> Maybe ListType
getListType b :: Block
b@(Div (Text
_, [Text]
_, [(Text, Text)]
kvs) [Block]
_) | Block -> Bool
isListItem Block
b =
  let
    start :: Maybe Text
start = Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"start" [(Text, Text)]
kvs
    frmt :: Maybe Text
frmt = Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"format" [(Text, Text)]
kvs
    txt :: Maybe Text
txt  = Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"text" [(Text, Text)]
kvs
  in
   case Maybe Text
frmt of
     Just Text
"bullet" -> ListType -> Maybe ListType
forall a. a -> Maybe a
Just ListType
Itemized
     Just Text
f        ->
       case (Char -> Bool) -> Text -> Text
T.filter (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isDigit) (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
txt of
         Just Text
t -> ListType -> Maybe ListType
forall a. a -> Maybe a
Just (ListType -> Maybe ListType) -> ListType -> Maybe ListType
forall a b. (a -> b) -> a -> b
$ ListAttributes -> ListType
Enumerated (
                  Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
1 (Maybe Text
start Maybe Text -> (Text -> Maybe Int) -> Maybe Int
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Maybe Int
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead) :: Int,
                  ListNumberStyle -> Maybe ListNumberStyle -> ListNumberStyle
forall a. a -> Maybe a -> a
fromMaybe ListNumberStyle
DefaultStyle (Text -> [(Text, ListNumberStyle)] -> Maybe ListNumberStyle
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
f [(Text, ListNumberStyle)]
listStyleMap),
                  ListNumberDelim -> Maybe ListNumberDelim -> ListNumberDelim
forall a. a -> Maybe a -> a
fromMaybe ListNumberDelim
DefaultDelim (Text -> [(Text, ListNumberDelim)] -> Maybe ListNumberDelim
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
t [(Text, ListNumberDelim)]
listDelimMap))
         Maybe Text
Nothing -> Maybe ListType
forall a. Maybe a
Nothing
     Maybe Text
_ -> Maybe ListType
forall a. Maybe a
Nothing
getListType Block
_ = Maybe ListType
forall a. Maybe a
Nothing

listParagraphDivs :: [T.Text]
listParagraphDivs :: [Text]
listParagraphDivs = [Text
"list-paragraph"]

listParagraphStyles :: [ParaStyleName]
listParagraphStyles :: [ParaStyleName]
listParagraphStyles = (Text -> ParaStyleName) -> [Text] -> [ParaStyleName]
forall a b. (a -> b) -> [a] -> [b]
map (String -> ParaStyleName
forall a. IsString a => String -> a
fromString (String -> ParaStyleName)
-> (Text -> String) -> Text -> ParaStyleName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack) [Text]
listParagraphDivs

-- This is a first stab at going through and attaching meaning to list
-- paragraphs, without an item marker, following a list item. We
-- assume that these are paragraphs in the same item.

handleListParagraphs :: [Block] -> [Block]
handleListParagraphs :: [Block] -> [Block]
handleListParagraphs [] = []
handleListParagraphs (
  Div attr1 :: (Text, [Text], [(Text, Text)])
attr1@(Text
_, [Text]
classes1, [(Text, Text)]
_) [Block]
blks1 :
  Div (Text
ident2, [Text]
classes2, [(Text, Text)]
kvs2) [Block]
blks2 :
  [Block]
blks
  ) | Text
"list-item" Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes1 Bool -> Bool -> Bool
&&
    Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
notElem Text
"list-item" [Text]
classes2 Bool -> Bool -> Bool
&&
    (Bool -> Bool
not (Bool -> Bool) -> ([Text] -> Bool) -> [Text] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) ([Text]
listParagraphDivs [Text] -> [Text] -> [Text]
forall a. Eq a => [a] -> [a] -> [a]
`intersect` [Text]
classes2) =
      -- We don't want to keep this indent.
      let newDiv2 :: Block
newDiv2 =
            (Text, [Text], [(Text, Text)]) -> [Block] -> Block
Div (Text
ident2, [Text]
classes2, ((Text, Text) -> Bool) -> [(Text, Text)] -> [(Text, Text)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(Text, Text)
kv -> (Text, Text) -> Text
forall a b. (a, b) -> a
fst (Text, Text)
kv Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"indent") [(Text, Text)]
kvs2) [Block]
blks2
      in
       [Block] -> [Block]
handleListParagraphs ((Text, [Text], [(Text, Text)]) -> [Block] -> Block
Div (Text, [Text], [(Text, Text)])
attr1 ([Block]
blks1 [Block] -> [Block] -> [Block]
forall a. [a] -> [a] -> [a]
++ [Block
newDiv2]) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
blks)
handleListParagraphs (Block
blk:[Block]
blks) = Block
blk Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block] -> [Block]
handleListParagraphs [Block]
blks

separateBlocks' :: Block -> [[Block]] -> [[Block]]
separateBlocks' :: Block -> [[Block]] -> [[Block]]
separateBlocks' Block
blk [[]] = [[Block
blk]]
separateBlocks' b :: Block
b@(BulletList [[Block]]
_) [[Block]]
acc = [[Block]] -> [[Block]]
forall a. HasCallStack => [a] -> [a]
init [[Block]]
acc [[Block]] -> [[Block]] -> [[Block]]
forall a. [a] -> [a] -> [a]
++ [[[Block]] -> [Block]
forall a. HasCallStack => [a] -> a
last [[Block]]
acc [Block] -> [Block] -> [Block]
forall a. [a] -> [a] -> [a]
++ [Block
b]]
separateBlocks' b :: Block
b@(OrderedList ListAttributes
_ [[Block]]
_) [[Block]]
acc = [[Block]] -> [[Block]]
forall a. HasCallStack => [a] -> [a]
init [[Block]]
acc [[Block]] -> [[Block]] -> [[Block]]
forall a. [a] -> [a] -> [a]
++ [[[Block]] -> [Block]
forall a. HasCallStack => [a] -> a
last [[Block]]
acc [Block] -> [Block] -> [Block]
forall a. [a] -> [a] -> [a]
++ [Block
b]]
-- The following is for the invisible bullet lists. This is how
-- pandoc-generated ooxml does multiparagraph item lists.
separateBlocks' Block
b [[Block]]
acc | (Text -> Text) -> Maybe Text -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Text
trim (Block -> Maybe Text
getText Block
b) Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"" =
  [[Block]] -> [[Block]]
forall a. HasCallStack => [a] -> [a]
init [[Block]]
acc [[Block]] -> [[Block]] -> [[Block]]
forall a. [a] -> [a] -> [a]
++ [[[Block]] -> [Block]
forall a. HasCallStack => [a] -> a
last [[Block]]
acc [Block] -> [Block] -> [Block]
forall a. [a] -> [a] -> [a]
++ [Block
b]]
separateBlocks' Block
b [[Block]]
acc = [[Block]]
acc [[Block]] -> [[Block]] -> [[Block]]
forall a. [a] -> [a] -> [a]
++ [[Block
b]]

separateBlocks :: [Block] -> [[Block]]
separateBlocks :: [Block] -> [[Block]]
separateBlocks [Block]
blks = (Block -> [[Block]] -> [[Block]])
-> [[Block]] -> [Block] -> [[Block]]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Block -> [[Block]] -> [[Block]]
separateBlocks' [[]] ([Block] -> [Block]
forall a. [a] -> [a]
reverse [Block]
blks)

flatToBullets' :: Integer -> [Block] -> [Block]
flatToBullets' :: Integer -> [Block] -> [Block]
flatToBullets' Integer
_ [] = []
flatToBullets' Integer
num xs :: [Block]
xs@(Block
b : [Block]
elems) =
  if Block -> Integer
getLevelN Block
b Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
num
     then (case Maybe Bool
bCheckmark of
             Just Bool
checked -> Bool -> Block -> Block
addCheckmark Bool
checked Block
b
             Maybe Bool
Nothing -> Block
b) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: Integer -> [Block] -> [Block]
flatToBullets' Integer
num [Block]
elems
     else case Block -> Maybe ListType
getListType Block
b of
            Just (Enumerated ListAttributes
attr) ->
              ListAttributes -> [[Block]] -> Block
OrderedList ListAttributes
attr ([Block] -> [[Block]]
separateBlocks ([Block] -> [[Block]]) -> [Block] -> [[Block]]
forall a b. (a -> b) -> a -> b
$ Integer -> [Block] -> [Block]
flatToBullets' Integer
bLevel [Block]
children) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:
              Integer -> [Block] -> [Block]
flatToBullets' Integer
num [Block]
remaining
            Maybe ListType
_ ->
              [[Block]] -> Block
BulletList ([Block] -> [[Block]]
separateBlocks ([Block] -> [[Block]]) -> [Block] -> [[Block]]
forall a b. (a -> b) -> a -> b
$ Integer -> [Block] -> [Block]
flatToBullets' Integer
bLevel [Block]
children) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:
              Integer -> [Block] -> [Block]
flatToBullets' Integer
num [Block]
remaining
 where
  bNumId :: Integer
bNumId = Block -> Integer
getNumIdN Block
b
  bLevel :: Integer
bLevel = Block -> Integer
getLevelN Block
b
  isCheckmark :: Maybe a -> Maybe Bool
isCheckmark (Just a
"\9744") = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
  isCheckmark (Just a
"\9746") = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True
  isCheckmark Maybe a
_ = Maybe Bool
forall a. Maybe a
Nothing
  bCheckmark :: Maybe Bool
bCheckmark =
    case Block -> Maybe ListType
getListType Block
b of
      Just ListType
Itemized -> Maybe Text -> Maybe Bool
forall {a}. (Eq a, IsString a) => Maybe a -> Maybe Bool
isCheckmark (Block -> Maybe Text
getText Block
b)
      Maybe ListType
_ -> Maybe Bool
forall a. Maybe a
Nothing
  addCheckmark :: Bool -> Block -> Block
addCheckmark Bool
checked (Div (Text, [Text], [(Text, Text)])
attrs [Para [Inline]
ils]) =
    (Text, [Text], [(Text, Text)]) -> [Block] -> Block
Div (Text, [Text], [(Text, Text)])
attrs [[Inline] -> Block
Para (Text -> Inline
Str (if Bool
checked then Text
"\9746" else Text
"\9744") Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: Inline
Space Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: [Inline]
ils)]
  addCheckmark Bool
checked (Div (Text, [Text], [(Text, Text)])
attrs [Plain [Inline]
ils]) =
    (Text, [Text], [(Text, Text)]) -> [Block] -> Block
Div (Text, [Text], [(Text, Text)])
attrs [[Inline] -> Block
Plain (Text -> Inline
Str (if Bool
checked then Text
"\9746" else Text
"\9744") Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: Inline
Space Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: [Inline]
ils)]
  addCheckmark Bool
_ Block
x = Block
x
  ([Block]
children, [Block]
remaining) =
    (Block -> Bool) -> [Block] -> ([Block], [Block])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span
    (\Block
b' ->
      Block -> Integer
getLevelN Block
b' Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
bLevel Bool -> Bool -> Bool
||
       (Block -> Integer
getLevelN Block
b' Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
bLevel Bool -> Bool -> Bool
&&
          (Block -> Integer
getNumIdN Block
b' Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
bNumId Bool -> Bool -> Bool
||
            (case Maybe Bool
bCheckmark of
               Just Bool
_ ->
                 case Block -> Maybe Text
getText Block
b' of
                   Just Text
"" -> Bool
True
                   Just Text
" " -> Bool
True
                   Just Text
x -> Maybe Bool -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Maybe Bool
forall {a}. (Eq a, IsString a) => Maybe a -> Maybe Bool
isCheckmark (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
x))
                   Maybe Text
Nothing -> Bool
False
               Maybe Bool
Nothing -> Bool
False))))
    [Block]
xs

flatToBullets :: [Block] -> [Block]
flatToBullets :: [Block] -> [Block]
flatToBullets [Block]
elems = Integer -> [Block] -> [Block]
flatToBullets' (-Integer
1) [Block]
elems

singleItemHeaderToHeader :: Block -> Block
singleItemHeaderToHeader :: Block -> Block
singleItemHeaderToHeader (OrderedList ListAttributes
_ [[h :: Block
h@Header{}]]) = Block
h
singleItemHeaderToHeader Block
blk                            = Block
blk


blocksToBullets :: [Block] -> [Block]
blocksToBullets :: [Block] -> [Block]
blocksToBullets [Block]
blks =
  (Block -> Block) -> [Block] -> [Block]
forall a b. (a -> b) -> [a] -> [b]
map Block -> Block
singleItemHeaderToHeader ([Block] -> [Block]) -> [Block] -> [Block]
forall a b. (a -> b) -> a -> b
$
  ([Block] -> [Block]) -> [Block] -> [Block]
forall a b. Walkable a b => (a -> a) -> b -> b
walk [Block] -> [Block]
removeListDivs ([Block] -> [Block]) -> [Block] -> [Block]
forall a b. (a -> b) -> a -> b
$ [Block] -> [Block]
flatToBullets ([Block] -> [Block]
handleListParagraphs [Block]
blks)

plainParaInlines :: Block -> [Inline]
plainParaInlines :: Block -> [Inline]
plainParaInlines (Plain [Inline]
ils) = [Inline]
ils
plainParaInlines (Para [Inline]
ils)  = [Inline]
ils
plainParaInlines Block
_           = []

blocksToDefinitions' :: [([Inline], [[Block]])] -> [Block] -> [Block] -> [Block]
blocksToDefinitions' :: [([Inline], [[Block]])] -> [Block] -> [Block] -> [Block]
blocksToDefinitions' []     [Block]
acc [] = [Block] -> [Block]
forall a. [a] -> [a]
reverse [Block]
acc
blocksToDefinitions' [([Inline], [[Block]])]
defAcc [Block]
acc [] =
  [Block] -> [Block]
forall a. [a] -> [a]
reverse ([Block] -> [Block]) -> [Block] -> [Block]
forall a b. (a -> b) -> a -> b
$ [([Inline], [[Block]])] -> Block
DefinitionList ([([Inline], [[Block]])] -> [([Inline], [[Block]])]
forall a. [a] -> [a]
reverse [([Inline], [[Block]])]
defAcc) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
acc
blocksToDefinitions' [([Inline], [[Block]])]
defAcc [Block]
acc
  (Div (Text
_, [Text]
classes1, [(Text, Text)]
_) [Block]
blks1 : Div (Text
ident2, [Text]
classes2, [(Text, Text)]
kvs2) [Block]
blks2 : [Block]
blks)
  | Text
"Definition-Term" Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes1 Bool -> Bool -> Bool
&& Text
"Definition"  Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes2 =
    let remainingAttr2 :: (Text, [Text], [(Text, Text)])
remainingAttr2 = (Text
ident2, Text -> [Text] -> [Text]
forall a. Eq a => a -> [a] -> [a]
delete Text
"Definition" [Text]
classes2, [(Text, Text)]
kvs2)
        pair :: ([Inline], [[Block]])
pair = if (Text, [Text], [(Text, Text)])
remainingAttr2 (Text, [Text], [(Text, Text)])
-> (Text, [Text], [(Text, Text)]) -> Bool
forall a. Eq a => a -> a -> Bool
== (Text
"", [], []) then ((Block -> [Inline]) -> [Block] -> [Inline]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Block -> [Inline]
plainParaInlines [Block]
blks1, [[Block]
blks2]) else ((Block -> [Inline]) -> [Block] -> [Inline]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Block -> [Inline]
plainParaInlines [Block]
blks1, [[(Text, [Text], [(Text, Text)]) -> [Block] -> Block
Div (Text, [Text], [(Text, Text)])
remainingAttr2 [Block]
blks2]])
    in
     [([Inline], [[Block]])] -> [Block] -> [Block] -> [Block]
blocksToDefinitions' (([Inline], [[Block]])
pair ([Inline], [[Block]])
-> [([Inline], [[Block]])] -> [([Inline], [[Block]])]
forall a. a -> [a] -> [a]
: [([Inline], [[Block]])]
defAcc) [Block]
acc [Block]
blks
blocksToDefinitions' (([Inline]
defTerm, [[Block]]
defItems):[([Inline], [[Block]])]
defs) [Block]
acc
  (Div (Text
ident2, [Text]
classes2, [(Text, Text)]
kvs2) [Block]
blks2 : [Block]
blks)
  | Text
"Definition"  Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes2 =
    let remainingAttr2 :: (Text, [Text], [(Text, Text)])
remainingAttr2 = (Text
ident2, Text -> [Text] -> [Text]
forall a. Eq a => a -> [a] -> [a]
delete Text
"Definition" [Text]
classes2, [(Text, Text)]
kvs2)
        defItems2 :: [Block]
defItems2 = if (Text, [Text], [(Text, Text)])
remainingAttr2 (Text, [Text], [(Text, Text)])
-> (Text, [Text], [(Text, Text)]) -> Bool
forall a. Eq a => a -> a -> Bool
== (Text
"", [], [])
          then [Block]
blks2
          else [(Text, [Text], [(Text, Text)]) -> [Block] -> Block
Div (Text, [Text], [(Text, Text)])
remainingAttr2 [Block]
blks2]
        defAcc' :: [([Inline], [[Block]])]
defAcc' = if [[Block]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Block]]
defItems
          then ([Inline]
defTerm, [[Block]
defItems2]) ([Inline], [[Block]])
-> [([Inline], [[Block]])] -> [([Inline], [[Block]])]
forall a. a -> [a] -> [a]
: [([Inline], [[Block]])]
defs
          else ([Inline]
defTerm, [[Block]] -> [[Block]]
forall a. HasCallStack => [a] -> [a]
init [[Block]]
defItems [[Block]] -> [[Block]] -> [[Block]]
forall a. [a] -> [a] -> [a]
++ [[[Block]] -> [Block]
forall a. HasCallStack => [a] -> a
last [[Block]]
defItems [Block] -> [Block] -> [Block]
forall a. [a] -> [a] -> [a]
++ [Block]
defItems2]) ([Inline], [[Block]])
-> [([Inline], [[Block]])] -> [([Inline], [[Block]])]
forall a. a -> [a] -> [a]
: [([Inline], [[Block]])]
defs
    in
     [([Inline], [[Block]])] -> [Block] -> [Block] -> [Block]
blocksToDefinitions' [([Inline], [[Block]])]
defAcc' [Block]
acc [Block]
blks
blocksToDefinitions' [] [Block]
acc (Block
b:[Block]
blks) =
  [([Inline], [[Block]])] -> [Block] -> [Block] -> [Block]
blocksToDefinitions' [] (Block
bBlock -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:[Block]
acc) [Block]
blks
blocksToDefinitions' [([Inline], [[Block]])]
defAcc [Block]
acc (Block
b:[Block]
blks) =
  [([Inline], [[Block]])] -> [Block] -> [Block] -> [Block]
blocksToDefinitions' [] (Block
b Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [([Inline], [[Block]])] -> Block
DefinitionList ([([Inline], [[Block]])] -> [([Inline], [[Block]])]
forall a. [a] -> [a]
reverse [([Inline], [[Block]])]
defAcc) Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
acc) [Block]
blks

removeListDivs' :: Block -> [Block]
removeListDivs' :: Block -> [Block]
removeListDivs' (Div (Text
ident, [Text]
classes, [(Text, Text)]
kvs) [Block]
blks)
  | Text
"list-item" Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes =
    case Text -> [Text] -> [Text]
forall a. Eq a => a -> [a] -> [a]
delete Text
"list-item" [Text]
classes of
      []       -> [Block]
blks
      [Text]
classes' -> [(Text, [Text], [(Text, Text)]) -> [Block] -> Block
Div (Text
ident, [Text]
classes', [(Text, Text)]
kvs) [Block]
blks]
removeListDivs' (Div (Text
ident, [Text]
classes, [(Text, Text)]
kvs) [Block]
blks)
  | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Text] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Text] -> Bool) -> [Text] -> Bool
forall a b. (a -> b) -> a -> b
$ [Text]
listParagraphDivs [Text] -> [Text] -> [Text]
forall a. Eq a => [a] -> [a] -> [a]
`intersect` [Text]
classes =
    case [Text]
classes [Text] -> [Text] -> [Text]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Text]
listParagraphDivs of
      []       -> [Block]
blks
      [Text]
classes' -> [(Text, [Text], [(Text, Text)]) -> [Block] -> Block
Div (Text
ident, [Text]
classes', [(Text, Text)]
kvs) [Block]
blks]
removeListDivs' Block
blk = [Block
blk]

removeListDivs :: [Block] -> [Block]
removeListDivs :: [Block] -> [Block]
removeListDivs = (Block -> [Block]) -> [Block] -> [Block]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Block -> [Block]
removeListDivs'

blocksToDefinitions :: [Block] -> [Block]
blocksToDefinitions :: [Block] -> [Block]
blocksToDefinitions = [([Inline], [[Block]])] -> [Block] -> [Block] -> [Block]
blocksToDefinitions' [] []