Compare commits

...

2 Commits

Author SHA1 Message Date
31c309aecc Add support for tags 2025-01-15 14:56:16 +01:00
12fa9e4e75 Enable dayjs for task dates 2025-01-15 14:19:23 +01:00
6 changed files with 100 additions and 32 deletions

View File

@@ -22,10 +22,36 @@ task = "-" _ "[" status:. "]" _ label:label meta:meta* {
}; };
} }
label = text:([^⏬🔽🔼⏫🔺➕⏳🛫📅✅❌🔁🏁🆔⛔⏰]*) { /**************************************************************************************************************************************/
return text.join("").trim()
label = spans:(tag / labelWord / labelWhitespace)* {
return spans;
} }
labelWord = word:[^ \t\r⏬🔽🔼⏫🔺⏳🛫📅✅❌🔁🏁🆔⛔⏰]+ {
return {
span: "word",
value: word.join("")
}
}
labelWhitespace = whitespace:[ \t\r]+ {
return {
span: "whitespace",
value: whitespace.join("")
}
}
tag = "#" tag:[a-zA-Z0-9-]+ {
return {
span: "tag",
value: tag.join("")
}
}
/**************************************************************************************************************************************/
meta = _ @(date / recurrence / delete / priority / dependency / reminder) _ meta = _ @(date / recurrence / delete / priority / dependency / reminder) _
/**************************************************************************************************************************************/ /**************************************************************************************************************************************/

7
package-lock.json generated
View File

@@ -9,6 +9,7 @@
"version": "0.0.1", "version": "0.0.1",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"dayjs": "^1.11.13",
"peggy": "^4.2.0" "peggy": "^4.2.0"
}, },
"bin": { "bin": {
@@ -574,6 +575,12 @@
"node": "^12.20.0 || >=14" "node": "^12.20.0 || >=14"
} }
}, },
"node_modules/dayjs": {
"version": "1.11.13",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
"license": "MIT"
},
"node_modules/dir-glob": { "node_modules/dir-glob": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",

View File

@@ -20,6 +20,7 @@
"typescript": "^5.6.3" "typescript": "^5.6.3"
}, },
"dependencies": { "dependencies": {
"dayjs": "^1.11.13",
"peggy": "^4.2.0" "peggy": "^4.2.0"
} }
} }

View File

