# Parse HTML to Markdown

Fuente conceptual: OpenViking `openviking/parse/parsers/html.py` (AGPL-3.0)
Reimplementar desde cero. No copiar codigo.

## Funciones a implementar

### 1. html_to_markdown

- **Dominio:** core
- **Lang:** Python
- **Purity:** pure
- **Signature:** `html_to_markdown(html: str) -> str`
- **Descripcion:** Convierte HTML a markdown. Usa readabilipy para extraer contenido principal (filtra nav, ads, boilerplate), luego markdownify para convertir a markdown.
- **Algoritmo:**
  1. Preprocesar HTML: manejar contenido oculto (ej: WeChat js_content), lazy loading images (data-src → src)
  2. Extraer contenido principal con readabilipy (basado en Mozilla Readability)
  3. Convertir a markdown con markdownify (headings ATX, strip script/style)
- **Deps:** `readabilipy`, `markdownify`, `beautifulsoup4`
- **Tests:** HTML con nav/footer (debe filtrarse), HTML limpio, HTML con imagenes lazy-loaded

### 2. detect_url_type

- **Dominio:** core
- **Lang:** Python
- **Purity:** impure (hace HTTP HEAD request)
- **Signature:** `detect_url_type(url: str, timeout: float = 10.0) -> tuple[str, dict]`
- **Descripcion:** Detecta el tipo de contenido de una URL. Retorna tipo ("webpage", "pdf", "markdown", "text", "code_repository") y metadata.
- **Algoritmo:**
  1. Verificar patrones de repos de codigo (github.com/org/repo, git@...)
  2. Verificar extension en URL (.pdf, .md, .txt, .html, .git)
  3. Si no se determino: HTTP HEAD request → leer Content-Type header
  4. Default: "webpage"
- **Deps:** `httpx`, `urllib.parse`
- **Error type:** Exception (timeout, network error)
- **Tests:** URL .pdf, URL github repo, URL webpage, URL con Content-Type custom

### 3. fetch_and_parse_url

- **Dominio:** core
- **Lang:** Python
- **Purity:** impure (I/O: HTTP request)
- **Signature:** `fetch_and_parse_url(url: str, timeout: float = 30.0) -> str`
- **Descripcion:** Descarga una pagina web y la convierte a markdown. Combina fetch HTML + html_to_markdown.
- **Algoritmo:**
  1. Detectar tipo de URL con detect_url_type
  2. Si webpage: fetch HTML con httpx, convertir a markdown
  3. Si download link: descargar a archivo temporal, delegar al parser apropiado
  4. Si code repository: delegar a parser de codigo
- **Deps:** `httpx`
- **Error type:** Exception

### 4. convert_github_to_raw_url

- **Dominio:** core
- **Lang:** Python
- **Purity:** pure
- **Signature:** `convert_github_to_raw_url(url: str) -> str`
- **Descripcion:** Convierte una URL de blob de GitHub/GitLab a su URL raw. Ej: `github.com/org/repo/blob/main/file.py` → `raw.githubusercontent.com/org/repo/main/file.py`
- **Algoritmo:**
  1. Parsear URL
  2. Si GitHub y path contiene `/blob/`: remover `/blob/` y cambiar dominio a raw.githubusercontent.com
  3. Si GitLab y path contiene `/blob/`: reemplazar por `/raw/`
  4. Si no aplica, retornar URL sin cambiar
- **Deps:** `urllib.parse`
- **Tests:** URL GitHub blob, URL GitLab blob, URL que no es blob, URL no-GitHub
