Template documents
Your document, filled with the model. Write the specification, the interface
control document or the test report in Word or LibreOffice, as your company
lays it out — its title page, styles, headers and tables — and put placeholders
where the model's content goes. archec doc fills them:
archec doc main.arche --template spec.docx -o spec-filled.docx
archec doc main.arche --template report.odt -o report.odt
The template is a .docx (or a .dotx) or an .odt (or an .ott); the result
is a document of the same kind. Nothing else is needed: no Word, no LibreOffice,
no pandoc. It is the idea of Capella's M2Doc and OpenMBEE's DocGen, with a
smaller language. An example: examples/templates/autonomous-car-spec.docx, for examples/autonomous-car/main.arche.
Placeholders#
A placeholder is written between {{ and }}, anywhere text goes: a heading,
a paragraph, a table cell. Spaces inside are free.
| Placeholder | What it gives |
|---|---|
{{ requirement REQ-1 .text }} |
a field of one element: requirement, system, component, part Car.brakes, message, test-plan, case, hazard… |
{{ requirement REQ-1 }} |
its label (its id when it has none) |
{{ project .version }} |
a field of the project; {{ project }} is its name |
{{ .text }} |
a field of the element the loop is on (a field the element does not have is read on the loops around it) |
{{ count requirements where status=draft }} |
how many elements a selection gives |
{{ diagram Car }} |
the block diagram of a system, as a picture; {{ diagram }} the system archec sim runs |
{{ date }} |
today, as 2026-11-10 |
Fields#
Any property, by its name: .text, .status, .priority, .owner,
.rationale, .tags, .kind, .layer, .verifies… A list gives its values
separated by commas; a flag written alone (tbc) gives true. A part has the
properties of its definition it does not set itself. And:
| Field | What it is |
|---|---|
.id, .label |
the name, and the label (the name when there is none) |
.text |
a requirement's text, else its description, else its ears |
.satisfied-by, .verified-by |
what satisfies or verifies a requirement, by the traces |
.path |
where a part is: Car.brakes |
.definition |
a part's definition |
.type, .direction, .value |
a port's or variable's type, a port's direction, a constant's value |
.index |
the place in its loop: 1, 2, 3… |
.file, .line |
where it is written |
Loops#
{{#each requirements}} … {{/each}} repeats what is between, once per
element. Where the two tags are says what repeats:
- in one paragraph: the text between them;
- in two cells, or two rows, of one table (or two paragraphs of one cell):
the rows, from the one with
{{#each}}to the one with{{/each}}. A requirement table is one row:{{#each requirements}}{{ .id }}in the first cell,{{ .text }}{{/each}}in the last; - in two paragraphs: the paragraphs from the first to the last. A paragraph that holds only the tag is left out of the document.
What a loop goes over: requirements, systems, parts (every part of every
system), components (the definitions), ports, links, messages, types,
constants, test-plans, cases, scenarios, functions, hazards,
safety-goals, threats, deployments, interfaces, variants, parameters,
states, transitions… Inside a loop, a name the element holds goes over its
own: {{#each cases}} in a test plan, {{#each ports}} or {{#each parts}} in
a part or a system, {{#each fields}} in a message, {{#each states}} in a
part with a state machine.
where#
where keeps the elements a condition holds for, as a viewpoint's filter does:
| Condition | Holds when |
|---|---|
status=approved |
the field is that value |
tag=safety,asil-d |
one of these (values ORed) |
status!=draft |
it is none of these |
text~brake |
the field contains the text (any case) |
rationale |
the field is written |
view=compute |
the viewpoint compute shows it (its kinds, layers, tags, text) |
Conditions joined by and must all hold: {{#each requirements where tag=safety and status!=draft}}.
A value with spaces is quoted: owner="A. Martin".
if#
{{#if status=approved}}…{{/if}}, inside a loop, keeps what is between when
the element passes the condition; the same conditions as where, laid out as a
loop is.
Diagrams#
{{ diagram Car }} puts the system's block diagram where it is — its parts,
their ports and the links, laid out as archec sim --html lays them out — six and
a half inches wide at most. In a .docx it is an SVG, which Word 2016 and later
show, with a PNG beside it of the same boxes and lines without the words, for
older readers. In an .odt it is an SVG, which LibreOffice shows. A diagram goes
in the body of the document, not in a header or a footer.
When Word cuts a placeholder#
Word saves a placeholder typed in several goes — corrected, partly bold, marked by the spelling checker — as several pieces of text. archec reads the pieces of a paragraph as one text and puts each placeholder back in its first piece, so it keeps that piece's formatting. A placeholder still has to be in one paragraph.
When something cannot be filled#
A placeholder archec cannot read, an element that does not exist, a loop
without its end: the document is written all the same, with
[archec: no requirement REQ-9] where the value would be, and each problem is
printed. archec doc then exits 1, so a pipeline sees it.