{-# LANGUAGE OverloadedStrings #-}
module Text.LaTeX.Base.Render
(
Text
, module Data.String
, Render (..)
, renderAppend
, renderChars
, renderCommas
, renderFile
, rendertex
, readFileTex
, showFloat
) where
import Text.LaTeX.Base.Syntax
import Text.LaTeX.Base.Class
import Data.String
import Data.List (intersperse)
import qualified Data.ByteString as B
import Data.Word (Word8)
import Numeric (showFFloat)
import Data.Text (Text,lines,unlines)
import Data.Text.Encoding
import Data.Text.Lazy (toStrict)
import Data.Text.Lazy.Builder (Builder)
import qualified Data.Text.Lazy.Builder as Builder
import qualified Data.Text.Lazy.Builder.Int as Builder
import qualified Data.Text.Lazy.Builder.RealFloat as Builder
class Show a => Render a where
render :: a -> Text
renderBuilder :: a -> Builder
render = forall a. IsString a => String -> a
fromString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
renderBuilder = Text -> Builder
Builder.fromText forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Render a => a -> Text
render
renderDefault :: Render a => a -> Text
renderDefault :: forall a. Render a => a -> Text
renderDefault = Text -> Text
toStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
Builder.toLazyText forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Render a => a -> Builder
renderBuilder
instance Render Text where
render :: Text -> Text
render = Text -> Text
protectText
renderAppend :: Render a => [a] -> Text
renderAppend :: forall a. Render a => [a] -> Text
renderAppend = forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Render a => a -> Text
render
renderAppendBuilder :: Render a => [a] -> Builder
renderAppendBuilder :: forall a. Render a => [a] -> Builder
renderAppendBuilder = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap forall a. Render a => a -> Builder
renderBuilder
renderChars :: Render a => Char -> [a] -> Text
renderChars :: forall a. Render a => Char -> [a] -> Text
renderChars Char
c = forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse (forall a. IsString a => String -> a
fromString [Char
c]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Render a => a -> Text
render
renderCharsBuilder :: Render a => Char -> [a] -> Builder
renderCharsBuilder :: forall a. Render a => Char -> [a] -> Builder
renderCharsBuilder Char
c = forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse (Char -> Builder
Builder.singleton Char
c) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Render a => a -> Builder
renderBuilder
renderCommas :: Render a => [a] -> Text
renderCommas :: forall a. Render a => [a] -> Text
renderCommas = forall a. Render a => Char -> [a] -> Text
renderChars Char
','
renderCommasBuilder :: Render a => [a] -> Builder
renderCommasBuilder :: forall a. Render a => [a] -> Builder
renderCommasBuilder = forall a. Render a => Char -> [a] -> Builder
renderCharsBuilder Char
','
renderFile :: Render a => FilePath -> a -> IO ()
renderFile :: forall a. Render a => String -> a -> IO ()
renderFile String
f = String -> ByteString -> IO ()
B.writeFile String
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Render a => a -> Text
render
readFileTex :: FilePath -> IO Text
readFileTex :: String -> IO Text
readFileTex = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
decodeUtf8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ByteString
B.readFile
rendertex :: (Render a,LaTeXC l) => a -> l
rendertex :: forall a l. (Render a, LaTeXC l) => a -> l
rendertex = forall l. LaTeXC l => LaTeX -> l
fromLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> LaTeX
TeXRaw forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Render a => a -> Text
render
instance Render Measure where
render :: Measure -> Text
render (Pt Double
x) = forall a. Render a => a -> Text
render Double
x forall a. Semigroup a => a -> a -> a
<> Text
"pt"
render (Mm Double
x) = forall a. Render a => a -> Text
render Double
x forall a. Semigroup a => a -> a -> a
<> Text
"mm"
render (Cm Double
x) = forall a. Render a => a -> Text
render Double
x forall a. Semigroup a => a -> a -> a
<> Text
"cm"
render (In Double
x) = forall a. Render a => a -> Text
render Double
x forall a. Semigroup a => a -> a -> a
<> Text
"in"
render (Ex Double
x) = forall a. Render a => a -> Text
render Double
x forall a. Semigroup a => a -> a -> a
<> Text
"ex"
render (Em Double
x) = forall a. Render a => a -> Text
render Double
x forall a. Semigroup a => a -> a -> a
<> Text
"em"
render (CustomMeasure LaTeX
x) = forall a. Render a => a -> Text
render LaTeX
x
instance Render LaTeX where
renderBuilder :: LaTeX -> Builder
renderBuilder (TeXRaw Text
t) = Text -> Builder
Builder.fromText Text
t
renderBuilder (TeXComm String
name []) = Builder
"\\" forall a. Semigroup a => a -> a -> a
<> forall a. IsString a => String -> a
fromString String
name forall a. Semigroup a => a -> a -> a
<> Builder
"{}"
renderBuilder (TeXComm String
name [TeXArg]
args) =
Builder
"\\"
forall a. Semigroup a => a -> a -> a
<> forall a. IsString a => String -> a
fromString String
name
forall a. Semigroup a => a -> a -> a
<> forall a. Render a => [a] -> Builder
renderAppendBuilder [TeXArg]
args
renderBuilder (TeXCommS String
name) = Builder
"\\" forall a. Semigroup a => a -> a -> a
<> forall a. IsString a => String -> a
fromString String
name
renderBuilder (TeXEnv String
name [TeXArg]
args LaTeX
c) =
Builder
"\\begin{"
forall a. Semigroup a => a -> a -> a
<> forall a. IsString a => String -> a
fromString String
name
forall a. Semigroup a => a -> a -> a
<> Builder
"}"
forall a. Semigroup a => a -> a -> a
<> forall a. Render a => [a] -> Builder
renderAppendBuilder [TeXArg]
args
forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
c
forall a. Semigroup a => a -> a -> a
<> Builder
"\\end{"
forall a. Semigroup a => a -> a -> a
<> forall a. IsString a => String -> a
fromString String
name
forall a. Semigroup a => a -> a -> a
<> Builder
"}"
renderBuilder (TeXMath MathType
Dollar LaTeX
l) = Builder
"$" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
l forall a. Semigroup a => a -> a -> a
<> Builder
"$"
renderBuilder (TeXMath MathType
DoubleDollar LaTeX
l) = Builder
"$$" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
l forall a. Semigroup a => a -> a -> a
<> Builder
"$$"
renderBuilder (TeXMath MathType
Square LaTeX
l) = Builder
"\\[" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
l forall a. Semigroup a => a -> a -> a
<> Builder
"\\]"
renderBuilder (TeXMath MathType
Parentheses LaTeX
l) = Builder
"\\(" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
l forall a. Semigroup a => a -> a -> a
<> Builder
"\\)"
renderBuilder (TeXLineBreak Maybe Measure
m Bool
b) = Builder
"\\\\" forall a. Semigroup a => a -> a -> a
<> forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty (\Measure
x -> Builder
"[" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder Measure
x forall a. Semigroup a => a -> a -> a
<> Builder
"]") Maybe Measure
m forall a. Semigroup a => a -> a -> a
<> ( if Bool
b then Builder
"*" else forall a. Monoid a => a
mempty )
renderBuilder (TeXBraces LaTeX
l) = Builder
"{" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
l forall a. Semigroup a => a -> a -> a
<> Builder
"}"
renderBuilder (TeXComment Text
c) =
let xs :: [Text]
xs = Text -> [Text]
Data.Text.lines Text
c
in if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
xs then Builder
"%\n"
else Text -> Builder
Builder.fromText forall a b. (a -> b) -> a -> b
$ [Text] -> Text
Data.Text.unlines forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text
"%" forall a. Semigroup a => a -> a -> a
<>) [Text]
xs
renderBuilder (TeXSeq LaTeX
l1 LaTeX
l2) = forall a. Render a => a -> Builder
renderBuilder LaTeX
l1 forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
l2
renderBuilder LaTeX
TeXEmpty = forall a. Monoid a => a
mempty
render :: LaTeX -> Text
render = forall a. Render a => a -> Text
renderDefault
instance Render TeXArg where
renderBuilder :: TeXArg -> Builder
renderBuilder (FixArg LaTeX
l) = Builder
"{" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
l forall a. Semigroup a => a -> a -> a
<> Builder
"}"
renderBuilder (OptArg LaTeX
l) = Builder
"[" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
l forall a. Semigroup a => a -> a -> a
<> Builder
"]"
renderBuilder (MOptArg []) = forall a. Monoid a => a
mempty
renderBuilder (MOptArg [LaTeX]
ls) = Builder
"[" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => [a] -> Builder
renderCommasBuilder [LaTeX]
ls forall a. Semigroup a => a -> a -> a
<> Builder
"]"
renderBuilder (SymArg LaTeX
l) = Builder
"<" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
l forall a. Semigroup a => a -> a -> a
<> Builder
">"
renderBuilder (MSymArg []) = forall a. Monoid a => a
mempty
renderBuilder (MSymArg [LaTeX]
ls) = Builder
"<" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => [a] -> Builder
renderCommasBuilder [LaTeX]
ls forall a. Semigroup a => a -> a -> a
<> Builder
">"
renderBuilder (ParArg LaTeX
l) = Builder
"(" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => a -> Builder
renderBuilder LaTeX
l forall a. Semigroup a => a -> a -> a
<> Builder
")"
renderBuilder (MParArg []) = forall a. Monoid a => a
mempty
renderBuilder (MParArg [LaTeX]
ls) = Builder
"(" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => [a] -> Builder
renderCommasBuilder [LaTeX]
ls forall a. Semigroup a => a -> a -> a
<> Builder
")"
render :: TeXArg -> Text
render = forall a. Render a => a -> Text
renderDefault
showFloat :: RealFloat a => a -> String
showFloat :: forall a. RealFloat a => a -> String
showFloat a
x = forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat (forall a. a -> Maybe a
Just Int
5) a
x []
instance Render Int where
renderBuilder :: Int -> Builder
renderBuilder = forall a. Integral a => a -> Builder
Builder.decimal
render :: Int -> Text
render = forall a. Render a => a -> Text
renderDefault
instance Render Integer where
renderBuilder :: Integer -> Builder
renderBuilder = forall a. Integral a => a -> Builder
Builder.decimal
render :: Integer -> Text
render = forall a. Render a => a -> Text
renderDefault
instance Render Float where
renderBuilder :: Float -> Builder
renderBuilder = forall a. RealFloat a => FPFormat -> Maybe Int -> a -> Builder
Builder.formatRealFloat FPFormat
Builder.Fixed (forall a. a -> Maybe a
Just Int
5)
render :: Float -> Text
render = forall a. Render a => a -> Text
renderDefault
instance Render Double where
renderBuilder :: Double -> Builder
renderBuilder = forall a. RealFloat a => FPFormat -> Maybe Int -> a -> Builder
Builder.formatRealFloat FPFormat
Builder.Fixed (forall a. a -> Maybe a
Just Int
5)
render :: Double -> Text
render = forall a. Render a => a -> Text
renderDefault
instance Render Word8 where
renderBuilder :: Word8 -> Builder
renderBuilder = forall a. Integral a => a -> Builder
Builder.decimal
render :: Word8 -> Text
render = forall a. Render a => a -> Text
renderDefault
instance Render Bool where
render :: Bool -> Text
render Bool
True = Text
"true"
render Bool
_ = Text
"false"
instance Render a => Render [a] where
renderBuilder :: [a] -> Builder
renderBuilder [a]
xs = Builder
"[" forall a. Semigroup a => a -> a -> a
<> forall a. Render a => [a] -> Builder
renderCommasBuilder [a]
xs forall a. Semigroup a => a -> a -> a
<> Builder
"]"
render :: [a] -> Text
render = forall a. Render a => a -> Text
renderDefault