cmd / mdembed
mdembed
is a command line tool to embed programming file contents in Markdown.
It is open source.
Install
go install github.com/croaky/mdembed
For that to work, Go must be installed and
$(go env GOPATH)/bin
must be on your $PATH
:
export PATH="$HOME/go/bin:$PATH"
Use
In input1.md
:
# Examples
Embed a whole file:
```embed
f1.rb
```
Embed multiple whole files:
```embed
f1.rb
f2.go
```
Embed specific lines in a file:
```embed
f3.js log
```
Embed multiple blocks within the same file:
```embed
f4.html h1
f4.html ul
```
Embed Markdown files and their embeds recursively:
```embed
input2.md
```
In f1.rb
:
puts "hi"
In f2.go
:
package main
import "fmt"
func main() {
fmt.Println("hi")
}
In f3.js
:
console.log("Not embedded");
// emdo log
console.log("hi");
// emdone log
console.log("Not embedded");
In f4.html
:
<!doctype html>
<html>
<head>
<title>Not embedded</title>
</head>
<body>
<!-- emdo h1 -->
<h1>h1</h1>
<!-- emdone h1 -->
<p>not embedded</p>
<!-- emdo ul -->
<ul>
<li>1</li>
<li>2</li>
</ul>
<!-- emdone ul -->
</body>
</html>
In input2.md
:
## Input2
Embed from within an embedded Markdown file:
```embed
f1.rb
```
Run:
cat input.md | mdembed
The output will be:
# Examples
Embed a whole file:
```rb
# f1.rb
puts "hi"
```
Embed multiple whole files:
```rb
# f1.rb
puts "hi"
```
```go
// f2.go
package main
import "fmt"
func main() {
fmt.Println("hi")
}
```
Embed specific lines in a file:
```js
// f3.js
console.log("hi");
```
Embed multiple blocks within the same file:
```html
<!-- f4.html -->
<h1>h1</h1>
```
```html
<!-- f4.html -->
<ul>
<li>1</li>
<li>2</li>
</ul>
```
Embed Markdown files and their embeds recursively:
## Input2
Embed from within an embedded Markdown file:
```rb
# f1.rb
puts "hi"
```
mdembed
embeds code blocks in the output Markdown,
removing surrounding whitespace.
The file extension is used as the code fence attribute.
If emdo
and emdone
magic comments were used, it will only embed the code
block wrapped by the magic comments.
It is aware of code comment styles for Ada, Assembly, Awk, Bash, C, Clojure, COBOL, C++, C#, CSS, D, Dart, Elm, Erlang, Elixir, Fortran, F#, Gleam, Go, Haml, Haskell, HTML, Java, Julia, JavaScript, Kotlin, Lisp, Logo, Lua, MATLAB, OCaml, Objective-C, Mojo, Nim, Pascal, PHP, Perl, Prolog, Python, R, Ruby, Rust, Scala, Schema, Sass, Shell, Solidity, SQL, Swift, Tcl, TypeScript, VBScript, Visual Basic, Wolfram, and Zig.
If you reference another Markdown file, mdembed
will embed its contents
directly, recursively embedding its code blocks.
So what?
I wanted the following workflow in Vim:
- Open
tmp.md
in my project. - Write a prompt for an LLM (Large Language Model), referencing other files, or subsets of files, in my project.
- Hit a key combo (
<Leader>+r
) to send the contents to an LLM and render the LLM's response in a vertical split.
mdembed
handles the Markdown parsing steps.
mods handles the LLM steps:
go install github.com/charmbracelet/mods@latest
So, my Vim config runs the following Unix pipeline in a vertical split:
cat example.md | mdembed | mods