{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TemplateHaskell #-}
module Diagrams.Backend.PGF.Surface
(
Surface(..)
, TexFormat(..)
, surfOnlineTex
, surfOnlineTexIO
, latexSurface
, contextSurface
, plaintexSurface
, sampleSurfaceOutput
, texFormat
, command
, arguments
, pageSize
, preamble
, beginDoc
, endDoc
) where
import Data.ByteString.Builder
import Data.Hashable (Hashable (..))
import Data.Typeable (Typeable)
import System.IO.Unsafe
import System.Texrunner.Online
import Diagrams.Prelude
import Prelude
data TexFormat = LaTeX | ConTeXt | PlainTeX
deriving (Int -> TexFormat -> ShowS
[TexFormat] -> ShowS
TexFormat -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [TexFormat] -> ShowS
$cshowList :: [TexFormat] -> ShowS
show :: TexFormat -> [Char]
$cshow :: TexFormat -> [Char]
showsPrec :: Int -> TexFormat -> ShowS
$cshowsPrec :: Int -> TexFormat -> ShowS
Show, ReadPrec [TexFormat]
ReadPrec TexFormat
Int -> ReadS TexFormat
ReadS [TexFormat]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [TexFormat]
$creadListPrec :: ReadPrec [TexFormat]
readPrec :: ReadPrec TexFormat
$creadPrec :: ReadPrec TexFormat
readList :: ReadS [TexFormat]
$creadList :: ReadS [TexFormat]
readsPrec :: Int -> ReadS TexFormat
$creadsPrec :: Int -> ReadS TexFormat
Read, TexFormat -> TexFormat -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TexFormat -> TexFormat -> Bool
$c/= :: TexFormat -> TexFormat -> Bool
== :: TexFormat -> TexFormat -> Bool
$c== :: TexFormat -> TexFormat -> Bool
Eq, Typeable)
data Surface = Surface
{ Surface -> TexFormat
_texFormat :: TexFormat
, Surface -> [Char]
_command :: String
, Surface -> [[Char]]
_arguments :: [String]
, Surface -> Maybe (V2 Int -> [Char])
_pageSize :: Maybe (V2 Int -> String)
, Surface -> [Char]
_preamble :: String
, Surface -> [Char]
_beginDoc :: String
, Surface -> [Char]
_endDoc :: String
}
makeLensesWith (lensRules & generateSignatures .~ False) ''Surface
texFormat :: Lens' Surface TexFormat
command :: Lens' Surface String
arguments :: Lens' Surface [String]
preamble :: Lens' Surface String
pageSize :: Lens' Surface (Maybe (V2 Int -> String))
beginDoc :: Lens' Surface String
endDoc :: Lens' Surface String
latexSurface :: Surface
latexSurface :: Surface
latexSurface = Surface
{ _texFormat :: TexFormat
_texFormat = TexFormat
LaTeX
, _command :: [Char]
_command = [Char]
"pdflatex"
, _arguments :: [[Char]]
_arguments = []
, _pageSize :: Maybe (V2 Int -> [Char])
_pageSize = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ \(V2 Int
w Int
h) ->
[Char]
"\\pdfpagewidth=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
w forall a. [a] -> [a] -> [a]
++ [Char]
"bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\pdfpageheight=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
h forall a. [a] -> [a] -> [a]
++ [Char]
"bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\textheight=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
h forall a. [a] -> [a] -> [a]
++ [Char]
"bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\pdfhorigin=-76.6bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\pdfvorigin=-52.8bp"
, _preamble :: [Char]
_preamble = [Char]
"\\documentclass{article}\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\usepackage{pgfcore}\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\pagenumbering{gobble}"
, _beginDoc :: [Char]
_beginDoc = [Char]
"\\begin{document}"
, _endDoc :: [Char]
_endDoc = [Char]
"\\end{document}"
}
contextSurface :: Surface
contextSurface :: Surface
contextSurface = Surface
{ _texFormat :: TexFormat
_texFormat = TexFormat
ConTeXt
, _command :: [Char]
_command = [Char]
"context"
, _arguments :: [[Char]]
_arguments = [[Char]
"--pipe", [Char]
"--once"]
, _pageSize :: Maybe (V2 Int -> [Char])
_pageSize = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ \(V2 Int
w Int
h) ->
[Char]
"\\definepapersize[diagram][width="forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
w forall a. [a] -> [a] -> [a]
++[Char]
"bp,height="forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
h forall a. [a] -> [a] -> [a]
++[Char]
"bp]\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\setuppapersize[diagram][diagram]\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\setuplayout\n"
forall a. [a] -> [a] -> [a]
++ [Char]
" [ topspace=0bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
" , backspace=0bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
" , header=0bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
" , footer=0bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
" , width=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
w forall a. [a] -> [a] -> [a]
++ [Char]
"bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
" , height=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
h forall a. [a] -> [a] -> [a]
++ [Char]
"bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
" ]"
, _preamble :: [Char]
_preamble = [Char]
"\\usemodule[pgf]\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\setuppagenumbering[location=]"
, _beginDoc :: [Char]
_beginDoc = [Char]
"\\starttext"
, _endDoc :: [Char]
_endDoc = [Char]
"\\stoptext"
}
plaintexSurface :: Surface
plaintexSurface :: Surface
plaintexSurface = Surface
{ _texFormat :: TexFormat
_texFormat = TexFormat
PlainTeX
, _command :: [Char]
_command = [Char]
"pdftex"
, _arguments :: [[Char]]
_arguments = []
, _pageSize :: Maybe (V2 Int -> [Char])
_pageSize = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ \(V2 Int
w Int
h) ->
[Char]
"\\pdfpagewidth=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
w forall a. [a] -> [a] -> [a]
++ [Char]
"bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\pdfpageheight=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
h forall a. [a] -> [a] -> [a]
++ [Char]
"bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\pdfhorigin=-20bp\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\pdfvorigin=0bp"
, _preamble :: [Char]
_preamble = [Char]
"\\input eplain\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\beginpackages\n\\usepackage{color}\n\\endpackages\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\input pgfcore\n"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\def\\frac#1#2{{\\begingroup #1\\endgroup\\over #2}}"
forall a. [a] -> [a] -> [a]
++ [Char]
"\\nopagenumbers"
, _beginDoc :: [Char]
_beginDoc = [Char]
""
, _endDoc :: [Char]
_endDoc = [Char]
"\\bye"
}
instance Default Surface where
def :: Surface
def = Surface
latexSurface
sampleSurfaceOutput :: Surface -> String
sampleSurfaceOutput :: Surface -> [Char]
sampleSurfaceOutput Surface
surf = [[Char]] -> [Char]
unlines
[ [Char]
"command: " forall a. [a] -> [a] -> [a]
++ Surface
surf forall s a. s -> Getting a s a -> a
^. Lens' Surface [Char]
command forall a. [a] -> [a] -> [a]
++ [Char]
" " forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unwords (Surface
surf forall s a. s -> Getting a s a -> a
^. Lens' Surface [[Char]]
arguments)
, [Char]
"\n% preamble"
, Surface
surf forall s a. s -> Getting a s a -> a
^. Lens' Surface [Char]
preamble
, [Char]
"\n% pageSize"
, forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall a b. Prism (Maybe a) (Maybe b) a b
_Just forall a b. (a -> b) -> a -> b
$ Surface
surf forall s a. s -> Getting a s a -> a
^. Lens' Surface (Maybe (V2 Int -> [Char]))
pageSize forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. a -> Maybe a
Just (forall a. a -> a -> V2 a
V2 Int
100 Int
80)
, [Char]
"\n% beginDoc"
, Surface
surf forall s a. s -> Getting a s a -> a
^. Lens' Surface [Char]
beginDoc
, [Char]
"\n<" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show (Surface
surf forall s a. s -> Getting a s a -> a
^. Lens' Surface TexFormat
texFormat) forall a. [a] -> [a] -> [a]
++ [Char]
" pgf code>"
, [Char]
"\n% endDoc"
, Surface
surf forall s a. s -> Getting a s a -> a
^. Lens' Surface [Char]
endDoc
]
surfOnlineTex :: Surface -> OnlineTex a -> a
surfOnlineTex :: forall a. Surface -> OnlineTex a -> a
surfOnlineTex Surface
surf OnlineTex a
a = forall a. IO a -> a
unsafePerformIO (forall a. Surface -> OnlineTex a -> IO a
surfOnlineTexIO Surface
surf OnlineTex a
a)
{-# NOINLINE surfOnlineTex #-}
surfOnlineTexIO :: Surface -> OnlineTex a -> IO a
surfOnlineTexIO :: forall a. Surface -> OnlineTex a -> IO a
surfOnlineTexIO Surface
surf = forall a. [Char] -> [[Char]] -> ByteString -> OnlineTex a -> IO a
runOnlineTex (Surface
surfforall s a. s -> Getting a s a -> a
^.Lens' Surface [Char]
command) (Surface
surfforall s a. s -> Getting a s a -> a
^.Lens' Surface [[Char]]
arguments) ByteString
begin
where
begin :: ByteString
begin = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall lazy strict. Strict lazy strict => Iso' lazy strict
strict forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
toLazyByteString forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Builder
stringUtf8
forall a b. (a -> b) -> a -> b
$ Surface
surf forall s a. s -> Getting a s a -> a
^. (Lens' Surface [Char]
preamble forall a. Semigroup a => a -> a -> a
<> Lens' Surface [Char]
beginDoc)
instance Hashable TexFormat where
hashWithSalt :: Int -> TexFormat -> Int
hashWithSalt Int
s TexFormat
LaTeX = Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
1::Int)
hashWithSalt Int
s TexFormat
ConTeXt = Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
2::Int)
hashWithSalt Int
s TexFormat
PlainTeX = Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
3::Int)
instance Eq Surface where
Surface TexFormat
tf1 [Char]
cm1 [[Char]]
ar1 Maybe (V2 Int -> [Char])
ps1 [Char]
p1 [Char]
bd1 [Char]
ed1 == :: Surface -> Surface -> Bool
== Surface TexFormat
tf2 [Char]
cm2 [[Char]]
ar2 Maybe (V2 Int -> [Char])
ps2 [Char]
p2 [Char]
bd2 [Char]
ed2
= forall (t :: * -> *). Foldable t => t Bool -> Bool
and
[ TexFormat
tf1 forall a. Eq a => a -> a -> Bool
== TexFormat
tf2
, [Char]
cm1 forall a. Eq a => a -> a -> Bool
== [Char]
cm2
, [[Char]]
ar1 forall a. Eq a => a -> a -> Bool
== [[Char]]
ar2
, (Maybe (V2 Int -> [Char])
ps1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. a -> Maybe a
Just (forall a. a -> a -> V2 a
V2 Int
1 Int
2)) forall a. Eq a => a -> a -> Bool
== (Maybe (V2 Int -> [Char])
ps2 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. a -> Maybe a
Just (forall a. a -> a -> V2 a
V2 Int
1 Int
2))
, [Char]
p1 forall a. Eq a => a -> a -> Bool
== [Char]
p2
, [Char]
bd1 forall a. Eq a => a -> a -> Bool
== [Char]
bd2
, [Char]
ed1 forall a. Eq a => a -> a -> Bool
== [Char]
ed2
]
instance Hashable Surface where
hashWithSalt :: Int -> Surface -> Int
hashWithSalt Int
s (Surface TexFormat
tf [Char]
cm [[Char]]
ar Maybe (V2 Int -> [Char])
ps [Char]
p [Char]
bd [Char]
ed)
= Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt`
TexFormat
tf forall a. Hashable a => Int -> a -> Int
`hashWithSalt`
[Char]
cm forall a. Hashable a => Int -> a -> Int
`hashWithSalt`
[[Char]]
ar forall a. Hashable a => Int -> a -> Int
`hashWithSalt`
Maybe (V2 Int -> [Char])
ps forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. a -> Maybe a
Just (forall a. a -> a -> V2 a
V2 Int
1 Int
2) forall a. Hashable a => Int -> a -> Int
`hashWithSalt`
[Char]
p forall a. Hashable a => Int -> a -> Int
`hashWithSalt`
[Char]
bd forall a. Hashable a => Int -> a -> Int
`hashWithSalt`
[Char]
ed