(tail: string)
| 148 | } |
| 149 | |
| 150 | function extractTokens(tail: string): ExtractedTokens { |
| 151 | let due: string | undefined |
| 152 | let priority: TaskPriority | undefined |
| 153 | let waiting = false |
| 154 | const tags: string[] = [] |
| 155 | let stripped = tail |
| 156 | |
| 157 | const dueMatch = stripped.match(INLINE_DUE_RE) |
| 158 | if (dueMatch) { |
| 159 | const candidate = dueMatch[1] |
| 160 | if (isValidIsoDate(candidate)) due = candidate |
| 161 | stripped = stripped.replace(INLINE_DUE_RE, ' ') |
| 162 | } |
| 163 | |
| 164 | const priMatch = stripped.match(INLINE_PRIORITY_RE) |
| 165 | if (priMatch) { |
| 166 | priority = normalizePriority(priMatch[1]) |
| 167 | stripped = stripped.replace(INLINE_PRIORITY_RE, ' ') |
| 168 | } |
| 169 | |
| 170 | if (INLINE_WAITING_RE.test(stripped)) { |
| 171 | waiting = true |
| 172 | stripped = stripped.replace(INLINE_WAITING_RE, ' ') |
| 173 | } |
| 174 | |
| 175 | INLINE_TAG_RE.lastIndex = 0 |
| 176 | let tm: RegExpExecArray | null |
| 177 | while ((tm = INLINE_TAG_RE.exec(tail))) { |
| 178 | const tag = tm[1].toLowerCase() |
| 179 | if (!tags.includes(tag)) tags.push(tag) |
| 180 | } |
| 181 | |
| 182 | return { |
| 183 | due, |
| 184 | priority, |
| 185 | waiting, |
| 186 | tags, |
| 187 | stripped: stripped.replace(/\s+/g, ' ').trim() |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | // --------------------------------------------------------------------------- |
| 192 | // Main parser |
no test coverage detected