WebVTT to Markdown converter with MarkItDown plugin integration.
Project description
webvtt-to-markdown
WebVTT to Markdown converter with a MarkItDown plugin entry point.
Findable as a MarkItDown plugin via #markitdown-plugin.
Scope
- Supports
.vtttranscript input only - Prioritizes Microsoft Teams-style WebVTT cues
- Falls back to a generic WebVTT generation source when no more specific source is detected
- Works as a MarkItDown plugin via the
markitdown.pluginentry point
Installation
pip install webvtt-to-markdown
Usage
Standalone Python usage:
from webvtt_to_markdown import transcript_to_markdown
markdown = transcript_to_markdown(vtt_text)
List installed plugins:
markitdown --list-plugins
Convert a Teams transcript with plugins enabled:
markitdown -p input.vtt
Write the output to a file:
markitdown -p input.vtt -o output.md
Current behavior
ms_teams_scheduled- recognizes Teams-style identifiers like
.../xxx-y - groups transcript fragments by
xxx - uses the
y=0cue as the block header when available
- recognizes Teams-style identifiers like
ms_teams_event- handles Teams-style identifiers without
<v ...>speaker tags
- handles Teams-style identifiers without
zoom_scheduled- expects numeric identifiers starting at
1 - expects single-line cues with textual speaker prefixes
- supports optional whitespace around
: - uses a document-wide first-colon or last-colon split depending on the cue sample
- expects numeric identifiers starting at
zoom_event- handles numeric single-line cues without speaker prefixes
- may also match a single numeric cue
meeting_novoicetag- handles meeting-style textual speaker prefixes without
<v ...>tags - requires speaker marking to be consistent; partially marked files fall back to
generic_webvtt
- handles meeting-style textual speaker prefixes without
generic_webvtt- preserves cue order
- uses
<v ...>speaker tags when present - also handles cues without identifiers
- renders
NOTEblocks as Markdown blockquotes - ignores
STYLEblocks
After generation-source rendering, a separate postprocessing step:
- stitches consecutive blocks from the same recognized speaker
- prevents stitching across list-like blocks and
NOTEblocks - applies text reflow for meeting-like generation sources
- leaves
generic_webvttintentionally conservative
Generation sources are loaded softly from gen_src_* modules inside the package. Detection scores all registered generation sources on a sampled prefix of the parsed document, then picks the highest confidence; ties are broken by the module importance.
Supported WebVTT text tags
<b>...</b>becomes**...**<i>...</i>becomes*...*<u>...</u>becomes_..._<c.class>...</c>keeps only the inner text<lang xx[-YY]>...</lang>keeps only the inner text<ruby>...</ruby>becomes( ... )style inline ruby text with spacing normalized around it- inline WebVTT timestamp tags like
<00:00:04.000>are removed - malformed inline tags are left visible instead of being guessed or silently repaired
Voice tags such as <v Speaker>...</v> and <v.team Speaker>...</v> are used to extract speaker names for headings.
Empty textual speaker lines such as Speaker: are ignored and not written to Markdown.
Encoding
- Input files may be provided with or without BOM.
- The plugin tries to detect the input charset when no charset hint is provided.
- The standard MarkItDown CLI writes output as UTF-8.
- For this plugin, the repository Golden outputs are stored as UTF-8 with BOM.
Strict vs lazy decoding
- Default behavior is strict: undecodable input raises an error.
- The plugin also supports a Python-API-only lazy mode via
charset_lazy=True. - In lazy mode, undecodable characters are replaced with
[ENC?].
Example with the Python API:
from markitdown import MarkItDown
converter = MarkItDown(enable_plugins=True)
result = converter.convert("input.vtt", charset_lazy=True)
print(result.markdown)
You can also force a specific generation source through the Python API:
from markitdown import MarkItDown
converter = MarkItDown(enable_plugins=True)
result = converter.convert("input.vtt", generation_source="generic_webvtt")
print(result.markdown)
Development
Project-specific process notes:
Install the project and development tools into the active environment:
pip install -e .[dev]
Run tests:
pytest
Current test status:
92 passed
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file webvtt_to_markdown-0.9.0.tar.gz.
File metadata
- Download URL: webvtt_to_markdown-0.9.0.tar.gz
- Upload date:
- Size: 23.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
910cf763b1b787db278d1bd95eadc1e12aba3d124a2d2b6f8684749cf557f9e5
|
|
| MD5 |
53ef552e71262cdb62e3408ddc337072
|
|
| BLAKE2b-256 |
d475c7ae144ee5f4abd2f05ea8cd25174a61d0787548018db72233ae8868ce38
|
File details
Details for the file webvtt_to_markdown-0.9.0-py3-none-any.whl.
File metadata
- Download URL: webvtt_to_markdown-0.9.0-py3-none-any.whl
- Upload date:
- Size: 21.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21f5ec5ed25d4685375340c4261d06d66c9aadf066bbec66f782463162af750e
|
|
| MD5 |
ae1c059eea370075c1069cdfa58814ac
|
|
| BLAKE2b-256 |
7415009804cc20394089a5904e2c6dbf0c7a651e776eb31853ae3265d77412bc
|