Skip to content

Commit 152ade4

Browse files
committed
Enforce org-mode markup limit of one linebreak between delimiters
See amake/orgro#27
1 parent ca03804 commit 152ade4

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

lib/src/grammar.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,18 @@ class OrgContentGrammarDefinition extends GrammarDefinition {
184184

185185
Parser code() => ref(markup, '~');
186186

187-
Parser markup(String marker) => drop(ref(_markup, marker), [0, -1]);
187+
Parser markup(String marker) => resultPredicate(
188+
drop(ref(_markup, marker), [0, -1]),
189+
(result, from, to) {
190+
for (var count = 0, i = from; i < to; i++) {
191+
// Ensure at most one LF (U+000A) in markup span
192+
if (result.codeUnitAt(i) == 0x000A && ++count > 1) {
193+
return false;
194+
}
195+
}
196+
return true;
197+
},
198+
);
188199

189200
Parser _markup(String marker) =>
190201
(startOfInput() | was(ref(preMarkup))) &

test/grammar_test.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ c/ d''');
176176
expect(result.value, ['~', "'", '~']);
177177
result = parser.parse('=+LEVEL=3+boss-TODO​="DONE"=');
178178
expect(result.value, ['=', '+LEVEL=3+boss-TODO​="DONE"', '=']);
179+
result = parser.parse('''+foo
180+
bar+''');
181+
expect(result.value, ['+', 'foo\nbar', '+']);
182+
result = parser.parse('''+foo
183+
184+
bar+''');
185+
expect(true, result.isFailure);
179186
});
180187
test('macro reference', () {
181188
final parser = buildSpecific(grammarDefinition.macroReference);

test/parser_test.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,20 @@ void main() {
2828
expect(link.description, 'bar');
2929
expect(link.location, 'foo::"[1]"');
3030
});
31+
test('markup', () {
32+
final parser = buildSpecific(parserDefinition.markups);
33+
var result = parser.parse('''/foo
34+
bar/''');
35+
final markup = result.value as OrgMarkup;
36+
expect(markup.content, 'foo\nbar');
37+
expect(markup.leadingDecoration, '/');
38+
expect(markup.trailingDecoration, '/');
39+
expect(markup.style, OrgStyle.italic);
40+
result = parser.parse('''/foo
41+
42+
bar/''');
43+
expect(result.isFailure, true);
44+
});
3145
test('macro reference', () {
3246
final parser = buildSpecific(parserDefinition.macroReference);
3347
var result = parser.parse('{{{name(arg1, arg2)}}}');

0 commit comments

Comments
 (0)