Known limitations
Everything below is a real failure mode, reproduced deliberately. If you hit something that is not on this list, it is worth reporting.
Missed code (false negatives)
Single lines floating in prose
An isolated line is held to a higher standard than one inside a run, because it has
no neighbouring code to corroborate it. A bare import numpy as np in the
middle of a paragraph, with no monospaced font, does not clear it — and is left
as prose.
Why it is tuned this way: a false positive is worse than a false negative here. Turning one sentence of a paragraph into a black code pane is jarring and destroys the reading flow; missing a one-line snippet leaves the document exactly as it already was. The cost is asymmetric, so the tuning is too.
Workaround: select the line in the result and mark it as code — two clicks, and it carries through to every download. Setting it in a monospaced font in the source document also settles it.
Heavily wrapped code in narrow PDF columns
When a two-column PDF forces a long line of code to wrap, the continuation arrives as its own line and loses the shape that identified it. The first half is usually detected and the tail is sometimes dropped.
Code inside images
Screenshots of an editor are pictures. There is no text to read and no OCR is performed, so they pass through untouched.
Prose that is written about code
A sentence discussing code shares its vocabulary. "A class implements it:" and "Write a program using a static member function" are caught by the sentence-shape rules, but a terse fragment that is neither clearly grammar nor clearly syntax — something like "static member function" on a line of its own next to a listing — can still be absorbed. There is no clean boundary here, only a better and worse guess.
Documents typeset entirely in a monospaced font
When everything is Courier, the strongest evidence available carries no information at all — it no longer distinguishes anything — so detection falls back to what it would do on plain text. That is the right behaviour, but it means a fully monospaced document detects less reliably than a mixed one — the opposite of what you might expect.
Terminal blocks are recognised by their caption, not their content
A transcript is only labelled Terminal if something above it says
Output:, Result:, Terminal: or similar, or the
shape of the transcript itself gives it away. Output with no caption, introduced by
unusual wording and not obviously a transcript, is read as ordinary text —
usually landing as prose, occasionally as an Unknown code block. Selecting it and
marking it as terminal fixes it in place.
Languages outside the supported set
Go, Rust, C#, Kotlin, Swift, SQL and shell are detected as code often enough, but are labelled Unknown and highlighted with a shared grammar rather than their own rules. Language-specific constructs will not be coloured correctly.
Wrongly detected text (false positives)
Dense tabular data in a monospaced font
A financial table or fixed-width data dump set in Courier starts out looking a lot like a listing. It usually escapes, because it has no keywords or brackets — but a table containing symbols, equals signs and abbreviations can cross the line. This is the most likely false positive in practice, and text inside a real table is protected from it explicitly.
Structured configuration and markup
YAML, INI, JSON and XML fragments are code in the ordinary sense, and the detector will often pick them up. They are then labelled Unknown, because none of the named languages matches. Whether that counts as an error depends on what you wanted.
Mathematical notation
Equations with heavy parenthesisation, subscripts rendered as brackets and few English words can look a great deal like code. Displayed equations are usually recognised as equations and typeset as such, but a block of LaTeX-ish inline maths in the middle of a paragraph remains a plausible false positive. Marking it as an equation both fixes the colour and typesets it properly.
Format-specific problems
Scanned PDFs produce nothing at all
If the PDF is an image of a page, there is no text layer. The tool will report that it found no readable text. Test by trying to select text in your PDF reader: if you cannot select it, this cannot read it.
PDF indentation is reconstructed, not read
PDFs do not store indentation — they store glyph positions. Leading whitespace is rebuilt by measuring the gap from the left margin and dividing by the median character width. This is accurate for monospaced code, and approximate when a listing was set in a proportional font. Occasionally an indent level is off by one space.
PDF line order follows layout, not reading order
Lines are grouped by vertical position and sorted top to bottom. In a multi-column layout this can interleave columns, and a code block spanning a column break may come back in the wrong order. Single-column documents are unaffected. More on the differences between the two formats.
Legacy .doc files are not supported
The old binary Word format is a different thing entirely from .docx. Open it in Word and save as .docx.
Word tables and text boxes
Text inside table cells is read and can be detected. Content in text boxes, headers, footers and footnotes is not read at all, because it lives outside the main document body.
Tokeniser edge cases
Regular-expression literals in JavaScript
/pattern/g is not recognised as a literal, because distinguishing it
from division requires tracking parser state that a token-level lexer does not
keep. The slashes are coloured as operators. Rare in documents; wrong when it happens.
Interpolation inside template literals
A JavaScript template literal is coloured as one string, including any
${expression} inside it. VS Code colours the expression separately.
Capitalised identifiers are assumed to be types
Any capitalised identifier gets the type colour. This matches Dark+ most of the time and is wrong for capitalised constants and for variables that happen to start with a capital.
Very long single-line files
Minified code on one line will be tokenised correctly but rendered as a single enormous line with horizontal scrolling. There is no line wrapping inside code panes.
Things that are out of scope on purpose
- Inline code inside a sentence is not lifted out into a block. Detecting it is a different problem with different trade-offs.
- No OCR. That is a substantially larger piece of machinery than the whole of the rest of this tool.
- PDF export hides the old code text rather than removing it. The panel is painted over the original, which stays in the file's text layer underneath. The .docx path genuinely replaces it. Why the two differ.
- Embedding your chosen code font into a PDF needs Chrome or Edge. A PDF has to carry the font file inside it, and the only way a web page can read a real installed font is the Local Font Access API, which Firefox and Safari do not implement and which asks your permission the first time. Where it is not available the PDF falls back to Courier — the one monospaced face every reader has — and the tool says so rather than substituting silently.
- The optional AI review can be wrong too. Gemini sees the text but not the fonts, spacing or layout the rules use, so it sometimes overturns a correct verdict. Its changes are badged AI in the result; select anything it got wrong and unmark it. Its reply is also capped — a response trying to flip most of the document is thrown away rather than applied.
- The AI review needs the network and a working API quota. If the call fails, times out, or the free-tier quota is exhausted, it says so and leaves the rule-based result untouched. You can press it again.
Reporting something
The most useful report is the smallest document that reproduces the problem, plus what you expected. The detection rules are all written down, so it is usually possible to say exactly which signal fired or failed to. Contact details are here.