    {-# LANGUAGE OverloadedStrings #-}
    module Text.Pandoc.Readers.LaTeX.Macro
      ( macroDef
      )
    where
    import Text.Pandoc.Extensions (Extension(..))
    import Text.Pandoc.Logging (LogMessage(MacroAlreadyDefined))
    import Text.Pandoc.Readers.LaTeX.Parsing
    import Text.Pandoc.TeX
    import Text.Pandoc.Class
    import Text.Pandoc.Shared (safeRead)
    import Text.Pandoc.Parsing hiding (blankline, mathDisplay, mathInline,
                                optional, space, spaces, withRaw, (<|>))
    import Control.Applicative ((<|>), optional)
    import qualified Data.Map as M
    import Data.Text (Text)
    import qualified Data.Text as T
    import qualified Data.List.NonEmpty as NonEmpty
    import Data.List.NonEmpty (NonEmpty(..))

    macroDef :: (PandocMonad m, Monoid a) => (Text -> a) -> LP m a
    macroDef :: forall (m :: * -> *) a.
    (PandocMonad m, Monoid a) =>
    (Text -> a) -> LP m a
    macroDef Text -> a
    constructor = do
        (_, s) <- LP m () -> LP m ((), [Tok])
    forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m (a, [Tok])
    withRaw (LP m ()
    commandDef LP m () -> LP m () -> LP m ()
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> LP m ()
    environmentDef)
        (constructor (untokenize s) <$
          guardDisabled Ext_latex_macros)
         <|> return mempty
      where commandDef :: LP m ()
    commandDef = do
              nameMacroPairs <- LP m [(Text, Macro)]
    forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
    newcommand LP m [(Text, Macro)]
    -> LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
                LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall (m :: * -> *).
    PandocMonad m =>
    LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    checkGlobal (LP m [(Text, Macro)]
    forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
    letmacro LP m [(Text, Macro)]
    -> LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> LP m [(Text, Macro)]
    forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
    edefmacro LP m [(Text, Macro)]
    -> LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> LP m [(Text, Macro)]
    forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
    defmacro LP m [(Text, Macro)]
    -> LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> LP m [(Text, Macro)]
    forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
    newif)
              guardDisabled Ext_latex_macros <|>
                mapM_ insertMacro nameMacroPairs
            environmentDef :: LP m ()
    environmentDef = do
              mbenv <- LP m (Maybe (Text, Macro, Macro))
    forall (m :: * -> *).
    PandocMonad m =>
    LP m (Maybe (Text, Macro, Macro))
    newenvironment
              case mbenv of
                Maybe (Text, Macro, Macro)
    Nothing -> () -> LP m ()
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                Just (Text
    name, Macro
    macro1, Macro
    macro2) ->
                  Extension -> LP m ()
    forall s (m :: * -> *) a st.
    (Stream s m a, HasReaderOptions st) =>
    Extension -> ParsecT s st m ()
    guardDisabled Extension
    Ext_latex_macros LP m () -> LP m () -> LP m ()
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
                    do (Text, Macro) -> LP m ()
    forall (m :: * -> *). PandocMonad m => (Text, Macro) -> LP m ()
    insertMacro (Text
    name, Macro
    macro1)
                       (Text, Macro) -> LP m ()
    forall (m :: * -> *). PandocMonad m => (Text, Macro) -> LP m ()
    insertMacro (Text
    "end" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    name, Macro
    macro2)
            -- @\newenvironment{envname}[n-args][default]{begin}{end}@
            -- is equivalent to
            -- @\newcommand{\envname}[n-args][default]{begin}@
            -- @\newcommand{\endenvname}@

    insertMacro :: PandocMonad m => (Text, Macro) -> LP m ()
    insertMacro :: forall (m :: * -> *). PandocMonad m => (Text, Macro) -> LP m ()
    insertMacro (Text
    name, macro' :: Macro
    macro'@(Macro MacroScope
    GlobalScope ExpansionPoint
    _ [ArgSpec]
    _ Maybe [Tok]
    _ [Tok]
    _)) =
      (LaTeXState -> LaTeXState) -> ParsecT TokStream LaTeXState m ()
    forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
    updateState ((LaTeXState -> LaTeXState) -> ParsecT TokStream LaTeXState m ())
    -> (LaTeXState -> LaTeXState) -> ParsecT TokStream LaTeXState m ()
    forall a b. (a -> b) -> a -> b
    $ \LaTeXState
    s ->
         LaTeXState
    s{ sMacros = NonEmpty.map (M.insert name macro') (sMacros s) }
    insertMacro (Text
    name, macro' :: Macro
    macro'@(Macro MacroScope
    GroupScope ExpansionPoint
    _ [ArgSpec]
    _ Maybe [Tok]
    _ [Tok]
    _)) =
      (LaTeXState -> LaTeXState) -> ParsecT TokStream LaTeXState m ()
    forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
    updateState ((LaTeXState -> LaTeXState) -> ParsecT TokStream LaTeXState m ())
    -> (LaTeXState -> LaTeXState) -> ParsecT TokStream LaTeXState m ()
    forall a b. (a -> b) -> a -> b
    $ \LaTeXState
    s ->
         LaTeXState
    s{ sMacros = M.insert name macro' (NonEmpty.head (sMacros s)) :|
                          NonEmpty.tail (sMacros s) }

    lookupMacro :: PandocMonad m => Text -> LP m Macro
    lookupMacro :: forall (m :: * -> *). PandocMonad m => Text -> LP m Macro
    lookupMacro Text
    name = do
       macros :| _ <- LaTeXState -> NonEmpty (Map Text Macro)
    sMacros (LaTeXState -> NonEmpty (Map Text Macro))
    -> ParsecT TokStream LaTeXState m LaTeXState
    -> ParsecT TokStream LaTeXState m (NonEmpty (Map Text Macro))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT TokStream LaTeXState m LaTeXState
    forall (m :: * -> *) s u. Monad m => ParsecT s u m u
    getState
       case M.lookup name macros of
         Just Macro
    m -> Macro -> ParsecT TokStream LaTeXState m Macro
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Macro
    m
         Maybe Macro
    Nothing -> String -> ParsecT TokStream LaTeXState m Macro
    forall a. String -> ParsecT TokStream LaTeXState m a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Macro not found"

    letmacro :: PandocMonad m => LP m [(Text, Macro)]
    letmacro :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
    letmacro = do
      Text -> LP m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "let"
      LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
    withVerbatimMode (LP m [(Text, Macro)] -> LP m [(Text, Macro)])
    -> LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a b. (a -> b) -> a -> b
    $ do
        Tok _ (CtrlSeq name) _ <- LP m Tok
    forall (m :: * -> *). PandocMonad m => LP m Tok
    anyControlSeq
        optional $ symbol '='
        spaces
        -- we first parse in verbatim mode, and then expand macros,
        -- because we don't want \let\foo\bar to turn into
        -- \let\foo hello if we have previously \def\bar{hello}
        target <- anyControlSeq <|> singleChar
        case target of
          (Tok SourcePos
    _ (CtrlSeq Text
    name') Text
    _) ->
             (do m <- Text -> LP m Macro
    forall (m :: * -> *). PandocMonad m => Text -> LP m Macro
    lookupMacro Text
    name'
                 pure [(name, m)])
             LP m [(Text, Macro)]
    -> LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure [(Text
    name,
                        MacroScope
    -> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
    Macro MacroScope
    GroupScope ExpansionPoint
    ExpandWhenDefined [] Maybe [Tok]
    forall a. Maybe a
    Nothing [Tok
    target])]
          Tok
    _ -> [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure [(Text
    name, MacroScope
    -> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
    Macro MacroScope
    GroupScope ExpansionPoint
    ExpandWhenDefined [] Maybe [Tok]
    forall a. Maybe a
    Nothing [Tok
    target])]

    checkGlobal :: PandocMonad m => LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    checkGlobal :: forall (m :: * -> *).
    PandocMonad m =>
    LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    checkGlobal LP m [(Text, Macro)]
    p =
      (Text -> LP m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "global" LP m Tok -> LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a b.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m b
    -> ParsecT TokStream LaTeXState m b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *>
          (((Text, Macro) -> (Text, Macro))
    -> [(Text, Macro)] -> [(Text, Macro)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Text
    n, Macro MacroScope
    _ ExpansionPoint
    expand [ArgSpec]
    arg Maybe [Tok]
    optarg [Tok]
    contents) ->
                    (Text
    n, MacroScope
    -> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
    Macro MacroScope
    GlobalScope ExpansionPoint
    expand [ArgSpec]
    arg Maybe [Tok]
    optarg [Tok]
    contents)) ([(Text, Macro)] -> [(Text, Macro)])
    -> LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> LP m [(Text, Macro)]
    p))
       LP m [(Text, Macro)]
    -> LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> LP m [(Text, Macro)]
    p

    edefmacro :: PandocMonad m => LP m [(Text, Macro)]
    edefmacro :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
    edefmacro = do
      scope <- (MacroScope
    GroupScope MacroScope
    -> ParsecT TokStream LaTeXState m Tok
    -> ParsecT TokStream LaTeXState m MacroScope
    forall a b.
    a
    -> ParsecT TokStream LaTeXState m b
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Text -> ParsecT TokStream LaTeXState m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "edef")
           ParsecT TokStream LaTeXState m MacroScope
    -> ParsecT TokStream LaTeXState m MacroScope
    -> ParsecT TokStream LaTeXState m MacroScope
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> (MacroScope
    GlobalScope MacroScope
    -> ParsecT TokStream LaTeXState m Tok
    -> ParsecT TokStream LaTeXState m MacroScope
    forall a b.
    a
    -> ParsecT TokStream LaTeXState m b
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Text -> ParsecT TokStream LaTeXState m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "xdef")
      (name, contents) <- withVerbatimMode $ do
        Tok _ (CtrlSeq name) _ <- anyControlSeq
        -- we first parse in verbatim mode, and then expand macros,
        -- because we don't want \let\foo\bar to turn into
        -- \let\foo hello if we have previously \def\bar{hello}
        contents <- bracedOrToken
        return (name, contents)
      -- expand macros
      contents' <- parseFromToks (many anyTok) contents
      return [(name, Macro scope ExpandWhenDefined [] Nothing contents')]

    defmacro :: PandocMonad m => LP m [(Text, Macro)]
    defmacro :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
    defmacro = do
      -- we use withVerbatimMode, because macros are to be expanded
      -- at point of use, not point of definition
      scope <- (MacroScope
    GroupScope MacroScope
    -> ParsecT TokStream LaTeXState m Tok
    -> ParsecT TokStream LaTeXState m MacroScope
    forall a b.
    a
    -> ParsecT TokStream LaTeXState m b
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Text -> ParsecT TokStream LaTeXState m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "def")
           ParsecT TokStream LaTeXState m MacroScope
    -> ParsecT TokStream LaTeXState m MacroScope
    -> ParsecT TokStream LaTeXState m MacroScope
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> (MacroScope
    GlobalScope MacroScope
    -> ParsecT TokStream LaTeXState m Tok
    -> ParsecT TokStream LaTeXState m MacroScope
    forall a b.
    a
    -> ParsecT TokStream LaTeXState m b
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Text -> ParsecT TokStream LaTeXState m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "gdef")
      withVerbatimMode $ do
        Tok _ (CtrlSeq name) _ <- anyControlSeq
        argspecs <- many (argspecArg <|> argspecPattern)
        contents <- bracedOrToken
        return [(name, Macro scope ExpandWhenUsed argspecs Nothing contents)]

    -- \newif\iffoo' defines:
    -- \iffoo to be \iffalse
    -- \footrue to be a command that defines \iffoo to be \iftrue
    -- \foofalse to be a command that defines \iffoo to be \iffalse
    newif :: PandocMonad m => LP m [(Text, Macro)]
    newif :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
    newif = do
      Text -> LP m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "newif"
      LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall (m :: * -> *) a. PandocMonad m => LP m a -> LP m a
    withVerbatimMode (LP m [(Text, Macro)] -> LP m [(Text, Macro)])
    -> LP m [(Text, Macro)] -> LP m [(Text, Macro)]
    forall a b. (a -> b) -> a -> b
    $ do
        Tok pos (CtrlSeq name) _ <- LP m Tok
    forall (m :: * -> *). PandocMonad m => LP m Tok
    anyControlSeq
        -- \def\iffoo\iffalse
        -- \def\footrue{\def\iffoo\iftrue}
        -- \def\foofalse{\def\iffoo\iffalse}
        let base = Int -> Text -> Text
    T.drop Int
    2 Text
    name
        return [ (name, Macro GroupScope ExpandWhenUsed [] Nothing
                        [Tok pos (CtrlSeq "iffalse") "\\iffalse"])
               , (base <> "true",
                       Macro GroupScope ExpandWhenUsed [] Nothing
                       [ Tok pos (CtrlSeq "def") "\\def"
                       , Tok pos (CtrlSeq name) ("\\" <> name)
                       , Tok pos Symbol "{"
                       , Tok pos (CtrlSeq "iftrue") "\\iftrue"
                       , Tok pos Symbol "}"
                       ])
               , (base <> "false",
                       Macro GroupScope ExpandWhenUsed [] Nothing
                       [ Tok pos (CtrlSeq "def") "\\def"
                       , Tok pos (CtrlSeq name) ("\\" <> name)
                       , Tok pos Symbol "{"
                       , Tok pos (CtrlSeq "iffalse") "\\iffalse"
                       , Tok pos Symbol "}"
                       ])
               ]

    argspecArg :: PandocMonad m => LP m ArgSpec
    argspecArg :: forall (m :: * -> *). PandocMonad m => LP m ArgSpec
    argspecArg = do
      Tok _ (Arg i) _ <- (Tok -> Bool) -> LP m Tok
    forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
    satisfyTok Tok -> Bool
    isArgTok
      return $ ArgNum i

    argspecPattern :: PandocMonad m => LP m ArgSpec
    argspecPattern :: forall (m :: * -> *). PandocMonad m => LP m ArgSpec
    argspecPattern =
      [Tok] -> ArgSpec
    Pattern ([Tok] -> ArgSpec)
    -> ParsecT TokStream LaTeXState m [Tok]
    -> ParsecT TokStream LaTeXState m ArgSpec
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT TokStream LaTeXState m Tok
    -> ParsecT TokStream LaTeXState m [Tok]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ((Tok -> Bool) -> ParsecT TokStream LaTeXState m Tok
    forall (m :: * -> *). PandocMonad m => (Tok -> Bool) -> LP m Tok
    satisfyTok (\(Tok SourcePos
    _ TokType
    toktype' Text
    txt) ->
                                  (TokType
    toktype' TokType -> TokType -> Bool
    forall a. Eq a => a -> a -> Bool
    == TokType
    Symbol Bool -> Bool -> Bool
    || TokType
    toktype' TokType -> TokType -> Bool
    forall a. Eq a => a -> a -> Bool
    == TokType
    Word) Bool -> Bool -> Bool
    &&
                                  (Text
    txt Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Text
    "{" Bool -> Bool -> Bool
    && Text
    txt Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Text
    "\\" Bool -> Bool -> Bool
    && Text
    txt Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Text
    "}")))

    newcommand :: PandocMonad m => LP m [(Text, Macro)]
    newcommand :: forall (m :: * -> *). PandocMonad m => LP m [(Text, Macro)]
    newcommand = do
      Tok pos (CtrlSeq mtype) _ <- Text -> LP m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "newcommand" LP m Tok -> LP m Tok -> LP m Tok
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
                                 Text -> LP m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "renewcommand" LP m Tok -> LP m Tok -> LP m Tok
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
                                 Text -> LP m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "providecommand" LP m Tok -> LP m Tok -> LP m Tok
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
                                 Text -> LP m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "DeclareMathOperator" LP m Tok -> LP m Tok -> LP m Tok
    forall a.
    ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
                                 Text -> LP m Tok
    forall (m :: * -> *). PandocMonad m => Text -> LP m Tok
    controlSeq Text
    "DeclareRobustCommand"
      withVerbatimMode $ do
        Tok _ (CtrlSeq name) txt <- do
          optional (symbol '*')
          anyControlSeq <|>
            (symbol '{' *> spaces *> anyControlSeq <* spaces <* symbol '}')
        spaces
        numargs <- option 0 $ try bracketedNum
        let argspecs = (Int -> ArgSpec) -> [Int] -> [ArgSpec]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> ArgSpec
    ArgNum [Int
    1..Int
    numargs]
        spaces
        optarg <- option Nothing $ Just <$> try bracketedToks
        spaces
        contents' <- bracedOrToken
        let contents =
             case Text
    mtype of
                  Text
    "DeclareMathOperator" ->
                     SourcePos -> TokType -> Text -> Tok
    Tok SourcePos
    pos (Text -> TokType
    CtrlSeq Text
    "mathop") Text
    "\\mathop"
                     Tok -> [Tok] -> [Tok]
    forall a. a -> [a] -> [a]
    : SourcePos -> TokType -> Text -> Tok
    Tok SourcePos
    pos TokType
    Symbol Text
    "{"
                     Tok -> [Tok] -> [Tok]
    forall a. a -> [a] -> [a]
    : SourcePos -> TokType -> Text -> Tok
    Tok SourcePos
    pos (Text -> TokType
    CtrlSeq Text
    "mathrm") Text
    "\\mathrm"
                     Tok -> [Tok] -> [Tok]
    forall a. a -> [a] -> [a]
    : SourcePos -> TokType -> Text -> Tok
    Tok SourcePos
    pos TokType
    Symbol Text
    "{"
                     Tok -> [Tok] -> [Tok]
    forall a. a -> [a] -> [a]
    : ([Tok]
    contents' [Tok] -> [Tok] -> [Tok]
    forall a. [a] -> [a] -> [a]
    ++
                       [ SourcePos -> TokType -> Text -> Tok
    Tok SourcePos
    pos TokType
    Symbol Text
    "}", SourcePos -> TokType -> Text -> Tok
    Tok SourcePos
    pos TokType
    Symbol Text
    "}" ])
                  Text
    _                     -> [Tok]
    contents'
        let macro = MacroScope
    -> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
    Macro MacroScope
    GroupScope ExpansionPoint
    ExpandWhenUsed [ArgSpec]
    argspecs Maybe [Tok]
    optarg [Tok]
    contents
        (do lookupMacro name
            case mtype of
              Text
    "providecommand" -> [(Text, Macro)] -> ParsecT TokStream LaTeXState m [(Text, Macro)]
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
              Text
    "renewcommand" -> [(Text, Macro)] -> ParsecT TokStream LaTeXState m [(Text, Macro)]
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return [(Text
    name, Macro
    macro)]
              Text
    _ -> [] [(Text, Macro)]
    -> ParsecT TokStream LaTeXState m ()
    -> ParsecT TokStream LaTeXState m [(Text, Macro)]
    forall a b.
    a
    -> ParsecT TokStream LaTeXState m b
    -> ParsecT TokStream LaTeXState m a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ LogMessage -> ParsecT TokStream LaTeXState m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (Text -> SourcePos -> LogMessage
    MacroAlreadyDefined Text
    txt SourcePos
    pos))
          <|> pure [(name, macro)]

    newenvironment :: PandocMonad m => LP m (Maybe (Text, Macro, Macro))
    newenvironment :: forall (m :: * -> *).
    PandocMonad m =>
    LP m (Maybe (Text, Macro, Macro))
    newenvironment = do
      pos <- ParsecT TokStream LaTeXState m SourcePos
    forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
    getPosition
      Tok _ (CtrlSeq mtype) _ <- controlSeq "newenvironment" <|>
                                 controlSeq "renewenvironment" <|>
                                 controlSeq "provideenvironment"
      withVerbatimMode $ do
        optional $ symbol '*'
        spaces
        name <- untokenize <$> braced
        spaces
        numargs <- option 0 $ try bracketedNum
        spaces
        optarg <- option Nothing $ Just <$> try bracketedToks
        let argspecs = (Int -> ArgSpec) -> [Int] -> [ArgSpec]
    forall a b. (a -> b) -> [a] -> [b]
    map (\Int
    i -> Int -> ArgSpec
    ArgNum Int
    i) [Int
    1..Int
    numargs]
        startcontents <- spaces >> bracedOrToken
        endcontents <- spaces >> bracedOrToken
        -- we need the environment to be in a group so macros defined
        -- inside behave correctly:
        let bg = SourcePos -> TokType -> Text -> Tok
    Tok SourcePos
    pos (Text -> TokType
    CtrlSeq Text
    "bgroup") Text
    "\\bgroup "
        let eg = SourcePos -> TokType -> Text -> Tok
    Tok SourcePos
    pos (Text -> TokType
    CtrlSeq Text
    "egroup") Text
    "\\egroup "
        let result = (Text
    name,
                        MacroScope
    -> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
    Macro MacroScope
    GroupScope ExpansionPoint
    ExpandWhenUsed [ArgSpec]
    argspecs Maybe [Tok]
    optarg
                          (Tok
    bgTok -> [Tok] -> [Tok]
    forall a. a -> [a] -> [a]
    :[Tok]
    startcontents),
                        MacroScope
    -> ExpansionPoint -> [ArgSpec] -> Maybe [Tok] -> [Tok] -> Macro
    Macro MacroScope
    GroupScope ExpansionPoint
    ExpandWhenUsed [] Maybe [Tok]
    forall a. Maybe a
    Nothing
                          ([Tok]
    endcontents [Tok] -> [Tok] -> [Tok]
    forall a. [a] -> [a] -> [a]
    ++ [Tok
    eg]))
        (do lookupMacro name
            case mtype of
              Text
    "provideenvironment" -> Maybe (Text, Macro, Macro)
    -> ParsecT TokStream LaTeXState m (Maybe (Text, Macro, Macro))
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Text, Macro, Macro)
    forall a. Maybe a
    Nothing
              Text
    "renewenvironment" -> Maybe (Text, Macro, Macro)
    -> ParsecT TokStream LaTeXState m (Maybe (Text, Macro, Macro))
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((Text, Macro, Macro) -> Maybe (Text, Macro, Macro)
    forall a. a -> Maybe a
    Just (Text, Macro, Macro)
    result)
              Text
    _ -> do
                 LogMessage -> LP m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> LP m ()) -> LogMessage -> LP m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> SourcePos -> LogMessage
    MacroAlreadyDefined Text
    name SourcePos
    pos
                 Maybe (Text, Macro, Macro)
    -> ParsecT TokStream LaTeXState m (Maybe (Text, Macro, Macro))
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Text, Macro, Macro)
    forall a. Maybe a
    Nothing)
          <|> return (Just result)

    bracketedNum :: PandocMonad m => LP m Int
    bracketedNum :: forall (m :: * -> *). PandocMonad m => LP m Int
    bracketedNum = do
      ds <- [Tok] -> Text
    untokenize ([Tok] -> Text)
    -> ParsecT TokStream LaTeXState m [Tok]
    -> ParsecT TokStream LaTeXState m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT TokStream LaTeXState m [Tok]
    forall (m :: * -> *). PandocMonad m => LP m [Tok]
    bracketedToks
      case safeRead ds of
           Just Int
    i -> Int -> ParsecT TokStream LaTeXState m Int
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Int
    i
           Maybe Int
    _      -> Int -> ParsecT TokStream LaTeXState m Int
    forall a. a -> ParsecT TokStream LaTeXState m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Int
    0