This is a tool to run Markdown code blocks.
This can be used by CI to guarantee that the samples written in the README will work.
Example repo: https://github.com/lempiji/sandbox-vuepress
Run it as dub fetch md
and dub run md -- README.md
Also, this README.md
is executable.
You can configure how your generated D source file is run by passing in command line arguments to md
:
show help
dub run md -- --help
The code block whose language is specified as d
or D
will be executed.
If there are multiple blocks as shown below, they will be combined and executed.
block 1
import std;
auto message = "Hello, " ~ "Markdown!";
block 2
writeln(message); // Hello, Markdown!
Code blocks specified as disabled
will not be executed, as shown below.
```d disabled
```
disabled code block
throw new Exception("disabled");
Can give an independent scope to a block of code by giving it a name like the following. Even if they are written separately, they will be combined like a block if they have the same name.
```d name=test
```
import std;
auto buf = iota(10).array();
writeln(buf);
If name
is not specified, it is treated as the name main
.
To make a single block of code run independently without being combined with other blocks, give it the attribute single
.
```d single
```
single block
import std;
auto message = "single code block";
writeln(message);
The tool supports several options that can be passed to the execution (dub run
). These options are directly passed as arguments to dub run
.
--build
--compiler
--arch
Example
dub run md -- README.md --build=release --compiler=ldc2 --arch=x86_64
If the current directory is a dub package, the dependency will be automatically added. (using a "path"
based dependency)
For example, if this README is in the same directory as md/dub.sdl
, then can import commands.main
of md
.
import commands.main;
import std.stdio;
writeln("current package: ", loadCurrentProjectName());
It's possible to specify -d <packageName>
or -d <packageName>@<versionString>
such as -d mir-ion@~>2.0.16
to add further dependencies. (long name: --dependency
)
It's possible to specify --dubsdl "<instruction>"
to add a dub.sdl recipe line into the generated file. This option can be used multiple times to add multiple lines.
Specifying this option disables the built-in CWD package dependency addition described above.
The normal code blocks are executed as if they were written in void main() {}
. The source will be generated with void main() {
and }
appended before and after.
If you want the code block to be interpreted as a single source file, you can add a global
attribute to the code block, which will not be combined with other code blocks as with the single
attribute.
```d global
```
single file
import std;
void main()
{
writeln("Hello, Markdown!");
}
Create a .md
directory in the temp directory, generate the source in dub single file format, and run it with a command like dub run --single md_xxx.md
.
It also automatically adds the following comment to the beginning of the source to achieve default package references.
/+ dub.sdl:
dependency "md" path="C:\\work\md"
+/
A normal code block will generate the source enclosed in void main() {}
.
UFCS will not work because the function definition is not a global function.
this code doesn't work
auto sum(R)(R range)
{
import std.range : ElementType;
alias E = ElementType!R;
auto result = E(0);
foreach (x; range)
{
result += x;
}
return result;
}
auto arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
auto result = arr.sum();
It works by setting the global attribute and writing the main function appropriately.
this code works
auto sum(R)(R range)
{
import std.range : ElementType;
alias E = ElementType!R;
auto result = E(0);
foreach (x; range)
{
result += x;
}
return result;
}
void main()
{
auto arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
auto result = arr.sum();
}