rspress-plugin-code-block
Version:
Rspress plugin to import and display file contents as code blocks
137 lines (136 loc) • 5.67 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.codeBlockPlugin = codeBlockPlugin;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
// 使用Rspress提供的内置工具函数
function codeBlockPlugin() {
return {
name: 'rspress-plugin-code-block',
markdown: {
remarkPlugins: [
function () {
// 使用Rspress内置的visit函数
const visit = (tree, type, callback) => {
if (tree.type === type) {
callback(tree);
}
if (tree.children) {
tree.children.forEach((child) => visit(child, type, callback));
}
};
return (tree, file) => {
visit(tree, 'mdxJsxFlowElement', (node) => {
// 检查是否是CodeBlock组件
if (node.name === 'CodeBlock') {
const srcAttr = node.attributes?.find(attr => attr.name === 'src');
const languageAttr = node.attributes?.find(attr => attr.name === 'language');
if (srcAttr) {
const srcPath = srcAttr.value;
const currentDir = path.dirname(file.path);
const fullPath = path.resolve(currentDir, srcPath);
try {
const content = fs.readFileSync(fullPath, 'utf-8');
// 获取语言
let language = '';
if (languageAttr) {
language = languageAttr.value;
}
else {
const ext = path.extname(fullPath).slice(1);
language = getLanguageFromExtension(ext);
}
// 将CodeBlock组件替换为代码块
const newNode = {
type: 'code',
lang: language,
meta: null,
value: content
};
// 替换节点
Object.assign(node, newNode);
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
node.type = 'code';
node.lang = '';
node.value = `<!-- 文件读取失败: ${srcPath} - ${errorMessage} -->`;
}
}
}
});
};
}
]
}
};
}
function getLanguageFromExtension(ext) {
const extensionMap = {
'js': 'javascript',
'jsx': 'javascript',
'ts': 'typescript',
'tsx': 'typescript',
'py': 'python',
'java': 'java',
'cpp': 'cpp',
'c': 'c',
'cs': 'csharp',
'php': 'php',
'rb': 'ruby',
'go': 'go',
'rs': 'rust',
'swift': 'swift',
'kt': 'kotlin',
'scala': 'scala',
'html': 'html',
'css': 'css',
'scss': 'scss',
'sass': 'sass',
'less': 'less',
'json': 'json',
'xml': 'xml',
'yaml': 'yaml',
'yml': 'yaml',
'md': 'markdown',
'sh': 'bash',
'sql': 'sql',
'dockerfile': 'dockerfile',
'vue': 'vue',
'svelte': 'svelte',
};
return extensionMap[ext] || ext;
}