Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 Контент вільний від AI. Цей пост на 100% написаний людиною, як і все на моєму блозі. Насолоджуйтесь!

27.08.2023

Розширення парсера Remark

Останній раз я писав про Remark з точки зору споживача. Проте, довелося також його й дописувати. Документації тут бракує, а екосистема складна, тому не так вже воно й легко.

Мені, власне, потрібно впровадити підтримку знайомого по GitHub синтаксису задач - [ ] To do. Для такого вже є рішення. Проте є нюанс: в Obsidian дозволено ставити статусом задачі не тільки хрестик, але й інші символи (наприклад, - для скасованих задач.) А всі плагіни, що існують, мають семантику “пробіл або хрестик”. Тому взяв за основу gfm-task-list-item та модифікував його так, щоб інші символи теж були дозволені.

Перший сюрприз - Remark використовує парсер micromark. Нестандартний синтаксис майже напевно потребує особливої обробки токенів, тому доведеться робити розширення для Micromark, що мене здивувало, бо це ціла окрема бібліотека (збирався робити на Remark, а опинився в Micromark). Micromark це взагалі повноцінний парсер, але Remark бере від нього саме токенізатор.

Доповнення для токенізатора складається з символу-тригера та логіки, яка споживає символи та генерує токени власних типів. Так, доповнення gfm-task-list-item споживало маркер задачі та перевіряло, чи то пробіл або хрестик. Якщо так, то генерувало токен “задача зроблена/не зроблена”, а в протилежному чині — відмовлялася від обробки. Я поміняв це на простішу логіку, що просто зберігає символ між квадратними дужками в токен taskListItemValue.

Щоб перетворити ці токени на елементи дерева AST, потрібне друге доповнення для іншого етапу, яке називається тут fromMarkdownExtension. Таке доповнення реагує на потік токенів та будує дерево. Відповідно, в моєму випадку воно слухає вихід з taskListItemValue (тобто коли вже відомо, що токен прочитаний повністю) та переносить символ маркера з токена в атрибут вузла listItem.

Все це треба робити тому, що без особливої обробки рядок [ ] не є вірним Markown - це посилання без адреси. Тому не можна просто шукати його в тексті вже по готовому дереву.