---
name: markdown-semantic-wrap
source: https://app.decimal.ai/s/markdown-semantic-wrap@1/SKILL.md
source_sha256: 30c6e8d41603
---

# Markdown Semantic Wrapping

## Contract

Enforces semantic line-wrapping for prose in committed markdown (`.md`)
files: every prose line breaks at or before 80 columns, on a sentence /
clause / conjunction / word boundary in that priority, and overflowing
URLs become reference-style links. Apply when writing or editing any
markdown that will be committed (READMEs, docs, design notes, skill
files). The goal is one clean git diff per edited sentence.

## Rules

1. **80-column ceiling.** No prose line may exceed 80 columns. Never emit
   a paragraph as a single long line; break it across multiple lines.

2. **Break-point priority.** When a line would pass column 80, place the
   break at the FIRST boundary that exists, scanning this order:
   1. **Sentence boundary** — after `. `, `! `, or `? `. Prefer one
      sentence per line when sentences fit under 80.
   2. else **Clause boundary** — after `, `, `; `, or `: `.
   3. else **Conjunction** — break BEFORE `and `, `but `, `or `, `nor `,
      `yet `, `so `.
   4. else **Word boundary** — break at the last space before column 80.
   Always break at the latest qualifying boundary that still keeps the
   line ≤ 80, not the earliest.

3. **Never break inside an atomic span.** Keep these intact on one line
   even if that pushes the line past 80: inline code `` `like_this` ``,
   link text `[text]`, link URLs `(https://…)`, image syntax
   `![alt](url)`, and emphasis spans `**bold**` / `_italic_`. Overflow is
   acceptable; splitting the span is not.

4. **Reference-style links for overflow URLs.** If an inline link
   `[text](url)` would push its line past 80 columns, rewrite it as
   `[text][id]` in the prose and add a `[id]: url` definition on its own
   line at the end of the current section (after the last paragraph,
   before the next heading) or at the end of the file. When the same URL
   appears more than once, define ONE shared `[id]` and reuse it.

5. **Short inline links stay inline.** A link whose line stays ≤ 80
   columns is left as `[text](url)`. Do not convert links that fit.

6. **Blank line before every list.** Put exactly one blank line between
   the lead-in prose and the first `- ` or `1. ` item.

7. **Blank line around every heading.** One blank line before and one
   after each heading. Exception: a heading on the file's first line needs
   no blank line above it.

8. **ATX headings only.** Use `# Heading` / `## Subheading`. Never use
   setext underlines (`Heading` then a line of `===` or `---`).

9. **Wrap continuation lines of list items** with the description aligned
   to where the text starts: 2 spaces under `- `, 3 spaces under `1. `.

10. **Blockquotes** wrap at 78 columns (80 minus the `> ` prefix), and
    every wrapped line keeps its own `> ` prefix.

11. **Never wrap or reflow** these — leave them exactly as written:
    table rows (each pipe row stays on one line at any width), fenced
    code blocks, headings, YAML/TOML frontmatter, raw HTML blocks,
    `[id]: url` link-definition lines, and image-only lines.

## Worked examples

**Rule 1 + 2.1 — one long line → one sentence per line (sentence breaks).**

```markdown
BEFORE:
Install the plugin with npm. Configure it in your settings file. Restart the editor to activate.

AFTER:
Install the plugin with npm.
Configure it in your settings file.
Restart the editor to activate.
```

**Rule 2.2 — long sentence breaks at a clause boundary (after a comma).**

```markdown
BEFORE:
When the configuration file is missing, the system falls back to sensible defaults for all settings.

AFTER:
When the configuration file is missing,
the system falls back to sensible defaults for all settings.
```

**Rule 2.3 — no clause boundary fits, so break before a conjunction.**

```markdown
BEFORE:
The parser reads the input file and transforms each node into an output token.

AFTER:
The parser reads the input file
and transforms each node into an output token.
```

**Rule 2.4 — no sentence/clause/conjunction, fall back to a word break.**

```markdown
BEFORE:
The implementation requires understanding the underlying architecture thoroughly.

AFTER:
The implementation requires understanding the underlying
architecture thoroughly.
```

**Rule 3 — keep a code span intact even past column 80.**

