All Projects → monopole → mdrip

monopole / mdrip

Licence: MIT license
turns markdown into tested tutorials

Programming Languages

go
31211 projects - #10 most used programming language
Dockerfile
14818 projects

Projects that are alternatives of or similar to mdrip

dotfiles
🏎 my dotfiles for macOS
Stars: ✭ 33 (+10%)
Mutual labels:  tmux
tools
Little codes here and there to automate some of my boring daily routines and configurations
Stars: ✭ 82 (+173.33%)
Mutual labels:  tmux
tmux-base16-statusline
Tmux Base16 Statusline
Stars: ✭ 24 (-20%)
Mutual labels:  tmux
dotfiles
My dotfiles and some scripts
Stars: ✭ 34 (+13.33%)
Mutual labels:  tmux
dotfiles
My dotfiles
Stars: ✭ 204 (+580%)
Mutual labels:  tmux
dotfiles
Configuration files for my development environment.
Stars: ✭ 14 (-53.33%)
Mutual labels:  tmux
configuration
Config files
Stars: ✭ 12 (-60%)
Mutual labels:  tmux
chappe
🧑‍💻 Developer Docs builder. Write guides in Markdown and references in API Blueprint. Comes with a built-in search engine.
Stars: ✭ 132 (+340%)
Mutual labels:  documentation-tool
lumen-cms
GraphQL API-First CMS based on NodeJS and Vue 2, Nuxt and Vuetify
Stars: ✭ 77 (+156.67%)
Mutual labels:  cms-framework
dotfiles
PJ's dotfiles - There are many like it but this one is mine
Stars: ✭ 24 (-20%)
Mutual labels:  tmux
dotfiles
My dot files and dev environment using bash, tmux and vim
Stars: ✭ 61 (+103.33%)
Mutual labels:  tmux
magpie
Dotfiles of my minimal Unix system geared for media, programming & writing
Stars: ✭ 37 (+23.33%)
Mutual labels:  tmux
tdab
Create side and top bars in tmux easily, along with a "devour" style command.
Stars: ✭ 14 (-53.33%)
Mutual labels:  tmux
tmux-weather
🌤 Weather plugin for tmux
Stars: ✭ 40 (+33.33%)
Mutual labels:  tmux
appear
reveal terminal programs in the gui
Stars: ✭ 29 (-3.33%)
Mutual labels:  tmux
dotfiles
shell, git, vim, tmux .etc dotfiles, managed via gnu stow
Stars: ✭ 20 (-33.33%)
Mutual labels:  tmux
dotfiles
My work setup
Stars: ✭ 14 (-53.33%)
Mutual labels:  tmux
strapi-pro
Strapi.io with image upload, location, wyswyg input
Stars: ✭ 14 (-53.33%)
Mutual labels:  cms-framework
mx.sh
Lean and opinionated tmux session manager.
Stars: ✭ 20 (-33.33%)
Mutual labels:  tmux
dotfiles
All my dotfiles (vim, zsh, tmux, etc.) in a single place
Stars: ✭ 42 (+40%)
Mutual labels:  tmux

mdrip

mdrip turns a directory hierarchy of markdown files into a testable, tutorial web app.

  • Navigate with keys (mouse usage optional).
  • Track progress with check marks.
  • Immediately execute code blocks in tmux without copy/paste.

Or just use mdrip to place markdown-based tutorials under CI/CD testing, to avoid disappointing users.

Build Status Go Report Card

Installation

Assuming Go installed just:

go get github.com/monopole/mdrip

or put it in your tmp dir

GOBIN=$TMPDIR go install github.com/monopole/mdrip

Execution

mdrip {filePath}

This searches the given path for files named *.md (ignoring everything else), and parses the markdown into memory.

The filePath argument can be

  • a single local file,
  • a local directory,
  • a github URL in the style gh:{user}/{repoName},
  • or a particular file or a directory in the repo, e.g. gh:{user}/{repoName}/foo/bar.

What happens next depends on the --mode flag.

Demo Mode: make a tutorial web app

mdrip --mode demo {filePath}

This serves rendered markdown at http://localhost:8000. Change the endpoint using --port and --hostname.

