一、基本信息

《意识之道》智能文章创建脚本

作者:道祖

文件名:newpost.ps1

编程语言:PowerShell

功能:创建新文章时自动分类与自动保存至相应的分类文件夹下

作者:道祖

版本:v1.01

日期:2026-02-04 00:10

更新日期:2026-02-16 01:35

二、使用示例

1、默认分类与默认标题

默认分类为道祖之道,默认标题为某年某月某日某时某分,自动分类至对应的分类文件夹,且在创建以年为单位的子文件夹,直接在powershell命令行中使用“.\newpost.ps1”,无需指定分类和标题。

1
2
3

.\newpost.ps1

2、指定分类与指定标题

指定分类需要有对应的本地分类文件夹,即在“source/_posts/categories/”下有对应的分类文件夹,其分类的层级就是文件夹的目录树;若指定的分类与指定的标题相同,那么将会在该目录下创建“index.md”文章,以作为本分类的总体规划性文章内容。

1
2
3

.\newpost.ps1 -category "网站构建" -title "构建日志"

三、源代码

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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341

# ============================================
### 《意识之道》智能文章创建脚本
### 作者:道祖
### 文件名:newpost.ps1
### 编程语言:PowerShell
### 功能:创建新文章时自动分类与自动保存至相应的分类文件夹下
### 作者:道祖
### 版本:v1.02
### 日期:2026-02-04 00:10
### 更新日期:2026-02-16 01:35
# ============================================



param(
[Parameter(Mandatory=$false, Position=0)]
[string]$category = "道祖之道",

[Parameter(Mandatory=$false, Position=1)]
[string]$title,

[Parameter(Mandatory=$false)]
[string]$writedate,

[Parameter(Mandatory=$false)]
[switch]$ShowDetails
)

# 导入模块
$modulesDir = "./psm-modules"
$modules = @(
"$modulesDir\CategoryMap.psm1",
"$modulesDir\FolderTree.psm1",
"$modulesDir\PathConverter.psm1"
)
foreach ($module in $modules) {
if (Test-Path $module) {
try {
Import-Module $module -Force -ErrorAction Stop
if ($ShowDetails) {
Write-Host "✅ 导入模块: $(Split-Path $module -Leaf)" -ForegroundColor Green
}
}
catch {
Write-Host "❌ 无法导入模块 $module : $_" -ForegroundColor Red
exit 1
}
}
else {
Write-Host "❌ 模块文件不存在: $module" -ForegroundColor Red
Write-Host "请确保以下模块文件存在:" -ForegroundColor Yellow
$modules | ForEach-Object { Write-Host " • $_" -ForegroundColor Gray }
exit 1
}
}

# 1. 加载分类映射
$categoryMap = Get-CategoryMap -Silent:(!$ShowDetails)
if ($categoryMap.Count -eq 0) {
Write-Host "❌ 无法加载分类映射" -ForegroundColor Red
exit 1
}

# 2. 扫描目录结构
$tree = Get-FolderTree -RootPath "source/_posts" -Silent:(!$ShowDetails)
if (-not $tree) {
Write-Host "❌ 无法扫描目录结构" -ForegroundColor Red
exit 1
}

$defcategory=$category -eq "道祖之道"

