mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 16:33:27 +00:00
fix: detect markdown when a heading/list follows a blank line
isMarkdown() treated the second newline of a blank line as a non-space character, flipping the line-start tracker off. ATX headings, blockquotes, and list markers that follow the standard blank-line spacing went undetected, so NIP-23 long-form articles made of prose plus section headings rendered as raw text. Exclude newline/carriage-return from the line-start guard so a blank line stays at line start. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7d77a057d6
commit
a97529d7af
@@ -207,7 +207,14 @@ object CachedRichTextParser {
|
||||
// checks that need to know "how much non-space text has
|
||||
// appeared on the current line".
|
||||
if (isNewLine) {
|
||||
if (c != ' ' && c != '\t') {
|
||||
// A blank line is still "at line start": skipping '\n'/'\r'
|
||||
// here keeps isNewLine true so a heading/blockquote/list
|
||||
// marker on the next line (the standard `\n\n#` spacing) is
|
||||
// still recognized as line-leading. Without the newline
|
||||
// exclusion, the second '\n' of a blank line flipped
|
||||
// isNewLine to false and ATX headings after a blank line
|
||||
// went undetected.
|
||||
if (c != ' ' && c != '\t' && c != '\n' && c != '\r') {
|
||||
isNewLine = false
|
||||
nonSpaceCharCountOnLine = 1
|
||||
lastNonSpaceChar = c
|
||||
|
||||
@@ -68,6 +68,46 @@ class CachedRichTextParserMarkdownTest {
|
||||
|
||||
@Test fun atxAfterNewlineIsMarkdown() = assertTrue(CachedRichTextParser.isMarkdown("intro\n# Heading"))
|
||||
|
||||
// ---- Line-leading markers after a BLANK line ------------------------
|
||||
// Regression: the standard `\n\n#` spacing (a blank line before a
|
||||
// heading) was undetected because the blank line's second '\n' flipped
|
||||
// the line-start tracker off. NIP-23 long-form articles that are pure
|
||||
// prose plus `## Section` headings rendered as raw text as a result.
|
||||
|
||||
@Test fun atxAfterBlankLineIsMarkdown() = assertTrue(CachedRichTextParser.isMarkdown("intro\n\n# Heading"))
|
||||
|
||||
@Test fun atxH3AfterBlankLineIsMarkdown() = assertTrue(CachedRichTextParser.isMarkdown("intro\n\n### Heading"))
|
||||
|
||||
@Test fun atxAfterMultipleBlankLinesIsMarkdown() = assertTrue(CachedRichTextParser.isMarkdown("intro\n\n\n\n## Heading"))
|
||||
|
||||
@Test fun atxAfterCrlfBlankLineIsMarkdown() = assertTrue(CachedRichTextParser.isMarkdown("intro\r\n\r\n## Heading"))
|
||||
|
||||
@Test fun blockquoteAfterBlankLineIsMarkdown() = assertTrue(CachedRichTextParser.isMarkdown("intro\n\n> quoted"))
|
||||
|
||||
@Test fun bulletAfterBlankLineIsMarkdown() = assertTrue(CachedRichTextParser.isMarkdown("intro\n\n- item"))
|
||||
|
||||
@Test fun orderedListAfterBlankLineIsMarkdown() = assertTrue(CachedRichTextParser.isMarkdown("intro\n\n1. first"))
|
||||
|
||||
@Test
|
||||
fun proseArticleWithHeadingAfterBlankLineIsMarkdown() =
|
||||
assertTrue(
|
||||
CachedRichTextParser.isMarkdown(
|
||||
"The cryptographic part of commerce has been solved.\n\n" +
|
||||
"What follows is a history.\n\n" +
|
||||
"### The merchant posts of the Hansa\n\n" +
|
||||
"Long before any king claimed a monopoly on letters.",
|
||||
),
|
||||
)
|
||||
|
||||
// Blank lines alone must NOT promote ordinary prose to markdown.
|
||||
@Test
|
||||
fun plainProseWithBlankLinesIsNotMarkdown() =
|
||||
assertFalse(
|
||||
CachedRichTextParser.isMarkdown(
|
||||
"Just a normal sentence.\n\nAnother paragraph with no markdown at all.",
|
||||
),
|
||||
)
|
||||
|
||||
// ---- Blockquote -----------------------------------------------------
|
||||
|
||||
@Test fun blockquoteIsMarkdown() = assertTrue(CachedRichTextParser.isMarkdown("> a quote"))
|
||||
|
||||
Reference in New Issue
Block a user