Skip to content

Commit

Permalink
Break paragraphs on blank lines, like Emacs
Browse files Browse the repository at this point in the history
Previously multiple notional paragraphs could be rolled up into one
OrgParagraph. This is usually not a problem, but Emacs does bidi text direction
detection per-paragraph, so to make this possible we must have only one true
paragraph per OrgParagraph.
  • Loading branch information
amake committed Oct 20, 2024
1 parent 84147a8 commit 17f1ff6
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 44 deletions.
7 changes: 5 additions & 2 deletions lib/src/org/grammar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,15 @@ class OrgContentGrammarDefinition extends GrammarDefinition {

Parser paragraph() =>
ref0(indent).flatten('Paragraph indent expected') &
ref1(textRun, ref0(nonParagraphElements)).plusLazy(ref0(paragraphEnd));
ref1(textRun, ref0(nonParagraphElements) | newline().repeat(2))
.plusLazy(ref0(paragraphEnd)) &
ref0(blankLines).optional();

Parser nonParagraphElements() =>
element()..replace(ref0(paragraph), noOpFail());

Parser paragraphEnd() => endOfInput() | ref0(nonParagraphElements);
Parser paragraphEnd() =>
endOfInput() | newline().repeat(2) | ref0(nonParagraphElements);

Parser textRun([Parser? limit]) => ref0(object) | ref1(plainText, limit);

Expand Down
12 changes: 9 additions & 3 deletions lib/src/org/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1426,10 +1426,11 @@ class OrgListOrderedItem extends OrgListItem {
}

class OrgParagraph extends OrgParentNode {
OrgParagraph(this.indent, this.body, [super.id]);
OrgParagraph(this.indent, this.body, this.trailing, [super.id]);

final String indent;
final OrgContent body;
final String trailing;

@override
List<OrgNode> get children => [body];
Expand All @@ -1440,7 +1441,9 @@ class OrgParagraph extends OrgParentNode {

@override
bool contains(Pattern pattern) =>
indent.contains(pattern) || body.contains(pattern);
indent.contains(pattern) ||
body.contains(pattern) ||
trailing.contains(pattern);

@override
String toString() => 'OrgParagraph';
Expand All @@ -1449,17 +1452,20 @@ class OrgParagraph extends OrgParentNode {
void _toMarkupImpl(OrgSerializer buf) {
buf
..write(indent)
..visit(body);
..visit(body)
..write(trailing);
}

OrgParagraph copyWith({
String? indent,
OrgContent? body,
String? trailing,
String? id,
}) =>
OrgParagraph(
indent ?? this.indent,
body ?? this.body,
trailing ?? this.trailing,
id ?? this.id,
);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/src/org/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,9 @@ class OrgContentParserDefinition extends OrgContentGrammarDefinition {
Parser paragraph() => super.paragraph().map((items) {
final indent = items[0] as String;
final bodyElements = items[1] as List;
final trailing = items[2] as String;
final body = OrgContent(bodyElements.cast());
return OrgParagraph(indent, body);
return OrgParagraph(indent, body, trailing);
});

@override
Expand Down
Loading

0 comments on commit 17f1ff6

Please sign in to comment.