Skip to content

Instantly share code, notes, and snippets.

@gmolveau
Last active March 28, 2023 16:19
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gmolveau/67d10dfaea1fdd729865b2f8d46f7488 to your computer and use it in GitHub Desktop.
Save gmolveau/67d10dfaea1fdd729865b2f8d46f7488 to your computer and use it in GitHub Desktop.
Markdown Bash Execute

Markdown Bash Execute

  • Execute bash code block from a markdown file → ```bash [...] ```

Getting started

  • add this to your .bashrc or .zshrc or .what-ever.rc
# markdown bash execute
function mbe() {
  if [ -f "$1" ]; then
    cat $1 | # print the file
    sed -n '/```bash/,/```/p' | # get the bash code blocks
    sed 's/```bash//g' | #  remove the ```bash
    sed 's/```//g' | # remove the trailing ```
    sed '/^$/d' | # remove empty lines
    /usr/bin/env sh ; # execute the command
  else
    echo "${1} is not valid" ;
  fi
}
  • call with mbe file.md

  • Enjoy !

@Skitionek
Copy link

Skitionek commented Jul 13, 2020

Following the idea this one will print out text in between (+respecting indentation):

#!/usr/bin/env bash

# markdown bash execute
function mbe() {
  if [ -f "$1" ]; then
    code=false
    while IFS= read -r line; do
        if [[ $line =~ "\`\`\`bash" ]]; then
            buff=""
            code=true
        elif [[ $line =~ "\`\`\`" ]]; then
            echo "$space$ $buff$space>"
            code=false
			eval $(echo ${buff} | sed -e 's/^[[:space:]]*//') 2>&1 | sed -e "s/^/$space  /" || exit 1
        elif $code; then
            space=$(echo "$line" | sed -e 's/^\([[:space:]]*\).*/\1/')
            trimmed=$(echo "$line" | sed 's/"/\"/' | sed -e 's/^[[:space:]]*//')
			buff="$buff$trimmed
"
		else
			echo "$line"
        fi
    done < "$1"
  else
    echo "${1} is not valid" ;
  fi
}

mbe ./scripts/setup/README.md

Example output:

# Setup

1. Change pipenv setting to create virtual environment in project.
    $ export PIPENV_VENV_IN_PROJECT=True
    >

2. Create virtual environment (try common location if python version was not found):
    $ pipenv --python 3.6.8 || pipenv --python ~/.pyenv/versions/3.6.8/bin/python
    >
      Virtualenv already exists!

@FilBot3
Copy link

FilBot3 commented Nov 2, 2021

These do seem to have a problem executing multi-line statements, as well as persisting state across code blocks. I also couldn't seemingly do multiple lines of code in a single block. I do see the example uses export so the variable is not just a local variable.

@gmolveau
Copy link
Author

gmolveau commented Nov 2, 2021

Could you provide a quick example please ?

@andyp1xe1
Copy link

Here is a little hack I made up, it uses heredocs and replaces codeblocks with the output:

#! /usr/bin/dash
#md-sh:

dash << end_sh
$1 << end_md
$(cat $2)
end_md
end_sh

Here is an example on how to use:

md-sh cat doc.md

or to format the output:

md-sh mdcat doc.md

@DJRHails
Copy link

Should have searched before writing my own!

If anyone needs multiple language / block support, I ended up doing something slightly more involved with python:

shot silly-moon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment