For developers
Reference
The full specification: command-line options, the transcript format, how the CSS is written, and what the tool does and doesn't handle. If you just want to make a page, the instructions are friendlier.
Online converter
The Online Converter is the browser-only route. The Tool page gives the Python reference. It accepts pasted marked transcripts, offers chat-style or Word-friendly HTML, and lets the user choose inline CSS or separate CSS. It does not change the Python processor behaviour.
Collector prompt
The Conversation Collector Prompt is an optional helper for creating a draft transcript. It is not part of the processor and does not change the accepted input format. The processor still expects marked turns using [USER] and [CHATBOT].
Command
python3 aichatprocess.py [options]
With no options it reads aichat.txt and writes
aichat.html (linking aichat.css) in the current
folder.
Options
| Option | Default | Purpose |
|---|---|---|
--source | aichat.txt, then aichat.md | Input transcript. See note below. |
--output | aichat.html | Output HTML file. |
--css | aichat.css | CSS file the HTML links to. |
--css-template | aichat-template.css | Optional template copied when writing CSS. |
--theme | default | Built-in look: default, dark, minimal, warm. |
--write-css | if-missing | never, if-missing, or overwrite. |
--word-output | — | Also write a Word-friendly transcript to this file. |
--word-style | default | Word look: default, compact, plain. Needs --word-output. |
--math | off | Render $…$ / $$…$$ with KaTeX (web page only, CDN). |
--title | AI Chat | The HTML page title. |
python3 aichatprocess.py --source mychat.txt --output mychat.html --write-css overwrite
Source resolution. If you pass --source,
the tool uses exactly that file. If you don't, it reads
aichat.txt, falling back to aichat.md when the
.txt is absent. If neither exists, it stops with an error
naming both. This lets you keep the transcript as aichat.md
and edit it in a Markdown editor with no extra flags.
Transcript format
Each turn begins with a line containing a role token — [USER]
or [CHATBOT] — matched case-insensitively. The rest of that
line is ignored, so # **[USER]**, [user] and
## [Chatbot]: all work. Everything until the next role line
is that turn's body, treated as Markdown. Text before the first role line
is ignored with a warning.
Conversion
Turn bodies are converted with
Python-Markdown using the
fenced_code, tables, sane_lists and
nl2br extensions.
- Fenced code blocks render as visible, escaped code — never interpreted as page markup. A transcript full of HTML examples stays safe.
- A code block's language tag is preserved as a CSS class, so a syntax highlighter can be added later; none is bundled.
- No maths/LaTeX handling — plain-text formulae stay as plain text.
- Markdown images with a web address (
) are passed through as<img>tags. Local or pasted images (, data URIs) are replaced with a small "[image not included]" placeholder — the tool never loads local files. - Attachments, native LLM export formats and automatic role detection are out of scope.
How the CSS is written
The --write-css setting controls this, and it is safe by
default.
| Mode | Behaviour |
|---|---|
never | Leave the CSS file untouched; only link to it. The template is ignored. |
if-missing | Write the CSS file only if it does not already exist (default). |
overwrite | Always re-write the CSS file. |
When writing — either overwrite, or if-missing
with no file present — the tool copies aichat-template.css
verbatim if that file exists, otherwise it writes a stylesheet built into
the script. So the tool works on a clean folder, and you can customise the
design by editing the template and re-running with
--write-css overwrite.
Choosing a look
Three things can decide the stylesheet, in this order of precedence: an
existing --css-template file wins; otherwise the
--theme you name is used; otherwise the built-in default.
The bundled themes are default, dark,
minimal and warm.
python3 aichatprocess.py --theme dark --write-css overwrite
See the styling page for live previews of each.
Word-friendly output
Pass --word-output to also write a second page designed for
pasting into Microsoft Word, alongside the normal chat page. Use the flag
on its own to name the file automatically from the output
(aichat.html becomes aichat-word.html), or give
an explicit filename:
python3 aichatprocess.py --word-output
python3 aichatprocess.py --word-output mychat-word.html
The matching stylesheet is named from the file with a .css
extension (so aichat-word.html links
aichat-word.css).
Word ignores the things that make the chat page look like a chat — flexbox layout, alignment, rounded bubbles, box-shadows — and handles linked stylesheets poorly. So this output is a different construction: a clean transcript (speaker label, then text) built only from constructs Word keeps, with the styling written inline on every element so it survives the copy-paste. A linked stylesheet is also included so the page looks tidy in the browser before you copy from it. Open the file, select the transcript, and paste into Word. No extra software is needed — the conversion is done by the tool itself, not by an external converter.
Three looks are available with --word-style:
default (coloured labels and separators), compact
(tighter spacing and smaller type, for fitting more on a page) and
plain (no rules or colour — most neutral, for reformatting
into another template).
Themes and Word looks are separate. --theme
styles the chat page; --word-style styles the Word page. They
don't overlap — the screen themes (with dark backgrounds and bubbles)
would not survive Word anyway, which is why the Word output has its own
neutral looks. If you set --theme alongside
--word-output, the tool prints a short note making this clear.
Maths (optional)
By default the tool doesn't typeset mathematics — reliably detecting
which text is a formula isn't possible, so a line like
9.8 m/s² should never be guessed at. Instead, maths is
opt-in: wrap it in $…$ (inline) or $$…$$
(display) and pass --math. The page then loads
KaTeX from a CDN and renders it in the
browser.
Two caveats: --math makes the page depend on that online
resource, which is why it's off by default (the page is otherwise fully
self-contained); and it applies to the chat web page only — the Word
version pastes static content and shows maths as plain $…$
text.
Scoping, not isolation
The generated CSS is scoped under .ai-chat-page so the
snippet can be pasted into pages that already have their own styles
without the two interfering. This is scoping, not guaranteed isolation:
full isolation would require an iframe or Shadow DOM, which would defeat
the goal of copying a plain HTML snippet.
Output structure
The output is a complete HTML page (not a fragment) linking the CSS file. The reusable chat section is wrapped in large repeated comment blocks so it's easy to find and copy:
<!-- ******************************************** -->
<!-- COPY CHAT HTML START -->
<!-- ******************************************** -->
<main class="ai-chat-page"> ... </main>
<!-- ******************************************** -->
<!-- COPY CHAT HTML END -->
<!-- ******************************************** -->
Project layout
ai-chat-to-html/
├── aichatprocess.py The processor
├── aichat-template.css Editable CSS template
├── requirements.txt Pins Python-Markdown
├── docs/ This website
│ ├── index.html instructions.html example.html
│ ├── styling.html reference.html
│ ├── site.css
│ ├── workflow.md requirements.md (plain-text source docs)
└── example/
├── aichat.txt aichat.html aichat.css
└── themes/ Alternate stylesheets + rendered demos
The online converter includes chat-style and Word-friendly output, inline or separate CSS, and a chat style choice for chat-style HTML.