HaTeX 3.3 → 3.4
raw patch · 12 files changed
+221/−95 lines, 12 filesdep ~transformersPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: transformers
API changes (from Hackage documentation)
- Text.LaTeX.Base.Writer: instance Applicative m => Applicative (LaTeXT m)
- Text.LaTeX.Packages.AMSMath: (=:, /=:) :: LaTeXC l => l -> l -> l
- Text.LaTeX.Packages.Graphicx: dvips, pdftex, dvipdfm :: LaTeXC l => l
+ Text.LaTeX.Base: instance Fractional LaTeX
+ Text.LaTeX.Base: instance Monad m => Eq (LaTeXT m a)
+ Text.LaTeX.Base: instance Monad m => Fractional (LaTeXT m a)
+ Text.LaTeX.Base: instance Monad m => Num (LaTeXT m a)
+ Text.LaTeX.Base: instance Monad m => Show (LaTeXT m a)
+ Text.LaTeX.Base.Class: liftL3 :: LaTeXC l => (LaTeX -> LaTeX -> LaTeX -> LaTeX) -> l -> l -> l -> l
+ Text.LaTeX.Base.Commands: hfill :: LaTeXC l => l
+ Text.LaTeX.Base.Commands: vfill :: LaTeXC l => l
+ Text.LaTeX.Base.Writer: liftIO :: MonadIO m => forall a. IO a -> m a
+ Text.LaTeX.Base.Writer: throwError :: Monad m => String -> LaTeXT m a
+ Text.LaTeX.Packages.AMSMath: (/=:) :: LaTeXC l => l -> l -> l
+ Text.LaTeX.Packages.AMSMath: (=:) :: LaTeXC l => l -> l -> l
+ Text.LaTeX.Packages.Graphicx: dvipdfm :: LaTeXC l => l
+ Text.LaTeX.Packages.Graphicx: dvips :: LaTeXC l => l
+ Text.LaTeX.Packages.Graphicx: pdftex :: LaTeXC l => l
- Text.LaTeX.Base.Commands: cite :: LaTeX -> LaTeX
+ Text.LaTeX.Base.Commands: cite :: LaTeXC l => l -> l
- Text.LaTeX.Base.Writer: liftOp :: Monad m => (LaTeX -> LaTeX -> LaTeX) -> (LaTeXT m a -> LaTeXT m a -> LaTeXT m a)
+ Text.LaTeX.Base.Writer: liftOp :: Monad m => (LaTeX -> LaTeX -> LaTeX) -> (LaTeXT m a -> LaTeXT m b -> LaTeXT m b)
- Text.LaTeX.Base.Writer: rendertexM :: (Render a, Monad m) => a -> LaTeXT_ m
+ Text.LaTeX.Base.Writer: rendertexM :: (Render a, Monad m) => a -> LaTeXT m ()
- Text.LaTeX.Base.Writer: runLaTeXT :: LaTeXT m a -> m (a, LaTeX)
+ Text.LaTeX.Base.Writer: runLaTeXT :: Monad m => LaTeXT m a -> m (Either String a, LaTeX)
Files
- Examples/tree.hs +40/−40
- HaTeX.cabal +4/−5
- ReleaseNotes +13/−0
- Text/LaTeX.hs +11/−9
- Text/LaTeX/Base.hs +37/−5
- Text/LaTeX/Base/Class.hs +27/−2
- Text/LaTeX/Base/Commands.hs +12/−2
- Text/LaTeX/Base/Render.hs +4/−0
- Text/LaTeX/Base/Writer.hs +53/−28
- Text/LaTeX/Packages/AMSFonts.hs +1/−0
- Text/LaTeX/Packages/AMSMath.hs +11/−3
- Text/LaTeX/Packages/Trees/Qtree.hs +8/−1
Examples/tree.hs view
@@ -1,41 +1,41 @@--{-# LANGUAGE OverloadedStrings #-}--import Text.LaTeX.Base-import Text.LaTeX.Packages.Trees.Qtree-import Text.LaTeX.Packages.Inputenc--treeExample1 :: Tree String-treeExample1 = Node (Just "Root") [Leaf "Leaf 1",Leaf "Leaf 2"]--treeExample2 :: Tree Int-treeExample2 = Node (Just 0) [Node Nothing [Leaf 1,Leaf 2] , Leaf 3]--treeExample3 :: Tree LaTeX-treeExample3 = Node (Just $ textbf $ textit "Bold and italic")- [ Leaf $ textbf "Bold"- , Leaf $ textit "Italic"- ]---- Main--main :: IO ()-main = renderFile "tree.tex" example--example :: LaTeX-example = thePreamble <> document theBody--thePreamble :: LaTeX-thePreamble =- documentclass [] article- <> usepackage [] qtree- <> usepackage [utf8] inputenc- <> title "Examples with trees"- <> author "Daniel Díaz"--theBody :: LaTeX-theBody =- maketitle- <> tree fromString treeExample1- <> rendertree treeExample2+ +{-# LANGUAGE OverloadedStrings #-} + +import Text.LaTeX.Base +import Text.LaTeX.Packages.Trees.Qtree +import Text.LaTeX.Packages.Inputenc + +treeExample1 :: Tree String +treeExample1 = Node (Just "Root") [Leaf "Leaf 1",Leaf "Leaf 2"] + +treeExample2 :: Tree Int +treeExample2 = Node (Just 0) [Node Nothing [Leaf 1,Leaf 2] , Leaf 3] + +treeExample3 :: Tree LaTeX +treeExample3 = Node (Just $ textbf $ textit "Bold and italic") + [ Leaf $ textbf "Bold" + , Leaf $ textit "Italic" + ] + +-- Main + +main :: IO () +main = renderFile "tree.tex" example + +example :: LaTeX +example = thePreamble <> document theBody + +thePreamble :: LaTeX +thePreamble = + documentclass [] article + <> usepackage [] qtree + <> usepackage [utf8] inputenc + <> title "Examples with trees" + <> author "Daniel Díaz" + +theBody :: LaTeX +theBody = + maketitle + <> tree fromString treeExample1 + <> rendertree treeExample2 <> tree id treeExample3
HaTeX.cabal view
@@ -1,14 +1,13 @@ Name: HaTeX -Version: 3.3 +Version: 3.4 Author: Daniel Díaz Category: Text Build-type: Simple License: BSD3 License-file: license -Maintainer: Daniel Díaz (danieldiaz <at> dhelta <dot> net) +Maintainer: Daniel Díaz (dhelta `dot` diaz `at` gmail `dot` com) Stability: Experimental -Homepage: http://dhelta.net/hprojects/HaTeX -Bug-reports: danieldiaz <at> dhelta <dot> net +Bug-reports: dhelta `dot` diaz `at` gmail `dot` com Synopsis: The Haskell LaTeX library. Description: As it is said: \"LaTeX is a high-quality typesetting system\". This library provides a bridge between that system and Haskell (i.e. it is a LaTeX DSL). @@ -39,7 +38,7 @@ Library Build-depends: base ==4.* , bytestring - , transformers ==0.3.* + , transformers >= 0.2.2 && < 0.4 , text , parsec >=3.1.2 && <3.2 Exposed-modules:
ReleaseNotes view
@@ -1,6 +1,19 @@ HaTeX Release Notes -- From version 3.0.0 +>>> 3.4 + +- Num instance for LaTeXT. +- New re-exports: liftIO. +- Relaxed transformers package dependency to: >= 0.2.2 && < 0.4 +- Changed infix rule of (=:) and (/=:). +- More documentation notes. +- New functions: hfill, vfill. +- The internal representation of LaTeXT has changed to prevent + a set of errors. +- Changes in Text.LaTeX. +- Several minor fixes. + >>> 3.3 - New functions 'protectString' and 'protectText'.
Text/LaTeX.hs view
@@ -1,13 +1,15 @@ --- | This module is a re-export of the main modules. --- Importing this will you give access to almost all --- functionality of the library. However, it is recommended --- to import the @Base@ module and, then, import only --- packages you actually need. +-- | This module is a re-export of the Base module. +-- You may find it shorter to import. +-- +-- Historically, this module also exported the Packages +-- module. But, since it's more common to import the Base +-- module and, then, only the packages you need (instead +-- of all of them), this module has been upgraded supporting +-- it. module Text.LaTeX - ( module Text.LaTeX.Base - , module Text.LaTeX.Packages + ( -- * Base module + module Text.LaTeX.Base ) where -import Text.LaTeX.Base -import Text.LaTeX.Packages+import Text.LaTeX.Base
Text/LaTeX/Base.hs view
@@ -17,7 +17,9 @@ * The "Text.LaTeX.Base.Commands" module, which exports the LaTeX standard commands and environments. -Here is also defined a 'Num' instance for 'LaTeX'. +* The "Text.LaTeX.Base.Writer" module, to work with the monad interface of the library. + +Here are also defined 'Num' and 'Fractional' instances for both 'LaTeX' and 'LaTeXT'. -} module Text.LaTeX.Base ( -- * @LaTeX@ datatype @@ -39,7 +41,8 @@ #endif ) where -import Text.LaTeX.Base.Syntax (LaTeX (..),(<>),protectString,protectText) +import Text.LaTeX.Base.Syntax (LaTeX (..), TeXArg (..),(<>),protectString,protectText) +import Text.LaTeX.Base.Class import Text.LaTeX.Base.Render import Text.LaTeX.Base.Types import Text.LaTeX.Base.Commands @@ -47,15 +50,44 @@ -- import Data.Monoid --- Num instance for LaTeX +-- Num and Fractional instances for LaTeX and LaTeXT --- | Methods 'abs' and 'signum' are undefined. Don't use them! +-- | Careful! Method 'signum' is undefined. Don't use it! instance Num LaTeX where (+) = TeXOp "+" (-) = TeXOp "-" (*) = (<>) negate = (TeXEmpty -) fromInteger = rendertex + abs x = between x "|" "|" -- Non-defined methods - abs _ = error "Cannot use \"abs\" Num method with a LaTeX value." signum _ = error "Cannot use \"signum\" Num method with a LaTeX value." + +-- | Division uses the LaTeX @frac@ command. +instance Fractional LaTeX where + p / q = TeXComm "frac" [FixArg p, FixArg q] + fromRational = rendertex . (fromRational :: Rational -> Float) + +-- | Warning: this instance only exist for the 'Num' instance. +instance Monad m => Eq (LaTeXT m a) where + _ == _ = error "Cannot use \"(==)\" Eq method with a LaTeXT value." + +-- | Warning: this instance only exist for the 'Num' instance. +instance Monad m => Show (LaTeXT m a) where + show _ = error "Cannot use \"show\" Show method with a LaTeXT value." + +-- | Careful! Method 'signum' is undefined. Don't use it! +instance Monad m => Num (LaTeXT m a) where + (+) = liftOp (+) + (-) = liftOp (-) + (*) = (>>) + negate = (mempty -) + fromInteger = fromLaTeX . fromInteger + abs = liftL abs + -- Non-defined methods + signum _ = error "Cannot use \"signum\" Num method with a LaTeXT value." + +-- | Division uses the LaTeX @frac@ command. +instance Monad m => Fractional (LaTeXT m a) where + (/) = liftOp (/) + fromRational = fromLaTeX . fromRational
Text/LaTeX/Base/Class.hs view
@@ -1,4 +1,7 @@ +-- | Definition of the 'LaTeXC' class, used to combine the classic applicative and +-- the latter monadic interfaces of /HaTeX 3/. The user can define new instances +-- as well, adding flexibility to the way /HaTeX/ is used. module Text.LaTeX.Base.Class ( LaTeXC (..) , Monoid (..) @@ -6,6 +9,7 @@ , fromLaTeX , liftL , liftL2 + , liftL3 , comm0 , commS , braces @@ -16,33 +20,54 @@ import Data.Monoid import Data.String +-- | This is the class of 'LaTeX' code generators. It has 'Monoid' and 'IsString' as +-- superclasses. class (Monoid l,IsString l) => LaTeXC l where + -- | This method must take a function that combines a list of 'LaTeX' values into a new one, + -- and creates a function that combines @l@-typed values. The combining function can be + -- seen as a function with 0 or more 'LaTeX' arguments with a 'LaTeX' value as output. liftListL :: ([LaTeX] -> LaTeX) -> [l] -> l +-- | This instance just sets @liftListL = id@. instance LaTeXC LaTeX where liftListL = id -- COMBINATORS +-- | Map a 'LaTeX' value to its equivalent in any 'LaTeXC' instance. fromLaTeX :: LaTeXC l => LaTeX -> l fromLaTeX l = liftListL (\_ -> l) [] +-- | Lift a inner function of 'LaTeX' values into any 'LaTeXC' instance. liftL :: LaTeXC l => (LaTeX -> LaTeX) -> l -> l liftL f x = liftListL (\[x] -> f x) [x] +-- | Variant of 'liftL' with a two arguments function. liftL2 :: LaTeXC l => (LaTeX -> LaTeX -> LaTeX) -> l -> l -> l liftL2 f x y = liftListL (\[x,y] -> f x y) [x,y] --- | A simple (without arguments) command generator, --- given the name of the command. +-- | Variant of 'liftL' with a three arguments function. +liftL3 :: LaTeXC l => (LaTeX -> LaTeX -> LaTeX -> LaTeX) -> l -> l -> l -> l +liftL3 f x y z = liftListL (\[x,y,z] -> f x y z) [x,y,z] + +-- | A simple (without arguments) and handy command generator +-- using the name of the command. -- -- > comm0 str = fromLaTeX $ TeXComm str [] -- comm0 :: LaTeXC l => String -> l comm0 str = fromLaTeX $ TeXComm str [] +-- | Like 'comm0' but using 'commS'. +-- +-- > commS = fromLaTeX . TeXCommS +-- commS :: LaTeXC l => String -> l commS = fromLaTeX . TeXCommS +-- | A lifted version of the 'TeXBraces' constructor. +-- +-- > braces = liftL TeXBraces +-- braces :: LaTeXC l => l -> l braces = liftL TeXBraces
Text/LaTeX/Base/Commands.hs view
@@ -109,6 +109,8 @@ , hspace , hspace_ , vspace + , hfill + , vfill , stretch , smallskip , bigskip @@ -177,7 +179,7 @@ , makebox , raisebox , rule - -- * Cross references + -- ** Cross references , caption , label , ref @@ -360,7 +362,7 @@ abstract :: LaTeXC l => l -> l abstract = liftL $ TeXEnv "abstract" [] -cite :: LaTeX -> LaTeX +cite :: LaTeXC l => l -> l cite = liftL $ \l -> TeXComm "cite" [FixArg l] -- Document class @@ -665,6 +667,14 @@ vspace :: LaTeXC l => Measure -> l vspace m = fromLaTeX $ TeXComm "vspace" [FixArg $ rendertex m] + +-- | Fill out all available horizontal space. +hfill :: LaTeXC l => l +hfill = comm0 "hfill" + +-- | Fill out all available vertical space. +vfill :: LaTeXC l => l +vfill = comm0 "vfill" protect :: LaTeXC l => l -> l protect l = commS "protect" <> l
Text/LaTeX/Base/Render.hs view
@@ -1,6 +1,10 @@ {-# LANGUAGE OverloadedStrings #-} +-- | The final purpose of this module is to render a Text value +-- from a 'LaTeX' value. The interface is abstracted via a typeclass +-- so you can cast to 'Text' other types as well. Also, some other +-- handy 'Text'-related functions are defined. module Text.LaTeX.Base.Render ( -- * Re-exports Text
Text/LaTeX/Base/Writer.hs view
@@ -42,9 +42,12 @@ , rendertexM , liftFun , liftOp + -- * Errors + , throwError , merror -- * Re-export , lift + , liftIO ) where import Control.Monad.Trans.Writer @@ -64,19 +67,38 @@ import Control.Monad (liftM) newtype LaTeXT m a = - LaTeXT { unwrapLaTeXT :: WriterT LaTeX m a } - deriving (Functor,Applicative,Monad,MonadIO) + LaTeXT { unwrapLaTeXT :: WriterT LaTeX m (a,Maybe String) } +instance Functor m => Functor (LaTeXT m) where + fmap f (LaTeXT c) = LaTeXT $ fmap (first f) c + +type LaTeXT_ m = LaTeXT m () + +pairNoth :: a -> (a,Maybe b) +pairNoth x = (x,Nothing) + instance MonadTrans LaTeXT where - lift = LaTeXT . lift + lift = LaTeXT . liftM pairNoth . lift +instance Monad m => Monad (LaTeXT m) where + return = lift . return + (LaTeXT c) >>= f = LaTeXT $ do + (a,_) <- c + let LaTeXT c' = f a + c' + +instance MonadIO m => MonadIO (LaTeXT m) where + liftIO = lift . liftIO + instance Monad m => LaTeXC (LaTeXT m a) where liftListL f xs = mapM extractLaTeX_ xs >>= merror "liftListL" . textell . f -type LaTeXT_ m = LaTeXT m () - -runLaTeXT :: LaTeXT m a -> m (a,LaTeX) -runLaTeXT = runWriterT . unwrapLaTeXT +runLaTeXT :: Monad m => LaTeXT m a -> m (Either String a,LaTeX) +runLaTeXT (LaTeXT c) = runWriterT c >>= ( + \((a,m),l) -> case m of + Nothing -> return (Right a ,l) + Just err -> return (Left err,l) + ) -- | This is the usual way to run the 'LaTeXT' monad -- and obtain a 'LaTeX' value. @@ -91,7 +113,9 @@ -- | This function run a 'LaTeXT' computation, -- lifting the result again in the monad. extractLaTeX :: Monad m => LaTeXT m a -> LaTeXT m (a,LaTeX) -extractLaTeX = LaTeXT . lift . runLaTeXT +extractLaTeX (LaTeXT c) = LaTeXT $ do + ((a,m),l) <- lift $ runWriterT c + return ((a,l),m) extractLaTeX_ :: Monad m => LaTeXT m a -> LaTeXT m LaTeX extractLaTeX_ = liftM snd . extractLaTeX @@ -99,20 +123,18 @@ -- | With 'textell' you can append 'LaTeX' values to the -- state of the 'LaTeXT' monad. textell :: Monad m => LaTeX -> LaTeXT m () -textell = LaTeXT . tell +textell = LaTeXT . liftM pairNoth . tell -- | Lift a function over 'LaTeX' values to a function -- acting over the state of a 'LaTeXT' computation. liftFun :: Monad m => (LaTeX -> LaTeX) -> (LaTeXT m a -> LaTeXT m a) -liftFun f ml = do - (a,l') <- lift $ do - (a,l) <- runLaTeXT ml - let l' = f l - return (a,l') - textell l' - return a +liftFun f (LaTeXT c) = LaTeXT $ do + (p,l) <- lift $ runWriterT c + tell $ f l + return p + -- | Lift an operator over 'LaTeX' values to an operator -- acting over the state of two 'LaTeXT' computations. @@ -121,33 +143,36 @@ -- /second argument of the lifted operator./ liftOp :: Monad m => (LaTeX -> LaTeX -> LaTeX) - -> (LaTeXT m a -> LaTeXT m a -> LaTeXT m a) -liftOp op ml1 ml2 = do - (a,l') <- lift $ do - (_,l1) <- runLaTeXT ml1 - (a,l2) <- runLaTeXT ml2 - let l' = l1 `op` l2 - return (a,l') - textell l' - return a + -> (LaTeXT m a -> LaTeXT m b -> LaTeXT m b) +liftOp op (LaTeXT c) (LaTeXT c') = LaTeXT $ do + (_,l) <- lift $ runWriterT c + (p,l') <- lift $ runWriterT c' + tell $ l `op` l' + return p -- | Just like 'rendertex', but with 'LaTeXT' output. -- -- > rendertexM = textell . rendertex -rendertexM :: (Render a, Monad m) => a -> LaTeXT_ m +rendertexM :: (Render a, Monad m) => a -> LaTeXT m () rendertexM = textell . rendertex -- Error throwing +throwError :: Monad m => String -> LaTeXT m a +throwError = 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 :: Monad m => String -> LaTeXT m a -> LaTeXT m b -merror = flip (>>) . return . error +merror = flip (>>) . throwError -- Overloaded Strings -- | Be careful when using 'fromString' over a 'LaTeXT' value, -- the returned value of the computation is bottom (i.e. 'undefined'). instance Monad m => IsString (LaTeXT m a) where - fromString = (>> return undefined) . textell . fromString + fromString = merror "LaTeXT: fromString!" . textell . fromString -- | 'mappend' @=@ '>>'. instance Monad m => Monoid (LaTeXT m a) where
Text/LaTeX/Packages/AMSFonts.hs view
@@ -1,4 +1,5 @@ +-- | Module for the package @amsfonts@. module Text.LaTeX.Packages.AMSFonts ( -- * AMSFonts package amsfonts
Text/LaTeX/Packages/AMSMath.hs view
@@ -129,10 +129,18 @@ \l1 l2 -> (l1 <> commS "not") `op` l2 -infix 4 =: , /=: +infixr 4 =: , /=: -(=:),(/=:) :: LaTeXC l => l -> l -> l +-- | Equal. +-- +-- > infixr 4 =: +(=:) :: LaTeXC l => l -> l -> l (=:) = liftL2 $ TeXOp "=" + +-- | Not equal. +-- +-- > infixr 4 /=: +(/=:) :: LaTeXC l => l -> l -> l (/=:) = notop (=:) -- | Greater. @@ -184,7 +192,7 @@ epsilon = comm0 "epsilon" varepsilon :: LaTeXC l => l -varepsilon = comm0 "epsilon" +varepsilon = comm0 "varepsilon" zeta :: LaTeXC l => l zeta = comm0 "zeta"
Text/LaTeX/Packages/Trees/Qtree.hs view
@@ -1,6 +1,9 @@ {-# LANGUAGE OverloadedStrings #-} +-- | Tree interface using the @qtree@ package. +-- An example is of usage is provided in the /examples/ directory of +-- the source distribution. module Text.LaTeX.Packages.Trees.Qtree ( -- * Tree re-export module Text.LaTeX.Packages.Trees @@ -18,6 +21,7 @@ import Data.Monoid import Data.List (intersperse) +-- | The 'qtree' package. qtree :: PackageName qtree = "qtree" @@ -31,8 +35,11 @@ , " ]" ] +-- | Given a function to @LaTeX@ values, you can create a @LaTeX@ tree from a +-- Haskell tree. The function specifies how to render the node values. tree :: LaTeXC l => (a -> l) -> Tree a -> l tree f t = commS "Tree" <> " " <> tree_ f t +-- | This function works as 'tree', but use 'render' as rendering function. rendertree :: (Render a, LaTeXC l) => Tree a -> l -rendertree = tree (raw . render)+rendertree = tree (raw . protectText . render)