feat(workspace): numbered lists and reliable markdown paste
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m5s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m5s
- block type 'numbered' (/number): 1., a., i. by nesting, continues on Enter, an empty item ends the list; markdown export/import as 1. - pasting: parser moved to lib/pasteOutline with tests; blank lines split paragraphs, numbered lists keep their type, indentation levels follow the widths in use (2, 3 or 4 spaces, tabs) - text that stays in the focused block after pasting (a paragraph with line breaks) was dropped; the block now takes it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9008d7c915
commit
2bfe74e66b
13 files changed
+286
-176
No files matched your search
@@ -0,0 +1,38 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { parsePastedLines } from '../pasteOutline';
|
||||
|
||||
const parse = (text: string) => parsePastedLines(text.split('\n'));
|
||||
|
||||
describe('parsePastedLines', () => {
|
||||
it('splits paragraphs at blank lines and keeps wrapped lines together', () => {
|
||||
expect(parse('Erster Absatz\nnoch erster\n\nZweiter Absatz')).toEqual([
|
||||
{ type: 'text', content: 'Erster Absatz\nnoch erster', indent: 0 },
|
||||
{ type: 'text', content: 'Zweiter Absatz', indent: 0 },
|
||||
]);
|
||||
});
|
||||
|
||||
it('keeps numbered lists with nesting (3-space indent)', () => {
|
||||
expect(parse('1. Eins\n 1. Unterpunkt\n 1. Tiefer\n2. Zwei')).toEqual([
|
||||
{ type: 'numbered', content: 'Eins', indent: 0 },
|
||||
{ type: 'numbered', content: 'Unterpunkt', indent: 1 },
|
||||
{ type: 'numbered', content: 'Tiefer', indent: 2 },
|
||||
{ type: 'numbered', content: 'Zwei', indent: 0 },
|
||||
]);
|
||||
});
|
||||
|
||||
it('reads headings, todos, bullets and dividers', () => {
|
||||
expect(parse('# Titel\nText danach\n- [x] erledigt\n- Punkt\n---')).toEqual([
|
||||
{ type: 'h1', content: 'Titel', indent: 0 },
|
||||
{ type: 'text', content: 'Text danach', indent: 0 },
|
||||
{ type: 'todo', checked: true, content: 'erledigt', indent: 0 },
|
||||
{ type: 'text', content: 'Punkt', indent: 0 },
|
||||
{ type: 'divider', content: '---', indent: 0 },
|
||||
]);
|
||||
});
|
||||
|
||||
it('keeps fenced code as one block', () => {
|
||||
const items = parse('```go\nfunc main() {}\n\n```\nDanach');
|
||||
expect(items[0].content).toBe('```go\nfunc main() {}\n\n```');
|
||||
expect(items[1]).toEqual({ type: 'text', content: 'Danach', indent: 0 });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user