1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
| const PARENT_FOLDER = "Parent folder";
const START_AT = "Start at";
const PAD_WIDTH = "Pad width";
const INDEX_NAME = "Index file name";
const TEMPLATE = "Template content";
function pad(num, width) {
return String(num).padStart(width, "0");
}
async function ensureFolder(app, path) {
const parts = path.split("/").filter(Boolean);
let current = "";
for (const part of parts) {
current = current ? `${current}/${part}` : part;
const existing = app.vault.getAbstractFileByPath(current);
if (!existing) {
await app.vault.createFolder(current);
}
}
}
function formatNow(fmt) {
if (typeof window !== "undefined" && window.moment) {
return window.moment().format(fmt);
}
const d = new Date();
const yyyy = d.getFullYear();
const mm = String(d.getMonth() + 1).padStart(2, "0");
const dd = String(d.getDate()).padStart(2, "0");
const hh = String(d.getHours()).padStart(2, "0");
const mi = String(d.getMinutes()).padStart(2, "0");
if (fmt === "YYYY-MM-DD") return `${yyyy}-${mm}-${dd}`;
if (fmt === "YYYY-MM-DD HH:mm") return `${yyyy}-${mm}-${dd} ${hh}:${mi}`;
return `${yyyy}-${mm}-${dd}`;
}
module.exports = {
entry: async (params, settings) => {
const { app } = params;
const parentFolder = String(settings[PARENT_FOLDER] || "").trim().replace(/^\/+|\/+$/g, "");
if (!parentFolder) {
throw new Error("Parent folder 不能为空");
}
const startAt = Number(settings[START_AT] ?? 1);
const padWidth = Number(settings[PAD_WIDTH] ?? 3);
const indexName = String(settings[INDEX_NAME] || "index").trim() || "index";
const template = String(settings[TEMPLATE] || "");
await ensureFolder(app, parentFolder);
const parent = app.vault.getAbstractFileByPath(parentFolder);
if (!parent || !Array.isArray(parent.children)) {
throw new Error(`找不到目标目录:${parentFolder}`);
}
const existingNumbers = parent.children
.filter((child) => Array.isArray(child.children)) // 只要子文件夹
.map((child) => child.name)
.filter((name) => /^\d+$/.test(name))
.map((name) => Number(name));
let nextNumber = existingNumbers.length > 0
? Math.max(...existingNumbers) + 1
: startAt;
let folderName = pad(nextNumber, padWidth);
let newFolderPath = `${parentFolder}/${folderName}`;
while (app.vault.getAbstractFileByPath(newFolderPath)) {
nextNumber += 1;
folderName = pad(nextNumber, padWidth);
newFolderPath = `${parentFolder}/${folderName}`;
}
await app.vault.createFolder(newFolderPath);
const content = template
.replace(/{{NUM}}/g, folderName)
.replace(/{{RAW_NUM}}/g, String(nextNumber))
.replace(/{{DATE}}/g, formatNow("YYYY-MM-DD"))
.replace(/{{DATETIME}}/g, formatNow("YYYY-MM-DD HH:mm"))
.replace(/{{FOLDER_PATH}}/g, newFolderPath);
const filePath = `${newFolderPath}/${indexName}.md`;
const file = await app.vault.create(filePath, content);
await app.workspace.getLeaf(true).openFile(file);
},
settings: {
name: "New Numbered Folder",
author: "LiuJason",
options: {
[PARENT_FOLDER]: {
type: "text",
defaultValue: "Projects",
placeholder: "例如:Projects/Active",
description: "新文件夹要创建到哪个父目录下",
},
[START_AT]: {
type: "text",
defaultValue: "1",
placeholder: "1",
description: "如果还没有数字文件夹,就从几开始",
},
[PAD_WIDTH]: {
type: "text",
defaultValue: "3",
placeholder: "3",
description: "编号补零位数;3 = 001, 002, 003",
},
[INDEX_NAME]: {
type: "text",
defaultValue: "index",
placeholder: "index",
description: "自动创建的 markdown 文件名,不带 .md",
},
[TEMPLATE]: {
type: "textarea",
defaultValue:
`---
title:
url: /post/{{NUM}}.html
date: {{DATETIME}}
draft: false
image:
description:
tags:
categories:
toc: true
comment: true
---
`,
description: "index.md 的初始内容;支持 {{NUM}} {{RAW_NUM}} {{DATE}} {{DATETIME}} {{FOLDER_PATH}}",
},
},
},
};
|