How to remove orphan and empty bold markers from markdown
- Step 1Paste the doc page — Paste the Markdown source of the page you're cleaning, or drop a single
.mdfile. - Step 2Run the normalizer — Empty
****/____are deleted,**__x__**collapses to**x**,***x***becomes**_x_**, and padded markers are trimmed in one pass. - Step 3Look for remaining literal markers — Any asterisks still showing in the output mean an unmatched or one-sided marker — those are left for you to resolve, not auto-balanced.
- Step 4Verify code samples — Confirm triple-backtick fenced blocks are unchanged. Inline backtick spans are not protected and should be eyeballed.
- Step 5Copy back into the repo — Copy the cleaned Markdown into your docs source, or download the
.mdfile for a commit. - Step 6Wire it into review — Run it again whenever a PR touches prose — clean text is idempotent, so it only ever changes genuine artifacts.
Orphan and redundancy rules
These are the rules relevant to documentation artifacts, applied in order to prose segments.
| Input | Result | Artifact it removes |
|---|---|---|
**** (bare) | (removed) | Empty bold run left after a term was deleted |
____ (bare) | (removed) | Empty underscore-bold run |
**__text__** | **text** | Double-strong wrapper from a merge or paste |
***text*** | **_text_** | Triple bold+italic standardised |
** text ** | **text** | Padded bold that wouldn't render |
__ text __ | __text__ | Padded underscore-bold trimmed |
Intentional non-removals
The tool is conservative. It does not guess at intent for these — they pass through.
| Artifact | Behaviour | Why |
|---|---|---|
| `**unclosed term | Preserved | No balancing logic — an unclosed marker stays visible for review |
** orphan** (one-sided space) | Preserved | Trim needs symmetric whitespace |
*** alone (three only) | Preserved | Only literal ****/____ quad runs are deleted |
| Asterisk in inline code | Modified | Inline backtick spans are not protected |
| Asterisk in fenced block | Preserved | Triple-backtick fences are detected and skipped |
Tier limits
Markdown-family limits. charLimit is independent of file size.
| Tier | Max file size | Max characters | Files per run |
|---|---|---|---|
| Free | 1 MB | 500,000 | 1 |
| Pro | 10 MB | 5,000,000 | 10 |
| Pro-media | 50 MB | 20,000,000 | 50 |
| Developer | 500 MB | Unlimited | Unlimited |
Cookbook
Before/after pairs taken from real documentation edits. The cleaner's output is shown beneath each source block.
Stray empty markers after a deleted term
An API name was removed but the bold wrapper stayed behind.
Before: Call the **** endpoint to refresh the token. After: Call the endpoint to refresh the token.
Double-strong heading from a merge
A merge wrapped an already-bold label in a second strong span.
Before: **__Deprecated:__** use the v2 client instead. After: **Deprecated:** use the v2 client instead.
Padded bold in a callout
Manual spacing around a warning kept it from rendering as bold.
Before: ** Warning ** this flag is irreversible. After: **Warning** this flag is irreversible.
Triple emphasis standardised
A migrated page used *** for an emphasised term.
Before: This is ***required*** for production deploys. After: This is **_required_** for production deploys.
Config example preserved
A fenced YAML block containing asterisks is untouched while prose is cleaned.
Before: Set the ***glob*** pattern: ```yaml include: "**/*.md" ``` After: Set the **_glob_** pattern: ```yaml include: "**/*.md" ```
Edge cases and what actually happens
Only literal `****`/`____` are deleted
By designAn orphan single ** or three-asterisk *** is not removed — only the exact empty quad runs **** and ____ match the delete rule. Other stray markers stay visible.
Deleting `****` collapses a space
Expecteda **b** and **** becomes a **b**and because removing the empty run pulls the surrounding words together. Re-add a space if the adjacency reads wrong.
Unclosed marker `**term
PreservedNo balancing logic exists. An opening marker without a close is left untouched so a reviewer can supply the missing word.
One-sided spacing `** term**`
PreservedTrim rules require spaces on both sides. A leading-only or trailing-only space is preserved.
Asterisk inside inline code
ModifiedInline backtick spans are treated as prose and rewritten. Put literal marker examples in a fenced block to protect them.
4-space indented code
ModifiedOnly triple-backtick fences are detected. An indented code block is processed as prose and its markers can change.
Fenced block with `**/*` globs
PreservedTriple-backtick fenced content is passed through unchanged, so glob patterns and shell wildcards inside fences survive.
`****text****` (filled quad)
NormalizedThis is not an orphan run; it contains text. The *** rule fires first, producing ***_text_*** rather than a deletion.
Already-clean page
UnchangedWell-formed emphasis passes through. The rules are idempotent, so clean docs are never altered by a re-run.
Page exceeds char limit
RejectedFree tier caps at 500,000 characters. A large generated doc may hit charLimit before the 1 MB byte size — split or upgrade.
Frequently asked questions
What counts as an orphan marker here?
Only the literal empty quad runs **** and ____ are deleted. A lone **, *, or *** with no content is not removed by this tool.
Does it remove unclosed bold like `**term`?
No. There is no balancing logic, so an opening marker with no close is left in place for a human to resolve.
Why did removing `****` join two words?
Deleting the empty run pulls the surrounding text together, so b** and **** can become b**and. Add a space back where needed.
Does it collapse `**__text__**`?
Yes. Redundant double-strong nesting becomes a single **text**, which is the most common documentation artifact after merges.
Are command examples in code blocks safe?
Yes, if they are in triple-backtick fences. Inline backtick spans are not protected and may be rewritten.
Will it touch `**/*.md` glob patterns?
Only outside fenced code. Inside a triple-backtick block such globs are preserved; in prose or inline code they are treated as emphasis.
Does it change `***term***`?
Yes — it standardises to **_term_**. Both render as bold+italic; the explicit form is more portable across renderers.
Is it safe to run on every PR?
Yes. The rules are idempotent, so clean Markdown is never degraded. It only changes genuine artifacts.
Is anything uploaded?
No. Processing happens in your browser, so internal documentation never leaves your machine.
Can I clean a whole docs folder at once?
Not here — it processes one file per run. Combine pages first with the merger, or split a large file with the splitter.
It left a stray asterisk — what now?
That marker was either unmatched or one-sided, both of which are intentionally preserved. Fix the source and re-run.
What about broken tables or headings?
Use the table repair tool for pipe tables, the heading shifter for levels, and the prettifier for overall formatting.
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.