Skip to content

Synchronizing Documentation and Output Images

Available since v0.10

In software technical documentation, command examples written in prose frequently fall out of sync with embedded execution screenshots. Manually recapturing screenshots, saving files under matching paths, and updating image links every time a tool is upgraded invites human error and stale references. Furthermore, static site generators (SSGs) such as Astro halt build pipelines if an image referenced in Markdown is missing locally, hindering local development when images represent commands runnable only in specific operating systems or CI environments.

The console2svg batch markdown command detects comment markers embedded directly within Markdown or MDX files, executes terminal commands via pseudo-terminals (PTYs), and automatically reflects the generated images back into the documentation. It eliminates manual screenshot workflows and keeps technical documentation strictly aligned with actual command execution.

Embedding images into documentation involves two straightforward steps: placing markers and running the batch synchronization command.

  1. Insert a comment marker in the format <!-- c2s:: [command] --> where you want the terminal graphic to appear:

    example.md
    Running `dotnet --info` outputs the following runtime details:
    <!-- c2s:: dotnet --info | head -n10 -->
  2. Run batch markdown, specifying the input documentation directory and the asset output directory:

    Terminal
    console2svg batch markdown -i ./docs -o ./assets
  3. The command scans the Markdown files, parses the markers, captures terminal execution outputs, and saves SVG images into the output folder. Simultaneously, the source Markdown file is updated automatically, inserting an image link immediately following the marker:

    example.md
    Running `dotnet --info` outputs the following runtime details:
    <!-- c2s:: dotnet --info | head -n10 -->
    ![dotnet --info | head -n10](assets/generated/a1b2c3d4.svg)

If an image reference already exists directly after a marker, the link is preserved without duplication, and only the underlying image file is overwritten with updated output.

Depending on your site builder setup, the physical destination of asset files on disk may differ from the URL path required inside Markdown documents. The --link-base option bridges this gap:

Terminal
console2svg batch markdown \
-i ./docs \
-o ./my-site/public/assets \
--link-base /assets

For instance, in Astro, static files placed under /public/assets/ are referenced from Markdown using absolute root paths such as /assets/filename.svg. By specifying the disk path with -o and the public URL root with --link-base, the path prefix written into Markdown links can be tailored to match any asset pipeline.

Whether generated graphics should be committed into Git version control depends on repository size policies and team workflow preferences.

When maintaining a modest number of figures and preferring a self-contained repository, commit both generated image files and updated Markdown files directly to Git:

Terminal
console2svg batch markdown -i docs -o assets
git add docs assets
git commit -m "docs: update command execution screenshots"

In this model, freshly cloned local environments already contain all required graphics, allowing developers to build documentation sites locally without executing extra generation steps.

When maintaining large documentation catalogs where image binaries would bloat repository clone sizes, add output folders to .gitignore and retain only markers in Markdown files without image tags:

example.md
<!-- c2s:: echo "Hero Image" -->
Omitting manual image tags delegates asset management to the automated build pipeline.

In this model, execute batch markdown during CI deployment to generate assets on the fly:

deploy.sh
console2svg batch markdown -i ./docs -o ./public/assets
npm run build

However, because image files are absent in fresh local clones, SSG builds would fail due to missing assets. This issue is addressed by using either batch restore or --placeholder.

Synchronizing Remote Assets for Local Builds

Section titled “Synchronizing Remote Assets for Local Builds”

When generating images exclusively on CI, use dedicated auxiliary commands to ensure smooth local development.

When generating images, batch markdown automatically produces an asset manifest file named assets.json alongside the generated images:

  • Directoryassets/
    • Directorygenerated/
      • a1b2c3d4.svg
    • assets.json

Deploying this manifest file along with public assets on your documentation host allows developers to restore pre-rendered images to their local machines via batch restore:

Terminal
console2svg batch restore -o ./assets \
https://example.com/assets/assets.json

Add the --prune flag to automatically delete obsolete local files that no longer exist in the remote manifest.

Bypassing Asset Generation via --placeholder

Section titled “Bypassing Asset Generation via --placeholder”

When you want to build and verify documentation layout immediately without downloading remote images over the network, use --placeholder:

Terminal
console2svg batch markdown -i ./docs -o ./assets --placeholder

This flag skips command execution entirely and creates 0-byte placeholder files for every referenced image path, satisfying SSG link checkers and allowing writers to focus on editing text and styles.

Markers specifying identical commands, parameters, and terminal dimensions share a single cached image asset, even if placed across disparate documentation files.

<!-- c2s:: -w 100 -h 12 --- dotnet --info | head -n10 -->

This deduplication is particularly beneficial for multilingual documentation. When English, Japanese, and Chinese versions of a guide display the exact same command execution, each page references the identical generated graphic, minimizing storage overhead and build duration.

Markers support extensive customization beyond simple inline commands, including window decorations, alternative formats, and automated lifecycle hooks.

Options supported by console2svg capture can be specified directly before the delimiter (--):

example.md
<!-- c2s:: -w 100 -h 10 -d macos -t nord --format png -- dotnet --version -->

Specifying --format png generates a raster PNG instead of SVG, automatically updating Markdown links to .png.

Controlling Execution Lifecycles with YAML

Section titled “Controlling Execution Lifecycles with YAML”

To manage environment setup before execution or clean up temporary files afterward, declare structured lifecycle hooks using YAML within the comment marker:

example.md
<!-- c2s:: -w 100 -h 10 -d macos
setup:
dotnet build
capture:
dotnet run --no-build
teardown:
rm -f temporary-file
-->

The script in setup prepares prerequisites silently without appearing in the captured screenshot. Only output produced by capture is rendered into the final image. Regardless of command success or failure, scripts defined in teardown run unconditionally upon completion.

To capture the execution of sample code displayed in documentation, assign a c2s-id to the code block and reference it inside the marker using {code:id}:

example.md
```csharp c2s-id=program
Console.WriteLine("Hello from C#!");
```
```bash c2s-id=run
dotnet run app.cs
```
<!-- c2s::
setup: |
cat > app.cs <<'EOF'
{code:program}
EOF
capture: "{code:run}"
teardown: rm -f app.cs
-->

This pattern eliminates dual maintenance of explanatory code snippets and executable scripts, ensuring that updating a documentation sample immediately updates the corresponding visual output.

Scripts defined in marker setup, capture, and teardown blocks execute directly in your host shell environment. Never execute batch markdown against untrusted Markdown files or pull requests from external contributors without review. When automating execution in CI pipelines, strictly scope permissions and restrict automated runs to trusted branches.