{-# LANGUAGE FlexibleInstances #-}
{- |
   Module      : Text.Pandoc.Readers.LaTeX.Types
   Copyright   : Copyright (C) 2017-2022 John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : John MacFarlane <jgm@berkeley.edu>
   Stability   : alpha
   Portability : portable

Types for LaTeX tokens and macros.
-}
module Text.Pandoc.Readers.LaTeX.Types ( Tok(..)
                                       , TokType(..)
                                       , Macro(..)
                                       , ArgSpec(..)
                                       , ExpansionPoint(..)
                                       , MacroScope(..)
                                       , SourcePos
                                       )
where
import Data.Text (Text)
import Text.Parsec.Pos (SourcePos, sourceName)
import Text.Pandoc.Sources
import Data.List (groupBy)

data TokType = CtrlSeq Text | Spaces | Newline | Symbol | Word | Comment |
               Esc1    | Esc2   | Arg Int
     deriving (TokType -> TokType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TokType -> TokType -> Bool
$c/= :: TokType -> TokType -> Bool
== :: TokType -> TokType -> Bool
$c== :: TokType -> TokType -> Bool
Eq, Eq TokType
TokType -> TokType -> Bool
TokType -> TokType -> Ordering
TokType -> TokType -> TokType
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TokType -> TokType -> TokType
$cmin :: TokType -> TokType -> TokType
max :: TokType -> TokType -> TokType
$cmax :: TokType -> TokType -> TokType
>= :: TokType -> TokType -> Bool
$c>= :: TokType -> TokType -> Bool
> :: TokType -> TokType -> Bool
$c> :: TokType -> TokType -> Bool
<= :: TokType -> TokType -> Bool
$c<= :: TokType -> TokType -> Bool
< :: TokType -> TokType -> Bool
$c< :: TokType -> TokType -> Bool
compare :: TokType -> TokType -> Ordering
$ccompare :: TokType -> TokType -> Ordering
Ord, Int -> TokType -> ShowS
[TokType] -> ShowS
TokType -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TokType] -> ShowS
$cshowList :: [TokType] -> ShowS
show :: TokType -> String
$cshow :: TokType -> String
showsPrec :: Int -> TokType -> ShowS
$cshowsPrec :: Int -> TokType -> ShowS
Show)

data Tok = Tok SourcePos TokType Text
     deriving (Tok -> Tok -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Tok -> Tok -> Bool
$c/= :: Tok -> Tok -> Bool
== :: Tok -> Tok -> Bool
$c== :: Tok -> Tok -> Bool
Eq, Eq Tok
Tok -> Tok -> Bool
Tok -> Tok -> Ordering
Tok -> Tok -> Tok
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Tok -> Tok -> Tok
$cmin :: Tok -> Tok -> Tok
max :: Tok -> Tok -> Tok
$cmax :: Tok -> Tok -> Tok
>= :: Tok -> Tok -> Bool
$c>= :: Tok -> Tok -> Bool
> :: Tok -> Tok -> Bool
$c> :: Tok -> Tok -> Bool
<= :: Tok -> Tok -> Bool
$c<= :: Tok -> Tok -> Bool
< :: Tok -> Tok -> Bool
$c< :: Tok -> Tok -> Bool
compare :: Tok -> Tok -> Ordering
$ccompare :: Tok -> Tok -> Ordering
Ord, Int -> Tok -> ShowS
[Tok] -> ShowS
Tok -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Tok] -> ShowS
$cshowList :: [Tok] -> ShowS
show :: Tok -> String
$cshow :: Tok -> String
showsPrec :: Int -> Tok -> ShowS
$cshowsPrec :: Int -> Tok -> ShowS
Show)

instance ToSources [Tok] where
  toSources :: [Tok] -> Sources
toSources = [(SourcePos, Text)] -> Sources
Sources
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (\[Tok]
ts -> case [Tok]
ts of
                    Tok SourcePos
p TokType
_ Text
_ : [Tok]
_ -> (SourcePos
p, forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Tok -> Text
tokToText [Tok]
ts)
                    [Tok]
_ -> forall a. HasCallStack => String -> a
error String
"toSources [Tok] encountered empty group")
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (\(Tok SourcePos
p1 TokType
_ Text
_) (Tok SourcePos
p2 TokType
_ Text
_) -> SourcePos -> String
sourceName SourcePos
p1 forall a. Eq a => a -> a -> Bool
== SourcePos -> String
sourceName SourcePos
p2)

tokToText :: Tok -> Text
tokToText :: Tok -> Text
tokToText (Tok SourcePos
_ TokType
_ Text
t) = Text
t