Clicking on a code block in your browser (or navigating to it using keys only) will copy its contents to your clipboard. Hit '?' in the browser to see key controls.

If you have a local instance of tmux running, the mdrip server sends the code block directly to active tmux pane for immediate execution.

Example:

Render the content you are now reading locally:

$TMPDIR/mdrip --mode demo gh:monopole/mdrip/README.md

Visit localhost:8000.

If you have it, start tmux. Click on command blocks in your browser to send them directly to your active tmux window.

Print Mode: extract code to stdout

In this default mode, the command

eval "$(mdrip file.md)"

runs extracted blocks in the current terminal, while

mdrip file.md | source /dev/stdin

runs extracted blocks in a piped shell that exits with extracted code status. The difference between these two compositions is the same as the difference between

eval "$(exit)"

and

echo exit | source /dev/stdin

The former affects your current shell, the latter does not. To stop on error, pipe mdrip output to bash -e.

Example:

Print all the fenced code blocks from this README:

$TMPDIR/mdrip gh:monopole/mdrip/README.md

Test Mode: place markdown code under test

mdrip --mode test /path/to/tutorial.md

runs extracted blocks in an mdrip subshell, leaving the executing shell unchanged.

In this mode, mdrip captures the stdout and stderr of the subprocess, reporting only blocks that fail, facilitating error diagnosis. Normally, mdrip exits with non-zero status only when used incorrectly, e.g. file not found, bad flags, etc. In test mode, mdrip will exit with the status of any failing code block.

This mode is an instance of literate programming in that code (shell commands) are embedded in explanatory content (markdown). One can use here documents to incorporate any programming language into the tests (see the example below).

Labels

Fenced code blocks can be preceeded in the markdown by a one-line HTML comment with embedded labels in this form:

<!-- @initializeCluster @tutorial03 @test -->
```
echo hello
```

Then the --label flag can be used to extract only code blocks with the given label, e.g.

mdrip --label test {filePath}

discards all code blocks other than those with a preceding @test label.

This can be used, for example, to gather blocks that should be placed under test, and ignore those that shouldn't. An example of the latter would be commands that prompt an interactive user to login (test frameworks typically have their own notion of an authenticated user).

Special labels

  • The first label on a block is slightly special, in that it's reported as the block name for logging in test mode. So its useful to treat it as a method name for the block, e.g. @initializeCluster or @createWebServer.

  • The label @sleep causes mdrip to insert a sleep 2 command after the block. Appropriate if one is starting a server in the background in that block, and want to impose a short wait (which you'd get implicitly if a human were executing the blocks more slowly as part of a demo).

Example:

This Go tutorial has code blocks that write, compile and run a Go program.

Use this to extract blocks to stdout:

alias mdrip=$TMPDIR/mdrip
mdrip --label lesson1 \
    gh:monopole/mdrip/data/example_tutorial.md

Test the code from the markdown in a subshell:

clear
mdrip --mode test --label lesson1 \
    gh:monopole/mdrip/data/example_tutorial.md
echo $?

The above command should show an error, and exit with non-zero status, because that example tutorial has several baked-in errors.

To see success, download the example and confirm that it fails locally:

tmp=$(mktemp -d)
git clone https://github.com/monopole/mdrip.git $tmp
file=$tmp/data/example_tutorial.md
mdrip --mode test --label lesson1 $file

Fix the problems:

sed -i 's|comment this|// comment this|' $file
sed -i 's|intended to fail|intended to succeed|' $file
sed -i 's|badCommandToTriggerTestFailure|echo Hello|' $file

Run the test again:

mdrip --mode test --label lesson1 $file
echo $?

The return code should be zero.

So, adding a line like

mdrip --mode test --label {someLabel} {filePath}

to your CI/CD test framework covers the execution path determined by that label.

Tips for writing markdown tutorials

  • Place commands that the reader should copy/paste/execute in fenced code blocks.

  • Eschew preceding commands with redundant prompts (e.g. $).

  • Code-style text not intended for immediate execution, e.g. alternative commands or example output, should be in a fenced code block indented via a block quote. This makes them invisible to mdrip.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].