文件
mynode/packages/app-desktop/gui/NoteEditor/utils/cleanMarkdownNbsp.ts
chen 301194963b
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
feat: Initial clean release of CHM
2026-11-04 11:29:39 +08:00

56 行
1.8 KiB
TypeScript

/**
* Removes standalone ` ` and related non-breaking whitespace entity lines
* (commonly produced when converting empty rich text paragraphs `<p>&nbsp;</p>` to Markdown)
* while safely preserving:
* 1. Fenced code blocks (``` or ~~~) containing `&nbsp;`
* 2. Inline `&nbsp;` within sentences or tables (e.g. `word1&nbsp;word2` or `| &nbsp; |`)
* 3. Inline code spans (e.g. `` `&nbsp;` ``)
*
* @param text The input markdown text.
* @returns Cleaned markdown text without raw standalone `&nbsp;` lines.
*/
export function cleanMarkdownNbsp(text: string): string {
if (!text || typeof text !== 'string') return text;
if (!text.includes('&nbsp;') && !text.includes('&#160;') && !text.includes('&#xA0;')) return text;
const lines = text.split(/\r?\n/);
const eol = text.includes('\r\n') ? '\r\n' : '\n';
const result: string[] = [];
let inCodeBlock = false;
// Matches lines consisting exclusively of one or more non-breaking space entities
// (&nbsp;, &#160;, &#xA0;) and whitespace / unicode non-breaking spaces (\u00A0)
const standaloneNbspLineRegex = /^[ \t\u00A0]*(?:(?:&nbsp;|&#160;|&#xA0;)[ \t\u00A0]*)+$/;
for (const line of lines) {
const trimmed = line.trim();
if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {
inCodeBlock = !inCodeBlock;
result.push(line);
continue;
}
if (inCodeBlock) {
result.push(line);
continue;
}
// Check if the line consists entirely of standalone non-breaking space entities
if (standaloneNbspLineRegex.test(line)) {
// If previous line was already empty, skip pushing another empty line
// to avoid ballooning vertical whitespace
if (result.length > 0 && result[result.length - 1] === '') {
continue;
}
result.push('');
continue;
}
result.push(line);
}
return result.join(eol).replace(/(\r?\n){3,}/g, '$1$1');
}
export default cleanMarkdownNbsp;