Skip to content

Commit 558158b

Browse files
committed
Support dual-value affiliated keywords
Closes #25
1 parent 085b552 commit 558158b

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

lib/src/org/grammar.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,27 @@ class OrgContentGrammarDefinition extends GrammarDefinition {
419419
ref0(affiliatedKeywordValue));
420420

421421
Parser affiliatedKeywordKey() =>
422+
ref0(affiliatedKeywordDualKey) | ref0(affiliatedKeywordSingleKey);
423+
424+
Parser affiliatedKeywordSingleKey() =>
422425
string('#+') & whitespace().neg().starLazy(char(':')) & char(':');
423426

427+
// See `org-element-dual-keywords`
428+
Parser affiliatedKeywordDualKey() =>
429+
string('#+') &
430+
(string('CAPTION', ignoreCase: true) |
431+
string('RESULTS', ignoreCase: true)) &
432+
ref0(affiliatedKeywordSecondaryValue).optional() &
433+
char(':');
434+
435+
Parser affiliatedKeywordSecondaryValue() =>
436+
char('[') &
437+
// TODO(aaron): This end condition handles some edge cases but for full
438+
// fidelity to `org-element-affiliated-re` we would need to support
439+
// backtracking
440+
any().starLazy(string(']:') & (whitespace() | lineEnd())) &
441+
char(']');
442+
424443
Parser affiliatedKeywordValue() => any()
425444
.starLazy(lineEnd())
426445
.flatten(message: 'Affiliated keyword value expected');

test/org/grammar/affiliated_keyword_test.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,30 @@ void main() {
3838
''
3939
]);
4040
});
41+
test('dual-value', () {
42+
final result = parser.parse('#+caption[blah]: foo');
43+
expect(result.value, [
44+
'',
45+
['#+caption[blah]:', ' foo'],
46+
''
47+
]);
48+
});
49+
test('dual-value-capable but single-value', () {
50+
final result = parser.parse('#+CAPTION: foo');
51+
expect(result.value, [
52+
'',
53+
['#+CAPTION:', ' foo'],
54+
''
55+
]);
56+
});
57+
test('dual-value edge case', () {
58+
final result = parser.parse('#+caption[:blah]: ]: foo');
59+
expect(result.value, [
60+
'',
61+
['#+caption[:blah]: ]:', ' foo'],
62+
''
63+
]);
64+
}, skip: "I don't think we can support this without backtracking");
4165
test('not at beginning of line', () {
4266
final result = parser.parse('''a #+blah''');
4367
expect(result, isA<Failure>());

0 commit comments

Comments
 (0)