---
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 `[[...]]`.
