Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Asymptote diagrams #61

Merged
merged 19 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ jobs:
run: |
Rscript -e "install.packages('ggplot2', repos='http://cran.rstudio.com/')"

- name: Install Octave, Gnuplot, Graphviz, and PlantUML [Linux]
- name: Install Octave, Gnuplot, Graphviz, PlantUML, and Asymptote [Linux]
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get --quiet --yes install octave
sudo apt-get --quiet --yes install gnuplot
sudo apt-get --quiet --yes install graphviz

sudo apt-get --quiet --yes install asymptote
sudo apt-get --quiet --yes install plantuml
echo $(plantuml -version)
# The ubuntu package version is too old
Expand All @@ -120,13 +120,15 @@ jobs:
dot -c

choco install --yes --no-progress gnuplot
choco install --yes --no-progress asymptote
choco install --yes --no-progress plantuml
plantuml -h

- name: Install Octave, Gnuplot, Graphviz, and PlantUML [Mac]
if: runner.os == 'macOS'
run: |
brew update
brew install asymptote
brew install octave
brew install gnuplot
brew install graphviz
Expand Down Expand Up @@ -202,6 +204,12 @@ jobs:
exit 1
fi
pandoc-plot clean tests/issue53.md

pandoc --filter pandoc-plot -i tests/issue55.md -t native
if [ $(ls "plots" | wc -l) != 2 ]; then
exit 1
fi
pandoc-plot clean tests/issue55.md

- name: Build documentation
run: source tools/mkmanual.sh
Expand Down
1 change: 1 addition & 0 deletions pandoc-plot.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ library
Text.Pandoc.Filter.Plot.Renderers.PlantUML
Text.Pandoc.Filter.Plot.Renderers.SageMath
Text.Pandoc.Filter.Plot.Renderers.D2
Text.Pandoc.Filter.Plot.Renderers.Asymptote
Text.Pandoc.Filter.Plot.Monad
Text.Pandoc.Filter.Plot.Monad.Logging
Text.Pandoc.Filter.Plot.Monad.Types
Expand Down
19 changes: 17 additions & 2 deletions src/Text/Pandoc/Filter/Plot/Configuration.hs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ defaultConfiguration =
plantumlPreamble = mempty,
sagemathPreamble = mempty,
d2Preamble = mempty,
asyPreamble = mempty,
-- Executables
matplotlibExe = python,
matlabExe = "matlab",
Expand All @@ -80,6 +81,7 @@ defaultConfiguration =
plantumlExe = "java",
sagemathExe = "sage",
d2Exe = "d2",
asyExe = "asy",
-- Command line arguments
matplotlibCmdArgs = mempty,
matlabCmdArgs = mempty,
Expand All @@ -95,6 +97,7 @@ defaultConfiguration =
plantumlCmdArgs = "-jar plantuml.jar",
sagemathCmdArgs = mempty,
d2CmdArgs = mempty,
asyCmdArgs = mempty,
-- Extras
matplotlibTightBBox = False,
matplotlibTransparent = False
Expand Down Expand Up @@ -155,7 +158,8 @@ data ConfigPrecursor = ConfigPrecursor
_plotsjlPrec :: !PlotsjlPrecursor,
_plantumlPrec :: !PlantUMLPrecursor,
_sagemathPrec :: !SageMathPrecursor,
_d2Prec :: !D2Precursor
_d2Prec :: !D2Precursor,
_asyPrec :: !AsyPrecursor
}

defaultConfigPrecursor :: ConfigPrecursor
Expand Down Expand Up @@ -183,7 +187,8 @@ defaultConfigPrecursor =
_plotsjlPrec = PlotsjlPrecursor Nothing (plotsjlExe defaultConfiguration) (plotsjlCmdArgs defaultConfiguration),
_plantumlPrec = PlantUMLPrecursor Nothing (plantumlExe defaultConfiguration) (plantumlCmdArgs defaultConfiguration),
_sagemathPrec = SageMathPrecursor Nothing (sagemathExe defaultConfiguration) (sagemathCmdArgs defaultConfiguration),
_d2Prec = D2Precursor Nothing (d2Exe defaultConfiguration) (d2CmdArgs defaultConfiguration)
_d2Prec = D2Precursor Nothing (d2Exe defaultConfiguration) (d2CmdArgs defaultConfiguration),
_asyPrec = AsyPrecursor Nothing (asyExe defaultConfiguration) (asyCmdArgs defaultConfiguration)
}

