@riebeckite/plugin-code-annotations 0.0.21 → 0.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # @riebeckite/plugin-code-annotations
2
2
 
3
- VitePress/Docusaurus-style code block annotations: line highlighting, focus,
4
- and diff markers that work on plain `<pre><code>` blocks and on the line
5
- wrappers produced by `@riebeckite/plugin-code-enhance`.
3
+ <!-- Generated from docs/docs/plugins/code-annotations.md. Edit the canonical documentation in docs/docs/plugins and run `pnpm docs:sync`. -->
4
+
5
+ Renders code diffs with the language syntax highlighter and Riebeckite's code
6
+ block UI.
6
7
 
7
8
  [日本語](./README_ja.md)
8
9
 
@@ -13,126 +14,55 @@ import { defineConfig } from "@riebeckite/core";
13
14
  import { codeAnnotations } from "@riebeckite/plugin-code-annotations";
14
15
 
15
16
  export default defineConfig({
16
- // ...
17
17
  plugins: [codeAnnotations()],
18
18
  });
19
19
  ```
20
20
 
21
- The plugin registers its own `style.css`. It adds no client entry and no
22
- runtime JavaScript.
21
+ Use it with `@riebeckite/plugin-code-enhance` to retain syntax highlighting,
22
+ line numbers, the language label, and copy controls.
23
23
 
24
24
  ## Syntax
25
25
 
26
- ### Line highlighting (fence meta)
27
-
28
- Add a brace range after the language, exactly like Docusaurus and VitePress.
29
-
30
- ````md
31
- ```js {2,4-5}
32
- const a = 1;
33
- const b = 2;
34
- const c = 3;
35
- const d = 4;
36
- const e = 5;
37
- ```
38
- ````
39
-
40
- Lines `2`, `4`, and `5` receive `rb-code__line--highlighted`.
41
-
42
- ### Focus
43
-
44
- Use the `focus` meta group, or an inline `[!code focus]` marker. An optional
45
- count focuses the current line and the following lines.
46
-
47
- ````md
48
- ```js focus:{2}
49
- const a = 1;
50
- const b = 2;
51
- ```
52
- ````
53
-
54
- ````md
55
- ```js
56
- const a = 1; // [!code focus]
57
- const b = 2;
58
- ```
59
- ````
60
-
61
- `.rb-code__line--focused` is applied. `[!code focus:3]` focuses three lines
62
- starting at the marker.
63
-
64
- ### Diff
65
-
66
- ````md
67
- ```js
68
- const kept = true;
69
- const added = true; // [!code ++]
70
- const removed = false; // [!code --]
71
- ```
72
- ````
73
-
74
- The marker comment is removed from the rendered text, and the line receives
75
- `rb-code__line--added` or `rb-code__line--removed`.
76
-
77
- ### Explicit highlight marker
26
+ Use `diff` as the fence language and put the target language after it. Lines
27
+ starting with `+` are additions, lines starting with `-` are removals, and all
28
+ other lines are unchanged.
78
29
 
79
30
  ````md
80
- ```js
81
- const value = 1; // [!code highlight]
31
+ ```diff js
32
+ + const message = "Hello";
33
+ - const message = "World";
34
+ const unchanged = true;
82
35
  ```
83
36
  ````
84
37
 
85
- Marker comments are recognized with the `//`, `#`, `--`, and `<!-- -->`
86
- comment prefixes, so the same syntax works for JavaScript, shell, SQL, Lua,
87
- HTML, and other languages.
88
-
89
- ## Options
90
-
91
- | Option | Type | Default | Description |
92
- | ------ | ---- | ------- | ----------- |
93
- | `className` | `string` | `"rb-code"` | Class on the block root (`<pre>` or `rehype-pretty-code` `<figure>`) |
94
- | `lineClassName` | `string` | `"rb-code__line"` | Class on generated line wrappers |
95
- | `highlightClassName` | `string` | `"rb-code__line--highlighted"` | Class for highlighted lines |
96
- | `addedClassName` | `string` | `"rb-code__line--added"` | Class for `[!code ++]` lines |
97
- | `removedClassName` | `string` | `"rb-code__line--removed"` | Class for `[!code --]` lines |
98
- | `focusClassName` | `string` | `"rb-code__line--focused"` | Class for focused lines |
99
- | `language` | `string` | unset | Only annotate blocks of this language |
100
-
101
- ```ts
102
- codeAnnotations({ highlightClassName: "is-highlighted" });
103
- ```
38
+ The `+` and `-` markers are rendered separately from the code, so Shiki
39
+ highlights the JavaScript, TypeScript, Python, JSON, or other target language
40
+ without treating the marker as source code. The copy button copies the visible
41
+ diff, including its markers.
104
42
 
105
- ## Using with code-enhance
43
+ An empty, malformed, or missing target language leaves the fence as an ordinary
44
+ `diff` code block. A target language that the syntax highlighter does not know
45
+ falls back to its normal unhighlighted rendering and does not fail the build.
106
46
 
107
- `@riebeckite/plugin-code-annotations` does not import or depend on
108
- `@riebeckite/plugin-code-enhance`. It detects both raw `<pre><code>` text and
109
- the `.line` wrappers emitted by `rehype-pretty-code`:
47
+ ## Integration
110
48
 
111
- - If line wrappers already exist, their classes are extended in place and the
112
- existing `data-line` attribute is kept.
113
- - Otherwise the plugin wraps the raw code text into
114
- `<span class="rb-code__line" data-line="N">` elements.
115
-
116
- Because `rehype-pretty-code` substitutes the `<code>` element, the plan is also
117
- mirrored into the preserved fence meta, so annotations still apply after
118
- code-enhance runs. Place `codeAnnotations()` after `codeEnhance()` in the
119
- plugins array; the plugin uses `order: 10` to run after code-enhance's
120
- highlighting regardless.
49
+ The plugin transforms Markdown in its remark phase, records each line marker in
50
+ fence metadata, then restores the markers and the existing
51
+ `rr-code__line--add` / `rr-code__line--remove` classes in its rehype phase.
52
+ `code-enhance` supplies the line wrappers and all code block UI. The plugin does
53
+ not import it, so the two packages remain independently configurable.
121
54
 
122
55
  ## Exports
123
56
 
