reanimate/reanimate-0.5.0.1-inplace/Reanimate.LaTeX.hs.html
2020-09-09 08:03:02 +00:00

205 lines
18 KiB
HTML

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
span.lineno { color: white; background: #aaaaaa; border-right: solid white 12px }
span.nottickedoff { background: yellow}
span.istickedoff { background: white }
span.tickonlyfalse { margin: -1px; border: 1px solid #f20913; background: #f20913 }
span.tickonlytrue { margin: -1px; border: 1px solid #60de51; background: #60de51 }
span.funcount { font-size: small; color: orange; z-index: 2; position: absolute; right: 20 }
span.decl { font-weight: bold }
span.spaces { background: white }
</style>
</head>
<body>
<pre>
<span class="decl"><span class="nottickedoff">never executed</span> <span class="tickonlytrue">always true</span> <span class="tickonlyfalse">always false</span></span>
</pre>
<pre>
<span class="lineno"> 1 </span>{-# LANGUAGE OverloadedStrings #-}
<span class="lineno"> 2 </span>{-# LANGUAGE ScopedTypeVariables #-}
<span class="lineno"> 3 </span>{-|
<span class="lineno"> 4 </span>Copyright : Written by David Himmelstrup
<span class="lineno"> 5 </span>License : Unlicense
<span class="lineno"> 6 </span>Maintainer : lemmih@gmail.com
<span class="lineno"> 7 </span>Stability : experimental
<span class="lineno"> 8 </span>Portability : POSIX
<span class="lineno"> 9 </span>-}
<span class="lineno"> 10 </span>module Reanimate.LaTeX
<span class="lineno"> 11 </span> ( latex
<span class="lineno"> 12 </span> , latexWithHeaders
<span class="lineno"> 13 </span> , latexChunks
<span class="lineno"> 14 </span> , xelatex
<span class="lineno"> 15 </span> , xelatexWithHeaders
<span class="lineno"> 16 </span> , ctex
<span class="lineno"> 17 </span> , ctexWithHeaders
<span class="lineno"> 18 </span> , latexAlign
<span class="lineno"> 19 </span> )
<span class="lineno"> 20 </span>where
<span class="lineno"> 21 </span>
<span class="lineno"> 22 </span>import qualified Data.ByteString as B
<span class="lineno"> 23 </span>import Data.Text ( Text )
<span class="lineno"> 24 </span>import qualified Data.Text as T
<span class="lineno"> 25 </span>import qualified Data.Text.Encoding as T
<span class="lineno"> 26 </span>import Graphics.SvgTree ( Tree
<span class="lineno"> 27 </span> , parseSvgFile
<span class="lineno"> 28 </span> )
<span class="lineno"> 29 </span>import Reanimate.Cache
<span class="lineno"> 30 </span>import Reanimate.Misc
<span class="lineno"> 31 </span>import Reanimate.Svg
<span class="lineno"> 32 </span>import Reanimate.Parameters
<span class="lineno"> 33 </span>import System.FilePath ( replaceExtension
<span class="lineno"> 34 </span> , takeFileName
<span class="lineno"> 35 </span> , (&lt;/&gt;)
<span class="lineno"> 36 </span> )
<span class="lineno"> 37 </span>import System.IO.Unsafe ( unsafePerformIO )
<span class="lineno"> 38 </span>
<span class="lineno"> 39 </span>-- | Invoke latex and import the result as an SVG object. SVG objects are
<span class="lineno"> 40 </span>-- cached to improve performance.
<span class="lineno"> 41 </span>--
<span class="lineno"> 42 </span>-- Example:
<span class="lineno"> 43 </span>--
<span class="lineno"> 44 </span>-- &gt; latex &quot;$e^{i\\pi}+1=0$&quot;
<span class="lineno"> 45 </span>--
<span class="lineno"> 46 </span>-- &lt;&lt;docs/gifs/doc_latex.gif&gt;&gt;
<span class="lineno"> 47 </span>latex :: T.Text -&gt; Tree
<span class="lineno"> 48 </span><span class="decl"><span class="istickedoff">latex = latexWithHeaders <span class="nottickedoff">[]</span></span></span>
<span class="lineno"> 49 </span>
<span class="lineno"> 50 </span>-- | Invoke latex with extra script headers.
<span class="lineno"> 51 </span>latexWithHeaders :: [T.Text] -&gt; T.Text -&gt; Tree
<span class="lineno"> 52 </span><span class="decl"><span class="istickedoff">latexWithHeaders = someTexWithHeaders <span class="nottickedoff">&quot;latex&quot;</span> <span class="nottickedoff">&quot;dvi&quot;</span> <span class="nottickedoff">[]</span></span></span>
<span class="lineno"> 53 </span>
<span class="lineno"> 54 </span>someTexWithHeaders :: String -&gt; String -&gt; [String] -&gt; [T.Text] -&gt; T.Text -&gt; Tree
<span class="lineno"> 55 </span><span class="decl"><span class="istickedoff">someTexWithHeaders _exec _dvi _args _headers tex | <span class="tickonlytrue">pNoExternals</span> = mkText tex</span>
<span class="lineno"> 56 </span><span class="spaces"></span><span class="istickedoff">someTexWithHeaders exec dvi args headers tex =</span>
<span class="lineno"> 57 </span><span class="spaces"> </span><span class="istickedoff"><span class="nottickedoff">(unsafePerformIO . (cacheMem . cacheDiskSvg) (latexToSVG dvi exec args))</span></span>
<span class="lineno"> 58 </span><span class="spaces"> </span><span class="istickedoff"><span class="nottickedoff">script</span></span>
<span class="lineno"> 59 </span><span class="spaces"> </span><span class="istickedoff">where</span>
<span class="lineno"> 60 </span><span class="spaces"> </span><span class="istickedoff"><span class="nottickedoff">script = mkTexScript exec args headers tex</span></span></span>
<span class="lineno"> 61 </span>
<span class="lineno"> 62 </span>-- | Invoke latex and separate results.
<span class="lineno"> 63 </span>latexChunks :: [T.Text] -&gt; [Tree]
<span class="lineno"> 64 </span><span class="decl"><span class="nottickedoff">latexChunks chunks | pNoExternals = map mkText chunks</span>
<span class="lineno"> 65 </span><span class="spaces"></span><span class="nottickedoff">latexChunks chunks = worker (svgGlyphs $ latex $ T.concat chunks) chunks</span>
<span class="lineno"> 66 </span><span class="spaces"> </span><span class="nottickedoff">where</span>
<span class="lineno"> 67 </span><span class="spaces"> </span><span class="nottickedoff">merge lst = mkGroup [ fmt svg | (fmt, _, svg) &lt;- lst ]</span>
<span class="lineno"> 68 </span><span class="spaces"> </span><span class="nottickedoff">worker [] [] = []</span>
<span class="lineno"> 69 </span><span class="spaces"> </span><span class="nottickedoff">worker _ [] = error &quot;latex chunk mismatch&quot;</span>
<span class="lineno"> 70 </span><span class="spaces"> </span><span class="nottickedoff">worker everything (x : xs) =</span>
<span class="lineno"> 71 </span><span class="spaces"> </span><span class="nottickedoff">let width = length $ svgGlyphs (latex x)</span>
<span class="lineno"> 72 </span><span class="spaces"> </span><span class="nottickedoff">in merge (take width everything) : worker (drop width everything) xs</span></span>
<span class="lineno"> 73 </span>
<span class="lineno"> 74 </span>-- | Invoke xelatex and import the result as an SVG object. SVG objects are
<span class="lineno"> 75 </span>-- cached to improve performance. Xelatex has support for non-western scripts.
<span class="lineno"> 76 </span>xelatex :: Text -&gt; Tree
<span class="lineno"> 77 </span><span class="decl"><span class="nottickedoff">xelatex = xelatexWithHeaders []</span></span>
<span class="lineno"> 78 </span>
<span class="lineno"> 79 </span>-- | Invoke xelatex with extra script headers.
<span class="lineno"> 80 </span>xelatexWithHeaders :: [T.Text] -&gt; T.Text -&gt; Tree
<span class="lineno"> 81 </span><span class="decl"><span class="nottickedoff">xelatexWithHeaders = someTexWithHeaders &quot;xelatex&quot; &quot;xdv&quot; [&quot;-no-pdf&quot;]</span></span>
<span class="lineno"> 82 </span>
<span class="lineno"> 83 </span>-- | Invoke xelatex with &quot;\usepackage[UTF8]{ctex}&quot; and import the result as an
<span class="lineno"> 84 </span>-- SVG object. SVG objects are cached to improve performance. Xelatex has
<span class="lineno"> 85 </span>-- support for non-western scripts.
<span class="lineno"> 86 </span>--
<span class="lineno"> 87 </span>-- Example:
<span class="lineno"> 88 </span>--
<span class="lineno"> 89 </span>-- &gt; ctex &quot;中文&quot;
<span class="lineno"> 90 </span>--
<span class="lineno"> 91 </span>-- &lt;&lt;docs/gifs/doc_ctex.gif&gt;&gt;
<span class="lineno"> 92 </span>ctex :: T.Text -&gt; Tree
<span class="lineno"> 93 </span><span class="decl"><span class="nottickedoff">ctex = ctexWithHeaders []</span></span>
<span class="lineno"> 94 </span>
<span class="lineno"> 95 </span>-- | Invoke xelatex with extra script headers + ctex headers.
<span class="lineno"> 96 </span>ctexWithHeaders :: [T.Text] -&gt; T.Text -&gt; Tree
<span class="lineno"> 97 </span><span class="decl"><span class="nottickedoff">ctexWithHeaders headers = xelatexWithHeaders (&quot;\\usepackage[UTF8]{ctex}&quot; : headers)</span></span>
<span class="lineno"> 98 </span>
<span class="lineno"> 99 </span>-- | Invoke latex and import the result as an SVG object. SVG objects are
<span class="lineno"> 100 </span>-- cached to improve performance. This wraps the TeX code in an 'align*'
<span class="lineno"> 101 </span>-- context.
<span class="lineno"> 102 </span>--
<span class="lineno"> 103 </span>-- Example:
<span class="lineno"> 104 </span>--
<span class="lineno"> 105 </span>-- &gt; latexAlign &quot;R = \\frac{{\\Delta x}}{{kA}}&quot;
<span class="lineno"> 106 </span>--
<span class="lineno"> 107 </span>-- &lt;&lt;docs/gifs/doc_latexAlign.gif&gt;&gt;
<span class="lineno"> 108 </span>latexAlign :: Text -&gt; Tree
<span class="lineno"> 109 </span><span class="decl"><span class="istickedoff">latexAlign tex = latex $ T.unlines [&quot;\\begin{align*}&quot;, tex, &quot;\\end{align*}&quot;]</span></span>
<span class="lineno"> 110 </span>
<span class="lineno"> 111 </span>postprocess :: Tree -&gt; Tree
<span class="lineno"> 112 </span><span class="decl"><span class="nottickedoff">postprocess = simplify</span></span>
<span class="lineno"> 113 </span>
<span class="lineno"> 114 </span>-- executable, arguments, header, tex
<span class="lineno"> 115 </span>latexToSVG :: String -&gt; String -&gt; [String] -&gt; Text -&gt; IO Tree
<span class="lineno"> 116 </span><span class="decl"><span class="nottickedoff">latexToSVG dviExt latexExec latexArgs tex = do</span>
<span class="lineno"> 117 </span><span class="spaces"> </span><span class="nottickedoff">latexBin &lt;- requireExecutable latexExec</span>
<span class="lineno"> 118 </span><span class="spaces"> </span><span class="nottickedoff">dvisvgm &lt;- requireExecutable &quot;dvisvgm&quot;</span>
<span class="lineno"> 119 </span><span class="spaces"> </span><span class="nottickedoff">withTempDir $ \tmp_dir -&gt; withTempFile &quot;tex&quot; $ \tex_file -&gt;</span>
<span class="lineno"> 120 </span><span class="spaces"> </span><span class="nottickedoff">withTempFile &quot;svg&quot; $ \svg_file -&gt; do</span>
<span class="lineno"> 121 </span><span class="spaces"> </span><span class="nottickedoff">let dvi_file =</span>
<span class="lineno"> 122 </span><span class="spaces"> </span><span class="nottickedoff">tmp_dir &lt;/&gt; replaceExtension (takeFileName tex_file) dviExt</span>
<span class="lineno"> 123 </span><span class="spaces"> </span><span class="nottickedoff">B.writeFile tex_file (T.encodeUtf8 tex)</span>
<span class="lineno"> 124 </span><span class="spaces"> </span><span class="nottickedoff">runCmd</span>
<span class="lineno"> 125 </span><span class="spaces"> </span><span class="nottickedoff">latexBin</span>
<span class="lineno"> 126 </span><span class="spaces"> </span><span class="nottickedoff">( latexArgs</span>
<span class="lineno"> 127 </span><span class="spaces"> </span><span class="nottickedoff">++ [ &quot;-interaction=nonstopmode&quot;</span>
<span class="lineno"> 128 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;-halt-on-error&quot;</span>
<span class="lineno"> 129 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;-output-directory=&quot; ++ tmp_dir</span>
<span class="lineno"> 130 </span><span class="spaces"> </span><span class="nottickedoff">, tex_file</span>
<span class="lineno"> 131 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 132 </span><span class="spaces"> </span><span class="nottickedoff">)</span>
<span class="lineno"> 133 </span><span class="spaces"> </span><span class="nottickedoff">runCmd</span>
<span class="lineno"> 134 </span><span class="spaces"> </span><span class="nottickedoff">dvisvgm</span>
<span class="lineno"> 135 </span><span class="spaces"> </span><span class="nottickedoff">[ dvi_file</span>
<span class="lineno"> 136 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;--precision=5&quot;</span>
<span class="lineno"> 137 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;--exact&quot; -- better bboxes.</span>
<span class="lineno"> 138 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;--no-fonts&quot; -- use glyphs instead of fonts.</span>
<span class="lineno"> 139 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;--scale=0.1,-0.1&quot;</span>
<span class="lineno"> 140 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;--verbosity=0&quot;</span>
<span class="lineno"> 141 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;-o&quot;</span>
<span class="lineno"> 142 </span><span class="spaces"> </span><span class="nottickedoff">, svg_file</span>
<span class="lineno"> 143 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 144 </span><span class="spaces"> </span><span class="nottickedoff">svg_data &lt;- B.readFile svg_file</span>
<span class="lineno"> 145 </span><span class="spaces"> </span><span class="nottickedoff">case parseSvgFile svg_file svg_data of</span>
<span class="lineno"> 146 </span><span class="spaces"> </span><span class="nottickedoff">Nothing -&gt; error &quot;Malformed svg&quot;</span>
<span class="lineno"> 147 </span><span class="spaces"> </span><span class="nottickedoff">Just svg -&gt; return $ postprocess $ unbox $ replaceUses svg</span></span>
<span class="lineno"> 148 </span>
<span class="lineno"> 149 </span>mkTexScript :: String -&gt; [String] -&gt; [Text] -&gt; Text -&gt; Text
<span class="lineno"> 150 </span><span class="decl"><span class="nottickedoff">mkTexScript latexExec latexArgs texHeaders tex =</span>
<span class="lineno"> 151 </span><span class="spaces"> </span><span class="nottickedoff">T.unlines</span>
<span class="lineno"> 152 </span><span class="spaces"> </span><span class="nottickedoff">$ [ &quot;% &quot; &lt;&gt; T.pack (unwords (latexExec : latexArgs))</span>
<span class="lineno"> 153 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;\\documentclass[preview]{standalone}&quot;</span>
<span class="lineno"> 154 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;\\usepackage{amsmath}&quot;</span>
<span class="lineno"> 155 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;\\usepackage{gensymb}&quot;</span>
<span class="lineno"> 156 </span><span class="spaces"> </span><span class="nottickedoff">]</span>
<span class="lineno"> 157 </span><span class="spaces"> </span><span class="nottickedoff">++ texHeaders</span>
<span class="lineno"> 158 </span><span class="spaces"> </span><span class="nottickedoff">++ [ &quot;\\usepackage[english]{babel}&quot;</span>
<span class="lineno"> 159 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;\\linespread{1}&quot;</span>
<span class="lineno"> 160 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;\\begin{document}&quot;</span>
<span class="lineno"> 161 </span><span class="spaces"> </span><span class="nottickedoff">, tex</span>
<span class="lineno"> 162 </span><span class="spaces"> </span><span class="nottickedoff">, &quot;\\end{document}&quot;</span>
<span class="lineno"> 163 </span><span class="spaces"> </span><span class="nottickedoff">]</span></span>
<span class="lineno"> 164 </span>
<span class="lineno"> 165 </span>{- Packages used by manim.
<span class="lineno"> 166 </span>
<span class="lineno"> 167 </span>\\\usepackage{amsmath}\n\
<span class="lineno"> 168 </span>\\\usepackage{amssymb}\n\
<span class="lineno"> 169 </span>\\\usepackage{dsfont}\n\
<span class="lineno"> 170 </span>\\\usepackage{setspace}\n\
<span class="lineno"> 171 </span>\\\usepackage{relsize}\n\
<span class="lineno"> 172 </span>\\\usepackage{textcomp}\n\
<span class="lineno"> 173 </span>\\\usepackage{mathrsfs}\n\
<span class="lineno"> 174 </span>\\\usepackage{calligra}\n\
<span class="lineno"> 175 </span>\\\usepackage{wasysym}\n\
<span class="lineno"> 176 </span>\\\usepackage{ragged2e}\n\
<span class="lineno"> 177 </span>\\\usepackage{physics}\n\
<span class="lineno"> 178 </span>\\\usepackage{xcolor}\n\
<span class="lineno"> 179 </span>\\\usepackage{textcomp}\n\
<span class="lineno"> 180 </span>\\\usepackage{xfrac}\n\
<span class="lineno"> 181 </span>\\\usepackage{microtype}\n\
<span class="lineno"> 182 </span>-}
</pre>
</body>
</html>