mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-24 10:12:44 +00:00
fix(app): allow additive task lists and admonitions in native prose
This commit is contained in:
@@ -15,11 +15,11 @@ commonmark: strike=0 tasks=0 quotes=1 spoilers=1
|
||||
github: strike=1 tasks=1 quotes=1 spoilers=1
|
||||
```
|
||||
|
||||
Paseo's existing parser does not implement task lists. Escape task markers during inline preparation so `[ ]` and `[x]` remain literal text after a bullet, in both streaming and settled replies. Leave task toggling disabled.
|
||||
GitHub flavor renders `[ ]` and `[x]` list items as checkboxes. Toggling is disabled because changes would not persist. Preserve task markers in both streaming and settled replies.
|
||||
|
||||
## Compatibility constraints
|
||||
|
||||
- Disable `latexMath`. Dollar-delimited text must stay literal. Disable admonitions too; they would reinterpret existing quote content.
|
||||
- Disable `latexMath`. Dollar-delimited text must stay literal. Enable admonitions for `[!NOTE]`-style quotes; they add formatting without hiding the quote content. Ordinary quotes keep the existing blockquote style mapping.
|
||||
- Spoilers have no public parser switch in 1.1.1. Prepare inline text with escaped pipes so `||text||` stays visible. Preserve pipes inside code and link destinations.
|
||||
- `lineHeight` is a minimum. Use the Markdown theme's line height; font metrics can still increase it.
|
||||
- Strikethrough color is iOS-only. Android uses the surrounding text color.
|
||||
|
||||
@@ -91,13 +91,17 @@ it.each([false, true])(
|
||||
},
|
||||
);
|
||||
|
||||
it.each(["- [ ] Task", "- [x] Done", "1. [X] Done", "- parent\n - [ ] Nested task"])(
|
||||
"keeps task markers literal through streaming and settlement: %s",
|
||||
(text) => {
|
||||
const settled = prepareProse(text, noFiles);
|
||||
const streaming = prepareProse(text, noFiles, true);
|
||||
expect(settled).toMatch(/\\\[/);
|
||||
expect(streaming).toBe(settled);
|
||||
expect(parser.render(settled)).toBe(parser.render(text));
|
||||
},
|
||||
);
|
||||
it.each([
|
||||
"- [ ] Task",
|
||||
"- [x] Done",
|
||||
"1. [X] Done",
|
||||
"- parent\n - [ ] Nested task",
|
||||
"> [!NOTE]\n> Keep this note",
|
||||
"> Ordinary quote",
|
||||
])("preserves native block markers through streaming and settlement: %s", (text) => {
|
||||
const settled = prepareProse(text, noFiles);
|
||||
const streaming = prepareProse(text, noFiles, true);
|
||||
expect(settled).toBe(text);
|
||||
expect(streaming).toBe(settled);
|
||||
expect(parser.render(settled)).toBe(parser.render(text));
|
||||
});
|
||||
|
||||
@@ -60,6 +60,15 @@ function renderInline(tokens: Token[], canResolveCode: (text: string) => boolean
|
||||
.join("");
|
||||
}
|
||||
|
||||
function preserveNativeBlockMarker(source: string, rendered: string): string {
|
||||
const marker = source.match(
|
||||
/^\[(?:[ xX]|!(?:NOTE|TIP|IMPORTANT|WARNING|CAUTION))\](?=\s|$)/,
|
||||
)?.[0];
|
||||
if (!marker) return rendered;
|
||||
const escaped = escapeText(marker);
|
||||
return rendered.startsWith(escaped) ? marker + rendered.slice(escaped.length) : rendered;
|
||||
}
|
||||
|
||||
/** Keep the existing inline dialect, including literal pipes and tappable inline paths. */
|
||||
export function prepareProse(
|
||||
text: string,
|
||||
@@ -88,7 +97,10 @@ export function prepareProse(
|
||||
if (child.type === "text") child.content = child.content.toUpperCase();
|
||||
}
|
||||
}
|
||||
const rendered = renderInline(token.children, canResolveCode)
|
||||
const rendered = preserveNativeBlockMarker(
|
||||
token.content,
|
||||
renderInline(token.children, canResolveCode),
|
||||
)
|
||||
.replace(/ $/, " ")
|
||||
.split("\n");
|
||||
const replacement = rendered.map(
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { MarkdownProseProps } from "./props";
|
||||
import { inlineCodeLinkContent, prepareProse } from "./prepare";
|
||||
|
||||
const ThemedMarkdown = withUnistyles(EnrichedMarkdownText);
|
||||
const MD4C_FLAGS = { latexMath: false, hardSoftBreaks: true, admonitions: false };
|
||||
const MD4C_FLAGS = { latexMath: false, hardSoftBreaks: true, admonitions: true };
|
||||
|
||||
function proseStyleMapping(theme: Theme): { markdownStyle: MarkdownStyle } {
|
||||
const styles = createMarkdownStyles(theme);
|
||||
|
||||
Reference in New Issue
Block a user