2 ms·
I did a little bit of work on a similar idea but for embedding shell commands in Markdown. My system is mainly targeted towards readmes and other documentation
by codetrotter 5y ago
I did a little bit of work on a similar idea but for embedding shell commands in Markdown.
My system is mainly targeted towards readmes and other documentation and the way that it works is as follows:
1. My program reads in a markdown file.
2. It finds fenced code blocks in the file, that have info strings corresponding to a shell scripting language like bash or zsh. For example
```zsh
grep foo bar.txt | sort -u
```
3. Then it looks at each of those fenced code blocks and checks if they are immediately followed by another fenced code block but where the info string is that of plain text. For example
```text
foo
foobar
```
When you author the document you insert empty fenced code blocks like
```text
```
4. For each shell script fenced code block that is followed by a plain text fenced code block, the commands in the shell script fenced code block are executed and the output is captured.
5. The captured output of each such shell script fenced code block is inserted into the corresponding plain text fenced code block that follows it.
6. Any fenced code block that is not immediately followed by a plain text fenced code block is ignored and not executed.
All together this allows for, among other possibilities:
- Updating outputs of sample commands in documentation all in one go.
- IPython Notebook style documents for shell scripts, except not interactive.
- Including commands that you want to inform the user about but which you explicitly don’t want to actually automatically execute.
I have a simple version of it for my own use that I put together a while back, and I started making a version of it that will eventually be usable by anyone. I will probably try and do a Show HN post about it when it is ready for others to use. Currently, completing the version that will be usable by anyone is on the back burner while I am working on some other things.
In my program, each block of code is run in an independent shell. So if you define a variable in one code block then it is available throughout that same code block but does not “transfer” to other code blocks. This is by design.
Command blocks are executed sequentially so that one can do operations that make changes to the file system in different blocks and still have the outcome be as excepted.
For example, you might be writing about generating and optimising png files, and your document might contain something like
First let's generate a 128x128 solid grey PNG and look at the size of the file.
```zsh
convert -size 100x100 xc:grey image1.png
ls -al image1.png
```
```text
```
The resulting file is quite small already.
But we can shave off a few bytes using a PNG optimizer.
```zsh
optipng image1.png
```
```text
```
And that saves us about 10% in file size in this case.
And for me this is the way that seems natural for the use case that what my program is doing. That the code blocks share operating system state and file system state, but not variables.