Skip to main content

Change scripts into Markdown documentation

Project description

Bash to Markdown Documentation

builds.sr.ht status

bmd is the dumbest documentation framework you could find on the earth ! It changes your bash scripts into a useful Markdown documentation.

Features

  1. It removes the shebang line for an aesthetic output.
  2. It removes the # string of your bash comments.

You should write all your bash comments into a compliant markdown format, and then it will work.

Also, we don't care about all the Markdown flavours. Choose the one for your use cases.

But, let's dissipate all doubts by seeing a compatibility table :

Flavor bmd
GFM
ExtraMark
All the others

Getting started

Start by documenting a hello world :

# hello.sh: My Hello World bash script
# ------------------------------------
#
# This **hello world** comes from my *heart*.
# See [Hello World!](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program)
# ```sh
echo "Hello World!"
# ```

Indeed, your script code will never be compliant with any Markdown formats.

So, the purposed solution is to encapsulate your code in a code block with the 3 backticks. You can specify the script langage, and you'll have a formated code rendering ! The drawback is : your documentation will be an annoted bash script.

By default, bmd will remove the common scripting langage comment lines but the option --regex should be used to change all others languages.

You can do the trick with a NodeJS script :

// # hello.js
// You know what I mean
// ```js
console.log('Hello World!')
// ```

This one can be changed with ./bmd.sh -r '^\/\/ ?' hello.js

The bash way : bmd.sh

Installing

The bash script should be installed by using curl:

curl https://git.sr.ht/~vlnk/bmd/blob/main/src/bmd.sh > bmd.sh
./bmd.sh
```sh

### How it works ?

It is 2 `sed` commands. That's all folks.

```sh
set -e

bmd () {
  cat "$1" | \
  sed "/^#!/d" | \
  sed -r "s/$2//"
}

How to use it ?

I suggest to do ./bmd.sh bmd.sh, but please, follow the help :

usage () {
  echo "bmd - Bash to Markdown Documentation"
  echo ""
  echo "USAGE: ./bmd.sh [OPTIONS] INPUT"
  echo ""
  echo "Change the script file INPUT to a Markdown documentation."
  echo ""
  echo "Options:"
  echo "-r, --regex PATTERN Specify the regex PATTERN to remove [default: '^# ?']."
  echo "-h, --help          Print help."
}

REGEX="^# ?"
INPUT=""

for i in "$@"; do
  case $i in
    -h|--help)
      usage;
      exit 0;;
    -r|--regex)
      HAS_REGEX=true;;
    *)
      if [ "$HAS_REGEX" ]; then
        REGEX="$i"
        unset HAS_REGEX
      else
        INPUT="$i"
      fi;;
  esac
done

if [ "$INPUT" ]; then
  bmd "$INPUT" "$REGEX"
else
  echo "error: missing required argument 'INPUT'"
fi

The python way : bmd.py

Installing

bmd is published on PyPi under the bmd-py package. You should be able to install it with:

pip install bmd-py
bmd.py --help
```sh

### How it works?

The python script do the same thing as the bash one but without `sed`, it uses `regex` instead

```py
import click
import regex

SHEBANG_REGEX = r'^#!'
REGEX_HELP='Specify the TEXT regex pattern to remove.'

@click.command()
@click.argument('input')
@click.option('-r', '--regex', 'pattern', default='^# ?', show_default=True, help=REGEX_HELP)
def bmd(input, pattern):
  """Change the script file INPUT to a Markdown documentation."""
  with open(input) as f:
    output = []

    for line in f:
      if not regex.match(SHEBANG_REGEX, line):
        if regex.match(pattern, line):
          output.append(
            regex.sub(pattern, '', line)
          )
        else:
          output.append(line)

    print(''.join(output), end='')

if __name__ == '__main__':
    bmd()

The javascript way : bmd.js

Installing

bmd is published on npm under the bmd-js package. You should be able to install it with:

npm install bmd-js
bmd-js --help

How it works?

The javascript code is using the NodeJS API to do the same thing as others. Is uses the asynchronous reading of each line to do the job.

const fs = require('fs')
const readline = require('readline');
const { program } = require('commander')

const SHEBANG_REGEX = /^#!/

function bmd (input, pattern) {
  const output = []
  const regex = new RegExp(pattern)
  const rl = readline.createInterface({
    input: fs.createReadStream(input),
    output: process.stdout,
    terminal: false
  });

  rl.on('line', (line) => {
    if (!line.match(SHEBANG_REGEX)) {
      if (line.match(regex)) {
        output.push(
          line.replace(regex, '')
        )
      } else {
        output.push(line)
      }
    }
  })

  rl.on('close', () => {
    process.stdout.write(
      output.join('\n') + '\n'
    );
  });
}

let input = ''

program
  .name('bmd.js')
  .description('Change the script file INPUT to a Markdown documentation.')
  .arguments('<INPUT>')
  .action(inputArg => { input = inputArg })
  .option('-r, --regex <PATTERN>', 'Specify the regex PATTERN to remove.', '^# ?')
  .parse(process.argv)

bmd(input, program.regex)

Contributing

Don't hesitate to submit issues in the bmd tracker.

Testing

Each new contribution should be applied with an associated unit test. The bmd CI is triggered on every push with:

.PHONY: test
test: install-all
	./tasks/test.sh

Documenting

I recommand you to use the pre-commit hook in order to always generate the new README.md file:

cd bmd
ln hooks/* .git/hooks/

But the README can be generated manually by using make doc:

.PHONY: doc
doc:
	./tasks/doc.sh 'README.md'

Building and publishing

Check the supported distributions:

Don't forget to be logged before publishing a new bmd package !

The Makefile contains all recipes in order to:

  • install dependencies (bmd-py, bmd-js)
  • bundle package (bmd-py, bmd-js)
  • check package (bmd-py)
  • publish (bmd-py, bmd-js)
.PHONY: install-py
install-py:
	pip3 install -r requirements.txt

.PHONY: build-py
bundle-py:
	python3 setup.py sdist

.PHONY: check-py
check-py: bundle-py
	twine check dist/*

.PHONY: publish-py
 publish-py: clean bundle-py
	twine upload dist/*

.PHONY: install-js
install-js:
	npm install

.PHONY: bundle-js
bundle-js:
	npm pack

.PHONY: publish-js
publish-js:
	npm publish

.PHONY: install-all
install-all: install-py install-js

.PHONY: publish-all
publish-all: publish-py publish-js

clean:
	if [ -d 'dist' ]; then rm -rd 'dist'; fi
	if [ -d 'bmd_py.egg-info' ]; then rm -rd 'bmd_py.egg-info'; fi

Foire aux Questions

  • Is it a joke ? Yes, and no. I wrote this for my own usage, I hope it would be useful for your owns.
  • Is it tested with all the flavours ? Of course not.
  • Where did you get this dumb idea ? From the rustdoc tool.
  • Is it a meta program? Yes, bmd is documented with itself.

KISS, @vlnk

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bmd-py-1.1.0.tar.gz (5.4 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page