Salta ai contenuti

Convertire qualsiasi formato in Markdown

La conversione di documenti eterogenei — PDF, presentazioni PowerPoint, fogli di calcolo Excel, immagini, file audio — in Markdown rappresenta un’operazione sempre più rilevante nell’ambito dell’analisi testuale, della preparazione di dati per modelli di intelligenza artificiale e della documentazione tecnica. MarkItDown è uno strumento open source sviluppato da Microsoft che risponde a questa esigenza, offrendo un’unica utility in grado di convertire decine di formati in Markdown mantenendo la struttura originale del documento: titoli, elenchi, tabelle, collegamenti e formattazione vengono preservati nella misura del possibile.

A differenza di strumenti come textract, MarkItDown si concentra sulla produzione di Markdown pulito e semanticamente corretto, ideale per essere consumato da Large Language Model (LLM), pipeline di text analysis e sistemi RAG (Retrieval-Augmented Generation). La presente guida illustra l’installazione, la configurazione dei plugin, l’utilizzo da riga di comando e tramite API Python, nonché i casi d’uso più comuni con esempi concreti.


MarkItDown (github.com/microsoft/markitdown) è un’utility Python sviluppata da Microsoft. L’installazione può avvenire in due modalità, a seconda dell’uso previsto:

  • pipx — consigliato per l’uso come strumento CLI globale: isola il pacchetto in un ambiente virtuale dedicato rendendolo accessibile da qualunque terminale, senza conflitti con altri progetti Python.
  • venv locale — consigliato quando si usa MarkItDown come libreria Python all’interno di un progetto specifico, ad esempio per integrarlo in pipeline di elaborazione dati.
  • Python 3.10 o superiore.

Se pipx non è presente nel sistema:

Finestra del terminale
pip install pipx
python -m pipx ensurepath

Il comando python -m pipx ensurepath aggiunge automaticamente la directory dei pacchetti pipx al PATH utente di Windows. Su Windows, pipx installa gli eseguibili dei pacchetti in %USERPROFILE%\.local\bin (ad esempio C:\Users\utente\.local\bin\markitdown.exe), mentre pipx stesso viene installato da pip in %APPDATA%\Python\Scripts. Entrambe queste directory devono trovarsi nel PATH affinché il comando markitdown sia raggiungibile da qualunque terminale.

Dopo l’esecuzione del comando, chiudere e riaprire completamente il terminale (non basta aprire una nuova scheda) affinché le modifiche al PATH abbiano effetto.

Verifica rapida della disponibilità del comando:

Finestra del terminale
where markitdown

Output atteso:

C:\Users\utente\.local\bin\markitdown.exe

Se il comando non viene trovato, aggiungere manualmente la directory al PATH utente tramite PowerShell:

Finestra del terminale
$binPath = "$env:USERPROFILE\.local\bin"
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
$parts = if ([string]::IsNullOrWhiteSpace($userPath)) { @() } else { $userPath -split ';' }
if (-not ($parts -contains $binPath)) {
$parts += $binPath
[Environment]::SetEnvironmentVariable('Path', (($parts | Select-Object -Unique) -join ';'), 'User')
Write-Host "Aggiunto $binPath al PATH utente. Riavviare il terminale."
}

Installare MarkItDown con il supporto a tutti i formati disponibili:

Finestra del terminale
pipx install "markitdown[all]"

L’opzione [all] installa tutte le dipendenze opzionali necessarie per i diversi formati. In alternativa, è possibile installare solo i formati specifici richiesti:

Finestra del terminale
pipx install "markitdown[pdf,docx,pptx]"

Installazione in un venv locale (uso come libreria)

Sezione intitolata “Installazione in un venv locale (uso come libreria)”

Per progetti che utilizzano MarkItDown come libreria Python — ad esempio all’interno di script di automazione o pipeline di elaborazione documenti — è preferibile installarlo in un ambiente virtuale dedicato al progetto:

Finestra del terminale
# Creare e attivare il venv
python -m venv .venv
.\.venv\Scripts\Activate
# Installare con tutte le dipendenze
pip install "markitdown[all]"
# Oppure solo le dipendenze necessarie
pip install "markitdown[pdf,docx]"

A questo punto MarkItDown è importabile come libreria nel codice Python del progetto:

from markitdown import MarkItDown

