{-# LANGUAGE CPP, DeriveDataTypeable, DeriveGeneric #-}

-- | LaTeX syntax description in the definition of the 'LaTeX' datatype.
--   If you want to add new commands or environments not defined in
--   the library, import this module and use 'LaTeX' data constructors.
module Text.LaTeX.Base.Syntax
 ( -- * @LaTeX@ datatype
   Measure (..)
 , MathType (..)
 , LaTeX (..)
 , TeXArg (..)
 , (<>), between
   -- * Escaping reserved characters
 , protectString
 , protectText
   -- * Syntax analysis
 , matchCommand
 , lookForCommand
 , matchEnv
 , lookForEnv
 , texmap
 , texmapM
   -- ** Utils
 , getBody
 , getPreamble
   ) where

import Data.Text (Text,pack)
import qualified Data.Text
import qualified Data.Semigroup as Semigroup
import Data.String
import Control.Applicative
import Control.Monad (replicateM)
import Data.Functor.Identity (runIdentity)
import Data.Data (Data)
import Data.Typeable
import Test.QuickCheck
import Data.Hashable
import GHC.Generics (Generic)
#if !MIN_VERSION_base(4,11,0)
import Data.Monoid
#endif

-- | Measure units defined in LaTeX. Use 'CustomMeasure' to use commands like 'textwidth'.
--   For instance:
--
-- > rule Nothing (CustomMeasure linewidth) (Pt 2)
--
-- This will create a black box (see 'rule') as wide as the text and two points tall.
--
data Measure =
   Pt Double -- ^ A point is 1/72.27 inch, that means about 0.0138 inch or 0.3515 mm.
 | Mm Double -- ^ Millimeter.
 | Cm Double -- ^ Centimeter.
 | In Double -- ^ Inch.
 | Ex Double -- ^ The height of an \"x\" in the current font.
 | Em Double -- ^ The width of an \"M\" in the current font.
 | CustomMeasure LaTeX -- ^ You can introduce a 'LaTeX' expression as a measure.
   deriving (Typeable Measure
DataType
Constr
Typeable Measure
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Measure -> c Measure)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Measure)
-> (Measure -> Constr)
-> (Measure -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Measure))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Measure))
-> ((forall b. Data b => b -> b) -> Measure -> Measure)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Measure -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Measure -> r)
-> (forall u. (forall d. Data d => d -> u) -> Measure -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Measure -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Measure -> m Measure)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Measure -> m Measure)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Measure -> m Measure)
-> Data Measure
Measure -> DataType
Measure -> Constr
(forall b. Data b => b -> b) -> Measure -> Measure
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Measure -> c Measure
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Measure
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Measure -> u
forall u. (forall d. Data d => d -> u) -> Measure -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Measure -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Measure -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Measure -> m Measure
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Measure -> m Measure
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Measure
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Measure -> c Measure
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Measure)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Measure)
$cCustomMeasure :: Constr
$cEm :: Constr
$cEx :: Constr
$cIn :: Constr
$cCm :: Constr
$cMm :: Constr
$cPt :: Constr
$tMeasure :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Measure -> m Measure
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Measure -> m Measure
gmapMp :: (forall d. Data d => d -> m d) -> Measure -> m Measure
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Measure -> m Measure
gmapM :: (forall d. Data d => d -> m d) -> Measure -> m Measure
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Measure -> m Measure
gmapQi :: Int -> (forall d. Data d => d -> u) -> Measure -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Measure -> u
gmapQ :: (forall d. Data d => d -> u) -> Measure -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Measure -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Measure -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Measure -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Measure -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Measure -> r
gmapT :: (forall b. Data b => b -> b) -> Measure -> Measure
$cgmapT :: (forall b. Data b => b -> b) -> Measure -> Measure
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Measure)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Measure)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Measure)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Measure)
dataTypeOf :: Measure -> DataType
$cdataTypeOf :: Measure -> DataType
toConstr :: Measure -> Constr
$ctoConstr :: Measure -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Measure
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Measure
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Measure -> c Measure
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Measure -> c Measure
$cp1Data :: Typeable Measure
Data, Measure -> Measure -> Bool
(Measure -> Measure -> Bool)
-> (Measure -> Measure -> Bool) -> Eq Measure
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Measure -> Measure -> Bool
$c/= :: Measure -> Measure -> Bool
== :: Measure -> Measure -> Bool
$c== :: Measure -> Measure -> Bool
Eq, (forall x. Measure -> Rep Measure x)
-> (forall x. Rep Measure x -> Measure) -> Generic Measure
forall x. Rep Measure x -> Measure
forall x. Measure -> Rep Measure x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Measure x -> Measure
$cfrom :: forall x. Measure -> Rep Measure x
Generic, Int -> Measure -> ShowS
[Measure] -> ShowS
Measure -> String
(Int -> Measure -> ShowS)
-> (Measure -> String) -> ([Measure] -> ShowS) -> Show Measure
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Measure] -> ShowS
$cshowList :: [Measure] -> ShowS
show :: Measure -> String
$cshow :: Measure -> String
showsPrec :: Int -> Measure -> ShowS
$cshowsPrec :: Int -> Measure -> ShowS
Show, Typeable)

