Saltar al contenido principal
TaskForge 3.0: tu IA lee tus tareas.

Convertir tareas de Obsidian entre formatos

Obsidian Tasks no tiene ningún comando que reescriba una bóveda de un formato a otro. Su documentación lo dice. Las conversiones de abajo son scripts y recetas que hacen el trabajo, cada una probada con las líneas de ejemplo de la documentación del propio complemento, más la única conversión para la que existe una herramienta: de línea de tarea a archivo de tarea y viceversa.

Escrito con Obsidian Tasks 8.6, Task Genius 9.13 y TaskNotes 4.14, octubre de 2026. Los nombres de campo y los símbolos están en la hoja de referencia.

Antes de cambiar nada

  1. Haz una copia de seguridad de la bóveda. Copia la carpeta o súbela a git. Un script que reescribe 4.000 líneas debería ser fácil de deshacer.
  2. Trabaja primero con una copia. Ejecuta la conversión en una copia de la bóveda, ábrela en Obsidian y lanza una de tus consultas de tareas habituales. Compara los totales con el original.
  3. Convierte y luego cambia el complemento. Obsidian Tasks lee un formato a la vez. Convierte primero las líneas y después cambia el formato de tarea en sus ajustes, para que el complemento nunca vea una bóveda a medio convertir.
  4. Revisa lo que queda. Busca en la bóveda los símbolos antiguos (📅, ⏳, ⏫ para emoji; due::, repeat:: para Dataview) y encontrarás las líneas que la receta se saltó.

Qué conversión necesitas

De A Cómo
Líneas con emoji Campos de Dataview El script o la receta de buscar y reemplazar de abajo.
Campos de Dataview Líneas con emoji El script o la receta inversos de abajo.
Cualquiera Task Genius No hay nada que reescribir. Task Genius lee ambos en la misma línea. Elige cuál escribe en sus ajustes.
Líneas de tarea Archivos de tarea TaskNotes convierte una línea cada vez. La línea de comandos de TaskForge convierte muchas a la vez.
Archivos de tarea Líneas de tarea La línea de comandos de TaskForge, con una vista previa de lo que se perdería.

De emoji a campos de Dataview

Cada emoji y su valor se convierte en un campo entre corchetes. Los emoji de prioridad pasan a ser un campo priority con una palabra, y el texto de recurrencia se mueve dentro de sus corchetes. Haz los reemplazos en este orden: primero fechas y prioridad, la recurrencia al final, para que el texto de recurrencia termine donde empieza el siguiente corchete.

Antes y después

Antes
- [ ] 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
Después
- [ ] 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]

Buscar y reemplazar, un campo cada vez

Estos patrones funcionan en cualquier editor con búsqueda regex en varios archivos, como VS Code, que escribe el texto capturado como $1. Activa el modo regex y distingue mayúsculas. A diferencia del script, se aplican a todas las líneas, no solo a las que tienen casilla.

Campo Buscar Reemplazar por
📅 (?:📅|📆|🗓️?)\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]

Lo mismo como script

