diff --git a/docs/packages/transformers.md b/docs/packages/transformers.md index 5baf924c6..7edc592be 100644 --- a/docs/packages/transformers.md +++ b/docs/packages/transformers.md @@ -544,3 +544,22 @@ CSS output: --shiki-light-bg: #ffffff; } ``` + +### `transformerRemoveComments` + +Remove comments from the code. + +```ts +import { transformerRemoveComments } from '@shikijs/transformers' + +const html = await codeToHtml(code, { + lang: 'ts', + transformers: [ + transformerRemoveComments(), + ], +}) +``` + +Options: + +- `removeEmptyLines`: Remove lines that become empty after removing comments. Default `true`. diff --git a/packages/transformers/src/index.ts b/packages/transformers/src/index.ts index a410acf0b..7bc630870 100644 --- a/packages/transformers/src/index.ts +++ b/packages/transformers/src/index.ts @@ -9,6 +9,7 @@ export * from './transformers/notation-focus' export * from './transformers/notation-highlight' export * from './transformers/notation-highlight-word' export * from './transformers/notation-map' +export * from './transformers/remove-comments' export * from './transformers/remove-line-breaks' export * from './transformers/remove-notation-escape' export * from './transformers/render-indent-guides' diff --git a/packages/transformers/src/transformers/remove-comments.ts b/packages/transformers/src/transformers/remove-comments.ts new file mode 100644 index 000000000..960bd60ee --- /dev/null +++ b/packages/transformers/src/transformers/remove-comments.ts @@ -0,0 +1,51 @@ +import type { ShikiTransformer } from '@shikijs/types' + +export interface TransformerRemoveCommentsOptions { + /** + * Remove lines that become empty after removing comments. + * @default true + */ + removeEmptyLines?: boolean +} + +/** + * Remove comments from the code. + */ +export function transformerRemoveComments( + options: TransformerRemoveCommentsOptions = {}, +): ShikiTransformer { + const { removeEmptyLines = true } = options + + return { + name: '@shikijs/transformers:remove-comments', + preprocess(_code, options) { + const opts = options as any + if (opts.includeExplanation !== true) + opts.includeExplanation = true + }, + tokens(tokens) { + const result = [] + for (const line of tokens) { + const hasComment = line.some(token => + token.explanation?.some(exp => exp.scopes.some(s => s.scopeName.startsWith('comment'))), + ) + + const filteredLine = line.filter((token) => { + const isComment = token.explanation?.some(exp => + exp.scopes.some(s => s.scopeName.startsWith('comment')), + ) + return !isComment + }) + + if (removeEmptyLines && hasComment) { + const isAllWhitespace = filteredLine.every(token => !token.content.trim()) + if (isAllWhitespace) + continue + } + + result.push(filteredLine) + } + return result + }, + } +} diff --git a/packages/transformers/test/fixtures.test.ts b/packages/transformers/test/fixtures.test.ts index d8496886b..a2300ea77 100644 --- a/packages/transformers/test/fixtures.test.ts +++ b/packages/transformers/test/fixtures.test.ts @@ -10,6 +10,7 @@ import { transformerNotationFocus, transformerNotationHighlight, transformerNotationWordHighlight, + transformerRemoveComments, transformerRemoveLineBreak, transformerRemoveNotationEscape, transformerRenderWhitespace, @@ -265,3 +266,18 @@ body { margin: 0; } .line { display: block; width: 100%; height: 1.2em; } `, ) + +suite( + 'remove-comments', + import.meta.glob('./fixtures/remove-comments/*.*', { query: '?raw', import: 'default', eager: true }), + [ + transformerRemoveComments(), + transformerRemoveLineBreak(), + ], + code => `${code} +`, +) diff --git a/packages/transformers/test/fixtures/remove-comments/basic.js b/packages/transformers/test/fixtures/remove-comments/basic.js new file mode 100644 index 000000000..8f1116655 --- /dev/null +++ b/packages/transformers/test/fixtures/remove-comments/basic.js @@ -0,0 +1,6 @@ +// This is a comment +const x = 1; // Inline comment +/* Block comment */ +const y = 2; + +// Another comment diff --git a/packages/transformers/test/fixtures/remove-comments/basic.js.output.html b/packages/transformers/test/fixtures/remove-comments/basic.js.output.html new file mode 100644 index 000000000..8d2f7c249 --- /dev/null +++ b/packages/transformers/test/fixtures/remove-comments/basic.js.output.html @@ -0,0 +1,6 @@ +
const x = 1; const y = 2;
+
\ No newline at end of file
diff --git a/test/exports/@shikijs/transformers.yaml b/test/exports/@shikijs/transformers.yaml
index 225c8df80..c4bf27d20 100644
--- a/test/exports/@shikijs/transformers.yaml
+++ b/test/exports/@shikijs/transformers.yaml
@@ -12,6 +12,7 @@
transformerNotationHighlight: function
transformerNotationMap: function
transformerNotationWordHighlight: function
+ transformerRemoveComments: function
transformerRemoveLineBreak: function
transformerRemoveNotationEscape: function
transformerRenderIndentGuides: function