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 details)

Uploaded Source

File details

Details for the file bmd-py-1.1.0.tar.gz.

File metadata

  • Download URL: bmd-py-1.1.0.tar.gz
  • Upload date:
  • Size: 5.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/47.3.1.post20200731 requests-toolbelt/0.9.1 tqdm/4.47.0 CPython/3.7.8

File hashes

Hashes for bmd-py-1.1.0.tar.gz
Algorithm Hash digest
SHA256 3726b20073d751b922aefe7ec464dc8addf27cb1c266f0c10a4b123fdadc7e65
MD5 45c760b2ccb3fbc7f75882cf7b99ab48
BLAKE2b-256 fdf28c38f6cabc4beb0ecc137bc39306998be3f50f4a8a781e2612064e96d19f

See more details on using hashes here.

Supported by

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