# 获取分类文件夹路径
function Get-foundFolder {
$foundFolders = $tree.Find($category)
if ($foundFolders -and $foundFolders.Count -gt 0) {
if ($foundFolders.Count -gt 1) {
if ($ShowDetails) {
Write-Host "⚠️ 找到多个匹配的文件夹,使用第一个" -ForegroundColor Yellow
$foundFolders | ForEach-Object { Write-Host " • $_" -ForegroundColor Gray }
}
$foundFolder = $foundFolders[0]
}
else {
$foundFolder = $foundFolders
}
return $foundFolder

}
else{
Write-Host "❌ 未找到包含 '$category' 的分类文件夹" -ForegroundColor Red

# 显示可用的分类映射
if ($categoryMap.Count -gt 0) {
Write-Host "`n📋 可用的分类映射:" -ForegroundColor Yellow

# 按分组显示
$groups = @{
"道经卷" = $categoryMap.Keys | Where-Object { $_ -match "^道经卷|法则篇|道演篇" }
"道境卷" = $categoryMap.Keys | Where-Object { $_ -match "^道境卷|道境之门|境界论述|实修根本|实修经|实修理术" }
"实践方向" = $categoryMap.Keys | Where-Object { $_ -match "^实践方向|哲学之道|科学之道|技术之道|道祖之道" }
"其他" = $categoryMap.Keys | Where-Object { $_ -notmatch "^道经卷|道境卷|实践方向" }
}

foreach ($groupKey in $groups.Keys) {
if ($groups[$groupKey].Count -gt 0) {
Write-Host "`n ${groupKey}:" -ForegroundColor Cyan
$groups[$groupKey] | Sort-Object | ForEach-Object {
Write-Host " • $_$($categoryMap[$_])" -ForegroundColor DarkGray
}
}
}
}

# 显示顶层文件夹
Write-Host "`n📁 可用的顶层文件夹:" -ForegroundColor Yellow

# 添加GetSubfolders方法到$tree对象(如果不存在)
if (-not ($tree | Get-Member -Name GetSubfolders -MemberType ScriptMethod)) {
$tree | Add-Member -MemberType ScriptMethod -Name GetSubfolders -Value {
param([string]$ParentPath)
if (-not $ParentPath) {
return $this.AllFolders | Where-Object { $_ -notmatch "/" }
}
$this.AllFolders | Where-Object { $_ -like "$ParentPath/*" -and $_ -ne $ParentPath }
}
}

$topLevelFolders = $tree.GetSubfolders("")
if ($topLevelFolders) {
$topLevelFolders | ForEach-Object { Write-Host " • $_" -ForegroundColor Gray }
}
exit 0
}

}

# 获取自定写作时间
function Get-WriteDate{
if (-not [string]::IsNullOrEmpty($writedate)) {
if ($writedate.Length -ne 12 -or $writedate -notmatch '^\d+$') {
Write-Error "参数格式错误:必须为12位数字 (yyyyMMddHHmm)"
exit 1
}
try {
# 解析为 DateTime 对象
$date= [datetime]::ParseExact($writedate, "yyyyMMddHHmm", $null)
$writingDate=$date.AddHours(-8).ToString("yyyy-MM-dd HH:mm:ss")
return $date,$writingDate
} catch {
Write-Error "无效的日期时间值:$writedate"
exit 1
}
}else{
$writingDate="{{ date }}"
$date=Get-Date
return $date,$writingDate
}
}


# 获取文章信息,处理 Front-matter
function Get-PostInfo {


$now,$writingDate = Get-WriteDate

# 处理文章标题
# 若标题为空,则以日期为标题
if ([string]::IsNullOrEmpty($title)) {
$title = "$($now.Year)年$($now.Month)月$($now.Day)日$($now.Hour)时$($now.Minute)分"
Write-Host "默认标题: $title" -ForegroundColor Yellow
}

if($defcategory){Write-Host "默认分类: $category" -ForegroundColor Yellow}

if ($category -eq $title) {
$posturl = "index"
} else {
# 使用时间戳作为URL的一部分,确保唯一性
$timestamp = [DateTimeOffset]::Now.ToUnixTimeMilliseconds()
$posturl = "$timestamp"
}
$PostTitle = $title

# 获取创建文章的分类文件夹路径
$foundFolder=Get-foundFolder

# 构建分类字符串,除去根节点categonries
$categories=$foundFolder
$categories=$categories.Replace($($tree.GetSubfolders("")+"/"),"[")
$categories=$categories.Replace("/",",")+"]"
$categories="categories: $categories"

#处理默认路径
if($defcategory){
$foundFolder="$foundFolder/$($now.Year)/$($now.Month)"
Write-Host "默认路径: $foundFolder" -ForegroundColor Yellow
}

# 构建永久链接
$permalink = Convert-PathToEnglish -RelativePath $foundFolder -CategoryMap $categoryMap
$permalinkPath = "permalink: /$permalink/$posturl/"

# 默认首页不显示,自定义字段
$hide = "hide: ture"

# 写作日期

#$writingDate = $now.AddHours(-8).ToString("yyyy-MM-dd HH:mm:ss")
return $foundFolder,$PostTitle,$categories,$permalinkPath,$hide,$writingDate
}


