diff --git a/docs/packages/transformers.md b/docs/packages/transformers.md index cf453634d..43d078ed1 100644 --- a/docs/packages/transformers.md +++ b/docs/packages/transformers.md @@ -314,6 +314,22 @@ console.log('Info') // [\!code info] - Outputs: `` for info - The outer `
` tag is modified: `
`
 
+You can also provide a message to be displayed:
+
+````md
+```ts
+console.error('Error') // [\!code error:This is an error message]
+```
+````
+
+Renders:
+
+```ts
+console.error('Error') // [!code error:This is an error message]
+```
+
+- Outputs: ``
+
 With some additional CSS rules, you can make it look like this:
 
 ```ts
diff --git a/packages/transformers/src/transformers/notation-error-level.ts b/packages/transformers/src/transformers/notation-error-level.ts
index 88ecae34c..d1db2aebb 100644
--- a/packages/transformers/src/transformers/notation-error-level.ts
+++ b/packages/transformers/src/transformers/notation-error-level.ts
@@ -1,6 +1,6 @@
 import type { ShikiTransformer } from '@shikijs/types'
 import type { MatchAlgorithmOptions } from '../shared/notation-transformer'
-import { transformerNotationMap } from './notation-map'
+import { createCommentNotationTransformer } from '../shared/notation-transformer'
 
 export interface TransformerNotationErrorLevelOptions extends MatchAlgorithmOptions {
   classMap?: Record
@@ -14,6 +14,10 @@ export interface TransformerNotationErrorLevelOptions extends MatchAlgorithmOpti
   classActiveCode?: string
 }
 
+function escapeRegExp(str: string): string {
+  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
+}
+
 /**
  * Allow using `[!code error]` `[!code warning]` notation in code to mark highlighted lines.
  */
@@ -30,13 +34,32 @@ export function transformerNotationErrorLevel(
     classActiveCode,
   } = options
 
-  return transformerNotationMap(
-    {
-      classMap,
-      classActivePre,
-      classActiveCode,
-      matchAlgorithm: options.matchAlgorithm,
-    },
+  return createCommentNotationTransformer(
     '@shikijs/transformers:notation-error-level',
+    new RegExp(`\\s*\\[!code (${Object.keys(classMap).map(escapeRegExp).join('|')})(:.*)?\\]`, 'gi'),
+    function ([_, match, rawRange = ''], _line, _comment, lines, index) {
+      const range = rawRange ? rawRange.slice(1) : ''
+      if (/^\d+$/.test(range)) {
+        const lineNum = Number.parseInt(range, 10)
+        for (let i = index; i < Math.min(index + lineNum, lines.length); i++) {
+          this.addClassToHast(lines[i], classMap[match])
+        }
+      }
+      else {
+        this.addClassToHast(lines[index], classMap[match])
+        if (range) {
+          const properties = lines[index].properties || {}
+          properties[`data-${match}`] = range
+          lines[index].properties = properties
+        }
+      }
+
+      if (classActivePre)
+        this.addClassToHast(this.pre, classActivePre)
+      if (classActiveCode)
+        this.addClassToHast(this.code, classActiveCode)
+      return true
+    },
+    options.matchAlgorithm,
   )
 }
diff --git a/packages/transformers/test/fixtures/error-level/message.js b/packages/transformers/test/fixtures/error-level/message.js
new file mode 100644
index 000000000..09a47234f
--- /dev/null
+++ b/packages/transformers/test/fixtures/error-level/message.js
@@ -0,0 +1,4 @@
+export function foo() {
+  console.error('error') // [!code error:This is an error]
+  console.warn('warn') // [!code warning:This is a warning]
+}
diff --git a/packages/transformers/test/fixtures/error-level/message.js.output.html b/packages/transformers/test/fixtures/error-level/message.js.output.html
new file mode 100644
index 000000000..eba3d39dc
--- /dev/null
+++ b/packages/transformers/test/fixtures/error-level/message.js.output.html
@@ -0,0 +1,8 @@
+
export function foo() {  console.error('error')   console.warn('warn') }
+ \ No newline at end of file diff --git a/packages/transformers/test/fixtures/error-level/numeric.js b/packages/transformers/test/fixtures/error-level/numeric.js new file mode 100644 index 000000000..132c965c7 --- /dev/null +++ b/packages/transformers/test/fixtures/error-level/numeric.js @@ -0,0 +1,6 @@ +export function foo() { + console.log('error') // [!code error:2] + console.log('error') + console.log('warn') // [!code warning:2] + console.log('warn') +} diff --git a/packages/transformers/test/fixtures/error-level/numeric.js.output.html b/packages/transformers/test/fixtures/error-level/numeric.js.output.html new file mode 100644 index 000000000..439c4480d --- /dev/null +++ b/packages/transformers/test/fixtures/error-level/numeric.js.output.html @@ -0,0 +1,8 @@ +
export function foo() {  console.log('error')   console.log('error')  console.log('warn')   console.log('warn')}
+ \ No newline at end of file