TeX-my-math-0.203.0.0: test/PdfSnippets/MkSnippets.hs
-- |
-- Module : Main
-- Copyright : (c) Justus Sagemรผller 2017
-- License : GPL v3
--
-- Maintainer : (@) jsag $ hvl.no
-- Stability : experimental
-- Portability : portable
--
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE CPP #-}
module Main where
import LaTeXComparer
import Math.LaTeX.Prelude
import Math.LaTeX.StringLiterals
import Text.LaTeX (LaTeX, raw, Text)
import Text.LaTeX.Base.Math
import Text.LaTeX.Packages.AMSFonts
import qualified Text.LaTeX as LaTeX
import qualified Data.Text as Txt
import qualified Data.Text.IO as Txt
import Data.Char
import CAS.Dumb
import CAS.Dumb.Symbols.ASCII hiding (d)
import System.FilePath
import System.Directory
import System.Process
import Data.Monoid
import Data.Function ((&))
import Control.Monad
main :: IO ()
main = do
examples_U <- evalTests tests_U
Txt.writeFile "EXAMPLES.md"
$ "_This file was generated automatically from [MkSnippets.hs](test/PdfSnippets/MkSnippets.hs). Run `cabal test` to refresh it._\n"
<> examples_U
examples_A <- evalTests tests_A
Txt.writeFile "EXAMPLES_ASCII.md"
$ "_This file was generated automatically from [MkSnippets.hs](test/PdfSnippets/MkSnippets.hs). Run `cabal test` to refresh it._\n"
<> examples_A
tests_A :: TestTree ASCII
tests_A = testGroup "Tests"
[ testGroup "Simple expressions"
[ [mkLaTeXSnip| a + b * c |] "a+b{\\cdot}c"
#if __GLASGOW_HASKELL__ > 801
, [mkLaTeXSnip| A * B + C |] "A{\\cdot}B+C"
#endif
, [mkLaTeXSnip| (a + b) * c |] "\\left(a+b\\right){\\cdot}c"
, [mkLaTeXSnip|(a + b) / (x - y) |] "\\frac{a+b}{x-y}"
, [mkLaTeXSnip| (a + b)**(x - y) |] "\\left(a+b\\right)^{x-y}"
, [mkLaTeXSnip| (p/q)**gamma |] "\\left(\\frac{p}{q}\\right)^{\\gamma{}}"
, [mkLaTeXSnip| abs(p/q)**xi |] "\\left|\\frac{p}{q}\\right|^{\\xi{}}"
, [mkLaTeXSnip| a**b**c |] "a^{b^{c}}"
, [mkLaTeXSnip| (a**b)**c |] "\\left(a^{b}\\right)^{c}"
, [mkLaTeXSnip| sin (sin x) |] "\\sin{\\left(\\sin{x}\\right)}"
, [mkLaTeXSnip| matrix[[ 0,1]
,[-1,0]] |] "\\begin{pmatrix}0&1\\\\ -1&0\\end{pmatrix}"
]
, testGroup "Operators"
[ testGroup "Arithmetic"
[ [mkLaTeXSnip| a + b |] "a+b"
, [mkLaTeXSnip| a - b |] "a-b"
, [mkLaTeXSnip| a * b |] "a{\\cdot}b"
, [mkLaTeXSnip| a `times` b |] "a\\times{}b"
, [mkLaTeXSnip| a +- b |] "a\\pm{}b"
, [mkLaTeXSnip| a -+ b |] "a\\mp{}b"
, [mkLaTeXSnip| a `oplus` b |] "a\\oplus{}b"
, [mkLaTeXSnip| a `otimes` b |] "a\\otimes{}b"
]
, testGroup "Sub/superscripts"
[ [mkLaTeXSnip| a!:b |] "{a}_{b}"
, [mkLaTeXSnip| a!^(b,c) |] "{a}_{b}^{c}"
, [mkLaTeXSnip| psi!:"Foo" |] "{\\psi{}}_{\\mathrm{Foo}}"
, [mkLaTeXSnip| psi!:(F<>o<>o) |] "{\\psi{}}_{Foo}"
]
, testGroup "Logical"
[ [mkLaTeXSnip| p `vee` q |] "p\\vee{}q"
, [mkLaTeXSnip| p `wedge` q |] "p\\wedge{}q"
, [mkLaTeXSnip| cases[(1, "Today"), (2, "Else")] |]
"\\begin{cases}1&\\text{Today}\\\\2&\\text{Else}\\end{cases}"
]
, testGroup "Relations"
[ [mkLaTeXSnip| a =: b |] "a=b"
, [mkLaTeXSnip| a >=: c |] "a\\geq{}c"
, [mkLaTeXSnip| a <: rho |] "a<\\rho{}"
, [mkLaTeXSnip| x =: y =: z |] "x=y=z"
, [mkLaTeXSnip| s `subset` t `subseteq` u |] "s\\subset{}t\\subseteq{}u"
, [mkLaTeXSnip| h `approx` i `sim` j `simeq` k `cong` l |] "h\\approx{}i\\sim{}j\\simeq{}k\\cong{}l"
, [mkLaTeXSnip| p `in_` mathbb Q `subset` mathbb R |]
"p\\in{}\\mathbb{Q}\\subset{}\\mathbb{R}"
, [mkLaTeXSnip| mathbf u `perp` (vec%$>v) `parallel` (underline%$>w) |]
"\\mathbf{u}\\perp{}\\vec{v}\\parallel{}\\underline{w}"
]
]
]
tests_U :: TestTree Unicode_MathLatin_RomanGreek__BopomofoGaps
tests_U = testGroup "Tests"
[ testGroup "Simple expressions"
[ [mkLaTeXSnip| ๐ + ๐ * ๐ |] "a+b{\\cdot}c"
#if __GLASGOW_HASKELL__ > 801
, [mkLaTeXSnip| ๐ด * ๐ต + ๐ถ |] "A{\\cdot}B+C"
#endif
, [mkLaTeXSnip| (๐ + ๐) * ๐ |] "\\left(a+b\\right){\\cdot}c"
, [mkLaTeXSnip|(๐ + ๐) / (๐ฅ - ๐ฆ) |] "\\frac{a+b}{x-y}"
, [mkLaTeXSnip| (๐ + ๐)**(๐ฅ - ๐ฆ) |] "\\left(a+b\\right)^{x-y}"
, [mkLaTeXSnip| (๐/๐)**ฮณ |] "\\left(\\frac{p}{q}\\right)^{\\gamma{}}"
, [mkLaTeXSnip| abs(๐/๐)**ฮพ |] "\\left|\\frac{p}{q}\\right|^{\\xi{}}"
, [mkLaTeXSnip| ๐**๐**๐ |] "a^{b^{c}}"
, [mkLaTeXSnip| (๐**๐)**๐ |] "\\left(a^{b}\\right)^{c}"
, [mkLaTeXSnip| sin (sin ๐ฅ) |] "\\sin{\\left(\\sin{x}\\right)}"
, [mkLaTeXSnip| (๐โฉต0,3)โ ๐ |] "\\sum_{i=0}^{3} i"
, [mkLaTeXSnip| matrix[[ 0,1]
,[-1,0]] |] "\\begin{pmatrix}0&1\\\\ -1&0\\end{pmatrix}"
]
, testGroup "Number literals"
[ [mkLaTeXSnip| 25697325 |] "25697325"
, [mkLaTeXSnip| 4.718 |] "4.718"
, [mkLaTeXSnip| 1e-3 |] "1{\\cdot}10^{ -3}"
, [mkLaTeXSnip| 257.35e9 |] "2.5735{\\cdot}10^{11}"
, [mkLaTeXSnip| -5.1e-8 |] " -5.1{\\cdot}10^{ -8}"
, [mkLaTeXSnip| 7/13 |] "\\frac{7}{13}"
, [mkLaTeXSnip| -(1/2) |] " -\\frac{1}{2}"
]
, testGroup "Operators"
[ testGroup "Arithmetic"
[ [mkLaTeXSnip| ๐ + ๐ |] "a+b"
, [mkLaTeXSnip| ๐ - ๐ |] "a-b"
, [mkLaTeXSnip| ๐ * ๐ |] "a{\\cdot}b"
, [mkLaTeXSnip| ๐<โช>๐ |] "\\left\\langle{a,b}\\right\\rangle"
, [mkLaTeXSnip| ๐ ร ๐ |] "a\\times{}b"
, [mkLaTeXSnip| ๐ ยฑ ๐ |] "a\\pm{}b"
, [mkLaTeXSnip| ๐ โ ๐ |] "a\\mp{}b"
, [mkLaTeXSnip| ๐ โ ๐ |] "a\\oplus{}b"
, [mkLaTeXSnip| ๐ โ ๐ |] "a\\otimes{}b"
]
, testGroup "Sub/superscripts"
[ [mkLaTeXSnip| ๐โ๐ |] "a_{b}"
, [mkLaTeXSnip| ๐โโ(๐,๐) |] "a_{b}^{c}"
, [mkLaTeXSnip| ฯโ"Foo" |] "\\psi{}_{\\mathrm{Foo}}"
, [mkLaTeXSnip| ฯโ๐นโธ๐โธ๐ |] "\\psi{}_{Foo}"
, [mkLaTeXSnip| ๐โ(3โฝ"")โพ๐ฅ |] "f^{\\left(3\\right)}\\left(x\\right)"
]
, testGroup "Function application and definition"
[ [mkLaTeXSnip| ๐โพ๐ฅ |] "f\\left(x\\right)"
, [mkLaTeXSnip| ๐โพ(๐โพ๐ฅ) |] "f\\left(g\\left(x\\right)\\right)"
#if __GLASGOW_HASKELL__ > 801
, [mkLaTeXSnip| ๐โพ(๐ฅโช๐ฆ) |] "f\\left(x,y\\right)"
#endif
, [mkLaTeXSnip| ๐โพฯโพ๐ฅ |]
"\\mathcal{F}\\left(\\varphi{}\\right)\\left(x\\right)"
, [mkLaTeXSnip| (๐โ๐)โฝ๐ฅ |] "\\left(f\\circ{}g\\right)x"
, [mkLaTeXSnip| (๐โ๐)โฝ(๐ฅ*๐ฆ) |]
"\\left(f\\circ{}g\\right)\\left(x{\\cdot}y\\right)"
, [mkLaTeXSnip| ๐โ๐โพ๐ฅ |] "f\\circ{}g\\left(x\\right)"
, [mkLaTeXSnip| ๐ รท (โค-โโ) |] "f:\\mathbb{Z}\\to{}\\mathbb{R}"
, [mkLaTeXSnip| ๐โพ๐ฅ รท= ๐ฅ+ฯ |] "f\\left(x\\right){:=}x+\\pi{}"
]
, testGroup "Logical"
[ [mkLaTeXSnip| ๐ โจ ๐ |] "p\\vee{}q"
, [mkLaTeXSnip| ๐ โง ๐ |] "p\\wedge{}q"
, [mkLaTeXSnip| ๐==>๐ |] "p\\Longrightarrow{}q"
, [mkLaTeXSnip| ๐<==๐ |] "p\\Longleftarrow{}q"
, [mkLaTeXSnip| ๐<=>๐ |] "p\\Longleftrightarrow{}q"
, [mkLaTeXSnip| ๐==>๐==>๐ |] "p\\Longrightarrow{}q\\Longrightarrow{}r"
, [mkLaTeXSnip| cases[(1, "Today"), (2, "Else")] |]
"\\begin{cases}1&\\text{Today}\\\\2&\\text{Else}\\end{cases}"
]
, testGroup "Relations"
[ [mkLaTeXSnip| ๐ โฉต ๐ |] "a=b"
, [mkLaTeXSnip| ๐ โฅ ๐ |] "a\\geq{}c"
, [mkLaTeXSnip| ๐ โชก ฯ |] "a<\\rho{}"
, [mkLaTeXSnip| ๐ฅ โฉต ๐ฆ โฉต ๐ง |] "x=y=z"
, [mkLaTeXSnip| ๐ โ ๐ก โ ๐ข |] "s\\subset{}t\\subseteq{}u"
, [mkLaTeXSnip| โ โ ๐ โผ ๐ โ ๐ โ
๐ |] "h\\approx{}g\\sim{}f\\simeq{}e\\cong{}d"
#if __GLASGOW_HASKELL__ > 801
, [mkLaTeXSnip| ๐ โ โ โ โ |] "p\\in{}\\mathbb{Q}\\subset{}\\mathbb{R}"
#endif
, [mkLaTeXSnip| ๐ฎ โ (vec%$>๐ฃ) โฅ (underline%$>๐ค) |]
"\\mathbf{u}\\perp{}\\vec{v}\\parallel{}\\underline{w}"
]
]
, testGroup "Calculus"
[ testGroup "Integration"
[ [mkLaTeXSnip| (-1,1)โซd ๐ฅ (๐ฅ**2) |] "\\int\\limits_{ -1}^{1}\\mathrm{d}x\\ {}x^{2}"
, [mkLaTeXSnip| ฯโโซd ๐ฅ (exp $ -(๐ฅ**2)) |]
"\\int_{\\omega{}}\\!\\!\\!\\mathrm{d}x\\ {}\\exp{\\left( -x^{2}\\right)}"
, [mkLaTeXSnip| (0,1)โซd ๐ฅ ((0,1)โซd ๐ฆ (๐ฅ*๐ฆ)) |]
"\\int\\limits_{0}^{1}\\mathrm{d}x\\ {}\\int\\limits_{0}^{1}\\mathrm{d}y\\ {}\\left(x{\\cdot}y\\right)"
]
]
, testGroup "Algebraic manipulation"
[ [mkLaTeXSnip| ๐ + ๐ + ๐ &~~! [๐ โฉต ๐ฆ] |]
"a+b+c=a+y+c"
, [mkLaTeXSnip| ๐ + ๐ + ๐ &~~! [๐+๐ โฉต ๐+๐, ๐+๐ โฉต ฮพ] |]
"a+b+c=\\xi{}+b"
, [mkLaTeXSnip| ๐ - ๐ &~~! [๐ โฉต ๐ฆ] &~~! [๐ โฉต ๐ง] |]
"a-b=a-y=z-y"
, [mkLaTeXSnip| ๐ฅ + ๐ฆ
& continueExpr (โฉต) (&~: ๐ฆ :=: ๐ฅ*(1+๐ฅ))
& continueExpr (โฉต) (&~: ๐ฅ :=: 2โ๐) |]
"x+y=x+x{\\cdot}\\left(1+x\\right)=2^{p}+2^{p}{\\cdot}\\left(1+2^{p}\\right)"
]
, testGroup "Juxtaposition"
[ [mkLaTeXSnip| ๐ + ๐โธ๐โธ๐ |]
"m+pqr"
, [mkLaTeXSnip| ๐ + ๐โธ(2+๐)โธ๐ |]
"m+p\\left(2+q\\right)r"
, [mkLaTeXSnip| ๐ + (๐โฃ๐โฃ๐) |]
"m+\\left(p\\ {}q\\ {}r\\right)"
, [mkLaTeXSnip| ๐ + (๐โฃ2+๐โฃ๐) |]
"m+\\left(p\\ {}2+q\\ {}r\\right)"
, [mkLaTeXSnip| ๐ + (๐<>๐<>๐) |]
"m+pqr"
, [mkLaTeXSnip| ๐ + (๐<>(2+๐)<>๐) |]
"m+\\left(p2+qr\\right)"
, [mkLaTeXSnip| ๐ * ((1+2)<>(3+4)) |]
"m{\\cdot}\\left(1+23+4\\right)"
]
, testGroup "Set-builders"
[ [mkLaTeXSnip| set(3โช4โช5) |]
"\\left\\{3,4,5\\right\\}"
, [mkLaTeXSnip| setCompr (๐ฅโ2) (๐ฅโโ) |]
"\\left\\{x^{2}\\middle|x\\in{}\\mathbb{N}\\right\\}"
, [mkLaTeXSnip| setCompr (๐ฅ/๐ฆ) (๐ฅโโคโช ๐ฆโโโช ๐ฆโชข0) |]
"\\left\\{\\frac{x}{y}\\middle|x\\in{}\\mathbb{Z},y\\in{}\\mathbb{N},y>0\\right\\}"
, [mkLaTeXSnip| setCompr (๐ฅโช๐ฆ) (๐ฅโโคโช ๐ฆโโ) |]
"\\left\\{\\left(x,y\\right)\\middle|x\\in{}\\mathbb{Z},y\\in{}\\mathbb{R}\\right\\}"
]
, testGroup "Stylised symbols"
[ [mkLaTeXSnip| ๐<>๐
<>๐ฅ<>๐<>๐ณ |]
"\\mathcal{A}\\mathfrak{B}\\mathfrak{h}\\mathbf{P}\\mathbf{z}"
]
, testGroup "Misc"
[ [mkLaTeXSnip| 3*๐ง - 1 |]
"3{\\cdot}z-1"
, [mkLaTeXSnip| ๐-๐+๐ |]
"a-b+c"
, [mkLaTeXSnip| (๐ฅ/2)|โโ(๐ฅโฉต0,1) |]
"\\left.\\frac{x}{2}\\right|_{x=0}^{1}"
, [mkLaTeXSnip| ๐ + (๐ฅ/2)
โฐโโฌโโฏ"fraction" |]
"b+\\underbrace{\\frac{x}{2}}_{\\mathrm{fraction}}"
, TestCase (3 - 1 &~~! [ ใ-ใ โฉต -(ใ-ใ) ])
"3 - 1 &~~! [ ใ-ใ โฉต -(ใ-ใ) ]" "3-1= -\\left(1-3\\right)"
, [mkLaTeXSnip| ๐ โ ๐ |] "a\\ast{}b"
, [mkLaTeXSnip| ๐ โ ๐ |] "a\\star{}b"
]
]
testGroup :: String -> [TestTree ฯ] -> TestTree ฯ
testGroup = TestGroup
evalTests :: (SymbolClass ฯ, SCConstraint ฯ LaTeX) => TestTree ฯ -> IO Text
evalTests = go False 1
where go hasHeader _ (TestCase e ec s)
| s==s' = do
let snipName = "test/PdfSnippets"</>encode (Txt.unpack s)
doesFileExist (snipName<.>".png") >>= flip
(when . not)`id` do
Txt.writeFile ("expression.tex") $ Txt.unlines
[ "\\documentclass[border=2pt]{standalone}"
, "\\usepackage[utf8x]{inputenc}"
, "\\usepackage{amsmath}"
, "\\usepackage{amssymb}"
, "\\pagestyle{empty}"
, "\\begin{document}"
, "$"<>s<>"$"
, "\\end{document}"
]
readProcess "pdflatex" ["expression.tex"] ""
callProcess "convert" [ "-density","300"
, "-background","grey", "-alpha","remove"
, "expression.pdf", snipName<.>"png" ]
return . (if hasHeader then id
else (("| Haskell | LaTeX | pdf |"
<>"\n| ---: | --- | :--- |\n")<>)) $
"| "<>mconcat[codesnippetify $
mkGithubtablesaveCode(Txt.pack (dropWhile (==' ') ecl))
| ecl<-lines ec]
<>"| `"<>mkGithubtablesaveCode s
<>"` | <>") |\n"
| otherwise = error $ "Got "<>show s'<>"; expected "
<> show s<>", when rendering "<>ec
where s' = LaTeX.render (toMathLaTeX e)
go _ i (TestGroup g (sโ:s))
= (Txt.pack (replicate i '#' <> " " <> g <> "\n") <>)
. Txt.concat <$> ((:) <$> go False (i+1) sโ
<*> mapM (go True $ i+1) s)
codesnippetify s
| '`'`elem`(Txt.unpack s) = "``"<>s<>"`` "
| otherwise = "`"<>s<>"` "
encode :: String -> String
encode = concatMap enc
where enc c
| isAlphaNum c = [c]
enc '+' = "โผฆ"
enc '-' = "โผ"
enc '\\' = "แญ"
enc '{' = "โถ"
enc '}' = "โถ"
enc '(' = "แ"
enc ')' = "แ"
enc '^' = "แ"
enc '_' = "โฃ"
enc '|' = "แ"
enc '!' = "โข"
enc '&' = "เฒค"
enc '=' = "ใง"
enc '<' = "แธ"
enc '>' = "แณ"
enc ',' = "ุ"
enc '.' = "แฐ"
enc ':' = "โฆ"
enc ' ' = "แง"
enc c = error $ "Unencodable character '"++[c]++"'"
mkGithubtablesaveCode :: Text -> Text
mkGithubtablesaveCode = Txt.concatMap esc
where esc '|' = "\\|"
esc c = Txt.singleton c