embedmd

command module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 23, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

README

Build and Test Go Reference Go Report Card

embedmd

This is a maintained fork of campoy/embedmd. The original project no longer takes changes, so this fork continues the work. It contains security fixes and features that upstream does not have. See MIGRATING.md if you come from the original tool.

Are you tired of copy pasting your code into your README.md file, just to forget about it later on and have unsynced copies? Or even worse, code that does not even compile?

Then embedmd is for you!

embedmd embeds files or fractions of files into Markdown files. It does so by searching embedmd commands, which are a subset of the Markdown syntax for comments. This means they are invisible when Markdown is rendered, so they can be kept in the file as pointers to the origin of the embedded text.

The command receives a list of Markdown files. You must give at least one file. The command does not read from the standard input.

The format of an embedmd command is:

[embedmd]:# (pathOrURL language /start regexp/ /end regexp/)

The embedded code will be extracted from the file at pathOrURL, which can either be a relative path to a file in the local file system (using always forward slashes as directory separator) or a URL starting with http:// or https://. If the pathOrURL is a URL the tool will fetch the content in that URL. The embedded content starts at the first line that matches /start regexp/ and finishes at the first line matching /end regexp/.

Omitting the the second regular expression will embed only the piece of text that matches /regexp/:

[embedmd]:# (pathOrURL language /regexp/)

To embed the whole line matching a regular expression you can use:

[embedmd]:# (pathOrURL language /.*regexp.*/)

To embed from a point to the end you should use:

[embedmd]:# (pathOrURL language /start regexp/ $)

To embed a whole file, omit both regular expressions:

[embedmd]:# (pathOrURL language)

You can omit the language in any of the previous commands, and the extension of the file will be used for the snippet syntax highlighting.

This works when the file extensions matches the name of the language (like Go files, since .go matches go). However, this will fail with other files like .md whose language name is markdown.

[embedmd]:# (file.ext)

Options

Options can be added after the regular expressions in an embedmd command.

Excluding delimiter lines

Prefix a regexp with ! to use it as a boundary but exclude the matching line from the output. This is useful when you use comments in your code to mark snippet boundaries:

// snippet-start
fmt.Println("hello")
// snippet-end
[embedmd]:# (example.go go !/\/\/ snippet-start/ !/\/\/ snippet-end/)

This embeds only fmt.Println("hello"), excluding the marker comments.

You can also exclude just the start or just the end:

[embedmd]:# (example.go go !/\/\/ start/ /end/)
Stripping indentation

Code inside functions is typically indented. The dedent option removes the common leading whitespace from all lines, so your Markdown code blocks are not unnecessarily indented:

[embedmd]:# (example.go go !/\/\/ snippet-start/ !/\/\/ snippet-end/ dedent)
Trimming trailing blank lines

Go's gofmt inserts a blank line between code and a following comment. The trim option removes trailing blank lines from the extracted content:

[embedmd]:# (example.go go !/\/\/ snippet-start/ !/\/\/ snippet-end/ trim)
Text substitution

The s/old/new/ option replaces all occurrences of old with new in the extracted content. This lets you use placeholder tokens in compilable code:

[embedmd]:# (example.go go /func demo/ /}/ s/ELLIPSIS/.../)

Multiple substitutions can be chained:

[embedmd]:# (example.go go /func/ /}/ s/ELLIPSIS/.../ s/_ = ELLIPSIS/.../)

Write a slash inside old or new as \/:

[embedmd]:# (example.go go s/http:\/\/example.com/https:\/\/example.org/)
Combining options

Options can be combined. They are applied in this order: line exclusion, trailing blank line trimming, dedentation, then text substitution.

[embedmd]:# (example.go go !/\/\/ snippet-start/ !/\/\/ snippet-end/ dedent trim s/ELLIPSIS/.../)

Installation

You can install Go by following these instructions.

embedmd is written in Go, so if you have Go installed you can install it with go install:

go install github.com/veggiemonk/embedmd@latest

This will download the code, compile it, and leave an embedmd binary in $GOPATH/bin.

The binary keeps the name embedmd. If you installed the original tool, the new binary replaces it in $GOPATH/bin.

Pre-built binaries for Linux, macOS, and Windows are attached to each release.

Usage:

Given the two files in sample:

hello.go:

// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("Hello, there, it is", time.Now())
}

docs.md:

# A hello world in Go

Go is very simple, here you can see a whole "hello, world" program.

[embedmd]:# (hello.go)

We can try to embed a file from a directory.

[embedmd]:# (test/hello.go /func main/ $)

You always start with a `package` statement like:

[embedmd]:# (hello.go /package.*/)

Followed by an `import` statement:

[embedmd]:# (hello.go /import/ /\)/)

You can also see how to get the current time:

[embedmd]:# (hello.go /time\.[^)]*\)/)

Flags

  • -w: Executing embedmd -w docs.md will modify docs.md and add the corresponding code snippets, as shown in sample/result.md.

  • -d: Executing embedmd -d docs.md will display the difference between the contents of docs.md and the output of embedmd docs.md.

  • -v: Displays the version.

Exit status

The exit status follows diff(1), so a script can tell a difference from a failure:

Status Meaning
0 Nothing to report.
1 -d found a difference.
2 The run failed.

Use as a library

The embedmd package exposes Process. It takes a context, so you can cancel a run and stop any HTTP fetch in flight.

err := embedmd.Process(ctx, out, in, embedmd.WithBaseDir(dir))

See the package documentation.

License and origin

This project is licensed under the Apache License 2.0. See LICENSE.

The original code was created by Francesc Campoy, first at Google Inc., with other contributors. See NOTICE for the full attribution and for the list of changes that this fork made.

Copyright 2016 Google Inc.
Copyright 2026 Julien Bisconti and the embedmd fork contributors.

This is not an official Google product, and it is not related to the original campoy/embedmd project.

Documentation

Overview

embedmd

embedmd embeds files or fractions of files into markdown files. It does so by searching embedmd commands, which are a subset of the markdown syntax for comments. This means they are invisible when markdown is rendered, so they can be kept in the file as pointers to the origin of the embedded text.

The command receives a list of markdown files to process. At least one file must be provided; reading from standard input is not supported.

embedmd supports two flags: -d: will print the difference of the input file with what the output

would have been if executed.

-w: rewrites the given files rather than writing the output to the standard

output.

The exit status follows diff(1): 0 when there is nothing to report, 1 when -d found a difference, and 2 when the run failed.

For more information on the format of the commands, read the documentation of the github.com/veggiemonk/embedmd/embedmd package.

Directories

Path Synopsis
Package embedmd provides a single function, Process, that parses markdown searching for markdown comments.
Package embedmd provides a single function, Process, that parses markdown searching for markdown comments.
test command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL