How to better syntax highlighting in long markdown
- Step 1Load the README — Paste the README body, or upload the single
.mdfile. One document per run. - Step 2Run the tagger — Click Run. No options — the heuristic pass is identical each time, which keeps PR diffs predictable.
- Step 3Untagged fences are detected — Each bare backtick fence is scanned by first line. Tilde fences and indented blocks are left alone.
- Step 4GitHub hints are inserted — Matching blocks gain a lowercase identifier; unmatched and already-tagged blocks are untouched.
- Step 5Preview the result — Paste into a GitHub PR preview or local Markdown preview to confirm the highlighting looks right.
- Step 6Commit to the repo — Download or copy the tagged README and open a PR. Re-running before release stays a no-op on tagged blocks.
README block types and outcomes
How a README's typical fence content fares. Recognised languages get GitHub hints; the rest stay bare.
| README block | Tagged as | Notes |
|---|---|---|
Quickstart shell (npm install ...) | Left bare | Bash/shell is not in the detection set |
Python usage (import yourlib) | python | Matches the import pattern |
Node usage (const x = require(...)) | javascript | const matches; TS examples also become javascript |
package.json snippet | json | Leading { matches the JSON rule |
HTML embed example (<div ...>) | html | Leading <div matches |
| Output / log dump | Left bare | Plain text matches nothing — tag ``` text ``` by hand |
GitHub-canonical identifiers it writes
Every hint the tool can insert is already the lowercase form GitHub's highlighter recognises.
| Language | Identifier inserted | GitHub renders |
|---|---|---|
| Python | python | Highlighted |
| JavaScript / TypeScript | javascript | Highlighted (TS shown as JS) |
| Rust | rust | Highlighted |
| Go | go | Highlighted |
| PHP | php | Highlighted |
| SQL | sql | Highlighted |
| HTML | html | Highlighted |
| JSON | json | Highlighted |
| C++ | cpp | Highlighted |
Cookbook
README-style diffs. Inputs are bare fences from real project READMEs; outputs are the exact tagged result.
Python quickstart gains highlighting
The usage block opens with import, so it is tagged python and GitHub colours it on the repo page.
Input: ``` import yourlib yourlib.run(config='prod') ``` Output: ```python import yourlib yourlib.run(config='prod') ```
Node example tagged javascript
const triggers the JavaScript pattern. A TypeScript example opening the same way is also tagged javascript.
Input:
```
const lib = require('yourlib');
lib.run({ env: 'prod' });
```
Output:
```javascript
const lib = require('yourlib');
lib.run({ env: 'prod' });
```Shell quickstart stays bare
Install commands are shell, which is not detected. The block is left untagged — add ``` bash ``` by hand for shell highlighting.
Input: ``` npm install yourlib npm run build ``` Output: ``` npm install yourlib npm run build ```
package.json snippet tagged json
The block starts with {, matching the JSON rule, so the config example gets coloured.
Input:
```
{
"scripts": { "build": "tsc" }
}
```
Output:
```json
{
"scripts": { "build": "tsc" }
}
```Contributor's hint preserved
A block a contributor tagged ``` toml ``` is left exactly as written, so the tool never overrides a deliberate choice in a shared README.
Input: ```toml [package] name = "yourlib" ``` Output: ```toml [package] name = "yourlib" ```
Edge cases and what actually happens
Shell / Bash quickstart
Left bareInstall and run commands are the most common README code, but shell is not in the nine-language set, so they stay untagged. Add ``` bash or sh ``` manually for those blocks.
TypeScript example tagged javascript
By designThere is no typescript target. A TS usage block matches the JavaScript pattern and is tagged javascript. Switch it to typescript by hand if your README theme distinguishes them.
Contributor already tagged a block
PreservedExisting hints are never edited. A deliberate ``` text or diff ``` from a PR stays intact through the pass.
Output / log block
Left bareConsole output and logs match no pattern and are left untagged. Tag them ``` text or console ``` yourself if you want monospace-only styling.
Go example tagged javascript
By designJavaScript is checked before Go and shares const /var . A Go block opening with const ( becomes javascript. Lead with package or func for a correct go tag.
Tilde or indented blocks
Not detectedOnly backtick fences are scanned. Tilde (~~~) fences and four-space-indented code are skipped — convert or fence them first.
Re-run before a release
ExpectedBecause tagged blocks are preserved, re-running before each release only touches newly added bare fences. There is no churn on existing tags.
Brace-first block
By designA block starting with { or [ is tagged json. A non-JSON config example that opens with a brace can be mislabelled — review brace-first blocks.
README over the size limit
Rejected over limitFree tier caps input at 500,000 characters / 1 MB per file. Very large monorepo READMEs beyond that are rejected; use a higher tier (Pro: 5,000,000 / 10 MB) or split the doc with md-splitter.
Frequently asked questions
Will it match GitHub's preferred identifiers?
Yes. It emits lowercase canonical forms like python and javascript (never py), which is exactly what GitHub's highlighter expects.
Does it affect my repo's language statistics?
No. GitHub computes repo language from file extensions, not fence hints. Tagging only changes how code blocks render in Markdown.
Why isn't my shell quickstart highlighted?
Shell/Bash is not in the detection set. Add ``` bash or sh ``` to those blocks manually after running.
What about diff blocks?
There is no diff detection. Tag them ``` diff ``` yourself; the tool will then leave them alone on future runs.
Which languages does it auto-tag?
Python, JavaScript, Rust, Go, PHP, SQL, HTML, JSON, and C++. Everything else stays bare.
Will it overwrite a contributor's tag?
No. Any block that already has a hint is preserved unchanged, so collaborative edits are safe.
Does it detect TypeScript?
Not separately. TS examples are tagged javascript. Rename to typescript by hand if needed.
Can I run it on multiple docs at once?
No — one document per run. Process each file individually for a multi-file repo, or combine docs first with md-merger.
Are there any settings to get wrong in review?
No. It is a one-click transform with no options, so a PR that runs it produces a clean, predictable diff — only inserted hints on previously bare fences.
Is it safe to run repeatedly?
Yes. It is idempotent: already-tagged blocks are skipped, so re-running before a release only tags new bare fences.
Does my README get uploaded anywhere?
No. Processing is in-browser, so you can tag a private repo's README before it ever goes public.
How do I preview the README the way GitHub renders it?
After tagging, run md-to-github-html to get GitHub-flavoured HTML, or tidy spacing first with md-prettifier. Tagging the code blocks last keeps the fences stable for those passes.
Privacy first
All Markdown processing runs locally in your browser using JavaScript. No file is ever uploaded to JAD Apps servers — only metadata counters are saved for signed-in dashboard stats.