-- | Different types of syntax for mathematical expressions.
data MathType = Parentheses | Square | Dollar | DoubleDollar
  deriving (Typeable MathType
DataType
Constr
Typeable MathType
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> MathType -> c MathType)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c MathType)
-> (MathType -> Constr)
-> (MathType -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c MathType))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MathType))
-> ((forall b. Data b => b -> b) -> MathType -> MathType)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> MathType -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> MathType -> r)
-> (forall u. (forall d. Data d => d -> u) -> MathType -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> MathType -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> MathType -> m MathType)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> MathType -> m MathType)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> MathType -> m MathType)
-> Data MathType
MathType -> DataType
MathType -> Constr
(forall b. Data b => b -> b) -> MathType -> MathType
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MathType -> c MathType
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MathType
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> MathType -> u
forall u. (forall d. Data d => d -> u) -> MathType -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MathType -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MathType -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MathType -> m MathType
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MathType -> m MathType
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MathType
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MathType -> c MathType
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MathType)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MathType)
$cDoubleDollar :: Constr
$cDollar :: Constr
$cSquare :: Constr
$cParentheses :: Constr
$tMathType :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> MathType -> m MathType
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MathType -> m MathType
gmapMp :: (forall d. Data d => d -> m d) -> MathType -> m MathType
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MathType -> m MathType
gmapM :: (forall d. Data d => d -> m d) -> MathType -> m MathType
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MathType -> m MathType
gmapQi :: Int -> (forall d. Data d => d -> u) -> MathType -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> MathType -> u
gmapQ :: (forall d. Data d => d -> u) -> MathType -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> MathType -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MathType -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MathType -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MathType -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MathType -> r
gmapT :: (forall b. Data b => b -> b) -> MathType -> MathType
$cgmapT :: (forall b. Data b => b -> b) -> MathType -> MathType
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MathType)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MathType)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c MathType)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MathType)
dataTypeOf :: MathType -> DataType
$cdataTypeOf :: MathType -> DataType
toConstr :: MathType -> Constr
$ctoConstr :: MathType -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MathType
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MathType
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MathType -> c MathType
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MathType -> c MathType
$cp1Data :: Typeable MathType
Data, MathType -> MathType -> Bool
(MathType -> MathType -> Bool)
-> (MathType -> MathType -> Bool) -> Eq MathType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MathType -> MathType -> Bool
$c/= :: MathType -> MathType -> Bool
== :: MathType -> MathType -> Bool
$c== :: MathType -> MathType -> Bool
Eq, (forall x. MathType -> Rep MathType x)
-> (forall x. Rep MathType x -> MathType) -> Generic MathType
forall x. Rep MathType x -> MathType
forall x. MathType -> Rep MathType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MathType x -> MathType
$cfrom :: forall x. MathType -> Rep MathType x
Generic, Int -> MathType -> ShowS
[MathType] -> ShowS
MathType -> String
(Int -> MathType -> ShowS)
-> (MathType -> String) -> ([MathType] -> ShowS) -> Show MathType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MathType] -> ShowS
$cshowList :: [MathType] -> ShowS
show :: MathType -> String
$cshow :: MathType -> String
showsPrec :: Int -> MathType -> ShowS
$cshowsPrec :: Int -> MathType -> ShowS
Show, Typeable)

-- | Type of @LaTeX@ blocks.
data LaTeX =
   TeXRaw Text -- ^ Raw text.
 | TeXComm String [TeXArg] -- ^ Constructor for commands.
                           -- First argument is the name of the command.
                           -- Second, its arguments.
 | TeXCommS String -- ^ Constructor for commands with no arguments.
                   --   When rendering, no space or @{}@ will be added at
                   --   the end.
 | TeXEnv String [TeXArg] LaTeX -- ^ Constructor for environments.
                                -- First argument is the name of the environment.
                                -- Second, its arguments.
                                -- Third, its content.
 | TeXMath MathType LaTeX -- ^ Mathematical expressions.
 | TeXLineBreak (Maybe Measure) Bool -- ^ Line break command.
 | TeXBraces LaTeX -- ^ A expression between braces.
 | TeXComment Text -- ^ Comments.
 | TeXSeq LaTeX LaTeX -- ^ Sequencing of 'LaTeX' expressions.
                      -- Use '<>' preferably.
 | TeXEmpty -- ^ An empty block.
            -- /Neutral element/ of '<>'.
   deriving (Typeable LaTeX
DataType
Constr
Typeable LaTeX
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> LaTeX -> c LaTeX)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LaTeX)
-> (LaTeX -> Constr)
-> (LaTeX -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c LaTeX))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LaTeX))
-> ((forall b. Data b => b -> b) -> LaTeX -> LaTeX)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> LaTeX -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> LaTeX -> r)
-> (forall u. (forall d. Data d => d -> u) -> LaTeX -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> LaTeX -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> LaTeX -> m LaTeX)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LaTeX -> m LaTeX)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> LaTeX -> m LaTeX)
-> Data LaTeX
LaTeX -> DataType
LaTeX -> Constr
(forall b. Data b => b -> b) -> LaTeX -> LaTeX
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LaTeX -> c LaTeX
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LaTeX
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> LaTeX -> u
forall u. (forall d. Data d => d -> u) -> LaTeX -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> LaTeX -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> LaTeX -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> LaTeX -> m LaTeX
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LaTeX -> m LaTeX
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LaTeX
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LaTeX -> c LaTeX
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LaTeX)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LaTeX)
$cTeXEmpty :: Constr
$cTeXSeq :: Constr
$cTeXComment :: Constr
$cTeXBraces :: Constr
$cTeXLineBreak :: Constr
$cTeXMath :: Constr
$cTeXEnv :: Constr
$cTeXCommS :: Constr
$cTeXComm :: Constr
$cTeXRaw :: Constr
$tLaTeX :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> LaTeX -> m LaTeX
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LaTeX -> m LaTeX
gmapMp :: (forall d. Data d => d -> m d) -> LaTeX -> m LaTeX
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> LaTeX -> m LaTeX
gmapM :: (forall d. Data d => d -> m d) -> LaTeX -> m LaTeX
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> LaTeX -> m LaTeX
gmapQi :: Int -> (forall d. Data d => d -> u) -> LaTeX -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> LaTeX -> u
gmapQ :: (forall d. Data d => d -> u) -> LaTeX -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> LaTeX -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> LaTeX -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> LaTeX -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> LaTeX -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> LaTeX -> r
gmapT :: (forall b. Data b => b -> b) -> LaTeX -> LaTeX
$cgmapT :: (forall b. Data b => b -> b) -> LaTeX -> LaTeX
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LaTeX)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LaTeX)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c LaTeX)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LaTeX)
dataTypeOf :: LaTeX -> DataType
$cdataTypeOf :: LaTeX -> DataType
toConstr :: LaTeX -> Constr
$ctoConstr :: LaTeX -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LaTeX
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LaTeX
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LaTeX -> c LaTeX
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LaTeX -> c LaTeX
$cp1Data :: Typeable LaTeX
Data, LaTeX -> LaTeX -> Bool
(LaTeX -> LaTeX -> Bool) -> (LaTeX -> LaTeX -> Bool) -> Eq LaTeX
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LaTeX -> LaTeX -> Bool
$c/= :: LaTeX -> LaTeX -> Bool
== :: LaTeX -> LaTeX -> Bool
$c== :: LaTeX -> LaTeX -> Bool
Eq, (forall x. LaTeX -> Rep LaTeX x)
-> (forall x. Rep LaTeX x -> LaTeX) -> Generic LaTeX
forall x. Rep LaTeX x -> LaTeX
forall x. LaTeX -> Rep LaTeX x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LaTeX x -> LaTeX
$cfrom :: forall x. LaTeX -> Rep LaTeX x
Generic, Int -> LaTeX -> ShowS
[LaTeX] -> ShowS
LaTeX -> String
(Int -> LaTeX -> ShowS)
-> (LaTeX -> String) -> ([LaTeX] -> ShowS) -> Show LaTeX
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LaTeX] -> ShowS
$cshowList :: [LaTeX] -> ShowS
show :: LaTeX -> String
$cshow :: LaTeX -> String
showsPrec :: Int -> LaTeX -> ShowS
$cshowsPrec :: Int -> LaTeX -> ShowS
Show, Typeable)