Guárdalo como emoji_to_dataview.py y ejecuta python3 emoji_to_dataview.py Inbox.md Projects/*.md. Solo toca líneas con casilla, escribe dos espacios antes de cada campo como hace Obsidian Tasks, y también convierte los símbolos alternativos de vencimiento y programada 📆, 🗓 y ⌛.

#!/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)

De campos de Dataview a emoji

La conversión inversa lee tanto [key:: value] como (key:: value) y escribe los emoji estándar. Los campos que no conoce, como [project:: Website], quedan en la línea sin tocar, y una prioridad escrita como número se deja como está porque los complementos no se ponen de acuerdo en qué significan los números.

Antes
- [ ] 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]
Después
- [ ] 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

Ejecutado sobre la salida del script anterior, devuelve exactamente las líneas de ejemplo de arriba. Las bóvedas reales son menos ordenadas: las líneas que usaban 📆, 🗓 o ⌛ vuelven como 📅 o ⏳, y una línea con la descripción vacía gana un espacio.

Guárdalo como dataview_to_emoji.py y ejecútalo de la misma manera.

#!/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)

Lo que la conversión no cubre

  • Una línea con texto entre dos campos. Obsidian Tasks lee desde el final de la línea, así que esos campos no los habrá leído de entrada.
  • Un enlace de bloque como ^abc123 al final de la línea. Los scripts lo dejan donde está, que es donde Obsidian lo espera.
  • Sintaxis exclusiva de Task Genius: horas tras las fechas, prioridades [#A], campos de proyecto y contexto, reglas de recurrencia de iCalendar. Deja esas líneas como están o conviértelas a mano.
  • Reglas de recurrencia que un formato escribe de otra manera. Revisa unas cuantas tareas recurrentes tras el cambio, sobre todo las que llevan when done.
  • Tareas recurrentes que ya tienen copias completadas en el archivo. Las copias son tareas hechas normales y se convierten como cualquier otra línea.
  • Líneas dentro de bloques de código. Los scripts trabajan línea a línea y no conocen los delimitadores, así que convierte a mano las notas que citan ejemplos.
  • Un campo no reconocido al final de la línea, como [custom:: x]. Obsidian Tasks lee desde el final, así que se detiene ahí e ignora los campos convertidos que van antes.
  • Una regla 🔁 seguida de una #etiqueta. La recurrencia queda sin convertir, así que mueve la etiqueta antes de ella o convierte esa línea a mano.
  • Tareas dentro de citas o llamadas (líneas que empiezan por > - [ ]). Los scripts las omiten.
  • Una hora tras una fecha, como 14:30. Queda fuera del campo convertido. Obsidian Tasks no tiene campo de hora, así que solo Task Genius la lee.

De líneas de tarea a archivos de tarea

Un archivo de tarea es una nota con los campos de la tarea en el frontmatter YAML, el formato que usa TaskNotes. No todos los campos de una línea tienen sitio ahí. Así se corresponden los campos con las propiedades de TaskNotes.

Dónde va cada campo

En una línea de tarea En un archivo de tarea Nota
📅 2026-11-03
due: 2026-11-03
Mismo nombre.
⏳ 2026-11-01
scheduled: 2026-11-01
Mismo nombre.
🛫 2026-11-10
start: 2026-11-10
TaskNotes no tiene fecha de inicio. Guárdala como propiedad personalizada si la necesitas.
➕ 2026-10-01
dateCreated: 2026-10-01T08:00:00Z
Se escribe como marca de tiempo ISO.
✅ 2026-10-20
completedDate: 2026-10-20
El estado pasa a un valor de hecha, y la fecha va en completedDate.
⏫
priority: high
Usa los valores de tu lista de prioridades de TaskNotes. La lista predeterminada tiene tres niveles, no cinco, así que decide cómo se corresponden los cinco.
🔁 every month
recurrence: "DTSTART:20261103;FREQ=MONTHLY"
Pasa a ser una regla de iCalendar. every month con una fecha de vencimiento de 2026-11-03 se convierte en DTSTART:20261103;FREQ=MONTHLY.
#finance
tags:
  - finance
Pasan a ser una lista YAML, sin la almohadilla.
🏁 delete
onCompletion: delete
No hay propiedad de TaskNotes. Se conserva como una clave de frontmatter normal que TaskNotes ignora.
🆔 parts1
id: parts1
No hay propiedad de TaskNotes. Las dependencias en TaskNotes apuntan a rutas de archivo, no a ID.
⛔ parts1
blockedBy:
  - uid: "Tasks/Order parts.md"
    reltype: FINISHTOSTART
Pasa a ser una entrada blockedBy que nombra el archivo de la otra tarea.

Una línea cada vez con TaskNotes

TaskNotes tiene un comando Convert to TaskNote y un botón de conversión junto a las casillas que puedes activar en sus ajustes de funciones. Cualquiera de los dos crea un archivo de tarea nuevo a partir de la línea y la sustituye por un enlace a él. Vale para unas pocas tareas, y es lento para toda una bóveda.

Muchas a la vez con la línea de comandos de TaskForge

TaskForge es una app independiente, y su herramienta de línea de comandos (también el motor de su servidor MCP) convierte tareas entre línea y archivo, en ambos sentidos, de una en una o en bloque. Necesita una bóveda configurada para archivos de tarea, porque tiene que saber cómo reconocerlos. Haz primero una vista previa. Una confirmación en bloque debe repetir el número de tareas que encontró la vista previa, de modo que una consulta demasiado amplia no pueda convertir más de lo que querías.

Vista previa y luego conversión de todas las tareas con la etiqueta #home
taskforge convert --query 'tag:home' --to tasknotes --folder Tasks --dry-run
taskforge convert --query 'tag:home' --to tasknotes --folder Tasks --acknowledge-count 2

Una ejecución real

En 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
---

La prioridad ⏫ pasó a high y every month se convirtió en una regla de iCalendar anclada a la fecha de vencimiento. En una segunda ejecución, una fecha de inicio, una acción al completar y un ID de tarea se conservaron como claves normales de frontmatter (start, onCompletion, id) en lugar de descartarse. El comando rechaza cualquier tarea que no pueda convertir entera. Al convertir un archivo de vuelta a línea, se añade a la línea la etiqueta que identifica al archivo, task.

Para ir en sentido contrario, indica una nota de destino y haz primero una vista previa:

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

Preguntas habituales

¿Cómo convierto los emoji de Obsidian Tasks al formato Dataview?

Obsidian Tasks no tiene comando de conversión. Cambia el formato de tarea en sus ajustes solo después de reescribir las líneas, con buscar y reemplazar mediante regex o con un script como el de esta página. Haz antes una copia de seguridad y prueba con una copia.

¿Cambiar el formato de tarea en Obsidian Tasks convierte mis tareas existentes?

No. El ajuste cambia cómo el complemento lee y escribe a partir de ese momento. Las líneas en el formato antiguo dejan de leerse como campos hasta que las reescribas.

¿Cómo convierto muchas tareas con casilla en archivos de TaskNotes?

TaskNotes convierte una línea cada vez. Para un lote, la línea de comandos de TaskForge convierte todas las tareas que cumplan una consulta, con una ejecución de prueba antes. En cualquier caso, comprueba que los campos sin propiedad en TaskNotes, como las fechas de inicio, hayan acabado donde quieres.

¿Necesito convertir algo si uso Task Genius?

Normalmente no. Task Genius lee campos con emoji y con corchetes en la misma línea, así que las bóvedas mixtas funcionan tal cual. Convertir solo ayuda si también usas Obsidian Tasks o Dataview, que leen un estilo cada uno.

¿Pueden los scripts dañar mis notas?

Solo cambian líneas con casilla y solo los campos que reconocen, pero reescriben los archivos en el sitio. Haz una copia de seguridad, ejecútalos en una copia y compara antes de confiarles la bóveda real.