Bitgram
Packet headers, bit fields, and register maps from YAML, JSON, or Ruby.
One definition. ASCII, Unicode, SVG, PNG, and JPEG.
Features · Installation · Quick start · Ruby API · Documentation
bitgram render --preset tcp -o tcp.svg
Features
- One layout, five outputs. Generate text for READMEs and RFC-style specifications, SVG for the web, or PNG and JPEG for documents and slides.
- Flexible bit layouts. Choose 1–128 bits per row, split fields across rows, merge address blocks, and represent variable-length data.
- Readable labels. Automatic wrapping, short names, vertical labels, and footnotes, with Unicode display widths for Japanese text.
- Style and context. Light, dark, monochrome, and automatic themes; field colors, reserved hatching, optional borders, and byte offsets.
- Ready-made protocols. Start with TCP, UDP, IPv4, IPv6, ICMP Echo, or ARP, then customize the definition.
- Reproducible output. Deterministic diagrams, validation with paths and YAML line numbers, and a shared rendering pipeline for the CLI and Ruby API.
Installation
Requires Ruby 3.3+. Install from a source checkout:
bundle install
bundle exec rake installASCII, Unicode, and SVG use the unicode-display_width gem and need no native rendering tools.
Install one of these converters. Automatic selection follows the order below.
| Backend | PNG | JPEG | Requirement |
|---|---|---|---|
| vips | ✓ | ✓ |
ruby-vips gem + libvips |
| rsvg | ✓ | — |
rsvg-convert command |
| ImageMagick | ✓ | ✓ |
magick or convert command |
For vips, add this to your application's Gemfile:
gem "ruby-vips", "~> 2.3"Install the native library, then run bundle install:
# macOS
brew install vips
# Ubuntu
sudo apt-get install libvips-dev fonts-noto-cjkRun bitgram doctor to check converters and CJK fonts. See the raster settings for scale, background, quality, and backend selection.
Quick start
Render a bundled preset immediately:
bitgram render --preset udp
bitgram render --preset tcp -o tcp.svg 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
. .
. Data .
. .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
To define your own diagram, save this as udp.yml:
version: 1
title: UDP Header
fields:
- { name: Source Port, bits: 16 }
- { name: Destination Port, bits: 16 }
- { name: Length, bits: 16 }
- { name: Checksum, bits: 16 }
- { name: Data, bits: variable }Render it, choose a style, or validate it before generating output:
bitgram render udp.yml -o udp.svg
bitgram render udp.yml --ascii-style unicode
bitgram render udp.yml -o udp.png --scale 2 # Requires a raster converter
bitgram validate udp.yml --strictUse bitgram init ipv6 > ipv6.yml to start from an editable preset. Browse the generated examples: TCP · UDP · IPv4 · IPv6 · ICMP · ARP.
Ruby API
Load a file, a YAML/JSON string, a Hash, or a bundled preset:
require "bitgram"
diagram = Bitgram.load_file("udp.yml")
puts diagram.to_ascii(style: :unicode)
diagram.save("udp.svg", theme: "dark")
diagram.save("udp.jpg", scale: 2, quality: 85) # Requires a raster converterOr describe a register directly in Ruby:
register = Bitgram.define(title: "CTRL") do
row_bits 16
bit_order :lsb0
field "EN", bits: 1, description: "Enable"
field "MODE", bits: 3
reserved 4
field "DIV", bits: 8
end
puts register.to_asciiThe Ruby API guide covers Hash and string inputs, overrides, diagnostics, and access to the logical layout.
Configuration
Set options in the definition, override them from the CLI, or pass renderer keywords in Ruby.
| Setting | Default | Purpose |
|---|---|---|
layout.row_bits |
32 |
Bits per row, from 1 to 128 |
layout.bit_order |
msb0 |
Number bits from the left or use lsb0 from the right |
layout.offsets |
none |
Show decimal or hexadecimal byte offsets |
ascii.style |
rfc |
Choose RFC-style or Unicode borders |
svg.theme |
default |
Use default, mono, dark, auto, or a theme file |
raster.scale |
2 |
Scale PNG/JPEG output |
bitgram render --preset tcp --theme dark --set layout.offsets=hex -o tcp.svgFields also support bytes, short, value, reserved, optional, and fill. See the complete format reference and JSON Schema for all settings and editor completion.
Documentation
| Guide | What's inside |
|---|---|
| Definition format | Fields, layout, themes, fitting strategies, and limits |
| CLI reference | Commands, options, stdin, validation, and exit codes |
| Ruby API | Loading, rendering, DSL, diagnostics, and layout inspection |
| Protocol presets | Bundled definitions and their RFC sources |
| Development | Tests, golden files, benchmarks, and implementation decisions |
| Releasing | Packaging and Trusted Publishing setup |
- Unicode borders assume ambiguous-width characters occupy one column. If your terminal displays them as two, use RFC style or adjust the terminal setting.
- PNG/JPEG use installed fonts. Japanese labels need a CJK font such as Noto Sans CJK JP;
bitgram doctorchecks fontconfig when available. - SVG text widths are estimated. Increase
svg.char_width_ratioor choose a monospace font if labels extend beyond their cells. - YAML aliases and object tags are rejected. Input strings and files are limited to 1 MiB, definitions to 10,000 fields and 4,096 logical rows, and raster output to 50 million pixels. Definitions never cause network requests.
Development
bundle install
bundle exec rake # RSpec + RuboCop
bundle exec yard docRun RASTER=0 bundle exec rake examples to regenerate text and SVG examples. To include PNG, install a converter and run bundle exec rake examples.
For all raster backends, enable the optional bundle with BUNDLE_WITH=raster bundle install, then run BUNDLE_WITH=raster REQUIRE_RASTER=1 bundle exec rake. See the development guide for prerequisites and verification details.
License
Released under the MIT License.