Skip to content

Commit bad833e

Browse files
authored
Merge pull request #3193 from obsidian-tasks-group/fix-variant-selectors
fix: Handle any hidden VS16 character on all emojis
2 parents 595785a + d872169 commit bad833e

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

src/TaskSerializer/DefaultTaskSerializer.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,13 @@ function dateFieldRegex(symbols: string) {
6060
}
6161

6262
function fieldRegex(symbols: string, valueRegexString: string) {
63-
let source = symbols;
63+
// \uFE0F? allows an optional Variant Selector 16 on emojis.
64+
let source = symbols + '\uFE0F?';
6465
if (valueRegexString !== '') {
6566
source += ' *' + valueRegexString;
6667
}
68+
// The regexes end with `$` because they will be matched and
69+
// removed from the end until none are left.
6770
source += '$';
6871
return new RegExp(source, 'u');
6972
}
@@ -93,10 +96,7 @@ export const DEFAULT_SYMBOLS: DefaultTaskSerializerSymbols = {
9396
dependsOnSymbol: '⛔',
9497
idSymbol: '🆔',
9598
TaskFormatRegularExpressions: {
96-
// The following regex's end with `$` because they will be matched and
97-
// removed from the end until none are left.
98-
// \uFE0F? allows an optional Variant Selector 16 on emojis.
99-
priorityRegex: fieldRegex('([🔺⏫🔼🔽⏬])\uFE0F?', ''),
99+
priorityRegex: fieldRegex('([🔺⏫🔼🔽⏬])', ''),
100100
startDateRegex: dateFieldRegex('🛫'),
101101
createdDateRegex: dateFieldRegex('➕'),
102102
scheduledDateRegex: dateFieldRegex('[⏳⌛]'),
@@ -105,7 +105,7 @@ export const DEFAULT_SYMBOLS: DefaultTaskSerializerSymbols = {
105105
cancelledDateRegex: dateFieldRegex('❌'),
106106
recurrenceRegex: fieldRegex('🔁', '([a-zA-Z0-9, !]+)'),
107107
onCompletionRegex: fieldRegex('🏁', '([a-zA-Z]+)'),
108-
dependsOnRegex: fieldRegex('⛔\uFE0F?', '(' + taskIdSequenceRegex.source + ')'),
108+
dependsOnRegex: fieldRegex('⛔', '(' + taskIdSequenceRegex.source + ')'),
109109
idRegex: fieldRegex('🆔', '(' + taskIdRegex.source + ')'),
110110
},
111111
} as const;

tests/TaskSerializer/DefaultTaskSerializer.test.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,16 @@ describe('validate emoji regular expressions', () => {
6666
expect(generateRegexApprovalTest()).toMatchInlineSnapshot(`
6767
"
6868
priorityRegex: /([🔺⏫🔼🔽⏬])\\ufe0f?$/u
69-
startDateRegex: /🛫 *(\\d{4}-\\d{2}-\\d{2})$/u
70-
createdDateRegex: /➕ *(\\d{4}-\\d{2}-\\d{2})$/u
71-
scheduledDateRegex: /[⏳⌛] *(\\d{4}-\\d{2}-\\d{2})$/u
72-
dueDateRegex: /[📅📆🗓] *(\\d{4}-\\d{2}-\\d{2})$/u
73-
doneDateRegex: /✅ *(\\d{4}-\\d{2}-\\d{2})$/u
74-
cancelledDateRegex: /❌ *(\\d{4}-\\d{2}-\\d{2})$/u
75-
recurrenceRegex: /🔁 *([a-zA-Z0-9, !]+)$/u
76-
onCompletionRegex: /🏁 *([a-zA-Z]+)$/u
69+
startDateRegex: /🛫\\ufe0f? *(\\d{4}-\\d{2}-\\d{2})$/u
70+
createdDateRegex: /➕\\ufe0f? *(\\d{4}-\\d{2}-\\d{2})$/u
71+
scheduledDateRegex: /[⏳⌛]\\ufe0f? *(\\d{4}-\\d{2}-\\d{2})$/u
72+
dueDateRegex: /[📅📆🗓]\\ufe0f? *(\\d{4}-\\d{2}-\\d{2})$/u
73+
doneDateRegex: /✅\\ufe0f? *(\\d{4}-\\d{2}-\\d{2})$/u
74+
cancelledDateRegex: /❌\\ufe0f? *(\\d{4}-\\d{2}-\\d{2})$/u
75+
recurrenceRegex: /🔁\\ufe0f? *([a-zA-Z0-9, !]+)$/u
76+
onCompletionRegex: /🏁\\ufe0f? *([a-zA-Z]+)$/u
7777
dependsOnRegex: /⛔\\ufe0f? *([a-zA-Z0-9-_]+( *, *[a-zA-Z0-9-_]+ *)*)$/u
78-
idRegex: /🆔 *([a-zA-Z0-9-_]+)$/u
78+
idRegex: /🆔\\ufe0f? *([a-zA-Z0-9-_]+)$/u
7979
"
8080
`);
8181
});
@@ -122,6 +122,15 @@ describe.each(symbolMap)("DefaultTaskSerializer with '$taskFormat' symbols", ({
122122
expect(taskDetails).toMatchTaskDetails({ ['scheduledDate']: moment('2021-06-20', 'YYYY-MM-DD') });
123123
});
124124

125+
it('should parse a scheduledDate - with Variation Selector', () => {
126+
// This test showed the existence of https://github.com/obsidian-tasks-group/obsidian-tasks/issues/3179
127+
const input = '⏳️ 2024-11-18';
128+
expect(hasVariantSelector16(input)).toBe(true);
129+
130+
const taskDetails = deserialize(input);
131+
expect(taskDetails).toMatchTaskDetails({ ['scheduledDate']: moment('2024-11-18', 'YYYY-MM-DD') });
132+
});
133+
125134
it('should parse a dueDate - with non-standard emoji 1', () => {
126135
const taskDetails = deserialize('📆 2021-06-20');
127136
expect(taskDetails).toMatchTaskDetails({ ['dueDate']: moment('2021-06-20', 'YYYY-MM-DD') });

0 commit comments

Comments
 (0)