Skip to content

Commit

Permalink
Add support for indentation in blocks in MD codec
Browse files Browse the repository at this point in the history
  • Loading branch information
amantoux committed Aug 19, 2024
1 parent 7f965d0 commit 0025f3d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 7 deletions.
31 changes: 24 additions & 7 deletions packages/parchment/lib/src/codecs/markdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import 'dart:convert';

import 'package:parchment_delta/parchment_delta.dart';

import '../document/attributes.dart';
import '../document.dart';
import '../document/attributes.dart';
import '../document/block.dart';
import '../document/leaf.dart';
import '../document/line.dart';
Expand Down Expand Up @@ -134,10 +134,15 @@ class _ParchmentMarkdownDecoder extends Converter<String, ParchmentDocument> {
}
final match = _olRegExp.matchAsPrefix(line);
final span = match?.group(2);
final indent = ((match?.group(1)?.length ?? 0) / 2).floor();
if (span != null) {
_handleSpan(span, delta, false, style);
_handleSpan(
'\n', delta, false, ParchmentStyle().put(ParchmentAttribute.ol));
ParchmentStyle blockStyle = ParchmentStyle().put(ParchmentAttribute.ol);
if (indent > 0) {
blockStyle =
blockStyle.put(ParchmentAttribute.indent.withLevel(indent));
}
_handleSpan('\n', delta, false, blockStyle);
return true;
}
return false;
Expand Down Expand Up @@ -432,10 +437,20 @@ class _ParchmentMarkdownEncoder extends Converter<ParchmentDocument, String> {
}

void handleBlock(BlockNode node) {
int currentItemOrder = 1;
// store for each indent level the current item order
int currentLevel = 0;
Map<int, int> currentItemOrders = {0: 1};
for (final lineNode in node.children) {
if ((lineNode is LineNode) &&
lineNode.style.contains(ParchmentAttribute.indent)) {
final indent = lineNode.style.value(ParchmentAttribute.indent)!;
currentLevel++;
currentItemOrders[currentLevel] = 1;
// Insert 2 spaces per indent before black start
lineBuffer.writeAll(List.generate(indent, (_) => ' '));
}
if (node.style.containsSame(ParchmentAttribute.ol)) {
lineBuffer.write(currentItemOrder);
lineBuffer.write(currentItemOrders[currentLevel]);
} else if (node.style.containsSame(ParchmentAttribute.cl)) {
lineBuffer.write('- [');
if ((lineNode as LineNode)
Expand All @@ -451,7 +466,7 @@ class _ParchmentMarkdownEncoder extends Converter<ParchmentDocument, String> {
if (!lineNode.isLast) {
buffer.write('\n');
}
currentItemOrder += 1;
currentItemOrders[currentLevel] = currentItemOrders[currentLevel]! + 1;
}

handleLine(LineNode());
Expand Down Expand Up @@ -490,7 +505,9 @@ class _ParchmentMarkdownEncoder extends Converter<ParchmentDocument, String> {
_writeBlockTag(buffer, attribute as ParchmentAttribute<String>,
close: close);
} else if (attribute?.key == ParchmentAttribute.checked.key) {
// no-op
// no-op already handled in handleBlock
} else if (attribute?.key == ParchmentAttribute.indent.key) {
// no-op already handled in handleBlock
} else {
throw ArgumentError('Cannot handle $attribute');
}
Expand Down
27 changes: 27 additions & 0 deletions packages/parchment/test/codecs/markdown_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,19 @@ void main() {
expect(act, exp);
});

test('ol with indent', () {
var markdown = '1. Hello\n 1. This is a\n2. List\n\n';
final act = parchmentMarkdown.decode(markdown).toDelta();
final exp = Delta()
..insert('Hello')
..insert('\n', {'block': 'ol'})
..insert('This is a')
..insert('\n', {'block': 'ol', 'indent': 1})
..insert('List')
..insert('\n', {'block': 'ol'});
expect(act, exp);
});

test('cl', () {
var markdown = '- [ ] Hello\n- [X] This is a\n- [ ] Checklist\n\n';
final act = parchmentMarkdown.decode(markdown).toDelta();
Expand Down Expand Up @@ -589,6 +602,20 @@ void main() {
expect(result, expected);
});

test('ol with indent', () {
final delta = Delta()
..insert('Hello')
..insert('\n', {'block': 'ol'})
..insert('This is a')
..insert('\n', {'block': 'ol', 'indent': 1})
..insert('List')
..insert('\n', {'block': 'ol'});
final result =
parchmentMarkdown.encode(ParchmentDocument.fromDelta(delta));
final expected = '1. Hello\n 1. This is a\n2. List\n\n';
expect(result, expected);
});

test('cl', () {
final delta = Delta()
..insert('Hello')
Expand Down

0 comments on commit 0025f3d

Please sign in to comment.