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

Proposal: custom renderers #52

Open
Tenchi2xh opened this issue Aug 27, 2018 · 4 comments
Open

Proposal: custom renderers #52

Tenchi2xh opened this issue Aug 27, 2018 · 4 comments

Comments

@Tenchi2xh
Copy link
Contributor

Tenchi2xh commented Aug 27, 2018

It's kind of a crazy idea, but after thinking for a while about how to manage this in the settings, I think I got a simple solution in the end.

It's a bit long to explain so I'll let the images do the talking:

screen shot 2018-08-27 at 23 45 36

screen shot 2018-08-27 at 23 45 41 1

screen shot 2018-08-27 at 23 45 44

screen shot 2018-08-27 at 23 54 28

screen shot 2018-08-27 at 23 54 30

screen shot 2018-08-27 at 23 54 32

screen shot 2018-08-27 at 23 54 35

screen shot 2018-08-27 at 23 54 37

What do you think? It would make it much easier for including diagrams. The alternative, inlining all diagrams and ASCII art, would take a lot of space in the markdown file, and make it harder to maintain: lots compiling, copy-pasting, and escaping special characters.

Here's in text format the config format I showed in the screenshots above:

imageRenderers:
  - pattern: .*\.(monopic|mono)
    command: monodraw --unicode {0}
  - pattern: .*\.puml
    command: java -jar ~/plantuml.jar -f txt {0}

spanRenderers:
  figlet:
    parameters:
      font: -f {0}
    command: figlet {0} {1}

  toilet:
    parameters:
      font: -f {0}
      filter: -F {0}
    command: toilet {0} {1}

  rainbowCow:
    parameters:
      cowfile: -f {0}
    command: cowsay {0} {1} | lolcat -F 0.3

(Instead of regexes, it could be just lists of strings containing the relevant extensions)

Edit: something I forgot! When using the markdown image syntax (or HTML), the text/alt part could be rendered underneath the rendered image like so:

screen shot 2018-08-28 at 11 25 05

@jaspervdj
Copy link
Owner

I would still like to have something like this but I haven't yet decided on a clean format.

One design decision to make is if we want to support a long-running process (like the https://github.com/gibiansky/IHaskell kernel) or if we just evaluate the command before displaying the slide and assume it exits.

@nbrandaleone
Copy link

+1 on the idea. I would love for Patat to support AsciiArt, or some sort of UTF-8 graphics.

@Floby
Copy link

Floby commented Jul 20, 2020

I support this because I had to inline my ascii schematics inside a

 block for it to render properly

@jaspervdj
Copy link
Owner

I'd like to pick this up now. I am leaning towards a design where an evaluator is set at the top level, e.g.:

patat:
  eval:
    command: bash

Whenever a code block is highlighted as eval, we:

  1. Start a process with the given command
  2. Feed the contents of the code block to the stdin handle of that process
  3. Render the stdout of the command in a code block

This means that this presentation:

---
patat:
  eval:
    command: bash
...

```eval
echo "Hello, world!"
```

Is equivalent to the following presentation:

```
Hello World!
```

Some questions / concerns around the design:

  1. Should the output always be wrapped in a code block? It definitely seems
    useful for most use cases. But not having it wrapped in a code block means
    you can use a command that renders markdown, which is also powerful.
    However, doing that would require us to re-parse the slides, so I'm leaning
    towards not doing this for now.
  2. Should we display the input as well as the output? This seems useful if
    you're teaching a programming languages and you want to show REPL
    examples! However, you probably wouldn't want it for the images example
    mentioned by @Tenchi2xh. Maybe it should be configurable?
  3. If we're displaying the input as I mentioned in (2), should the user press
    a key before we display the output? That seems useful as well for teaching.
    Maybe there needs to be a setting here as well? Or do we do this by
    default?
  4. Do we need to care about the order of commands? If we have something
    like mkdir foo on slide 2, and touch foo/bar on slide 3, what happens if
    the user skips to slide 3? Should we always run all commands just once
    in-order and cache the result? That may cause a noticeable delay when
    opening the presentation or seeking...

jaspervdj added a commit that referenced this issue Sep 10, 2020
Fragments deal with how content is shown piece by piece.  For example, if we
have the slide:

    Foo

    . . .

    Bar

There are two fragments.  First, only `Foo` is visible.  When the user goes
to the next fragment, `Foo` and `Bar` are both visible.

The first implementation of fragments in patat would compute the state of
all the visible items.  In this case, that would be:

1.  `[Foo]`
2.  `[Foo, Bar]`

This does not work elegantly if you want another pass to add further fragments:
you now need to split `Foo` in multiple places (and the thunk is no longer
shared).  This PR refactors this to use "instructions" over the slide content.
For the example, these instructions would be:

1.  `Append [Foo]`
2.  `Pause`
3.  `Append [Bar]`

The `Pause`s are explicit, and indicate how many fragments are present.

There are more constructors, for manipulation of lists which is necessary
if nested lists are shown incrementally.  This all for allows much nicer
manipulation of the fragments, which in turn is useful for #52.
jaspervdj added a commit that referenced this issue Sep 10, 2020
Fragments deal with how content is shown piece by piece.  For example, if we
have the slide:

    Foo

    . . .

    Bar

There are two fragments.  First, only `Foo` is visible.  When the user goes
to the next fragment, `Foo` and `Bar` are both visible.

The first implementation of fragments in patat would compute the state of
all the visible items.  In this case, that would be:

1.  `[Foo]`
2.  `[Foo, Bar]`

This does not work elegantly if you want another pass to add further fragments:
you now need to split `Foo` in multiple places (and the thunk is no longer
shared).  This PR refactors this to use "instructions" over the slide content.
For the example, these instructions would be:

1.  `Append [Foo]`
2.  `Pause`
3.  `Append [Bar]`

The `Pause`s are explicit, and indicate how many fragments are present.

There are more constructors, for manipulation of lists which is necessary
if nested lists are shown incrementally.  This all for allows much nicer
manipulation of the fragments, which in turn is useful for #52.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants