Parse code fences from text.
go install github.com/unstoppablemango/fenced@latestOr add as a tool in your go.mod:
go get -tool github.com/unstoppablemango/fencedOr download a binary from GitHub Releases:
# Linux/macOS
curl -L https://github.com/UnstoppableMango/fenced/releases/latest/download/fenced_$(uname -s)_$(uname -m).tar.gz | tar xz
mkdir -p ~/.local/bin && mv fenced ~/.local/bin/Parse fenced code blocks from a file:
$ fenced testdata/markdown.md
import "fmt"
func main() {
fmt.Println("Hello, World!")
}Parse from multiple files:
$ fenced file1.md file2.md file3.md
# Output from all files concatenatedAdd a delimiter between code blocks:
$ fenced -d --- file1.md file2.md
# First block
---
# Second block
---
# Third blockAn implicit newline is appended after the delimiter by default. Use -N/--no-implicit-newline to disable this:
$ fenced -d --- -N file1.md file2.md
# First block
---# Second block
---# Third blockOr pipe content to stdin:
$ cat testdata/markdown.md | fenced
import "fmt"
func main() {
fmt.Println("Hello, World!")
}Use - to explicitly read from stdin (useful in scripts or mixing with files):
$ echo '```bash
echo "Hello"
```' | fenced -
echo "Hello"
$ fenced file1.md - file2.md < input.md
# Reads file1.md, then stdin, then file2.mdRun directly without installing:
nix run github:UnstoppableMango/fenced -- testdata/markdown.mdInstall into your profile:
nix profile install github:UnstoppableMango/fencedAs a flake (NixOS configuration):
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
fenced.url = "github:UnstoppableMango/fenced";
};
outputs = { nixpkgs, fenced, ... }: {
nixosConfigurations.mySystem = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [{
environment.systemPackages = [ fenced.packages.x86_64-linux.default ];
}];
};
};
}Or use in a devShell:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
fenced.url = "github:UnstoppableMango/fenced";
};
outputs = { nixpkgs, fenced, ... }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.${system}.default = pkgs.mkShell {
packages = [ fenced.packages.${system}.default ];
};
};
}docker run -v $(pwd):/data ghcr.io/unstoppablemango/fenced:latest /data/testdata/markdown.mdOr with stdin:
cat testdata/markdown.md | docker run -i ghcr.io/unstoppablemango/fenced:latestimport (
"fmt"
"io/fs"
"os"
fenced "github.com/unstoppablemango/fenced/pkg"
)
func main() {
f, err := os.Open("testdata/markdown.md")
if err != nil {
panic(err)
}
defer f.Close()
blocks, err := fenced.Parse(f)
if err != nil {
panic(err)
}
for _, b := range blocks {
fmt.Println(b)
}
}Write a single block to an io.Writer:
import (
"os"
fenced "github.com/unstoppablemango/fenced/pkg"
)
func main() {
block := fenced.Block{
Lang: "go",
Content: "fmt.Println(\"Hello, World!\")\n",
}
if _, err := fenced.Write(os.Stdout, block); err != nil {
panic(err)
}
}Write multiple blocks with a delimiter using WriteAll:
import (
"os"
fenced "github.com/unstoppablemango/fenced/pkg"
)
func main() {
f, err := os.Open("testdata/markdown.md")
if err != nil {
panic(err)
}
defer f.Close()
blocks, err := fenced.Parse(f)
if err != nil {
panic(err)
}
if _, err := fenced.WriteAll(os.Stdout, blocks, fenced.WithDelimiter("---")); err != nil {
panic(err)
}
}