Skip to content
/ markin Public

Easily interpolate shell script output (e.g., 'yourcommand --help') into Markdown files

License

Notifications You must be signed in to change notification settings

ernstki/markin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

markin - interpolate shell script output into Markdown

A tool for inserting the output of shell commands into your Markdown files. Inspired by Cog, but has no dependencies besides awk, which you already have on your system. Works with your $SHELL.

A practical use case would be to insert a Git-derived changelog, or the output of your program's --help option into a Markdown README.

Quickstart

Download markin, put it in your $PATH, and make it executable. See the "Installation" section for a step-by-step.

Given:

<!-- README.md -->
My command's help output:

<!-- {{{markin
# single quotes are not supported--yet (see issue #1)
mycommand --help | sed "s/^/    /"
}}} -->
<!-- {{{end}}} -->

then:

markin README.md > README.md_ 

# see if you like what it did
diff README.md*

# if you're happy with that, overwrite the original
mv -i README.md{_,}

An in-place option (-i like sed) will very likely be added later. To be honest though, I probably wouldn't do these steps by hand, because that's what Makefiles and Git pre-commit hooks are for.

This produces:

<!-- README.md -->
My command's help output:

<!-- {{{markin
# single quotes are not supported--yet (see issue #1)
mycommand --help | sed "s/^/    /"
}}} -->
    mycommand - do the things
  
    usage:
      mycommand [-h|--help]
      mycommand [-i|--input-file] [-o|--output-file] [-v|--verbose]
  
    where:
    
<!-- {{{end}}} -->

Which renders as:

My command's help output:

mycommand - do the things

usage:
  mycommand [-h|--help]
  mycommand [-i|--input-file] [-o|--output-file] [-v|--verbose]

where:
  ⋮

Note that—just like Cog, and unlike conventional template languages—the bits used to programmatically generate the document output are preserved in-place. There is no separate "template file" to have to deal with.

Installation

Assuming a reasonably default macOS or Linux box and the Bash shell:

MARKIN=https://raw.githubusercontent.com/ernstki/markin/master/markin
mkdir -p ~/bin
curl "$MARKIN" > ~/bin/markin
chmod a+x ~/bin/markin

It's quite rare for it not to be these days, but if $HOME/bin is not in your search path, you can update that in your ~/.bash_profile or ~/.profile (whichever one you have):

export PATH=$HOME/bin:$PATH

Log (completely) out and back in in order for this change to take effect. Then double-check to make sure your shell can find it:

which markin

Other tips

If you have moreutils installed, you can update the file in-place with sponge:

markin README.md | sponge README.md

…at least until #3 is implemented.

Test run to see changes side-by-side with the original:

diff README.md <(markin README.md)

# or
sdiff --suppress-common-lines README.md <(markin README.md)

…or, if you have delta:

diff -u README.md <(markin README.md) | delta --side-by-side

That's a lot to type. Try this:

# in your ~/.bashrc, or wherever you put that stuff
markin-diff() {
    for file in "$@"; do
        diff -u "$file" <(markin "$file") | delta --side-by-side
    done
}

Notes

Markin itself is supposed to work with whatever awk you have; if it doesn't that's a bug.

However, macOS and probably BSD have no problem with multiple arguments in the shebang line, so if for some odd reason you wanted to use your /opt/local/bin/gawk from MacPorts, you can do so by updating the first line of the markin script to say:

#!/usr/bin/env gawk -f

Linux doesn't doesn't support this, but unless you're on an embedded system, your /usr/bin/awk is probably gawk anyway. See here for more details and history of the Unix #! line.

I have a preference for using tools that are already on the system, rather than installing some extra package like Jinja, Mustache, or Template Toolkit. Often I'll reach for M4 in cases like this. But the idea of having a README.md.m4 in addition to the output README.md seemed unpalatable. There is already so much crap in the top-level of Git repositories these days. Everybody has /usr/bin/awk, basically built-in, even Windows if you use WSL or Cygwin.

Although 100% inspired by Cog's markers (triple square brackets), I chose

 <!-- {{{markin
 shell-command --option1 --option2
 }}} -->
 Where the output of `shell-command` appears
 <!-- {{{end}}} -->

for the simple reasons that the braces don't have to be escaped in regexes, and the triple curly braces coincide with Vim's default foldmarker.

Bugs / mis-features

Single quotes within shell commands are not currently supported (see #1). This means something as simple as echo "Mornin', y'all!" will crash the script. This is pretty unacceptable. The solution will be to read the entire markin block into a temp file, invoke it with $SHELL and getline the results back in; but, for now, this is how it is.

Inline usage is not currently supported (see #2); what this means is you can't do something like this yet:

# My Program - v. <!--{{{markin: myprogram --version}}}--><!--{{{end}}}-->

…but that is the dream, even if the syntax looks gnarly.

Multi-line strings, line continuation markers (e.g., in Bash, \), and shebangs (alternate interpreters) could be supported later. Pretty easily, I think!

Its similarity to Cog's cog/end markers, and being able to :set foldmethod=marker in Vim and fold the Markin blocks is nifty and all, but I still think you have to type way more symbols than should be necessary to get the job done.

Credits

  • Cog by Ned Batchelder
    • A really neat tool! However, for small automation tasks like this, I work mostly in shell script, so

      import cog
      import subprocess
      cog.outl(subprocess.check_output('myprogram --version'))

      seemed like a lot to remember for what is essentially a one-liner shell script.

License

MIT.

About

Easily interpolate shell script output (e.g., 'yourcommand --help') into Markdown files

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Languages