124
- - `codeAnnotations(options?)` / `codeAnnotationsPlugin(options?)` — plugin factory
125
- - `remarkCodeAnnotations(options?)` — remark transform
126
- - `rehypeCodeAnnotations(options?)` — rehype transform
127
- - `parseCodeAnnotations(meta)` — parse fence meta into a plan
128
- - `parseLineRanges(spec)` — parse `1,3-5` into line numbers
129
- - `collectCodeAnnotations(meta, code)` — parse meta plus inline markers
130
- - `resolveCodeAnnotationsOptions(options?)` — fill in defaults
131
- - Types: `CodeAnnotationsOptions`, `ResolvedCodeAnnotationsOptions`,
132
- `CodeAnnotationPlan`, `CodeAnnotationKind`
57
+ - `codeAnnotations()` / `codeAnnotationsPlugin()` — plugin factory
58
+ - `remarkCodeAnnotations()` — Markdown transform
59
+ - `rehypeCodeAnnotations()` — HTML transform
60
+ - `collectCodeDiff(code)` — separates diff markers from source text
61
+ - `serializeCodeDiff(plan)` / `deserializeCodeDiff(value)` — line-plan helpers
62
+ - `encodeCodeDiffMeta(plan)` / `extractCodeDiffMeta(meta)` — metadata helpers
63
+ - Types: `CodeDiffPlan`, `DiffMarker`
133
64
 
134
65
  ## See also
135
66
 
