Adding text¶
Add Markdown text to a document with the @, |, and call forms.
Every line of prose in a CMX document is a text block. You append one by handing a string to doc. Start with the example, then pick the form that reads best.
from cmx import doc
doc.config(__file__)
doc @ "# Experiment Report"
doc @ "Training finished. Results follow."
doc.flush()
# Experiment Report
Training finished. Results follow.
The three equivalent forms¶
There are three ways to append a text block. They do the same thing — append a Text block (with end="\n" by default) and return doc — so you can chain further calls off any of them.
doc("# Title", end="\n") # call form (end="\n" is the default)
doc @ "# Title" # prefix @ operator
"# Title" | doc # postfix | operator
Every block ends with end="\n" unless you override it on the call form — see Controlling line endings below.
A tuple spreads into one block per item:
doc @ ("First paragraph.", "Second paragraph.")
Warning
The pipe only works with the string on the left: "text" | doc. The left-side form doc | other raises NotImplementedError.
Multi-line text and dedent¶
Use a triple-quoted string for multi-line content. Text is dedented by default (dedent=True), so the common leading indentation is stripped and indented source stays clean in the output.
with doc:
doc @ """
## Results
The model converged after 12 epochs.
- Accuracy: 0.97
- Loss: 0.08
"""
## Results
The model converged after 12 epochs.
- Accuracy: 0.97
- Loss: 0.08
The leading spaces from the source indentation are gone, but the blank lines and list structure are preserved.
Controlling line endings with end=¶
Each text block ends with a single newline by default (end="\n"). Pass end= on the call form to change it. Only the trailing run of newlines is replaced — newlines inside the block are left alone.
Use end="" to keep the next block on the same line:
doc("Status: ")
doc("OK")
Status:
OK
With end="" on the first block, the two join:
doc("Status: ", end="")
doc("OK")
Status: OK
Because only the trailing newlines change, a multi-line block keeps its internal structure while you control just the final separator.
Note
end= is a keyword argument, so it is available on the call form doc("...", end="..."). The @ and | operators take a single value and use the default ending.
When to use each form¶
All three forms are functionally identical; choose for readability.
Form |
Reads best for |
|---|---|
|
Passing arguments such as |
|
Quick prose where the document leads the line. |
`“…” |
doc` |
Be consistent within a file. Reach for the call form whenever you need a keyword argument, since @ and | accept only the text.
Inside with doc:¶
All three forms work inside a capture block. The captured source and any text you append appear in document order, interleaved with doc.print() output.
with doc:
doc @ "## Summary"
"Run completed without errors." | doc
doc.print(f"Elapsed: {elapsed:.1f}s")
Next steps¶
Printing — Add computed output with
doc.print().Context managers — Control what appears using
with doc:,doc.hide, anddoc.skip.