diff --git a/grammar/task.pegjs b/grammar/task.pegjs index 6fb07ec..7e079b8 100644 --- a/grammar/task.pegjs +++ b/grammar/task.pegjs @@ -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) _ /**************************************************************************************************************************************/ diff --git a/src/parser/task.ts b/src/parser/task.ts index e33ea38..6e1e413 100644 --- a/src/parser/task.ts +++ b/src/parser/task.ts @@ -16,7 +16,24 @@ export class LazyTask implements Task { } 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 { @@ -104,7 +121,8 @@ export class LazyTask implements Task { o("delete", this.onDelete), o("id", this.id), 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(", ")}}`; diff --git a/src/types/grammar/task.ts b/src/types/grammar/task.ts index e32f4cd..fb02e6f 100644 --- a/src/types/grammar/task.ts +++ b/src/types/grammar/task.ts @@ -8,10 +8,15 @@ export type ParseResult = { export type ParsedTask = { status: string; - label: string; + label: ParsedTaskLabel[]; meta: ParsedTaskMeta[]; } +export type ParsedTaskLabel = { + span: 'word'|'whitespace'|'tag'; + value: string +}; + export type ParsedTaskMeta = | ParsedTaskPriority | ParsedTaskRecurrence diff --git a/src/types/task.ts b/src/types/task.ts index aa2e2bd..d5d56ef 100644 --- a/src/types/task.ts +++ b/src/types/task.ts @@ -3,6 +3,8 @@ import { Dayjs } from "dayjs"; export type Task = { status: string; label: string; + fullLabel: string; + tags: string[]; priority: TaskPriority; createdDate?: Dayjs; startDate?: Dayjs;