{-# LANGUAGE CPP #-} -- | 'LaTeX' values pretty printer. -- -- Still experimental. Give it a try and send us your feedback! :) module Text.LaTeX.Base.Pretty ( -- * @LaTeX@ pretty printer prettyLaTeX -- * Configurable printer , docLaTeX ) where import Text.LaTeX.Base.Syntax import Text.LaTeX.Base.Render import Data.Text.Prettyprint.Doc ( Doc, pretty , backslash, line, softline, hardline , braces, brackets , indent, align, vsep , list, encloseSep , LayoutOptions (..) , PageWidth (..) , layoutSmart ) import Data.Text.Prettyprint.Doc.Render.String (renderString) import Data.Text (unpack,lines) #if !MIN_VERSION_base(4,8,0) import Data.Monoid (mconcat,mempty) #endif text :: Text -> Doc ann text = pretty -- | This function transforms a value of type 'LaTeX' to a 'Doc'. -- You can then choose how to print this 'Doc' value using -- the function from the "Text.PrettyPrint.Free" module. docLaTeX :: LaTeX -> Doc () docLaTeX (TeXRaw t) = pretty $ unpack t docLaTeX (TeXComm n as) = backslash <> pretty n <> align (mconcat (fmap docTeXArg as)) <> softline docLaTeX (TeXCommS n) = backslash <> pretty n <> softline docLaTeX (TeXEnv n as b) = let a = FixArg $ fromString n in mconcat [ line , docLaTeX $ TeXComm "begin" $ a : as , indent 4 $ docLaTeX b , line , docLaTeX $ TeXComm "end" [a] ] docLaTeX (TeXMath t b) = let (l,r) = case t of Parentheses -> ("\\(","\\)") Square -> ("\\[","\\]") Dollar -> ("$","$") DoubleDollar -> ("$$","$$") in text l <> docLaTeX b <> text r docLaTeX (TeXLineBreak m b) = text "\\\\" <> maybe mempty (brackets . pretty . unpack . render) m <> ( if b then text "*" else mempty ) docLaTeX (TeXBraces b) = braces $ docLaTeX b docLaTeX (TeXComment t) = let ls = Data.Text.lines t in if null ls then pretty '%' <> hardline else (align $ vsep $ fmap (pretty . ("% "++) . unpack) ls) <> hardline docLaTeX (TeXSeq l1 l2) = docLaTeX l1 <> docLaTeX l2 docLaTeX TeXEmpty = mempty docTeXArg :: TeXArg -> Doc () docTeXArg (FixArg l) = braces $ docLaTeX l docTeXArg (OptArg l) = brackets $ docLaTeX l docTeXArg (MOptArg ls) = if null ls then mempty else list $ fmap docLaTeX ls docTeXArg (SymArg l) = docTeXArg $ MSymArg [l] docTeXArg (MSymArg ls) = encloseSep (pretty '<') (pretty '>') (pretty ',') $ fmap docLaTeX ls docTeXArg (ParArg l) = docTeXArg $ MParArg [l] docTeXArg (MParArg ls) = encloseSep (pretty '(') (pretty ')') (pretty ',') $ fmap docLaTeX ls -- | Pretty print a 'LaTeX' value. It produces a more human-friendly output than 'render'. -- -- This function should be used only for debugging purposes since it may change -- the semantics of the input in order to create a prettier output. -- In other words, running a LaTeX compiler in the output file of @renderFile fp l@ may -- produce a different document than running it in the output of @writeFile fp (prettyLaTeX l)@. -- You should use 'renderFile' unless you really need to read the LaTeX file. -- prettyLaTeX :: LaTeX -> String prettyLaTeX = renderString . layoutSmart layout . docLaTeX layout :: LayoutOptions layout = LayoutOptions $ AvailablePerLine 60 1