markdown-org-extract
CLI утилита для извлечения задач из markdown файлов с поддержкой меток Emacs Org-mode.
Установка и сборка
Требования
- Rust 1.70 или новее
- Cargo
Сборка проекта
Сборка в режиме разработки:
Сборка оптимизированной версии для production:
Бинарный файл будет создан в:
- Debug:
target/debug/markdown-org-extract - Release:
target/release/markdown-org-extract
Запуск
После сборки запустите утилиту:
# Debug версия
# Release версия
Или используйте cargo для запуска без явной сборки:
Тестирование
Запуск тестов:
Запуск с подробным выводом:
Проверка кода:
Покрытие тестами функционала рабочих дней
Модуль holidays (9 тестов):
- Загрузка календаря праздников
- Проверка обычных выходных и рабочих дней
- Новогодние каникулы 2025 (1-8 января) и 2026 (1-9 января)
- Переносы праздников 2026 (8 марта → 9 марта, 9 мая → 11 мая)
- Пропуск выходных и праздников при поиске следующего рабочего дня
Модуль timestamp::repeater (6 тестов):
- Парсинг повторов
+1wd,+2wd,++1wd,.+1wd - Расчет следующего повтора по рабочим дням
- Пропуск праздников в повторах
Модуль timestamp::parser (2 теста):
- Парсинг временных меток с
+1wdи+2wd
Использование
Параметры
--dir <DIR>- каталог для поиска (по умолчанию:.)--glob <GLOB>- шаблон для фильтрации файлов (по умолчанию:*.md)--format <FORMAT>- формат вывода:json,md,html(по умолчанию:json)--output <OUTPUT>- файл для записи результата (по умолчанию: stdout)--locale <LOCALE>- локали для дней недели через запятую (по умолчанию:ru,en)--agenda <MODE>- режим agenda:day,week,month(по умолчанию:day)--tasks- показать все TODO задачи, отсортированные по приоритету (альтернатива--agenda tasks)--date <DATE>- дата для режимаdayв формате YYYY-MM-DD (по умолчанию: текущая дата)--from <DATE>- начальная дата для режимаweekв формате YYYY-MM-DD (по умолчанию: понедельник текущей недели)--to <DATE>- конечная дата для режимаweekв формате YYYY-MM-DD (по умолчанию: воскресенье текущей недели)--tz <TIMEZONE>- часовой пояс для определения текущей даты (по умолчанию:Europe/Moscow)--current-date <DATE>- явная текущая дата для расчета overdue в формате YYYY-MM-DD (по умолчанию: сегодня в указанной таймзоне)--holidays <YEAR>- вывести список праздников для указанного года (1900-2100) в формате JSON
Примеры использования
Извлечь задачи из текущего каталога в JSON:
Извлечь задачи из конкретного каталога:
Сохранить результат в HTML файл:
Вывести в markdown формате:
Использовать примеры из проекта:
Использовать только русские дни недели:
Использовать только английские дни недели:
Примеры работы с agenda
Задачи на сегодня (по умолчанию):
Задачи на конкретную дату:
Получить список праздников для года:
Пример вывода праздников:
Задачи на текущую неделю:
```bash
markdown-org-extract --dir ./notes --agenda week
Задачи на текущий месяц:
Задачи на диапазон дат:
Все TODO задачи, отсортированные по приоритету:
Использовать другой часовой пояс:
Использовать явную текущую дату (для тестов):
Вывести список праздников для года:
Примеры файлов
В каталоге examples/ находятся примеры markdown файлов с различными метками:
project-tasks.md- задачи разработки проектаpersonal-notes.md- личные заметки и задачиmeeting-notes.md- заметки со встреч
Попробуйте запустить:
Режимы Agenda
Утилита поддерживает четыре режима работы с задачами, аналогично Emacs Org-mode:
day - Задачи на день
Показывает задачи с временными метками (SCHEDULED, DEADLINE) на указанную дату. По умолчанию используется текущая дата в указанной таймзоне.
# Задачи на сегодня
# Задачи на конкретную дату
week - Задачи на неделю
Показывает задачи с временными метками в диапазоне дат. По умолчанию используется текущая неделя (понедельник-воскресенье).
Каждый день показывает:
- Задачи, запланированные на этот день (scheduled)
- Предстоящие задачи относительно этого дня (upcoming)
- Просроченные задачи (overdue) - только для текущей даты
# Задачи на текущую неделю
# Задачи на конкретный диапазон
month - Задачи на месяц
Показывает задачи с временными метками в диапазоне дат. По умолчанию используется текущий месяц (с первого по последний день).
Работает аналогично режиму week - каждый день показывает scheduled, upcoming и overdue задачи.
# Задачи на текущий месяц
# Задачи на конкретный диапазон
tasks - Все TODO задачи
Показывает все задачи со статусом TODO, отсортированные по приоритету (A → B → C → без приоритета). Временные метки не учитываются.
# Все TODO задачи по приоритетам
Часовые пояса
Параметр --tz определяет часовой пояс для вычисления текущей даты и недели. Поддерживаются все стандартные IANA таймзоны.
# Московское время (по умолчанию)
# UTC
# Нью-Йорк
Поддерживаемые метки
Метки задач
Утилита распознает метки TODO и DONE в заголовках:
Приоритеты задач
Поддерживаются приоритеты в формате org-mode (буквы A-Z в квадратных скобках):
Приоритет указывается после метки TODO/DONE и перед текстом задачи. Наиболее распространенные приоритеты:
[#A]- высокий приоритет (критические задачи)[#B]- средний приоритет (важные задачи)[#C]- низкий приоритет (обычные задачи)
Приоритет является необязательным параметром.
Временные метки
Временные метки должны быть заключены в обратные кавычки:
Простая временная метка:
`<2024-12-10 Mon 10:00-12:00>`
Метки планирования:
`CREATED: <2024-12-01 Mon>`
`DEADLINE: <2024-12-15 Sun>`
`SCHEDULED: <2024-12-05 Wed>`
`CLOSED: <2024-12-01 Mon>`
Диапазон дат:
`<2024-12-20 Mon>--<2024-12-22 Wed>`
Неактивные временные метки (НЕ извлекаются):
`[2024-12-10 Mon]` - квадратные скобки означают неактивную метку
Примечание: Метка CREATED извлекается отдельно от других временных меток и сохраняется в поле created. Это позволяет отслеживать дату создания задачи независимо от других временных меток (SCHEDULED, DEADLINE, CLOSED).
Учет времени (CLOCK)
Утилита поддерживает метки CLOCK для отслеживания времени, потраченного на задачи, аналогично Emacs Org-mode.
Формат CLOCK записей (в обратных кавычках, как временные метки):
`SCHEDULED: <2024-12-10 Tue>`
`CLOCK: <2024-12-09 Mon 10:00>--<2024-12-09 Mon 12:30> => 2:30`
`CLOCK: <2024-12-09 Mon 14:00>--<2024-12-09 Mon 16:15> => 2:15`
Альтернативный формат (в code blocks, как в org-mode):
`SCHEDULED: <2024-12-10 Tue>`
CLOCK: [2024-12-09 Mon 10:00]--[2024-12-09 Mon 12:30] => 2:30 CLOCK: [2024-12-09 Mon 14:00]--[2024-12-09 Mon 16:15] => 2:15
Открытая CLOCK запись (активная работа):
`CLOCK: <2024-12-10 Tue 09:00>`
Возможности:
- Автоматическое извлечение всех CLOCK записей под заголовком
- Подсчет общего времени (
total_clock_time) по всем записям - Поддержка открытых (активных) CLOCK записей без времени окончания
- Отображение в JSON, Markdown и HTML форматах
- Поддержка как квадратных
[...](как в org-mode), так и угловых<...>скобок
Пример вывода JSON:
Пример вывода Markdown:
**Total Time:** 4:45
**Clock:**
- -
Поддержка локалей
Утилита поддерживает дни недели на разных языках через параметр --locale.
Поддерживаемые локали
en- английский (Mon, Tue, Wed, Thu, Fri, Sat, Sun, Monday, Tuesday, ...)ru- русский (Пн, Вт, Ср, Чт, Пт, Сб, Вс, Понедельник, Вторник, ...)
По умолчанию используются обе локали: --locale ru,en
Примеры с русскими днями недели
`<2024-12-10 Пн 10:00>`
`<2024-12-20 Понедельник>--<2024-12-22 Среда>`
`DEADLINE: <2024-12-15 Вс>`
Все русские дни недели автоматически нормализуются в английский формат при извлечении.
Формат вывода
Формат вывода зависит от режима agenda:
Режим --tasks (список задач)
JSON
Markdown
**File:** /path/to/file.md:42
**Type:** TODO
**Priority:** [#A]
**Created:** CREATED: <2024-12-01 Mon>
**Time:** DEADLINE: <2024-12-15 Sun>
Task description
Режимы --agenda day и --agenda week (дневная agenda)
В этих режимах задачи группируются по дням. Каждый день содержит категории задач (в порядке отображения):
- Overdue (только для текущей даты) - просроченные задачи, самые старые наверху
- Scheduled (with time) - задачи дня со временем, отсортированные по времени (ранние наверху)
- Scheduled (no time) - задачи дня без времени
- Upcoming - предстоящие задачи относительно этого дня, ближайшие наверху
Важно: Каждый день показывает upcoming задачи относительно себя, а не относительно общей референсной даты.
JSON
Поле days_offset показывает:
- Положительное число - количество дней до срока (upcoming)
- Отрицательное число - количество дней просрочки (overdue)
- Отсутствует для задач текущего дня (scheduled)
Markdown
**File:** ./examples/project-tasks.md:13
**Type:** Done
**Time:** CLOSED: <2024-12-01 Mon>
Repository created and initial structure set up.
**File:** ./examples/project-tasks.md:5
**Type:** Todo
**Priority:** A
**Time:** SCHEDULED: <2024-12-05 Wed>
Need to finalize the database structure.
**File:** ./examples/project-tasks.md:47
**Type:** Todo
**Time:** DEADLINE: <2024-12-06 Thu>
Critical bug fix needs review.
Поля разобранных временных меток
Для удобства отрисовки agenda внешними потребителями, временные метки автоматически разбираются на составные части:
timestamp_type- тип временной метки:SCHEDULED,DEADLINE,CLOSED,PLAINtimestamp_date- дата в форматеYYYY-MM-DDtimestamp_time- время начала (если указано), например10:00timestamp_end_time- время окончания (если указан диапазон), например12:00
Эти поля позволяют внешним системам отображать задачи на временной шкале без повторного парсинга строки timestamp.
Повторяющиеся задачи
Утилита поддерживает синтаксис повторов org-mode для автоматического планирования задач:
Типы повторов
Поддерживаются все стандартные единицы org-mode:
+Nh- повтор каждые N часов+Nd- повтор каждые N дней (строгий, сохраняет просрочку)+Nw- повтор каждые N недель+Nm- повтор каждые N месяцев+Ny- повтор каждые N лет+Nwd- повтор каждые N рабочих дней (расширение, с учетом праздников и выходных РФ)
Модификаторы типа повтора:
+- строгий повтор (cumulative), сохраняет просрочку++- умный повтор (catch-up), сохраняет день недели.+- повтор от даты завершения (restart)
Рабочие дни
Повторы с суффиксом wd (workday) учитывают:
- Обычные выходные (суббота, воскресенье)
- Официальные праздники РФ
- Переносы праздничных дней
Данные о праздниках хранятся в файле holidays_ru.json. При сборке проекта (build.rs) данные компилируются в статические константы Rust для максимальной производительности - парсинг JSON происходит один раз на этапе компиляции, а не в runtime.
Примеры
`SCHEDULED: <2025-12-05 Thu 10:00 +1h>`
`SCHEDULED: <2025-12-05 Thu +1d>`
`SCHEDULED: <2025-12-05 Thu +1w>`
`SCHEDULED: <2025-12-05 Thu +1m>`
`SCHEDULED: <2025-12-05 Thu +1y>`
`SCHEDULED: <2025-12-05 Thu +1wd>`
`SCHEDULED: <2025-12-05 Thu +2wd>`
Структура проекта
markdown-org-extract/
├── src/
│ └── main.rs # Основной код приложения
├── examples/ # Примеры markdown файлов
│ ├── project-tasks.md
│ ├── personal-notes.md
│ └── meeting-notes.md
├── Cargo.toml # Зависимости проекта
└── README.md # Документация
Зависимости
clap- парсинг аргументов командной строкиcomrak- парсинг markdownglob- поиск файлов по шаблонуregex- работа с регулярными выражениямиserde/serde_json- сериализация данных
Лицензия
MIT