Przejdź do głównej treści
TaskForge 3.0: SI czyta twoje zadania.

Konwersja zadań Obsidian między formatami

Obsidian Tasks nie ma polecenia, które przepisuje sejf z jednego formatu na drugi. Mówi o tym jego dokumentacja. Poniższe skrypty i przepisy robią to zadanie, każdy sprawdzony na przykładowych liniach z dokumentacji samej wtyczki, plus jedna konwersja, do której istnieje narzędzie: linia zadania na plik zadania i z powrotem.

Napisane dla Obsidian Tasks 8.6, Task Genius 9.13 i TaskNotes 4.14, październik 2026. Nazwy pól i symbole są wymienione w ściądze.

Zanim cokolwiek zmienisz

  1. Zrób kopię zapasową sejfu. Skopiuj folder lub zacommituj go w git. Skrypt przepisujący 4 000 linii powinno być łatwo cofnąć.
  2. Najpierw pracuj na kopii. Uruchom konwersję na kopii sejfu, otwórz ją w Obsidian i wykonaj jedno ze swoich zwykłych zapytań o zadania. Porównaj liczby z oryginałem.
  3. Najpierw skonwertuj, potem przełącz wtyczkę. Obsidian Tasks czyta jeden format naraz. Najpierw skonwertuj linie, potem zmień format zadań w jego ustawieniach, żeby wtyczka nigdy nie zobaczyła w pół skonwertowanego sejfu.
  4. Sprawdź, co zostało. Przeszukaj sejf pod kątem starych symboli (📅, ⏳, ⏫ dla emoji; due::, repeat:: dla Dataview), aby znaleźć linie pominięte przez przepis.

Jakiej konwersji potrzebujesz

Z Na Jak
Linie z emoji Pola Dataview Skrypt lub przepis na znajdź i zamień poniżej.
Pola Dataview Linie z emoji Skrypt odwrotny lub przepis poniżej.
Dowolny Task Genius Nie ma czego przepisywać. Task Genius czyta oba w tej samej linii. Który z nich zapisuje, wybierasz w jego ustawieniach.
Linie zadań Pliki zadań TaskNotes konwertuje po jednej linii. Wiersz poleceń TaskForge konwertuje wiele naraz.
Pliki zadań Linie zadań Wiersz poleceń TaskForge, z podglądem wszystkiego, co by przepadło.

Z emoji na pola Dataview

Każde emoji wraz z wartością staje się polem w nawiasach. Emoji priorytetu zamieniają się w pole priority ze słowem, a tekst powtarzania trafia do nawiasów. Wykonuj zamiany w tej kolejności: najpierw daty i priorytet, powtarzanie na końcu, żeby tekst powtarzania kończył się tam, gdzie zaczyna się następny nawias.

Przed i po

Przed
- [ ] Send invoice to Acme ⏫ 🔁 every month ➕ 2026-10-01 ⏳ 2026-11-01 📅 2026-11-03 #finance
- [x] Book flights 📅 2026-10-25 ✅ 2026-10-20
- [ ] Order parts 🆔 parts1
- [ ] Assemble 🛫 2026-11-10 ⛔ parts1 📅 2026-11-15
Po
- [ ] Send invoice to Acme  [priority:: high]  [repeat:: every month]  [created:: 2026-10-01]  [scheduled:: 2026-11-01]  [due:: 2026-11-03] #finance
- [x] Book flights  [due:: 2026-10-25]  [completion:: 2026-10-20]
- [ ] Order parts  [id:: parts1]
- [ ] Assemble  [start:: 2026-11-10]  [dependsOn:: parts1]  [due:: 2026-11-15]

Znajdź i zamień, jedno pole naraz

Te wzorce działają w każdym edytorze z wyszukiwaniem regex w wielu plikach, takim jak VS Code, który zapisuje przechwycony tekst jako $1. Włącz tryb regex i rozróżnianie wielkości liter. W przeciwieństwie do skryptu działają na każdej linii, nie tylko na polach wyboru.

