Writer API contract

Every writer module exposes the same four output forms as extension functions on its model types. X stands for the format name (Asciidoc, Markdown, Dot, Bnf); x for its lower-case form.

The four forms

Signature Returns Behavior

toX(): String

String

the complete output as one string

writeXTo(out: Appendable)

Unit

appends the output to any Appendable (StringBuilder, java.io.Writer, …​)

writeXTo(sink: Sink)

Unit

writes the output UTF-8 encoded to a kotlinx-io Sink

xFlow(): Flow<String>

Flow<String>

cold flow of output chunks in document order

Writer options

A writer that has an output option takes it as a defaulted parameter on all four forms, rather than adding functions — the four forms stay four. markup-bnf-writer is the only such writer today: toBnf(flavor), writeBnfTo(out, flavor), writeBnfTo(sink, flavor) and bnfFlow(flavor) all take an optional BnfFlavor (default EBNF). The contract below holds per flavor.

Receiver × writer matrix

Receiver markup-asciidoc-writer markup-markdown-writer markup-dot-writer markup-bnf-writer

Markup (document)

toAsciidoc(), writeAsciidocTo(Appendable), writeAsciidocTo(Sink), asciidocFlow()

toMarkdown(), writeMarkdownTo(Appendable), writeMarkdownTo(Sink), markdownFlow()

Table (standalone)

same four forms

same four forms

Graph

toDot(), writeDotTo(Appendable), writeDotTo(Sink), dotFlow()

Grammar

toBnf(), writeBnfTo(Appendable), writeBnfTo(Sink), bnfFlow() — each with an optional BnfFlavor

Packages

Writer module Package

markup-asciidoc-writer

org.markup.poet.dsl.write.asciidoc

markup-markdown-writer

org.markup.poet.dsl.write.markdown

markup-dot-writer

org.markup.poet.dsl.write.dot

markup-bnf-writer

org.markup.poet.dsl.write.bnf

Example imports:

import org.markup.poet.dsl.write.asciidoc.toAsciidoc
import org.markup.poet.dsl.write.markdown.writeMarkdownTo
import org.markup.poet.dsl.write.dot.dotFlow
import org.markup.poet.dsl.write.bnf.toBnf

Contract

  • Concatenation equality — concatenating all emissions of xFlow() yields exactly the string returned by toX(); all four forms produce byte-identical output.

  • Sink lifecycle — the Sink overloads write UTF-8 and neither flush nor close the sink; the caller owns its lifecycle.

  • Cold flowsxFlow() does no work until collected, and each collection produces the chunks anew.

  • Chunk boundaries are an implementation detail — chunks arrive in document order, but their size and split points may change between releases; do not depend on them.