data ExpansionPoint = ExpandWhenDefined | ExpandWhenUsed
     deriving (ExpansionPoint -> ExpansionPoint -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExpansionPoint -> ExpansionPoint -> Bool
$c/= :: ExpansionPoint -> ExpansionPoint -> Bool
== :: ExpansionPoint -> ExpansionPoint -> Bool
$c== :: ExpansionPoint -> ExpansionPoint -> Bool
Eq, Eq ExpansionPoint
ExpansionPoint -> ExpansionPoint -> Bool
ExpansionPoint -> ExpansionPoint -> Ordering
ExpansionPoint -> ExpansionPoint -> ExpansionPoint
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ExpansionPoint -> ExpansionPoint -> ExpansionPoint
$cmin :: ExpansionPoint -> ExpansionPoint -> ExpansionPoint
max :: ExpansionPoint -> ExpansionPoint -> ExpansionPoint
$cmax :: ExpansionPoint -> ExpansionPoint -> ExpansionPoint
>= :: ExpansionPoint -> ExpansionPoint -> Bool
$c>= :: ExpansionPoint -> ExpansionPoint -> Bool
> :: ExpansionPoint -> ExpansionPoint -> Bool
$c> :: ExpansionPoint -> ExpansionPoint -> Bool
<= :: ExpansionPoint -> ExpansionPoint -> Bool
$c<= :: ExpansionPoint -> ExpansionPoint -> Bool
< :: ExpansionPoint -> ExpansionPoint -> Bool
$c< :: ExpansionPoint -> ExpansionPoint -> Bool
compare :: ExpansionPoint -> ExpansionPoint -> Ordering
$ccompare :: ExpansionPoint -> ExpansionPoint -> Ordering
Ord, Int -> ExpansionPoint -> ShowS
[ExpansionPoint] -> ShowS
ExpansionPoint -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExpansionPoint] -> ShowS
$cshowList :: [ExpansionPoint] -> ShowS
show :: ExpansionPoint -> String
$cshow :: ExpansionPoint -> String
showsPrec :: Int -> ExpansionPoint -> ShowS
$cshowsPrec :: Int -> ExpansionPoint -> ShowS
Show)

data MacroScope = GlobalScope | GroupScope
  deriving (MacroScope -> MacroScope -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MacroScope -> MacroScope -> Bool
$c/= :: MacroScope -> MacroScope -> Bool
== :: MacroScope -> MacroScope -> Bool
$c== :: MacroScope -> MacroScope -> Bool
Eq, Eq MacroScope
MacroScope -> MacroScope -> Bool
MacroScope -> MacroScope -> Ordering
MacroScope -> MacroScope -> MacroScope
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MacroScope -> MacroScope -> MacroScope
$cmin :: MacroScope -> MacroScope -> MacroScope
max :: MacroScope -> MacroScope -> MacroScope
$cmax :: MacroScope -> MacroScope -> MacroScope
>= :: MacroScope -> MacroScope -> Bool
$c>= :: MacroScope -> MacroScope -> Bool
> :: MacroScope -> MacroScope -> Bool
$c> :: MacroScope -> MacroScope -> Bool
<= :: MacroScope -> MacroScope -> Bool
$c<= :: MacroScope -> MacroScope -> Bool
< :: MacroScope -> MacroScope -> Bool
$c< :: MacroScope -> MacroScope -> Bool
compare :: MacroScope -> MacroScope -> Ordering
$ccompare :: MacroScope -> MacroScope -> Ordering
Ord, Int -> MacroScope -> ShowS
[MacroScope] -> ShowS
MacroScope -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MacroScope] -> ShowS
$cshowList :: [MacroScope] -> ShowS
show :: MacroScope -> String
$cshow :: MacroScope -> String
showsPrec :: Int -> MacroScope -> ShowS
$cshowsPrec :: Int -> MacroScope -> ShowS
Show)

data Macro = Macro MacroScope ExpansionPoint [ArgSpec] (Maybe [Tok]) [Tok]
     deriving Int -> Macro -> ShowS
[Macro] -> ShowS
Macro -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Macro] -> ShowS
$cshowList :: [Macro] -> ShowS
show :: Macro -> String
$cshow :: Macro -> String
showsPrec :: Int -> Macro -> ShowS
$cshowsPrec :: Int -> Macro -> ShowS
Show

data ArgSpec = ArgNum Int | Pattern [Tok]
     deriving Int -> ArgSpec -> ShowS
[ArgSpec] -> ShowS
ArgSpec -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ArgSpec] -> ShowS
$cshowList :: [ArgSpec] -> ShowS
show :: ArgSpec -> String
$cshow :: ArgSpec -> String
showsPrec :: Int -> ArgSpec -> ShowS
$cshowsPrec :: Int -> ArgSpec -> ShowS
Show