--- name: extract_obsidian_wikilinks kind: function lang: py domain: obsidian version: "1.0.0" purity: pure signature: "def extract_obsidian_wikilinks(body: str) -> list" description: "Extrae los targets de los wikilinks [[...]] del cuerpo de una nota de Obsidian. Normaliza alias ([[nota|alias]] -> nota), heading ([[nota#h]] -> nota) y block id ([[nota#^id]] -> nota). Incluye tambien los embeds ![[...]] como links (Obsidian los trata como tales). Deduplica preservando orden de aparicion. Pura, sin I/O." tags: [obsidian, wikilink, links, markdown, extract, note, graph] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "" imports: ["re"] params: - name: body desc: "Cuerpo Markdown de una nota de Obsidian (idealmente sin frontmatter). Puede contener wikilinks [[...]] y embeds ![[...]] con alias (|), heading (#) o block id (#^)." output: "Lista de strings con los nombres de nota target unicos, en orden de primera aparicion. Cada target esta normalizado (sin alias, sin heading/block anchor, sin espacios al borde). Los embeds de imagen/nota se incluyen igual que los links normales. Lista vacia si no hay wikilinks." tested: true tests: - "links basicos y normalizacion" - "incluye embeds" - "dedup preserva orden" - "alias y heading combinados" - "whitespace se strippa" - "sin links" - "body vacio" test_file_path: "python/functions/obsidian/extract_obsidian_wikilinks_test.py" file_path: "python/functions/obsidian/extract_obsidian_wikilinks.py" --- ## Ejemplo ```python body = ( "See [[Note A]] and [[Note B|the second]] plus [[Note A#Section]] " "and [[Note C#^block123]]. Embed: ![[diagram.png]]. Repeat [[Note A]]." ) extract_obsidian_wikilinks(body) # ["Note A", "Note B", "Note C", "diagram.png"] ``` ## Cuando usarla Usala para construir el grafo de enlaces de un vault (backlinks/forward-links), detectar notas huerfanas o referenciadas, o validar enlaces rotos antes de un refactor. Aplicala al `body` que devuelve `parse_obsidian_frontmatter` para ignorar wikilinks que pudieran aparecer dentro de valores YAML del frontmatter. ## Gotchas - Los embeds `![[...]]` se incluyen como links (decision intencional: Obsidian los cuenta en el grafo). Si necesitas separar links de embeds, filtra por la extension del target o por el `!` aparte — esta funcion no distingue. - Solo normaliza al nombre de nota: pierde deliberadamente el alias, el heading y el block id. Si necesitas el anchor completo, parsea el body tu mismo. - No resuelve rutas relativas ni desambigua notas con el mismo nombre en carpetas distintas: devuelve el texto del link tal cual (sin la carpeta si el link no la incluye). - No procesa Markdown links estandar `[texto](url)` — solo wikilinks `[[...]]`.