#Formatter
This document defines the currently implemented Masterbelt formatting behavior.
The formatter is intentionally minimal at this stage. Future syntax additions must extend this document before or together with formatter changes.
#Options
The formatter accepts an indentation string option.
The indentation string is used for one indentation level inside grouped declarations. Callers should derive this value from the user's editor configuration when available.
If no indentation string is provided, the formatter uses two spaces.
#Source Files
The formatter parses source text and emits top-level declarations, statements, and comments in source order.
Top-level items are separated by one blank line.
The formatted output ends with one trailing line feed.
#Comments
Line comments and block comments are preserved.
Line comments and block comments that appear as top-level items are emitted on their own lines in source order.
Consecutive top-level line comments and block comments are kept together without blank lines between them.
A top-level line comment or block comment immediately followed by a declaration or statement is kept adjacent to that declaration or statement, with no blank line inserted between the comment and the following item.
Line comments that appear after a declaration item or expression statement on the same source line are preserved as trailing line comments on the formatted line.
Inside grouped const declarations, line comments and block comments are indented by one indentation level.
#Documentation Comments
Documentation comments are emitted immediately before the declaration, statement, or grouped const item they document.
The formatter preserves the documentation comment text after the leading ///.
Top-level documentation comments are not indented.
Grouped const item documentation comments are indented by one indentation level.
#Const Declarations
A single-item const declaration is formatted on one line:
const A = 1
const A: int = 1
pub const A: bool = true
A const declaration with more than one item is formatted as a group:
pub const (
A = 1
B: string = "x"
)
Grouped const items are indented by one indentation level.
The outer visibility modifier applies to the group and is emitted before const.
#Expression Statements
Expression statements are formatted as their expression.
#Master Validation Section
The validation section of a master (validation.md) is formatted as a brace-delimited section. When a master documents a canonical section order, the validation section follows filter and precedes static, matching the grammar order.
- The
eachandallscope groups each indent one level deeper than thevalidationsection. Consecutive groups are separated by exactly one blank line. - Within a group, each
validate <id> { ... }block indents one level deeper than the group. Consecutivevalidateblocks are separated by exactly one blank line. - An
assert <expr>statement is formatted like any other statement. Rule bodies reuse the existing statement and expression formatting.
master Records {
record { primary ID: int, Name: string, Value: int }
validation {
each {
validate nameRequired {
assert row.Name != ""
}
validate valuePositive {
assert row.Value > 0
}
}
all {
validate checkValueSum {
let total = 0
for row in table {
total = total + row.Value
}
assert total < 1000
}
}
}
}
#Master Scope Section
A master scope declaration is formatted as [pub ][indexed ]scope name(params) body with canonical spacing. The two modifiers always render in pub indexed scope order regardless of their surface spelling.
- A block-body scope renders its body one level deeper than the declaration, reusing the function-block statement and expression formatting; the
returnand any chained method calls follow the existing expression style. - An arrow-body scope renders
=> expressionon the declaration line. - Each scope declaration sits at the master-body indent and is separated from neighbouring sections by exactly one blank line, the same as the other sections.
master Records {
record { primary id: int, age: int, gender: int }
scope adult() {
return self.where(fn(row) => row.age.ge(20))
}
pub scope genderedAdult(gender: int) {
return self.adult().gendered(gender)
}
indexed scope youngest() => self.orderBy(fn(row) => row.age.asc())
}
#Literals
Null and boolean literals are emitted as null, true, and false.
Integer literals preserve their parsed source spelling.
String literals are emitted from their decoded value using the supported escape sequences.