diff --git a/src/content.config.ts b/src/content.config.ts index bc0d738..778606f 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -25,21 +25,6 @@ function toPlainMarkdown(body: string): string { .replace(/\n{3,}/g, '\n\n'); } -// Inject inline HTML into the spec source before rendering so that the FAQ -// comparison table shows accessible support indicators in HTML, while the -// plain Markdown body keeps its prose for curl/llms.txt consumers. -function preprocessForRendering(source: string): string { - return source - .replace( - /\| Supported \|/g, - '| |', - ) - .replace( - /\| Not supported \|/g, - '| |', - ); -} - const specification = defineCollection({ loader: { name: 'sembr-specification', @@ -58,7 +43,7 @@ const specification = defineCollection({ const id = 'sembr'; const data = await parseData({ id, data: {} }); const digest = generateDigest(source); - const rendered = await renderMarkdown(preprocessForRendering(source)); + const rendered = await renderMarkdown(source); const body = toPlainMarkdown(source); store.set({ id, data, body, digest, rendered }); diff --git a/src/lib/remark-sembr.ts b/src/lib/remark-sembr.ts index c8d8753..ac58c5f 100644 --- a/src/lib/remark-sembr.ts +++ b/src/lib/remark-sembr.ts @@ -2,7 +2,7 @@ import type { Definition, Html, Root, RootContent, Text } from 'mdast'; import type { Plugin } from 'unified'; import { visit } from 'unist-util-visit'; -const KEYWORDS = [ +const RFC_2119_KEYWORDS = [ 'MUST NOT', 'SHALL NOT', 'SHOULD NOT', @@ -15,7 +15,7 @@ const KEYWORDS = [ 'MAY', ] as const; -const KEYWORD_PATTERN = new RegExp(`\\b(${KEYWORDS.join('|')})\\b`, 'g'); +const RFC_2119_PATTERN = new RegExp(`\\b(${RFC_2119_KEYWORDS.join('|')})\\b`, 'g'); const EM_DASH = '\u2014'; const EM_DASH_PATTERN = /---/g; @@ -54,11 +54,13 @@ function ccSymbolsForLicenseUrl(rawUrl: string): string | null { export const remarkSembr: Plugin<[], Root> = () => { return (tree) => { + // Collect link definitions for resolving Creative Commons references. const definitions = new Map(); visit(tree, 'definition', (node: Definition) => { definitions.set(node.identifier, node.url); }); + // Mark multiline
 blocks as SemBr examples for whitespace styling.
 		visit(tree, 'html', (node) => {
 			const match = node.value.match(MULTILINE_PRE_PATTERN);
 			if (
@@ -70,6 +72,39 @@ export const remarkSembr: Plugin<[], Root> = () => {
 			}
 		});
 
+		// FAQ comparison table: accessible support indicators and styled "None".
+		visit(tree, 'tableCell', (node) => {
+			if (node.children.length !== 1 || node.children[0]?.type !== 'text') {
+				return;
+			}
+			const value = node.children[0].value;
+			if (value === 'Supported') {
+				node.children = [
+					{
+						type: 'html',
+						value:
+							'',
+					},
+				];
+			} else if (value === 'Not supported') {
+				node.children = [
+					{
+						type: 'html',
+						value:
+							'',
+					},
+				];
+			} else if (value === 'None') {
+				node.children = [
+					{
+						type: 'html',
+						value: 'None',
+					},
+				];
+			}
+		});
+
+		// Keep "Line Breaks" on one line in the title via a non-breaking space.
 		visit(tree, 'heading', (node) => {
 			if (
 				node.depth === 1 &&
@@ -81,13 +116,14 @@ export const remarkSembr: Plugin<[], Root> = () => {
 			}
 		});
 
+		// Highlight RFC 2119 keywords and normalize --- to an em dash.
 		visit(tree, 'text', (node, index, parent) => {
 			if (!parent || typeof index !== 'number') {
 				return;
 			}
 
 			const value = node.value.replace(EM_DASH_PATTERN, EM_DASH);
-			const matches = [...value.matchAll(KEYWORD_PATTERN)];
+			const matches = [...value.matchAll(RFC_2119_PATTERN)];
 
 			if (matches.length === 0) {
 				if (value !== node.value) {
@@ -124,6 +160,7 @@ export const remarkSembr: Plugin<[], Root> = () => {
 			parent.children.splice(index, 1, ...(nodes as typeof parent.children));
 		});
 
+		// Prefix Creative Commons license links with Unicode license symbols.
 		visit(tree, ['link', 'linkReference'], (node, index, parent) => {
 			if (!parent || typeof index !== 'number') {
 				return;
diff --git a/src/styles/global.css b/src/styles/global.css
index fc2c741..a9a43ed 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -185,6 +185,7 @@
 		position: relative;
 		padding-inline-start: var(--space-s);
 		margin-block-end: var(--space-s);
+		text-wrap: balance;
 	}
 
 	ol>li::marker {
@@ -379,11 +380,15 @@
 		font-weight: 700;
 	}
 
-	mark[data-supported="true"] {
+	tbody tr>td:nth-child(2) {
+		text-wrap: balance;
+	}
+
+	:is(mark, em)[data-supported="true"] {
 		color: var(--color-heading);
 	}
 
-	mark[data-supported="false"] {
+	:is(mark, em)[data-supported="false"] {
 		color: var(--color-rule);
 	}