@dr-ishaan/rehype-perfect-code-blocks 1.1.4 → 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 +67 -25
- package/dist/astro.js.map +1 -1
- package/package.json +1 -1
- package/src/astro.ts +67 -28
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,11 +37,31 @@ 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',
|
|
42
63
|
hooks: {
|
|
43
|
-
'astro:config:setup': ({ updateConfig
|
|
64
|
+
'astro:config:setup': ({ updateConfig }) => {
|
|
44
65
|
// 1. Register the remark + rehype plugins with the Markdown pipeline.
|
|
45
66
|
const userRehypePlugins = options.rehypePlugins ?? [];
|
|
46
67
|
updateConfig({
|
|
@@ -57,38 +78,59 @@ export default function perfectCode(options = {}) {
|
|
|
57
78
|
[rehypePerfectCodeBlocks, options],
|
|
58
79
|
],
|
|
59
80
|
},
|
|
60
|
-
// 2. Inject CSS via a Vite plugin (not injectScript, which is JS-only
|
|
61
|
-
// in Astro v5+). The transformIndexHtml hook inserts a <style>
|
|
62
|
-
// tag into every page's <head>.
|
|
63
|
-
vite: {
|
|
64
|
-
plugins: [
|
|
65
|
-
{
|
|
66
|
-
name: 'rehype-perfect-code-blocks-css',
|
|
67
|
-
transformIndexHtml(html) {
|
|
68
|
-
if (options.injectStyles === false)
|
|
69
|
-
return html;
|
|
70
|
-
const css = loadCss();
|
|
71
|
-
if (!css)
|
|
72
|
-
return html;
|
|
73
|
-
return html.replace('</head>', `<style data-pcb>${css}</style></head>`);
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
],
|
|
77
|
-
},
|
|
78
81
|
});
|
|
79
|
-
|
|
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
|
|
80
97
|
if (options.copyButton !== false) {
|
|
81
|
-
|
|
82
|
-
//
|
|
98
|
+
injections.push(`<script>${COPY_SCRIPT}</script>`);
|
|
99
|
+
// Graceful degradation: .no-js class
|
|
83
100
|
if (options.hideCopyWithoutJs !== false) {
|
|
84
|
-
|
|
101
|
+
injections.push(`<script>document.documentElement.classList.add('no-js');</script>`);
|
|
85
102
|
}
|
|
86
103
|
}
|
|
87
|
-
//
|
|
104
|
+
// Manual theme override
|
|
88
105
|
if (options.theme && options.theme !== 'auto') {
|
|
89
106
|
const safeTheme = ['dark', 'light'].includes(options.theme) ? options.theme : 'auto';
|
|
90
107
|
if (safeTheme !== 'auto') {
|
|
91
|
-
|
|
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
|
|
92
134
|
}
|
|
93
135
|
}
|
|
94
136
|
},
|
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,
|
|
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,13 +41,32 @@ 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 {
|
|
46
66
|
return {
|
|
47
67
|
name: 'rehype-perfect-code-blocks',
|
|
48
68
|
hooks: {
|
|
49
|
-
'astro:config:setup': ({ updateConfig
|
|
69
|
+
'astro:config:setup': ({ updateConfig }) => {
|
|
50
70
|
// 1. Register the remark + rehype plugins with the Markdown pipeline.
|
|
51
71
|
const userRehypePlugins = options.rehypePlugins ?? [];
|
|
52
72
|
updateConfig({
|
|
@@ -64,50 +84,69 @@ export default function perfectCode(
|
|
|
64
84
|
[rehypePerfectCodeBlocks, options],
|
|
65
85
|
] as never,
|
|
66
86
|
},
|
|
67
|
-
// 2. Inject CSS via a Vite plugin (not injectScript, which is JS-only
|
|
68
|
-
// in Astro v5+). The transformIndexHtml hook inserts a <style>
|
|
69
|
-
// tag into every page's <head>.
|
|
70
|
-
vite: {
|
|
71
|
-
plugins: [
|
|
72
|
-
{
|
|
73
|
-
name: 'rehype-perfect-code-blocks-css',
|
|
74
|
-
transformIndexHtml(html: string) {
|
|
75
|
-
if (options.injectStyles === false) return html;
|
|
76
|
-
const css = loadCss();
|
|
77
|
-
if (!css) return html;
|
|
78
|
-
return html.replace(
|
|
79
|
-
'</head>',
|
|
80
|
-
`<style data-pcb>${css}</style></head>`
|
|
81
|
-
);
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
},
|
|
86
87
|
});
|
|
88
|
+
},
|
|
89
|
+
|
|
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[] = [];
|
|
87
96
|
|
|
88
|
-
//
|
|
97
|
+
// CSS
|
|
98
|
+
if (options.injectStyles !== false) {
|
|
99
|
+
const css = loadCss();
|
|
100
|
+
if (css) {
|
|
101
|
+
injections.push(`<style data-pcb>${css}</style>`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Copy-button script
|
|
89
106
|
if (options.copyButton !== false) {
|
|
90
|
-
|
|
107
|
+
injections.push(`<script>${COPY_SCRIPT}</script>`);
|
|
91
108
|
|
|
92
|
-
//
|
|
109
|
+
// Graceful degradation: .no-js class
|
|
93
110
|
if (options.hideCopyWithoutJs !== false) {
|
|
94
|
-
|
|
95
|
-
'page',
|
|
111
|
+
injections.push(
|
|
96
112
|
`<script>document.documentElement.classList.add('no-js');</script>`
|
|
97
113
|
);
|
|
98
114
|
}
|
|
99
115
|
}
|
|
100
116
|
|
|
101
|
-
//
|
|
117
|
+
// Manual theme override
|
|
102
118
|
if (options.theme && options.theme !== 'auto') {
|
|
103
119
|
const safeTheme = ['dark', 'light'].includes(options.theme) ? options.theme : 'auto';
|
|
104
120
|
if (safeTheme !== 'auto') {
|
|
105
|
-
|
|
106
|
-
'page',
|
|
121
|
+
injections.push(
|
|
107
122
|
`<script>document.documentElement.setAttribute('data-theme','${safeTheme}');</script>`
|
|
108
123
|
);
|
|
109
124
|
}
|
|
110
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
|
+
}
|
|
111
150
|
},
|
|
112
151
|
},
|
|
113
152
|
};
|