Skip to content

feat: add remark plugin to strip emojis#14122

Merged
mnkiefer merged 1 commit intomainfrom
strip-emojis
Feb 6, 2026
Merged

feat: add remark plugin to strip emojis#14122
mnkiefer merged 1 commit intomainfrom
strip-emojis

Conversation

@mnkiefer
Copy link
Contributor

@mnkiefer mnkiefer commented Feb 6, 2026

  • Introduces a new custom remark plugin by stripping emojis from text, code blocks, image metadata, etc. to ensure a more professional appearance.

@mnkiefer mnkiefer self-assigned this Feb 6, 2026
Copilot AI review requested due to automatic review settings February 6, 2026 12:53
@mnkiefer mnkiefer merged commit c7ecb1d into main Feb 6, 2026
36 checks passed
@mnkiefer mnkiefer deleted the strip-emojis branch February 6, 2026 12:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a custom remark plugin to strip emoji characters from rendered documentation, aiming for a more professional appearance. The plugin recursively traverses the markdown AST and removes emojis from text nodes, code blocks, image/link metadata, and MDX JSX attributes.

Changes:

  • Added a new remark plugin at docs/src/lib/remark/stripEmojis.js that implements tree traversal and emoji stripping logic
  • Integrated the plugin into the Astro markdown pipeline via astro.config.mjs

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
docs/src/lib/remark/stripEmojis.js New remark plugin that recursively visits AST nodes and strips emojis using a replacement map and Unicode property escapes
docs/astro.config.mjs Registers the stripEmojis plugin in the markdown.remarkPlugins configuration array

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +26 to +32
if (node.type === 'inlineCode' && typeof node.value === 'string') {
node.value = stripEmojis(node.value);
}

if (node.type === 'code' && typeof node.value === 'string') {
node.value = stripEmojis(node.value);
}
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stripping emojis from code blocks and inline code could break code examples that intentionally include emoji characters. For example, string literals, test cases, or documentation examples that demonstrate emoji handling would be modified. Consider whether code should be excluded from emoji stripping to preserve code examples as written.

Copilot uses AI. Check for mistakes.
Comment on lines +113 to +121
* @param {string} input
*/
function stripEmojis(input) {
let output = input;

for (const [from, to] of replacements.entries()) {
if (output.includes(from)) output = output.split(from).join(to);
}

Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string replacement approach using split().join() is inefficient for multiple replacements on the same string. Each replacement iterates through the entire string, resulting in O(n*m) complexity where n is string length and m is number of replacements. Consider using a single pass with a regex combining all patterns, or use replaceAll() which is more efficient and clearer in intent.

Suggested change
* @param {string} input
*/
function stripEmojis(input) {
let output = input;
for (const [from, to] of replacements.entries()) {
if (output.includes(from)) output = output.split(from).join(to);
}
* Escape special characters in a string for use in a RegExp.
* @param {string} value
* @returns {string}
*/
function escapeRegex(value) {
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
// Build a single regex that matches any of the replacement keys.
const replacementPattern = Array.from(replacements.keys())
.sort((a, b) => b.length - a.length) // longer first to prefer longer matches
.map((key) => escapeRegex(key))
.join('|');
const replacementsRegex = new RegExp(replacementPattern, 'gu');
/**
* @param {string} input
*/
function stripEmojis(input) {
let output = input.replace(
replacementsRegex,
(match) => replacements.get(match) ?? match,
);

Copilot uses AI. Check for mistakes.
*/
export default function remarkStripEmojis() {
return function transform(tree) {
visit(tree);
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The transform function should return the tree after modifications. While remark plugins that mutate the tree in-place may work without an explicit return, it's a best practice to return the tree to follow the unified plugin specification and ensure compatibility with the remark ecosystem. Add return tree; after the visit call.

Suggested change
visit(tree);
visit(tree);
return tree;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants