-- | The writer monad applied to 'LaTeX' values. Useful to compose 'LaTeX' values-- using the @do@ notation:---- > anExample :: Monad m => LaTeXT m ()-- > anExample = do-- > documentclass [] article-- > author "Daniel Monad"-- > title "LaTeX and do notation"-- > document $ do-- > maketitle-- > section "Some words"-- > "Using " ; texttt "do" ; " notation "-- > "you avoid many ocurrences of the "-- > texttt "(<>)" ; " operator and a lot of "-- > "parentheses. With the cost of a monad."---- Since 'LaTeXT' is a monad transformer, you can do also:---- > anotherExample :: LaTeXT IO ()-- > anotherExample = lift (readFile "foo") >>= verbatim . fromString---- This way, it is easy (without carrying arguments) to include IO outputs-- in the LaTeX document, like files, times or random objects.---- Another approach could be to have custom counters, label management-- or any other user-defined feature.---- Of course, you can always use the simpler interface provided by the plain 'LaTeX' type.moduleText.LaTeX.Base.Writer(-- * @LaTeXT@ writerLaTeXT,LaTeXT_,runLaTeXT,execLaTeXT,execLaTeXTWarn,extractLaTeX,extractLaTeX_,textell,rendertexM,liftFun,liftOp-- * Errors,throwError,merror-- * Re-export,lift,liftIO)whereimportControl.Monad.Trans.WriterimportControl.Monad.Trans.StateimportControl.Monad.IO.ClassimportControl.Monad.Trans.ClassimportControl.ApplicativeimportControl.ArrowimportData.StringimportData.Monoid--importText.LaTeX.Base.SyntaximportText.LaTeX.Base.ClassimportText.LaTeX.Base.RenderimportText.LaTeX.Base.Warnings(Warning,checkAll,check)--importControl.Monad(liftM)newtypeLaTeXTma=LaTeXT{unwrapLaTeXT::WriterTLaTeXm(a,MaybeString)}instanceFunctorf=>Functor(LaTeXTf)wherefmapf(LaTeXTc)=LaTeXT$fmap(firstf)cpairNoth::a->(a,Maybeb)pairNothx=(x,Nothing)instanceApplicativef=>Applicative(LaTeXTf)wherepure=LaTeXT.pure.pairNoth(LaTeXTf)<*>(LaTeXTx)=LaTeXT$fmap(first.fst)f<*>xtypeLaTeXT_m=LaTeXTm()instanceMonadTransLaTeXTwherelift=LaTeXT.liftMpairNoth.liftinstanceMonadm=>Monad(LaTeXTm)wherereturn=LaTeXT.return.pairNoth(LaTeXTc)>>=f=LaTeXT$do(a,_)<-cletLaTeXTc'=fac'fail=throwErrorinstanceMonadIOm=>MonadIO(LaTeXTm)whereliftIO=lift.liftIOinstanceMonadm=>LaTeXC(LaTeXTma)whereliftListLfxs=mapMextractLaTeX_xs>>=merror"liftListL".textell.frunLaTeXT::Monadm=>LaTeXTma->m(EitherStringa,LaTeX)runLaTeXT(LaTeXTc)=runWriterTc>>=(\((a,m),l)->casemofNothing->return(Righta,l)Justerr->return(Lefterr,l))-- | This is the usual way to run the 'LaTeXT' monad-- and obtain a 'LaTeX' value.execLaTeXT::Monadm=>LaTeXTma->mLaTeXexecLaTeXT=liftMsnd.runLaTeXT-- | Version of 'execLaTeXT' with possible warning messages.-- This function applies 'checkAll' to the 'LaTeX' output.execLaTeXTWarn::Monadm=>LaTeXTma->m(LaTeX,[Warning])execLaTeXTWarn=liftM(id&&&checkcheckAll).execLaTeXT-- | This function run a 'LaTeXT' computation,-- lifting the result again in the monad.extractLaTeX::Monadm=>LaTeXTma->LaTeXTm(a,LaTeX)extractLaTeX(LaTeXTc)=LaTeXT$do((a,m),l)<-lift$runWriterTcreturn((a,l),m)extractLaTeX_::Monadm=>LaTeXTma->LaTeXTmLaTeXextractLaTeX_=liftMsnd.extractLaTeX-- | With 'textell' you can append 'LaTeX' values to the-- state of the 'LaTeXT' monad.textell::Monadm=>LaTeX->LaTeXTm()textell=LaTeXT.liftMpairNoth.tell-- | Lift a function over 'LaTeX' values to a function-- acting over the state of a 'LaTeXT' computation.liftFun::Monadm=>(LaTeX->LaTeX)->(LaTeXTma->LaTeXTma)liftFunf(LaTeXTc)=LaTeXT$do(p,l)<-lift$runWriterTctell$flreturnp-- | Lift an operator over 'LaTeX' values to an operator-- acting over the state of two 'LaTeXT' computations.---- /Note: The returned value is the one returned by the/-- /second argument of the lifted operator./liftOp::Monadm=>(LaTeX->LaTeX->LaTeX)->(LaTeXTma->LaTeXTmb->LaTeXTmb)liftOpop(LaTeXTc)(LaTeXTc')=LaTeXT$do(_,l)<-lift$runWriterTc(p,l')<-lift$runWriterTc'tell$l`op`l'returnp-- | Just like 'rendertex', but with 'LaTeXT' output.---- > rendertexM = textell . rendertexrendertexM::(Rendera,Monadm)=>a->LaTeXTm()rendertexM=textell.rendertex-- Error throwingthrowError::Monadm=>String->LaTeXTmathrowError=LaTeXT.return.(error&&&Just)-- | Function 'merror' casts a value contained in a monad @m@ to the-- bottom value of another type. If you try to evaluate this value, you will-- get an error message with the 'String' passed as argument to 'merror'.merror::Monadm=>String->LaTeXTma->LaTeXTmbmerror=flip(>>).throwError-- Overloaded Strings-- | Be careful when using 'fromString' over a 'LaTeXT' value,-- the returned value of the computation is bottom (i.e. 'undefined').instanceMonadm=>IsString(LaTeXTma)wherefromString=merror"LaTeXT: fromString!".textell.fromString-- | 'mappend' @=@ '>>'.instanceMonadm=>Monoid(LaTeXTma)wheremempty=throwError"LaTeXT: mempty!"mappend=(>>)