feat: Restrict GitHub Actions to main branch and enhance settings for folder structure and asset handling
Some checks failed
Node.js build / build (20.x) (push) Failing after 22s
Node.js build / build (22.x) (push) Failing after 14m17s

This commit is contained in:
2026-04-21 18:22:45 +08:00
parent 113c3b668f
commit a5fceda7d0
4 changed files with 69 additions and 23 deletions

View File

@@ -2,9 +2,9 @@ name: Node.js build
on: on:
push: push:
branches: ["**"] branches: ["main"]
pull_request: pull_request:
branches: ["**"] branches: ["main"]
jobs: jobs:
build: build:

View File

@@ -95,11 +95,30 @@ export default class VitePressExporterPlugin extends Plugin {
// 1. 扫描并复制所有资源文件(传入文件对象用于路径解析) // 1. 扫描并复制所有资源文件(传入文件对象用于路径解析)
const updatedContent = await this.processAssets(content, file); const updatedContent = await this.processAssets(content, file);
// 2. 处理 canvas 引用(暂时保留,后续实现) // 2. 计算输出路径
// const finalContent = await this.processCanvases(updatedContent); let docsPath: string;
const fileNameWithoutExt = file.name.replace('.md', '');
const filePathWithoutExt = file.path.replace('.md', '');
// 3. 写入到 docs 目录(使用 binary 模式保留原始格式) if (this.settings.preserveFolderStructure && this.settings.nestNoteFolder) {
const docsPath = `${this.settings.docsPath}/${file.name}`; // 保留文件夹 + 嵌套: notes/some-note.md > docs/notes/some-note/index.md
docsPath = `${this.settings.docsPath}/${filePathWithoutExt}/index.md`;
} else if (this.settings.preserveFolderStructure) {
// 保留文件夹结构: notes/some-note.md > docs/notes/some-note.md
docsPath = `${this.settings.docsPath}/${file.path}`;
} else if (this.settings.nestNoteFolder) {
// 嵌套文件夹: notes/some-note.md > docs/some-note/index.md
docsPath = `${this.settings.docsPath}/${fileNameWithoutExt}/index.md`;
} else {
// 默认: notes/some-note.md > docs/some-note.md
docsPath = `${this.settings.docsPath}/${file.name}`;
}
// 3. 确保目标目录存在
const targetDir = docsPath.substring(0, docsPath.lastIndexOf('/'));
await vault.adapter.mkdir(targetDir);
// 4. 写入到 docs 目录(使用 binary 模式保留原始格式)
const updatedBuffer = new TextEncoder().encode(updatedContent); const updatedBuffer = new TextEncoder().encode(updatedContent);
await vault.adapter.writeBinary(docsPath, updatedBuffer.buffer); await vault.adapter.writeBinary(docsPath, updatedBuffer.buffer);
@@ -244,14 +263,17 @@ export default class VitePressExporterPlugin extends Plugin {
console.log('Trying to replace links for paths:', possiblePaths); console.log('Trying to replace links for paths:', possiblePaths);
// 替换 markdown 格式: ![](path) -> ![](assets/newfile.png) // 使用根路径: /image.png
const assetsRef = `/${newFileName}`;
// 替换 markdown 格式: ![](path) -> ![](/filename.png)
const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g;
content = content.replace(markdownRegex, (match, alt, path) => { content = content.replace(markdownRegex, (match, alt, path) => {
// 检查这个路径是否匹配我们的目标文件 // 检查这个路径是否匹配我们的目标文件
for (const testPath of possiblePaths) { for (const testPath of possiblePaths) {
if (path === testPath || path === testPath.replace(/^\//, '')) { if (path === testPath || path === testPath.replace(/^\//, '')) {
console.log(`Found matching link: ${path} -> ${this.settings.assetsPath}/${newFileName}`); console.log(`Found matching link: ${path} -> ${assetsRef}`);
return `![](${this.settings.assetsPath}/${newFileName})`; return `![](${assetsRef})`;
} }
} }
return match; return match;
@@ -265,8 +287,8 @@ export default class VitePressExporterPlugin extends Plugin {
for (const testPath of possiblePaths) { for (const testPath of possiblePaths) {
if (cleanLink === testPath || cleanLink === testPath.replace(/^\//, '')) { if (cleanLink === testPath || cleanLink === testPath.replace(/^\//, '')) {
console.log(`Found matching wikilink: ${cleanLink} -> ${this.settings.assetsPath}/${newFileName}`); console.log(`Found matching wikilink: ${cleanLink} -> ${assetsRef}`);
return `![[${this.settings.assetsPath}/${newFileName}]]`; return `![[${assetsRef}]]`;
} }
} }
return match; return match;
@@ -519,21 +541,23 @@ export default class VitePressExporterPlugin extends Plugin {
console.log('Trying to replace canvas links for paths:', possiblePaths); console.log('Trying to replace canvas links for paths:', possiblePaths);
// 替换 markdown 格式: !(canvas) -> <Viewer src="assets/image.png" /> // 使用根路径: /image.png
const assetsRef = `/${imageFileName}`;
// 替换 markdown 格式: !(canvas) -> <Viewer src="/image.png" />
const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; const markdownRegex = /!\[([^\]]*)\]\(([^)]+)\)/g;
content = content.replace(markdownRegex, (match, alt, path) => { content = content.replace(markdownRegex, (match, _alt, path) => {
// 检查这个路径是否匹配我们的 canvas 文件 // 检查这个路径是否匹配我们的 canvas 文件
for (const testPath of possiblePaths) { for (const testPath of possiblePaths) {
if (path === testPath || path === testPath.replace(/^\//, '')) { if (path === testPath || path === testPath.replace(/^\//, '')) {
const relativePath = this.settings.assetsPath.replace('docs/', ''); console.log(`Found matching canvas link: ${path} -> <Viewer src="${assetsRef}" />`);
console.log(`Found matching canvas link: ${path} -> <Viewer src="${relativePath}/${imageFileName}" />`); return `<Viewer src="${assetsRef}" />`;
return `<Viewer src="${relativePath}/${imageFileName}" />`;
} }
} }
return match; return match;
}); });
// 替换 wikilink 格式: ![[canvas]] -> <Viewer src="assets/image.png" /> // 替换 wikilink 格式: ![[canvas]] -> <Viewer src="/image.png" />
const wikilinkRegex = /!\[\[([^\]]+)\]\]/g; const wikilinkRegex = /!\[\[([^\]]+)\]\]/g;
content = content.replace(wikilinkRegex, (match, link) => { content = content.replace(wikilinkRegex, (match, link) => {
// 移除可能的别名字段 // 移除可能的别名字段
@@ -541,9 +565,8 @@ export default class VitePressExporterPlugin extends Plugin {
for (const testPath of possiblePaths) { for (const testPath of possiblePaths) {
if (cleanLink === testPath || cleanLink === testPath.replace(/^\//, '')) { if (cleanLink === testPath || cleanLink === testPath.replace(/^\//, '')) {
const relativePath = this.settings.assetsPath.replace('docs/', ''); console.log(`Found matching canvas wikilink: ${cleanLink} -> <Viewer src="${assetsRef}" />`);
console.log(`Found matching canvas wikilink: ${cleanLink} -> <Viewer src="${relativePath}/${imageFileName}" />`); return `<Viewer src="${assetsRef}" />`;
return `<Viewer src="${relativePath}/${imageFileName}" />`;
} }
} }
return match; return match;

View File

@@ -4,11 +4,15 @@ import VitePressExporterPlugin from "./main";
export interface VitePressExporterSettings { export interface VitePressExporterSettings {
docsPath: string; docsPath: string;
assetsPath: string; assetsPath: string;
nestNoteFolder: boolean;
preserveFolderStructure: boolean;
} }
export const DEFAULT_SETTINGS: VitePressExporterSettings = { export const DEFAULT_SETTINGS: VitePressExporterSettings = {
docsPath: 'docs', docsPath: 'docs',
assetsPath: 'docs/public' assetsPath: 'docs/public',
nestNoteFolder: true,
preserveFolderStructure: true
} }
// 设置面板 // 设置面板
@@ -48,5 +52,25 @@ export class VitePressExporterSettingTab extends PluginSettingTab {
this.plugin.settings.assetsPath = value; this.plugin.settings.assetsPath = value;
await this.plugin.saveSettings(); await this.plugin.saveSettings();
})); }));
new Setting(containerEl)
.setName('Nest note folder')
.setDesc('Create a folder for each note (e.g., notes/some-note.md > docs/some-note/index.md)')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.nestNoteFolder)
.onChange(async (value) => {
this.plugin.settings.nestNoteFolder = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName('Preserve folder structure')
.setDesc('Keep original folder structure (e.g., notes/some-note.md > docs/notes/some-note.md)')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.preserveFolderStructure)
.onChange(async (value) => {
this.plugin.settings.preserveFolderStructure = value;
await this.plugin.saveSettings();
}));
} }
} }

View File

@@ -1,6 +1,5 @@
{ {
"compilerOptions": { "compilerOptions": {
"ignoreDeprecations": "6.0",
"baseUrl": "src", "baseUrl": "src",
"inlineSourceMap": true, "inlineSourceMap": true,
"inlineSources": true, "inlineSources": true,