@dr-ishaan/rehype-perfect-code-blocks 1.1.5 → 1.1.6
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/dist/astro.d.ts.map +1 -1
- package/dist/astro.js +75 -40
- package/dist/astro.js.map +1 -1
- package/package.json +1 -1
- package/src/astro.ts +78 -44
package/dist/astro.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"astro.d.ts","sourceRoot":"","sources":["../src/astro.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAI9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"astro.d.ts","sourceRoot":"","sources":["../src/astro.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAI9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAuCrD,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,OAAO,GAAE,kBAAuB,GAC/B,gBAAgB,CAwFlB"}
|
package/dist/astro.js
CHANGED
|
@@ -20,6 +20,7 @@ import { rehypePerfectCodeBlocks } from './index.js';
|
|
|
20
20
|
import { remarkPreserveCodeMeta } from './remark.js';
|
|
21
21
|
import { COPY_SCRIPT } from './copy-script.js';
|
|
22
22
|
import { readFileSync } from 'node:fs';
|
|
23
|
+
import { readdirSync, writeFileSync, readFileSync as readFile } from 'node:fs';
|
|
23
24
|
import { fileURLToPath } from 'node:url';
|
|
24
25
|
import { dirname, join } from 'node:path';
|
|
25
26
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -36,6 +37,26 @@ function loadCss() {
|
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
}
|
|
40
|
+
/** Recursively walk a directory and return all .html file paths. */
|
|
41
|
+
function findHtmlFiles(dir) {
|
|
42
|
+
const results = [];
|
|
43
|
+
try {
|
|
44
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
const fullPath = join(dir, entry.name);
|
|
47
|
+
if (entry.isDirectory()) {
|
|
48
|
+
results.push(...findHtmlFiles(fullPath));
|
|
49
|
+
}
|
|
50
|
+
else if (entry.name.endsWith('.html')) {
|
|
51
|
+
results.push(fullPath);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Directory doesn't exist or can't be read
|
|
57
|
+
}
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
39
60
|
export default function perfectCode(options = {}) {
|
|
40
61
|
return {
|
|
41
62
|
name: 'rehype-perfect-code-blocks',
|
|
@@ -57,48 +78,62 @@ export default function perfectCode(options = {}) {
|
|
|
57
78
|
[rehypePerfectCodeBlocks, options],
|
|
58
79
|
],
|
|
59
80
|
},
|
|
60
|
-
// 2. Inject CSS + scripts via Vite's transformIndexHtml hook.
|
|
61
|
-
// We can't use Astro's injectScript() because Astro v5 tries to
|
|
62
|
-
// parse/execute the injected JS during build (SSR), which fails
|
|
63
|
-
// because `document` isn't available. transformIndexHtml just
|
|
64
|
-
// inserts raw HTML into <head>.
|
|
65
|
-
vite: {
|
|
66
|
-
plugins: [
|
|
67
|
-
{
|
|
68
|
-
name: 'rehype-perfect-code-blocks-inject',
|
|
69
|
-
transformIndexHtml(html) {
|
|
70
|
-
const injections = [];
|
|
71
|
-
// CSS
|
|
72
|
-
if (options.injectStyles !== false) {
|
|
73
|
-
const css = loadCss();
|
|
74
|
-
if (css) {
|
|
75
|
-
injections.push(`<style data-pcb>${css}</style>`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
// Copy-button script
|
|
79
|
-
if (options.copyButton !== false) {
|
|
80
|
-
injections.push(`<script>${COPY_SCRIPT}</script>`);
|
|
81
|
-
// Graceful degradation: .no-js class
|
|
82
|
-
if (options.hideCopyWithoutJs !== false) {
|
|
83
|
-
injections.push(`<script>document.documentElement.classList.add('no-js');</script>`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// Manual theme override
|
|
87
|
-
if (options.theme && options.theme !== 'auto') {
|
|
88
|
-
const safeTheme = ['dark', 'light'].includes(options.theme) ? options.theme : 'auto';
|
|
89
|
-
if (safeTheme !== 'auto') {
|
|
90
|
-
injections.push(`<script>document.documentElement.setAttribute('data-theme','${safeTheme}');</script>`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
if (injections.length === 0)
|
|
94
|
-
return html;
|
|
95
|
-
return html.replace('</head>', `${injections.join('\n')}</head>`);
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
],
|
|
99
|
-
},
|
|
100
81
|
});
|
|
101
82
|
},
|
|
83
|
+
'astro:build:done': ({ dir }) => {
|
|
84
|
+
// 2. After Astro finishes building all pages, inject CSS + scripts
|
|
85
|
+
// into every generated .html file. This is the most reliable
|
|
86
|
+
// method — it works with Astro v4, v5, static and SSR modes,
|
|
87
|
+
// and doesn't require the user to import anything in their layout.
|
|
88
|
+
const injections = [];
|
|
89
|
+
// CSS
|
|
90
|
+
if (options.injectStyles !== false) {
|
|
91
|
+
const css = loadCss();
|
|
92
|
+
if (css) {
|
|
93
|
+
injections.push(`<style data-pcb>${css}</style>`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Copy-button script
|
|
97
|
+
if (options.copyButton !== false) {
|
|
98
|
+
injections.push(`<script>${COPY_SCRIPT}</script>`);
|
|
99
|
+
// Graceful degradation: .no-js class
|
|
100
|
+
if (options.hideCopyWithoutJs !== false) {
|
|
101
|
+
injections.push(`<script>document.documentElement.classList.add('no-js');</script>`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Manual theme override
|
|
105
|
+
if (options.theme && options.theme !== 'auto') {
|
|
106
|
+
const safeTheme = ['dark', 'light'].includes(options.theme) ? options.theme : 'auto';
|
|
107
|
+
if (safeTheme !== 'auto') {
|
|
108
|
+
injections.push(`<script>document.documentElement.setAttribute('data-theme','${safeTheme}');</script>`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (injections.length === 0)
|
|
112
|
+
return;
|
|
113
|
+
const injectionHtml = injections.join('\n');
|
|
114
|
+
const outputDir = fileURLToPath(dir);
|
|
115
|
+
const htmlFiles = findHtmlFiles(outputDir);
|
|
116
|
+
for (const htmlFile of htmlFiles) {
|
|
117
|
+
try {
|
|
118
|
+
const html = readFile(htmlFile, 'utf8');
|
|
119
|
+
// Inject before </head>. If no </head> (rare), inject after <html...>.
|
|
120
|
+
let updated;
|
|
121
|
+
if (html.includes('</head>')) {
|
|
122
|
+
updated = html.replace('</head>', `${injectionHtml}</head>`);
|
|
123
|
+
}
|
|
124
|
+
else if (html.includes('<body')) {
|
|
125
|
+
updated = html.replace('<body', `${injectionHtml}<body`);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
updated = injectionHtml + html;
|
|
129
|
+
}
|
|
130
|
+
writeFileSync(htmlFile, updated);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// Skip files that can't be read/written
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
},
|
|
102
137
|
},
|
|
103
138
|
};
|
|
104
139
|
}
|
package/dist/astro.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"astro.js","sourceRoot":"","sources":["../src/astro.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,SAAS,OAAO;IACd,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,UAA8B,EAAE;IAEhC,OAAO;QACL,IAAI,EAAE,4BAA4B;QAClC,KAAK,EAAE;YACL,oBAAoB,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE;gBACzC,sEAAsE;gBACtE,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;gBACtD,YAAY,CAAC;oBACX,QAAQ,EAAE;wBACR,eAAe,EAAE,OAAO;wBACxB,WAAW,EACT,OAAO,OAAO,CAAC,KAAK,EAAE,KAAK,KAAK,QAAQ;4BACtC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE;4BAChC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK;gCACpB,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE;gCACjC,CAAC,CAAC,SAAS;wBACjB,aAAa,EAAE,CAAC,sBAAsB,CAAC;wBACvC,aAAa,EAAE;4BACb,GAAI,iBAA+B;4BACnC,CAAC,uBAAuB,EAAE,OAAO,CAAC;yBAC1B;qBACX;
|
|
1
|
+
{"version":3,"file":"astro.js","sourceRoot":"","sources":["../src/astro.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dr-ishaan/rehype-perfect-code-blocks",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"description": "Beautiful, configurable code blocks for Astro / MDX / any rehype pipeline. Built on Shiki, inspired by rehype-pretty-code, VitePress, Docusaurus, and Expressive Code.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
package/src/astro.ts
CHANGED
|
@@ -23,6 +23,7 @@ import { remarkPreserveCodeMeta } from './remark.js';
|
|
|
23
23
|
import { COPY_SCRIPT } from './copy-script.js';
|
|
24
24
|
import type { PerfectCodeOptions } from './types.js';
|
|
25
25
|
import { readFileSync } from 'node:fs';
|
|
26
|
+
import { readdirSync, writeFileSync, readFileSync as readFile } from 'node:fs';
|
|
26
27
|
import { fileURLToPath } from 'node:url';
|
|
27
28
|
import { dirname, join } from 'node:path';
|
|
28
29
|
|
|
@@ -40,6 +41,25 @@ function loadCss(): string {
|
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
/** Recursively walk a directory and return all .html file paths. */
|
|
45
|
+
function findHtmlFiles(dir: string): string[] {
|
|
46
|
+
const results: string[] = [];
|
|
47
|
+
try {
|
|
48
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
const fullPath = join(dir, entry.name);
|
|
51
|
+
if (entry.isDirectory()) {
|
|
52
|
+
results.push(...findHtmlFiles(fullPath));
|
|
53
|
+
} else if (entry.name.endsWith('.html')) {
|
|
54
|
+
results.push(fullPath);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} catch {
|
|
58
|
+
// Directory doesn't exist or can't be read
|
|
59
|
+
}
|
|
60
|
+
return results;
|
|
61
|
+
}
|
|
62
|
+
|
|
43
63
|
export default function perfectCode(
|
|
44
64
|
options: PerfectCodeOptions = {}
|
|
45
65
|
): AstroIntegration {
|
|
@@ -64,55 +84,69 @@ export default function perfectCode(
|
|
|
64
84
|
[rehypePerfectCodeBlocks, options],
|
|
65
85
|
] as never,
|
|
66
86
|
},
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// parse/execute the injected JS during build (SSR), which fails
|
|
70
|
-
// because `document` isn't available. transformIndexHtml just
|
|
71
|
-
// inserts raw HTML into <head>.
|
|
72
|
-
vite: {
|
|
73
|
-
plugins: [
|
|
74
|
-
{
|
|
75
|
-
name: 'rehype-perfect-code-blocks-inject',
|
|
76
|
-
transformIndexHtml(html: string) {
|
|
77
|
-
const injections: string[] = [];
|
|
87
|
+
});
|
|
88
|
+
},
|
|
78
89
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
90
|
+
'astro:build:done': ({ dir }) => {
|
|
91
|
+
// 2. After Astro finishes building all pages, inject CSS + scripts
|
|
92
|
+
// into every generated .html file. This is the most reliable
|
|
93
|
+
// method — it works with Astro v4, v5, static and SSR modes,
|
|
94
|
+
// and doesn't require the user to import anything in their layout.
|
|
95
|
+
const injections: string[] = [];
|
|
86
96
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
// CSS
|
|
98
|
+
if (options.injectStyles !== false) {
|
|
99
|
+
const css = loadCss();
|
|
100
|
+
if (css) {
|
|
101
|
+
injections.push(`<style data-pcb>${css}</style>`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
90
104
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
`<script>document.documentElement.classList.add('no-js');</script>`
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
105
|
+
// Copy-button script
|
|
106
|
+
if (options.copyButton !== false) {
|
|
107
|
+
injections.push(`<script>${COPY_SCRIPT}</script>`);
|
|
98
108
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
}
|
|
109
|
+
// Graceful degradation: .no-js class
|
|
110
|
+
if (options.hideCopyWithoutJs !== false) {
|
|
111
|
+
injections.push(
|
|
112
|
+
`<script>document.documentElement.classList.add('no-js');</script>`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
108
116
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
// Manual theme override
|
|
118
|
+
if (options.theme && options.theme !== 'auto') {
|
|
119
|
+
const safeTheme = ['dark', 'light'].includes(options.theme) ? options.theme : 'auto';
|
|
120
|
+
if (safeTheme !== 'auto') {
|
|
121
|
+
injections.push(
|
|
122
|
+
`<script>document.documentElement.setAttribute('data-theme','${safeTheme}');</script>`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (injections.length === 0) return;
|
|
128
|
+
|
|
129
|
+
const injectionHtml = injections.join('\n');
|
|
130
|
+
const outputDir = fileURLToPath(dir);
|
|
131
|
+
const htmlFiles = findHtmlFiles(outputDir);
|
|
132
|
+
|
|
133
|
+
for (const htmlFile of htmlFiles) {
|
|
134
|
+
try {
|
|
135
|
+
const html = readFile(htmlFile, 'utf8');
|
|
136
|
+
// Inject before </head>. If no </head> (rare), inject after <html...>.
|
|
137
|
+
let updated: string;
|
|
138
|
+
if (html.includes('</head>')) {
|
|
139
|
+
updated = html.replace('</head>', `${injectionHtml}</head>`);
|
|
140
|
+
} else if (html.includes('<body')) {
|
|
141
|
+
updated = html.replace('<body', `${injectionHtml}<body`);
|
|
142
|
+
} else {
|
|
143
|
+
updated = injectionHtml + html;
|
|
144
|
+
}
|
|
145
|
+
writeFileSync(htmlFile, updated);
|
|
146
|
+
} catch {
|
|
147
|
+
// Skip files that can't be read/written
|
|
148
|
+
}
|
|
149
|
+
}
|
|
116
150
|
},
|
|
117
151
|
},
|
|
118
152
|
};
|