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

Add eval.wrap option #158

Merged
merged 1 commit into from
Nov 25, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,8 @@ empty list `[]`.

### Images

#### Native Images support

`patat-0.8.0.0` and newer include images support for some terminal emulators.

```markdown
Expand Down Expand Up @@ -624,6 +626,33 @@ patat:
path: '/home/jasper/.local/bin/w3mimgdisplay'
```

#### Images using Evaluation

Rather than using the built-in image support, you can also use programs that
write ASCII escape codes directly to the screen with
[code evaluation](#evaluating-code).

In order to do that, for example, we could configure `kitten` code snippets
to evaluate using [Kitty]'s command `icat`. This uses the `rawInline` code
setting to ensure that the resulting output is not wrapped in a code block,
and the `fragment` and `replace` settings immediately replace the snippet.

---
patat:
eval:
kitten:
command: sed 's/^/kitten /' | bash
replace: true
fragment: false
wrap: rawInline
...

See, for example:

```kitten
icat --align left dank-meme.jpg
```

### Breadcrumbs

By default, `patat` will print a breadcrumbs-style header, e.g.:
Expand Down Expand Up @@ -660,6 +689,7 @@ _evaluator_ by specifying this in the YAML metadata:
command: irb --noecho --noverbose
fragment: true # Optional
replace: false # Optional
wrap: code # Optional
...

Here is an example of a code block that is evaluated:
Expand All @@ -681,6 +711,12 @@ Aside from the command, there are two more options:
between showing the original code block and the output. Defaults to `true`.
- `replace`: Remove the original code block and replace it with the output
rather than appending the output in a new code block. Defaults to `false`.
- `wrap`: By default, the output is wrapped in a code block again with the
original syntax highlighting. You can customize this behaviour by setting
`wrap` to:
* `code`: the default setting.
* `raw`: no formatting applied.
* `rawInline`: no formatting applied and no trailing newline.

Setting `fragment: false` and `replace: true` offers a way to "filter" code
blocks, which can be used to render ASCII graphics.
Expand Down
14 changes: 10 additions & 4 deletions lib/Patat/Eval.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import qualified Data.Text as T
import qualified Data.Text.IO as T
import Patat.Presentation.Instruction
import Patat.Presentation.Internal
import Patat.Presentation.Settings
import System.Exit (ExitCode (..))
import qualified System.IO as IO
import System.IO.Unsafe (unsafeInterleaveIO)
Expand Down Expand Up @@ -70,15 +71,20 @@ evalBlock settings orig@(Pandoc.CodeBlock attr@(_, classes, _) txt)
ExitFailure i ->
evalCommand <> ": exit code " <> T.pack (show i) <> "\n" <>
erStderr
let fmt = "eval"
blocks = case evalWrap of
EvalWrapCode -> [Pandoc.CodeBlock attr out]
EvalWrapRaw -> [Pandoc.RawBlock fmt out]
EvalWrapRawInline -> [Pandoc.Plain [Pandoc.RawInline fmt out]]
pure $ case (evalFragment, evalReplace) of
(False, True) -> [Append [Pandoc.CodeBlock attr out]]
(False, False) -> [Append [orig, Pandoc.CodeBlock attr out]]
(False, True) -> [Append blocks]
(False, False) -> [Append (orig : blocks)]
(True, True) ->
[ Append [orig], Pause
, Delete, Append [Pandoc.CodeBlock attr out]
, Delete, Append blocks
]
(True, False) ->
[Append [orig], Pause, Append [Pandoc.CodeBlock attr out]]
[Append [orig], Pause, Append blocks]
| _ : _ : _ <- lookupSettings classes settings =
let msg = "patat eval matched multiple settings for " <>
T.intercalate "," classes in
Expand Down
3 changes: 2 additions & 1 deletion lib/Patat/Presentation/Display.hs
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,11 @@ prettyInline ds (Pandoc.Image _attrs text (target, _title)) =
"![" <> themed ds themeImageText (prettyInlines ds text) <> "](" <>
themed ds themeImageTarget (PP.text target) <> ")"

prettyInline _ (Pandoc.RawInline _ t) = PP.text t

-- These elements aren't really supported.
prettyInline ds (Pandoc.Cite _ t) = prettyInlines ds t
prettyInline ds (Pandoc.Span _ t) = prettyInlines ds t
prettyInline _ds (Pandoc.RawInline _ t) = PP.text t
prettyInline ds (Pandoc.Note t) = prettyBlocks ds t
prettyInline ds (Pandoc.Superscript t) = prettyInlines ds t
prettyInline ds (Pandoc.Subscript t) = prettyInlines ds t
Expand Down
44 changes: 32 additions & 12 deletions lib/Patat/Presentation/Settings.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Patat.Presentation.Settings
, ImageSettings (..)

, EvalSettingsMap
, EvalSettingsWrap (..)
, EvalSettings (..)

, SpeakerNotesSettings (..)
Expand All @@ -23,18 +24,18 @@ module Patat.Presentation.Settings


--------------------------------------------------------------------------------
import Control.Monad (mplus)
import qualified Data.Aeson.Extended as A
import qualified Data.Aeson.TH.Extended as A
import qualified Data.Foldable as Foldable
import Data.Function (on)
import qualified Data.HashMap.Strict as HMS
import Data.List (intercalate)
import qualified Data.Text as T
import qualified Patat.Theme as Theme
import Control.Monad (mplus)
import qualified Data.Aeson.Extended as A
import qualified Data.Aeson.TH.Extended as A
import qualified Data.Foldable as Foldable
import Data.Function (on)
import qualified Data.HashMap.Strict as HMS
import Data.List (intercalate)
import qualified Data.Text as T
import qualified Patat.Theme as Theme
import Prelude
import qualified Text.Pandoc as Pandoc
import Text.Read (readMaybe)
import qualified Text.Pandoc as Pandoc
import Text.Read (readMaybe)


--------------------------------------------------------------------------------
Expand Down Expand Up @@ -195,20 +196,39 @@ instance A.FromJSON ImageSettings where
type EvalSettingsMap = HMS.HashMap T.Text EvalSettings


--------------------------------------------------------------------------------
data EvalSettingsWrap
= EvalWrapCode
| EvalWrapRaw
| EvalWrapRawInline
deriving (Show)


--------------------------------------------------------------------------------
instance A.FromJSON EvalSettingsWrap where
parseJSON = A.withText "FromJSON EvalSettingsWrap" $ \txt -> case txt of
"code" -> pure EvalWrapCode
"raw" -> pure EvalWrapRaw
"rawInline" -> pure EvalWrapRawInline
_ -> fail $ "unknown wrap: " <> show txt


--------------------------------------------------------------------------------
data EvalSettings = EvalSettings
{ evalCommand :: !T.Text
, evalReplace :: !Bool
, evalFragment :: !Bool
, evalWrap :: !EvalSettingsWrap
} deriving (Show)


--------------------------------------------------------------------------------
instance A.FromJSON EvalSettings where
parseJSON = A.withObject "FromJSON EvalSettings" $ \o -> EvalSettings
<$> o A..: "command"
<*> o A..:? "replace" A..!= False
<*> o A..:? "replace" A..!= False
<*> o A..:? "fragment" A..!= True
<*> o A..:? "wrap" A..!= EvalWrapCode


--------------------------------------------------------------------------------
Expand Down
52 changes: 52 additions & 0 deletions tests/golden/inputs/eval06.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
patat:
eval:
shImplicit:
command: sh
wrap: code
replace: true
fragment: false
shCode:
command: sh
wrap: code
replace: true
fragment: false
shRaw:
command: sh
wrap: raw
replace: true
fragment: false
shInline:
command: sh
wrap: rawInline
replace: true
fragment: false
...

# Implicit eval slide

~~~{.shImplicit}
printf '\e[1;34m%-6s\e[m' "This is text"
~~~

# Code eval slide

~~~{.shCode}
printf '\e[1;34m%-6s\e[m' "This is text"
~~~

# Raw eval slide

~~~{.shRaw}
printf '\e[1;34m%-6s\e[m' "This is text"
~~~

Newline here...

# Raw Inline eval slide

~~~{.shInline}
printf '\e[1;34m%-6s\e[m' "This is text"
~~~

No newline here...
41 changes: 41 additions & 0 deletions tests/golden/outputs/eval06.md.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
 eval06.md 

# Implicit eval slide

  
  This is text 
  

 1 / 4 

{slide}
 eval06.md 

# Code eval slide

  
  This is text 
  

 2 / 4 

{slide}
 eval06.md 

# Raw eval slide

This is text

Newline here...

 3 / 4 

{slide}
 eval06.md 

# Raw Inline eval slide

This is text
No newline here...

 4 / 4 
Loading