-- | An argument for a 'LaTeX' command or environment.
data TeXArg =
   FixArg LaTeX    -- ^ Fixed argument.
 | OptArg LaTeX    -- ^ Optional argument.
 | MOptArg [LaTeX] -- ^ Multiple optional argument.
 | SymArg LaTeX    -- ^ An argument enclosed between @\<@ and @\>@.
 | MSymArg [LaTeX] -- ^ Version of 'SymArg' with multiple options.
 | ParArg LaTeX    -- ^ An argument enclosed between @(@ and @)@.
 | MParArg [LaTeX] -- ^ Version of 'ParArg' with multiple options.
   deriving (Typeable TeXArg
DataType
Constr
Typeable TeXArg
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TeXArg -> c TeXArg)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TeXArg)
-> (TeXArg -> Constr)
-> (TeXArg -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TeXArg))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TeXArg))
-> ((forall b. Data b => b -> b) -> TeXArg -> TeXArg)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TeXArg -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TeXArg -> r)
-> (forall u. (forall d. Data d => d -> u) -> TeXArg -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> TeXArg -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> TeXArg -> m TeXArg)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TeXArg -> m TeXArg)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TeXArg -> m TeXArg)
-> Data TeXArg
TeXArg -> DataType
TeXArg -> Constr
(forall b. Data b => b -> b) -> TeXArg -> TeXArg
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TeXArg -> c TeXArg
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TeXArg
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> TeXArg -> u
forall u. (forall d. Data d => d -> u) -> TeXArg -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TeXArg -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TeXArg -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TeXArg -> m TeXArg
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TeXArg -> m TeXArg
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TeXArg
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TeXArg -> c TeXArg
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TeXArg)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TeXArg)
$cMParArg :: Constr
$cParArg :: Constr
$cMSymArg :: Constr
$cSymArg :: Constr
$cMOptArg :: Constr
$cOptArg :: Constr
$cFixArg :: Constr
$tTeXArg :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> TeXArg -> m TeXArg
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TeXArg -> m TeXArg
gmapMp :: (forall d. Data d => d -> m d) -> TeXArg -> m TeXArg
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TeXArg -> m TeXArg
gmapM :: (forall d. Data d => d -> m d) -> TeXArg -> m TeXArg
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> TeXArg -> m TeXArg
gmapQi :: Int -> (forall d. Data d => d -> u) -> TeXArg -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TeXArg -> u
gmapQ :: (forall d. Data d => d -> u) -> TeXArg -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> TeXArg -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TeXArg -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> TeXArg -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TeXArg -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> TeXArg -> r
gmapT :: (forall b. Data b => b -> b) -> TeXArg -> TeXArg
$cgmapT :: (forall b. Data b => b -> b) -> TeXArg -> TeXArg
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TeXArg)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TeXArg)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c TeXArg)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TeXArg)
dataTypeOf :: TeXArg -> DataType
$cdataTypeOf :: TeXArg -> DataType
toConstr :: TeXArg -> Constr
$ctoConstr :: TeXArg -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TeXArg
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TeXArg
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TeXArg -> c TeXArg
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TeXArg -> c TeXArg
$cp1Data :: Typeable TeXArg
Data, TeXArg -> TeXArg -> Bool
(TeXArg -> TeXArg -> Bool)
-> (TeXArg -> TeXArg -> Bool) -> Eq TeXArg
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TeXArg -> TeXArg -> Bool
$c/= :: TeXArg -> TeXArg -> Bool
== :: TeXArg -> TeXArg -> Bool
$c== :: TeXArg -> TeXArg -> Bool
Eq, (forall x. TeXArg -> Rep TeXArg x)
-> (forall x. Rep TeXArg x -> TeXArg) -> Generic TeXArg
forall x. Rep TeXArg x -> TeXArg
forall x. TeXArg -> Rep TeXArg x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TeXArg x -> TeXArg
$cfrom :: forall x. TeXArg -> Rep TeXArg x
Generic, Int -> TeXArg -> ShowS
[TeXArg] -> ShowS
TeXArg -> String
(Int -> TeXArg -> ShowS)
-> (TeXArg -> String) -> ([TeXArg] -> ShowS) -> Show TeXArg
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TeXArg] -> ShowS
$cshowList :: [TeXArg] -> ShowS
show :: TeXArg -> String
$cshow :: TeXArg -> String
showsPrec :: Int -> TeXArg -> ShowS
$cshowsPrec :: Int -> TeXArg -> ShowS
Show, Typeable)

-- Monoid instance for 'LaTeX'.

-- | Method 'mappend' is strict in both arguments (except in the case when the first argument is 'TeXEmpty').
instance Monoid LaTeX where
 mempty :: LaTeX
mempty = LaTeX
TeXEmpty
 mappend :: LaTeX -> LaTeX -> LaTeX