136
- - [Plugin guide](../../../docs/docs/reference/plugin-api.md)
67
+ - [Plugin guide](https://github.com/Rerurate514/riebeckite/blob/main/docs/docs/reference/plugin-api.md)
137
68
  - [`@riebeckite/plugin-code-enhance`](../code-enhance/README.md)
138
-
package/README_ja.md CHANGED
@@ -1,9 +1,8 @@
1
1
  # @riebeckite/plugin-code-annotations
2
2
 
3
- VitePress / Docusaurus 風のコードブロック装飾を加えるプラグインです。フェンスの
4
- メタ情報による行の強調と、`[!code ...]` のインラインマーカーによるフォーカス・
5
- 差分表示に対応します。素の `<pre><code>` と
6
- `@riebeckite/plugin-code-enhance` の行ラッパーの両方で動作します。
3
+ <!-- Generated from docs/docs/plugins/code-annotations.ja.md. Edit the canonical documentation in docs/docs/plugins and run `pnpm docs:sync`. -->
4
+
5
+ 差分のコードブロックを、対象言語のシンタックスハイライトとRiebeckiteのコードブロックUIで表示します。
7
6
 
8
7
  [English](./README.md)
9
8
 
@@ -14,124 +13,49 @@ import { defineConfig } from "@riebeckite/core";
14
13
  import { codeAnnotations } from "@riebeckite/plugin-code-annotations";
15
14
 
16
15
  export default defineConfig({
17
- // ...
18
16
  plugins: [codeAnnotations()],
19
17
  });
20
18
  ```
21
19
 
22
- プラグインは `style.css` のみを登録します。クライアントエントリーはなく、
23
- 実行時 JavaScript は追加しません。
20
+ シンタックスハイライト、行番号、言語ラベル、コピー操作を使う場合は、
21
+ `@riebeckite/plugin-code-enhance` と併用してください。
24
22
 
25
23
  ## 書き方
26
24
 
27
- ### フェンスメタによる行の強調
28
-
29
- 言語の後ろに波括弧で行範囲を書きます。Docusaurus や VitePress と同じ記法です。
30
-
31
- ````md
32
- ```js {2,4-5}
33
- const a = 1;
34
- const b = 2;
35
- const c = 3;
36
- const d = 4;
37
- const e = 5;
38
- ```
39
- ````
40
-
41
- 2、4、5 行目に `rb-code__line--highlighted` が付きます。
42
-
43
- ### フォーカス
44
-
45
- `focus` メタ、またはインラインの `[!code focus]` を使います。行数を指定すると
46
- その行から続く行までをまとめてフォーカスします。
47
-
48
- ````md
49
- ```js focus:{2}
50
- const a = 1;
51
- const b = 2;
52
- ```
53
- ````
54
-
55
- ````md
56
- ```js
57
- const a = 1; // [!code focus]
58
- const b = 2;
59
- ```
60
- ````
61
-
62
- `rb-code__line--focused` が付きます。`[!code focus:3]` なら 3 行分です。
63
-
64
- ### 差分
65
-
66
- ````md
67
- ```js
68
- const kept = true;
69
- const added = true; // [!code ++]
70
- const removed = false; // [!code --]
71
- ```
72
- ````
73
-
74
- マーカーのコメントは表示テキストから取り除かれ、行には
75
- `rb-code__line--added` または `rb-code__line--removed` が付きます。
76
-
77
- ### 明示的な強調マーカー
25
+ コードフェンスの言語に `diff` を指定し、その後に対象言語を書きます。`+` で始まる行は追加、
26
+ `-` で始まる行は削除、それ以外は変更のない行として扱います。
78
27
 
79
28
  ````md
80
- ```js
81
- const value = 1; // [!code highlight]
29
+ ```diff js
30
+ + const message = "Hello";
31
+ - const message = "World";
32
+ const unchanged = true;
82
33
  ```
83
34
  ````
84
35
 
85
- マーカーは `//`、`#`、`--`、`<!-- -->` のコメント記法に対応します。JavaScript、
86
- シェル、SQL、Lua、HTML などで同じ書き方が使えます。
87
-
88
- ## オプション
89
-
90
- | オプション | 既定値 | 内容 |
91
- | --- | --- | --- |
92
- | `className` | `"rb-code"` | ブロック直下(`<pre>` または `rehype-pretty-code` の `<figure>`)に付くクラス |
93
- | `lineClassName` | `"rb-code__line"` | 生成する行ラッパーのクラス |
94
- | `highlightClassName` | `"rb-code__line--highlighted"` | 強調行のクラス |
95
- | `addedClassName` | `"rb-code__line--added"` | `[!code ++]` 行のクラス |
96
- | `removedClassName` | `"rb-code__line--removed"` | `[!code --]` 行のクラス |
97
- | `focusClassName` | `"rb-code__line--focused"` | フォーカス行のクラス |
98
- | `language` | 未設定 | 指定した言語のブロックだけを対象にする |
99
-
100
- ```ts
101
- codeAnnotations({ highlightClassName: "is-highlighted" });
102
- ```
36
+ `+` と `-` はコード本体とは別に描画されます。そのためJavaScript、TypeScript、Python、JSON
37
+ などのシンタックスハイライトを妨げません。コピー操作では、表示された差分と同じくマーカーも含めてコピーします。
103
38
 
104
- ## code-enhance との併用
39
+ 対象言語が空、形式が不正、または指定されていないフェンスは、通常の `diff` コードブロックとして扱います。
40
+ シンタックスハイライトが対応していない言語を指定しても、ハイライトなしで表示され、ビルドは失敗しません。
105
41
 
106
- `@riebeckite/plugin-code-annotations` は
107
- `@riebeckite/plugin-code-enhance` を import せず、依存もしません。素の
108
- `<pre><code>` のテキストと、`rehype-pretty-code` が出力する `.line` ラッパーの
109
- 両方を検出します。
42
+ ## 連携
110
43
 
111
- - 行ラッパーがすでにある場合は、既存のクラスに追記し、既存の `data-line` を
112
- そのまま使います。
113
- - ない場合は、コード本文を
114
- `<span class="rb-code__line" data-line="N">` に分割します。
44
+ このプラグインはremark段階で差分マーカーをコード本体から分離し、フェンスメタ情報に記録します。rehype段階では、
45
+ マーカーと既存の `rr-code__line--add` / `rr-code__line--remove` クラスを戻します。行ラッパーやコードブロックUIは
46
+ `code-enhance` が提供します。両パッケージはimportで依存していないため、個別に設定できます。
115
47
 
116
- `rehype-pretty-code` は `<code>` 要素を差し替えるため、注釈プランは保持される
117
- フェンスメタにも複製します。これにより code-enhance の後でも注釈が適用されます。
118
- プラグイン配列では `codeEnhance()` の後に `codeAnnotations()` を置いてください。
119
- `order: 10` により、順序に関わらず強調処理の後に実行されます。
48
+ ## 公開API
120
49
 
121
- ## 公開 API
122
-
123
- - `codeAnnotations(options?)` / `codeAnnotationsPlugin(options?)` — プラグインファクトリ
124
- - `remarkCodeAnnotations(options?)` — remark 変換
125
- - `rehypeCodeAnnotations(options?)` — rehype 変換
126
- - `parseCodeAnnotations(meta)` — フェンスメタをプランに変換
127
- - `parseLineRanges(spec)` — `1,3-5` を行番号に変換
128
- - `collectCodeAnnotations(meta, code)` — メタとインラインマーカーをまとめて解析
129
- - `resolveCodeAnnotationsOptions(options?)` — 既定値を補完
130
- - 型: `CodeAnnotationsOptions`、`ResolvedCodeAnnotationsOptions`、
131
- `CodeAnnotationPlan`、`CodeAnnotationKind`
50
+ - `codeAnnotations()` / `codeAnnotationsPlugin()` — プラグインファクトリ
51
+ - `remarkCodeAnnotations()` — Markdown変換
52
+ - `rehypeCodeAnnotations()` — HTML変換
53
+ - `collectCodeDiff(code)` — 差分マーカーとコード本体を分離
54
+ - `serializeCodeDiff(plan)` / `deserializeCodeDiff(value)` — 行情報の変換
55
+ - `encodeCodeDiffMeta(plan)` / `extractCodeDiffMeta(meta)` — メタ情報の変換
56
+ - 型: `CodeDiffPlan`、`DiffMarker`
132
57
 
133
58
  ## 関連資料
134
59
 
135
- - [プラグインシステム](../../../docs/docs/reference/plugin-api.ja.md)
60
+ - [プラグインシステム](https://github.com/Rerurate514/riebeckite/blob/main/docs/docs/reference/plugin-api.ja.md)
136
61
  - [`@riebeckite/plugin-code-enhance`](../code-enhance/README_ja.md)
137
-
package/dist/index.d.ts CHANGED
@@ -1,18 +1,6 @@
1
- import type { CodeAnnotationsOptions } from "./src/types.js";
2
- export type { CollectedCodeAnnotations, InlineCodeAnnotation, } from "./src/annotations.js";
3
- export { ANNOTATIONS_META_PREFIX, collectCodeAnnotations, createEmptyPlan, deserializeAnnotations, encodeAnnotationsMeta, extractAnnotationsMeta, hasAnnotations, parseCodeAnnotations, parseLineRanges, serializeAnnotations, stripInlineCodeAnnotation, } from "./src/annotations.js";
4
- export { DEFAULT_CODE_ANNOTATIONS_OPTIONS, resolveCodeAnnotationsOptions, } from "./src/options.js";
1
+ export type { CodeDiffPlan, DiffMarker } from "./src/annotations.js";
2
+ export { appendCodeDiffMeta, collectCodeDiff, deserializeCodeDiff, encodeCodeDiffMeta, extractCodeDiffMeta, removeCodeDiffMeta, serializeCodeDiff, } from "./src/annotations.js";
5
3
  export { rehypeCodeAnnotations } from "./src/rehype.js";
6
4
  export { remarkCodeAnnotations } from "./src/remark.js";
7
- export type { CodeAnnotationKind, CodeAnnotationPlan, CodeAnnotationsOptions, ResolvedCodeAnnotationsOptions, } from "./src/types.js";
8
- /**
9
- * VitePress/Docusaurus-style code block annotations: line highlighting from
10
- * fence meta and inline `[!code ...]` marker comments for focus, highlight,
11
- * and diff lines.
12
- *
13
- * Runs after `@riebeckite/plugin-code-enhance` (via `order`) so it can annotate
14
- * the line wrappers produced by `rehype-pretty-code` instead of re-wrapping
15
- * them. It never imports or depends on code-enhance.
16
- */
17
- export declare function codeAnnotations(options?: CodeAnnotationsOptions): import("@riebeckite/core").RiebeckitePlugin<import("./index.js").ResolvedCodeAnnotationsOptions>;
5
+ export declare function codeAnnotations(): import("@riebeckite/core").RiebeckitePlugin<unknown>;
18
6
  export declare const codeAnnotationsPlugin: typeof codeAnnotations;
package/dist/index.js CHANGED
@@ -1,188 +1,55 @@
1
1
  // index.ts
2
- import { createStyleAsset, definePlugin } from "@riebeckite/core";
3
-
4
- // src/options.ts
5
- var DEFAULT_CODE_ANNOTATIONS_OPTIONS = {
6
- className: "rb-code",
7
- lineClassName: "rb-code__line",
8
- highlightClassName: "rb-code__line--highlighted",
9
- addedClassName: "rb-code__line--added",
10
- removedClassName: "rb-code__line--removed",
11
- focusClassName: "rb-code__line--focused"
12
- };
13
- function resolveCodeAnnotationsOptions(options = {}) {
14
- const resolved = {
15
- className: options.className ?? DEFAULT_CODE_ANNOTATIONS_OPTIONS.className,
16
- lineClassName: options.lineClassName ?? DEFAULT_CODE_ANNOTATIONS_OPTIONS.lineClassName,
17
- highlightClassName: options.highlightClassName ?? DEFAULT_CODE_ANNOTATIONS_OPTIONS.highlightClassName,
18
- addedClassName: options.addedClassName ?? DEFAULT_CODE_ANNOTATIONS_OPTIONS.addedClassName,
19
- removedClassName: options.removedClassName ?? DEFAULT_CODE_ANNOTATIONS_OPTIONS.removedClassName,
20
- focusClassName: options.focusClassName ?? DEFAULT_CODE_ANNOTATIONS_OPTIONS.focusClassName
21
- };
22
- const language = options.language?.trim();
23
- if (language) resolved.language = language;
24
- return resolved;
25
- }
2
+ import { definePlugin } from "@riebeckite/core";
26
3
 
27
4
  // src/annotations.ts
28
- import { scanMarkdownFenceLines } from "@riebeckite/core";
29
- var ANNOTATIONS_META_PREFIX = "rb-annotations=";
30
- var ANNOTATION_KEYS = [
31
- "highlight",
32
- "added",
33
- "removed",
34
- "focus"
35
- ];
36
- var FOCUS_META_PATTERN = /(?:^|\s)focus[:=]\{([^}]*)\}/g;
37
- var HIGHLIGHT_META_PATTERN = /\{([^{}]*)\}/g;
38
- var INLINE_ANNOTATION_PATTERN = /([ \t]*)(?:(?:\/\/|#|--)[ \t]*\[!code[ \t]+(focus|highlight|\+\+|--)(?::(\d+))?\]|<!--[ \t]*\[!code[ \t]+(focus|highlight|\+\+|--)(?::(\d+))?[ \t]*\][ \t]*-->)[ \t]*$/;
39
- function createEmptyPlan() {
40
- return { highlight: [], added: [], removed: [], focus: [] };
41
- }
42
- function parseCodeAnnotations(meta) {
43
- const plan = createEmptyPlan();
44
- if (typeof meta !== "string" || meta.length === 0) return plan;
45
- const rest = meta.replace(FOCUS_META_PATTERN, (_match, body) => {
46
- addRanges(plan.focus, parseLineRanges(body));
47
- return " ";
48
- });
49
- for (const match of rest.matchAll(HIGHLIGHT_META_PATTERN)) {
50
- addRanges(plan.highlight, parseLineRanges(match[1] ?? ""));
51
- }
52
- return normalizePlan(plan);
53
- }
54
- function parseLineRanges(spec) {
55
- const lines = [];
56
- for (const part of spec.split(",")) {
57
- const trimmed = part.trim();
58
- if (trimmed === "") continue;
59
- const range = /^(\d+)\s*-\s*(\d+)$/.exec(trimmed);
60
- if (range) {
61
- const first = Number(range[1]);
62
- const second = Number(range[2]);
63
- const from = Math.min(first, second);
64
- const to = Math.max(first, second);
65
- for (let line = from; line <= to; line += 1) lines.push(line);
66
- continue;
67
- }
68
- if (/^\d+$/.test(trimmed)) lines.push(Number(trimmed));
69
- }
70
- return lines;
71
- }
72
- function stripInlineCodeAnnotation(line) {
73
- const match = INLINE_ANNOTATION_PATTERN.exec(line);
74
- if (!match) return { line, annotation: null };
75
- const kind = normalizeKind(match[2] ?? match[4]);
76
- if (!kind) return { line, annotation: null };
77
- const rawCount = match[3] ?? match[5];
78
- const parsedCount = rawCount === void 0 ? 1 : Number(rawCount);
79
- const lineCount = Number.isFinite(parsedCount) ? Math.max(1, parsedCount) : 1;
80
- const index = match.index ?? line.length;
81
- const stripped = line.slice(0, index).replace(/[ \t]+$/, "");
82
- return { line: stripped, annotation: { kind, lineCount } };
83
- }
84
- function collectCodeAnnotations(meta, code) {
85
- const plan = parseCodeAnnotations(meta);
86
- const strippedLines = [];
87
- scanMarkdownFenceLines(code).forEach(({ value: rawLine, inFence }, index) => {
88
- const { line, annotation } = inFence ? { line: rawLine, annotation: null } : stripInlineCodeAnnotation(rawLine);
89
- strippedLines.push(line);
90
- if (!annotation) return;
91
- const lineNumber = index + 1;
92
- if (annotation.kind === "focus") {
93
- for (let focused = lineNumber; focused < lineNumber + annotation.lineCount; focused += 1) {
94
- plan.focus.push(focused);
95
- }
96
- return;
97
- }
98
- plan[annotation.kind].push(lineNumber);
5
+ var DIFF_META_PREFIX = "rb-diff=";
6
+ function collectCodeDiff(code) {
7
+ const markers = [];
8
+ const lines = code.split("\n").map((line) => {
9
+ const marker = line.startsWith("+") || line.startsWith("-") ? line[0] : null;
10
+ markers.push(marker);
11
+ return marker ? line.slice(1) : line;
99
12
  });
100
- const hasAnnotations2 = ANNOTATION_KEYS.some((key) => plan[key].length > 0);
101
- return {
102
- plan: hasAnnotations2 ? normalizePlan(plan) : createEmptyPlan(),
103
- code: strippedLines.join("\n"),
104
- hasAnnotations: hasAnnotations2
105
- };
106
- }
107
- function normalizePlan(plan) {
108
- return {
109
- highlight: normalizeLines(plan.highlight),
110
- added: normalizeLines(plan.added),
111
- removed: normalizeLines(plan.removed),
112
- focus: normalizeLines(plan.focus)
113
- };
114
- }
115
- function hasAnnotations(plan) {
116
- if (!plan) return false;
117
- return ANNOTATION_KEYS.some((key) => plan[key].length > 0);
13
+ return { code: lines.join("\n"), plan: { markers } };
118
14
  }
119
- function serializeAnnotations(plan) {
120
- return JSON.stringify(normalizePlan(plan));
15
+ function serializeCodeDiff(plan) {
16
+ return JSON.stringify(plan);
121
17
  }
122
- function deserializeAnnotations(value) {
18
+ function deserializeCodeDiff(value) {
123
19
  if (typeof value !== "string" || value === "") return null;
124
20
  try {
125
- return coercePlan(JSON.parse(value));
21
+ const parsed = JSON.parse(value);
22
+ if (!Array.isArray(parsed.markers)) return null;
23
+ return {
24
+ markers: parsed.markers.map(
25
+ (marker) => marker === "+" || marker === "-" ? marker : null
26
+ )
27
+ };
126
28
  } catch {
127
29
  return null;
128
30
  }
129
31
  }
130
- function encodeAnnotationsMeta(plan) {
131
- return `${ANNOTATIONS_META_PREFIX}${encodeURIComponent(
132
- serializeAnnotations(plan)
133
- )}`;
32
+ function encodeCodeDiffMeta(plan) {
33
+ return `${DIFF_META_PREFIX}${encodeURIComponent(serializeCodeDiff(plan))}`;
134
34
  }
135
- function appendAnnotationsMeta(meta, plan) {
136
- const token = encodeAnnotationsMeta(plan);
137
- const base = typeof meta === "string" ? meta.trim() : "";
138
- return base === "" ? token : `${base} ${token}`;
139
- }
140
- function extractAnnotationsMeta(meta) {
35
+ function extractCodeDiffMeta(meta) {
141
36
  if (typeof meta !== "string") return null;
142
- const match = meta.match(/(?:^|\s)rb-annotations=([^\s]+)/);
37
+ const match = meta.match(/(?:^|\s)rb-diff=([^\s]+)/);
143
38
  if (!match) return null;
144
39
  try {
145
- return coercePlan(JSON.parse(decodeURIComponent(match[1])));
40
+ return deserializeCodeDiff(decodeURIComponent(match[1]));
146
41
  } catch {
147
42
  return null;
148
43
  }
149
44
  }
150
- function removeAnnotationsMeta(meta) {
151
- if (typeof meta !== "string") return "";
152
- return meta.replace(/(?:^|\s)rb-annotations=[^\s]+/g, " ").trim().replace(/\s+/g, " ");
153
- }
154
- function coercePlan(value) {
155
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
156
- return null;
157
- }
158
- const record = value;
159
- return {
160
- highlight: coerceLines(record.highlight),
161
- added: coerceLines(record.added),
162
- removed: coerceLines(record.removed),
163
- focus: coerceLines(record.focus)
164
- };
165
- }
166
- function coerceLines(value) {
167
- if (!Array.isArray(value)) return [];
168
- return value.filter(
169
- (entry) => typeof entry === "number" && Number.isFinite(entry) && entry > 0
170
- );
171
- }
172
- function addRanges(target, ranges) {
173
- target.push(...ranges);
174
- }
175
- function normalizeLines(lines) {
176
- return [...new Set(lines.filter((line) => line > 0))].sort(
177
- (left, right) => left - right
178
- );
45
+ function appendCodeDiffMeta(meta, plan) {
46
+ const token = encodeCodeDiffMeta(plan);
47
+ const base = typeof meta === "string" ? meta.trim() : "";
48
+ return base === "" ? token : `${base} ${token}`;
179
49
  }
180
- function normalizeKind(kind) {
181
- if (kind === "++") return "added";
182
- if (kind === "--") return "removed";
183
- if (kind === "focus") return "focus";
184
- if (kind === "highlight") return "highlight";
185
- return null;
50
+ function removeCodeDiffMeta(meta) {
51
+ if (typeof meta !== "string") return "";
52
+ return meta.replace(/(?:^|\s)rb-diff=[^\s]+/g, " ").trim().replace(/\s+/g, " ");
186
53
  }
187
54
 
188
55
  // src/hast.ts
@@ -214,19 +81,6 @@ function getBooleanProperty(node, key) {
214
81
  const value = getProperty(node, key);
215
82
  return value === true || value === "true" || value === "";
216
83
  }
217
- function hasProperty(node, key) {
218
- return getProperty(node, key) !== void 0;
219
- }
220
- function getClassNameList(node) {
221
- const value = node.properties?.className;
222
- if (Array.isArray(value)) {
223
- return value.filter((entry) => typeof entry === "string");
224
- }
225
- if (typeof value === "string") {
226
- return value.split(/\s+/).filter(Boolean);
227
- }
228
- return [];
229
- }
230
84
  function mergeClassName(current, next) {
231
85
  const currentClass = Array.isArray(current) ? current.join(" ") : typeof current === "string" ? current : "";
232
86
  if (next === "") return currentClass;
@@ -239,12 +93,6 @@ function getDataMeta(node) {
239
93
  const meta = data.meta;
240
94
  return typeof meta === "string" ? meta : null;
241
95
  }
242
- function getTextContent(node) {
243
- if (node.type === "text" && "value" in node && typeof node.value === "string") {
244
- return node.value;
245
- }
246
- return getChildren(node).map(getTextContent).join("");
247
- }
248
96
  function getProperty(node, key) {
249
97
  const value = node.properties?.[key];
250
98
  if (value !== void 0) return value;
@@ -261,19 +109,37 @@ function getChildren(node) {
261
109
  }
262
110
 
263
111
  // src/rehype.ts
264
- function rehypeCodeAnnotations(options = resolveCodeAnnotationsOptions()) {
112
+ function rehypeCodeAnnotations() {
265
113
  return (tree) => {
266
114
  visitElementTree(tree, (node, ancestors) => {
267
115
  if (node.tagName !== "code") return;
268
- const parent = ancestors[ancestors.length - 1];
269
- if (parent?.tagName !== "pre") return;
270
- const pre = parent;
116
+ const pre = ancestors[ancestors.length - 1];
117
+ if (pre?.tagName !== "pre") return;
271
118
  const figure = findFigure(ancestors);
272
119
  const plan = readPlan(node, pre, figure);
273
- stripAnnotationsFromProperties(node);
274
- if (plan === null || !hasAnnotations(plan)) return;
275
- if (!languageMatches(node, options.language)) return;
276
- applyPlan(node, pre, figure, plan, options);
120
+ stripDiffFromProperties(node);
121
+ if (!plan) return;
122
+ const lines = getLineElements(node);
123
+ const codeLines = lines.length > 0 ? lines : wrapCodeLines(node);
124
+ codeLines.forEach((line, index) => {
125
+ const marker = plan.markers[index];
126
+ if (!marker) return;
127
+ line.properties = {
128
+ ...line.properties,
129
+ className: mergeClassName(
130
+ line.properties?.className,
131
+ marker === "+" ? "rr-code__line--add" : "rr-code__line--remove"
132
+ )
133
+ };
134
+ line.children = [
135
+ element(
136
+ "span",
137
+ { className: "rr-code__diff-marker", ariaHidden: "true" },
138
+ [text(marker)]
139
+ ),
140
+ ...line.children ?? []
141
+ ];
142
+ });
277
143
  });
278
144
  };
279
145
  }
@@ -286,169 +152,114 @@ function findFigure(ancestors) {
286
152
  return null;
287
153
  }
288
154
  function readPlan(code, pre, figure) {
289
- const fromAttribute = deserializeAnnotations(
290
- getStringProperty(code, "dataRbCodeAnnotations") ?? getStringProperty(code, "data-rb-code-annotations")
155
+ const fromAttribute = deserializeCodeDiff(
156
+ getStringProperty(code, "dataRbCodeDiff") ?? getStringProperty(code, "data-rb-code-diff")
291
157
  );
292
158
  if (fromAttribute) return fromAttribute;
293
- const metas = [getDataMeta(figure), getDataMeta(pre), getDataMeta(code)];
294
- for (const meta of metas) {
295
- const plan = extractAnnotationsMeta(meta);
159
+ for (const meta of [
160
+ getDataMeta(figure),
161
+ getDataMeta(pre),
162
+ getDataMeta(code)
163
+ ]) {
164
+ const plan = extractCodeDiffMeta(meta);
296
165
  if (plan) return plan;
297
166
  }
298
167
  return null;
299
168
  }
300
- function stripAnnotationsFromProperties(code) {
169
+ function stripDiffFromProperties(code) {
301
170
  if (!code.properties) return;
302
- delete code.properties["data-rb-code-annotations"];
303
- delete code.properties.dataRbCodeAnnotations;
171
+ delete code.properties["data-rb-code-diff"];
172
+ delete code.properties.dataRbCodeDiff;
304
173
  for (const key of ["data-meta", "dataMeta"]) {
305
174
  const value = code.properties[key];
306
175
  if (typeof value !== "string") continue;
307
- const stripped = removeAnnotationsMeta(value);
176
+ const stripped = removeCodeDiffMeta(value);
308
177
  if (stripped !== "") code.properties[key] = stripped;
309
178
  else delete code.properties[key];
310
179
  }
311
180
  }
312
- function applyPlan(code, pre, figure, plan, options) {
313
- const root = figure && getBooleanProperty(figure, "dataRehypePrettyCodeFigure") ? figure : pre;
314
- root.properties = {
315
- ...root.properties,
316
- className: mergeClassName(root.properties?.className, options.className)
317
- };
318
- const lines = getLineElements(code);
319
- if (lines.length > 0) {
320
- lines.forEach((line, index) => {
321
- applyLineClasses(line, index + 1, plan, options);
322
- });
323
- return;
324
- }
325
- const rawLines = getTextContent(code).replace(/\n$/, "").split("\n");
326
- const children = [];
327
- rawLines.forEach((lineText, index) => {
328
- const classNames = [
329
- options.lineClassName,
330
- ...annotationClassNames(index + 1, plan, options)
331
- ];
332
- children.push(
333
- element(
334
- "span",
335
- {
336
- className: classNames.join(" "),
337
- dataLine: String(index + 1)
338
- },
339
- [text(lineText)]
340
- )
341
- );
342
- if (index < rawLines.length - 1) children.push(text("\n"));
343
- });
344
- code.children = children;
345
- }
346
- function applyLineClasses(line, lineNumber, plan, options) {
347
- for (const name of annotationClassNames(lineNumber, plan, options)) {
348
- line.properties = {
349
- ...line.properties,
350
- className: mergeClassName(line.properties?.className, name)
351
- };
352
- }
353
- }
354
- function annotationClassNames(lineNumber, plan, options) {
355
- const names = [];
356
- if (plan.highlight.includes(lineNumber)) {
357
- names.push(options.highlightClassName);
358
- }
359
- if (plan.added.includes(lineNumber)) names.push(options.addedClassName);
360
- if (plan.removed.includes(lineNumber)) names.push(options.removedClassName);
361
- if (plan.focus.includes(lineNumber)) names.push(options.focusClassName);
362
- return names;
363
- }
364
181
  function getLineElements(code) {
365
182
  return (code.children ?? []).filter(isElementNode).filter((child) => {
366
183
  if (child.tagName !== "span") return false;
367
- if (hasProperty(child, "dataLine")) return true;
368
- const classNames = getClassNameList(child);
369
- return classNames.includes("line") || classNames.some((name) => name.endsWith("__line"));
184
+ return getBooleanProperty(child, "dataLine");
370
185
  });
371
186
  }
372
- function languageMatches(code, language) {
373
- if (!language) return true;
374
- return detectLanguage(code) === language;
375
- }
376
- function detectLanguage(code) {
377
- const explicit = getStringProperty(code, "dataLanguage") ?? getStringProperty(code, "data-language");
378
- if (explicit) return explicit;
379
- for (const name of getClassNameList(code)) {
380
- if (name.startsWith("language-")) return name.slice("language-".length);
381
- }
382
- return null;
187
+ function wrapCodeLines(code) {
188
+ const lines = (code.children ?? []).filter((child) => child.type === "text").flatMap(
189
+ (child) => child.value.replace(/\n$/, "").split("\n")
190
+ );
191
+ const wrapped = lines.map(
192
+ (line, index) => element(
193
+ "span",
194
+ { className: "rr-code__line", dataLine: String(index + 1) },
195
+ [text(line)]
196
+ )
197
+ );
198
+ code.children = wrapped.flatMap(
199
+ (line, index) => index < wrapped.length - 1 ? [line, text("\n")] : [line]
200
+ );
201
+ return wrapped;
383
202
  }
384
203
 
385
204
  // src/remark.ts
386
- function remarkCodeAnnotations(options = resolveCodeAnnotationsOptions()) {
205
+ function remarkCodeAnnotations() {
387
206
  return (tree) => {
388
207
  visitMdast(tree, (node) => {
389
- if (node.type !== "code" || typeof node.value !== "string") return;
390
- if (options.language !== void 0 && node.lang !== options.language) {
208
+ if (node.type !== "code" || node.lang !== "diff" || typeof node.value !== "string") {
391
209
  return;
392
210
  }
393
- const meta = typeof node.meta === "string" ? node.meta : null;
394
- const { plan, code, hasAnnotations: hasAnnotations2 } = collectCodeAnnotations(
395
- meta,
396
- node.value
397
- );
398
- if (!hasAnnotations2) return;
211
+ const language = parseTargetLanguage(node.meta);
212
+ if (!language) return;
213
+ const { code, plan } = collectCodeDiff(node.value);
214
+ node.lang = language;
399
215
  node.value = code;
400
216
  const hProperties = {
401
217
  ...node.data?.hProperties
402
218
  };
403
- hProperties["data-rb-code-annotations"] = serializeAnnotations(plan);
404
- const existingMeta = hProperties["data-meta"] ?? hProperties.dataMeta;
405
- hProperties["data-meta"] = typeof existingMeta === "string" && existingMeta !== "" ? appendAnnotationsMeta(existingMeta, plan) : encodeAnnotationsMeta(plan);
219
+ hProperties["data-rb-code-diff"] = serializeCodeDiff(plan);
220
+ hProperties["data-meta"] = appendCodeDiffMeta(node.meta, plan);
406
221
  node.data = { ...node.data ?? {}, hProperties };
407
222
  });
408
223
  };
409
224
  }
225
+ function parseTargetLanguage(meta) {
226
+ if (typeof meta !== "string") return null;
227
+ const language = meta.trim().split(/\s+/, 1)[0];
228
+ return language && /^[\w#+.-]+$/.test(language) ? language : null;
229
+ }
410
230
  function visitMdast(node, visitor) {
411
231
  visitor(node);
412
232
  for (const child of node.children ?? []) visitMdast(child, visitor);
413
233
  }
414
234
 
415
235
  // index.ts
416
- function codeAnnotations(options = {}) {
417
- const resolved = resolveCodeAnnotationsOptions(options);
236
+ function codeAnnotations() {
418
237
  return definePlugin({
419
238
  name: "code-annotations",
420
239
  order: 10,
421
240
  processedContentCache: {
422
- version: "code-annotations-v1",
241
+ version: "code-annotations-v2",
423
242
  dependencyMode: "none"
424
243
  },
425
- options: resolved,
426
244
  extendMarkdownPipeline: (pipeline) => {
427
- pipeline.use(remarkCodeAnnotations, resolved);
245
+ pipeline.use(remarkCodeAnnotations);
428
246
  },
429
247
  extendHtmlPipeline: (pipeline) => {
430
- pipeline.use(rehypeCodeAnnotations, resolved);
431
- },
432
- assets: [createStyleAsset("code-annotations")]
248
+ pipeline.use(rehypeCodeAnnotations);
249
+ }
433
250
  });
434
251
  }
435
252
  var codeAnnotationsPlugin = codeAnnotations;
436
253
  export {
437
- ANNOTATIONS_META_PREFIX,
438
- DEFAULT_CODE_ANNOTATIONS_OPTIONS,
254
+ appendCodeDiffMeta,
439
255
  codeAnnotations,
440
256
  codeAnnotationsPlugin,
441
- collectCodeAnnotations,
442
- createEmptyPlan,
443
- deserializeAnnotations,
444
- encodeAnnotationsMeta,
445
- extractAnnotationsMeta,
446
- hasAnnotations,
447
- parseCodeAnnotations,
448
- parseLineRanges,
257
+ collectCodeDiff,
258
+ deserializeCodeDiff,
259
+ encodeCodeDiffMeta,
260
+ extractCodeDiffMeta,
449
261
  rehypeCodeAnnotations,
450
262
  remarkCodeAnnotations,
451
- resolveCodeAnnotationsOptions,
452
- serializeAnnotations,
453
- stripInlineCodeAnnotation
263
+ removeCodeDiffMeta,
264
+ serializeCodeDiff
454
265
  };
@@ -1,48 +1,15 @@
1
- import type { CodeAnnotationKind, CodeAnnotationPlan } from "./types.js";
2
- /** Prefix used to smuggle a plan through the preserved fence meta channel. */
3
- export declare const ANNOTATIONS_META_PREFIX = "rb-annotations=";
4
- export declare function createEmptyPlan(): CodeAnnotationPlan;
5
- /**
6
- * Parse the highlight/focus specifiers of a code fence meta string.
7
- *
8
- * Docusaurus-style `{1,3-5}` groups become `highlight` lines. An optional
9
- * `focus:{1,2}` (or `focus={1,2}`) group becomes `focus` lines. Inline marker
10
- * comments are not part of the meta string and are handled by
11
- * {@link collectCodeAnnotations}.
12
- */
13
- export declare function parseCodeAnnotations(meta: string | null | undefined): CodeAnnotationPlan;
14
- /**
15
- * Parse a numeric range list such as `1,3-5` into sorted 1-based line numbers.
16
- */
17
- export declare function parseLineRanges(spec: string): number[];
18
- export type InlineCodeAnnotation = {
19
- kind: CodeAnnotationKind;
20
- lineCount: number;
1
+ export declare const DIFF_META_PREFIX = "rb-diff=";
2
+ export type DiffMarker = "+" | "-" | null;
3
+ export type CodeDiffPlan = {
4
+ markers: DiffMarker[];
21
5
  };
22
- /**
23
- * Remove a trailing `[!code ...]` marker comment from a line and report what
24
- * it annotated. The comment prefix may be `//`, `#`, `--`, or an HTML comment.
25
- */
26
- export declare function stripInlineCodeAnnotation(line: string): {
27
- line: string;
28
- annotation: InlineCodeAnnotation | null;
29
- };
30
- export type CollectedCodeAnnotations = {
31
- plan: CodeAnnotationPlan;
6
+ export declare function collectCodeDiff(code: string): {
32
7
  code: string;
33
- hasAnnotations: boolean;
8
+ plan: CodeDiffPlan;
34
9
  };
35
- /**
36
- * Parse fence meta and inline markers from a code block, returning the
37
- * annotation plan and the code text with marker comments removed.
38
- */
39
- export declare function collectCodeAnnotations(meta: string | null | undefined, code: string): CollectedCodeAnnotations;
40
- export declare function normalizePlan(plan: CodeAnnotationPlan): CodeAnnotationPlan;
41
- export declare function hasAnnotations(plan: CodeAnnotationPlan | null): boolean;
42
- export declare function serializeAnnotations(plan: CodeAnnotationPlan): string;
43
- export declare function deserializeAnnotations(value: unknown): CodeAnnotationPlan | null;
44
- export declare function encodeAnnotationsMeta(plan: CodeAnnotationPlan): string;
45
- export declare function appendAnnotationsMeta(meta: string | null | undefined, plan: CodeAnnotationPlan): string;
46
- export declare function extractAnnotationsMeta(meta: string | null | undefined): CodeAnnotationPlan | null;
47
- /** Remove an embedded plan token, keeping any surrounding fence meta. */
48
- export declare function removeAnnotationsMeta(meta: string | null | undefined): string;
10
+ export declare function serializeCodeDiff(plan: CodeDiffPlan): string;
11
+ export declare function deserializeCodeDiff(value: unknown): CodeDiffPlan | null;
12
+ export declare function encodeCodeDiffMeta(plan: CodeDiffPlan): string;
13
+ export declare function extractCodeDiffMeta(meta: string | null | undefined): CodeDiffPlan | null;
14
+ export declare function appendCodeDiffMeta(meta: string | null | undefined, plan: CodeDiffPlan): string;
15
+ export declare function removeCodeDiffMeta(meta: string | null | undefined): string;
@@ -1,8 +1,2 @@
1
- import type { HastNode, ResolvedCodeAnnotationsOptions } from "./types.js";
2
- /**
3
- * Materializes annotation plans recorded by {@link remarkCodeAnnotations}.
4
- * Reuses existing per-line wrappers (for example the ones emitted by
5
- * `rehype-pretty-code` through `@riebeckite/plugin-code-enhance`) and falls
6
- * back to wrapping raw `<code>` text into `rb-code__line` spans.
7
- */
8
- export declare function rehypeCodeAnnotations(options?: ResolvedCodeAnnotationsOptions): (tree: HastNode) => void;
1
+ import type { HastNode } from "./types.js";
2
+ export declare function rehypeCodeAnnotations(): (tree: HastNode) => void;
@@ -1,16 +1 @@
1
- import type { ResolvedCodeAnnotationsOptions } from "./types.js";
2
- /**
3
- * Reads the fence meta and inline `[!code ...]` markers of every code block,
4
- * strips the marker comments from the code text, and records the resulting
5
- * plan for the rehype stage.
6
- *
7
- * The plan travels through two properties:
8
- *
9
- * - `data-rb-code-annotations` is the primary channel and is read directly for
10
- * plain `<pre><code>` blocks.
11
- * - `data-meta` carries an encoded copy because
12
- * `rehype-pretty-code` (used by `@riebeckite/plugin-code-enhance`) replaces
13
- * the `<code>` element and drops its properties. code-enhance already reads
14
- * `data-meta`, so the copy survives on the generated `<figure>`.
15
- */
16
- export declare function remarkCodeAnnotations(options?: ResolvedCodeAnnotationsOptions): (tree: unknown) => void;
1
+ export declare function remarkCodeAnnotations(): (tree: unknown) => void;
@@ -1,44 +1,3 @@
1
- export type CodeAnnotationsOptions = {
2
- /**
3
- * Class applied to the code block root (`<pre>` or the
4
- * `rehype-pretty-code` `<figure>`). Defaults to `"rb-code"`.
5
- */
6
- className?: string;
7
- /**
8
- * Class applied to each generated line wrapper. Defaults to
9
- * `"rb-code__line"`. Existing line wrappers are not re-classed.
10
- */
11
- lineClassName?: string;
12
- /** Class applied to highlighted lines. Defaults to `"rb-code__line--highlighted"`. */
13
- highlightClassName?: string;
14
- /** Class applied to `++` lines. Defaults to `"rb-code__line--added"`. */
15
- addedClassName?: string;
16
- /** Class applied to `--` lines. Defaults to `"rb-code__line--removed"`. */
17
- removedClassName?: string;
18
- /** Class applied to focused lines. Defaults to `"rb-code__line--focused"`. */
19
- focusClassName?: string;
20
- /**
21
- * When set, annotations are only applied to code blocks whose detected
22
- * language matches this value. Unset by default.
23
- */
24
- language?: string;
25
- };
26
- export type ResolvedCodeAnnotationsOptions = {
27
- className: string;
28
- lineClassName: string;
29
- highlightClassName: string;
30
- addedClassName: string;
31
- removedClassName: string;
32
- focusClassName: string;
33
- language?: string;
34
- };
35
- export type CodeAnnotationPlan = {
36
- highlight: number[];
37
- added: number[];
38
- removed: number[];
39
- focus: number[];
40
- };
41
- export type CodeAnnotationKind = "highlight" | "added" | "removed" | "focus";
42
1
  export type ElementNode = {
43
2
  type: string;
44
3
  tagName?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riebeckite/plugin-code-annotations",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -11,15 +11,14 @@
11
11
  "import": "./dist/index.js",
12
12
  "source": "./index.ts",
13
13
  "default": "./dist/index.js"
14
- },
15
- "./style.css": "./style.css"
14
+ }
16
15
  },
17
16
  "dependencies": {
18
- "@riebeckite/core": "0.0.21"
17
+ "@riebeckite/core": "0.0.22"
19
18
  },
20
19
  "devDependencies": {
21
20
  "tsx": "^4.22.4",
22
- "@riebeckite/test": "0.0.21"
21
+ "@riebeckite/test": "0.0.22"
23
22
  },
24
23
  "publishConfig": {
25
24
  "access": "public"
@@ -28,8 +27,7 @@
28
27
  "LICENSE",
29
28
  "README.md",
30
29
  "README_ja.md",
31
- "dist",
32
- "style.css"
30
+ "dist"
33
31
  ],
34
32
  "repository": {
35
33
  "type": "git",
@@ -40,7 +38,7 @@
40
38
  "bugs": {
41
39
  "url": "https://github.com/Rerurate514/riebeckite/issues"
42
40
  },
43
- "description": "Code block annotations, highlights, and diff markers for Riebeckite.",
41
+ "description": "Syntax-highlighted diff code fences for Riebeckite.",
44
42
  "keywords": [
45
43
  "riebeckite",
46
44
  "plugin",
@@ -50,9 +48,7 @@
50
48
  "engines": {
51
49
  "node": "^20.19.0 || >=22.12.0"
52
50
  },
53
- "sideEffects": [
54
- "./style.css"
55
- ],
51
+ "sideEffects": false,
56
52
  "scripts": {
57
53
  "build": "node ../../../scripts/build_package.mjs",
58
54
  "test": "node --import tsx --test \"test/*.test.ts\""
@@ -1,10 +0,0 @@
1
- import type { CodeAnnotationsOptions, ResolvedCodeAnnotationsOptions } from "./types.js";
2
- export declare const DEFAULT_CODE_ANNOTATIONS_OPTIONS: {
3
- readonly className: "rb-code";
4
- readonly lineClassName: "rb-code__line";
5
- readonly highlightClassName: "rb-code__line--highlighted";
6
- readonly addedClassName: "rb-code__line--added";
7
- readonly removedClassName: "rb-code__line--removed";
8
- readonly focusClassName: "rb-code__line--focused";
9
- };
10
- export declare function resolveCodeAnnotationsOptions(options?: CodeAnnotationsOptions): ResolvedCodeAnnotationsOptions;
package/style.css DELETED
@@ -1,36 +0,0 @@
1
- .rb-code {
2
- --rb-code-annotation-accent: var(--rb-color-accent, #686868);
3
- position: relative;
4
- }
5
-
6
- .rb-code__line {
7
- display: block;
8
- min-width: 100%;
9
- }
10
-
11
- .rb-code__line--highlighted {
12
- background: color-mix(
13
- in srgb,
14
- var(--rb-code-annotation-accent) 14%,
15
- transparent
16
- );
17
- }
18
-
19
- .rb-code__line--added {
20
- background: color-mix(in srgb, #1f883d 14%, transparent);
21
- }
22
-
23
- .rb-code__line--removed {
24
- background: color-mix(in srgb, #cf222e 14%, transparent);
25
- }
26
-
27
- .rb-code__line--focused {
28
- background: color-mix(
29
- in srgb,
30
- var(--rb-code-annotation-accent) 10%,
31
- transparent
32
- );
33
- outline: 1px solid
34
- color-mix(in srgb, var(--rb-code-annotation-accent) 45%, transparent);
35
- outline-offset: -1px;
36
- }