Colour markdown's tables and the addresses written in it

A table is recognised by its delimiter row, the only line of one that cannot
be anything else, and its header is the line above -- the single place the
scanner looks ahead. Colouring every `|` instead would have marked the pipes
of a shell command written in a paragraph.

Addresses come in two shapes: `<...>` needs a scheme's colon or an at sign
inside it and no whitespace, which leaves `<div>` alone; a bare `scheme://`
needs no closer, so where it ends is the decision -- the sentence's trailing
punctuation is given back, and so is a closing bracket unless one opened
inside the URL.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-04 10:47:18 -04:00
1 parent 68c5180260
commit 7997eeb7f8
4 files changed
+238 -8

No files matched your search

@@ -255,6 +255,78 @@ class HighlighterTest {
assertSpans(code, Language.MARKDOWN, Kind.METADATA, "(PLAN.md)")
}
@Test
fun `a table is found by its delimiter row, and pipes elsewhere are plain`() {
val code = "| a | b |\n|---|---|\n| 1 | 2 |\n\nrun a | b in a paragraph"
assertSpans(
code,
Language.MARKDOWN,
Kind.MARK,
"|",
"|",
"|",
"|---|---|",
"|",
"|",
"|",
)
}
@Test
fun `a table without outer pipes still colours, and the table ends with the rows`() {
val code = "a | b\n--- | ---\nnot a row"
assertSpans(code, Language.MARKDOWN, Kind.MARK, "|", "--- | ---")
}
/**
* The tag in the last case is not an autolink and is left plain, but the address inside it is
* still an address and the bare-URL pass finds it. That is the intended reading: raw HTML is
* not something this scanner knows, and a URL is a URL wherever it was written.
*/
@Test
fun `an autolink colours and an HTML tag does not`() {
val code = "<https://example.com> and <a@b.com> and <div> and <img src=\"http://x\">"
assertSpans(
code,
Language.MARKDOWN,
Kind.METADATA,
"<https://example.com>",
"<a@b.com>",
"http://x",
)
}
@Test
fun `a bare URL gives back the sentence's punctuation`() {
assertSpans(
"see https://example.com/a., and ssh://host/x)",
Language.MARKDOWN,
Kind.METADATA,
"https://example.com/a",
"ssh://host/x",
)
}
@Test
fun `a bracket a URL opened itself stays in it`() {
assertSpans(
"https://en.wikipedia.org/wiki/A_(b) here",
Language.MARKDOWN,
Kind.METADATA,
"https://en.wikipedia.org/wiki/A_(b)",
)
}
@Test
fun `a URL inside a link destination is not coloured twice`() {
assertSpans(
"[x](https://example.com)",
Language.MARKDOWN,
Kind.METADATA,
"(https://example.com)",
)
}
@Test
fun `a bracket with no destination after it is left plain`() {
assertSpans("an [aside] here", Language.MARKDOWN, Kind.MARK)
@@ -305,6 +377,12 @@ class HighlighterTest {
"1.",
"[x](",
"#######",
"|",
"|---|",
"<",
"<>",
"http://",
"a://",
"\n\n \n",
)
for (language in Language.entries) {