Le dipendenze opzionali sono le stesse per entrambe le modalità di installazione:

DipendenzaFormati supportati
[pdf]Documenti PDF
[docx]Documenti Word
[pptx]Presentazioni PowerPoint
[xlsx]Fogli di calcolo Excel moderni
[xls]Fogli di calcolo Excel legacy
[outlook]Messaggi Outlook (.msg)
[audio-transcription]File audio (MP3, WAV, MP4)
[youtube-transcription]Trascrizioni YouTube
[all]Tutti i formati sopra elencati
Finestra del terminale
markitdown --version

Per la conversione di file audio è necessario ffmpeg:

Finestra del terminale
winget install --id=Gyan.FFmpeg -e --accept-package-agreements

MarkItDown offre un’interfaccia a riga di comando minimale e intuitiva. La sintassi base prevede la specifica del file di input e, opzionalmente, del file di output.

Finestra del terminale
markitdown <file-input> -o <file-output>
  • PDF → Markdown:

    Finestra del terminale
    markitdown documento.pdf -o documento.md
  • Word → Markdown:

    Finestra del terminale
    markitdown relazione.docx -o relazione.md
  • PowerPoint → Markdown:

    Finestra del terminale
    markitdown presentazione.pptx -o presentazione.md
  • Excel → Markdown:

    Finestra del terminale
    markitdown dati.xlsx -o dati.md
  • Immagine → Markdown:

    [!NOTE] Per le immagini singole (JPG, PNG, ecc.) non serve il plugin OCR: MarkItDown dispone di un convertitore immagini integrato che invia l’immagine a un LLM vision per ottenerne una descrizione testuale. Tuttavia la CLI non permette di specificare il modello LLM: serve quindi uno script Python o il file convert.py descritto nella sezione Script personalizzati.

    Finestra del terminale
    # Con script Python (serve llm_client + llm_model)
    python convert.py foto.png -o descrizione.md
  • File audio → Markdown (trascrizione):

    Finestra del terminale
    markitdown registrazione.mp3 -o trascrizione.md
  • URL YouTube → Markdown:

    Finestra del terminale
    markitdown https://www.youtube.com/watch?v=VIDEO_ID -o video.md

[!CAUTION] Encoding dei caratteri su Windows: non utilizzare il redirect della shell (>) per salvare l’output, poiché il terminale Windows sostituisce i caratteri non-ASCII (accenti, apostrofi) con il simbolo “. Utilizzare sempre l’opzione -o per scrivere direttamente su file con encoding UTF-8.

OpzioneDescrizione
-o, --outputFile di output
-c, --charsetSuggerimento sul charset del file di input (es. UTF-8)
-p, --use-pluginsAbilita i plugin di terze parti
--list-pluginsElenca i plugin installati
--keep-data-urisMantiene i data URI (es. immagini base64) nell’output
-d, --use-docintelUsa Azure Document Intelligence per l’estrazione

MarkItDown può essere utilizzato come libreria Python, offrendo un controllo più granulare rispetto alla CLI. L’API è particolarmente indicata per l’integrazione in pipeline automatizzate e script personalizzati.

from markitdown import MarkItDown
md = MarkItDown()
result = md.convert("documento.pdf")
print(result.text_content)

Per convertire immagini o per estrarre testo da immagini embedded in PDF e documenti Office, è necessario fornire un client LLM compatibile con l’API OpenAI:

from markitdown import MarkItDown
from openai import OpenAI
md = MarkItDown(
llm_client=OpenAI(
api_key="chiave-api",
base_url="https://endpoint-compatibile/v1",
),
llm_model="nome-modello",
)
result = md.convert("immagine.png")
print(result.text_content)
from markitdown import MarkItDown
from openai import OpenAI
md = MarkItDown(
enable_plugins=True,
llm_client=OpenAI(),
llm_model="gpt-4o",
)
result = md.convert("documento-con-immagini.pdf")
print(result.text_content)

MarkItDown supporta nativamente una vasta gamma di formati. La tabella seguente elenca i principali, indicando le dipendenze richieste, la necessità di un client LLM e l’eventuale necessità del plugin OCR.

