█▀█ ▄▀▄ █▄ ▄█ █▀█ █▀▄ █▀█ █ ▀ █ █▀▀
RAMP: Readable Assignment Markup Protocol
RAMP is a human-friendly data format for configuration files and manifests. It is designed to be easy to read, write, and parse across programming languages.
The syntax is intentionally small: key-value assignments, dotted paths, bullets, inline arrays, and two forms of comments. There is no indentation-based nesting and no multi-line string syntax. If you can read a terminal, you can read RAMP.
RAMP does not use tabs or spaces to define structure. Indentation is never meaningful. Leading and trailing whitespace on a line is ignored. Spaces and tabs may appear freely for alignment or readability, but they never change the meaning of a document.
Structure comes only from explicit tokens: keys, assignment operators, bullets, brackets, and commas. You can write every statement starting at column zero, or pad keys for visual columns; both are valid and produce the same result.
Most configuration formats force a trade-off. JSON is unambiguous but hostile to humans. YAML is flexible but full of edge cases that trip up both writers and parsers. TOML is clean yet becomes noisy once nesting deepens. RAMP takes a different path: keep the surface language tiny, make every construct explicit, and leave no room for surprising behaviour.
The result is a format you can learn in minutes, audit by eye, and implement without a large dependency.
server.port, db.user= or :#) and block comments ((# ... #))Document
A RAMP document is a sequence of lines. Each line may contain at
most one statement, optional surrounding whitespace, and an
optional line comment. Empty lines and pure comment lines are
allowed.
Statement
A statement is either a key-value assignment or a bullet item.
Statements form an ordered sequence. Order is part of the abstract
document model (see "ordering" below).
Key path
A key path is one or more segments separated by dots
(.). Each segment begins with a letter or underscore
and may continue with letters, digits, underscores, or hyphens.
Example: server.port, db.credentials.user.
Assignment
A key path is followed by either = or :
and then a value. Both operators are equivalent. Whitespace around
the operator is optional and ignored.
Bullet item
A line that begins with a hyphen followed by whitespace
(- ) introduces a bullet. The remainder of the line is
either a key-value assignment or a bare value.
Bullets produce an ordered list of items. When a bullet contains a key-value assignment, the item is a single-entry map. There is no additional nesting syntax under a bullet and no native map-as-value construct. Related fields are written as successive bullets with dotted keys, or the application groups them after parsing.
This keeps the grammar flat and the parser simple. The cost is that lists of objects are more verbose than in TOML or JSON, and most applications will post-process bullet sequences into richer structures. That post-processing step is expected and intentional.
Value
A value is either a scalar or an inline array. There is no native
syntax for a map as a value. Nested maps are recovered by the host
from dotted key paths after parsing. The RAMP document model is
therefore a flat ordered sequence of statements; the host language
model (nested maps and arrays) is derived from it.
Null
Written as null or ~. These two forms
are the only null literals. All other capitalisations are rejected.
Boolean
Written as true or false (lowercase only).
Any other capitalisation is a syntax error.
Integer
An optional sign followed by one or more digits:
42, -7, +100.
Float
An optional sign, digits, a decimal point, more digits, and an
optional scientific exponent:
3.14, -0.5, 1.5e+10.
Quoted string
Enclosed in double quotes. Supports the escapes
\", \\, \n,
\t, \r, and \uXXXX
(four hex digits). Use quoted strings whenever the value contains
spaces or special characters. In practice almost any non-trivial
string will be quoted; the unquoted form is reserved for simple
identifiers and tokens.
Unquoted string
A single contiguous sequence of characters that does not contain
space, tab, newline, or any of the special characters
, = : # " [ ] { } ( ). An unquoted string is exactly
one token; it cannot contain spaces. If a value needs spaces or
any special character, it must be written as a quoted string.
Example: mode = production is valid.
mode = production mode is a syntax error (two tokens
where one value is expected). Write
mode = "production mode" instead.
Inline array
Square brackets containing zero or more values separated by commas.
Whitespace around elements and a trailing comma are both allowed:
[ "a", "b", "c", ].
Line comment
Starts with # and continues to the end of the line.
Everything after the # is ignored.
Block comment
Starts with (# and ends with #). Block
comments may appear anywhere whitespace is allowed, including in
the middle of a statement:
port = (# default #) 8080.
A RAMP document is an ordered sequence of statements. Parsers must preserve that order in their intermediate representation.
When mapping into a host language:
Applications that care about order (for example, generating output that round-trips) should use an ordered map or keep the original statement list.
RAMP has no multi-line string syntax. Every value lives on a single line. Long text must be written as one quoted string, split into an array of strings that the application joins, or referenced from an external file.
External file references are the recommended way to handle certificates, multi-line scripts, long messages, or any content that does not fit comfortably on one line. A conventional pattern is a string value that the application treats as a path:
tls.cert = "./certs/server.pem" tls.key = "./certs/server.key" script = "./scripts/deploy.sh"
The format itself does not open or interpret those paths; that is the application's responsibility. This keeps the parser simple and avoids inventing ad-hoc "join this array" conventions inside the language.
The absence of multi-line strings is a deliberate trade-off. It eliminates an entire class of whitespace and chomping rules. RAMP is aimed at configuration and manifests where values are usually short. For documents dominated by long free-form text, a different format is more appropriate.
The RAMP document model is intentionally flat: an ordered sequence of statements (assignments and bullets). Nested maps and richer object lists are not expressed directly in the syntax. They are recovered by the host after parsing, typically by:
This separation keeps the parser small and the grammar unambiguous. The cost is that the on-disk form is further from the in-memory form than in JSON. That is accepted: the on-disk form prioritises human readability and implementability; the host is free to build whatever structure it needs.
a single document that exercises every construct
# line comment at the top # both assignment operators are equivalent name = "edge-proxy" version : 1.4.2 # null forms (only null and ~) cache.ttl = null cache.backup = ~ # booleans (lowercase only) debug = false strict = true # integers (signed and unsigned) workers = 4 retries = -1 max_conns = +1024 # floats, including scientific notation timeouts.connect = 2.5 timeouts.backoff = 1.5e+3 timeouts.jitter = -0.25 # quoted strings with escapes and spaces message = "hello\tworld\n" path = "C:\\data\\file.txt" unicode = "smile \u263A" title = "production mode" # unquoted strings (single token, no spaces) mode = production region = us-east-1 # inline arrays (trailing comma allowed) features = [ "gzip", "http2", "metrics", ] ports = [ 80, 443, 8080 ] mixed = [ true, 42, "ok", null, ] # dotted key paths (nesting recovered by host) listen.host = 0.0.0.0 listen.port = 8080 db.credentials.user = app db.credentials.pass = "s3cret" # external file references for large content tls.cert = "./certs/server.pem" tls.key = "./certs/server.key" # block comment mid-statement log.level = (# production only #) "warn" log.path = (# unused in test #) "/var/log/app.log" # bullets with key-value pairs # (flat list of single-entry maps; host may group into objects) - id = primary - url = "https://api.example.com" - weight = 10 # bullets with bare values - "first item" - second-item - 42 - true - ~ # empty lines and trailing comments are fine end = true # done
Because the language has no significant whitespace and a very small set of tokens, a conforming parser can be written in a few hundred lines of most languages. Recommended behaviour:
null / ~ for null and only lowercase true / false for booleansRAMP v1.0 is frozen. The language prioritises clarity and implementability. Future revisions will be numbered and remain backward-compatible with documents that validate against the v1.0 rules.