packages feed

gnuplot 0.3.4 → 0.5.7

raw patch · 57 files changed

Files

+ Changes.md view
@@ -0,0 +1,15 @@+# Change log for the `gnuplot` Haskell binding++## 0.5.7:++ * `Gnuplot.Terminal.QT`++ * `Gnuplot.Execute`:+   Do longer call `pgnuplot` on Windows.+   It is gone in gnuplot-5.0 in January 2015.++## 0.5.5:++ * `Gnuplot.Utility.quote` bugfix:+   Do not escape printable non-ASCII characters+   because gnuplot has no universal escaping support for Unicode codepoints.
Makefile view
@@ -1,14 +1,26 @@ ghci:	ghci-tmp  ghci-tmp:-	ghci -Wall -i:src:execute/tmp src/Graphics/Gnuplot/Simple.hs+	ghci -Wall -i:src:dist/build/autogen:execute/tmp src/Graphics/Gnuplot/Simple.hs  ghci-pipe:-	ghci -Wall -i:src:execute/pipe src/Graphics/Gnuplot/Simple.hs+	ghci -Wall -i:src:dist/build/autogen:execute/pipe src/Graphics/Gnuplot/Simple.hs  ghci-shell:-	ghci -Wall -i:src:execute/shell src/Graphics/Gnuplot/Simple.hs+	ghci -Wall -i:src:dist/build/autogen:execute/shell src/Graphics/Gnuplot/Simple.hs  ghci-demo:-	ghci -Wall -i:src:execute/tmp src/Demo.hs+	ghci -Wall -i:src:dist/build/autogen:execute/tmp src/Demo.hs +testbuild:+	runhaskell Setup configure --user -f buildExamples+	runhaskell Setup build+	runhaskell Setup haddock++	runhaskell Setup clean+	runhaskell Setup configure --user -f executePipe+	runhaskell Setup build++	runhaskell Setup clean+	runhaskell Setup configure --user -f executeShell+	runhaskell Setup build
+ data/runtime.data view
@@ -0,0 +1,52 @@+#description: runtimes over input size+1		6.355182636689504e-5+100		1.0948364162371856e-2+199		2.2883437011933076e-2+298		3.6984818514001545e-2+397		5.278430392525412e-2+496		6.556876441607734e-2+595		8.094012753488622e-2+694		9.764933499422945e-2+793		0.11376420890800729+892		0.1303682446197088+991		0.1494559487429532+1090		0.16847618759261968+1189		0.1870789716535227+1288		0.20706133347400274+1387		0.22577923641544467+1486		0.24842725050880543+1585		0.2687356359522487+1684		0.29853175822408823+1783		0.30569358846083045+1882		0.34811570598277525+1981		0.37377121156830634+2080		0.3976917936986544+2179		0.4248938615564355+2278		0.4563135662584595+2377		0.4827751635322885+2476		0.5078150705665049+2575		0.5308599307954707+2674		0.5731755964461464+2773		0.5953289658030824+2872		0.6123024067073677+2971		0.5644368814660525+3070		0.6892736894713817+3169		0.7198984790477585+3268		0.75820146082337+3367		0.7922666002868061+3466		0.8332174605827827+3565		0.8727248373231685+3664		0.9070082204645331+3763		0.941051246582755+3862		0.9763012261824174+3961		1.0146614115691386+4060		1.053540654379474+4159		1.1035736989768552+4258		1.1434341162864607+4357		1.1855544921484864+4456		0.935738517553156+4555		1.2367099547145342+4654		1.2909424329951484+4753		1.3264400538531225+4852		1.3685529705611144+4951		1.4105760332671073
execute/shell/Graphics/Gnuplot/Execute.hs view
@@ -1,9 +1,10 @@ module Graphics.Gnuplot.Execute where +import Graphics.Gnuplot.Utility (semiColonConcat, )++import Shell.Utility.Quote as Quote import System.Exit (ExitCode, ) import System.Cmd (system, )-import Graphics.Gnuplot.Utility-   (quote, semiColonConcat, )   simple ::@@ -12,7 +13,7 @@    -> IO ExitCode simple program options =    let cmd =-          "sh -c 'echo " ++ quote (semiColonConcat program) +++          "sh -c 'echo " ++ Quote.minimal (semiColonConcat program) ++                  " | gnuplot " ++ unwords options ++ "'"    in  do --putStrLn cmd           system cmd
execute/tmp/Graphics/Gnuplot/Execute.hs view
@@ -1,7 +1,9 @@ module Graphics.Gnuplot.Execute where +import qualified System.IO as IO+import System.IO.Temp (withSystemTempFile, ) import System.Exit (ExitCode, )-import System.Cmd (rawSystem, )+import System.Process (readProcessWithExitCode, )   tmpScript :: FilePath@@ -12,6 +14,12 @@    -> [String] {-^ Options for gnuplot -}    -> IO ExitCode simple program options =-   do writeFile tmpScript (unlines program)-      -- putStrLn cmd-      rawSystem "gnuplot" $ options ++ [tmpScript]+   withSystemTempFile tmpScript $ \path handle -> do+      IO.hPutStr handle (unlines program)+      IO.hClose handle+      -- putStrLn $ showCommandForUser "gnuplot" (options ++ [path])+      (exitCode, _out, _err) <-+         readProcessWithExitCode "gnuplot" (options ++ [path]) []+      -- putStr out+      -- putStr err+      return exitCode
gnuplot.cabal view
@@ -1,6 +1,7 @@+Cabal-Version:    2.2 Name:             gnuplot-Version:          0.3.4-License:          BSD3+Version:          0.5.7+License:          BSD-3-Clause License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de> Maintainer:       Henning Thielemann <haskell@henning-thielemann.de>@@ -12,8 +13,9 @@    This is a wrapper to gnuplot    which lets you create 2D and 3D plots.    .-   Start a simple session with @make ghci@.-   This loads the module "Graphics.Gnuplot.Simple"+   Start a simple session with @cabal repl@.+   If not already loaded, call @:module Graphics.Gnuplot.Simple@+   in order to load "Graphics.Gnuplot.Simple"    which is ready for use in GHCi.    It does not address all fancy gnuplot features    in order to stay simple.@@ -22,27 +24,36 @@    I recommend "Graphics.Gnuplot.Advanced".    This module contains also an overview    of the hierarchy of objects.+   .    Examples for using this interface can be found in the "Demo" module.+   In order to compile this and install an example data file,+   use the Cabal flag @buildExamples@:    .+   > $ cabal install -fbuildExamples gnuplot+   .    With the Cabal flags executePipe and executeShell    you can switch to more convenient    but probably less portable ways    of feeding gnuplot with a script.-Tested-With:       GHC==6.8.2-Cabal-Version:     >=1.2+   .+   Alternative packages: @plot@, @HPlot@, @Chart@, @textPlot@, @easyplot@+Tested-With:       GHC==7.4.2, GHC==7.6.3, GHC==7.8.4, GHC==7.10.3+Tested-With:       GHC==8.2.1, GHC==8.6.5 Build-Type:        Simple Extra-Source-Files:   Makefile-  execute/tmp/Graphics/Gnuplot/Execute.hs-  execute/pipe/Graphics/Gnuplot/Execute.hs-  execute/shell/Graphics/Gnuplot/Execute.hs+  Changes.md+Data-Files:+  data/runtime.data -Flag splitBase-  description: Choose the new smaller, split-up base package.+Source-Repository this+  Tag:         0.5.7+  Type:        darcs+  Location:    http://code.haskell.org/gnuplot/ -Flag buildTests-  description: Build test executables-  default:     False+Source-Repository head+  Type:        darcs+  Location:    http://code.haskell.org/gnuplot/  Flag buildExamples   description: Build example executables@@ -58,20 +69,21 @@  Library   Build-Depends:-    array >= 0.1 && <0.4,-    containers >= 0.1 && <0.4,-    utility-ht >= 0.0.1 && < 0.1,-    monoid-transformer >= 0.0.2 && <0.1-  If flag(splitBase)-    Build-Depends:-      base >= 2 && <6,-      process >= 1.0 && < 1.1,-      time >= 1.1 && < 1.2,-      old-locale >= 1.0 && < 1.1-  Else-    Build-Depends:-      base >= 1.0 && < 2+    filepath >=1.1 && <1.5,+    temporary >=1.1 && <1.4,+    array >=0.1 && <0.6,+    containers >=0.1 && <0.7,+    utility-ht >=0.0.12 && <0.1,+    data-accessor-transformers >=0.2.1 && <0.3,+    data-accessor >=0.2.2 && <0.3,+    transformers >=0.3 && <0.7,+    semigroups >=0.1 && <1.0,+    deepseq >=1.0 && <1.5,+    process >=1.0 && <1.7,+    time >=1.5 && <1.14,+    base >=2 && <5 +  Default-Language: Haskell98   GHC-Options: -Wall    Hs-Source-Dirs: src@@ -80,6 +92,7 @@   Else     If flag(executeShell)       Hs-Source-Dirs: execute/shell+      Build-Depends: shell-utility >=0.0 && <0.2     Else       Hs-Source-Dirs: execute/tmp @@ -87,38 +100,68 @@     Graphics.Gnuplot.Simple     Graphics.Gnuplot.Time     Graphics.Gnuplot.Advanced+    Graphics.Gnuplot.Display+    Graphics.Gnuplot.File+    Graphics.Gnuplot.Terminal+    Graphics.Gnuplot.Terminal.Default     Graphics.Gnuplot.Terminal.PostScript     Graphics.Gnuplot.Terminal.PNG     Graphics.Gnuplot.Terminal.SVG+    Graphics.Gnuplot.Terminal.WXT+    Graphics.Gnuplot.Terminal.QT     Graphics.Gnuplot.Terminal.X11+    Graphics.Gnuplot.Encoding     Graphics.Gnuplot.Frame     Graphics.Gnuplot.Frame.Option     Graphics.Gnuplot.Frame.OptionSet+    Graphics.Gnuplot.Frame.OptionSet.Style+    Graphics.Gnuplot.Frame.OptionSet.Histogram+    Graphics.Gnuplot.Plot     Graphics.Gnuplot.Plot.TwoDimensional     Graphics.Gnuplot.Plot.ThreeDimensional+    Graphics.Gnuplot.Graph     Graphics.Gnuplot.Graph.TwoDimensional     Graphics.Gnuplot.Graph.ThreeDimensional     Graphics.Gnuplot.LineSpecification+    Graphics.Gnuplot.ColorSpecification     Graphics.Gnuplot.MultiPlot+    Graphics.Gnuplot.Value.Atom+    Graphics.Gnuplot.Value.Tuple+    Graphics.Gnuplot.Value.ColumnSet   Other-Modules:     Graphics.Gnuplot.Private.LineSpecification+    Graphics.Gnuplot.Private.ColorSpecification     Graphics.Gnuplot.Private.Plot     Graphics.Gnuplot.Private.Frame     Graphics.Gnuplot.Private.FrameOption     Graphics.Gnuplot.Private.FrameOptionSet-    Graphics.Gnuplot.Private.GraphType     Graphics.Gnuplot.Private.Graph     Graphics.Gnuplot.Private.Graph2D     Graphics.Gnuplot.Private.Graph3D+    Graphics.Gnuplot.Private.Graph2DType+    Graphics.Gnuplot.Private.Graph3DType     Graphics.Gnuplot.Private.GraphEmpty+    Graphics.Gnuplot.Private.Terminal+    Graphics.Gnuplot.Private.Encoding+    Graphics.Gnuplot.Private.Display+    Graphics.Gnuplot.Private.File+    Graphics.Gnuplot.Private.Command     Graphics.Gnuplot.Utility     Graphics.Gnuplot.Execute-    Graphics.Gnuplot.Display-    Graphics.Gnuplot.Terminal  Executable gnuplot-demo-  If !flag(buildExamples)+  If flag(buildExamples)+    Build-Depends:+      gnuplot,+      time,+      array,+      filepath,+      utility-ht,+      base+  Else     Buildable: False+  Default-Language: Haskell98   GHC-Options: -Wall-  Hs-Source-Dirs: src, execute/tmp-  Main-Is: Demo.hs+  Main-Is: src/Demo.hs+  Other-Modules: Paths_gnuplot+  Autogen-Modules: Paths_gnuplot
src/Demo.hs view
@@ -1,81 +1,225 @@ module Main where -import qualified Graphics.Gnuplot.Advanced as Plot-import qualified Graphics.Gnuplot.Terminal.X11 as X11+import qualified Graphics.Gnuplot.Advanced as GP  import qualified Graphics.Gnuplot.MultiPlot as MultiPlot  import qualified Graphics.Gnuplot.Frame as Frame-import qualified Graphics.Gnuplot.Frame.Option as Opt import qualified Graphics.Gnuplot.Frame.OptionSet as Opts+import qualified Graphics.Gnuplot.Frame.OptionSet.Style as OptsStyle+import qualified Graphics.Gnuplot.Frame.OptionSet.Histogram as Histogram +import qualified Graphics.Gnuplot.Graph as Graph+ import qualified Graphics.Gnuplot.Plot.ThreeDimensional as Plot3D+import qualified Graphics.Gnuplot.Graph.ThreeDimensional as Graph3D  import qualified Graphics.Gnuplot.Plot.TwoDimensional as Plot2D import qualified Graphics.Gnuplot.Graph.TwoDimensional as Graph2D import Graphics.Gnuplot.Plot.TwoDimensional (linearScale, ) +import qualified Graphics.Gnuplot.LineSpecification as LineSpec+import Graphics.Gnuplot.Value.Tuple (Label(Label))++import qualified Data.Time as Time++import qualified Paths_gnuplot as Path+import System.FilePath ((</>), )++import Control.Monad (liftM2, ) import Data.Array (listArray, )-import Data.Monoid (mappend, )+import Data.Foldable (foldMap, )+import Data.Monoid (mappend, mconcat, )+import Data.Tuple.HT (mapFst)  -simple2d :: Plot2D.T+simple2d :: Plot2D.T Double Double simple2d =-   Plot2D.function (linearScale 100 (-10,10::Double)) sin+   Plot2D.function Graph2D.lines+      (linearScale 100 (-10,10)) sin -circle2d :: Plot2D.T+circle2d :: Plot2D.T Double Double circle2d =-   fmap-      (Graph2D.typ Graph2D.points)-      (Plot2D.parameterFunction-         (linearScale 24 (-pi,pi::Double))-         (\t -> (cos t, sin t)))+   Plot2D.parameterFunction Graph2D.lines+      (linearScale 24 (-pi,pi))+      (\t -> (cos t, sin t)) -overlay2d :: Frame.T Graph2D.T+list2d :: Plot2D.T Int Integer+list2d =+   Plot2D.list Graph2D.listPoints [0,1,1,2,3,5,8,13]++labels2d :: Plot2D.T Double Double+labels2d =+   Plot2D.list Graph2D.labels $+   flip map [1..12] $+   \t -> (let w = fromInteger t*2*pi/12 in (sin w, cos w), Label $ show t)++candle2d :: Plot2D.T Time.Day Double+candle2d =+   Plot2D.list Graph2D.candleSticks $+   zip [(Time.fromGregorian 2008 01 01) ..] $+   flip map (linearScale 32 (0,2*pi)) $+   \t -> (-sin t, -2*sin t, 2*sin t, sin t)++image2d :: Plot2D.T Double Double+image2d =+   case linearScale 300 (-20,20) of+      xs ->+         Plot2D.function Graph2D.image (liftM2 (,) xs xs) $+            \(x,y) -> cos (sqrt (x*x+x*y+y*y))++overlay2d :: Frame.T (Graph2D.T Double Double) overlay2d =-   Frame.cons (Opts.size 1 0.4 $ Opts.remove Opt.key $ Opts.deflt) $-   Plot2D.function (linearScale 100 (-pi,pi::Double)) cos+   Frame.cons (Opts.size 1 0.4 $ defltOpts) $+   Plot2D.function Graph2D.lines (linearScale 100 (-pi,pi)) cos    `mappend`    circle2d -multiplot2d :: MultiPlot.T-multiplot2d =-   let opts :: Opts.T graph-       opts =-          Opts.remove Opt.key $+histogram2d :: Frame.T (Graph2D.T Int Double)+histogram2d =+   Frame.cons (+      Opts.title "Comparison of how well software revisions perform on each hardware version" $+      Histogram.clusteredGap 2 $+      Opts.boxwidthAbsolute 0.9 $+      OptsStyle.fillBorderLineType (-1) $+      OptsStyle.fillSolid $+      Opts.keyOutside $+      Opts.xTicks2d+         [("220", 0), ("320", 1), ("420", 2), ("520", 3), ("620", 4), ("720", 5)] $+      Opts.deflt) $+   foldMap (\(title,dat) ->+      fmap (Graph2D.lineSpec (LineSpec.title title LineSpec.deflt)) $+      Plot2D.list Graph2D.histograms dat) $+   ("1.0011", [102, 213, 378, 408, 840,  920]) :+   ("1.0012", [152, 233, 388, 433, 850, 1200]) :+   ("1.0013", [172, 263, 408, 463, 860, 1500]) :+   ("1.0014", [192, 293, 458, 483, 890, 2000]) :+   []++names2d :: Frame.T (Graph2D.T Double Double)+names2d =+   let domain = (-10,10)+       frameOpts =+          Opts.xRange2d domain $+          Opts.yRange2d (-1.5,1.5) $           Opts.deflt-       (prefix,suffix) =+   in  Frame.cons frameOpts $+       Plot2D.functionsWithLineSpec Graph2D.lines (linearScale 100 domain) $+       map (mapFst (flip LineSpec.title LineSpec.deflt)) $+       ("sin", sin) :+       ("cos", cos) :+       ("tan", tan) :+       []++filled2d :: Frame.T (Graph2D.T Double Double)+filled2d =+   let scale = linearScale 100 (-10,10)+       wave style (lower,upper) =+          Plot2D.function style scale $+          (\y -> (lower*y, upper*y)) . sin+   in  Frame.cons (Opts.key False Opts.deflt) $ mconcat $+       wave Graph2D.filledStripeAbove (1.0, 1.3) :+       wave Graph2D.filledStripeBelow (1.0, 1.3) :+       wave Graph2D.filledStripe      (0.7, 1.0) :+       []++file2d :: FilePath -> FilePath -> Frame.T (Graph2D.T Int Double)+file2d path file =+   let lineSpec =+          Graph2D.lineSpec $+          LineSpec.title "runtimes" $+          LineSpec.lineWidth 2.5 $+          LineSpec.deflt+       frameOpts =+          Opts.xLabel "input size" $+          Opts.yLabel "runtime (ms)" $+          Opts.title ("Graph from " ++ file) $+          Opts.deflt+   in  Frame.cons frameOpts $ fmap lineSpec $+       Plot2D.pathFromFile Graph2D.lines (path </> file) 1 2++mixed2d :: MultiPlot.T+mixed2d =+   MultiPlot.simpleFromPartArray $+   listArray ((0,0), (0,2)::(Int,Int)) $+   MultiPlot.partFromPlot circle2d :+   MultiPlot.partFromFrame+      (Frame.cons (Opts.sizeSquare $ Opts.xFormat "%m-%d" $ defltOpts) $+       candle2d) :+   MultiPlot.partFromPlot list2d :+   []++{-+The size settings of overlay2d interfer badly with the other plots,+because 'unset' does not restore the size to the multiplot settings.+-}+size2d :: MultiPlot.T+size2d =+   MultiPlot.simpleFromPartArray $+   listArray ((0,0), (0,2)::(Int,Int)) $+   MultiPlot.partFromPlot candle2d :+   MultiPlot.partFromFrame+      (Frame.cons (Opts.yLabel "Fibonacci" $ defltOpts) list2d) :+   MultiPlot.partFromPlot candle2d :+   []++defltOpts :: Graph.C graph => Opts.T graph+defltOpts = Opts.key False $ Opts.deflt++wave3d :: Frame.T (Graph3D.T Double Double Double)+wave3d =+   let meshNodes = linearScale 20 (-2,2)+   in  Frame.cons+          (Opts.grid True $+           Opts.view 42 17 1 1 $+           Opts.xRange3d (-2.5,2.5) $+           Opts.yRange3d (-2.5,2.5) $+           defltOpts) $+       Plot3D.surface meshNodes meshNodes (\x y -> cos(x*x+y*y))++lissajous3d :: Frame.T (Graph3D.T Double Double Double)+lissajous3d =+   let t = linearScale 300 (-pi, pi)+       f n = map (sin . (*) n) t+   in  Frame.cons defltOpts $+       Plot3D.cloud Graph3D.lines $+       zip3 (f 3) (f 4) (f 9)++multiplot :: MultiPlot.T+multiplot =+   let (prefix,suffix) =           splitAt 7 $           map MultiPlot.partFromFrame $           map (\k ->-             Frame.cons (Opts.xRange (-1,1) opts) $-             Plot2D.parameterFunction+             Frame.cons (Opts.xRange2d (-1,1) defltOpts) $+             Plot2D.parameterFunction Graph2D.lines                 (linearScale 48 (-pi,pi::Double))                 (\t -> (cos (t + pi/7*fromInteger k), sin (2*t)))) $           [0..13]-       meshNodes = linearScale 20 (-2,2::Double)-{--       center =-          MultiPlot.partFromFrame $-          Frame.empty--}-       center =-          MultiPlot.partFromFrame $-          Frame.cons-             (Opts.xRange (-2.5,2.5) $-              Opts.yRange (-2.5,2.5) $-              opts) $-          (Plot3D.function-             meshNodes meshNodes-             (\x y -> cos(x*x+y*y)))-   in  MultiPlot.simpleFromPartArray $-       listArray ((0::Int,0::Int), (2,4)) $+--       center = MultiPlot.partFromFrame Frame.empty+       center = MultiPlot.partFromFrame wave3d+   in  MultiPlot.title "multiplot of 2d and 3d graphics" $+       MultiPlot.simpleFromPartArray $+       listArray ((0,0), (2,4)::(Int,Int)) $        prefix ++ center : suffix   main :: IO ()-main =-   do Plot.plot X11.cons simple2d-      Plot.plot X11.cons overlay2d-      Plot.plot X11.cons multiplot2d-      return ()+main = sequence_ $+   GP.plotDefault simple2d :+   GP.plotDefault list2d :+   GP.plotDefault labels2d :+   GP.plotDefault candle2d :+   GP.plotDefault image2d :+   GP.plotDefault histogram2d :+   GP.plotDefault names2d :+   GP.plotDefault filled2d :+   GP.plotDefault overlay2d :+   (GP.plotDefault . flip file2d "runtime.data"+      =<< fmap (</> "data") Path.getDataDir) :+   GP.plotDefault mixed2d :+   GP.plotDefault size2d :+   GP.plotDefault wave3d :+   GP.plotDefault lissajous3d :+   GP.plotDefault multiplot :+   []
src/Graphics/Gnuplot/Advanced.hs view
@@ -34,7 +34,7 @@ of learning gnuplot script syntax, it happens frequently that people ask, how to express a certain gnuplot script using this package.-Thus let's annotate the gnuplot script generated by @Demo.multiplot2d@+Thus let's annotate the gnuplot script generated by @Demo.multiplot@ in order to show, what belongs to where:  > # the terminal selection is part of the 'plot' command of this module@@ -71,20 +71,29 @@ -} module Graphics.Gnuplot.Advanced (     plot,+    plotDefault,+    plotSync,+    plotAsync,+    fileContents,   ) where  import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet-import qualified Graphics.Gnuplot.Display as Display--import qualified Graphics.Gnuplot.Terminal as Terminal-import qualified Graphics.Gnuplot.Execute as Exec+import qualified Graphics.Gnuplot.Private.Display as Display+import qualified Graphics.Gnuplot.Private.Terminal as Terminal+import qualified Graphics.Gnuplot.Terminal.Default as DefaultTerm+import qualified Graphics.Gnuplot.File as File +import qualified Graphics.Gnuplot.Private.Command as Cmd+import Control.Concurrent (ThreadId, forkIO, ) import System.Exit (ExitCode, )-import Data.Monoid (Monoid, ) -- for Haddock-import qualified Data.Monoid.State as State-import Data.List (intersperse, ) +import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS+import Data.Monoid (Monoid, mempty, )+import Control.Functor.HT (void, )+import Data.Tuple.HT (mapFst, ) + -- * User front-end  @@ -95,24 +104,86 @@ For interactive sessions, better use "Graphics.Gnuplot.Simple". @gfx@ must be one of the types @Plot@, @Frame@, @MultiPlot@.++This function runs gnuplot asynchronously+for interactive terminals (X11, WX)+and synchronously for file terminals (PostScript, PNG, etc.).+This emulates the behaviour of @gnuplot --persist@.+However, when running asynchronous+we cannot obtain a real 'ExitCode'.+Thus, in this case we will always return 'ExitSuccess'. -} plot ::    (Terminal.C terminal, Display.C gfx) =>    terminal -> gfx -> IO ExitCode plot term gfx =+   case Terminal.canonical term of+      cterm ->+         Cmd.asyncIfInteractive+            (Terminal.interactive cterm)+            (plotCore cterm gfx)++plotAsync ::+   (Terminal.C terminal, Display.C gfx) =>+   terminal -> gfx -> IO ThreadId+plotAsync term gfx = forkIO $ void $ plotSync term gfx++plotSync ::+   (Terminal.C terminal, Display.C gfx) =>+   terminal -> gfx -> IO ExitCode+plotSync = plotCore . Terminal.canonical++plotCore ::+   (Display.C gfx) =>+   Terminal.T -> gfx -> IO ExitCode+plotCore term gfx =+   Cmd.run $ render term gfx++{- |+Return the gnuplot script and the curve files+corresponding to your plot data.+The first parameter is the directory where the curve files are located.+This directory is baked into the gnuplot script+and the paths of the curve files.++Don't make any assumptions about the structure of the files.+Feeding the files to gnuplot, archiving them or study them+are the intended uses of them.+-}+fileContents ::+   (Terminal.C terminal, Display.C gfx) =>+   FilePath -> terminal -> gfx -> (String, [File.T])+fileContents dir term gfx =+   mapFst unlines $ render (Terminal.canonical term) gfx dir++render ::+   Display.C gfx =>+   Terminal.T -> gfx -> FilePath -> ([String], [File.T])+render term gfx dir =    let body =-          State.evaluate (0, OptionSet.decons OptionSet.deflt) $+          flip MR.runReader dir $+          flip MS.evalStateT (0, OptionSet.initial) $           Display.runScript $           Display.toScript gfx-   in  do mapM_ Display.writeData (Display.files body)-          Exec.simple-             (formatTerminal term : Display.commands body)-             ["-persist"]+   in  (Terminal.format term ++ Display.commands body,+        Display.files body) -formatTerminal ::-   (Terminal.C terminal) =>-   terminal -> String-formatTerminal term =-   let (Terminal.Cons options commands) = Terminal.canonical term-   in  concat $ intersperse "; " $-          ("set terminal " ++ unwords options) : commands++{- |+Plot using the default gnuplot terminal.+-}+plotDefault ::+   (Display.C gfx) =>+   gfx -> IO ExitCode+plotDefault =+   plot DefaultTerm.cons++{-+In the module introduction we refer to Monoid.+That is we must import Monoid module in order to make Haddock happy.+On the other hand we do not use Monoid in the module body,+thus GHC emits a warning.+This dummy declaration makes both GHC and Haddock happy.+-}+_haddockDummy :: Monoid a => a+_haddockDummy = mempty
+ src/Graphics/Gnuplot/ColorSpecification.hs view
@@ -0,0 +1,307 @@+module Graphics.Gnuplot.ColorSpecification (+   T,+   rgb,+   rgb8,+   name,+   paletteFrac,++   white,+   black,+   gray0,+   grey0,+   gray10,+   grey10,+   gray20,+   grey20,+   gray30,+   grey30,+   gray40,+   grey40,+   gray50,+   grey50,+   gray60,+   grey60,+   gray70,+   grey70,+   gray80,+   grey80,+   gray90,+   grey90,+   gray100,+   grey100,+   gray,+   grey,+   lightGray,+   lightGrey,+   darkGray,+   darkGrey,+   red,+   lightRed,+   darkRed,+   yellow,+   lightYellow,+   darkYellow,+   green,+   lightGreen,+   darkGreen,+   springGreen,+   forestGreen,+   seaGreen,+   blue,+   lightBlue,+   darkBlue,+   midnightBlue,+   navy,+   mediumBlue,+   royalblue,+   skyblue,+   cyan,+   lightCyan,+   darkCyan,+   magenta,+   lightMagenta,+   darkMagenta,+   turquoise,+   lightTurquoise,+   darkTurquoise,+   pink,+   lightPink,+   darkPink,+   coral,+   lightCoral,+   orangeRed,+   salmon,+   lightSalmon,+   darkSalmon,+   aquamarine,+   khaki,+   darkKhaki,+   goldenrod,+   lightGoldenrod,+   darkGoldenrod,+   gold,+   beige,+   brown,+   orange,+   darkOrange,+   violet,+   darkViolet,+   plum,+   purple,++   ) where++import qualified Graphics.Gnuplot.Private.ColorSpecification as Color+import Graphics.Gnuplot.Private.ColorSpecification (T, )+import Data.Ord.HT (limit, )+import Data.Word (Word8, )+++{- |+Color components for Red, Green, Blue, must be in the range @[0,1]@.+-}+rgb :: Double -> Double -> Double -> T+rgb r g b =+   rgb8 (word8FromDouble r) (word8FromDouble g) (word8FromDouble b)++word8FromDouble :: Double -> Word8+word8FromDouble c =+   round (limit (0,1) c * 255)++rgb8 :: Word8 -> Word8 -> Word8 -> T+rgb8 = Color.RGB8++paletteFrac :: Double -> T+paletteFrac = Color.PaletteFrac++{- |+Specify a color by name.+You are responsible for choosing an existing name in gnuplot.+If your color is available as Haskell variable in this module,+then prefer this one.+-}+name :: String -> T+name = Color.Name+++{-+This function chooses how we represent below colors in gnuplot.+If we use RGB values then we stay independent from the available color names+in the current gnuplot version.+If we use color names, then the generated gnuplot scripts are more readable.+-}+makeColor :: String -> Int -> Word8 -> Word8 -> Word8 -> T+makeColor str _ _ _ _ = name str+++white,+ black,+ gray0,+ grey0,+ gray10,+ grey10,+ gray20,+ grey20,+ gray30,+ grey30,+ gray40,+ grey40,+ gray50,+ grey50,+ gray60,+ grey60,+ gray70,+ grey70,+ gray80,+ grey80,+ gray90,+ grey90,+ gray100,+ grey100,+ gray,+ grey,+ lightGray,+ lightGrey,+ darkGray,+ darkGrey,+ red,+ lightRed,+ darkRed,+ yellow,+ lightYellow,+ darkYellow,+ green,+ lightGreen,+ darkGreen,+ springGreen,+ forestGreen,+ seaGreen,+ blue,+ lightBlue,+ darkBlue,+ midnightBlue,+ navy,+ mediumBlue,+ royalblue,+ skyblue,+ cyan,+ lightCyan,+ darkCyan,+ magenta,+ lightMagenta,+ darkMagenta,+ turquoise,+ lightTurquoise,+ darkTurquoise,+ pink,+ lightPink,+ darkPink,+ coral,+ lightCoral,+ orangeRed,+ salmon,+ lightSalmon,+ darkSalmon,+ aquamarine,+ khaki,+ darkKhaki,+ goldenrod,+ lightGoldenrod,+ darkGoldenrod,+ gold,+ beige,+ brown,+ orange,+ darkOrange,+ violet,+ darkViolet,+ plum,+ purple :: T++{-+gnuplot> show colornames+-}++white             = makeColor "white"              0xffffff 255 255 255+black             = makeColor "black"              0x000000   0   0   0+gray0             = makeColor "gray0"              0x000000   0   0   0+grey0             = makeColor "grey0"              0x000000   0   0   0+gray10            = makeColor "gray10"             0x1a1a1a  26  26  26+grey10            = makeColor "grey10"             0x1a1a1a  26  26  26+gray20            = makeColor "gray20"             0x333333  51  51  51+grey20            = makeColor "grey20"             0x333333  51  51  51+gray30            = makeColor "gray30"             0x4d4d4d  77  77  77+grey30            = makeColor "grey30"             0x4d4d4d  77  77  77+gray40            = makeColor "gray40"             0x666666 102 102 102+grey40            = makeColor "grey40"             0x666666 102 102 102+gray50            = makeColor "gray50"             0x7f7f7f 127 127 127+grey50            = makeColor "grey50"             0x7f7f7f 127 127 127+gray60            = makeColor "gray60"             0x999999 153 153 153+grey60            = makeColor "grey60"             0x999999 153 153 153+gray70            = makeColor "gray70"             0xb3b3b3 179 179 179+grey70            = makeColor "grey70"             0xb3b3b3 179 179 179+gray80            = makeColor "gray80"             0xcccccc 204 204 204+grey80            = makeColor "grey80"             0xcccccc 204 204 204+gray90            = makeColor "gray90"             0xe5e5e5 229 229 229+grey90            = makeColor "grey90"             0xe5e5e5 229 229 229+gray100           = makeColor "gray100"            0xffffff 255 255 255+grey100           = makeColor "grey100"            0xffffff 255 255 255+gray              = makeColor "gray"               0xbebebe 190 190 190+grey              = makeColor "grey"               0xbebebe 190 190 190+lightGray         = makeColor "light-gray"         0xd3d3d3 211 211 211+lightGrey         = makeColor "light-grey"         0xd3d3d3 211 211 211+darkGray          = makeColor "dark-gray"          0xa9a9a9 169 169 169+darkGrey          = makeColor "dark-grey"          0xa9a9a9 169 169 169+red               = makeColor "red"                0xff0000 255   0   0+lightRed          = makeColor "light-red"          0xf03232 240  50  50+darkRed           = makeColor "dark-red"           0x8b0000 139   0   0+yellow            = makeColor "yellow"             0xffff00 255 255   0+lightYellow       = makeColor "light-yellow"       0xffffe0 255 255 224+darkYellow        = makeColor "dark-yellow"        0xc8c800 200 200   0+green             = makeColor "green"              0x00ff00   0 255   0+lightGreen        = makeColor "light-green"        0x90ee90 144 238 144+darkGreen         = makeColor "dark-green"         0x006400   0 100   0+springGreen       = makeColor "spring-green"       0x00ff7f   0 255 127+forestGreen       = makeColor "forest-green"       0x228b22  34 139  34+seaGreen          = makeColor "sea-green"          0x2e8b57  46 139  87+blue              = makeColor "blue"               0x0000ff   0   0 255+lightBlue         = makeColor "light-blue"         0xadd8e6 173 216 230+darkBlue          = makeColor "dark-blue"          0x00008b   0   0 139+midnightBlue      = makeColor "midnight-blue"      0x191970  25  25 112+navy              = makeColor "navy"               0x000080   0   0 128+mediumBlue        = makeColor "medium-blue"        0x0000cd   0   0 205+royalblue         = makeColor "royalblue"          0x4169e1  65 105 225+skyblue           = makeColor "skyblue"            0x87ceeb 135 206 235+cyan              = makeColor "cyan"               0x00ffff   0 255 255+lightCyan         = makeColor "light-cyan"         0xe0ffff 224 255 255+darkCyan          = makeColor "dark-cyan"          0x008b8b   0 139 139+magenta           = makeColor "magenta"            0xff00ff 255   0 255+lightMagenta      = makeColor "light-magenta"      0xf055f0 240  85 240+darkMagenta       = makeColor "dark-magenta"       0x8b008b 139   0 139+turquoise         = makeColor "turquoise"          0x40e0d0  64 224 208+lightTurquoise    = makeColor "light-turquoise"    0xafeeee 175 238 238+darkTurquoise     = makeColor "dark-turquoise"     0x00ced1   0 206 209+pink              = makeColor "pink"               0xffc0cb 255 192 203+lightPink         = makeColor "light-pink"         0xffb6c1 255 182 193+darkPink          = makeColor "dark-pink"          0xff1493 255  20 147+coral             = makeColor "coral"              0xff7f50 255 127  80+lightCoral        = makeColor "light-coral"        0xf08080 240 128 128+orangeRed         = makeColor "orange-red"         0xff4500 255  69   0+salmon            = makeColor "salmon"             0xfa8072 250 128 114+lightSalmon       = makeColor "light-salmon"       0xffa07a 255 160 122+darkSalmon        = makeColor "dark-salmon"        0xe9967a 233 150 122+aquamarine        = makeColor "aquamarine"         0x7fffd4 127 255 212+khaki             = makeColor "khaki"              0xf0e68c 240 230 140+darkKhaki         = makeColor "dark-khaki"         0xbdb76b 189 183 107+goldenrod         = makeColor "goldenrod"          0xdaa520 218 165  32+lightGoldenrod    = makeColor "light-goldenrod"    0xeedd82 238 221 130+darkGoldenrod     = makeColor "dark-goldenrod"     0xb8860b 184 134  11+gold              = makeColor "gold"               0xffd700 255 215   0+beige             = makeColor "beige"              0xf5f5dc 245 245 220+brown             = makeColor "brown"              0xa52a2a 165  42  42+orange            = makeColor "orange"             0xffa500 255 165   0+darkOrange        = makeColor "dark-orange"        0xff8c00 255 140   0+violet            = makeColor "violet"             0xee82ee 238 130 238+darkViolet        = makeColor "dark-violet"        0x9400d3 148   0 211+plum              = makeColor "plum"               0xdda0dd 221 160 221+purple            = makeColor "purple"             0xa020f0 160  32 240
src/Graphics/Gnuplot/Display.hs view
@@ -1,59 +1,7 @@ {- |-This class allows gives a uniform interface to plotting+This class gives a uniform interface to plotting @Plot@, @Frame@ and @MultiPlot@. -}-module Graphics.Gnuplot.Display where--import qualified Graphics.Gnuplot.Private.FrameOption as Option--import qualified Data.Map as Map-import qualified Data.Monoid.State as State-import Data.Monoid (Monoid, mempty, mappend, )----- * User front-end--newtype Script =-   Script {-      runScript :: State.T (Int, OptionSet) Body-   }--data Body =-   Body {-      files :: [File],-      commands :: [String]-   }--type OptionSet = Map.Map Option.T [String]--data File =-   File {-      filename :: FilePath,-      content :: String-   }--writeData :: File -> IO ()-writeData (File fn cont) =-   writeFile fn cont---{--Could also be implemented with Control.Monad.Trans.State:-mappend = liftA2 mappend--}-instance Monoid Script where-   mempty = Script mempty-   mappend (Script b0) (Script b1) =-      Script (mappend b0 b1)--{--Could also be implemented with Control.Monad.Trans.State:-mappend = liftA2 mappend--}-instance Monoid Body where-   mempty = Body mempty mempty-   mappend (Body f0 c0) (Body f1 c1) =-      Body (mappend f0 f1) (mappend c0 c1)+module Graphics.Gnuplot.Display (C, ) where -class C gfx where-   toScript :: gfx -> Script+import Graphics.Gnuplot.Private.Display
+ src/Graphics/Gnuplot/Encoding.hs view
@@ -0,0 +1,53 @@+{- |+Support for special characters++Gnuplot has no universal Unicode escaping mechanism,+you can only work with encodings.+However, not all terminals support all encodings,+not all terminals even support utf-8.+Some terminals seem to support only one encoding.+E.g. WX seems to support only UTF-8,+X11 seems to support only Latin-1.+Postscript, SVG, PNG seem to support both UTF-8 and Latin-1.++The @gnuplot@ Haskell bindings+always write using the system-wide default encoding.+Thus it is better not to set an encoding other than 'locale' explicitly.+However, if you write the files yourself in a certain encoding+you should use the @encoding@ option of the according terminal.+-}+module Graphics.Gnuplot.Encoding (+   T,+   locale, deflt,+   iso_8859_1, iso_8859_15, iso_8859_2, iso_8859_9,+   koi8r, koi8u,+   cp437, cp850, cp852, cp950, cp1250, cp1251, cp1254,+   sjis, utf8,+   ) where++import Graphics.Gnuplot.Private.Encoding (T(Cons))+++locale, deflt,+   iso_8859_1, iso_8859_15, iso_8859_2, iso_8859_9,+   koi8r, koi8u,+   cp437, cp850, cp852, cp950, cp1250, cp1251, cp1254,+   sjis, utf8 :: T++locale      = Cons "locale"+deflt       = Cons "default"+iso_8859_1  = Cons "iso_8859_1"+iso_8859_15 = Cons "iso_8859_15"+iso_8859_2  = Cons "iso_8859_2"+iso_8859_9  = Cons "iso_8859_9"+koi8r       = Cons "koi8r"+koi8u       = Cons "koi8u"+cp437       = Cons "cp437"+cp850       = Cons "cp850"+cp852       = Cons "cp852"+cp950       = Cons "cp950"+cp1250      = Cons "cp1250"+cp1251      = Cons "cp1251"+cp1254      = Cons "cp1254"+sjis        = Cons "sjis"+utf8        = Cons "utf8"
+ src/Graphics/Gnuplot/File.hs view
@@ -0,0 +1,17 @@+module Graphics.Gnuplot.File (T(Cons, name, content), write) where++import qualified Graphics.Gnuplot.Private.File as File++data T =+   Cons {+      name :: FilePath,+      content :: String+   }+   deriving (Show, Eq)+++write :: T -> IO ()+write (Cons fn cont) = writeFile fn cont++instance File.C T where+   write = write
src/Graphics/Gnuplot/Frame.hs view
@@ -3,20 +3,18 @@    cons, simple, empty,    ) where +import qualified Graphics.Gnuplot.Frame.OptionSet as OptionSet import qualified Graphics.Gnuplot.Private.Frame as Frame import qualified Graphics.Gnuplot.Private.Plot as Plot-import qualified Graphics.Gnuplot.Private.FrameOptionSet as Option import qualified Graphics.Gnuplot.Private.GraphEmpty as Empty--import qualified Data.Monoid.State as State+import qualified Graphics.Gnuplot.Private.Graph as Graph  -cons :: Option.T graph -> Plot.T graph -> Frame.T graph+cons :: OptionSet.T graph -> Plot.T graph -> Frame.T graph cons = Frame.Cons -simple :: Plot.T graph -> Frame.T graph-simple = cons Option.deflt+simple :: Graph.C graph => Plot.T graph -> Frame.T graph+simple = cons OptionSet.deflt  empty :: Frame.T Empty.T-empty =-   simple (Plot.Cons (State.pure []))+empty = simple $ Plot.pure []
src/Graphics/Gnuplot/Frame/Option.hs view
@@ -1,9 +1,42 @@ module Graphics.Gnuplot.Frame.Option (-   Option.T,-   module Graphics.Gnuplot.Private.FrameOption,+   -- hide Cons constructor+   T,++   custom,++   title,+   grid,+   size,+   key,+   border,+   pm3d,+   view,++   xRange,+   yRange,+   zRange,++   xLabel,+   yLabel,+   zLabel,++   xTicks,+   yTicks,+   zTicks,++   xLogScale,+   yLogScale,+   zLogScale,++   xData,+   yData,+   zData,++   xFormat,+   yFormat,+   zFormat,++   timeFmt,    ) where --- exclude Cons constructor--- this does not work, Cons is exported anyway-import Graphics.Gnuplot.Private.FrameOption hiding (T)-import qualified Graphics.Gnuplot.Private.FrameOption as Option+import Graphics.Gnuplot.Private.FrameOption
src/Graphics/Gnuplot/Frame/OptionSet.hs view
@@ -1,73 +1,185 @@ module Graphics.Gnuplot.Frame.OptionSet (    OptionSet.T,-   OptionSet.deflt,+   deflt,     OptionSet.add,    OptionSet.remove,+   OptionSet.boolean,+   OptionSet.addBool,     size,+   sizeRatio,+   sizeSquare,    title,-   xRange,-   yRange,-   zRange,+   key,+   keyInside,+   keyOutside,+   xRange2d,+   yRange2d,+   xRange3d,+   yRange3d,+   zRange3d,    xLabel,    yLabel,    zLabel,+   xTicks2d,+   yTicks2d,+   xTicks3d,+   yTicks3d,+   zTicks3d,+   xLogScale,+   yLogScale,+   zLogScale,+   grid,+   gridXTicks,+   gridYTicks,+   gridZTicks,+   xFormat,+   yFormat,+   zFormat,     view,    viewMap,++   boxwidthRelative,+   boxwidthAbsolute,    ) where   import qualified Graphics.Gnuplot.Graph.ThreeDimensional as Graph3D+import qualified Graphics.Gnuplot.Graph.TwoDimensional as Graph2D  import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet import qualified Graphics.Gnuplot.Private.FrameOption as Option import qualified Graphics.Gnuplot.Private.Graph as Graph +import qualified Graphics.Gnuplot.Value.Atom as Atom+import qualified Graphics.Gnuplot.Value.Tuple as Tuple+ import Graphics.Gnuplot.Private.FrameOptionSet (T, ) -import Graphics.Gnuplot.Utility-   (quote, )+import Graphics.Gnuplot.Utility (quote, commaConcat, ) +import qualified Data.List as List ++deflt :: Graph.C graph => T graph+deflt = Graph.defltOptions++ size :: Graph.C graph => Double -> Double -> T graph -> T graph size x y =-   OptionSet.add Option.size [show x ++ ", " ++ show y]+   OptionSet.add Option.sizeScale [show x ++ ", " ++ show y] +sizeRatio :: Graph.C graph => Double -> T graph -> T graph+sizeRatio r =+   OptionSet.add Option.sizeRatio ["ratio", show r]++sizeSquare :: Graph.C graph => T graph -> T graph+sizeSquare =+   OptionSet.add Option.sizeRatio ["square"]+ title :: Graph.C graph => String -> T graph -> T graph title text =    OptionSet.add Option.title [quote text] +key :: Graph.C graph => Bool -> T graph -> T graph+key = OptionSet.boolean Option.keyShow +keyInside :: Graph.C graph => T graph -> T graph+keyInside = OptionSet.add Option.keyPosition ["inside"]++keyOutside :: Graph.C graph => T graph -> T graph+keyOutside = OptionSet.add Option.keyPosition ["outside"]++{- xRange :: Graph.C graph => (Double, Double) -> T graph -> T graph xRange = range Option.xRange  yRange :: Graph.C graph => (Double, Double) -> T graph -> T graph yRange = range Option.yRange -zRange :: (Double, Double) -> T Graph3D.T -> T Graph3D.T+zRange :: (Double, Double) -> T (Graph3D.T x y z) -> T (Graph3D.T x y z) zRange = range Option.zRange+-} -range :: Graph.C graph => Option.T -> (Double, Double) -> T graph -> T graph+xRange2d ::+   (Atom.C x, Atom.C y, Tuple.C x) =>+   (x, x) -> T (Graph2D.T x y) -> T (Graph2D.T x y)+xRange2d = range Option.xRangeBounds++yRange2d ::+   (Atom.C x, Atom.C y, Tuple.C y) =>+   (y, y) -> T (Graph2D.T x y) -> T (Graph2D.T x y)+yRange2d = range Option.yRangeBounds+++xRange3d ::+   (Atom.C x, Atom.C y, Atom.C z, Tuple.C x) =>+   (x, x) -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+xRange3d = range Option.xRangeBounds++yRange3d ::+   (Atom.C x, Atom.C y, Atom.C z, Tuple.C y) =>+   (y, y) -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+yRange3d = range Option.yRangeBounds++zRange3d ::+   (Atom.C x, Atom.C y, Atom.C z, Tuple.C z) =>+   (z, z) -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+zRange3d = range Option.zRangeBounds+++range ::+   (Atom.C a, Tuple.C a, Graph.C graph) =>+   Option.T -> (a, a) -> T graph -> T graph range opt (x,y) =-   OptionSet.add opt ["[" ++ show x ++ ":" ++ show y ++ "]"]+   OptionSet.add opt+      [showString "[" . atomText x .+       showString ":" . atomText y $+       "]"] +atomText ::+   (Atom.C a, Tuple.C a) =>+   a -> ShowS+atomText x =+   case Tuple.text x of+      [s] -> s+      _ -> error "OptionSet.fromSingleton: types of Atom class must generate single representation texts" + xLabel :: Graph.C graph => String -> T graph -> T graph-xLabel = label Option.xLabel+xLabel = label Option.xLabelText  yLabel :: Graph.C graph => String -> T graph -> T graph-yLabel = label Option.yLabel+yLabel = label Option.yLabelText -zLabel :: String -> T Graph3D.T -> T Graph3D.T-zLabel = label Option.zLabel+zLabel ::+   (Atom.C x, Atom.C y, Atom.C z) =>+   String -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+zLabel = label Option.zLabelText  label :: Graph.C graph => Option.T -> String -> T graph -> T graph label opt x =    OptionSet.add opt [quote x]  +xFormat :: Graph.C graph => String -> T graph -> T graph+xFormat = format Option.xFormat++yFormat :: Graph.C graph => String -> T graph -> T graph+yFormat = format Option.yFormat++zFormat ::+   (Atom.C x, Atom.C y, Atom.C z) =>+   String -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+zFormat = format Option.zFormat++format :: Graph.C graph => Option.T -> String -> T graph -> T graph+format opt x =+   OptionSet.add opt [quote x]++ {- | Set parameters of viewing a surface graph. See <info:gnuplot/view>@@ -77,34 +189,105 @@    Double {- ^ rotateZ -} ->    Double {- ^ scale -} ->    Double {- ^ scaleZ -} ->-   T Graph3D.T -> T Graph3D.T+   T (Graph3D.T x y z) -> T (Graph3D.T x y z) view rotateX rotateZ scale scaleZ =-   OptionSet.add Option.view [show rotateX, show rotateZ, show scale, show scaleZ]+   OptionSet.add Option.view+      [commaConcat [show rotateX, show rotateZ, show scale, show scaleZ]]  {- | Show flat pixel map. -}-viewMap :: T Graph3D.T -> T Graph3D.T+viewMap :: T (Graph3D.T x y z) -> T (Graph3D.T x y z) viewMap =    OptionSet.add Option.view ["map"] -{--xTicks :: Graph.C graph => Double -> Double -> T graph -> T graph-xTicks = ticks Option.xTicks -yTicks :: Graph.C graph => Double -> Double -> T graph -> T graph-yTicks = ticks Option.yTicks+xTicks2d ::+   (Atom.C x, Atom.C y, Tuple.C x) =>+   [(String, x)] -> T (Graph2D.T x y) -> T (Graph2D.T x y)+xTicks2d = ticks Option.xTickLabels -zTicks :: Double -> Double -> T Graph3D.T -> T Graph3D.T-zTicks = ticks Option.zTicks+yTicks2d ::+   (Atom.C x, Atom.C y, Tuple.C y) =>+   [(String, y)] -> T (Graph2D.T x y) -> T (Graph2D.T x y)+yTicks2d = ticks Option.yTickLabels -ticks :: Graph.C graph => Option.T -> Double -> Double -> T graph -> T graph-ticks opt x y =-   OptionSet.add opt [show x ++ ":" ++ show y]--} +xTicks3d ::+   (Atom.C x, Atom.C y, Atom.C z, Tuple.C x) =>+   [(String, x)] -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+xTicks3d = ticks Option.xTickLabels++yTicks3d ::+   (Atom.C x, Atom.C y, Atom.C z, Tuple.C y) =>+   [(String, y)] -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+yTicks3d = ticks Option.yTickLabels++zTicks3d ::+   (Atom.C x, Atom.C y, Atom.C z, Tuple.C z) =>+   [(String, z)] -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+zTicks3d = ticks Option.zTickLabels+++ticks ::+   (Atom.C a, Tuple.C a, Graph.C graph) =>+   Option.T -> [(String, a)] -> T graph -> T graph+ticks opt labels =+   OptionSet.add opt+      [('(' :) $ foldr ($) ")" $+       List.intersperse (showString ", ") $+       map+          (\(lab,pos) ->+             showString (quote lab) .+             showString " " .+             atomText pos)+          labels]+++xLogScale :: Graph.C graph => T graph -> T graph+xLogScale = OptionSet.add Option.xLogScale []++yLogScale :: Graph.C graph => T graph -> T graph+yLogScale = OptionSet.add Option.yLogScale []++zLogScale ::+   (Atom.C x, Atom.C y, Atom.C z) =>+   T (Graph3D.T x y z) -> T (Graph3D.T x y z)+zLogScale = OptionSet.add Option.zLogScale []+++grid :: Graph.C graph => Bool -> T graph -> T graph+grid b =+   OptionSet.addBool Option.gridXTicks b .+   OptionSet.addBool Option.gridYTicks b .+   OptionSet.addBool Option.gridZTicks b++gridXTicks :: Graph.C graph => Bool -> T graph -> T graph+gridXTicks = OptionSet.addBool Option.gridXTicks++gridYTicks :: Graph.C graph => Bool -> T graph -> T graph+gridYTicks = OptionSet.addBool Option.gridYTicks++gridZTicks ::+   (Atom.C x, Atom.C y, Atom.C z) =>+   Bool -> T (Graph3D.T x y z) -> T (Graph3D.T x y z)+gridZTicks = OptionSet.addBool Option.gridZTicks+++boxwidthRelative ::+   (Graph.C graph) =>+   Double -> T graph -> T graph+boxwidthRelative width =+   OptionSet.add Option.boxwidth [show width, "relative"]++boxwidthAbsolute ::+   (Graph.C graph) =>+   Double -> T graph -> T graph+boxwidthAbsolute width =+   OptionSet.add Option.boxwidth [show width, "absolute"]+ {--cornerToColor :: CornersToColor -> T Graph3D.T -> T Graph3D.T+cornerToColor :: CornersToColor -> T (Graph3D.T x y z) -> T (Graph3D.T x y z) -type3d :: Plot3dType -> T Graph3D.T -> T Graph3D.T+type3d :: Plot3dType -> T (Graph3D.T x y z) -> T (Graph3D.T x y z) -}
+ src/Graphics/Gnuplot/Frame/OptionSet/Histogram.hs view
@@ -0,0 +1,61 @@+module Graphics.Gnuplot.Frame.OptionSet.Histogram (+   clustered,+   clusteredGap,+   errorbars,+   errorbarsGap,+   errorbarsGapLineWidth,+   rowstacked,+   columnstacked,+   ) where++import qualified Graphics.Gnuplot.Graph.TwoDimensional as Graph2D++import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet+import qualified Graphics.Gnuplot.Private.FrameOption as Option++import qualified Graphics.Gnuplot.Value.Atom as Atom++import Graphics.Gnuplot.Private.FrameOptionSet (T, )+++clustered ::+   (Atom.C x, Atom.C y) =>+   T (Graph2D.T x y) -> T (Graph2D.T x y)+clustered =+   OptionSet.add Option.styleHistogram ["clustered"]++clusteredGap ::+   (Atom.C x, Atom.C y) =>+   Double -> T (Graph2D.T x y) -> T (Graph2D.T x y)+clusteredGap gapSize =+   OptionSet.add Option.styleHistogram ["clustered", "gap", show gapSize]++errorbars ::+   (Atom.C x, Atom.C y) =>+   T (Graph2D.T x y) -> T (Graph2D.T x y)+errorbars =+   OptionSet.add Option.styleHistogram ["errorbars"]++errorbarsGap ::+   (Atom.C x, Atom.C y) =>+   Double -> T (Graph2D.T x y) -> T (Graph2D.T x y)+errorbarsGap gapSize =+   OptionSet.add Option.styleHistogram ["errorbars", "gap", show gapSize]++errorbarsGapLineWidth ::+   (Atom.C x, Atom.C y) =>+   Double -> Double -> T (Graph2D.T x y) -> T (Graph2D.T x y)+errorbarsGapLineWidth gapSize width =+   OptionSet.add Option.styleHistogram ["errorbars", "gap", show gapSize, show width]++rowstacked ::+   (Atom.C x, Atom.C y) =>+   T (Graph2D.T x y) -> T (Graph2D.T x y)+rowstacked =+   OptionSet.add Option.styleHistogram ["rowstacked"]++columnstacked ::+   (Atom.C x, Atom.C y) =>+   T (Graph2D.T x y) -> T (Graph2D.T x y)+columnstacked =+   OptionSet.add Option.styleHistogram ["columnstacked"]
+ src/Graphics/Gnuplot/Frame/OptionSet/Style.hs view
@@ -0,0 +1,26 @@+module Graphics.Gnuplot.Frame.OptionSet.Style (+   fillSolid,+   fillBorder,+   fillBorderLineType,+   ) where++import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet+import qualified Graphics.Gnuplot.Private.FrameOption as Option+import qualified Graphics.Gnuplot.Private.Graph as Graph++import Graphics.Gnuplot.Private.FrameOptionSet (T, )++-- import Graphics.Gnuplot.Utility (quote, )+++fillSolid :: Graph.C graph => T graph -> T graph+fillSolid =+   OptionSet.addBool Option.styleFillSolid True++fillBorder :: Graph.C graph => Bool -> T graph -> T graph+fillBorder =+   OptionSet.addBool Option.styleFillBorder++fillBorderLineType :: Graph.C graph => Int -> T graph -> T graph+fillBorderLineType n =+   OptionSet.add Option.styleFillBorder ["border", show n]
+ src/Graphics/Gnuplot/Graph.hs view
@@ -0,0 +1,3 @@+module Graphics.Gnuplot.Graph (Graph.C) where++import qualified Graphics.Gnuplot.Private.Graph as Graph
src/Graphics/Gnuplot/Graph/ThreeDimensional.hs view
@@ -2,39 +2,17 @@    T,    Type, -   defaultType,-   deflt,+--   deflt, -   typ,    lineSpec, -   lines,-   points,-   linesPoints,    impulses,-   dots,-   steps,-   fSteps,-   hiSteps,-   errorBars,-   xErrorBars,-   yErrorBars,-   xyErrorBars,-   errorLines,-   xErrorLines,-   yErrorLines,-   xyErrorLines,-   boxes,-   filledCurves,-   boxErrorBars,-   boxXYErrorBars,-   financeBars,-   candleSticks,    vectors,-   pm3d,+   Graph3DType.pm3d,++   Graph3DType.lines,+   points,    ) where  import Graphics.Gnuplot.Private.Graph3D-import Graphics.Gnuplot.Private.GraphType hiding (T, )--import Prelude hiding (lines, )+import Graphics.Gnuplot.Private.Graph3DType as Graph3DType hiding (T, )
src/Graphics/Gnuplot/Graph/TwoDimensional.hs view
@@ -2,13 +2,32 @@    T,    Type, -   defaultType,-   deflt,+--   deflt, -   typ,    lineSpec, -   lines,+   listLines,+   listPoints,+   listLinesPoints,+   listImpulses,+   listDots,+   histograms,++   xErrorBarsRelative,+   yErrorBarsRelative,+   xyErrorBarsRelative,+   xErrorBarsAbsolute,+   yErrorBarsAbsolute,+   xyErrorBarsAbsolute,++   xErrorLinesRelative,+   yErrorLinesRelative,+   xyErrorLinesRelative,+   xErrorLinesAbsolute,+   yErrorLinesAbsolute,+   xyErrorLinesAbsolute,++   Graph2DType.lines,    points,    linesPoints,    impulses,@@ -17,24 +36,24 @@    fSteps,    hiSteps,    errorBars,-   xErrorBars,-   yErrorBars,-   xyErrorBars,    errorLines,-   xErrorLines,-   yErrorLines,-   xyErrorLines,    boxes,    filledCurves,+{-    boxErrorBars,    boxXYErrorBars,+-}    financeBars,    candleSticks,    vectors,-   -- pm3d,+   image,++   filledStripe,+   filledStripeAbove,+   filledStripeBelow,++   labels,    ) where  import Graphics.Gnuplot.Private.Graph2D-import Graphics.Gnuplot.Private.GraphType hiding (T, )--import Prelude hiding (lines, )+import Graphics.Gnuplot.Private.Graph2DType as Graph2DType hiding (T, )
src/Graphics/Gnuplot/LineSpecification.hs view
@@ -6,6 +6,7 @@    lineStyle,    lineType,    lineWidth,+   lineColor,    pointType,    pointSize,    title,
src/Graphics/Gnuplot/MultiPlot.hs view
@@ -5,24 +5,27 @@    partFromPlot,    simpleFromFrameArray,    simpleFromPartArray,+   title,    ) where  import qualified Graphics.Gnuplot.Private.Frame as Frame import qualified Graphics.Gnuplot.Private.Plot as Plot -import qualified Graphics.Gnuplot.Display as Display+import qualified Graphics.Gnuplot.Private.Display as Display import qualified Graphics.Gnuplot.Private.Graph as Graph -import qualified Data.Monoid.State as State import Data.Monoid (mconcat, )+import Data.Foldable (foldMap, )  import Data.Array (Array, elems, bounds, ) import Data.Ix (Ix, rangeSize, ) +import Graphics.Gnuplot.Utility (quote, ) + data T =    Cons {-      _option :: (),  -- to be extended by multiplot options+      title_ :: Maybe String,       numRows, numColumns :: Int,       parts :: [Part]    }@@ -60,20 +63,26 @@    Array (i,j) Part -> T simpleFromPartArray arr =    let ((r0,c0), (r1,c1)) = bounds arr-   in  Cons ()+   in  Cons Nothing           (rangeSize (r0,r1))           (rangeSize (c0,c1))           (elems arr)  +title :: String -> T -> T+title str mp =+   mp {title_ = Just str}++ instance Display.C T where    toScript mp =       mconcat $-      (Display.Script $ State.pure $-         Display.Body [] ["set multiplot layout " ++-                      show (numRows mp) ++ ", " ++-                      show (numColumns mp)]) :+      (Display.pure $+         Display.Body []+            ["set multiplot layout " +++             show (numRows mp) ++ ", " ++ show (numColumns mp) +++             foldMap ((" title " ++) . quote) (title_ mp)]) :       (map scriptFromPart $ parts mp) ++-      (Display.Script $ State.pure $+      (Display.pure $          Display.Body [] ["unset multiplot"]) :       []
+ src/Graphics/Gnuplot/Plot.hs view
@@ -0,0 +1,3 @@+module Graphics.Gnuplot.Plot (T) where++import Graphics.Gnuplot.Private.Plot (T)
src/Graphics/Gnuplot/Plot/ThreeDimensional.hs view
@@ -1,35 +1,67 @@ module Graphics.Gnuplot.Plot.ThreeDimensional (+   T,+   cloud,+--   function,+   mesh,+   surface,+    linearScale,-   module Graphics.Gnuplot.Plot.ThreeDimensional,+   functionToGraph,    ) where +import qualified Graphics.Gnuplot.Private.Graph3DType as Type import qualified Graphics.Gnuplot.Private.Graph3D as Graph import qualified Graphics.Gnuplot.Private.Plot    as Plot+-- import qualified Graphics.Gnuplot.Value.ColumnSet as Col+import qualified Graphics.Gnuplot.Value.Tuple as Tuple+import qualified Graphics.Gnuplot.Value.Atom  as Atom  import Graphics.Gnuplot.Utility-   (showTriplet, linearScale, )+   (functionToGraph, linearScale, assembleCells, )  import Data.List.HT (outerProduct, )   {- |-Plots can be assembled using 'mappend' or 'mconcat'.+Plots can be assembled using 'mappend' or 'mconcat'+or several functions from "Data.Foldable". -}-type T = Plot.T Graph.T+type T x y z = Plot.T (Graph.T x y z)   -- * computed plots -mesh ::-   (Show a, Show b, Show c) =>-   [[(a,b,c)]] -> T-mesh dat =+cloud ::+   (Atom.C x, Atom.C y, Atom.C z,+    Tuple.C a) =>+   Type.T x y z a -> [a] -> T x y z+cloud typ ps =    Plot.withUniqueFile-      (unlines (map (unlines . map showTriplet) dat))-      [Graph.deflt (Graph.Dim3 1 2 3)]+      (assembleCells (map Tuple.text ps))+      [Graph.deflt typ+         [1 .. case Type.tupleSize typ of Tuple.ColumnCount n -> n]] +{- function ::-   (Show a, Show b, Show c) =>-   [b] -> [c] -> (b -> c -> a) -> T+   (Atom.C x, Atom.C y, Atom.C z) =>+   Type.T (x,y,z) -> [x] -> [y] -> (x -> y -> z) -> T function xArgs yArgs f =+   cloud (liftM2 (\x y -> (x, y, f x y)) xArgs yArgs)+-}+++mesh ::+   (Atom.C x, Atom.C y, Atom.C z,+    Tuple.C x, Tuple.C y, Tuple.C z) =>+   [[(x,y,z)]] -> T x y z+mesh pss =+   Plot.withUniqueFile+      (assembleCells (concatMap (\ps -> map Tuple.text ps ++ [[]]) pss))+      [Graph.pm3d]++surface ::+   (Atom.C x, Atom.C y, Atom.C z,+    Tuple.C x, Tuple.C y, Tuple.C z) =>+   [x] -> [y] -> (x -> y -> z) -> T x y z+surface xArgs yArgs f =    mesh (outerProduct (\x y -> (x, y, f x y)) xArgs yArgs)
src/Graphics/Gnuplot/Plot/TwoDimensional.hs view
@@ -1,73 +1,129 @@ -- shall this also export Graph.Type, set plotType and so on? module Graphics.Gnuplot.Plot.TwoDimensional (+   T,++   list,+   function,+   functions,+   functionsWithLineSpec,+   parameterFunction,++   listFromFile,+   pathFromFile,+    linearScale,-   module Graphics.Gnuplot.Plot.TwoDimensional,+   functionToGraph,    ) where +import qualified Graphics.Gnuplot.Private.Graph2DType as Type import qualified Graphics.Gnuplot.Private.Graph2D as Graph import qualified Graphics.Gnuplot.Private.Plot    as Plot+import qualified Graphics.Gnuplot.Private.LineSpecification as LineSpec+import qualified Graphics.Gnuplot.Value.ColumnSet as Col+import qualified Graphics.Gnuplot.Value.Tuple as Tuple+import qualified Graphics.Gnuplot.Value.Atom  as Atom  import Graphics.Gnuplot.Utility-   (functionToGraph, commaConcat, linearScale, )+   (functionToGraph, linearScale, assembleCells, )  import qualified Data.List.Match as Match+import qualified Data.List.HT as ListHT   {- | Plots can be assembled using 'mappend' or 'mconcat'.+You can alter attributes of embedded graphs using 'fmap'. -}-type T = Plot.T Graph.T+type T x y = Plot.T (Graph.T x y)   -- * computed plots  {- |-> list (take 30 (let fibs = 0 : 1 : zipWith (+) fibs (tail fibs) in fibs))+> list Type.listLines (take 30 (let fibs = 0 : 1 : zipWith (+) fibs (tail fibs) in fibs))+> list Type.lines (take 30 (let fibs0 = 0 : fibs1; fibs1 = 1 : zipWith (+) fibs0 fibs1 in zip fibs0 fibs1)) -}-list :: Show a => [a] -> T-list dat =+list ::+   (Atom.C x, Atom.C y, Tuple.C a) =>+   Type.T x y a -> [a] -> T x y+list typ ps =    Plot.withUniqueFile-      (unlines (map show dat))-      ([Graph.deflt (Graph.Dim1 1)])+      (assembleCells (map Tuple.text ps))+      [Graph.deflt typ+         [1 .. case Type.tupleSize typ of Tuple.ColumnCount n -> n]]  {- |-> function (linearScale 1000 (-10,10)) sin+> function Type.line (linearScale 1000 (-10,10)) sin -}-function :: Show a => [a] -> (a -> a) -> T-function args f =-   path (functionToGraph args f)+function ::+   (Atom.C x, Atom.C y,+    Tuple.C a, Tuple.C b) =>+   Type.T x y (a,b) -> [a] -> (a -> b) -> T x y+function typ args f =+   list typ (functionToGraph args f)  {- |-> functions (linearScale 1000 (-10,10)) [sin, cos]+> functions Type.line (linearScale 1000 (-10,10)) [sin, cos] -}-functions :: Show a => [a] -> [a -> a] -> T-functions args fs =-   let dat = map (\x -> (x, map ($ x) fs)) args+functions ::+   (Atom.C x, Atom.C y,+    Tuple.C a, Tuple.C b) =>+   Type.T x y (a,b) -> [a] -> [a -> b] -> T x y+functions typ args =+   functionsWithLineSpec typ args . map ((,) LineSpec.deflt)++{- |+> functionsWithLineSpec Type.line (linearScale 1000 (-10,10)) $+>    map (mapFst (flip LineSpec.title LineSpec.deflt)) [("sin", sin), ("cos", cos)]+-}+functionsWithLineSpec ::+   (Atom.C x, Atom.C y,+    Tuple.C a, Tuple.C b) =>+   Type.T x y (a,b) -> [a] -> [(LineSpec.T, a -> b)] -> T x y+functionsWithLineSpec typ args fs =+   let dat = map (\x -> (x, map (($ x) . snd) fs)) args+       mapType :: (a -> b) -> Type.T x y a -> Type.T x y b+       mapType _ (Type.Cons str) = Type.Cons str+       Tuple.ColumnCount na = Type.tupleSize $ mapType fst typ+       Tuple.ColumnCount nb = Type.tupleSize $ mapType snd typ    in  Plot.withUniqueFile-          (unlines (map (commaConcat . map show . uncurry (:)) dat))+          (assembleCells+              (map (\(a,b) -> Tuple.text a ++ concatMap Tuple.text b) dat))           (Match.take fs $-           map (Graph.deflt . Graph.Dim2 1) [2..])+           zipWith+              (\(lineSpec,_f) ns ->+                 Graph.lineSpec lineSpec $ Graph.deflt typ ([1..na] ++ ns))+              fs $+           ListHT.sliceVertical nb [(na+1)..]) -path :: Show a => [(a,a)] -> T-path dat =-   Plot.withUniqueFile-      (unlines (map (\(x,y) -> show x ++ ", " ++ show y) dat))-      ([Graph.deflt (Graph.Dim2 1 2)])  {- |-> parameterFunction (linearScale 1000 (0,2*pi)) (\t -> (sin (2*t), cos t))+> parameterFunction Type.line (linearScale 1000 (0,2*pi)) (\t -> (sin (2*t), cos t)) -}-parameterFunction :: Show a => [a] -> (a -> (a,a)) -> T-parameterFunction args f = path (map f args)+parameterFunction ::+   (Atom.C x, Atom.C y,+    Tuple.C a) =>+   Type.T x y a -> [t] -> (t -> a) -> T x y+parameterFunction typ args f = list typ (map f args)    -- * plot stored data -listFromFile :: FilePath -> Int -> T-listFromFile filename column =-   Plot.fromGraphs filename [Graph.deflt (Graph.Dim1 column)]+fromFile ::+   (Atom.C x, Atom.C y) =>+   Type.T x y a -> FilePath -> Col.T a -> T x y+fromFile typ filename (Col.Cons cs) =+   Plot.fromGraphs filename [Graph.deflt typ cs] -pathFromFile :: FilePath -> Int -> Int -> T-pathFromFile filename columnX columnY =-   Plot.fromGraphs filename [Graph.deflt (Graph.Dim2 columnX columnY)]+listFromFile ::+   (Atom.C i, Atom.C y) =>+   Type.T i y y -> FilePath -> Int -> T i y+listFromFile typ filename column =+   fromFile typ filename (Col.atom column)++pathFromFile ::+   (Atom.C x, Atom.C y) =>+   Type.T x y (x,y) -> FilePath -> Int -> Int -> T x y+pathFromFile typ filename columnX columnY =+   fromFile typ filename (Col.pair (Col.atom columnX) (Col.atom columnY))
+ src/Graphics/Gnuplot/Private/ColorSpecification.hs view
@@ -0,0 +1,22 @@+module Graphics.Gnuplot.Private.ColorSpecification where++import Graphics.Gnuplot.Utility (quote, )+import Data.List.HT (padLeft, )+import Data.Word (Word8, )+import Numeric (showHex, )+++data T =+     Name String+   | RGB8 {red, green, blue :: Word8}+   | PaletteFrac Double+++toString :: T -> String+toString c =+   case c of+      Name name -> "rgbcolor " ++ quote name+      RGB8 r g b ->+         "rgbcolor #" +++         concatMap (padLeft '0' 2 . flip showHex "") [r,g,b]+      PaletteFrac frac -> "palette frac " ++ show frac
+ src/Graphics/Gnuplot/Private/Command.hs view
@@ -0,0 +1,28 @@+module Graphics.Gnuplot.Private.Command where++import qualified Graphics.Gnuplot.Private.File as File+import qualified Graphics.Gnuplot.Execute as Exec+import System.Exit (ExitCode(ExitSuccess), )+import Control.Concurrent (forkIO, )++import System.IO.Temp (withSystemTempDirectory, )++import Control.DeepSeq (deepseq, )+import Control.Functor.HT (void, )+++run ::+   (File.C file) =>+   (FilePath -> ([String], [file])) -> IO ExitCode+run render =+   withSystemTempDirectory "gnuplot" $ \dir ->+   case render dir of+      (cmds, files) -> deepseq cmds $ do+         mapM_ File.write files+         Exec.simple (cmds ++ ["pause mouse close"]) []++asyncIfInteractive :: Bool -> IO ExitCode -> IO ExitCode+asyncIfInteractive interactive act =+   if interactive+     then fmap (const ExitSuccess) $ forkIO $ void act+     else act
+ src/Graphics/Gnuplot/Private/Display.hs view
@@ -0,0 +1,56 @@+module Graphics.Gnuplot.Private.Display where++import qualified Graphics.Gnuplot.Private.FrameOption as Option+import qualified Graphics.Gnuplot.File as File++import qualified Data.Map as Map+import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS+import Control.Monad (liftM2, return, )+import Data.Monoid (Monoid, mempty, mappend, )+import Data.Semigroup (Semigroup, (<>), )++import Prelude (FilePath, String, Int, ($), (.), )+++newtype Script =+   Script {+      runScript :: MS.StateT (Int, OptionSet) (MR.Reader FilePath) Body+   }++pure :: Body -> Script+pure = Script . return++data Body =+   Body {+      files :: [File.T],+      commands :: [String]+   }++type OptionSet = Map.Map Option.T [String]+++instance Semigroup Script where+   Script b0 <> Script b1 = Script (liftM2 (<>) b0 b1)++{-+Could also be implemented with Control.Monad.Trans.State:+mappend = liftA2 mappend+-}+instance Monoid Script where+   mempty = Script $ return mempty+   mappend = (<>)++instance Semigroup Body where+   Body f0 c0 <> Body f1 c1 = Body (f0 <> f1) (c0 <> c1)++{-+Could also be implemented with Control.Monad.Trans.State:+mappend = liftA2 mappend+-}+instance Monoid Body where+   mempty = Body mempty mempty+   mappend = (<>)++class C gfx where+   toScript :: gfx -> Script
+ src/Graphics/Gnuplot/Private/Encoding.hs view
@@ -0,0 +1,11 @@+module Graphics.Gnuplot.Private.Encoding where++import Graphics.Gnuplot.Utility (listFromMaybeWith)++newtype T = Cons String++format :: T -> String+format (Cons enc) = "set encoding " ++ enc++formatMaybe :: Maybe T -> [String]+formatMaybe = listFromMaybeWith format
+ src/Graphics/Gnuplot/Private/File.hs view
@@ -0,0 +1,4 @@+module Graphics.Gnuplot.Private.File where++class C file where+   write :: file -> IO ()
src/Graphics/Gnuplot/Private/Frame.hs view
@@ -3,11 +3,10 @@ import qualified Graphics.Gnuplot.Private.Plot as Plot import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet -import qualified Graphics.Gnuplot.Display as Display+import qualified Graphics.Gnuplot.Private.Display as Display import qualified Graphics.Gnuplot.Private.Graph as Graph -import qualified Data.Monoid.State as State-import Data.Monoid (Monoid, mappend, )+import Data.Monoid (mappend, )   data T graph =@@ -18,11 +17,6 @@  instance Graph.C graph => Display.C (T graph) where    toScript frame =-      (Display.Script $-         State.Cons $ \(n, opts0) ->-            let opts1 = option frame-            in  (Display.Body [] $-                 OptionSet.diffToString (OptionSet.Cons opts0) opts1,-                 (n, OptionSet.decons opts1)))+      (Plot.optionsToScript $ option frame)       `mappend`-      (Display.toScript $ plot frame)+      (Plot.toScript $ plot frame)
src/Graphics/Gnuplot/Private/FrameOption.hs view
@@ -1,27 +1,106 @@+{- |+If you add a new option,+please mind to add a default value to FrameOptionSet.deflt, too.+-} module Graphics.Gnuplot.Private.FrameOption where -newtype T = Cons String+{- |+Every option represents an internal state in gnuplot.+It is altered with gnuplot's set command.+The first field in 'T' is the name of the option+and the name of the according internal state in gnuplot.++Sometimes the addressed state is not explicitly mentioned+but is expressed by the syntax of the values.+E.g. you can write @set grid xtics@ and @set grid noxtics@,+but both commands refer to the same internal boolean variable,+that we like to call @xtics@.+It is important that the gnuplot Haskell bindings know+that these two set commands refer to the same gnuplot state,+since we want to simulate a stateless functional interface+in front of a stateful imperative one.++In case of a such a hidden state,+we manage an identifier in the second field of 'T'.+It is mainly used for distinguishing different hidden states,+that are accessed by the same @set@ variable.+This second field may not contain valid gnuplot identifiers,+however you might use the field for formatting boolean options+using 'Graphics.Gnuplot.Frame.OptionSet.addBool'.+-}+data T = Cons String String    deriving (Eq, Ord, Show) -custom :: String -> T+{- |+Constructs a generic option from Strings for the first and second field of 'T'.++This is very flexible, but not very safe.+Use it only as fall-back,+if there is no specific setter function in "Graphics.Gnuplot.Frame.OptionSet".+-}+custom :: String -> String -> T custom = Cons -title  :: T; title  = Cons "title"-grid   :: T; grid   = Cons "grid"-size   :: T; size   = Cons "size"-key    :: T; key    = Cons "key"-border :: T; border = Cons "border"-pm3d   :: T; pm3d   = Cons "pm3d"-view   :: T; view   = Cons "view"+grid   :: String -> T; grid   = Cons "grid"+size   :: String -> T; size   = Cons "size"+key    :: String -> T; key    = Cons "key"+border :: String -> T; border = Cons "border"+pm3d   :: String -> T; pm3d   = Cons "pm3d" -xRange :: T; xRange = Cons "xrange"-yRange :: T; yRange = Cons "yrange"-zRange :: T; zRange = Cons "zrange"+xRange :: String -> T; xRange = Cons "xrange"+yRange :: String -> T; yRange = Cons "yrange"+zRange :: String -> T; zRange = Cons "zrange" -xLabel :: T; xLabel = Cons "xlabel"-yLabel :: T; yLabel = Cons "ylabel"-zLabel :: T; zLabel = Cons "zlabel"+xLabel :: String -> T; xLabel = Cons "xlabel"+yLabel :: String -> T; yLabel = Cons "ylabel"+zLabel :: String -> T; zLabel = Cons "zlabel" -xTicks :: T; xTicks = Cons "xtics"-yTicks :: T; yTicks = Cons "ytics"-zTicks :: T; zTicks = Cons "ztics"+xTicks :: String -> T; xTicks = Cons "xtics"+yTicks :: String -> T; yTicks = Cons "ytics"+zTicks :: String -> T; zTicks = Cons "ztics"++xLogScale :: T; xLogScale = Cons "logscale x" ""+yLogScale :: T; yLogScale = Cons "logscale y" ""+zLogScale :: T; zLogScale = Cons "logscale z" ""+++title :: T; title = Cons "title" ""+view  :: T; view  = Cons "view" ""++xFormat :: T; xFormat = Cons "format x" ""+yFormat :: T; yFormat = Cons "format y" ""+zFormat :: T; zFormat = Cons "format z" ""++timeFmt :: T; timeFmt = Cons "timefmt" ""++xData :: T; xData = Cons "xdata" ""+yData :: T; yData = Cons "ydata" ""+zData :: T; zData = Cons "zdata" ""+++sizeScale :: T; sizeScale = size "scale"+sizeRatio :: T; sizeRatio = size "ratio"+keyShow     :: T; keyShow     = key "show"+keyPosition :: T; keyPosition = key "position"++xRangeBounds :: T; xRangeBounds = xRange "bounds"+yRangeBounds :: T; yRangeBounds = yRange "bounds"+zRangeBounds :: T; zRangeBounds = zRange "bounds"++xLabelText :: T; xLabelText = xLabel "text"+yLabelText :: T; yLabelText = yLabel "text"+zLabelText :: T; zLabelText = zLabel "text"++xTickLabels :: T; xTickLabels = xTicks "labels"+yTickLabels :: T; yTickLabels = yTicks "labels"+zTickLabels :: T; zTickLabels = zTicks "labels"++gridXTicks :: T; gridXTicks = grid "xtics"+gridYTicks :: T; gridYTicks = grid "ytics"+gridZTicks :: T; gridZTicks = grid "ztics"++boxwidth :: T; boxwidth = Cons "boxwidth" ""++styleFillSolid  :: T; styleFillSolid  = Cons "style fill" "solid"+styleFillBorder :: T; styleFillBorder = Cons "style fill" "border"+styleHistogram  :: T; styleHistogram  = Cons "style histogram" ""
src/Graphics/Gnuplot/Private/FrameOptionSet.hs view
@@ -11,6 +11,7 @@ module Graphics.Gnuplot.Private.FrameOptionSet where  import qualified Graphics.Gnuplot.Private.FrameOption as Option+import Graphics.Gnuplot.Utility (formatBool, )  import qualified Data.Map as Map @@ -18,33 +19,57 @@ import Data.Maybe (mapMaybe, )  +type Plain = Map.Map Option.T [String]+ newtype T graph =-   Cons {decons :: Map.Map Option.T [String]}+   Cons {decons :: Plain} + {- | The default options contain what we expect as default value in gnuplot.-We need an entry for every option-that cannot be reset by @unset@.+We need an entry for every option that cannot be reset by @unset@. -}-deflt :: T graph+deflt :: Plain deflt =-   Cons $ Map.fromList $-   (Option.key, []) :-   (Option.border, []) :-   (Option.xLabel, []) :-   (Option.yLabel, []) :-   (Option.zLabel, []) :-   (Option.xRange, ["[*:*]"]) :-   (Option.yRange, ["[*:*]"]) :-   (Option.zRange, ["[*:*]"]) :-   (Option.xTicks, []) :-   (Option.yTicks, []) :-   (Option.zTicks, []) :+   Map.fromList $+   (Option.keyShow, []) :+--   (Option.border, []) :+   (Option.sizeRatio, ["noratio"]) :+   (Option.xLabelText, []) :+   (Option.yLabelText, []) :+   (Option.zLabelText, []) :+   (Option.xRangeBounds, ["[*:*]"]) :+   (Option.yRangeBounds, ["[*:*]"]) :+   (Option.zRangeBounds, ["[*:*]"]) :+   (Option.xFormat, []) :+   (Option.yFormat, []) :+   (Option.zFormat, []) :+   (Option.xTickLabels, []) :+   (Option.yTickLabels, []) :+   (Option.zTickLabels, []) :+   (Option.gridXTicks, ["noxtics"]) :+   (Option.gridYTicks, ["noytics"]) :+   (Option.gridZTicks, ["noztics"]) :+   (Option.styleFillSolid, ["0"]) :+   (Option.styleFillBorder, []) :+   (Option.styleHistogram, ["clustered"]) :+--   (Option.timeFmt, [quote "%s"]) :+   (Option.boxwidth, []) :    [] +initial :: Plain+initial =+   flip Map.union deflt $+   Map.fromList $+   (Option.xData, []) :+   (Option.yData, []) :+   (Option.zData, []) :+--   (Option.timeFmt, []) :+   []  {- |-Add an option with arguments as plain strings.+Add (set) an option with arguments as plain strings.+ This is very flexible, but not very safe. Use it only as fall-back, if there is no specific setter function in "Graphics.Gnuplot.Frame.OptionSet".@@ -54,7 +79,11 @@    Cons (Map.insert opt args m)  {- |-Remove an option.+Remove (unset) an option.++This is very flexible, but not very safe.+Use it only as fall-back,+if there is no specific setter function in "Graphics.Gnuplot.Frame.OptionSet". -} remove :: Option.T -> T graph -> T graph remove opt (Cons m) =@@ -64,17 +93,49 @@ Convert the difference between the first and the second option set into a sequence of 'set' and 'unset' commands. -}-diffToString :: T graph -> T graph -> [String]-diffToString (Cons m0) (Cons m1) =+diffToString :: Plain -> Plain -> [String]+diffToString m0 m1 =    mapMaybe-      (\(Option.Cons opt, (old,new)) ->+      (\(Option.Cons opt _, (old,new)) ->          toMaybe (old/=new) $          maybe             ("unset " ++ opt)-            (\args -> "set " ++ opt ++ " " ++ unwords args)+            (\args -> "set " ++ opt ++ concatMap (' ':) args)             new) $    Map.toList $    Map.unionWith       (\(old,_) (_,new) -> (old,new))       (fmap (\x -> (Just x, Nothing)) m0)       (fmap (\x -> (Nothing, Just x)) m1)++{- |+Set or unset option according to a 'Bool'.+This is for switches that can be disabled using @unset@.++This is very flexible, but not very safe.+Use it only as fall-back,+if there is no specific setter function in "Graphics.Gnuplot.Frame.OptionSet".++See also: 'addBool', 'add', 'remove'.+-}+boolean :: Option.T -> Bool -> T graph -> T graph+boolean opt on =+   if on+     then add opt []+     else remove opt++{- |+Add an option with boolean value+that is formatted like @set style fill border@ and @set style fill noborder@.+The name of the internal state (i.e. @border@)+must be stored in the second field of the option.++This is very flexible, but not very safe.+Use it only as fall-back,+if there is no specific setter function in "Graphics.Gnuplot.Frame.OptionSet".++See also 'boolean'.+-}+addBool :: Option.T -> Bool -> T graph -> T graph+addBool opt@(Option.Cons _ state) arg =+   add opt [formatBool state arg]
src/Graphics/Gnuplot/Private/Graph.hs view
@@ -1,5 +1,10 @@ module Graphics.Gnuplot.Private.Graph where +import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet+ class C graph where-   command :: graph -> String+   command :: Command graph    toString :: graph -> String+   defltOptions :: OptionSet.T graph++newtype Command graph = Command {commandString :: String}
src/Graphics/Gnuplot/Private/Graph2D.hs view
@@ -1,53 +1,82 @@ module Graphics.Gnuplot.Private.Graph2D where +import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet+import qualified Graphics.Gnuplot.Private.FrameOption as Option import qualified Graphics.Gnuplot.Private.LineSpecification as LineSpec-import qualified Graphics.Gnuplot.Private.GraphType as GraphType+import qualified Graphics.Gnuplot.Private.Graph2DType as GraphType import qualified Graphics.Gnuplot.Private.Graph as Graph+import qualified Graphics.Gnuplot.Value.Atom as Atom+import qualified Data.Map as Map+import qualified Data.List as List  import Prelude hiding (lines, )  -data T =+data T x y =    Cons {-      column_   :: Column,+      column_   :: Columns,       type_     :: Type,       lineSpec_ :: LineSpec.T    } -data Column =-     Dim1 {columnX :: Int}-   | Dim2 {columnX, columnY :: Int}-+type Columns = [Int] -type Type = GraphType.T+type Type = String  -columnToString :: Column -> String-columnToString c =-   case c of-      Dim1 x -> show x-      Dim2 x y -> show x ++ ":" ++ show y+columnToString :: Columns -> String+columnToString =+   concat . List.intersperse ":" . map show -toString :: T -> String+toString :: T x y -> String toString (Cons c t l) =    "using " ++ columnToString c ++-   " with " ++ GraphType.toString t +++   " with " ++ t ++    " " ++ LineSpec.toString l -instance Graph.C T where-   command _ = "plot"-   toString = toString +type AxisOption x y a =+   OptionSet.T (T x y) -> Atom.OptionSet a -defaultType :: Type-defaultType = GraphType.lines+defltOptions :: (Atom.C x, Atom.C y) => OptionSet.T (T x y)+defltOptions =+   let mk ::+          Option.T -> Option.T ->+          Atom.OptionSet a -> [(Option.T, [String])]+       mk optData optFormat opts =+          (optData, Atom.optData opts) :+          (optFormat, Atom.optFormat opts) :+          Atom.optOthers opts+       result ::+          Atom.OptionSet x ->+          Atom.OptionSet y ->+          OptionSet.T (T x y)+       result optX optY =+          OptionSet.Cons $+          flip Map.union OptionSet.deflt $+          Map.fromList $+          mk Option.xData Option.xFormat optX +++          mk Option.yData Option.yFormat optY +++          (Option.zData, []) :+          (Option.zFormat, []) :+          []+   in  result Atom.options Atom.options -deflt :: Column -> T-deflt c = Cons c defaultType LineSpec.deflt +instance (Atom.C x, Atom.C y) => Graph.C (T x y) where+   command = Graph.Command "plot"+   toString = toString+   defltOptions = defltOptions -typ :: Type -> T -> T++deflt :: GraphType.T x y a -> Columns -> T x y+deflt t c = Cons c (GraphType.toString t) LineSpec.deflt++typ :: Type -> T x y -> T x y typ t gr = gr{type_ = t} -lineSpec :: LineSpec.T -> T -> T+{- |+You can alter the line specification of graphs in a plot using 'fmap'.+-}+lineSpec :: LineSpec.T -> T x y -> T x y lineSpec ls gr = gr{lineSpec_ = ls}
+ src/Graphics/Gnuplot/Private/Graph2DType.hs view
@@ -0,0 +1,125 @@+module Graphics.Gnuplot.Private.Graph2DType where++import qualified Graphics.Gnuplot.Value.Atom as Atom+import qualified Graphics.Gnuplot.Value.Tuple as Tuple+import Graphics.Gnuplot.Value.Tuple (Label)+import Prelude hiding (lines, )+++{- |+The type parameter @x@ is for the values on the X axis,+@y@ of the Y axis and+@a@ is the type of the plotted data.+The type @a@ is a pair in case of points in the plane,+or a more complex tuple in case of error plots and the like.+-}+newtype T x y a = Cons String++tupleSize :: (Tuple.C a) => T x y a -> Tuple.ColumnCount a+tupleSize _ = Tuple.columnCount+++{-+See info:/gnuplot/set_style_rectangle+-}++listLines       :: (Atom.C y) => T Int y y+listPoints      :: (Atom.C y) => T Int y y+listLinesPoints :: (Atom.C y) => T Int y y+listImpulses    :: (Atom.C y) => T Int y y+listDots        :: (Atom.C y) => T Int y y+histograms      :: (Atom.C y) => T Int y y++xErrorBarsRelative   :: (Atom.C x, Atom.C y) => T x y ((x,y),x)+yErrorBarsRelative   :: (Atom.C x, Atom.C y) => T x y ((x,y),y)+xyErrorBarsRelative  :: (Atom.C x, Atom.C y) => T x y ((x,y),(x,y))+xErrorBarsAbsolute   :: (Atom.C x, Atom.C y) => T x y ((x,y),(x,x))+yErrorBarsAbsolute   :: (Atom.C x, Atom.C y) => T x y ((x,y),(y,y))+xyErrorBarsAbsolute  :: (Atom.C x, Atom.C y) => T x y ((x,y),((x,x),(y,y)))++xErrorLinesRelative  :: (Atom.C x, Atom.C y) => T x y ((x,y),x)+yErrorLinesRelative  :: (Atom.C x, Atom.C y) => T x y ((x,y),y)+xyErrorLinesRelative :: (Atom.C x, Atom.C y) => T x y ((x,y),(x,y))+xErrorLinesAbsolute  :: (Atom.C x, Atom.C y) => T x y ((x,y),(x,x))+yErrorLinesAbsolute  :: (Atom.C x, Atom.C y) => T x y ((x,y),(y,y))+xyErrorLinesAbsolute :: (Atom.C x, Atom.C y) => T x y ((x,y),((x,x),(y,y)))++lines          :: (Atom.C x, Atom.C y) => T x y (x,y)+points         :: (Atom.C x, Atom.C y) => T x y (x,y)+linesPoints    :: (Atom.C x, Atom.C y) => T x y (x,y)+impulses       :: (Atom.C x, Atom.C y) => T x y (x,y)+dots           :: (Atom.C x, Atom.C y) => T x y (x,y)+steps          :: (Atom.C x, Atom.C y) => T x y (x,y)+fSteps         :: (Atom.C x, Atom.C y) => T x y (x,y)+hiSteps        :: (Atom.C x, Atom.C y) => T x y (x,y)+errorBars      :: (Atom.C x, Atom.C y) => T x y (x,y)+errorLines     :: (Atom.C x, Atom.C y) => T x y (x,y)+boxes          :: (Atom.C x, Atom.C y) => T x y (x,y)+filledCurves   :: (Atom.C x, Atom.C y) => T x y (x,y)+{-+boxErrorBars   :: (Atom.C x, Atom.C y) => T x y (x,y)+boxXYErrorBars :: (Atom.C x, Atom.C y) => T x y (x,y)+-}+financeBars    :: (Atom.C x, Atom.C y) => T x y (x,(y,y,y,y))+candleSticks   :: (Atom.C x, Atom.C y) => T x y (x,(y,y,y,y))+vectors        :: (Atom.C x, Atom.C y) => T x y ((x,y),(x,y))+image          :: (Atom.C x, Atom.C y, Atom.C z) => T x y ((x, y), z)++filledStripe      :: (Atom.C x, Atom.C y) => T x y (x,(y,y))+filledStripeAbove :: (Atom.C x, Atom.C y) => T x y (x,(y,y))+filledStripeBelow :: (Atom.C x, Atom.C y) => T x y (x,(y,y))++labels          :: (Atom.C x, Atom.C y) => T x y ((x,y),Label)+++listLines       = Cons "lines"+listPoints      = Cons "points"+listLinesPoints = Cons "linespoints"+listImpulses    = Cons "impulses"+listDots        = Cons "dots"+histograms      = Cons "histograms"++xErrorBarsRelative   = Cons "xerrorbars"+yErrorBarsRelative   = Cons "yerrorbars"+xyErrorBarsRelative  = Cons "xyerrorbars"+xErrorBarsAbsolute   = Cons "xerrorbars"+yErrorBarsAbsolute   = Cons "yerrorbars"+xyErrorBarsAbsolute  = Cons "xyerrorbars"++xErrorLinesRelative  = Cons "xerrorlines"+yErrorLinesRelative  = Cons "yerrorlines"+xyErrorLinesRelative = Cons "xyerrorlines"+xErrorLinesAbsolute  = Cons "xerrorlines"+yErrorLinesAbsolute  = Cons "yerrorlines"+xyErrorLinesAbsolute = Cons "xyerrorlines"++lines          = Cons "lines"+points         = Cons "points"+linesPoints    = Cons "linespoints"+impulses       = Cons "impulses"+dots           = Cons "dots"+steps          = Cons "steps"+fSteps         = Cons "fsteps"+hiSteps        = Cons "histeps"+errorBars      = Cons "errorbars"+errorLines     = Cons "errorlines"+boxes          = Cons "boxes"+filledCurves   = Cons "filledcurves"+{-+boxErrorBars   = Cons "boxerrorbars"+boxXYErrorBars = Cons "boxxyerrorbars"+-}+financeBars    = Cons "financebars"+candleSticks   = Cons "candlesticks"+vectors        = Cons "vectors"+image          = Cons "image"++filledStripe      = Cons "filledcurves"+filledStripeAbove = Cons "filledcurves above"+filledStripeBelow = Cons "filledcurves below"++labels       = Cons "labels"+++toString :: T x y a -> String+toString (Cons t) = t
src/Graphics/Gnuplot/Private/Graph3D.hs view
@@ -1,53 +1,93 @@ module Graphics.Gnuplot.Private.Graph3D where +import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet+import qualified Graphics.Gnuplot.Private.FrameOption as Option import qualified Graphics.Gnuplot.Private.LineSpecification as LineSpec-import qualified Graphics.Gnuplot.Private.GraphType as GraphType+import qualified Graphics.Gnuplot.Private.Graph3DType as GraphType import qualified Graphics.Gnuplot.Private.Graph as Graph+import qualified Graphics.Gnuplot.Value.Atom as Atom+import qualified Data.Map as Map +import Graphics.Gnuplot.Private.Graph2D (Columns, columnToString, )+ import Prelude hiding (lines, )  -data T =+data T x y z =    Cons {-      column_   :: Column,+      column_   :: Columns,       type_     :: Type,       lineSpec_ :: LineSpec.T    } -data Column =-     Dim3 {columnX, columnY, columnZ :: Int}-   | Dim4 {columnX, columnY, columnZ, columnC :: Int}---type Type = GraphType.T+type Type = String  -columnToString :: Column -> String-columnToString col =-   case col of-      Dim3 x y z -> show x ++ ":" ++ show y ++ ":" ++ show z-      Dim4 x y z c -> show x ++ ":" ++ show y ++ ":" ++ show z ++ ":" ++ show c--toString :: T -> String+toString :: T x y z -> String toString (Cons c t l) =    "using " ++ columnToString c ++-   " with " ++ GraphType.toString t +++   " with " ++ t ++    " " ++ LineSpec.toString l -instance Graph.C T where-   command _ = "splot"-   toString = toString +type AxisOption x y z a =+   OptionSet.T (T x y z) -> Atom.OptionSet a -defaultType :: Type-defaultType = GraphType.pm3d+defltOptions :: (Atom.C x, Atom.C y, Atom.C z) => OptionSet.T (T x y z)+defltOptions =+   let mk ::+          Option.T -> Option.T ->+          Atom.OptionSet a ->+          [(Option.T, [String])]+       mk optData optFormat opts =+          (optData, Atom.optData opts) :+          (optFormat, Atom.optFormat opts) :+          Atom.optOthers opts+       result ::+          Atom.OptionSet x ->+          Atom.OptionSet y ->+          Atom.OptionSet z ->+          OptionSet.T (T x y z)+       result optX optY optZ =+          OptionSet.Cons $+          flip Map.union OptionSet.deflt $+          Map.fromList $+          mk Option.xData Option.xFormat optX +++          mk Option.yData Option.yFormat optY +++          mk Option.yData Option.yFormat optZ +++          []+   in  result Atom.options Atom.options Atom.options -deflt :: Column -> T-deflt c = Cons c defaultType LineSpec.deflt +instance (Atom.C x, Atom.C y, Atom.C z) => Graph.C (T x y z) where+   command = Graph.Command "splot"+   toString = toString+   defltOptions = defltOptions -typ :: Type -> T -> T++pm3d :: T x y z+pm3d = Cons (1:2:3:[]) "pm3d" LineSpec.deflt++deflt :: GraphType.T x y z a -> Columns -> T x y z+deflt t c = Cons c (GraphType.toString t) LineSpec.deflt++typ :: Type -> T x y z -> T x y z typ t gr = gr{type_ = t} -lineSpec :: LineSpec.T -> T -> T+{-+for 3D plots not all line attributes are supported like:+   pointsize+   pointtype++pm3d and impulses allow:+   linestyle+   linewidth+   linecolor+   linetype+   title++FIXME:+Do we need a separate LineSpec3D type or a type parameter for LineSpec?+-}+lineSpec :: LineSpec.T -> T x y z -> T x y z lineSpec ls gr = gr{lineSpec_ = ls}
+ src/Graphics/Gnuplot/Private/Graph3DType.hs view
@@ -0,0 +1,38 @@+module Graphics.Gnuplot.Private.Graph3DType where++import qualified Graphics.Gnuplot.Value.Atom as Atom+import qualified Graphics.Gnuplot.Value.Tuple as Tuple++import Prelude hiding (lines, )+++newtype T x y z a = Cons String++tupleSize :: (Tuple.C a) => T x y z a -> Tuple.ColumnCount a+tupleSize _ = Tuple.columnCount+++lines          :: (Atom.C x, Atom.C y, Atom.C z) => T x y z (x,y,z)+points         :: (Atom.C x, Atom.C y, Atom.C z) => T x y z (x,y,z)++lines          = Cons "lines"+points         = Cons "points"+++{-+See info:/gnuplot/set_style_rectangle+-}++impulses       :: (Atom.C x, Atom.C y, Atom.C z) => T x y z (x,y,z)+vectors        :: (Atom.C x, Atom.C y, Atom.C z) => T x y z ((x,y,z), (x,y,z))+pm3d           :: (Atom.C x, Atom.C y, Atom.C z) => T x y z (x,y,z)++impulses       = Cons "impulses"+vectors        = Cons "vectors"+pm3d           = Cons "pm3d"++{-# DEPRECATED pm3d "do not use this as graph type, use Graphics.Gnuplot.Plot.ThreeDimensional.surface instead" #-}+++toString :: T x y z a -> String+toString (Cons t) = t
src/Graphics/Gnuplot/Private/GraphEmpty.hs view
@@ -7,11 +7,14 @@ module Graphics.Gnuplot.Private.GraphEmpty where  import qualified Graphics.Gnuplot.Private.Graph as Graph+import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet   data T = Cons   instance Graph.C T where-   command _ = "clear"+   command = Graph.Command "clear"    toString = const ""+   defltOptions =+      OptionSet.Cons OptionSet.deflt
− src/Graphics/Gnuplot/Private/GraphType.hs
@@ -1,61 +0,0 @@-module Graphics.Gnuplot.Private.GraphType where--import Prelude hiding (lines, )---newtype T = Cons String---lines          :: T-points         :: T-linesPoints    :: T-impulses       :: T-dots           :: T-steps          :: T-fSteps         :: T-hiSteps        :: T-errorBars      :: T-xErrorBars     :: T-yErrorBars     :: T-xyErrorBars    :: T-errorLines     :: T-xErrorLines    :: T-yErrorLines    :: T-xyErrorLines   :: T-boxes          :: T-filledCurves   :: T-boxErrorBars   :: T-boxXYErrorBars :: T-financeBars    :: T-candleSticks   :: T-vectors        :: T-pm3d           :: T--lines          = Cons "lines"-points         = Cons "points"-linesPoints    = Cons "linespoints"-impulses       = Cons "impulses"-dots           = Cons "dots"-steps          = Cons "steps"-fSteps         = Cons "fsteps"-hiSteps        = Cons "histeps"-errorBars      = Cons "errorbars"-xErrorBars     = Cons "xerrorbars"-yErrorBars     = Cons "yerrorbars"-xyErrorBars    = Cons "xyerrorbars"-errorLines     = Cons "errorlines"-xErrorLines    = Cons "xerrorlines"-yErrorLines    = Cons "yerrorlines"-xyErrorLines   = Cons "xyerrorlines"-boxes          = Cons "boxes"-filledCurves   = Cons "filledcurves"-boxErrorBars   = Cons "boxerrorbars"-boxXYErrorBars = Cons "boxxyerrorbars"-financeBars    = Cons "financebars"-candleSticks   = Cons "candlesticks"-vectors        = Cons "vectors"-pm3d           = Cons "pm3d"---toString :: T -> String-toString (Cons t) = t
src/Graphics/Gnuplot/Private/LineSpecification.hs view
@@ -1,5 +1,6 @@ module Graphics.Gnuplot.Private.LineSpecification where +import qualified Graphics.Gnuplot.Private.ColorSpecification as Color import Data.Maybe (catMaybes, ) import Graphics.Gnuplot.Utility (quote, ) @@ -14,6 +15,7 @@       { lineStyle_ :: Maybe Int       , lineType_  :: Maybe Int       , lineWidth_ :: Maybe Double+      , lineColor_ :: Maybe Color.T       , pointType_ :: Maybe Int       , pointSize_ :: Maybe Double       , title_     :: Maybe String@@ -25,6 +27,7 @@       { lineStyle_ = Nothing       , lineType_  = Nothing       , lineWidth_ = Nothing+      , lineColor_ = Nothing       , pointType_ = Nothing       , pointSize_ = Nothing       , title_     = Nothing@@ -39,6 +42,9 @@ lineWidth :: Double -> T -> T lineWidth x ls = ls{lineWidth_ = Just x} +lineColor :: Color.T -> T -> T+lineColor x ls = ls{lineColor_ = Just x}+ pointType :: Int -> T -> T pointType x ls = ls{pointType_ = Just x} @@ -54,10 +60,11 @@    let showField :: String -> (a -> String) -> (T -> Maybe a) -> Maybe [String]        showField s f access = fmap (\a -> [s, f a]) $ access linespec    in  unwords $ concat $ catMaybes $+       showField "linestyle" show  lineStyle_ :        showField "linetype"  show  lineType_  :        showField "linewidth" show  lineWidth_ :+       showField "linecolor" Color.toString lineColor_ :        showField "pointtype" show  pointType_ :        showField "pointsize" show  pointSize_ :        showField "title"     quote title_     :-       showField "linestyle" show  lineStyle_ :        []
src/Graphics/Gnuplot/Private/Plot.hs view
@@ -1,39 +1,66 @@ module Graphics.Gnuplot.Private.Plot where -import qualified Data.Monoid.State as State-import Data.Monoid (Monoid, mempty, mappend, )--import qualified Graphics.Gnuplot.Display as Display+import qualified Graphics.Gnuplot.Private.Display as Display+import qualified Graphics.Gnuplot.Private.FrameOptionSet as OptionSet import qualified Graphics.Gnuplot.Private.Graph as Graph+import qualified Graphics.Gnuplot.Private.File as FileClass+import qualified Graphics.Gnuplot.File as File import Graphics.Gnuplot.Utility (quote, commaConcat, ) -import Data.Maybe (mapMaybe, )+import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS+import qualified Control.Monad.Trans.Class as MT+import qualified Data.Accessor.Monad.Trans.State as AccState+import qualified Data.Accessor.Tuple as AccTuple+import qualified Data.Foldable as Fold+import Control.Monad (liftM2, return, )+import Data.Monoid (Monoid, mempty, mappend, )+import Data.Semigroup (Semigroup, (<>), )+import Data.Maybe (Maybe(Just, Nothing), mapMaybe, )+import Data.List (concatMap, map, (++), )+import Data.Function (($), (.), )  +import qualified System.FilePath as Path+import System.FilePath (FilePath, (</>), )++import Prelude (Functor, fmap, String, show, Int, succ, writeFile, )++ {- |-Plots can be assembled using 'mappend' or 'mconcat'.+Plots can be assembled using 'mappend' or 'mconcat'+or several functions from "Data.Foldable". -}-newtype T graph = Cons (State.T Int [File graph])+newtype T graph = Cons (MS.StateT Int (MR.Reader FilePath) [File graph]) +pure :: [File graph] -> T graph+pure = Cons . return++instance Semigroup (T graph) where+   Cons s0 <> Cons s1 = Cons (liftM2 (<>) s0 s1)+ {- Could also be implemented with Control.Monad.Trans.State: mappend = liftA2 mappend -} instance Monoid (T graph) where-   mempty = Cons mempty-   mappend (Cons s0) (Cons s1) =-      Cons (mappend s0 s1)+   mempty = Cons $ return mempty+   mappend = (<>)   withUniqueFile :: String -> [graph] -> T graph-withUniqueFile content graphs =-   Cons (State.Cons $ \n ->-      ([File (tmpFileStem ++ show n ++ ".csv") (Just content) graphs],-       succ n))+withUniqueFile content graphs = Cons $ do+   n <- MS.get+   dir <- MT.lift MR.ask+   MS.put $ succ n+   return $+      [File+         (dir </> Path.addExtension (tmpFileStem ++ show n) "csv")+         (Just content) graphs]  fromGraphs :: FilePath -> [graph] -> T graph fromGraphs name gs =-   Cons (State.pure [File name Nothing gs])+   pure [File name Nothing gs]   data File graph =@@ -43,9 +70,9 @@       graphs_ :: [graph]    } -writeData :: File graph -> IO ()-writeData (File fn cont _) =-   maybe (return ()) (writeFile fn) cont+instance FileClass.C (File graph) where+   write (File fn cont _) =+      Fold.mapM_ (writeFile fn) cont   tmpFileStem :: FilePath@@ -63,24 +90,48 @@       fmap (map (\file -> file{graphs_ = map f $ graphs_ file}))       mp +{- |+In contrast to the Display.toScript method instantiation+this function leaves the options,+and thus can be used to write the Display.toScript instance for Frame.+-}+toScript :: Graph.C graph => T graph -> Display.Script+toScript p@(Cons mp) =+   Display.Script $ do+      blocks <- AccState.liftT AccTuple.first mp+      let files =+             mapMaybe+                (\blk -> fmap (File.Cons (filename_ blk)) (content_ blk))+                blocks+          graphs =+             concatMap+                (\blk ->+                   map+                      (\gr ->+                         quote (filename_ blk) ++ " " +++                         Graph.toString gr) $ graphs_ blk) $+             blocks+      return $+         Display.Body files+            [Graph.commandString (plotCmd p) ++ " " ++ commaConcat graphs]++optionsToScript :: Graph.C graph => OptionSet.T graph -> Display.Script+optionsToScript opts =+   Display.Script $+   AccState.liftT AccTuple.second $ do+      opts0 <- MS.get+      let opts1 = OptionSet.decons opts+      MS.put opts1+      return $+         Display.Body [] $+         OptionSet.diffToString opts0 opts1++defltOpts :: Graph.C graph => T graph -> OptionSet.T graph+defltOpts _ = Graph.defltOptions+ instance Graph.C graph => Display.C (T graph) where-   toScript p@(Cons mp) =-      Display.Script $ State.Cons $-         \(n0, opts) ->-            let (blocks, n1) = State.run mp n0-                files =-                   mapMaybe-                      (\blk -> fmap (Display.File (filename_ blk)) (content_ blk))-                      blocks-                graphs =-                   concatMap (\blk ->-                      map (\gr -> quote (filename_ blk) ++ " " ++ Graph.toString gr) $ graphs_ blk) $-                      blocks-            in  (Display.Body files-                    [plotCmd p undefined ++ " " ++ commaConcat graphs],-                 (n1, opts))+   toScript plot =+      optionsToScript (defltOpts plot)  `mappend`  toScript plot -plotCmd ::-   Graph.C graph =>-   T graph -> graph -> String+plotCmd :: Graph.C graph => T graph -> Graph.Command graph plotCmd _plot = Graph.command
+ src/Graphics/Gnuplot/Private/Terminal.hs view
@@ -0,0 +1,19 @@+module Graphics.Gnuplot.Private.Terminal where++data T =+   Cons {+      precommands :: [String],+      options :: [String],+      commands :: [String],+      interactive :: Bool+   }++class C terminal where+   canonical :: terminal -> T++format :: T -> [String]+format (Cons pre opts cmds _ia) =+   pre +++   if null opts+     then cmds+     else (unwords $ "set" : "terminal" : opts) : cmds
src/Graphics/Gnuplot/Simple.hs view
@@ -5,6 +5,10 @@ instead we provide an advanced modularized interface in "Graphics.Gnuplot.Advanced". +Here is a pretty simple example:++> Graphics.Gnuplot.Simple> plotFunc [] (linearScale 1000 (-10,10::Double)) sin+ This was formerly part of the htam package. -} module Graphics.Gnuplot.Simple (@@ -51,27 +55,34 @@ import qualified Graphics.Gnuplot.Plot.ThreeDimensional as Plot3D import qualified Graphics.Gnuplot.Private.LineSpecification as LineSpec import qualified Graphics.Gnuplot.Private.Graph2D as Graph2D-import qualified Graphics.Gnuplot.Private.Graph3D as Graph3D-import qualified Graphics.Gnuplot.Private.GraphType as GraphType+import qualified Graphics.Gnuplot.Private.Graph2DType as GraphType+import qualified Graphics.Gnuplot.Private.Graph as Graph import qualified Graphics.Gnuplot.Private.Plot as Plot +import qualified Graphics.Gnuplot.Value.Tuple as Tuple+import qualified Graphics.Gnuplot.Value.Atom as Atom+ {- import qualified Graphics.Gnuplot.Terminal.PostScript as PS import qualified Graphics.Gnuplot.Terminal.PNG as PNG import qualified Graphics.Gnuplot.Terminal.SVG as SVG -} -import qualified Graphics.Gnuplot.Terminal as Terminal-import qualified Graphics.Gnuplot.Execute as Exec+import qualified Graphics.Gnuplot.Private.Terminal as Terminal -import System.Cmd (rawSystem, ) import Graphics.Gnuplot.Utility-   (quote, commaConcat, showTriplet, linearScale, )-import qualified Data.Monoid.State as State+   (quote, commaConcat, semiColonConcat, showTriplet, linearScale, )++import qualified Control.Monad.Trans.Reader as MR+import qualified Control.Monad.Trans.State as MS++import qualified Graphics.Gnuplot.Private.Command as Cmd+import System.Process (rawSystem, )+import Control.Functor.HT (void, )++import qualified Data.List.Reverse.StrictElement as ListRev+import Data.Foldable (foldMap, ) import Data.Maybe (listToMaybe, mapMaybe, isNothing, )-import Data.List.HT (dropWhileRev, )-import Data.List (intersperse, )-import Data.Monoid (mconcat, )   -- * User front-end@@ -93,6 +104,7 @@    | Title  String    | XLabel String    | YLabel String+   | ZLabel String    | XRange (Double, Double)    | YRange (Double, Double)    | ZRange (Double, Double)@@ -109,8 +121,23 @@      Ratio Double    | NoRatio -{- The Int types would be better enumerations-   but their interpretations depend on the gnuplot output type. :-( -}+{- |+Be careful with 'LineTitle'+which can only be used as part of gnuplot's @plot@ command+but not as part of @set@.+That is,++> plotList [LineStyle 0 [LineTitle "foobar"]] [0,5..100::Double]++will leave you with an invalid gnuplot script, whereas++> plotListStyle [] (defaultStyle {lineSpec = CustomStyle [LineTitle "foobar"]}) [0,5..100::Double]++does what you want.++The 'Int' types would be better enumerations+but their interpretations depend on the gnuplot output type. :-(+-} data LineAttr =      LineType  Int    | LineWidth Double@@ -163,75 +190,109 @@  -- * plot functions +list :: (Tuple.C a) => [a] -> Plot2D.T Double Double+list = Plot2D.list (GraphType.Cons "lines")+-- list = Plot2D.list GraphType.listLines+ {- | > plotList [] (take 30 (let fibs = 0 : 1 : zipWith (+) fibs (tail fibs) in fibs)) -}-plotList :: Show a => [Attribute] -> [a] -> IO ()+plotList ::+   (Tuple.C a) =>+   [Attribute] -> [a] -> IO () plotList attrs =-   plot2d attrs . Plot2D.list+   plot2d attrs . list -plotListStyle :: Show a => [Attribute] -> PlotStyle -> [a] -> IO ()+{- |+> plotListStyle [] (defaultStyle{plotType = CandleSticks}) (Plot2D.functionToGraph (linearScale 32 (0,2*pi::Double)) (\t -> (-sin t, -2*sin t, 2*sin t, sin t)))+-}+plotListStyle ::+   (Tuple.C a) =>+   [Attribute] -> PlotStyle -> [a] -> IO () plotListStyle attrs style =-   plot2d attrs . setPlotStyle style . Plot2D.list+   plot2d attrs . setPlotStyle style . list -plotLists :: Show a => [Attribute] -> [[a]] -> IO ()+plotLists ::+   (Tuple.C a) =>+   [Attribute] -> [[a]] -> IO () plotLists attrs xss =-   plot2d attrs (mconcat $ map Plot2D.list xss)+   plot2d attrs (foldMap list xss) -plotListsStyle :: Show a => [Attribute] -> [(PlotStyle, [a])] -> IO ()+plotListsStyle ::+   (Tuple.C a) =>+   [Attribute] -> [(PlotStyle, [a])] -> IO () plotListsStyle attrs =-   plot2d attrs . mconcat .-   map (\(style,xs) -> setPlotStyle style $ Plot2D.list xs)+   plot2d attrs .+   foldMap (\(style,xs) -> setPlotStyle style $ list xs)  {- | > plotFunc [] (linearScale 1000 (-10,10)) sin -}-plotFunc :: Show a => [Attribute] -> [a] -> (a -> a) -> IO ()+plotFunc ::+   (Atom.C a, Tuple.C a) =>+   [Attribute] -> [a] -> (a -> a) -> IO () plotFunc attrs args f =-   plot2d attrs (Plot2D.function args f)+   plot2d attrs (Plot2D.function GraphType.lines args f)  {- | > plotFuncs [] (linearScale 1000 (-10,10)) [sin, cos] -}-plotFuncs :: Show a => [Attribute] -> [a] -> [a -> a] -> IO ()+plotFuncs ::+   (Atom.C a, Tuple.C a) =>+   [Attribute] -> [a] -> [a -> a] -> IO () plotFuncs attrs args fs =-   plot2d attrs (Plot2D.functions args fs)+   plot2d attrs (Plot2D.functions GraphType.lines args fs) -plotPath :: Show a => [Attribute] -> [(a,a)] -> IO ()+plotPath ::+   (Tuple.C a) =>+   [Attribute] -> [(a,a)] -> IO () plotPath attrs =-   plot2d attrs . Plot2D.path+   plot2d attrs . list -plotPaths :: Show a => [Attribute] -> [[(a,a)]] -> IO ()+plotPaths ::+   (Tuple.C a) =>+   [Attribute] -> [[(a,a)]] -> IO () plotPaths attrs xss =-   plot2d attrs (mconcat $ map Plot2D.path xss)+   plot2d attrs (foldMap list xss) -plotPathStyle :: Show a => [Attribute] -> PlotStyle -> [(a,a)] -> IO ()+plotPathStyle ::+   (Tuple.C a) =>+   [Attribute] -> PlotStyle -> [(a,a)] -> IO () plotPathStyle attrs style =-   plot2d attrs . setPlotStyle style . Plot2D.path+   plot2d attrs . setPlotStyle style . list -plotPathsStyle :: Show a => [Attribute] -> [(PlotStyle, [(a,a)])] -> IO ()+plotPathsStyle ::+   (Tuple.C a) =>+   [Attribute] -> [(PlotStyle, [(a,a)])] -> IO () plotPathsStyle attrs =-   plot2d attrs . mconcat .-   map (\(style,xs) -> setPlotStyle style $ Plot2D.path xs)+   plot2d attrs .+   foldMap (\(style,xs) -> setPlotStyle style $ list xs)  {- | > plotParamFunc [] (linearScale 1000 (0,2*pi)) (\t -> (sin (2*t), cos t)) -}-plotParamFunc :: Show a => [Attribute] -> [a] -> (a -> (a,a)) -> IO ()+plotParamFunc ::+   (Atom.C a, Tuple.C a) =>+   [Attribute] -> [a] -> (a -> (a,a)) -> IO () plotParamFunc attrs args f =-   plot2d attrs (Plot2D.parameterFunction args f)+   plot2d attrs (Plot2D.parameterFunction GraphType.lines args f)  {- | > plotParamFuncs [] (linearScale 1000 (0,2*pi)) [\t -> (sin (2*t), cos t), \t -> (cos t, sin (2*t))] -}-plotParamFuncs :: Show a => [Attribute] -> [a] -> [a -> (a,a)] -> IO ()+plotParamFuncs ::+   (Atom.C a, Tuple.C a) =>+   [Attribute] -> [a] -> [a -> (a,a)] -> IO () plotParamFuncs attrs args fs =-   plot2d attrs (mconcat $ map (Plot2D.parameterFunction args) fs)+   plot2d attrs $+   foldMap (Plot2D.parameterFunction GraphType.lines args) fs  -plotDots :: Show a => [Attribute] -> [(a,a)] -> IO ()+plotDots ::+   (Atom.C a, Tuple.C a) =>+   [Attribute] -> [(a,a)] -> IO () plotDots attrs xs =-   plot2d attrs (fmap (Graph2D.typ GraphType.dots) $ Plot2D.path xs)+   plot2d attrs (Plot2D.list GraphType.dots xs)   @@ -255,19 +316,25 @@  {- | > let xs = [-2,-1.8..2::Double] in plotMesh3d [] [] (do x <- xs; return (do y <- xs; return (x,y,cos(x*x+y*y))))++> let phis = linearScale 30 (-pi, pi :: Double) in plotMesh3d [] [] (do phi <- phis; return (do psi <- phis; let r = 5 + sin psi in return (r * cos phi, r * sin phi, cos psi))) -}-plotMesh3d :: (Show a, Show b, Show c) =>-   [Attribute] -> [Attribute3d] -> [[(a,b,c)]] -> IO ()+plotMesh3d ::+   (Atom.C x, Atom.C y, Atom.C z,+    Tuple.C x, Tuple.C y, Tuple.C z) =>+   [Attribute] -> [Attribute3d] -> [[(x,y,z)]] -> IO () plotMesh3d attrs pt dat =    plot3d attrs pt (Plot3D.mesh dat)  {- | > let xs = [-2,-1.8..2::Double] in plotFunc3d [] [] xs xs (\x y -> exp(-(x*x+y*y))) -}-plotFunc3d :: (Show a, Show b, Show c) =>-   [Attribute] -> [Attribute3d] -> [b] -> [c] -> (b -> c -> a) -> IO ()+plotFunc3d ::+   (Atom.C x, Atom.C y, Atom.C z,+    Tuple.C x, Tuple.C y, Tuple.C z) =>+   [Attribute] -> [Attribute3d] -> [x] -> [y] -> (x -> y -> z) -> IO () plotFunc3d attrs pt xArgs yArgs f =-   plot3d attrs pt (Plot3D.function xArgs yArgs f)+   plot3d attrs pt (Plot3D.surface xArgs yArgs f)   @@ -281,8 +348,7 @@    -> IO () epspdfPlot filename plot =    do plot (EPS (filename++".eps") : Key Nothing : [])-      rawSystem "epstopdf" [filename++".eps"]-      return ()+      void $ rawSystem "epstopdf" [filename++".eps"]  {-| Creates an EPS and a PDF graphics     and returns a string that can be inserted into a LaTeX document@@ -308,10 +374,8 @@ attrToProg (Custom attribute parameters) =    "set " ++ attribute ++ " " ++ unwords parameters -attrToProg (Terminal (Terminal.Cons options commands)) =-   concat $-   intersperse "; " $-   ("set terminal " ++ unwords options) : commands+attrToProg (Terminal term) =+   semiColonConcat $ Terminal.format term  attrToProg (EPS filename) =    "set terminal postscript eps; " ++  -- latex@@ -343,6 +407,7 @@ attrToProg (Title  title_)       = "set title " ++ quote title_ attrToProg (XLabel label)        = "set xlabel " ++ quote label attrToProg (YLabel label)        = "set ylabel " ++ quote label+attrToProg (ZLabel label)        = "set zlabel " ++ quote label attrToProg (XRange _)            = ""  -- xrange is handled in plot command attrToProg (YRange _)            = ""  -- yrange is handled in plot command attrToProg (ZRange _)            = ""  -- zrange is handled in plot command@@ -370,37 +435,46 @@    let ranges = map (listToMaybe . flip mapMaybe attrs)                     [xRangeFromAttr, yRangeFromAttr, zRangeFromAttr]        showRng (l,r) = "[" ++ show l ++ ":" ++ show r ++ "]"-   in  unwords (map (maybe "[:]" showRng) (dropWhileRev isNothing ranges))+   in  unwords $ map (maybe "[:]" showRng) (ListRev.dropWhile isNothing ranges) +interactiveTerm :: [Attribute] -> Bool+interactiveTerm =+   all $ \attr ->+      case attr of+         Terminal term -> Terminal.interactive term+         PNG _ -> False+         EPS _ -> False+         _ -> True  -plotTypeToGraph :: PlotType -> GraphType.T++plotTypeToGraph :: PlotType -> Graph2D.Type -- GraphType.T plotTypeToGraph t =    case t of-      Lines          -> GraphType.lines-      Points         -> GraphType.points-      LinesPoints    -> GraphType.linesPoints-      Impulses       -> GraphType.impulses-      Dots           -> GraphType.dots-      Steps          -> GraphType.steps-      FSteps         -> GraphType.fSteps-      HiSteps        -> GraphType.hiSteps-      ErrorBars      -> GraphType.errorBars-      XErrorBars     -> GraphType.xErrorBars-      YErrorBars     -> GraphType.yErrorBars-      XYErrorBars    -> GraphType.xyErrorBars-      ErrorLines     -> GraphType.errorLines-      XErrorLines    -> GraphType.xErrorLines-      YErrorLines    -> GraphType.yErrorLines-      XYErrorLines   -> GraphType.xyErrorLines-      Boxes          -> GraphType.boxes-      FilledCurves   -> GraphType.filledCurves-      BoxErrorBars   -> GraphType.boxErrorBars-      BoxXYErrorBars -> GraphType.boxXYErrorBars-      FinanceBars    -> GraphType.financeBars-      CandleSticks   -> GraphType.candleSticks-      Vectors        -> GraphType.vectors-      PM3d           -> GraphType.pm3d+      Lines          -> "lines"+      Points         -> "points"+      LinesPoints    -> "linespoints"+      Impulses       -> "impulses"+      Dots           -> "dots"+      Steps          -> "steps"+      FSteps         -> "fsteps"+      HiSteps        -> "histeps"+      ErrorBars      -> "errorbars"+      XErrorBars     -> "xerrorbars"+      YErrorBars     -> "yerrorbars"+      XYErrorBars    -> "xyerrorbars"+      ErrorLines     -> "errorlines"+      XErrorLines    -> "xerrorlines"+      YErrorLines    -> "yerrorlines"+      XYErrorLines   -> "xyerrorlines"+      Boxes          -> "boxes"+      FilledCurves   -> "filledcurves"+      BoxErrorBars   -> "boxerrorbars"+      BoxXYErrorBars -> "boxxyerrorbars"+      FinanceBars    -> "financebars"+      CandleSticks   -> "candlesticks"+      Vectors        -> "vectors"+      PM3d           -> "pm3d"   plot3dTypeToString :: Plot3dType -> String@@ -423,30 +497,24 @@   -plot2d :: [Attribute] -> Plot2D.T -> IO ()-plot2d attrs (Plot.Cons mp) =-   let files = State.evaluate 0 mp-   in  do mapM_ Plot.writeData files-          callGnuplot attrs "plot" $-             concatMap (\(Plot.File filename _ grs) ->-                map (\gr -> quote filename ++ " " ++ Graph2D.toString gr) grs) $-             files+plot2d ::+   (Atom.C x, Atom.C y) =>+   [Attribute] -> Plot2D.T x y -> IO ()+plot2d attrs plt =+   runGnuplot attrs "plot" plt -setPlotStyle :: PlotStyle -> Plot2D.T -> Plot2D.T+setPlotStyle :: PlotStyle -> Plot2D.T x y -> Plot2D.T x y setPlotStyle ps =    fmap (Graph2D.typ (plotTypeToGraph $ plotType ps) .          Graph2D.lineSpec (lineSpecRecord $ lineSpec ps))  -plot3d :: [Attribute] -> [Attribute3d] -> Plot3D.T -> IO ()-plot3d attrs pt (Plot.Cons mp) =-   let files = State.evaluate 0 mp-   in  do mapM_ Plot.writeData files-          callGnuplot-             (attrs ++ [Custom "pm3d" (map attribute3dToString pt)]) "splot" $-             concatMap (\(Plot.File filename _ grs) ->-                map (\gr -> quote filename ++ " " ++ Graph3D.toString gr) grs) $-             files+plot3d ::+   (Atom.C x, Atom.C y, Atom.C z) =>+   [Attribute] -> [Attribute3d] -> Plot3D.T x y z -> IO ()+plot3d attrs pt plt =+   runGnuplot+      (Custom "pm3d" (map attribute3dToString pt) : attrs) "splot" plt   lineSpecRecord :: LineSpec -> LineSpec.T@@ -466,13 +534,21 @@          LineTitle s -> LineSpec.title     s       ) -callGnuplot :: [Attribute] -> String -> [String] -> IO ()-callGnuplot attrs cmd params =-   Exec.simple-      (map attrToProg attrs ++-       [cmd ++ " " ++-        extractRanges attrs ++ " " ++-        commaConcat params])-      ["-persist"]-   -- instead of the option, one can also use 'set terminal x11 persist'-     >> return ()+runGnuplot ::+   Graph.C graph =>+   [Attribute] -> String -> Plot.T graph -> IO ()+runGnuplot attrs cmd (Plot.Cons mp) =+   void $ Cmd.asyncIfInteractive (interactiveTerm attrs) $ Cmd.run $ \dir ->+      let files = MR.runReader (MS.evalStateT mp 0) dir+      in  (map attrToProg attrs +++           [cmd ++ " " +++            extractRanges attrs ++ " " +++            commaConcat (plotFileStatements files)],+           files)++plotFileStatements ::+   Graph.C graph => [Plot.File graph] -> [String]+plotFileStatements =+   concatMap+      (\(Plot.File filename _ grs) ->+         map (\gr -> quote filename ++ " " ++ Graph.toString gr) grs)
src/Graphics/Gnuplot/Terminal.hs view
@@ -1,18 +1,3 @@-module Graphics.Gnuplot.Terminal where--data T =-   Cons {-      options :: [String],-      commands :: [String]-   }--class C terminal where-   canonical :: terminal -> T--deflt :: T-deflt = Cons ["x11"] []-+module Graphics.Gnuplot.Terminal (C, ) where -formatBool :: String -> Bool -> String-formatBool name b =-   if b then name else "no"++name+import Graphics.Gnuplot.Private.Terminal
+ src/Graphics/Gnuplot/Terminal/Default.hs view
@@ -0,0 +1,21 @@+module Graphics.Gnuplot.Terminal.Default (+   T, cons,+   ) where++import qualified Graphics.Gnuplot.Private.Terminal as Terminal+++data T = Cons++cons :: T+cons = Cons+++instance Terminal.C T where+   canonical _term =+      Terminal.Cons {+         Terminal.precommands = [],+         Terminal.options = [],+         Terminal.commands = [],+         Terminal.interactive = True  -- Always true? I don't know.+      }
src/Graphics/Gnuplot/Terminal/PNG.hs view
@@ -1,20 +1,22 @@ module Graphics.Gnuplot.Terminal.PNG (    T, cons,+   encoding,    transparent, noTransparent,    interlace, noInterlace,    trueColor, noTrueColor,    fontTiny, fontSmall, fontMedium, fontLarge, fontGiant,    ) where -import qualified Graphics.Gnuplot.Terminal as Terminal-import Graphics.Gnuplot.Terminal (formatBool, )+import qualified Graphics.Gnuplot.Private.Terminal as Terminal+import qualified Graphics.Gnuplot.Private.Encoding as Encoding import Data.Maybe (catMaybes, )-import Graphics.Gnuplot.Utility (quote, )+import Graphics.Gnuplot.Utility (quote, formatBool, )   data T =    Cons {       filename_ :: FilePath,+      encoding_ :: Maybe Encoding.T,       transparent_ :: Maybe Bool,       interlace_ :: Maybe Bool,       trueColor_ :: Maybe Bool,@@ -25,6 +27,7 @@ cons path =    Cons {       filename_ = path,+      encoding_ = Nothing,       transparent_ = Nothing,       interlace_ = Nothing,       trueColor_ = Nothing,@@ -32,6 +35,13 @@    }  +{- |+Setting the encoding to anything different+from 'Graphics.Gnuplot.Encoding.locale'+makes only sense if you write your gnuplot files manually using this encoding.+-}+encoding :: Encoding.T -> T -> T+encoding enc term = term{encoding_ = Just enc}  transparent, noTransparent :: T -> T transparent   term = term{transparent_ = Just True}@@ -78,6 +88,7 @@ instance Terminal.C T where    canonical term =       Terminal.Cons {+         Terminal.precommands = Encoding.formatMaybe $ encoding_ term,          Terminal.options =             "png" :             catMaybes (@@ -87,5 +98,6 @@                (fmap formatFontSize $ fontSize_ term) :                []),          Terminal.commands =-            ["set output " ++ (quote $ filename_ term)]+            ["set output " ++ (quote $ filename_ term)],+         Terminal.interactive = False       }
src/Graphics/Gnuplot/Terminal/PostScript.hs view
@@ -1,30 +1,47 @@ module Graphics.Gnuplot.Terminal.PostScript (    T, cons,+   encoding,    landscape, portrait, eps,    color, monochrome,+   font, embedFont,    ) where -import qualified Graphics.Gnuplot.Terminal as Terminal-import Data.Maybe (catMaybes, )-import Graphics.Gnuplot.Utility (quote, )+import qualified Graphics.Gnuplot.Private.Terminal as Terminal+import qualified Graphics.Gnuplot.Private.Encoding as Encoding+import Graphics.Gnuplot.Utility (listFromMaybeWith, quote, )+import Data.Foldable (foldMap, )   data T =    Cons {       filename_ :: FilePath,+      encoding_ :: Maybe Encoding.T,       mode_ :: Maybe Mode,-      color_ :: Maybe Bool+      color_ :: Maybe Bool,+      embedFont_ :: [FilePath],+      font_ :: Maybe (String, Int)    }  cons :: FilePath -> T cons path =    Cons {       filename_ = path,+      encoding_ = Nothing,       mode_ = Nothing,-      color_ = Nothing+      color_ = Nothing,+      embedFont_ = [],+      font_ = Nothing    }  +{- |+Setting the encoding to anything different+from 'Graphics.Gnuplot.Encoding.locale'+makes only sense if you write your gnuplot files manually using this encoding.+-}+encoding :: Encoding.T -> T -> T+encoding enc term = term{encoding_ = Just enc}+ landscape :: T -> T landscape = setMode Landscape @@ -43,7 +60,20 @@ monochrome term =    term{color_ = Just False} +font :: String -> Int -> T -> T+font fontName fontSize term =+   term{font_ = Just (fontName, fontSize)} +{- |+Embed a font file in the generated PostScript output.+Each call adds a new font file,+there is no way to remove it again.+-}+embedFont :: FilePath -> T -> T+embedFont fontFile term =+   term{embedFont_ = fontFile : embedFont_ term}++ -- private functions  data Mode =@@ -65,12 +95,15 @@ instance Terminal.C T where    canonical term =       Terminal.Cons {+         Terminal.precommands = Encoding.formatMaybe $ encoding_ term,          Terminal.options =             "postscript" :-            catMaybes (-               (fmap formatMode $ mode_ term) :-               (fmap (\b -> if b then "color" else "monochrome") $ color_ term) :-               []),+            (listFromMaybeWith formatMode $ mode_ term) +++            (listFromMaybeWith (\b -> if b then "color" else "monochrome") $ color_ term) +++            (concatMap (\path -> "fontfile" : quote path : []) $ embedFont_ term) +++            (foldMap (\(name,size) -> "font" : quote name : show size : []) $ font_ term) +++            [],          Terminal.commands =-            ["set output " ++ (quote $ filename_ term)]+            ["set output " ++ (quote $ filename_ term)],+         Terminal.interactive = False       }
+ src/Graphics/Gnuplot/Terminal/QT.hs view
@@ -0,0 +1,53 @@+{- |+Terminal using QT.+Derived from wxt.+-}+module Graphics.Gnuplot.Terminal.QT (+   T, cons,+   title, noTitle,+   persist, noPersist,+   ) where++import qualified Graphics.Gnuplot.Private.Terminal as Terminal+import Data.Maybe (catMaybes, )+import Graphics.Gnuplot.Utility (quote, formatBool, )+++data T =+   Cons {+      title_ :: Maybe String,+      persist_ :: Maybe Bool+   }++cons :: T+cons =+   Cons {+      title_ = Nothing,+      persist_ = Nothing+   }+++title :: String -> T -> T+title text term = term{title_ = Just text}++noTitle :: T -> T+noTitle term = term{title_ = Nothing}++persist, noPersist :: T -> T+persist   term = term{persist_ = Just True}+noPersist term = term{persist_ = Just False}+++instance Terminal.C T where+   canonical term =+      Terminal.Cons {+         Terminal.precommands = [],+         Terminal.options =+            "qt" :+            catMaybes (+               (fmap quote $ title_ term) :+               (fmap (formatBool "persist") $ persist_ term) :+               []),+         Terminal.commands = [],+         Terminal.interactive = True+      }
src/Graphics/Gnuplot/Terminal/SVG.hs view
@@ -1,22 +1,33 @@ module Graphics.Gnuplot.Terminal.SVG (    T, cons,+   encoding,    ) where -import qualified Graphics.Gnuplot.Terminal as Terminal+import qualified Graphics.Gnuplot.Private.Terminal as Terminal+import qualified Graphics.Gnuplot.Private.Encoding as Encoding import Graphics.Gnuplot.Utility (quote, )   data T =    Cons {-      filename_ :: FilePath+      filename_ :: FilePath,+      encoding_ :: Maybe Encoding.T    }  cons :: FilePath -> T cons path =    Cons {-      filename_ = path+      filename_ = path,+      encoding_ = Nothing    } +{- |+Setting the encoding to anything different+from 'Graphics.Gnuplot.Encoding.locale'+makes only sense if you write your gnuplot files manually using this encoding.+-}+encoding :: Encoding.T -> T -> T+encoding enc term = term{encoding_ = Just enc}   -- private functions@@ -24,9 +35,11 @@ instance Terminal.C T where    canonical term =       Terminal.Cons {+         Terminal.precommands = Encoding.formatMaybe $ encoding_ term,          Terminal.options =             "svg" :             [],          Terminal.commands =-            ["set output " ++ (quote $ filename_ term)]+            ["set output " ++ (quote $ filename_ term)],+         Terminal.interactive = False       }
+ src/Graphics/Gnuplot/Terminal/WXT.hs view
@@ -0,0 +1,53 @@+{- |+Terminal using wxwidgets.+Derived from X11.+-}+module Graphics.Gnuplot.Terminal.WXT (+   T, cons,+   title, noTitle,+   persist, noPersist,+   ) where++import qualified Graphics.Gnuplot.Private.Terminal as Terminal+import Data.Maybe (catMaybes, )+import Graphics.Gnuplot.Utility (quote, formatBool, )+++data T =+   Cons {+      title_ :: Maybe String,+      persist_ :: Maybe Bool+   }++cons :: T+cons =+   Cons {+      title_ = Nothing,+      persist_ = Nothing+   }+++title :: String -> T -> T+title text term = term{title_ = Just text}++noTitle :: T -> T+noTitle term = term{title_ = Nothing}++persist, noPersist :: T -> T+persist   term = term{persist_ = Just True}+noPersist term = term{persist_ = Just False}+++instance Terminal.C T where+   canonical term =+      Terminal.Cons {+         Terminal.precommands = [],+         Terminal.options =+            "wxt" :+            catMaybes (+               (fmap quote $ title_ term) :+               (fmap (formatBool "persist") $ persist_ term) :+               []),+         Terminal.commands = [],+         Terminal.interactive = True+      }
src/Graphics/Gnuplot/Terminal/X11.hs view
@@ -4,10 +4,9 @@    persist, noPersist,    ) where -import qualified Graphics.Gnuplot.Terminal as Terminal-import Graphics.Gnuplot.Terminal (formatBool, )+import qualified Graphics.Gnuplot.Private.Terminal as Terminal import Data.Maybe (catMaybes, )-import Graphics.Gnuplot.Utility (quote, )+import Graphics.Gnuplot.Utility (quote, formatBool, )   data T =@@ -38,12 +37,13 @@ instance Terminal.C T where    canonical term =       Terminal.Cons {+         Terminal.precommands = [],          Terminal.options =             "x11" :             catMaybes (                (fmap quote $ title_ term) :                (fmap (formatBool "persist") $ persist_ term) :                []),-         Terminal.commands =-            []+         Terminal.commands = [],+         Terminal.interactive = True       }
src/Graphics/Gnuplot/Time.hs view
@@ -1,7 +1,6 @@ module Graphics.Gnuplot.Time where -import System.Locale (defaultTimeLocale, )-import Data.Time.Format (FormatTime, formatTime, )+import Data.Time.Format (FormatTime, formatTime, defaultTimeLocale, ) import Data.Tuple.HT (mapFst, )  {- |
src/Graphics/Gnuplot/Utility.hs view
@@ -1,9 +1,12 @@ module Graphics.Gnuplot.Utility where +import Text.Printf (printf, )++import qualified Data.Char as Char import Data.List (intersperse, )  -functionToGraph :: [a] -> (a -> a) -> [(a,a)]+functionToGraph :: [x] -> (x -> y) -> [(x,y)] functionToGraph args f = map (\x -> (x, f x)) args -- functionToGraph args f = map swap $ attachKey f args @@ -22,5 +25,40 @@ semiColonConcat = concat . intersperse "; "  -quote :: String -> String-quote = show+{-+In former versions this was simply 'show'.+However, Haskell formats non-ASCII characters with decimal backslash sequences+whereas gnuplot expects octal ones.+gnuplot does also not accept bigger octal numbers.+The current version writes non-ASCII printable characters+with the system default encoding.+-}+quote, _quote :: String -> String+quote str = '"' : foldr (++) "\"" (map escapeChar str)+_quote str = '"' : concatMap escapeChar str ++ "\""++escapeChar :: Char -> String+escapeChar c =+   case c of+      '"'  -> "\\\""+      '\\' -> "\\\\"+      '\t' -> "\\t"+      '\n' -> "\\n"+      _ -> if Char.isPrint c then [c] else printf "\\%o" $ Char.ord c++assembleCells :: [[ShowS]] -> String+assembleCells ps =+   foldr ($) ""+      (concatMap+         (\p ->+            intersperse (showString ", ") p +++            [showString "\n"])+         ps)+++listFromMaybeWith :: (a -> b) -> Maybe a -> [b]+listFromMaybeWith f = maybe [] ((:[]) . f)++formatBool :: String -> Bool -> String+formatBool name b =+   if b then name else "no"++name
+ src/Graphics/Gnuplot/Value/Atom.hs view
@@ -0,0 +1,54 @@+{- |+Provide a class that restricts the range of Haskell types+to the ones that gnuplot can process.+-}+module Graphics.Gnuplot.Value.Atom (+   OptionSet(..),+   C(..),+   ) where++import qualified Graphics.Gnuplot.Private.FrameOption as Option+import Graphics.Gnuplot.Utility (quote, )++import qualified Data.Time as Time+import Data.Word (Word8, Word16, Word32, Word64, )+import Data.Int (Int8, Int16, Int32, Int64, )+import Data.Ratio (Ratio, )+++data OptionSet a =+   OptionSet {+      optData :: [String],+      optFormat :: [String],+      optOthers :: [(Option.T, [String])]+   }++class C a where+   options :: OptionSet a+   options =+      OptionSet [] [{- quote "%g" -}] []++instance C Float   where+instance C Double  where+instance C Int     where+instance C Integer where+instance (Integral a) => C (Ratio a) where++instance C Int8  where+instance C Int16 where+instance C Int32 where+instance C Int64 where+instance C Word8  where+instance C Word16 where+instance C Word32 where+instance C Word64 where+++timeOptions :: OptionSet time+timeOptions =+   OptionSet ["time"] [quote "%d/%m"] [(Option.timeFmt, [quote "%s"])]++instance C Time.Day where+   options = timeOptions+instance C Time.UTCTime where+   options = timeOptions
+ src/Graphics/Gnuplot/Value/ColumnSet.hs view
@@ -0,0 +1,38 @@+{- |+We provide a way to specify a set of columns+that matches the tuple structure of a certain graph type.+-}+module Graphics.Gnuplot.Value.ColumnSet+   (T(Cons), atom, pair, triple, quadruple,+   ) where++import qualified Graphics.Gnuplot.Value.Atom  as Atom+++newtype T a = Cons [Int]++{-+Functor and Applicative instances would be useful+for combining column sets,+but they are dangerous, because they can bring+type and column number out of sync.++instance Functor Column where+   fmap _ (Cons n) = Cons n++instance Applicative Column where+   pure _ = Cons []+   Cons ns <*> Cons ms = Cons (ns++ms)+-}++atom :: Atom.C a => Int -> T a+atom i = Cons [i]++pair :: T a -> T b -> T (a,b)+pair (Cons ai) (Cons bi) = Cons (ai++bi)++triple :: T a -> T b -> T c -> T (a,b,c)+triple (Cons ai) (Cons bi) (Cons ci) = Cons (ai++bi++ci)++quadruple :: T a -> T b -> T c -> T d -> T (a,b,c,d)+quadruple (Cons ai) (Cons bi) (Cons ci) (Cons di) = Cons (ai++bi++ci++di)
+ src/Graphics/Gnuplot/Value/Tuple.hs view
@@ -0,0 +1,118 @@+{- |+Provide a class that renders multiple Haskell values in a text form+that is accessible by gnuplot.++Maybe we add a method for the binary interface to gnuplot later.+-}+module Graphics.Gnuplot.Value.Tuple (+   C(text, columnCount),+   ColumnCount(ColumnCount),+   Label(Label),+   ) where++import Graphics.Gnuplot.Utility (quote)++import Data.Time.Format (defaultTimeLocale, )+import qualified Data.Time as Time++import Data.Word (Word8, Word16, Word32, Word64, )+import Data.Int (Int8, Int16, Int32, Int64, )+import Data.Ratio (Ratio, )++import Data.Function (id, ($), (.), )+import Text.Show (Show, ShowS, shows, showString, )+import Prelude+         (Eq, Ord, String, Int, Integer, Integral, Float, Double,+          realToFrac, (+), (++), )+++class C a where+   {- |+   For values that are also in Atom class,+   'text' must generate a singleton list.+   -}+   text :: a -> [ShowS]++   {- |+   It must hold @ColumnCount (length (text x)) == columnCount@.+   -}+   columnCount :: ColumnCount a+   columnCount = ColumnCount 1++{- |+Count numbers of gnuplot data columns for the respective type.++Somehow a writer monad with respect to Sum monoid+without material monadic result.++Cf. ColumnSet module.+-}+newtype ColumnCount a = ColumnCount Int+   deriving (Eq, Ord, Show)++{-+Functor and Applicative instances would be useful+for combining column sets,+but they are dangerous, because they can bring+type and column columnCount out of sync.+-}++pure :: a -> ColumnCount a+pure _ = ColumnCount 0++(<*>) :: ColumnCount (a -> b) -> ColumnCount a -> ColumnCount b+ColumnCount n <*> ColumnCount m = ColumnCount (n+m)+++singleton :: a -> [a]+singleton = (:[])+++instance C Float   where text = singleton . shows+instance C Double  where text = singleton . shows+instance C Int     where text = singleton . shows+instance C Integer where text = singleton . shows+instance (Integral a) => C (Ratio a) where+   text = singleton . shows . (id :: Double->Double) . realToFrac++instance C Int8  where text = singleton . shows+instance C Int16 where text = singleton . shows+instance C Int32 where text = singleton . shows+instance C Int64 where text = singleton . shows+instance C Word8  where text = singleton . shows+instance C Word16 where text = singleton . shows+instance C Word32 where text = singleton . shows+instance C Word64 where text = singleton . shows++instance C Time.Day where+   text d = text $ Time.UTCTime d 0+instance C Time.UTCTime where+   text = singleton . showString . Time.formatTime defaultTimeLocale "%s"++newtype Label = Label String+instance C Label where text (Label str) = singleton $ showString $ quote str+++instance (C a, C b) => C (a,b) where+   text (a,b) = text a ++ text b+   columnCount =+      pure (,)+         <*> columnCount+         <*> columnCount++instance (C a, C b, C c) => C (a,b,c) where+   text (a,b,c) = text a ++ text b ++ text c+   columnCount =+      pure (,,)+         <*> columnCount+         <*> columnCount+         <*> columnCount++instance (C a, C b, C c, C d) => C (a,b,c,d) where+   text (a,b,c,d) = text a ++ text b ++ text c ++ text d+   columnCount =+      pure (,,,)+         <*> columnCount+         <*> columnCount+         <*> columnCount+         <*> columnCount