This is a Markdown linter for MoonBit. It gathers all MoonBit codes in Markdown, checks them using MoonBit's compiler, and reports any diagnostics.
To use the MoonBit Markdown Linter, you need to install the MoonBit compiler.
npm install -g @moonbit/markdown-linter
mdlint
checks for possible errors in your moonbit code inside markdown documents:
// test.md
```moonbit // defaults to normal
fn id[T : Eq](x : T) -> T {
x
}
```
```moonbit expr
id(5)
```
```moonbit no-check
// this is not moonbit at all
unsafe def gcd_unsafe: ℕ -> ℕ -> ℕ
| a, 0 => a
| a, b + 1 => gcd_unsafe (b + 1) (a % (b + 1))
```
```moonbit enclosed
fn fib(n : Int) -> Int {
match n {
0 => 0
1 => true // type error here
_ => fib(n - 1) + fib(n - 2)
}
}
```
Use mdlint test.md
to check (the actual output is colored):
The line number is correctly mapped to that in the markdown document, this is especially useful for debugging. Note that for multiple markdown files, each of them results in a independent project.
As seen above, mdlint
supports several code environments including
normal
: codeblocks marked w/normal
are copied as-is to generate moonbit project. Default behavior. Linting is performed.expr
: codeblocks marked w/expr
are wrapped inside aprintln()
, this environment only supports expressions. Linting is performed.no-check
: codeblocks marked w/no-check
are ignored, not included in the generated project at all. Linting is NOT performed, suitable for writing pcode.enclose
: codeblocks marked w/enclose
are enclosed inside ainit()
. Mainly used to avoid naming conflicts. Linting is performed.
It's common to write not-so-well-formed code (e.g. Unused variables) for demonstration purposes, not production. It would be annoying if the compiler keeps complaining about those trivial problems. mdlint
acknowledges that and provides --suppress,-s
to suppress specific compiler error/warning in the output. It can be parsed inline:
```moonbit enclosed -e1001 -e1002
fn fib(n : Int) -> Int {
match n {
0 => 0
1 => true // type error here
_ => fib(n - 1) + fib(n - 2)
}
}
```
or provided through cli:
mdlint -s=e1001,e1002 test.md # use comma-separated list
- the special
-s=all-warnings
suppresses all warnings frommoon
. - the
--ignore,-i
specifically ignores all error codes from codeblocks, useful for temporarily enabling error/warnings suppressed before.
--dump,-d
dumps the project generated from the corresponding markdown document in the same directory with the extension .proj
. e.g. test.md
results in test.md.proj
.
A project generated by mdlint
typically has the structure
.
├── README.md
├── lib
│ ├── fib.mbt
│ └── moon.pkg.json
├── moon.mod.json
├── moon.pkg.json
└── top.mbt
the -f
flag is used to specify which moonbit source file the code should be copied to. This flag can only be parsed inline:
// fib() now goes into lib/fib.mbt
```moonbit -e1001 -f=fib.mbt
fn fib(n : Int) -> Int {
match n {
0 => 0
1 => true // type error here
_ => fib(n - 1) + fib(n - 2)
}
}
```
By default, codeblocks are copied to top.mbt
. If -f
is provided with a value other than top.mbt
(such as fib.mbt
), mdlint
would place that codeblock inside lib/*.mbt
. This hopefully provides very basic literate programming utility.