# Chat Transcript Formatter

Clean a messy chat log into one consistently-formatted transcript with normalized speakers, timestamps, and WhatsApp/IRC/plain line parsing.

## Run it

- **CLI:** `gizza tool chat-transcript-formatter "[2023-01-05, 10:04] Alice: hey, running late
10:05 Bob: no worries
<Carol> see you soon"`
- **Web:** https://gizza.ai/tools/chat-transcript-formatter/
- **Agents:** machine-readable descriptor (parameters JSON Schema) at https://gizza.ai/tools/chat-transcript-formatter/tool.json

## Inputs

- `input` — Chat log _(field)_
- `output_format` — Speaker style _(field)_
- `time_format` — Timestamps _(field)_
- `include_dates` — Keep dates _(field)_
- `merge_consecutive` — Merge consecutive turns _(field)_
- `blank_line_between` — Blank line between turns _(field)_

## Output

- Formatted transcript (text)

## Query parameters

Open the tool pre-filled and auto-run via URL:

- `input` — Chat log
- `output_format` — Speaker style
- `time_format` — Timestamps
- `include_dates` — Keep dates
- `merge_consecutive` — Merge consecutive turns
- `blank_line_between` — Blank line between turns

Example: `https://gizza.ai/tools/chat-transcript-formatter/?input=%5B2023-01-05%2C%2010%3A04%5D%20Alice%3A%20hey%2C%20running%20late%0A10%3A05%20Bob%3A%20no%20worries%0A%3CCarol%3E%20see%20you%20soon&output_format=plain&time_format=keep&include_dates=true&merge_consecutive=true&blank_line_between=true`

---

## About this tool

Chat logs come in a dozen inconsistent shapes: a WhatsApp `.txt` export uses
`[2023-01-05, 10:04] Alice: message` or `05/01/2023, 10:04 AM - Alice: message`,
an IRC or Discord copy-paste uses `<Alice> message` or `[10:04] <Alice> message`,
and a hand-typed log is often just `Alice: message`. This formatter parses all of
those line shapes and re-emits them as **one** consistently-formatted transcript,
so a mixed-source paste comes out uniform.

You control three things independently. **Speaker style** picks how each name is
rendered — plain `Name:`, Markdown-bold `**Name:**`, IRC-style `<Name>`, or an
uppercased screenplay `NAME:`. **Timestamps** can be kept verbatim, normalized to
24-hour or 12-hour clocks, or dropped entirely. And two toggles tidy the layout:
merge consecutive turns from the same speaker into one block, and add a blank line
between turns for a paragraph-style read. Dates from WhatsApp exports are dropped
by default; turn on **Keep dates** to retain them.

Everything runs locally in your browser — the transcript is parsed by a small
WebAssembly module with fixed rules, so nothing is uploaded and there is no AI
guesswork. Lines that don't match any recognized speaker or timestamp shape are
folded into the previous message as continuations, which is how wrapped or
soft-broken lines get stitched back together.

## FAQ

<!-- FAQ MUST be <details>/<summary> accordions -->

<details>
<summary>Which chat formats does it understand?</summary>

WhatsApp exports in both the bracket form (`[2023-01-05, 10:04] Name: msg`) and
the dash form (`05/01/2023, 10:04 AM - Name: msg`), bracketed or parenthesized
timestamps (`[10:04] Name:` and `(10:04 AM) <Name>`), a bare leading time
(`10:04 Name: msg`), IRC/Discord angle form (`<Name> msg`), and plain `Name: msg`
lines. You can paste a mix of these and they all normalize to the same output.

</details>

<details>
<summary>What happens to a line with no speaker or timestamp?</summary>

It is treated as a continuation and folded into the previous message. This is what
makes wrapped lines — a long message that got soft-broken across two lines, or a
pasted paragraph — reassemble into a single turn instead of becoming orphaned
lines.

</details>

<details>
<summary>Why is a plain `Word: text` line read as a speaker?</summary>

Because the tool is deterministic — it has no way to know whether `Word:` is a
name or just a sentence with a colon, so in a chat-log context it always treats a
leading `Word:` (followed by a space) as a speaker label. A bare URL like
`http://example.com` is safe: the colon there isn't followed by a space, so it's
never mistaken for a speaker.

</details>

<details>
<summary>Does anything get sent to a server?</summary>

No. The transcript is parsed entirely in your browser by a WebAssembly module.
Nothing is uploaded, and there's no LLM or network call — the same input always
produces the same output.

</details>

## Related tools

- [Transcript Cleaner](https://gizza.ai/tools/transcript-clean/): Paste a raw transcript or captions and clean it into readable prose: strip timestamps, remove filler words, merge speaker turns, and fix punctuation locally.
- [Context Trimmer](https://gizza.ai/tools/context-trimmer/): Trim text to an approximate token budget for LLM prompts, keeping the head, tail, middle, or both ends. Runs locally in your browser.
- [Compare Two Lists](https://gizza.ai/tools/list-set-diff/): Compare two lists as sets and see which items are only in A, only in B, or shared — with counts. Ignore case, trim, dedupe, and leading zeros. Runs in your browser.
- [Colorize Text with Regex Rules](https://gizza.ai/tools/text-colorizer/): Highlight log or command output with user-defined regex color rules, then export ANSI terminal escapes or self-contained HTML.
- [Text Diff](https://gizza.ai/tools/text-diff/): Compare two text blocks and highlight added, removed, and changed lines.
