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