FormatoEstensioniDipendenzaLLM richiestoPlugin OCR
PDF.pdf[pdf]NoSolo per OCR immagini embedded o PDF scansionati
Word.docx[docx]NoSolo per OCR immagini embedded
PowerPoint.pptx[pptx]NoSolo per OCR immagini embedded
Excel.xlsx, .xls[xlsx] / [xls]NoSolo per OCR immagini embedded
Immagini.jpg, .png, .gif, .webpNo — convertitore integrato
Audio.mp3, .wav, .m4a, .mp4[audio-transcription]NoNo
HTML.html, .htmNoNo
CSV.csvNoNo
JSON.jsonNoNo
XML.xmlNoNo
EPub.epubNoNo
Archivi ZIP.zipNoNo
Messaggi Outlook.msg[outlook]NoNo
YouTubeURL[youtube-transcription]NoNo

[!NOTE] Differenza chiave tra immagini singole e immagini embedded:

  • Immagini singole (JPG, PNG, ecc.): MarkItDown ha un convertitore immagini integrato che invia il file a un LLM vision. Non serve alcun plugin, ma serve un llm_client configurato.
  • Immagini embedded dentro PDF/DOCX/PPTX/XLSX: per estrarre testo da queste immagini serve il plugin OCR (markitdown-ocr), anch’esso basato su LLM vision.
  • PDF scansionati (solo immagini, senza testo estraibile): richiedono il plugin OCR.

MarkItDown supporta plugin di terze parti che estendono le funzionalità dei convertitori integrati. Il plugin più rilevante è markitdown-ocr.

È fondamentale distinguere due meccanismi diversi:

MeccanismoCosa faQuando si attivaServe plugin?
Convertitore immagini integratoInvia un’immagine singola a un LLM vision e restituisce una descrizione testualeFile .jpg, .png, .gif, .webpNo — basta un llm_client
Plugin OCR (markitdown-ocr)Estrae testo da immagini embedded dentro PDF, DOCX, PPTX e XLSX, o da PDF interamente scansionatiPDF/DOCX/PPTX/XLSX che contengono immagini con testo al loro interno

In sintesi:

  • Vuoi convertire una foto o uno screenshot in testo? → Serve solo un llm_client, non serve il plugin.
  • Vuoi estrarre testo da immagini dentro un PDF o un DOCX? → Serve il plugin OCR + un llm_client.
  • Il PDF contiene testo selezionabile? → Non serve né il plugin né un LLM.

Il plugin va installato all’interno dell’ambiente virtuale pipx di MarkItDown:

Finestra del terminale
pipx inject markitdown markitdown-ocr openai
Finestra del terminale
markitdown --list-plugins

Output atteso:

Finestra del terminale
Installed MarkItDown 3rd-party Plugins:
* ocr (package: markitdown_ocr)
Use the -p (or --use-plugins) option to enable 3rd-party plugins.

Quando il plugin è attivo e un client LLM è configurato:

  1. MarkItDown estrae le immagini embedded dal documento.
  2. Ciascuna immagine viene inviata al modello vision con un prompt di estrazione.
  3. Il testo restituito dal modello viene inserito inline nel documento Markdown, preservando il flusso strutturale.
  4. Se la chiamata LLM fallisce, la conversione prosegue senza il testo dell’immagine interessata.

Per i PDF scansionati (privi di testo estraibile), il plugin rileva automaticamente la situazione e invia l’intera pagina come immagine al modello.

Finestra del terminale
markitdown -p documento.pdf -o output.md
from markitdown import MarkItDown
from openai import OpenAI
md = MarkItDown(
enable_plugins=True,
llm_client=OpenAI(
api_key="chiave-api",
base_url="https://endpoint-compatibile/v1",
),
llm_model="nome-modello-vision",
)
result = md.convert("documento_con_immagini.pdf")
print(result.text_content)

Il plugin utilizza il pattern llm_client / llm_model basato sull’API OpenAI. Qualunque provider che offra un endpoint compatibile può essere utilizzato:

  • OpenAI: https://api.openai.com/v1
  • Azure OpenAI: endpoint personalizzato Azure
  • Provider alternativi: qualunque endpoint che implementi il protocollo chat.completions.create() di OpenAI

La libreria openai legge automaticamente le seguenti variabili d’ambiente, eliminando la necessità di specificarle nel codice:

Finestra del terminale
$env:OPENAI_API_KEY = "chiave-api"
$env:OPENAI_BASE_URL = "https://endpoint-compatibile/v1"