# 文章模板处理
function Set-ProcScaffold {
param(
[string]$PostTitle,
[string]$writingDate,
[string]$categories,
[string]$permalinkPath,
[string]$hide
)

# 不改变原有模板,创建新的模板进行处理
$postTemplate = "post.md"
$newTemplate = "newpost.md"
$templatePath = Join-Path (Get-Location) "scaffolds\$postTemplate"
$newTemplatePath = Join-Path (Get-Location) "scaffolds\$newTemplate"

if (Test-Path $templatePath) {
# 复制模板
Copy-Item $templatePath $newTemplatePath -Force

# 更新模板内容
$templateContent = Get-Content $newTemplatePath

# 替换title(如果模板中有占位符)
if ($templateContent -match 'title:\s*{{ title }}') {
$templateContent = $templateContent -replace 'title:\s*{{ title }}', "title: $PostTitle"
}
if ($templateContent -match 'writing_date:\s*.*') {
$templateContent = $templateContent -replace 'writing_date:\s*.*', "writing_date: $writingDate"
}
# 替换categories
if ($templateContent -match 'categories:\s*.*') {
$templateContent = $templateContent -replace 'categories:\s*.*', "$categories"
} else {
# 如果没有categories行,添加一个
$templateContent = $templateContent -replace '---', "---`n$categories"
}

# 替换permalink
if ($templateContent -match 'permalink:\s*.*') {
$templateContent = $templateContent -replace 'permalink:\s*.*', "$permalinkPath"
} else {
# 如果没有permalink行,添加一个
$templateContent = $templateContent -replace '---', "---`n$permalinkPath"
}

# 替换hide
if ($templateContent -match 'hide:\s*.*') {
$templateContent = $templateContent -replace 'hide:\s*.*', "$hide"
} else {
#如果没有hide行,添加一个
$templateContent = $templateContent -replace '---', "---`n$hide"
}

Set-Content -Path $newTemplatePath -Value $templateContent -Encoding UTF8

#code $newTemplatePath #查看模板文件

if ($ShowDetails) {
Write-Host "📄 更新模板内容:" -ForegroundColor Gray
Write-Host " permalink: $permalinkPath" -ForegroundColor DarkGray
Write-Host " categories: $categories" -ForegroundColor DarkGray
}

return $newTemplatePath
}
else{
Write-Host "❌ 模板文件不存在: $templatePath" -ForegroundColor Red
Write-Host "请确保存在 scaffolds\post.md 文件" -ForegroundColor Yellow
exit 0
}
}