data LoggingPrecursor = LoggingPrecursor
Expand Down Expand Up @@ -226,6 +231,8 @@ data SageMathPrecursor = SageMathPrecursor {_sagemathPreamble :: !(Maybe FilePat

data D2Precursor = D2Precursor {_d2Preamble :: !(Maybe FilePath), _d2Exe :: !FilePath, _d2CmdArgs :: !Text}

data AsyPrecursor = AsyPrecursor {_asyPreamble :: !(Maybe FilePath), _asyExe :: !FilePath, _asyCmdArgs :: !Text}

instance FromJSON LoggingPrecursor where
parseJSON (Object v) =
LoggingPrecursor
Expand Down Expand Up @@ -298,6 +305,10 @@ instance FromJSON D2Precursor where
parseJSON (Object v) = D2Precursor <$> v .:? asKey PreambleK <*> v .:? asKey ExecutableK .!= d2Exe defaultConfiguration <*> v .:? asKey CommandLineArgsK .!= d2CmdArgs defaultConfiguration
parseJSON _ = fail $ mconcat ["Could not parse ", show SageMath, " configuration."]

instance FromJSON AsyPrecursor where
parseJSON (Object v) = AsyPrecursor <$> v .:? asKey PreambleK <*> v .:? asKey ExecutableK .!= asyExe defaultConfiguration <*> v .:? asKey CommandLineArgsK .!= asyCmdArgs defaultConfiguration
parseJSON _ = fail $ mconcat ["Could not parse ", show Asymptote, " configuration."]

toolkitAsKey :: Toolkit -> Key
toolkitAsKey = fromString . unpack . cls

Expand Down Expand Up @@ -328,6 +339,7 @@ instance FromJSON ConfigPrecursor where
_plantumlPrec <- v .:? toolkitAsKey PlantUML .!= _plantumlPrec defaultConfigPrecursor
_sagemathPrec <- v .:? toolkitAsKey SageMath .!= _sagemathPrec defaultConfigPrecursor
_d2Prec <- v .:? toolkitAsKey D2 .!= _d2Prec defaultConfigPrecursor
_asyPrec <- v .:? toolkitAsKey Asymptote .!= _asyPrec defaultConfigPrecursor

return $ ConfigPrecursor {..}
parseJSON _ = fail "Could not parse configuration."
Expand Down Expand Up @@ -363,6 +375,7 @@ renderConfig ConfigPrecursor {..} = do
plantumlExe = _plantumlExe _plantumlPrec
sagemathExe = _sagemathExe _sagemathPrec
d2Exe = _d2Exe _d2Prec
asyExe = _asyExe _asyPrec

matplotlibCmdArgs = _matplotlibCmdArgs _matplotlibPrec
matlabCmdArgs = _matlabCmdArgs _matlabPrec
Expand All @@ -378,6 +391,7 @@ renderConfig ConfigPrecursor {..} = do
plantumlCmdArgs = _plantumlCmdArgs _plantumlPrec
sagemathCmdArgs = _sagemathCmdArgs _sagemathPrec
d2CmdArgs = _d2CmdArgs _d2Prec
asyCmdArgs = _asyCmdArgs _asyPrec

matplotlibPreamble <- readPreamble (_matplotlibPreamble _matplotlibPrec)
matlabPreamble <- readPreamble (_matlabPreamble _matlabPrec)
Expand All @@ -393,6 +407,7 @@ renderConfig ConfigPrecursor {..} = do
plantumlPreamble <- readPreamble (_plantumlPreamble _plantumlPrec)
sagemathPreamble <- readPreamble (_sagemathPreamble _sagemathPrec)
d2Preamble <- readPreamble (_d2Preamble _d2Prec)
asyPreamble <- readPreamble (_asyPreamble _asyPrec)

return Configuration {..}
where
Expand Down
7 changes: 7 additions & 0 deletions src/Text/Pandoc/Filter/Plot/Monad.hs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ executable tk = exeSelector tk <&> exeFromPath
exeSelector PlantUML = asksConfig plantumlExe
exeSelector SageMath = asksConfig sagemathExe
exeSelector D2 = asksConfig d2Exe
exeSelector Asymptote = asksConfig asyExe

-- | The @Configuration@ type holds the default values to use
-- when running pandoc-plot. These values can be overridden in code blocks.
Expand Down Expand Up @@ -353,6 +354,8 @@ data Configuration = Configuration
sagemathPreamble :: !Script,
-- | The default preamble script for the d2 toolkit.
d2Preamble :: !Script,
-- | The default preamble script for the Asymptote toolkit.
asyPreamble :: !Script,
-- | The executable to use to generate figures using the matplotlib toolkit.
matplotlibExe :: !FilePath,
-- | The executable to use to generate figures using the MATLAB toolkit.
Expand Down Expand Up @@ -381,6 +384,8 @@ data Configuration = Configuration
sagemathExe :: !FilePath,
-- | The executable to use to generate figures using d2.
d2Exe :: !FilePath,
-- | The executable to use to generate figures using Asymptote
asyExe :: !FilePath,
-- | Command-line arguments to pass to the Python interpreter for the Matplotlib toolkit
matplotlibCmdArgs :: !Text,
-- | Command-line arguments to pass to the interpreter for the MATLAB toolkit.
Expand Down Expand Up @@ -409,6 +414,8 @@ data Configuration = Configuration
sagemathCmdArgs :: !Text,
-- | Command-line arguments to pass to the interpreter for the d2 toolkit.
d2CmdArgs :: !Text,
-- | Command-line arguments to pass to the interpreter for the Asymptote toolkit.
asyCmdArgs :: !Text,
-- | Whether or not to make Matplotlib figures tight by default.
matplotlibTightBBox :: !Bool,
-- | Whether or not to make Matplotlib figures transparent by default.
Expand Down
3 changes: 3 additions & 0 deletions src/Text/Pandoc/Filter/Plot/Monad/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ data Toolkit
| PlantUML
| SageMath
| D2
| Asymptote
deriving (Bounded, Eq, Enum, Generic, Ord)

-- | This instance should only be used to display toolkit names
Expand All @@ -80,6 +81,7 @@ instance Show Toolkit where
show PlantUML = "PlantUML"
show SageMath = "SageMath"
show D2 = "D2"
show Asymptote = "Asymptote"

-- | Class name which will trigger the filter
cls :: Toolkit -> Text
Expand All @@ -97,6 +99,7 @@ cls Plotsjl = "plotsjl"
cls PlantUML = "plantuml"
cls SageMath = "sageplot"
cls D2 = "d2"
cls Asymptote = "asy"

-- | Executable program, and sometimes the directory where it can be found.
data Executable
Expand Down
8 changes: 7 additions & 1 deletion src/Text/Pandoc/Filter/Plot/Renderers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ import Text.Pandoc.Filter.Plot.Renderers.SageMath
( sagemath,
sagemathSupportedSaveFormats,
)

import Text.Pandoc.Filter.Plot.Renderers.Asymptote
( asymptote,
asymptoteSupportedSaveFormats,
)
-- | Get the renderer associated with a toolkit.
-- If the renderer has not been used before,
-- initialize it and store where it is. It will be re-used.
Expand All @@ -114,6 +117,7 @@ renderer Plotsjl = plotsjl
renderer PlantUML = plantuml
renderer SageMath = sagemath
renderer D2 = d2
renderer Asymptote = asymptote

-- | Save formats supported by this renderer.
supportedSaveFormats :: Toolkit -> [SaveFormat]
Expand All @@ -131,6 +135,7 @@ supportedSaveFormats Plotsjl = plotsjlSupportedSaveFormats
supportedSaveFormats PlantUML = plantumlSupportedSaveFormats
supportedSaveFormats SageMath = sagemathSupportedSaveFormats
supportedSaveFormats D2 = d2SupportedSaveFormats
supportedSaveFormats Asymptote = asymptoteSupportedSaveFormats

-- | The function that maps from configuration to the preamble.
preambleSelector :: Toolkit -> (Configuration -> Script)
Expand All @@ -148,6 +153,7 @@ preambleSelector Plotsjl = plotsjlPreamble
preambleSelector PlantUML = plantumlPreamble
preambleSelector SageMath = sagemathPreamble
preambleSelector D2 = d2Preamble
preambleSelector Asymptote = asyPreamble

-- | Parse code block headers for extra attributes that are specific
-- to this renderer. By default, no extra attributes are parsed.
Expand Down
49 changes: 49 additions & 0 deletions src/Text/Pandoc/Filter/Plot/Renderers/Asymptote.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NoImplicitPrelude #-}

-- |
-- Module : $header$
-- Copyright : (c) Laurent P René de Cotret, 2019 - present
-- License : GNU GPL, version 2 or above
-- Maintainer : [email protected]
-- Stability : internal
-- Portability : portable
--
-- Rendering Asymptote plots code blocks
module Text.Pandoc.Filter.Plot.Renderers.Asymptote
( asymptote,
asymptoteSupportedSaveFormats,
)
where

import Text.Pandoc.Filter.Plot.Renderers.Prelude

asymptote :: PlotM Renderer
asymptote = do
cmdargs <- asksConfig asyCmdArgs
return
$ Renderer
{ rendererToolkit = Asymptote,
rendererCapture = asymptoteCapture,
rendererCommand = asymptoteCommand cmdargs,
rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -environment|],
rendererSupportedSaveFormats = asymptoteSupportedSaveFormats,
rendererChecks = mempty,
rendererLanguage = "asy",
rendererComment = mappend "// ",
rendererScriptExtension = ".asy"
}

asymptoteSupportedSaveFormats :: [SaveFormat]
asymptoteSupportedSaveFormats = [PDF]

asymptoteCommand :: Text -> OutputSpec -> Text
asymptoteCommand cmdArgs OutputSpec {..} =
[st|#{pathToExe oExecutable} #{cmdArgs} -o "#{oFigurePath}" "#{oScriptPath}"|]

-- Asymptote export is entirely based on command-line arguments
-- so there is no need to modify the script itself.
asymptoteCapture :: FigureSpec -> FilePath -> Script
asymptoteCapture FigureSpec {..} _ = script
7 changes: 6 additions & 1 deletion tests/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ defaultTestConfig :: Configuration
defaultTestConfig =
defaultConfiguration
{ logVerbosity = Silent,
logSink = StdErr
logSink = StdErr,
defaultSaveFormat = PDF -- Asymptote does not support PNG
}

-------------------------------------------------------------------------------
Expand All @@ -47,6 +48,7 @@ testFileCreation tk =

let cb = (addDirectory tempDir $ codeBlock tk (trivialContent tk))
_ <- runPlotM Nothing defaultTestConfig $ make cb
created <- listDirectory tempDir
filesCreated <- length <$> listDirectory tempDir
assertEqual "" 2 filesCreated

Expand Down Expand Up @@ -121,10 +123,12 @@ testFileInclusion tk =
include PlantUML = "tests/includes/plantuml.txt"
include SageMath = "tests/includes/sagemath.sage"
include D2 = "tests/includes/d2-dd.d2"
include Asymptote = "tests/includes/asymptote.asy"

-------------------------------------------------------------------------------
-- Test that the files are saved in the appropriate format
testSaveFormat :: Toolkit -> TestTree
testSaveFormat Asymptote = testCase "asymptote does not support format selection" $ return ()
testSaveFormat tk =
testCase "saves in the appropriate format" $ do
let postfix = unpack . cls $ tk
Expand Down Expand Up @@ -403,6 +407,7 @@ trivialContent Plotsjl = "using Plots; x = 1:10; y = rand(10); plot(x, y);"
trivialContent PlantUML = "@startuml\nAlice -> Bob: test\n@enduml"
trivialContent SageMath = "G = plot(sin, 1, 10)"
trivialContent D2 = "x -> y -> z"
trivialContent Asymptote = "draw((0,0)--(1,0));"

addCaption :: String -> Block -> Block
addCaption caption (CodeBlock (id', cls, attrs) script) =
Expand Down
1 change: 1 addition & 0 deletions tests/includes/asymptote.asy
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// This is comment in Asymptote
Loading
Loading