=== FEATURE-INLINE-LINKS.md === # FEATURE: Inline Links and Images | Field | Value | |-------------|-------| | Version | 20260812 V1 | | Description | Defines inline links, reference links, images, destinations, titles, and reference resolution. | | Depends On | ARCHITECTURE.md, FEATURE-BLOCK-LEAF.md, FEATURE-INLINE-EMPHASIS.md | | Provides | link parser, image parser, reference resolver | | Consumes | block parser, inline parser | ## Questions - None. ## Purpose The inline parser recognizes inline, full-reference, collapsed-reference, and shortcut links and images. It resolves link reference definitions collected during block parsing, supports balanced destinations and titles, and prevents nested links while permitting nested image descriptions. ## Behavior - Inline destinations may be empty, angle-bracket delimited, escaped, or contain balanced parentheses. - Titles may use single quotes, double quotes, or parentheses. - Reference labels are normalized with Unicode case folding and whitespace normalization. - The first matching reference definition wins. - Link text is parsed as inline content. - Image descriptions produce plain-text `alt` content. - Links cannot contain links; image descriptions may contain links. ## Programmatic Acceptance === AC inline-links-suite === Intent: The inline link, reference link, and image syntax passes its complete owned conformance scope. Suite: scoped Requires: executable=python3; scope=test import subprocess import sys result = subprocess.run( [sys.executable, "spec_tests.py", "--spec", "spec.txt", "--program", "./commonmark", "--pattern", "^(Links|Images)$"], capture_output=True, text=True, ) print(result.stdout) print(result.stderr, file=sys.stderr) assert result.returncode == 0 === END AC inline-links-suite === === AC inline-links-boundaries === Intent: The implementation preserves link and image destination, title, reference, and nesting behavior. Suite: scoped Requires: executable=python3; scope=test import subprocess import sys result = subprocess.run( [sys.executable, "spec_tests.py", "--spec", "spec.txt", "--program", "./commonmark", "--pattern", "^(Links|Images)$"], capture_output=True, text=True, ) assert result.returncode == 0 === END AC inline-links-boundaries === ## User Acceptance - None. ## Guardrails - The implementation does not use a public Markdown implementation. - Reference definitions are resolved globally while preserving first-definition precedence. === END FEATURE-INLINE-LINKS.md === === FEATURE-INLINE-HTML.md === # FEATURE: Autolinks and Raw HTML | Field | Value | |-------------|-------| | Version | 20260812 V1 | | Description | Defines URI and email autolinks and preservation of raw HTML inline constructs. | | Depends On | ARCHITECTURE.md, FEATURE-INLINE-LINKS.md | | Provides | autolink parser, raw HTML parser | | Consumes | block parser, inline parser | ## Questions - None. ## Behavior - Absolute URI autolinks become links whose labels preserve the source URI. - Valid email autolinks become `mailto:` links. - HTML tags, comments, declarations, processing instructions, and CDATA are preserved as raw HTML. - Invalid autolinks and malformed HTML-like text remain escaped text. - Backslash escapes do not apply inside autolinks or raw HTML. ## Programmatic Acceptance === AC inline-html-suite === Intent: The autolink and raw HTML syntax passes its complete owned conformance scope. Suite: scoped Requires: executable=python3; scope=test import subprocess import sys result = subprocess.run( [sys.executable, "spec_tests.py", "--spec", "spec.txt", "--program", "./commonmark", "--pattern", "^(Autolinks|Raw HTML)$"], capture_output=True, text=True, ) print(result.stdout) print(result.stderr, file=sys.stderr) assert result.returncode == 0 === END AC inline-html-suite === === AC inline-html-malformed === Intent: Invalid autolinks and malformed HTML remain ordinary escaped content. Suite: scoped Requires: executable=python3; scope=test import subprocess import sys result = subprocess.run( [sys.executable, "spec_tests.py", "--spec", "spec.txt", "--program", "./commonmark", "--pattern", "^(Autolinks|Raw HTML)$"], capture_output=True, text=True, ) assert result.returncode == 0 === END AC inline-html-malformed === ## User Acceptance - None. ## Guardrails - Raw HTML is preserved only when it satisfies the CommonMark inline grammar. - The parser does not execute or fetch HTML or URI content. === END FEATURE-INLINE-HTML.md === === FEATURE-RENDER-BLOCKS.md === # FEATURE: Block HTML Rendering | Field | Value | |-------------|-------| | Version | 20260812 V1 | | Description | Defines HTML rendering for parsed block structure and block-level content. | | Depends On | ARCHITECTURE.md, FEATURE-BLOCK-LISTS.md, FEATURE-INLINE-HTML.md | | Provides | block HTML renderer | | Consumes | block parser, inline parser | ## Questions - None. ## Rendering Contract - Paragraphs render as `
` elements except for paragraphs in tight lists. - ATX and setext headings render as `
` content.
- Block quotes render as ``.
- Ordered and unordered lists preserve nesting, start values, item boundaries, and tightness.
- Raw HTML blocks remain unescaped.
## Programmatic Acceptance
=== AC render-blocks-suite ===
Intent: Block-level HTML rendering passes the complete owned conformance scope.
Suite: scoped
Requires: executable=python3; scope=test
import subprocess
import sys
result = subprocess.run(
[sys.executable, "spec_tests.py", "--spec", "spec.txt", "--program", "./commonmark",
"--pattern", "^(Thematic breaks|ATX headings|Setext headings|Indented code blocks|Fenced code blocks|HTML blocks|Paragraphs|Blank lines|Block quotes|List items|Lists)$"],
capture_output=True, text=True,
)
print(result.stdout)
print(result.stderr, file=sys.stderr)
assert result.returncode == 0
=== END AC render-blocks-suite ===
=== AC render-blocks-escaping ===
Intent: Block rendering preserves structural nesting and escapes literal code content.
Suite: scoped
Requires: executable=python3; scope=test
import subprocess
import sys
result = subprocess.run(
[sys.executable, "spec_tests.py", "--spec", "spec.txt", "--program", "./commonmark",
"--pattern", "^(Indented code blocks|Fenced code blocks|Block quotes|List items|Lists)$"],
capture_output=True, text=True,
)
assert result.returncode == 0
=== END AC render-blocks-escaping ===
## User Acceptance
- None.
## Guardrails
- Block rendering never treats captured test output as a correctness oracle.
- Literal code content is escaped while raw HTML blocks remain preserved.
=== END FEATURE-RENDER-BLOCKS.md ===
=== FEATURE-RENDER-INLINE.md ===
# FEATURE: Inline HTML Rendering
| Field | Value |
|-------------|-------|
| Version | 20260812 V1 |
| Description | Defines HTML rendering for parsed inline nodes and inline source constructs. |
| Depends On | ARCHITECTURE.md, FEATURE-RENDER-BLOCKS.md |
| Provides | inline HTML renderer |
| Consumes | inline parser |
## Questions
- None.
## Rendering Contract
- Text escapes HTML-significant characters.
- Emphasis and strong emphasis render as `` and ``.
- Code spans render as escaped `` content.
- Links render escaped `href` and optional `title` attributes.
- Images render escaped `src`, plain-text `alt`, and optional `title`.
- Hard breaks render as `
`; soft breaks preserve permitted line-break semantics.
- Autolinks and raw HTML preserve the required HTML representation.
- Entity references render as their corresponding characters, with HTML escaping where required.
## Programmatic Acceptance
=== AC render-inline-suite ===
Intent: Inline HTML rendering passes the complete owned conformance scope.
Suite: scoped
Requires: executable=python3; scope=test
import subprocess
import sys
result = subprocess.run(
[sys.executable, "spec_tests.py", "--spec", "spec.txt", "--program", "./commonmark",
"--pattern", "^(Characters and lines|Backslash escapes|Entity and numeric character references|Code spans|Emphasis and strong emphasis|Links|Images|Autolinks|Raw HTML|Hard line breaks|Soft line breaks|Textual content)$"],
capture_output=True, text=True,
)
print(result.stdout)
print(result.stderr, file=sys.stderr)
assert result.returncode == 0
=== END AC render-inline-suite ===
=== AC render-inline-escaping ===
Intent: Inline rendering escapes text and code while preserving links, images, and raw HTML.
Suite: scoped
Requires: executable=python3; scope=test
import subprocess
import sys
result = subprocess.run(
[sys.executable, "spec_tests.py", "--spec", "spec.txt", "--program", "./commonmark",
"--pattern", "^(Code spans|Links|Images|Autolinks|Raw HTML|Hard line breaks|Soft line breaks)$"],
capture_output=True, text=True,
)
assert result.returncode == 0
=== END AC render-inline-escaping ===
## User Acceptance
- None.
## Guardrails
- Renderer output is derived from parsed inline nodes and never from test-result text.
- User text cannot inject markup except through valid raw HTML constructs.
=== END FEATURE-RENDER-INLINE.md ===
=== FEATURE-RENDER-NORMALIZATION.md ===
# FEATURE: Normalized HTML Output
| Field | Value |
|-------------|-------|
| Version | 20260812 V1 |
| Description | Defines URL, title, attribute, entity, and special-character output compatibility with the supplied harness. |
| Depends On | ARCHITECTURE.md, FEATURE-RENDER-INLINE.md |
| Provides | normalized URL output, normalized title output, normalized attribute output |
| Consumes | block HTML renderer, inline HTML renderer |
## Questions
- None.
## Output Rules
- URLs preserve valid percent escapes and encode required spaces, Unicode characters, and backslashes.
- Titles and attribute values are HTML-escaped.
- Attribute output is deterministic and preserves required source semantics.
- Entity and numeric references are normalized consistently with the supplied harness.
- Special characters use the required HTML entities.
- Normalization compatibility does not alter code-block whitespace or raw HTML semantics.
## Programmatic Acceptance
=== AC render-normalization-suite ===
Intent: URL, title, attribute, entity, and special-character rendering passes its complete conformance scope.
Suite: scoped
Requires: executable=python3; scope=test
import subprocess
import sys
result = subprocess.run(
[sys.executable, "spec_tests.py", "--spec", "spec.txt", "--program", "./commonmark",
"--pattern", "^(Links|Images|Autolinks|Raw HTML|Entity and numeric character references)$"],
capture_output=True, text=True,
)
print(result.stdout)
print(result.stderr, file=sys.stderr)
assert result.returncode == 0
=== END AC render-normalization-suite ===
=== AC render-normalization-specials ===
Intent: Normalized output preserves URL escaping, title escaping, attribute semantics, and special characters.
Suite: scoped
Requires: executable=python3; scope=test
import subprocess
import sys
result = subprocess.run(
[sys.executable, "spec_tests.py", "--spec", "spec.txt", "--program", "./commonmark",
"--pattern", "^(Links|Images|Autolinks|Raw HTML|Entity and numeric character references)$"],
capture_output=True, text=True,
)
assert result.returncode == 0
=== END AC render-normalization-specials ===
## User Acceptance
- None.
## Guardrails
- Output normalization is deterministic and does not use a hardcoded pass tally.
- The supplied normalizer is used only as a comparison aid; its output is never the acceptance oracle.
=== END FEATURE-RENDER-NORMALIZATION.md ===