Pole Znajdź Zamień na
📅 (?:📅|📆|🗓️?)\s*(\d{4}-\d{2}-\d{2}) [due:: $1]
⏳ (?:⏳|⌛)\s*(\d{4}-\d{2}-\d{2}) [scheduled:: $1]
🛫 🛫\s*(\d{4}-\d{2}-\d{2}) [start:: $1]
➕ ➕\s*(\d{4}-\d{2}-\d{2}) [created:: $1]
✅ ✅\s*(\d{4}-\d{2}-\d{2}) [completion:: $1]
❌ ❌\s*(\d{4}-\d{2}-\d{2}) [cancelled:: $1]
🔺 🔺️? [priority:: highest]
⏫ ⏫️? [priority:: high]
🔼 🔼️? [priority:: medium]
🔽 🔽️? [priority:: low]
⏬ ⏬️? [priority:: lowest]
🏁 🏁\s*(keep|delete) [onCompletion:: $1]
🆔 🆔\s*([A-Za-z0-9_-]+) [id:: $1]
⛔ ⛔\s*([A-Za-z0-9_-]+(?:\s*,\s*[A-Za-z0-9_-]+)*) [dependsOn:: $1]
🔁 🔁\s*([A-Za-z0-9, !]*[A-Za-z0-9])(?=\s*(?:\[|\^|$)) [repeat:: $1]

To samo jako skrypt

Zapisz go jako emoji_to_dataview.py i uruchom: python3 emoji_to_dataview.py Inbox.md Projects/*.md. Dotyka tylko linii z polami wyboru, wstawia dwie spacje przed każdym polem tak jak Obsidian Tasks, a także konwertuje zapasowe symbole terminu i daty zaplanowanej 📆, 🗓 i ⌛.

#!/usr/bin/env python3
"""Rewrite Obsidian Tasks emoji fields to Dataview [key:: value] fields.

Usage: emoji_to_dataview.py NOTE.md [NOTE.md ...]   (rewrites in place; back up first)
Only checkbox lines are touched. Run it on a copy of your vault first.
"""
import os
import re
import sys

DATE = r"(\d{4}-\d{2}-\d{2})"
ID = r"[A-Za-z0-9_-]+"
RULES = [
    (rf"(?:📅|📆|🗓️?)\s*{DATE}", r"[due:: \1]"),
    (rf"(?:⏳|⌛)\s*{DATE}", r"[scheduled:: \1]"),
    (rf"🛫\s*{DATE}", r"[start:: \1]"),
    (rf"➕\s*{DATE}", r"[created:: \1]"),
    (rf"✅\s*{DATE}", r"[completion:: \1]"),
    (rf"❌\s*{DATE}", r"[cancelled:: \1]"),
    (r"🔺️?", "[priority:: highest]"),
    (r"⏫️?", "[priority:: high]"),
    (r"🔼️?", "[priority:: medium]"),
    (r"🔽️?", "[priority:: low]"),
    (r"⏬️?", "[priority:: lowest]"),
    (r"🏁\s*(keep|delete)", r"[onCompletion:: \1]"),
    (rf"🆔\s*({ID})", r"[id:: \1]"),
    (rf"⛔\s*({ID}(?:\s*,\s*{ID})*)", r"[dependsOn:: \1]"),
    # Last, so the rule text ends at the next bracket or the end of the line.
    (r"🔁\s*([A-Za-z0-9, !]*[A-Za-z0-9])(?=\s*(?:\[|\^|$))", r"[repeat:: \1]"),
]
TASK = re.compile(r"^(\s*(?:[-*+]|\d+\.)\s+\[.\]\s)(.*)$")

for path in sys.argv[1:]:
    out = []
    for raw in open(path, encoding="utf-8", newline="").read().split("\n"):
        cr = "\r" if raw.endswith("\r") else ""
        line = raw[: len(raw) - len(cr)]
        m = TASK.match(line)
        if m:
            head, body = m.groups()
            for pattern, repl in RULES:
                body = re.sub(pattern, repl, body)
            body = re.sub(r"\s*(\[(?:due|scheduled|start|created|completion|cancelled|priority|onCompletion|id|dependsOn|repeat):: )", r"  \1", body)
            line = head + body
        out.append(line + cr)
    tmp = path + ".tmp"
    with open(tmp, "w", encoding="utf-8", newline="") as fh:
        fh.write("\n".join(out))
    os.replace(tmp, path)

Z pól Dataview na emoji

Odwrotny skrypt czyta zarówno [key:: value], jak i (key:: value) i zapisuje standardowe emoji. Pola, których nie zna, jak [project:: Website], zostają w linii nietknięte, a priorytet zapisany liczbą jest pomijany, bo wtyczki nie zgadzają się co do znaczenia liczb.

Przed
- [ ] Send invoice to Acme  [priority:: high]  [repeat:: every month]  [created:: 2026-10-01]  [scheduled:: 2026-11-01]  [due:: 2026-11-03] #finance
- [x] Book flights  [due:: 2026-10-25]  [completion:: 2026-10-20]
- [ ] Order parts  [id:: parts1]
- [ ] Assemble  [start:: 2026-11-10]  [dependsOn:: parts1]  [due:: 2026-11-15]
Po
- [ ] Send invoice to Acme ⏫ 🔁 every month ➕ 2026-10-01 ⏳ 2026-11-01 📅 2026-11-03 #finance
- [x] Book flights 📅 2026-10-25 ✅ 2026-10-20
- [ ] Order parts 🆔 parts1
- [ ] Assemble 🛫 2026-11-10 ⛔ parts1 📅 2026-11-15

Uruchomiony na wyniku poprzedniego skryptu zwraca dokładnie powyższe przykładowe linie. Prawdziwe sejfy są mniej uporządkowane: linie z 📆, 🗓 lub ⌛ wracają jako 📅 lub ⏳, a linia z pustym opisem zyskuje spację.

Zapisz go jako dataview_to_emoji.py i uruchom tak samo.

#!/usr/bin/env python3
"""Rewrite Dataview [key:: value] task fields to Obsidian Tasks emoji fields.

Usage: dataview_to_emoji.py NOTE.md [NOTE.md ...]   (rewrites in place; back up first)
Reads [key:: v] and (key:: v). Only checkbox lines are touched.
"""
import os
import re
import sys

DATE = r"(\d{4}-\d{2}-\d{2})"
ID = r"[A-Za-z0-9_-]+"


def field(key, value):
    return rf"[\[(]\s*{key}::\s*{value}\s*[\])]"


RULES = [
    (field("due", DATE), r"📅 \1"),
    (field("scheduled", DATE), r"⏳ \1"),
    (field("start", DATE), r"🛫 \1"),
    (field("created", DATE), r"➕ \1"),
    (field("completion", DATE), r"✅ \1"),
    (field("cancelled", DATE), r"❌ \1"),
    (field("priority", "highest"), "🔺"),
    (field("priority", "high"), "⏫"),
    (field("priority", "medium"), "🔼"),
    (field("priority", "low"), "🔽"),
    (field("priority", "lowest"), "⏬"),
    (field("onCompletion", "(keep|delete)"), r"🏁 \1"),
    (field("id", f"({ID})"), r"🆔 \1"),
    (field("dependsOn", rf"({ID}(?:\s*,\s*{ID})*)"), r"⛔ \1"),
    (field("repeat", r"([A-Za-z0-9, !]*[A-Za-z0-9])"), r"🔁 \1"),
]
TASK = re.compile(r"^(\s*(?:[-*+]|\d+\.)\s+\[.\]\s)(.*)$")

for path in sys.argv[1:]:
    out = []
    for raw in open(path, encoding="utf-8", newline="").read().split("\n"):
        cr = "\r" if raw.endswith("\r") else ""
        line = raw[: len(raw) - len(cr)]
        m = TASK.match(line)
        if m:
            head, body = m.groups()
            for pattern, repl in RULES:
                body = re.sub(pattern, repl, body, flags=re.I if "priority" in pattern else 0)
            line = head + re.sub(r"[ \t]{2,}", " ", body).rstrip()
        out.append(line + cr)
    tmp = path + ".tmp"
    with open(tmp, "w", encoding="utf-8", newline="") as fh:
        fh.write("\n".join(out))
    os.replace(tmp, path)

Czego konwersja nie obsługuje

  • Linii z tekstem między dwoma polami. Obsidian Tasks czyta od końca linii, więc tych pól i tak by nie przeczytał.
  • Linku blokowego, takiego jak ^abc123, na końcu linii. Skrypty zostawiają go na miejscu, czyli tam, gdzie oczekuje go Obsidian.
  • Składni tylko dla Task Genius: godzin po datach, priorytetów [#A], pól projektu i kontekstu, reguł powtarzania iCalendar. Zostaw te linie w spokoju albo skonwertuj je ręcznie.
  • Reguł powtarzania, które jeden format zapisuje inaczej. Po przełączeniu sprawdź kilka zadań cyklicznych, zwłaszcza z when done.
  • Zadań cyklicznych, które mają już w pliku ukończone kopie. Kopie to zwykłe ukończone zadania i konwertują się jak każda inna linia.
  • Linii wewnątrz bloków kodu. Skrypty działają linia po linii i nie znają bloków, więc notatki cytujące przykłady skonwertuj ręcznie.
  • Nierozpoznane pole na końcu linii, np. [custom:: x]. Obsidian Tasks czyta od końca, więc zatrzymuje się na nim i pomija skonwertowane pola przed nim.
  • Reguła 🔁 po której stoi #tag. Powtarzanie zostaje nieskonwertowane, więc przenieś tag przed nią albo skonwertuj tę linię ręcznie.
  • Zadania w cytatach lub calloutach (linie zaczynające się od > - [ ]). Skrypty je pomijają.
  • Godzina po dacie, np. 14:30. Zostaje poza skonwertowanym polem. Obsidian Tasks nie ma pola godziny, więc czyta ją tylko Task Genius.

Z linii zadań na pliki zadań

Plik zadania to notatka z polami zadania we frontmatterze YAML, w formacie używanym przez TaskNotes. Nie każde pole linii ma tam swoje miejsce. Tak pola mapują się na właściwości TaskNotes.

Gdzie trafia każde pole

W linii zadania W pliku zadania Uwaga
📅 2026-11-03
due: 2026-11-03
Ta sama nazwa.
⏳ 2026-11-01
scheduled: 2026-11-01
Ta sama nazwa.
🛫 2026-11-10
start: 2026-11-10
TaskNotes nie ma daty startowej. Zachowaj ją jako właściwość niestandardową, jeśli jej potrzebujesz.
➕ 2026-10-01
dateCreated: 2026-10-01T08:00:00Z
Zapisywana jako znacznik czasu ISO.
✅ 2026-10-20
completedDate: 2026-10-20
Status staje się wartością „ukończone”, a data trafia do completedDate.
⏫
priority: high
Używa wartości z Twojej listy priorytetów TaskNotes. Lista domyślna ma trzy poziomy, nie pięć, więc zdecyduj, jak mapuje się pięć.
🔁 every month
recurrence: "DTSTART:20261103;FREQ=MONTHLY"
Staje się regułą iCalendar. every month przy terminie 2026-11-03 zamienia się w DTSTART:20261103;FREQ=MONTHLY.
#finance
tags:
  - finance
Stają się listą YAML, bez krzyżyka.
🏁 delete
onCompletion: delete
Brak właściwości TaskNotes. Zachowane jako zwykły klucz frontmatter, który TaskNotes ignoruje.
🆔 parts1
id: parts1
Brak właściwości TaskNotes. Zależności w TaskNotes wskazują ścieżki plików, nie ID.
⛔ parts1
blockedBy:
  - uid: "Tasks/Order parts.md"
    reltype: FINISHTOSTART
Staje się wpisem blockedBy wskazującym plik drugiego zadania.

Po jednej linii z TaskNotes

TaskNotes ma polecenie Convert to TaskNote oraz przycisk konwersji obok pól wyboru, który możesz włączyć w ustawieniach funkcji. Każde z nich tworzy z linii nowy plik zadania i zastępuje linię linkiem do niego. W sam raz na kilka zadań, wolne dla całego sejfu.

Wiele naraz z wierszem poleceń TaskForge

TaskForge to osobna aplikacja, a jej narzędzie wiersza poleceń (będące też silnikiem jej serwera MCP) konwertuje zadania między linią a plikiem, w obu kierunkach, pojedynczo lub zbiorczo. Potrzebuje sejfu skonfigurowanego pod pliki zadań, bo musi wiedzieć, jak je rozpoznawać. Najpierw podgląd. Zbiorcze zatwierdzenie musi powtórzyć liczbę zadań znalezionych w podglądzie, więc zbyt szerokie zapytanie nie skonwertuje więcej, niż zamierzano.

Podgląd, potem konwersja każdego zadania z tagiem #home
taskforge convert --query 'tag:home' --to tasknotes --folder Tasks --dry-run
taskforge convert --query 'tag:home' --to tasknotes --folder Tasks --acknowledge-count 2

Prawdziwe uruchomienie

W Inbox.md
- [ ] Send invoice to Acme ⏫ 🔁 every month 📅 2026-11-03 #finance
Tasks/Send invoice to Acme.md
---
title: Send invoice to Acme
status: open
priority: high
tags:
  - finance
  - task
recurrence: "DTSTART:20261103;FREQ=MONTHLY"
due: 2026-11-03
---

Priorytet ⏫ stał się high, a every month stało się regułą iCalendar zakotwiczoną na terminie. W drugim uruchomieniu data startowa, akcja po ukończeniu i ID zadania zostały zachowane jako zwykłe klucze frontmatter (start, onCompletion, id), a nie odrzucone. Polecenie odmawia każdego zadania, którego nie umie skonwertować w całości. Konwersja pliku z powrotem na linię dodaje do linii tag identyfikujący plik, task.

Aby pójść w drugą stronę, wskaż notatkę docelową i najpierw zrób podgląd:

taskforge convert --query 'tag:home' --to inline --folder Inbox.md --dry-run

Pytania, które ludzie zadają

Jak skonwertować emoji Obsidian Tasks na format Dataview?

Obsidian Tasks nie ma polecenia konwersji. Zmień format zadań w jego ustawieniach dopiero po przepisaniu linii, używając znajdź i zamień z regex albo skryptu takiego jak ten na tej stronie. Najpierw zrób kopię zapasową i przetestuj na kopii.

Czy zmiana formatu zadań w Obsidian Tasks skonwertuje moje istniejące zadania?

Nie. Ustawienie zmienia tylko to, jak wtyczka czyta i zapisuje od tej chwili. Linie w starym formacie przestają być czytane jako pola, dopóki ich nie przepiszesz.

Jak zamienić wiele zadań z polami wyboru w pliki TaskNotes?

TaskNotes konwertuje po jednej linii. Dla całej partii wiersz poleceń TaskForge konwertuje każde zadanie pasujące do zapytania, najpierw na sucho. Tak czy inaczej sprawdź, czy pola bez właściwości w TaskNotes, takie jak daty startowe, wylądowały tam, gdzie chcesz.

Czy w ogóle muszę konwertować, jeśli używam Task Genius?

Zwykle nie. Task Genius czyta pola z emoji i w nawiasach w tej samej linii, więc sejfy mieszane działają bez zmian. Konwersja pomaga tylko wtedy, gdy używasz też Obsidian Tasks lub Dataview, z których każdy czyta jeden styl.

Czy skrypty mogą uszkodzić moje notatki?

Zmieniają tylko linie z polami wyboru i tylko rozpoznawane pola, ale przepisują pliki w miejscu. Zrób najpierw kopię zapasową, uruchom na kopii i porównaj wyniki, zanim powierzysz im prawdziwy sejf.