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