mappend LaTeX
TeXEmpty LaTeX
x = LaTeX
x
 mappend LaTeX
x LaTeX
TeXEmpty = LaTeX
x
 -- This equation is to make 'mappend' associative.
 mappend (TeXSeq LaTeX
x LaTeX
y) LaTeX
z = LaTeX -> LaTeX -> LaTeX
TeXSeq LaTeX
x (LaTeX -> LaTeX) -> LaTeX -> LaTeX
forall a b. (a -> b) -> a -> b
$ LaTeX -> LaTeX -> LaTeX
forall a. Monoid a => a -> a -> a
mappend LaTeX
y LaTeX
z
 --
 mappend LaTeX
x LaTeX
y = LaTeX -> LaTeX -> LaTeX
TeXSeq LaTeX
x LaTeX
y

instance Semigroup.Semigroup LaTeX where
  <> :: LaTeX -> LaTeX -> LaTeX
(<>) = LaTeX -> LaTeX -> LaTeX
forall a. Monoid a => a -> a -> a
mappend

-- | Calling 'between' @c l1 l2@ puts @c@ between @l1@ and @l2@ and
--   appends them.
--
-- > between c l1 l2 = l1 <> c <> l2
between :: Monoid m => m -> m -> m -> m
between :: m -> m -> m -> m
between m
c m
l1 m
l2 = m
l1 m -> m -> m
forall a. Semigroup a => a -> a -> a
<> m
c m -> m -> m
forall a. Semigroup a => a -> a -> a
<> m
l2

-- | Method 'fromString' escapes LaTeX reserved characters using 'protectString'.
instance IsString LaTeX where
 fromString :: String -> LaTeX
fromString = Text -> LaTeX
TeXRaw (Text -> LaTeX) -> (String -> Text) -> String -> LaTeX
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> ShowS -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
protectString

-- | Escape LaTeX reserved characters in a 'String'.
protectString :: String -> String
protectString :: ShowS
protectString = [String] -> String
forall a. Monoid a => [a] -> a
mconcat ([String] -> String) -> (String -> [String]) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> String) -> String -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> String
protectChar

-- | Escape LaTeX reserved characters in a 'Text'.
protectText :: Text -> Text
protectText :: Text -> Text
protectText = (Char -> Text) -> Text -> Text
Data.Text.concatMap (String -> Text
forall a. IsString a => String -> a
fromString (String -> Text) -> (Char -> String) -> Char -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> String
protectChar)

protectChar :: Char -> String
protectChar :: Char -> String
protectChar Char
'#'  = String
"\\#"
protectChar Char
'$'  = String
"\\$"
protectChar Char
'%'  = String
"\\%"
protectChar Char
'^'  = String
"\\^{}"
protectChar Char
'&'  = String
"\\&"
protectChar Char
'{'  = String
"\\{"
protectChar Char
'}'  = String
"\\}"
protectChar Char
'~'  = String
"\\~{}"
protectChar Char
'\\' = String
"\\textbackslash{}"
protectChar Char
'_'  = String
"\\_{}"
protectChar Char
x = [Char
x]

-- Syntax analysis

-- | Look into a 'LaTeX' syntax tree to find any call to the command with
--   the given name. It returns a list of arguments with which this command
--   is called.
--
-- > lookForCommand = (fmap snd .) . matchCommand . (==)
--
--   If the returned list is empty, the command was not found. However,
--   if the list contains empty lists, those are callings to the command
--   with no arguments.
--
--   For example
--
-- > lookForCommand "author" l
--
--   would look for the argument passed to the @\\author@ command in @l@.
lookForCommand :: String -- ^ Name of the command.
               -> LaTeX  -- ^ LaTeX syntax tree.
               -> [[TeXArg]] -- ^ List of arguments passed to the command.
