Skip to content

Commit 684081f

Browse files
authored
Merge pull request #60 from SanchayanMaity/d2
Add support for D2
2 parents 664e00e + 1d68016 commit 684081f

File tree

10 files changed

+89
-3
lines changed

10 files changed

+89
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ The resulting `output.html` looks like this:
7171
- `plotsjl`: plots using the [Julia `Plots.jl`](https://docs.juliaplots.org/latest/) package;
7272
- `plantuml`: diagrams using the [PlantUML](https://plantuml.com/) software suite;
7373
- `sageplot`: plots using the [Sage](https://www.sagemath.org/) software system.
74+
- `d2`: plots using [D2](https://d2lang.com/).
7475

7576
To know which toolkits are useable on *your machine* (and which ones are
7677
not available), you can check with the `toolkits` command:

example-config.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,8 @@ plantuml:
141141
sageplot:
142142
# preamble: sageplot.sage
143143
executable: sage
144-
command_line_arguments:
144+
command_line_arguments:
145+
146+
d2:
147+
executable: d2
148+
command_line_arguments:

pandoc-plot.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ library
7979
Text.Pandoc.Filter.Plot.Renderers.Plotsjl
8080
Text.Pandoc.Filter.Plot.Renderers.PlantUML
8181
Text.Pandoc.Filter.Plot.Renderers.SageMath
82+
Text.Pandoc.Filter.Plot.Renderers.D2
8283
Text.Pandoc.Filter.Plot.Monad
8384
Text.Pandoc.Filter.Plot.Monad.Logging
8485
Text.Pandoc.Filter.Plot.Monad.Types

src/Text/Pandoc/Filter/Plot/Configuration.hs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ defaultConfiguration =
6464
plotsjlPreamble = mempty,
6565
plantumlPreamble = mempty,
6666
sagemathPreamble = mempty,
67+
d2Preamble = mempty,
6768
-- Executables
6869
matplotlibExe = python,
6970
matlabExe = "matlab",
@@ -78,6 +79,7 @@ defaultConfiguration =
7879
plotsjlExe = "julia",
7980
plantumlExe = "java",
8081
sagemathExe = "sage",
82+
d2Exe = "d2",
8183
-- Command line arguments
8284
matplotlibCmdArgs = mempty,
8385
matlabCmdArgs = mempty,
@@ -92,6 +94,7 @@ defaultConfiguration =
9294
plotsjlCmdArgs = mempty,
9395
plantumlCmdArgs = "-jar plantuml.jar",
9496
sagemathCmdArgs = mempty,
97+
d2CmdArgs = mempty,
9598
-- Extras
9699
matplotlibTightBBox = False,
97100
matplotlibTransparent = False
@@ -151,7 +154,8 @@ data ConfigPrecursor = ConfigPrecursor
151154
_bokehPrec :: !BokehPrecursor,
152155
_plotsjlPrec :: !PlotsjlPrecursor,
153156
_plantumlPrec :: !PlantUMLPrecursor,
154-
_sagemathPrec :: !SageMathPrecursor
157+
_sagemathPrec :: !SageMathPrecursor,
158+
_d2Prec :: !D2Precursor
155159
}
156160

157161
defaultConfigPrecursor :: ConfigPrecursor
@@ -178,7 +182,8 @@ defaultConfigPrecursor =
178182
_bokehPrec = BokehPrecursor Nothing (bokehExe defaultConfiguration) (bokehCmdArgs defaultConfiguration),
179183
_plotsjlPrec = PlotsjlPrecursor Nothing (plotsjlExe defaultConfiguration) (plotsjlCmdArgs defaultConfiguration),
180184
_plantumlPrec = PlantUMLPrecursor Nothing (plantumlExe defaultConfiguration) (plantumlCmdArgs defaultConfiguration),
181-
_sagemathPrec = SageMathPrecursor Nothing (sagemathExe defaultConfiguration) (sagemathCmdArgs defaultConfiguration)
185+
_sagemathPrec = SageMathPrecursor Nothing (sagemathExe defaultConfiguration) (sagemathCmdArgs defaultConfiguration),
186+
_d2Prec = D2Precursor Nothing (d2Exe defaultConfiguration) (d2CmdArgs defaultConfiguration)
182187
}
183188

184189
data LoggingPrecursor = LoggingPrecursor
@@ -219,6 +224,8 @@ data PlantUMLPrecursor = PlantUMLPrecursor {_plantumlPreamble :: !(Maybe FilePat
219224

220225
data SageMathPrecursor = SageMathPrecursor {_sagemathPreamble :: !(Maybe FilePath), _sagemathExe :: !FilePath, _sagemathCmdArgs :: !Text}
221226

227+
data D2Precursor = D2Precursor {_d2Preamble :: !(Maybe FilePath), _d2Exe :: !FilePath, _d2CmdArgs :: !Text}
228+
222229
instance FromJSON LoggingPrecursor where
223230
parseJSON (Object v) =
224231
LoggingPrecursor <$> v .:? "verbosity" .!= logVerbosity defaultConfiguration
@@ -286,6 +293,10 @@ instance FromJSON SageMathPrecursor where
286293
parseJSON (Object v) = SageMathPrecursor <$> v .:? asKey PreambleK <*> v .:? asKey ExecutableK .!= sagemathExe defaultConfiguration <*> v .:? asKey CommandLineArgsK .!= sagemathCmdArgs defaultConfiguration
287294
parseJSON _ = fail $ mconcat ["Could not parse ", show SageMath, " configuration."]
288295

296+
instance FromJSON D2Precursor where
297+
parseJSON (Object v) = D2Precursor <$> v .:? asKey PreambleK <*> v .:? asKey ExecutableK .!= d2Exe defaultConfiguration <*> v .:? asKey CommandLineArgsK .!= d2CmdArgs defaultConfiguration
298+
parseJSON _ = fail $ mconcat ["Could not parse ", show SageMath, " configuration."]
299+
289300
toolkitAsKey :: Toolkit -> Key
290301
toolkitAsKey = fromString . unpack . cls
291302

@@ -315,6 +326,7 @@ instance FromJSON ConfigPrecursor where
315326
_plotsjlPrec <- v .:? toolkitAsKey Plotsjl .!= _plotsjlPrec defaultConfigPrecursor
316327
_plantumlPrec <- v .:? toolkitAsKey PlantUML .!= _plantumlPrec defaultConfigPrecursor
317328
_sagemathPrec <- v .:? toolkitAsKey SageMath .!= _sagemathPrec defaultConfigPrecursor
329+
_d2Prec <- v .:? toolkitAsKey D2 .!= _d2Prec defaultConfigPrecursor
318330

319331
return $ ConfigPrecursor {..}
320332
parseJSON _ = fail "Could not parse configuration."
@@ -349,6 +361,7 @@ renderConfig ConfigPrecursor {..} = do
349361
plotsjlExe = _plotsjlExe _plotsjlPrec
350362
plantumlExe = _plantumlExe _plantumlPrec
351363
sagemathExe = _sagemathExe _sagemathPrec
364+
d2Exe = _d2Exe _d2Prec
352365

353366
matplotlibCmdArgs = _matplotlibCmdArgs _matplotlibPrec
354367
matlabCmdArgs = _matlabCmdArgs _matlabPrec
@@ -363,6 +376,7 @@ renderConfig ConfigPrecursor {..} = do
363376
plotsjlCmdArgs = _plotsjlCmdArgs _plotsjlPrec
364377
plantumlCmdArgs = _plantumlCmdArgs _plantumlPrec
365378
sagemathCmdArgs = _sagemathCmdArgs _sagemathPrec
379+
d2CmdArgs = _d2CmdArgs _d2Prec
366380

367381
matplotlibPreamble <- readPreamble (_matplotlibPreamble _matplotlibPrec)
368382
matlabPreamble <- readPreamble (_matlabPreamble _matlabPrec)
@@ -377,6 +391,7 @@ renderConfig ConfigPrecursor {..} = do
377391
plotsjlPreamble <- readPreamble (_plotsjlPreamble _plotsjlPrec)
378392
plantumlPreamble <- readPreamble (_plantumlPreamble _plantumlPrec)
379393
sagemathPreamble <- readPreamble (_sagemathPreamble _sagemathPrec)
394+
d2Preamble <- readPreamble (_d2Preamble _d2Prec)
380395

381396
return Configuration {..}
382397
where

src/Text/Pandoc/Filter/Plot/Monad.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ executable tk = exeSelector tk <&> exeFromPath
282282
exeSelector Plotsjl = asksConfig plotsjlExe
283283
exeSelector PlantUML = asksConfig plantumlExe
284284
exeSelector SageMath = asksConfig sagemathExe
285+
exeSelector D2 = asksConfig d2Exe
285286

286287
-- | The @Configuration@ type holds the default values to use
287288
-- when running pandoc-plot. These values can be overridden in code blocks.
@@ -350,6 +351,8 @@ data Configuration = Configuration
350351
plantumlPreamble :: !Script,
351352
-- | The default preamble script for the SageMath toolkit.
352353
sagemathPreamble :: !Script,
354+
-- | The default preamble script for the d2 toolkit.
355+
d2Preamble :: !Script,
353356
-- | The executable to use to generate figures using the matplotlib toolkit.
354357
matplotlibExe :: !FilePath,
355358
-- | The executable to use to generate figures using the MATLAB toolkit.
@@ -376,6 +379,8 @@ data Configuration = Configuration
376379
plantumlExe :: !FilePath,
377380
-- | The executable to use to generate figures using SageMath.
378381
sagemathExe :: !FilePath,
382+
-- | The executable to use to generate figures using d2.
383+
d2Exe :: !FilePath,
379384
-- | Command-line arguments to pass to the Python interpreter for the Matplotlib toolkit
380385
matplotlibCmdArgs :: !Text,
381386
-- | Command-line arguments to pass to the interpreter for the MATLAB toolkit.
@@ -402,6 +407,8 @@ data Configuration = Configuration
402407
plantumlCmdArgs :: !Text,
403408
-- | Command-line arguments to pass to the interpreter for the SageMath toolkit.
404409
sagemathCmdArgs :: !Text,
410+
-- | Command-line arguments to pass to the interpreter for the d2 toolkit.
411+
d2CmdArgs :: !Text,
405412
-- | Whether or not to make Matplotlib figures tight by default.
406413
matplotlibTightBBox :: !Bool,
407414
-- | Whether or not to make Matplotlib figures transparent by default.

src/Text/Pandoc/Filter/Plot/Monad/Types.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ data Toolkit
6161
| Plotsjl
6262
| PlantUML
6363
| SageMath
64+
| D2
6465
deriving (Bounded, Eq, Enum, Generic, Ord)
6566

6667
-- | This instance should only be used to display toolkit names
@@ -78,6 +79,7 @@ instance Show Toolkit where
7879
show Plotsjl = "Julia/Plots.jl"
7980
show PlantUML = "PlantUML"
8081
show SageMath = "SageMath"
82+
show D2 = "D2"
8183

8284
-- | Class name which will trigger the filter
8385
cls :: Toolkit -> Text
@@ -94,6 +96,7 @@ cls Bokeh = "bokeh"
9496
cls Plotsjl = "plotsjl"
9597
cls PlantUML = "plantuml"
9698
cls SageMath = "sageplot"
99+
cls D2 = "d2"
97100

98101
-- | Executable program, and sometimes the directory where it can be found.
99102
data Executable

src/Text/Pandoc/Filter/Plot/Renderers.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ import Text.Pandoc.Filter.Plot.Renderers.Plotsjl
6464
( plotsjl, plotsjlSupportedSaveFormats )
6565
import Text.Pandoc.Filter.Plot.Renderers.SageMath
6666
( sagemath, sagemathSupportedSaveFormats )
67+
import Text.Pandoc.Filter.Plot.Renderers.D2
68+
( d2, d2SupportedSaveFormats )
6769
import System.Directory (findExecutable)
6870

6971
-- | Get the renderer associated with a toolkit.
@@ -83,6 +85,7 @@ renderer Bokeh = bokeh
8385
renderer Plotsjl = plotsjl
8486
renderer PlantUML = plantuml
8587
renderer SageMath = sagemath
88+
renderer D2 = d2
8689

8790
-- | Save formats supported by this renderer.
8891
supportedSaveFormats :: Toolkit -> [SaveFormat]
@@ -99,6 +102,7 @@ supportedSaveFormats Bokeh = bokehSupportedSaveFormats
99102
supportedSaveFormats Plotsjl = plotsjlSupportedSaveFormats
100103
supportedSaveFormats PlantUML = plantumlSupportedSaveFormats
101104
supportedSaveFormats SageMath = sagemathSupportedSaveFormats
105+
supportedSaveFormats D2 = d2SupportedSaveFormats
102106

103107
-- | The function that maps from configuration to the preamble.
104108
preambleSelector :: Toolkit -> (Configuration -> Script)
@@ -115,6 +119,7 @@ preambleSelector Bokeh = bokehPreamble
115119
preambleSelector Plotsjl = plotsjlPreamble
116120
preambleSelector PlantUML = plantumlPreamble
117121
preambleSelector SageMath = sagemathPreamble
122+
preambleSelector D2 = d2Preamble
118123

119124
-- | Parse code block headers for extra attributes that are specific
120125
-- to this renderer. By default, no extra attributes are parsed.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
{-# LANGUAGE QuasiQuotes #-}
3+
{-# LANGUAGE RecordWildCards #-}
4+
{-# LANGUAGE NoImplicitPrelude #-}
5+
6+
-- |
7+
-- Module : $header$
8+
-- Copyright : (c) Sanchayan Maity, 2023 - present
9+
-- License : GNU GPL, version 2 or above
10+
-- Maintainer : sanchayan@sanchayanmaity.net
11+
-- Stability : internal
12+
-- Portability : portable
13+
--
14+
-- Rendering D2 plots code blocks
15+
module Text.Pandoc.Filter.Plot.Renderers.D2
16+
( d2,
17+
d2SupportedSaveFormats,
18+
)
19+
where
20+
21+
import Text.Pandoc.Filter.Plot.Renderers.Prelude
22+
23+
d2 :: PlotM Renderer
24+
d2 = do
25+
cmdargs <- asksConfig d2CmdArgs
26+
return $
27+
Renderer
28+
{ rendererToolkit = D2,
29+
rendererCapture = d2Capture,
30+
rendererCommand = d2Command cmdargs,
31+
rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -v|],
32+
rendererSupportedSaveFormats = d2SupportedSaveFormats,
33+
rendererChecks = mempty,
34+
rendererLanguage = "d2",
35+
rendererComment = mappend "# ",
36+
rendererScriptExtension = ".d2"
37+
}
38+
39+
d2SupportedSaveFormats :: [SaveFormat]
40+
d2SupportedSaveFormats = [PNG, PDF, SVG]
41+
42+
d2Command :: Text -> OutputSpec -> Text
43+
d2Command cmdargs OutputSpec {..} = [st|#{pathToExe oExecutable} #{cmdargs} "#{oScriptPath}" "#{oFigurePath}"|]
44+
45+
-- d2 export is entirely based on command-line arguments
46+
-- so there is no need to modify the script itself.
47+
d2Capture :: FigureSpec -> FilePath -> Script
48+
d2Capture FigureSpec {..} _ = script

tests/Common.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ testFileInclusion tk =
119119
include Plotsjl = "tests/includes/plotsjl.jl"
120120
include PlantUML = "tests/includes/plantuml.txt"
121121
include SageMath = "tests/includes/sagemath.sage"
122+
include D2 = "tests/includes/d2-dd.d2"
122123

123124
-------------------------------------------------------------------------------
124125
-- Test that the files are saved in the appropriate format
@@ -389,6 +390,7 @@ trivialContent Bokeh =
389390
trivialContent Plotsjl = "using Plots; x = 1:10; y = rand(10); plot(x, y);"
390391
trivialContent PlantUML = "@startuml\nAlice -> Bob: test\n@enduml"
391392
trivialContent SageMath = "G = plot(sin, 1, 10)"
393+
trivialContent D2 = "x -> y -> z"
392394

393395
addCaption :: String -> Block -> Block
394396
addCaption caption (CodeBlock (id', cls, attrs) script) =

tests/includes/d2-dd.d2

Whitespace-only changes.

0 commit comments

Comments
 (0)