# 创建新文章
function Set-NewPost{
param(
[string]$foundFolder,
[string]$PostTitle
)
# 执行Hexo命令创建文章
try {
# 构建完整的文章路径
$fullPostPath = Join-Path (Get-Location) "source/_posts" $foundFolder $PostTitle
$fullPostPath = $fullPostPath.Replace("/", "\") + ".md"

# 检查是否已存在
if (Test-Path $fullPostPath) {
Write-Host "⚠️ 文件已存在: $fullPostPath" -ForegroundColor Yellow
$overwrite = Read-Host "是否覆盖?(y/n)"
if ($overwrite -ne 'y') {
Write-Host "❌ 已取消创建" -ForegroundColor Red
exit 0
}
}

# 使用Hexo创建文章
hexo new newpost --path "$foundFolder/$PostTitle" $PostTitle
# 打开文章
code "source/_posts/$foundFolder/$PostTitle.md"
Write-Host "✅ 成功创建标题为'$PostTitle'的文章" -ForegroundColor Green
Write-Host "📁 路径: source/_posts/$foundFolder/$PostTitle.md" -ForegroundColor Cyan
}
catch {
Write-Host "❌ 执行Hexo命令时出错: $_" -ForegroundColor Red
# 手动创建文件的备用方案
Write-Host "手动创建文件..." -ForegroundColor Yellow
}
}



$foundFolder,$PostTitle,$categories,$permalinkPath,$hide,$writingDate=Get-PostInfo
$newTemplatePath=Set-ProcScaffold -PostTitle:($PostTitle) -categories:($categories) -permalinkPath:($permalinkPath) -hide:($hide) -writingDate:($writingDate)
Set-NewPost -foundFolder:($foundFolder) -PostTitle:($PostTitle)


# 清理
# 移除临时模板
if (Test-Path $newTemplatePath) {
Remove-Item $newTemplatePath -Force
}
# 移除模块
Remove-Module CategoryMap, FolderTree, PathConverter -ErrorAction SilentlyContinue

Write-Host "`n✅ 脚本执行完成" -ForegroundColor Green

历史版本

智能文章创建脚本v1
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# ============================================
# 《意识之道》智能文章创建脚本
# 作者:道祖
# 版本:v1
# 日期:2026-02-04 00:10
# 更新日期:2026-02-04 00:10
# ============================================



param(
[Parameter(Mandatory=$true)]
[string]$category,

[string]$title,
[switch]$ShowDetails = $false
)

# 导入模块
$modulesDir = "./psm-modules"
$modules = @(
"$modulesDir\CategoryMap.psm1",
"$modulesDir\FolderTree.psm1",
"$modulesDir\PathConverter.psm1"
)

foreach ($module in $modules) {
if (Test-Path $module) {
try {
Import-Module $module -Force -ErrorAction Stop
if ($ShowDetails) {
Write-Host "✅ 导入模块: $(Split-Path $module -Leaf)" -ForegroundColor Green
}
}
catch {
Write-Host "❌ 无法导入模块 $module : $_" -ForegroundColor Red
exit 1
}
}
else {
Write-Host "❌ 模块文件不存在: $module" -ForegroundColor Red
Write-Host "请确保以下模块文件存在:" -ForegroundColor Yellow
$modules | ForEach-Object { Write-Host " • $_" -ForegroundColor Gray }
exit 1
}
}

# 1. 加载分类映射
$categoryMap = Get-CategoryMap -Silent:(!$ShowDetails)
if ($categoryMap.Count -eq 0) {
Write-Host "❌ 无法加载分类映射" -ForegroundColor Red
exit 1
}

# 2. 扫描目录结构
$tree = Get-FolderTree -RootPath "source/_posts" -Silent:(!$ShowDetails)
if (-not $tree) {
Write-Host "❌ 无法扫描目录结构" -ForegroundColor Red
exit 1
}

# 3. 搜索文件夹
$foundFolders = $tree.Find($category)

if ($foundFolders -and $foundFolders.Count -gt 0) {
# 如果有多个匹配,使用第一个
if ($foundFolders.Count -gt 1) {
if ($ShowDetails) {
Write-Host "⚠️ 找到多个匹配的文件夹,使用第一个" -ForegroundColor Yellow
$foundFolders | ForEach-Object { Write-Host " • $_" -ForegroundColor Gray }
}
$foundFolder = $foundFolders[0]
} else {
$foundFolder = $foundFolders
}

# 显示找到的文件夹
if ($ShowDetails) {
Write-Host "✅ 找到文件夹: $foundFolder" -ForegroundColor Green

# 显示路径转换
$englishPath = Convert-PathToEnglish -RelativePath $foundFolder -CategoryMap $categoryMap
Write-Host "📁 原始路径 (中文): $foundFolder" -ForegroundColor Yellow
Write-Host "🔤 转换路径 (英文): $englishPath" -ForegroundColor Cyan
}

# 如果提供了标题,则创建文章
if ($title) {
# 处理文章标题和URL
$postName = $title
if ($category -eq $title) {
$posturl = "index"
} else {
# 使用时间戳作为URL的一部分,确保唯一性
$timestamp = [DateTimeOffset]::Now.ToUnixTimeMilliseconds()
$posturl = "$timestamp"
}


# 构建分类字符串,除去根节点categonries
$categories=$foundFolder
$categories=$categories.Replace($($tree.GetSubfolders("")+"/"),"[")
$categories=$categories.Replace("/",",")+"]"

$categories
# 构建永久链接
$permalink = Convert-PathToEnglish -RelativePath $foundFolder -CategoryMap $categoryMap
$permalinkPath = "$permalink/$posturl/"

# 创建新文章
$postTemplate = "post.md"
$newTemplate = "newpost.md"
$templatePath = Join-Path (Get-Location) "scaffolds\$postTemplate"
$newTemplatePath = Join-Path (Get-Location) "scaffolds\$newTemplate"

if (Test-Path $templatePath) {
# 复制模板
Copy-Item $templatePath $newTemplatePath -Force

# 更新模板内容
$templateContent = Get-Content $newTemplatePath

# 替换permalink
if ($templateContent -match 'permalink:\s*.*') {
$templateContent = $templateContent -replace 'permalink:\s*.*', "permalink: /$permalinkPath"
} else {
# 如果没有permalink行,添加一个
$templateContent = $templateContent -replace '---', "---`npermalink: $permalinkPath"
}

# 替换categories
if ($templateContent -match 'categories:\s*.*') {
$templateContent = $templateContent -replace 'categories:\s*.*', "categories: $categories"
} else {
# 如果没有categories行,添加一个
$templateContent = $templateContent -replace '---', "---`ncategories: $categories"
}

# 替换hide
if ($templateContent -match 'hide:\s*.*') {
$templateContent = $templateContent -replace 'hide:\s*.*', "hide: ture"
} else {
#如果没有hide行,添加一个
$templateContent = $templateContent -replace '---', "---`nhide: ture"
}

# 替换title(如果模板中有占位符)
if ($templateContent -match 'title:\s*{{ title }}') {
$templateContent = $templateContent -replace 'title:\s*{{ title }}', "title: $title"
}

Set-Content -Path $newTemplatePath -Value $templateContent -Encoding UTF8

if ($ShowDetails) {
Write-Host "📄 更新模板内容:" -ForegroundColor Gray
Write-Host " permalink: $permalinkPath" -ForegroundColor DarkGray
Write-Host " categories: $categories" -ForegroundColor DarkGray
}

# 执行Hexo命令创建文章
try {
# 构建完整的文章路径
$fullPostPath = Join-Path (Get-Location) "source/_posts" $foundFolder $title
$fullPostPath = $fullPostPath.Replace("/", "\") + ".md"

Write-Host "📝 创建文章: $title" -ForegroundColor Cyan
Write-Host "📁 路径: $foundFolder/$title.md" -ForegroundColor Gray

# 检查是否已存在
if (Test-Path $fullPostPath) {
Write-Host "⚠️ 文件已存在: $fullPostPath" -ForegroundColor Yellow
$overwrite = Read-Host "是否覆盖?(y/n)"
if ($overwrite -ne 'y') {
Write-Host "❌ 已取消创建" -ForegroundColor Red
exit 0
}
}

# 使用Hexo创建文章
hexo new newpost --path "$foundFolder/$title" $title

Write-Host "✅ 成功创建标题为'$title'的文章" -ForegroundColor Green
Write-Host "📁 路径: source/_posts/$foundFolder/$title.md" -ForegroundColor Cyan

# 显示完整的Front Matter
if ($ShowDetails) {
Write-Host "`n📋 文章配置:" -ForegroundColor Yellow
Write-Host " title: $title" -ForegroundColor Gray
Write-Host " categories: $categories" -ForegroundColor Gray
Write-Host " permalink: $permalinkPath" -ForegroundColor Gray
Write-Host " date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Gray
}
}
catch {
Write-Host "❌ 执行Hexo命令时出错: $_" -ForegroundColor Red

# 手动创建文件的备用方案
Write-Host "尝试手动创建文件..." -ForegroundColor Yellow

$frontMatter = @"
---
title: $title
date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
updated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
categories: $categories
permalink: $permalinkPath
tags: []
---
"@

Set-Content -Path $fullPostPath -Value $frontMatter -Encoding UTF8
Write-Host "✅ 手动创建文件: $fullPostPath" -ForegroundColor Green
}

# 清理临时模板
if (Test-Path $newTemplatePath) {
Remove-Item $newTemplatePath -Force
}
}
else {
Write-Host "❌ 模板文件不存在: $templatePath" -ForegroundColor Red
Write-Host "请确保存在 scaffolds\post.md 文件" -ForegroundColor Yellow
}
}
else {
# 只显示文件夹信息
Write-Host "📁 原始路径 (中文): $foundFolder" -ForegroundColor Yellow

$englishPath = Convert-PathToEnglish -RelativePath $foundFolder -CategoryMap $categoryMap
Write-Host "🔤 转换路径 (英文): $englishPath" -ForegroundColor Cyan

Write-Host "`n💡 提示: 使用 -title 参数创建文章" -ForegroundColor Gray
Write-Host " 例如: .\newpost.ps1 -category '$category' -title '新文章标题'" -ForegroundColor DarkGray
}
}
else {
Write-Host "❌ 未找到包含 '$category' 的文件夹" -ForegroundColor Red

# 显示可用的分类映射
if ($categoryMap.Count -gt 0) {
Write-Host "`n📋 可用的分类映射:" -ForegroundColor Yellow

# 按分组显示
$groups = @{
"道经卷" = $categoryMap.Keys | Where-Object { $_ -match "^道经卷|法则篇|道演篇" }
"道境卷" = $categoryMap.Keys | Where-Object { $_ -match "^道境卷|道境之门|境界论述|实修根本|实修经|实修理术" }
"实践方向" = $categoryMap.Keys | Where-Object { $_ -match "^实践方向|哲学之道|科学之道|技术之道|道祖之道" }
"其他" = $categoryMap.Keys | Where-Object { $_ -notmatch "^道经卷|道境卷|实践方向" }
}

foreach ($groupKey in $groups.Keys) {
if ($groups[$groupKey].Count -gt 0) {
Write-Host "`n ${groupKey}:" -ForegroundColor Cyan
$groups[$groupKey] | Sort-Object | ForEach-Object {
Write-Host " • $_$($categoryMap[$_])" -ForegroundColor DarkGray
}
}
}
}

# 显示顶层文件夹
Write-Host "`n📁 可用的顶层文件夹:" -ForegroundColor Yellow

# 添加GetSubfolders方法到$tree对象(如果不存在)
if (-not ($tree | Get-Member -Name GetSubfolders -MemberType ScriptMethod)) {
$tree | Add-Member -MemberType ScriptMethod -Name GetSubfolders -Value {
param([string]$ParentPath)
if (-not $ParentPath) {
return $this.AllFolders | Where-Object { $_ -notmatch "/" }
}
$this.AllFolders | Where-Object { $_ -like "$ParentPath/*" -and $_ -ne $ParentPath }
}
}

$topLevelFolders = $tree.GetSubfolders("")
if ($topLevelFolders) {
$topLevelFolders | ForEach-Object { Write-Host " • $_" -ForegroundColor Gray }
}
}

# 移除模块(清理)
Remove-Module CategoryMap, FolderTree, PathConverter -ErrorAction SilentlyContinue

Write-Host "`n✅ 脚本执行完成" -ForegroundColor Green

智能文章创建脚本v1.01
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

# ============================================
### 《意识之道》智能文章创建脚本
### 作者:道祖
### 文件名:newpost.ps1
### 编程语言:PowerShell
### 功能:创建新文章时自动分类与自动保存至相应的分类文件夹下
### 作者:道祖
### 版本:v1.01
### 日期:2026-02-04 00:10
### 更新日期:2026-02-09 02:39
# ============================================



param(
[Parameter(Mandatory=$false, Position=0)]
[string]$category = "道祖之道",

[Parameter(Mandatory=$false, Position=1)]
[string]$title,

[Parameter(Mandatory=$false)]
[switch]$ShowDetails
)

# 导入模块
$modulesDir = "./psm-modules"
$modules = @(
"$modulesDir\CategoryMap.psm1",
"$modulesDir\FolderTree.psm1",
"$modulesDir\PathConverter.psm1"
)
foreach ($module in $modules) {
if (Test-Path $module) {
try {
Import-Module $module -Force -ErrorAction Stop
if ($ShowDetails) {
Write-Host "✅ 导入模块: $(Split-Path $module -Leaf)" -ForegroundColor Green
}
}
catch {
Write-Host "❌ 无法导入模块 $module : $_" -ForegroundColor Red
exit 1
}
}
else {
Write-Host "❌ 模块文件不存在: $module" -ForegroundColor Red
Write-Host "请确保以下模块文件存在:" -ForegroundColor Yellow
$modules | ForEach-Object { Write-Host " • $_" -ForegroundColor Gray }
exit 1
}
}

# 1. 加载分类映射
$categoryMap = Get-CategoryMap -Silent:(!$ShowDetails)
if ($categoryMap.Count -eq 0) {
Write-Host "❌ 无法加载分类映射" -ForegroundColor Red
exit 1
}

# 2. 扫描目录结构
$tree = Get-FolderTree -RootPath "source/_posts" -Silent:(!$ShowDetails)
if (-not $tree) {
Write-Host "❌ 无法扫描目录结构" -ForegroundColor Red
exit 1
}

$defcategory=$category -eq "道祖之道"

# 获取分类文件夹路径
function Get-foundFolder {
$foundFolders = $tree.Find($category)
if ($foundFolders -and $foundFolders.Count -gt 0) {
if ($foundFolders.Count -gt 1) {
if ($ShowDetails) {
Write-Host "⚠️ 找到多个匹配的文件夹,使用第一个" -ForegroundColor Yellow
$foundFolders | ForEach-Object { Write-Host " • $_" -ForegroundColor Gray }
}
$foundFolder = $foundFolders[0]
}
else {
$foundFolder = $foundFolders
}
return $foundFolder

}
else{
Write-Host "❌ 未找到包含 '$category' 的分类文件夹" -ForegroundColor Red

# 显示可用的分类映射
if ($categoryMap.Count -gt 0) {
Write-Host "`n📋 可用的分类映射:" -ForegroundColor Yellow

# 按分组显示
$groups = @{
"道经卷" = $categoryMap.Keys | Where-Object { $_ -match "^道经卷|法则篇|道演篇" }
"道境卷" = $categoryMap.Keys | Where-Object { $_ -match "^道境卷|道境之门|境界论述|实修根本|实修经|实修理术" }
"实践方向" = $categoryMap.Keys | Where-Object { $_ -match "^实践方向|哲学之道|科学之道|技术之道|道祖之道" }
"其他" = $categoryMap.Keys | Where-Object { $_ -notmatch "^道经卷|道境卷|实践方向" }
}

foreach ($groupKey in $groups.Keys) {
if ($groups[$groupKey].Count -gt 0) {
Write-Host "`n ${groupKey}:" -ForegroundColor Cyan
$groups[$groupKey] | Sort-Object | ForEach-Object {
Write-Host " • $_$($categoryMap[$_])" -ForegroundColor DarkGray
}
}
}
}

# 显示顶层文件夹
Write-Host "`n📁 可用的顶层文件夹:" -ForegroundColor Yellow

# 添加GetSubfolders方法到$tree对象(如果不存在)
if (-not ($tree | Get-Member -Name GetSubfolders -MemberType ScriptMethod)) {
$tree | Add-Member -MemberType ScriptMethod -Name GetSubfolders -Value {
param([string]$ParentPath)
if (-not $ParentPath) {
return $this.AllFolders | Where-Object { $_ -notmatch "/" }
}
$this.AllFolders | Where-Object { $_ -like "$ParentPath/*" -and $_ -ne $ParentPath }
}
}

$topLevelFolders = $tree.GetSubfolders("")
if ($topLevelFolders) {
$topLevelFolders | ForEach-Object { Write-Host " • $_" -ForegroundColor Gray }
}
exit 0
}

}


# 获取文章信息,处理 Front-matter
function Get-PostInfo {
# 处理文章标题
# 若标题为空,则以日期为标题
if ([string]::IsNullOrEmpty($title)) {
$now = Get-Date
$title = "$($now.Year)年$($now.Month)月$($now.Day)日$($now.Hour)时$($now.Minute)分"
Write-Host "默认标题: $title" -ForegroundColor Yellow
}

if($defcategory){Write-Host "默认分类: $category" -ForegroundColor Yellow}

if ($category -eq $title) {
$posturl = "index"
} else {
# 使用时间戳作为URL的一部分,确保唯一性
$timestamp = [DateTimeOffset]::Now.ToUnixTimeMilliseconds()
$posturl = "$timestamp"
}
$PostTitle = $title

# 获取创建文章的分类文件夹路径
$foundFolder=Get-foundFolder

# 构建分类字符串,除去根节点categonries
$categories=$foundFolder
$categories=$categories.Replace($($tree.GetSubfolders("")+"/"),"[")
$categories=$categories.Replace("/",",")+"]"
$categories="categories: $categories"

#处理默认路径
if($defcategory){
$foundFolder="$foundFolder/$($now.Year)/$($now.Month)"
Write-Host "默认路径: $foundFolder" -ForegroundColor Yellow
}

# 构建永久链接
$permalink = Convert-PathToEnglish -RelativePath $foundFolder -CategoryMap $categoryMap
$permalinkPath = "permalink: /$permalink/$posturl/"

# 默认首页不显示,自定义字段
$hide = "hide: ture"

return $foundFolder,$PostTitle,$categories,$permalinkPath,$hide
}


# 文章模板处理
function Set-ProcScaffold {
param(
[string]$PostTitle,
[string]$categories,
[string]$permalinkPath,
[string]$hide
)

# 不改变原有模板,创建新的模板进行处理
$postTemplate = "post.md"
$newTemplate = "newpost.md"
$templatePath = Join-Path (Get-Location) "scaffolds\$postTemplate"
$newTemplatePath = Join-Path (Get-Location) "scaffolds\$newTemplate"

if (Test-Path $templatePath) {
# 复制模板
Copy-Item $templatePath $newTemplatePath -Force

# 更新模板内容
$templateContent = Get-Content $newTemplatePath

# 替换title(如果模板中有占位符)
if ($templateContent -match 'title:\s*{{ title }}') {
$templateContent = $templateContent -replace 'title:\s*{{ title }}', "title: $PostTitle"
}

# 替换categories
if ($templateContent -match 'categories:\s*.*') {
$templateContent = $templateContent -replace 'categories:\s*.*', "$categories"
} else {
# 如果没有categories行,添加一个
$templateContent = $templateContent -replace '---', "---`n$categories"
}

# 替换permalink
if ($templateContent -match 'permalink:\s*.*') {
$templateContent = $templateContent -replace 'permalink:\s*.*', "$permalinkPath"
} else {
# 如果没有permalink行,添加一个
$templateContent = $templateContent -replace '---', "---`n$permalinkPath"
}

# 替换hide
if ($templateContent -match 'hide:\s*.*') {
$templateContent = $templateContent -replace 'hide:\s*.*', "$hide"
} else {
#如果没有hide行,添加一个
$templateContent = $templateContent -replace '---', "---`n$hide"
}

Set-Content -Path $newTemplatePath -Value $templateContent -Encoding UTF8

#code $newTemplatePath #查看模板文件

if ($ShowDetails) {
Write-Host "📄 更新模板内容:" -ForegroundColor Gray
Write-Host " permalink: $permalinkPath" -ForegroundColor DarkGray
Write-Host " categories: $categories" -ForegroundColor DarkGray
}

return $newTemplatePath
}
else{
Write-Host "❌ 模板文件不存在: $templatePath" -ForegroundColor Red
Write-Host "请确保存在 scaffolds\post.md 文件" -ForegroundColor Yellow
exit 0
}
}

# 创建新文章
function Set-NewPost{
param(
[string]$foundFolder,
[string]$PostTitle
)
# 执行Hexo命令创建文章
try {
# 构建完整的文章路径
$fullPostPath = Join-Path (Get-Location) "source/_posts" $foundFolder $PostTitle
$fullPostPath = $fullPostPath.Replace("/", "\") + ".md"

# 检查是否已存在
if (Test-Path $fullPostPath) {
Write-Host "⚠️ 文件已存在: $fullPostPath" -ForegroundColor Yellow
$overwrite = Read-Host "是否覆盖?(y/n)"
if ($overwrite -ne 'y') {
Write-Host "❌ 已取消创建" -ForegroundColor Red
exit 0
}
}

# 使用Hexo创建文章
hexo new newpost --path "$foundFolder/$PostTitle" $PostTitle
# 打开文章
code "source/_posts/$foundFolder/$PostTitle.md"
Write-Host "✅ 成功创建标题为'$PostTitle'的文章" -ForegroundColor Green
Write-Host "📁 路径: source/_posts/$foundFolder/$PostTitle.md" -ForegroundColor Cyan
}
catch {
Write-Host "❌ 执行Hexo命令时出错: $_" -ForegroundColor Red
# 手动创建文件的备用方案
Write-Host "手动创建文件..." -ForegroundColor Yellow
}
}



$foundFolder,$PostTitle,$categories,$permalinkPath,$hide=Get-PostInfo
$newTemplatePath=Set-ProcScaffold -PostTitle:($PostTitle) -categories:($categories) -permalinkPath:($permalinkPath) -hide:($hide)
Set-NewPost -foundFolder:($foundFolder) -PostTitle:($PostTitle)


# 清理
# 移除临时模板
if (Test-Path $newTemplatePath) {
Remove-Item $newTemplatePath -Force
}
# 移除模块
Remove-Module CategoryMap, FolderTree, PathConverter -ErrorAction SilentlyContinue

Write-Host "`n✅ 脚本执行完成" -ForegroundColor Green