lookForCommand :: String -> LaTeX -> [[TeXArg]]
lookForCommand = (((String, [TeXArg]) -> [TeXArg])
-> [(String, [TeXArg])] -> [[TeXArg]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String, [TeXArg]) -> [TeXArg]
forall a b. (a, b) -> b
snd ([(String, [TeXArg])] -> [[TeXArg]])
-> (LaTeX -> [(String, [TeXArg])]) -> LaTeX -> [[TeXArg]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((LaTeX -> [(String, [TeXArg])]) -> LaTeX -> [[TeXArg]])
-> (String -> LaTeX -> [(String, [TeXArg])])
-> String
-> LaTeX
-> [[TeXArg]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand ((String -> Bool) -> LaTeX -> [(String, [TeXArg])])
-> (String -> String -> Bool)
-> String
-> LaTeX
-> [(String, [TeXArg])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> Bool
forall a. Eq a => a -> a -> Bool
(==)

-- | Traverse a 'LaTeX' syntax tree and returns the commands (see 'TeXComm' and
--   'TeXCommS') that matches the condition and their arguments in each call.
matchCommand :: (String -> Bool) -> LaTeX -> [(String,[TeXArg])]
matchCommand :: (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f (TeXComm String
str [TeXArg]
as) =
  let xs :: [(String, [TeXArg])]
xs = (TeXArg -> [(String, [TeXArg])])
-> [TeXArg] -> [(String, [TeXArg])]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((String -> Bool) -> TeXArg -> [(String, [TeXArg])]
matchCommandArg String -> Bool
f) [TeXArg]
as
  in  if String -> Bool
f String
str then (String
str,[TeXArg]
as) (String, [TeXArg]) -> [(String, [TeXArg])] -> [(String, [TeXArg])]
forall a. a -> [a] -> [a]
: [(String, [TeXArg])]
xs else [(String, [TeXArg])]
xs
matchCommand String -> Bool
f (TeXCommS String
str) = [(String
str, []) | String -> Bool
f String
str]
matchCommand String -> Bool
f (TeXEnv String
_ [TeXArg]
as LaTeX
l) =
  let xs :: [(String, [TeXArg])]
xs = (TeXArg -> [(String, [TeXArg])])
-> [TeXArg] -> [(String, [TeXArg])]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((String -> Bool) -> TeXArg -> [(String, [TeXArg])]
matchCommandArg String -> Bool
f) [TeXArg]
as
  in  [(String, [TeXArg])]
xs [(String, [TeXArg])]
-> [(String, [TeXArg])] -> [(String, [TeXArg])]
forall a. [a] -> [a] -> [a]
++ (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f LaTeX
l
matchCommand String -> Bool
f (TeXMath MathType
_ LaTeX
l) = (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f LaTeX
l
matchCommand String -> Bool
f (TeXBraces LaTeX
l) = (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f LaTeX
l
matchCommand String -> Bool
f (TeXSeq LaTeX
l1 LaTeX
l2) = (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f LaTeX
l1 [(String, [TeXArg])]
-> [(String, [TeXArg])] -> [(String, [TeXArg])]
forall a. [a] -> [a] -> [a]
++ (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f LaTeX
l2
matchCommand String -> Bool
_ LaTeX
_ = []

matchCommandArg :: (String -> Bool) -> TeXArg -> [(String,[TeXArg])]
matchCommandArg :: (String -> Bool) -> TeXArg -> [(String, [TeXArg])]
matchCommandArg String -> Bool
f (OptArg  LaTeX
l ) = (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f LaTeX
l
matchCommandArg String -> Bool
f (FixArg  LaTeX
l ) = (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f LaTeX
l
matchCommandArg String -> Bool
f (MOptArg [LaTeX]
ls) = (LaTeX -> [(String, [TeXArg])]) -> [LaTeX] -> [(String, [TeXArg])]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f) [LaTeX]
ls
matchCommandArg String -> Bool
f (SymArg  LaTeX
l ) = (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f LaTeX
l
matchCommandArg String -> Bool
f (MSymArg [LaTeX]
ls) = (LaTeX -> [(String, [TeXArg])]) -> [LaTeX] -> [(String, [TeXArg])]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f) [LaTeX]
ls
matchCommandArg String -> Bool
f (ParArg  LaTeX
l ) = (String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f LaTeX
l
matchCommandArg String -> Bool
f (MParArg [LaTeX]
ls) = (LaTeX -> [(String, [TeXArg])]) -> [LaTeX] -> [(String, [TeXArg])]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((String -> Bool) -> LaTeX -> [(String, [TeXArg])]
matchCommand String -> Bool
f) [LaTeX]
ls

-- | Similar to 'lookForCommand', but applied to environments.
--   It returns a list with arguments passed and content of the
--   environment in each call.
--
-- > lookForEnv = (fmap (\(_,as,l) -> (as,l)) .) . matchEnv . (==)
--
lookForEnv :: String -> LaTeX -> [([TeXArg],LaTeX)]
lookForEnv :: String -> LaTeX -> [([TeXArg], LaTeX)]
lookForEnv = (((String, [TeXArg], LaTeX) -> ([TeXArg], LaTeX))
-> [(String, [TeXArg], LaTeX)] -> [([TeXArg], LaTeX)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(String
_,[TeXArg]
as,LaTeX
l) -> ([TeXArg]
as,LaTeX
l)) ([(String, [TeXArg], LaTeX)] -> [([TeXArg], LaTeX)])
-> (LaTeX -> [(String, [TeXArg], LaTeX)])
-> LaTeX
-> [([TeXArg], LaTeX)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((LaTeX -> [(String, [TeXArg], LaTeX)])
 -> LaTeX -> [([TeXArg], LaTeX)])
-> (String -> LaTeX -> [(String, [TeXArg], LaTeX)])
-> String
-> LaTeX
-> [([TeXArg], LaTeX)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv ((String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)])
-> (String -> String -> Bool)
-> String
-> LaTeX
-> [(String, [TeXArg], LaTeX)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> Bool
forall a. Eq a => a -> a -> Bool
(==)

-- | Traverse a 'LaTeX' syntax tree and returns the environments (see
--   'TeXEnv') that matches the condition, their arguments and their content
--   in each call.
matchEnv :: (String -> Bool) -> LaTeX -> [(String,[TeXArg],LaTeX)]
matchEnv :: (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f (TeXComm String
_ [TeXArg]
as) = (TeXArg -> [(String, [TeXArg], LaTeX)])
-> [TeXArg] -> [(String, [TeXArg], LaTeX)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((String -> Bool) -> TeXArg -> [(String, [TeXArg], LaTeX)]
matchEnvArg String -> Bool
f) [TeXArg]
as
matchEnv String -> Bool
f (TeXEnv String
str [TeXArg]
as LaTeX
l) =
  let xs :: [(String, [TeXArg], LaTeX)]
xs = (TeXArg -> [(String, [TeXArg], LaTeX)])
-> [TeXArg] -> [(String, [TeXArg], LaTeX)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((String -> Bool) -> TeXArg -> [(String, [TeXArg], LaTeX)]
matchEnvArg String -> Bool
f) [TeXArg]
as
      ys :: [(String, [TeXArg], LaTeX)]
ys = (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f LaTeX
l
      zs :: [(String, [TeXArg], LaTeX)]
zs = [(String, [TeXArg], LaTeX)]
xs [(String, [TeXArg], LaTeX)]
-> [(String, [TeXArg], LaTeX)] -> [(String, [TeXArg], LaTeX)]
forall a. [a] -> [a] -> [a]
++ [(String, [TeXArg], LaTeX)]
ys
  in  if String -> Bool
f String
str then (String
str,[TeXArg]
as,LaTeX
l) (String, [TeXArg], LaTeX)
-> [(String, [TeXArg], LaTeX)] -> [(String, [TeXArg], LaTeX)]
forall a. a -> [a] -> [a]
: [(String, [TeXArg], LaTeX)]
zs else [(String, [TeXArg], LaTeX)]
zs
matchEnv String -> Bool
f (TeXMath MathType
_ LaTeX
l) = (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f LaTeX
l
matchEnv String -> Bool
f (TeXBraces LaTeX
l) = (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f LaTeX
l
matchEnv String -> Bool
f (TeXSeq LaTeX
l1 LaTeX
l2) = (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f LaTeX
l1 [(String, [TeXArg], LaTeX)]
-> [(String, [TeXArg], LaTeX)] -> [(String, [TeXArg], LaTeX)]
forall a. [a] -> [a] -> [a]
++ (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f LaTeX
l2
matchEnv String -> Bool
_ LaTeX
_ = []

matchEnvArg :: (String -> Bool) -> TeXArg -> [(String,[TeXArg],LaTeX)]
matchEnvArg :: (String -> Bool) -> TeXArg -> [(String, [TeXArg], LaTeX)]
matchEnvArg String -> Bool
f (OptArg  LaTeX
l ) = (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f LaTeX
l
matchEnvArg String -> Bool
f (FixArg  LaTeX
l ) = (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f LaTeX
l
matchEnvArg String -> Bool
f (MOptArg [LaTeX]
ls) = (LaTeX -> [(String, [TeXArg], LaTeX)])
-> [LaTeX] -> [(String, [TeXArg], LaTeX)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f) [LaTeX]
ls
matchEnvArg String -> Bool
f (SymArg  LaTeX
l ) = (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f LaTeX
l
matchEnvArg String -> Bool
f (MSymArg [LaTeX]
ls) = (LaTeX -> [(String, [TeXArg], LaTeX)])
-> [LaTeX] -> [(String, [TeXArg], LaTeX)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f) [LaTeX]
ls
matchEnvArg String -> Bool
f (ParArg  LaTeX
l ) = (String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f LaTeX
l
matchEnvArg String -> Bool
f (MParArg [LaTeX]
ls) = (LaTeX -> [(String, [TeXArg], LaTeX)])
-> [LaTeX] -> [(String, [TeXArg], LaTeX)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((String -> Bool) -> LaTeX -> [(String, [TeXArg], LaTeX)]
matchEnv String -> Bool
f) [LaTeX]
ls

-- | The function 'texmap' looks for subexpressions that match a given
--   condition and applies a function to them.
--
-- > texmap c f = runIdentity . texmapM c (pure . f)
texmap :: (LaTeX -> Bool) -- ^ Condition.
       -> (LaTeX -> LaTeX) -- ^ Function to apply when the condition matches.
       ->  LaTeX -> LaTeX
texmap :: (LaTeX -> Bool) -> (LaTeX -> LaTeX) -> LaTeX -> LaTeX
texmap LaTeX -> Bool
c LaTeX -> LaTeX
f = Identity LaTeX -> LaTeX
forall a. Identity a -> a
runIdentity (Identity LaTeX -> LaTeX)
-> (LaTeX -> Identity LaTeX) -> LaTeX -> LaTeX
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LaTeX -> Bool)
-> (LaTeX -> Identity LaTeX) -> LaTeX -> Identity LaTeX
forall (m :: * -> *).
(Applicative m, Monad m) =>
(LaTeX -> Bool) -> (LaTeX -> m LaTeX) -> LaTeX -> m LaTeX
texmapM LaTeX -> Bool
c (LaTeX -> Identity LaTeX
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LaTeX -> Identity LaTeX)
-> (LaTeX -> LaTeX) -> LaTeX -> Identity LaTeX
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LaTeX -> LaTeX
f)

-- | Version of 'texmap' where the function returns values in a 'Monad'.
texmapM :: (Applicative m, Monad m)
        => (LaTeX -> Bool) -- ^ Condition.
        -> (LaTeX -> m LaTeX) -- ^ Function to apply when the condition matches.
        ->  LaTeX -> m LaTeX
texmapM :: (LaTeX -> Bool) -> (LaTeX -> m LaTeX) -> LaTeX -> m LaTeX
texmapM LaTeX -> Bool
c LaTeX -> m LaTeX
f = LaTeX -> m LaTeX
go
  where
   go :: LaTeX -> m LaTeX
go l :: LaTeX
l@(TeXComm String
str [TeXArg]
as)  = if LaTeX -> Bool
c LaTeX
l then LaTeX -> m LaTeX
f LaTeX
l else String -> [TeXArg] -> LaTeX
TeXComm String
str ([TeXArg] -> LaTeX) -> m [TeXArg] -> m LaTeX
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (TeXArg -> m TeXArg) -> [TeXArg] -> m [TeXArg]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM TeXArg -> m TeXArg
go' [TeXArg]
as
   go l :: LaTeX
l@(TeXEnv String
str [TeXArg]
as LaTeX
b) = if LaTeX -> Bool
c LaTeX
l then LaTeX -> m LaTeX
f LaTeX
l else String -> [TeXArg] -> LaTeX -> LaTeX
TeXEnv String
str ([TeXArg] -> LaTeX -> LaTeX) -> m [TeXArg] -> m (LaTeX -> LaTeX)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (TeXArg -> m TeXArg) -> [TeXArg] -> m [TeXArg]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM TeXArg -> m TeXArg
go' [TeXArg]
as m (LaTeX -> LaTeX) -> m LaTeX -> m LaTeX
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> LaTeX -> m LaTeX
go LaTeX
b
   go l :: LaTeX
l@(TeXMath MathType
t LaTeX
b)     = if LaTeX -> Bool
c LaTeX
l then LaTeX -> m LaTeX
f LaTeX
l else MathType -> LaTeX -> LaTeX
TeXMath MathType
t (LaTeX -> LaTeX) -> m LaTeX -> m LaTeX
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LaTeX -> m LaTeX
go LaTeX
b
   go l :: LaTeX
l@(TeXBraces LaTeX
b)     = if LaTeX -> Bool
c LaTeX
l then LaTeX -> m LaTeX
f LaTeX
l else LaTeX -> LaTeX
TeXBraces (LaTeX -> LaTeX) -> m LaTeX -> m LaTeX
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LaTeX -> m LaTeX
go LaTeX
b
   go l :: LaTeX
l@(TeXSeq LaTeX
l1 LaTeX
l2)    = if LaTeX -> Bool
c LaTeX
l then LaTeX -> m LaTeX
f LaTeX
l else (LaTeX -> LaTeX -> LaTeX) -> m LaTeX -> m LaTeX -> m LaTeX
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 LaTeX -> LaTeX -> LaTeX
TeXSeq (LaTeX -> m LaTeX
go LaTeX
l1) (LaTeX -> m LaTeX
go LaTeX
l2)
   go LaTeX
l = if LaTeX -> Bool
c LaTeX
l then LaTeX -> m LaTeX
f LaTeX
l else LaTeX -> m LaTeX
forall (f :: * -> *) a. Applicative f => a -> f a
pure LaTeX
l
   --
   go' :: TeXArg -> m TeXArg
go' (FixArg  LaTeX
l ) = LaTeX -> TeXArg
FixArg  (LaTeX -> TeXArg) -> m LaTeX -> m TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LaTeX -> m LaTeX
go LaTeX
l
   go' (OptArg  LaTeX
l ) = LaTeX -> TeXArg
OptArg  (LaTeX -> TeXArg) -> m LaTeX -> m TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LaTeX -> m LaTeX
go LaTeX
l
   go' (MOptArg [LaTeX]
ls) = [LaTeX] -> TeXArg
MOptArg ([LaTeX] -> TeXArg) -> m [LaTeX] -> m TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LaTeX -> m LaTeX) -> [LaTeX] -> m [LaTeX]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM LaTeX -> m LaTeX
go [LaTeX]
ls
   go' (SymArg  LaTeX
l ) = LaTeX -> TeXArg
SymArg  (LaTeX -> TeXArg) -> m LaTeX -> m TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LaTeX -> m LaTeX
go LaTeX
l
   go' (MSymArg [LaTeX]
ls) = [LaTeX] -> TeXArg
MSymArg ([LaTeX] -> TeXArg) -> m [LaTeX] -> m TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LaTeX -> m LaTeX) -> [LaTeX] -> m [LaTeX]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM LaTeX -> m LaTeX
go [LaTeX]
ls
   go' (ParArg  LaTeX
l ) = LaTeX -> TeXArg
ParArg  (LaTeX -> TeXArg) -> m LaTeX -> m TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LaTeX -> m LaTeX
go LaTeX
l
   go' (MParArg [LaTeX]
ls) = [LaTeX] -> TeXArg
MParArg ([LaTeX] -> TeXArg) -> m [LaTeX] -> m TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LaTeX -> m LaTeX) -> [LaTeX] -> m [LaTeX]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM LaTeX -> m LaTeX
go [LaTeX]
ls

-- | Extract the content of the 'document' environment, if present.
getBody :: LaTeX -> Maybe LaTeX
getBody :: LaTeX -> Maybe LaTeX
getBody LaTeX
l =
  case String -> LaTeX -> [([TeXArg], LaTeX)]
lookForEnv String
"document" LaTeX
l of
    (([TeXArg]
_,LaTeX
b):[([TeXArg], LaTeX)]
_) -> LaTeX -> Maybe LaTeX
forall a. a -> Maybe a
Just LaTeX
b
    [([TeXArg], LaTeX)]
_ -> Maybe LaTeX
forall a. Maybe a
Nothing

-- | Extract the preamble of a 'LaTeX' document (everything before the 'document'
--   environment). It could be empty.
getPreamble :: LaTeX -> LaTeX
getPreamble :: LaTeX -> LaTeX
getPreamble (TeXEnv String
"document" [TeXArg]
_ LaTeX
_) = LaTeX
forall a. Monoid a => a
mempty
getPreamble (TeXSeq LaTeX
l1 LaTeX
l2) = LaTeX -> LaTeX
getPreamble LaTeX
l1 LaTeX -> LaTeX -> LaTeX
forall a. Semigroup a => a -> a -> a
<> LaTeX -> LaTeX
getPreamble LaTeX
l2
getPreamble LaTeX
l = LaTeX
l

---------------------------------------
-- LaTeX Arbitrary instance

arbitraryChar :: Gen Char
arbitraryChar :: Gen Char
arbitraryChar = String -> Gen Char
forall a. [a] -> Gen a
elements (String -> Gen Char) -> String -> Gen Char
forall a b. (a -> b) -> a -> b
$
     [Char
'A'..Char
'Z']
  String -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char
'a'..Char
'z']
  String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n-+*/!\"().,:;'@<>? "

-- | Utility for the instance of 'LaTeX' to 'Arbitrary'.
--   We generate a short sequence of characters and
--   escape reserved characters with 'protectText'.
arbitraryRaw :: Gen Text
arbitraryRaw :: Gen Text
arbitraryRaw = do
  Int
n <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
1,Int
20)
  Text -> Text
protectText (Text -> Text) -> (String -> Text) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> Text) -> Gen String -> Gen Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen Char -> Gen String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n Gen Char
arbitraryChar

-- | Generator for names of command and environments.
--   We use only alphabetical characters.
arbitraryName :: Gen String
arbitraryName :: Gen String
arbitraryName = do
  Int
n <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
1,Int
10)
  Int -> Gen Char -> Gen String
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
n (Gen Char -> Gen String) -> Gen Char -> Gen String
forall a b. (a -> b) -> a -> b
$ String -> Gen Char
forall a. [a] -> Gen a
elements (String -> Gen Char) -> String -> Gen Char
forall a b. (a -> b) -> a -> b
$ [Char
'a' .. Char
'z'] String -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char
'A' .. Char
'Z']

instance Arbitrary Measure where
  arbitrary :: Gen Measure
arbitrary = do
     Int
n <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0,Int
5)
     let f :: Double -> Measure
f = [Double -> Measure
Pt,Double -> Measure
Mm,Double -> Measure
Cm,Double -> Measure
In,Double -> Measure
Ex,Double -> Measure
Em] [Double -> Measure] -> Int -> Double -> Measure
forall a. [a] -> Int -> a
!! Int
n
     Double -> Measure
f (Double -> Measure) -> Gen Double -> Gen Measure
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Double
forall a. Arbitrary a => Gen a
arbitrary

instance Arbitrary LaTeX where
  arbitrary :: Gen LaTeX
arbitrary = Bool -> Gen LaTeX
arbitraryLaTeX Bool
False

arbitraryLaTeX :: Bool -> Gen LaTeX
arbitraryLaTeX :: Bool -> Gen LaTeX
arbitraryLaTeX Bool
inDollar = do
  -- We give more chances to 'TeXRaw'.
  -- This results in arbitrary 'LaTeX' values
  -- not getting too large.
  Int
n <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0,Int
16 :: Int)
  case Int
n of
    Int
0 -> if Bool
inDollar then Bool -> Gen LaTeX
arbitraryLaTeX Bool
True else LaTeX -> Gen LaTeX
forall (f :: * -> *) a. Applicative f => a -> f a
pure LaTeX
TeXEmpty
    Int
1 -> do Int
m <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0,Int
5)
            String -> [TeXArg] -> LaTeX
TeXComm (String -> [TeXArg] -> LaTeX)
-> Gen String -> Gen ([TeXArg] -> LaTeX)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
arbitraryName Gen ([TeXArg] -> LaTeX) -> Gen [TeXArg] -> Gen LaTeX
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> Gen TeXArg -> Gen [TeXArg]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
m Gen TeXArg
forall a. Arbitrary a => Gen a
arbitrary
    Int
2 -> String -> LaTeX
TeXCommS (String -> LaTeX) -> Gen String -> Gen LaTeX
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
arbitraryName
    Int
3 -> do Int
m <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0,Int
5)
            String -> [TeXArg] -> LaTeX -> LaTeX
TeXEnv (String -> [TeXArg] -> LaTeX -> LaTeX)
-> Gen String -> Gen ([TeXArg] -> LaTeX -> LaTeX)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen String
arbitraryName Gen ([TeXArg] -> LaTeX -> LaTeX)
-> Gen [TeXArg] -> Gen (LaTeX -> LaTeX)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> Gen TeXArg -> Gen [TeXArg]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
m Gen TeXArg
forall a. Arbitrary a => Gen a
arbitrary Gen (LaTeX -> LaTeX) -> Gen LaTeX -> Gen LaTeX
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary
    Int
4 -> if Bool
inDollar
            then Bool -> Gen LaTeX
arbitraryLaTeX Bool
True
            else do Int
m <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0,Int
3)
                    let t :: MathType
t = [MathType
Parentheses,MathType
Square,MathType
Dollar,MathType
DoubleDollar] [MathType] -> Int -> MathType
forall a. [a] -> Int -> a
!! Int
m
                    MathType -> LaTeX -> LaTeX
TeXMath (MathType -> LaTeX -> LaTeX)
-> Gen MathType -> Gen (LaTeX -> LaTeX)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MathType -> Gen MathType
forall (f :: * -> *) a. Applicative f => a -> f a
pure MathType
t Gen (LaTeX -> LaTeX) -> Gen LaTeX -> Gen LaTeX
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Bool -> Gen LaTeX
arbitraryLaTeX (MathType
t MathType -> MathType -> Bool
forall a. Eq a => a -> a -> Bool
== MathType
Dollar Bool -> Bool -> Bool
|| MathType
t MathType -> MathType -> Bool
forall a. Eq a => a -> a -> Bool
== MathType
DoubleDollar)
    Int
5 -> Maybe Measure -> Bool -> LaTeX
TeXLineBreak (Maybe Measure -> Bool -> LaTeX)
-> Gen (Maybe Measure) -> Gen (Bool -> LaTeX)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Maybe Measure)
forall a. Arbitrary a => Gen a
arbitrary Gen (Bool -> LaTeX) -> Gen Bool -> Gen LaTeX
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Bool
forall a. Arbitrary a => Gen a
arbitrary
    Int
6 -> LaTeX -> LaTeX
TeXBraces (LaTeX -> LaTeX) -> Gen LaTeX -> Gen LaTeX
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary
    Int
7 -> Text -> LaTeX
TeXComment (Text -> LaTeX) -> Gen Text -> Gen LaTeX
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Text
arbitraryRaw
    Int
8 -> LaTeX -> LaTeX -> LaTeX
TeXSeq (LaTeX -> LaTeX -> LaTeX) -> Gen LaTeX -> Gen (LaTeX -> LaTeX)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (if Bool
inDollar then Bool -> Gen LaTeX
arbitraryLaTeX Bool
True else Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary) Gen (LaTeX -> LaTeX) -> Gen LaTeX -> Gen LaTeX
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary
    Int
_ -> Text -> LaTeX
TeXRaw (Text -> LaTeX) -> Gen Text -> Gen LaTeX
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Text
arbitraryRaw

instance Arbitrary TeXArg where
  arbitrary :: Gen TeXArg
arbitrary = do
     Int
n <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0,Int
6 :: Int)
     case Int
n of
       Int
0 -> LaTeX -> TeXArg
OptArg (LaTeX -> TeXArg) -> Gen LaTeX -> Gen TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary
       Int
1 -> do Int
m <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
1,Int
5)
               [LaTeX] -> TeXArg
MOptArg ([LaTeX] -> TeXArg) -> Gen [LaTeX] -> Gen TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen LaTeX -> Gen [LaTeX]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
m Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary
       Int
2 -> LaTeX -> TeXArg
SymArg (LaTeX -> TeXArg) -> Gen LaTeX -> Gen TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary
       Int
3 -> do Int
m <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
1,Int
5)
               [LaTeX] -> TeXArg
MSymArg ([LaTeX] -> TeXArg) -> Gen [LaTeX] -> Gen TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen LaTeX -> Gen [LaTeX]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
m Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary
       Int
4 -> LaTeX -> TeXArg
ParArg (LaTeX -> TeXArg) -> Gen LaTeX -> Gen TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary
       Int
5 -> do Int
m <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
1,Int
5)
               [LaTeX] -> TeXArg
MParArg ([LaTeX] -> TeXArg) -> Gen [LaTeX] -> Gen TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen LaTeX -> Gen [LaTeX]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
m Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary
       Int
_ -> LaTeX -> TeXArg
FixArg (LaTeX -> TeXArg) -> Gen LaTeX -> Gen TeXArg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen LaTeX
forall a. Arbitrary a => Gen a
arbitrary


instance Hashable Measure
instance Hashable MathType
instance Hashable TeXArg
instance Hashable LaTeX