Skip to content

Commit 6103266

Browse files
authored
Added FOAM_DATE_WEEK_YEAR template variable (#1532)
* Updated resolver to include FOAM_DATE_WEEK_YEAR * Updated docs
1 parent 9192cef commit 6103266

File tree

4 files changed

+66
-0
lines changed

4 files changed

+66
-0
lines changed

docs/user/features/templates.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ Supported variables include:
258258
- `FOAM_DATE_YEAR`: 4-digit year (e.g. 2025)
259259
- `FOAM_DATE_MONTH`: 2-digit month (e.g. 09)
260260
- `FOAM_DATE_WEEK`: ISO 8601 week number (e.g. 37)
261+
- `FOAM_DATE_WEEK_YEAR`: the year of the ISO 8601 week number. The year that contains the Thursday of the current week, may vary from calendar year near Jan 1. Often used with `FOAM_DATE_WEEK`.
261262
- `FOAM_DATE_DAY_ISO`: ISO 8601 weekday number (1-7, where Monday=1, Sunday=7)
262263
- `FOAM_DATE_DATE`: 2-digit day of month (e.g. 15)
263264
- `FOAM_DATE_DAY_NAME`: Full weekday name (e.g. Monday)

packages/foam-vscode/src/dated-notes.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ Month: \${FOAM_DATE_MONTH} (name: \${FOAM_DATE_MONTH_NAME}, short: \${FOAM_DATE_
111111
Date: \${FOAM_DATE_DATE}
112112
Day: \${FOAM_DATE_DAY_NAME} (short: \${FOAM_DATE_DAY_NAME_SHORT})
113113
Week: \${FOAM_DATE_WEEK}
114+
Week Year: \${FOAM_DATE_WEEK_YEAR}
114115
Unix: \${FOAM_DATE_SECONDS_UNIX}`,
115116
DAILY_NOTE_TEMPLATE
116117
);
@@ -127,6 +128,7 @@ Unix: \${FOAM_DATE_SECONDS_UNIX}`,
127128
expect(content).toContain('Date: 12');
128129
expect(content).toContain('Day: Sunday (short: Sun)');
129130
expect(content).toContain('Week: 36');
131+
expect(content).toContain('Week Year: 2021');
130132

131133
await deleteFile(template.uri);
132134
await deleteFile(result.uri);

packages/foam-vscode/src/services/variable-resolver.spec.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ describe('variable-resolver, variable resolution', () => {
156156
expect(await resolver.resolveAll(variables)).toEqual(expected);
157157
});
158158

159+
function getISOWeekYear(date: Date): number {
160+
const temp = new Date(date.getTime());
161+
// Set to Thursday of this week (ISO 8601 defines week based on Thursday)
162+
temp.setDate(temp.getDate() + 3 - ((temp.getDay() + 6) % 7));
163+
return temp.getFullYear();
164+
}
165+
159166
it('should resolve FOAM_DATE_* properties with current day by default', async () => {
160167
const variables = [
161168
new Variable('FOAM_DATE_YEAR'),
@@ -171,6 +178,7 @@ describe('variable-resolver, variable resolution', () => {
171178
new Variable('FOAM_DATE_SECOND'),
172179
new Variable('FOAM_DATE_SECONDS_UNIX'),
173180
new Variable('FOAM_DATE_DAY_ISO'),
181+
new Variable('FOAM_DATE_WEEK_YEAR'),
174182
];
175183

176184
const expected = new Map<string, string>();
@@ -188,6 +196,8 @@ describe('variable-resolver, variable resolution', () => {
188196
now.toLocaleString('default', { day: '2-digit' })
189197
);
190198
expected.set('FOAM_DATE_DAY_ISO', String(((now.getDay() + 6) % 7) + 1));
199+
expected.set('FOAM_DATE_WEEK_YEAR', String(getISOWeekYear(now)));
200+
191201
const givenValues = new Map<string, string>();
192202
const resolver = new Resolver(givenValues, new Date());
193203

@@ -213,6 +223,7 @@ describe('variable-resolver, variable resolution', () => {
213223
new Variable('FOAM_DATE_SECONDS_UNIX'),
214224
new Variable('FOAM_DATE_WEEK'),
215225
new Variable('FOAM_DATE_DAY_ISO'),
226+
new Variable('FOAM_DATE_WEEK_YEAR'),
216227
];
217228

218229
const expected = new Map<string, string>();
@@ -233,6 +244,7 @@ describe('variable-resolver, variable resolution', () => {
233244
(targetDate.getTime() / 1000).toString()
234245
);
235246
expected.set('FOAM_DATE_DAY_ISO', '5'); // Friday is 5 in ISO 8601
247+
expected.set('FOAM_DATE_WEEK_YEAR', '2021');
236248

237249
const givenValues = new Map<string, string>();
238250
const resolver = new Resolver(givenValues, targetDate);
@@ -265,6 +277,44 @@ describe('variable-resolver, variable resolution', () => {
265277
});
266278
});
267279

280+
test.each([
281+
[new Date(2025, 0, 1), '2025', '01'], // Jan 1 2025 (Wed) - week 1 of 2025
282+
[new Date(2024, 11, 30), '2025', '01'], // Dec 30 2024 (Mon) - week 1 of 2025
283+
[new Date(2024, 0, 1), '2024', '01'], // Jan 1 2024 (Mon) - week 1 of 2024
284+
[new Date(2023, 0, 1), '2022', '52'], // Jan 1 2023 (Sun) - week 52 of 2022
285+
[new Date(2022, 0, 1), '2021', '52'], // Jan 1 2022 (Sat) - week 52 of 2021
286+
])(
287+
'should resolve FOAM_DATE_WEEK_YEAR correctly',
288+
async (date, expectedWeekYear, expectedWeek) => {
289+
const resolver = new Resolver(new Map(), date);
290+
const weekYear = await resolver.resolve(
291+
new Variable('FOAM_DATE_WEEK_YEAR')
292+
);
293+
const week = await resolver.resolve(new Variable('FOAM_DATE_WEEK'));
294+
295+
expect(weekYear).toBe(expectedWeekYear);
296+
expect(week).toBe(expectedWeek);
297+
}
298+
);
299+
300+
it('should resolve FOAM_DATE_WEEK_YEAR with FOAM_DATE_WEEK in template', async () => {
301+
// Example: 2024-W01 format where Dec 30, 2024 is in week 1 of 2025
302+
const date = new Date(2024, 11, 30); // Dec 30, 2024 (Monday)
303+
const resolver = new Resolver(new Map(), date);
304+
305+
const variables = [
306+
new Variable('FOAM_DATE_WEEK_YEAR'),
307+
new Variable('FOAM_DATE_WEEK'),
308+
new Variable('FOAM_DATE_YEAR'),
309+
];
310+
311+
const result = await resolver.resolveAll(variables);
312+
313+
expect(result.get('FOAM_DATE_WEEK_YEAR')).toBe('2025');
314+
expect(result.get('FOAM_DATE_WEEK')).toBe('01');
315+
expect(result.get('FOAM_DATE_YEAR')).toBe('2024');
316+
});
317+
268318
describe('FOAM_CURRENT_DIR', () => {
269319
it('should resolve to workspace root when no active editor', async () => {
270320
const resolver = new Resolver(new Map<string, string>(), new Date());

packages/foam-vscode/src/services/variable-resolver.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const knownFoamVariables = new Set([
2323
'FOAM_DATE_DATE',
2424
'FOAM_DATE_DAY_ISO',
2525
'FOAM_DATE_WEEK',
26+
'FOAM_DATE_WEEK_YEAR',
2627
'FOAM_DATE_DAY_NAME',
2728
'FOAM_DATE_DAY_NAME_SHORT',
2829
'FOAM_DATE_HOUR',
@@ -216,6 +217,18 @@ export class Resolver implements VariableResolver {
216217
value = Promise.resolve(String(weekDay.valueOf()).padStart(2, '0'));
217218
break;
218219
}
220+
case 'FOAM_DATE_WEEK_YEAR': {
221+
// ISO 8601 week-numbering year
222+
// The year that contains the Thursday of the current week
223+
const date = new Date(this.foamDate);
224+
225+
// Find Thursday of this week starting on Monday
226+
date.setDate(date.getDate() + 4 - (date.getDay() || 7));
227+
228+
// The year of this Thursday is the ISO week year
229+
value = Promise.resolve(String(date.getFullYear()));
230+
break;
231+
}
219232
case 'FOAM_DATE_DAY_NAME':
220233
value = Promise.resolve(
221234
this.foamDate.toLocaleString('default', { weekday: 'long' })

0 commit comments

Comments
 (0)