# `gno.land/p/nym-moultest123/md` Markdown builders for realm `Render` output: headings, lists, links, images, code blocks, collapsible sections, columns. ```go out := md.H1("Posts") out += md.BulletList([]string{"first", "second"}) out += md.Link("gno.land", "https://gno.land") out += md.CollapsibleSection("Details", md.CodeBlock(dump)) ``` ## Read this before rendering user input **Half these helpers sanitize their arguments and half do not**, and using the wrong one is how a realm ends up rendering somebody else's markup. The rule is per-helper, not per-package, and getting it backwards is a bug in both directions: an unsanitized helper leaks markup, a double-wrapped one mangles text (the escapers are not idempotent). | | helpers | what you pass | | --- | --- | --- | | **sanitize internally** | `Link`, `UserLink`, `Image`, `InlineImageWithLink`, `FootnoteDefinition`, `LinkReferenceDefinition`, `CollapsibleSection` (title only), `InlineCode`, `CodeBlock`, `LanguageCodeBlock`, `Blockquote` | **raw** user input | | **do not sanitize** | `Bold`, `Italic`, `Strikethrough`, `H1`-`H6`, `BulletList`, `BulletItem`, `OrderedList`, `TodoList`, `TodoItem`, `Nested`, `Paragraph`, `Columns`, `ColumnsN`, `HorizontalRule` | input already wrapped in `sanitize.*` | ```go out += md.Link(post.Title, post.URL) // good: Link sanitizes out += md.H2(sanitize.InlineText(post.Title)) // good: H2 does not out += md.H2(post.Title) // BAD: raw user input out += md.Link(sanitize.InlineText(post.Title), sanitize.URL(post.URL)) // BAD: double-wrap ``` **Composition has a direction.** A sanitizing helper's output is finished markdown chrome and nests safely inside a non-sanitizing one. The reverse re-escapes your own markup: ```go out += md.H2(md.Link(post.Title, post.URL)) // good out += md.Link(md.Bold(post.Title), post.URL) // BAD: Link escapes the ** back out ``` Sanitization goes through `p/nt/markdown/sanitize`. `EscapeText` and `EscapeURL` are exported if you need them directly. ## The rest `Nested(content, prefix)` indents a block so lists can hold paragraphs and nested lists. `Columns` / `ColumnsN` lay content out side by side. `TodoList(items, done)` takes the checkboxes as a parallel `[]bool`. A worked gallery of every helper is on chain at [`r/docs/moul_md`](https://gno.land/r/docs/moul_md). --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. **Dependency graph:** ![gno.land/p/nym-moultest123/md/v0 dependency graph](https://raw.githubusercontent.com/moul/gno-contracts/main/_assets/gno.land/p/nym-moultest123/md/v0/deps.png) > ⚠️ **Disclaimer:** provided as-is, without warranty; not security-audited. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md).