Write javascript in your markdown & execute it. I wanted a way of making sure the javscript that I write in markdown was valid and worked, not only for my own sake, but to ensure the examples and code provided was valid for others to reliably refer to.
evalmd will scan a markdown file searching for a javascript code declaration, all of them are gathered then the string sent to eval.
```javascript
```
or
```js
```
evalmd - Evaluate the javascript in markdown files
Options:
-i, --include Includes prevented blocks [default: false]
-P, --prevent Prevent code from being evaluated [default: false]
-b, --block Change the scope to block level [default: false]
-o, --output Output js [choices: false, true, "preserve", "concat", "preserveAlter", "concatAlter"] [default: false]
-n, --nonstop Runs all files regardless if error [default: false]
-s, --silent Silence `evalmd` logging [default: false]
-u, --uniform Does not use absolute urls when error logging [default: false]
-D, --debug Debug Output [default: false]
-e, --eval Comma-separated list of block kinds to evaluate (e.g. js, sh) [default: "js"]
--sloppy Evaluate code in sloppy (non-strict) mode [default: false]
--eslint Derive parser settings (ecmaVersion, sourceType, parser) from your eslint config per block [default: false]
-h, --help Show help [boolean]
--path Prefix local module with path [default: "./"]
--package Th path of a package.json [default: "./package.json"]
--version Show version number [boolean]
-d, --delimeter [default: false]
Examples:
evalmd <file(s)> Evaluate file(s)
evalmd <file(s)> -n Evaluate file(s) uninterrupted
evalmd <file(s)> -b Evaluate block(s)
evalmd <file(s)> -bn Evaluate block(s) uninterrupted
evalmd <file(s)> -Po Outputs js file(s)
evalmd <file(s)> -Pio Outputs js file(s) with all block(s) (for linting)
evalmd <file(s)> -Pob Outputs block(s)
evalmd <file(s)> -Piob Outputs all blocks(s) (for linting)
evalmd <file(s)> --eval=js,sh Evaluate js and sh block(s)
By default evalmd evaluates js (and javascript) blocks. Use --eval to pick which fenced block kinds are evaluated, given as a comma-separated list - or by repeating the flag. Each kind is dispatched to its own evaluator, so more kinds can be added over time.
evalmd ./readme.md --eval=js,sh
evalmd ./readme.md --eval=js --eval=sh
An sh block is one or more prompts and their expected output.
A prompt line begins with $, %, or >;
every line after it, up to the next prompt, is the command's expected combined stdout/stderr output.
Each command must exit 0 and its output must match, otherwise evalmd exits non-zero.
Multiple prompts per block are supported.
```sh
> echo hello
hello
> node -e "console.log('a'); console.error('b')"
a
b
```
Blocks are evaluated in strict mode by default. Pass --sloppy to evaluate in sloppy (non-strict) mode instead - for example, to use with.
Sloppy blocks use CommonJS (require);
ES import/export syntax is only available in the default strict mode.
Dependency detection parses each block with a fixed ecmaVersion by default, so modern syntax (object spread, etc.) can fail to parse. Pass --eslint to instead derive the parser settings from your own eslint config, per block.
For each block, evalmd resolves the config for the virtual path <file>.md/<n>.js (where <n> is the block number), so eslint overrides (eslintrc) or files (flat config) that target **/*.md/*.js apply — the same convention as eslint-plugin-markdown. This is how each block (or block kind) gets its own settings. eslint 8, 9, and 10 are supported, in both eslintrc and flat config.
--eslint honors ecmaVersion, sourceType, and a configured parser (such as @typescript-eslint/parser). It requires eslint to be installed — evalmd does not depend on it, so nothing changes for users who don't pass --eslint.
Here is a bit of javascript that has an assertion at the end of it. The assertion will throw an error if the result of the .equal is invalid. This file is used as a test to see if evalmd is in working order.
var assert = require('assert')
var helloWorld = 'foo'
assert.equal(helloWorld, 'foo')Here's another one:
var assert = require('assert')
var helloWorld = ['foo', 'bar']
assert.deepEqual(helloWorld, ['foo', 'bar'])If you run this file using test-markdown it will exit with a status code of 0, meaning no exceptions where thrown.
This overall provides a different way of sharing and explaining code, because it's much more formal then a complicated test file.
Try it yourself by executing the command:
npm install evalmd -g
evalmd ./readme.mdIf the command is ran within a node module with a package.main and a package.name then that reference will be replaced throughout your code. For instance the following passes.
var evalmd = require('evalmd')
assert.equal(typeof evalmd, 'function')The preventEval declaration allows you to prevent a code block from being evaluated. There are two different ways of declaring a code block. One is to use an anchor. Here's an example:
[](#preventEval)
```js
module.exports = 'alpha-path'
```
When adding a preventEval declaration in this way the name of the file is the text content of the anchor. Another way to declare a block as a file is using a comment. Here's an example:
```js
// preventEval
module.exports = 'alpha-path'
```
When the first line of a code block is a comment with the word preventEval in front the string after will be interpreted as the file.
Note. The match patterns for
prevent evalandpreventEvalare case-insensitive. SopReVenTeVaLworks just as well.
The fileEval declaration allows you to define a code block as a file. There are two different ways of declaring a code block. One is to use an anchor tag with the href set to #fileEval. Here's an example:
This is the file [./alpha.js](#fileEval).
```js
module.exports = 'alpha-path'
```
When adding a fileEval declaration in this way the name of the file is the text content of the anchor. Another way to declare a block as a file is using a comment. Here's an example:
```js
// fileEval ./alpha.js
module.exports = 'alpha-path'
```
When the first line of a code block is a comment with the word fileEval in front the string after will be interpreted as the file.
Note. If any of the code blocks in a file contain a
fileEvaldeclaration then the entire file will be run asblockScope.
Note. The match patterns for
file evalandfileEvalare case-insensitive. SofILeEvAlworks just as well.
If you want to run code from docs, and your javscript files are in the root directory, you can use the --prepend flag to prepend every local module reference with the value.
Let's say you run the command:
evalmd ./docs/my-document.md --prepend='..'And you have my-document.md with the conents:
```javascript
var alpha = require('./alpha.js')
```
The prepend command will transform this code to this before it executes it.
```javascript
var alpha = require('../alpha.js')
```
Note: it's a prepend
path.join()string, and not a concatenated prepend.
I wanted a way of writing unit tests in markdown. I've been playing around with things like yamadapc/jsdoctest which parses JSDoc declarations looking for @example keywords in source code and creates a test based on them.
- Add ability for custom linting support (<3
standard)