Quando l’utilizzo da riga di comando non è sufficiente — ad esempio per integrare il client LLM o per automatizzare conversioni di massa — è possibile creare script Python dedicati.

Il seguente script accetta un file di input e un opzionale file di output, leggendo il modello dalla variabile d’ambiente Z_AI_MODEL:

from markitdown import MarkItDown
from openai import OpenAI
import sys
import os
input_file = sys.argv[1]
output_file = None
model = os.environ.get("Z_AI_MODEL", "gpt-4o")
args = sys.argv[2:]
for i, arg in enumerate(args):
if arg == "-o" and i + 1 < len(args):
output_file = args[i + 1]
break
md = MarkItDown(
enable_plugins=True,
llm_client=OpenAI(),
llm_model=model,
)
result = md.convert(input_file)
if output_file:
with open(output_file, "w", encoding="utf-8") as f:
f.write(result.text_content)
print(f"Salvato in {output_file}")
else:
print(result.text_content)

Per semplificare l’uso su Windows, si può creare un file .bat che imposta le variabili d’ambiente e invoca lo script Python con l’interprete corretto:

Finestra del terminale
@echo off
set OPENAI_API_KEY=la-tua-chiave
set OPENAI_BASE_URL=https://endpoint-compatibile/v1
set Z_AI_MODEL=nome-modello
C:\Users\utente\pipx\venvs\markitdown\Scripts\python.exe convert.py %*

Utilizzo:

Finestra del terminale
.\convert.bat documento.pdf -o output.md

Per convertire tutti i file di una cartella:

from markitdown import MarkItDown
from pathlib import Path
md = MarkItDown()
cartella = Path("./documenti")
output = Path("./output")
output.mkdir(exist_ok=True)
for file in cartella.iterdir():
if file.suffix in [".pdf", ".docx", ".pptx", ".xlsx"]:
try:
result = md.convert(str(file))
out_file = output / f"{file.stem}.md"
out_file.write_text(result.text_content, encoding="utf-8")
print(f"Convertito: {file.name} -> {out_file.name}")
except Exception as e:
print(f"Errore con {file.name}: {e}")

Nel corso dell’utilizzo di MarkItDown possono verificarsi diverse problematiche. La tabella seguente riassume le più comuni con le relative soluzioni.

ProblemaCausa comuneSoluzione
Caratteri nel file di outputUtilizzo del redirect > su WindowsUsare sempre -o file.md invece del redirect
Warning ffmpeg not foundffmpeg non installato o non nel PATHInstallare con winget install Gyan.FFmpeg
command not found: markitdownPATH non aggiornato dopo installazione pipxChiudere e riaprire il terminale
Plugin OCR non caricaPlugin non installato nel venv pipxpipx inject markitdown markitdown-ocr
OCR non estrae testollm_client o llm_model mancantiPassare entrambi i parametri al costruttore
Errore 404 dalle APIEndpoint o chiave API erratiVerificare OPENAI_API_KEY e OPENAI_BASE_URL
Librerie non trovate negli scriptPython globale invece del venv pipxUsare C:\Users\utente\pipx\venvs\markitdown\Scripts\python.exe
PDF con testo vuotoPDF scansionato (solo immagini)Abilitare il plugin OCR (-p) con un LLM vision
Tabelle mal formattateLayout complesso nel PDF originaleIl formato Markdown non supporta merge di celle

ScenarioComandoPlugin OCRLLM
PDF con testo → MDmarkitdown file.pdf -o out.mdNoNo
PDF con immagini embedded → MDmarkitdown -p file.pdf -o out.md
PDF scansionato → MDmarkitdown -p file.pdf -o out.md
Word → MDmarkitdown file.docx -o out.mdNoNo
Word con immagini → MDmarkitdown -p file.docx -o out.md
PowerPoint → MDmarkitdown file.pptx -o out.mdNoNo
Excel → MDmarkitdown file.xlsx -o out.mdNoNo
Immagine singola → MDpython convert.py foto.png -o out.mdNo
Audio → MDmarkitdown file.mp3 -o out.mdNoNo
YouTube → MDmarkitdown URL -o out.mdNoNo
HTML → MDmarkitdown file.html -o out.mdNoNo
Archivio ZIP → MDmarkitdown file.zip -o out.mdNoNo