zimbatm / mdsh

`$ mdsh` # a markdown shell pre-processor
https://zimbatm.github.io/mdsh/
MIT License
123 stars 11 forks source link

add syntax for using existing snippet as input #57

Open katexochen opened 9 months ago

katexochen commented 9 months ago

As far as I understand mdsh, it is currently used to (re-)generate markdown snippets. It would be nice if a command could update an existing snippet, so we don't have to generate the entire thing in code but rather modify the tiny bit we are interested in.

This could be implemented by injecting the target block as stdin:

& sed -e 's/foo/bar/'

loooooooooooooooooooooooong snippet foo

Run mdsh. foo is fed as stdin to sed. Result:

& sed -e 's/foo/bar/'

loooooooooooooooooooooooong snippet bar

This could for example be used to update things like versions in more complex markdown blocks.

zimbatm commented 9 months ago

Can you give me a more concrete example of the use case? I'm having trouble figuring out how it would work in practice.

katexochen commented 9 months ago

Sure. The following is an example that instructs the reader to install a program. The goal is to point to a concrete release, but keep the release number up to date.

Example 1:


Download the latest CLI from our release and put it into your PATH:

! new=$(curl -fsSw "%{redirect_url}" https://github.com/errata-ai/vale-action/releases/latest | rev | cut -d '/' -f1 | rev) $ echo -e "curl -fLO https://github.com/errata-ai/vale-action/releases/download/${new}/vale\nmv vale /usr/local/bin/vale" as sh

curl -fLO https://github.com/errata-ai/vale-action/releases/download/v2.1.0/vale
mv vale /usr/local/bin/vale

However, to my current understanding, the template must currently be places in the inline shell code, which makes Example 1 quite repetitive.

Let's say we introduce a new inline shell operator &, which is similar to $, but in addition injects the code block underneath the statement into stdin. We could write the previous example as

Example 2:


Download the latest CLI from our release and put it into your PATH:

! new=$(curl -fsSw "%{redirect_url}" https://github.com/errata-ai/vale-action/releases/latest | rev | cut -d '/' -f1 | rev) & sed -e "s|download/[^/]+|download/${new}|" as sh

curl -fLO https://github.com/errata-ai/vale-action/releases/download/v2.1.0/vale
mv vale /usr/local/bin/vale

The two lines in the code fence of Example 2 are put into the stdin of sed, so sed can just work on the content of the code block that already exists.

Might be even clearer with the following, using cat as the identity operator.

Example 3:


& cat

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

Now matter how often you run mdsh on Example 3, the text will always stay the same, as we put the text into stdin of cat, and cat will just output it.