```markdown
BEFORE (split mid-span — wrong):
Pass the client-supplied `idempotency_
key` so retries do not double-charge.

AFTER (span stays whole; break elsewhere):
Pass the client-supplied `idempotency_key`
so retries do not double-charge.
```

**Rule 4 — overflowing inline URL → reference-style link.**

```markdown
BEFORE:
See the [complete formatting guide](https://google.github.io/styleguide/docguide/style.html) for details.

AFTER:
See the [complete formatting guide][fmt] for details.

[fmt]: https://google.github.io/styleguide/docguide/style.html
```

**Rule 6 — blank line before a list.**

```markdown
BEFORE:
The release includes three changes:
- streaming responses
- a memory-leak fix

AFTER:
The release includes three changes:

- streaming responses
- a memory-leak fix
```

**Rule 7 + 8 — heading spacing and ATX form.**

```markdown
BEFORE:
Some text.
Overview
========
More text.

AFTER:
Some text.

## Overview

More text.
```

**Rule 9 — wrap a long list-item description with aligned continuation.**

```markdown
BEFORE:
- **markdown-formatting**: Canonical conventions for diff-friendly documentation generation and review.

AFTER:
- **markdown-formatting**: Canonical conventions for
  diff-friendly documentation generation and review.
```

**Rule 10 — blockquote wraps at 78 and keeps the prefix.**

```markdown
BEFORE:
> This is a very long blockquote line that exceeds 80 characters when you include the prefix.

AFTER:
> This is a very long blockquote line that exceeds
> 80 characters when you include the prefix.
```

**Rule 11 — a wide table row is NOT wrapped.**

```markdown
AFTER (left on one line at any width):
| Plan       | Requests/mo | Price  |
| Enterprise | unlimited   | custom |
```

## Edge cases & exceptions

- **First line of the file is a heading** — no blank line above it; the
  blank line below it still applies.
- **A single word longer than 80 columns** (a long URL, a hash, a path):
  leave it on its own line and exceed 80. Atomic spans (Rule 3) win over
  the 80-column ceiling.
- **A URL that fits** — keep it inline; do NOT mint a reference definition
  for a link that already stays under 80.
- **Same URL twice** — one shared `[id]` definition, referenced from both
  spots; do not define two ids for the same target.
- **Code-block contents that exceed 80** — never touched; the ceiling
  applies to prose only, not to fenced or indented code.
- **Table introduced by prose** — wrap the prose, blank-line before the
  table, then leave every pipe row unwrapped.
- **Nested list items** — continuation lines align to the text start of
  THAT item's marker, accounting for its indentation.

## Do / Don't

- **Never** emit a paragraph as one long unbroken line. **Always** wrap at
  or before column 80.
- **Never** break at an arbitrary mid-clause word when a sentence or
  clause boundary is available before column 80. **Always** prefer the
  highest-priority boundary that fits.
- **Never** split an inline code span, link text, or URL across lines.
  **Always** keep the span whole, even if the line runs long.
- **Never** leave a long overflowing URL as an inline `[text](url)`.
  **Always** convert it to `[text][id]` plus a trailing `[id]: url`.
- **Never** glue a list directly under its lead-in sentence. **Always**
  put one blank line before the list.
- **Never** use setext (`===` / `---`) underlines for headings. **Always**
  use ATX `#` headings.
- **Never** reflow a table row to fit 80 columns. **Always** leave pipe
  rows on one line.

## Common mistakes

- Emitting the whole paragraph as a single 200-character line (the base
  model's default for documentation prose).
- Using inline `[text](https://very/long/url)` for a URL that blows past
  80 columns instead of a reference-style link.
- Breaking right at column 80 mid-word even though a comma or period sat a
  few characters earlier.
- Hard-wrapping the rows of a table or the lines of a code block.
- Forgetting the blank line before a list, or omitting the blank line
  after a heading.
- Splitting `` `code_span` `` or a `[link](url)` across two lines to
  satisfy the 80-column rule.

## Quick checklist

- [ ] No prose line over 80 columns.
- [ ] Breaks at sentence → clause → conjunction → word, in that order.
- [ ] Code spans, link text, and URLs never split.
- [ ] Overflowing URLs are reference-style with a trailing `[id]: url`.
- [ ] One blank line before every list and around every heading.
- [ ] ATX `#` headings only.
- [ ] Tables, code blocks, and frontmatter left unwrapped.