@@ -1,3 +1,4 @@
import dayjs, { Dayjs } from "dayjs";
import { ParsedTask, ParsedTaskDate, ParsedTaskDependency, ParsedTaskMeta } from "../types/grammar/task"; import { ParsedTask, ParsedTaskDate, ParsedTaskDependency, ParsedTaskMeta } from "../types/grammar/task";
import { Task, TaskPriority } from "../types/task"; import { Task, TaskPriority } from "../types/task";
@@ -15,7 +16,24 @@ export class LazyTask implements Task {
} }
get label(): string { get label(): string {
return this.#parsed.label; return this.#parsed.label
.filter(x => x.span === 'word' || x.span === 'whitespace')
.map(x => x.value)
.join("")
.trim();
}
get fullLabel(): string {
return this.#parsed.label
.map(x => x.span === 'tag' ? `#${x.value}` : x.value)
.join("")
.trim();
}
get tags(): string[] {
return this.#parsed.label
.filter(x => x.span === 'tag')
.map(x => x.value);
} }
get priority(): TaskPriority { get priority(): TaskPriority {
@@ -34,31 +52,37 @@ export class LazyTask implements Task {
}[priority] as TaskPriority; }[priority] as TaskPriority;
} }
get createdDate(): string|undefined { get createdDate(): Dayjs|undefined {
return this.#dates.find(d => d.type === '')?.date; return this.#date(this.#dates.find(d => d.type === '')?.date);
} }
get startDate(): string|undefined { #date(string?: string): Dayjs|undefined {
return this.#dates.find(d => d.type === '🛫')?.date; return string
? dayjs(string)
: undefined;
} }
get scheduledDate(): string|undefined { get startDate(): Dayjs|undefined {
return this.#dates.find(d => d.type === '')?.date; return this.#date(this.#dates.find(d => d.type === '🛫')?.date);
}
get scheduledDate(): Dayjs|undefined {
return this.#date(this.#dates.find(d => d.type === '⏳')?.date);
} }
get dueDate(): string|undefined { get dueDate(): Dayjs|undefined {
return this.#dates.find(d => d.type === '📅')?.date; return this.#date(this.#dates.find(d => d.type === '📅')?.date);
} }
get completedDate(): string|undefined { get completedDate(): Dayjs|undefined {
return this.#dates.find(d => d.type === '✅')?.date; return this.#date(this.#dates.find(d => d.type === '✅')?.date);
} }
get cancelledDate(): string|undefined { get cancelledDate(): Dayjs|undefined {
return this.#dates.find(d => d.type === '❌')?.date; return this.#date(this.#dates.find(d => d.type === '❌')?.date);
} }
get recurrencyRule(): string|undefined { get recurrenceRule(): string|undefined {
return this.#parsed.meta.find(x => x.feature === 'recurrence')?.rule; return this.#parsed.meta.find(x => x.feature === 'recurrence')?.rule;
} }
@@ -87,17 +111,18 @@ export class LazyTask implements Task {
const items = [ const items = [
o("priority", this.priority), o("priority", this.priority),
o("created", this.createdDate), o("created", this.createdDate?.format("YYYY-MM-DD")),
o("start", this.startDate), o("start", this.startDate?.format("YYYY-MM-DD")),
o("scheduled", this.scheduledDate), o("scheduled", this.scheduledDate?.format("YYYY-MM-DD")),
o("due", this.dueDate), o("due", this.dueDate?.format("YYYY-MM-DD")),
o("completed", this.completedDate), o("completed", this.completedDate?.format("YYYY-MM-DD")),
o("cancelled", this.cancelledDate), o("cancelled", this.cancelledDate?.format("YYYY-MM-DD")),
o("recurrence", this.recurrencyRule), o("recurrence", this.recurrenceRule),
o("delete", this.onDelete), o("delete", this.onDelete),
o("id", this.id), o("id", this.id),
o("deps", this.dependsOn.join(",")), o("deps", this.dependsOn.join(",")),
o("reminder", this.reminder) o("reminder", this.reminder),
o("tags", this.tags.join(","))
]; ];
return `- [${this.status}] ${this.label} {${items.filter(x => x.length > 0).join(", ")}}`; return `- [${this.status}] ${this.label} {${items.filter(x => x.length > 0).join(", ")}}`;

View File

@@ -8,10 +8,15 @@ export type ParseResult = {
export type ParsedTask = { export type ParsedTask = {
status: string; status: string;
label: string; label: ParsedTaskLabel[];
meta: ParsedTaskMeta[]; meta: ParsedTaskMeta[];
} }
export type ParsedTaskLabel = {
span: 'word'|'whitespace'|'tag';
value: string
};
export type ParsedTaskMeta = export type ParsedTaskMeta =
| ParsedTaskPriority | ParsedTaskPriority
| ParsedTaskRecurrence | ParsedTaskRecurrence

View File

@@ -1,14 +1,18 @@
import { Dayjs } from "dayjs";
export type Task = { export type Task = {
status: string; status: string;
label: string; label: string;
fullLabel: string;
tags: string[];
priority: TaskPriority; priority: TaskPriority;
createdDate?: string; createdDate?: Dayjs;
startDate?: string; startDate?: Dayjs;
scheduledDate?: string; scheduledDate?: Dayjs;
dueDate?: string; dueDate?: Dayjs;
completedDate?: string; completedDate?: Dayjs;
cancelledDate?: string; cancelledDate?: Dayjs;
recurrencyRule?: string; recurrenceRule?: string;
onDelete?: string; onDelete?: string;
id?: string; id?: string;
dependsOn?: string[]; dependsOn?: string[];