Files
NewBlog/scripts/new-thought.mjs
T
dsh 6f4cc13a20 初始提交:时之刃的小站
基于 VermilionVoid(朱墨留白)主题的个人博客。
- 站点配置集中在 src/data/site.ts 与 src/data/profile.ts
- 30 篇文章、8 条偶得、相册
- 评论使用自托管 twikoo
- 部署走 deploy.sh(rsync 到树莓派 + 云服务器)
2026-09-14 20:44:12 +08:00

134 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 创建一条新的「偶得」(thought)
*
* 用法:
* pnpm new-thought "今天把树莓派的散热换掉了,温度降了 15 度。"
* pnpm new-thought "标题" --title 换散热 --location 张掖 --weather "晴 27°C" \
* --images /gallery/GalleryFav/xxx.png --tags 生活,硬件 --pinned
*
* 只提供正文,其余字段都是可选的。
*/
import fs from "node:fs"
import path from "node:path"
const TARGET_DIR = "./src/content/thoughts"
/**
* 用带时区的 ISO 时间。若写成不带时区的 `2026-09-14 21:30`,
* YAML 会按 UTC 解析,显示时会偏移。
*/
function nowIso() {
return new Date().toISOString()
}
function fileStamp() {
const now = new Date()
const pad = (n) => String(n).padStart(2, "0")
return (
`${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}` +
`-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`
)
}
const args = process.argv.slice(2)
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
console.log(`创建一条新的「偶得」
用法:
pnpm new-thought "正文内容" [选项]
选项:
--title <标题> 可选标题
--location <地点> 地点,显示在日期旁
--weather <天气> 天气,与地点一起显示
--images <路径,路径> 配图,public 下的绝对路径,逗号分隔
--tags <标签,标签> 标签,逗号分隔
--pinned 置顶
示例:
pnpm new-thought "换了散热,温度降了 15 度。" --location 张掖 --tags 硬件`)
process.exit(args.length === 0 ? 1 : 0)
}
const content = args[0]
const options = {
title: "",
location: "",
weather: "",
images: "",
tags: "",
pinned: false,
}
for (let i = 1; i < args.length; i++) {
const arg = args[i]
if (arg === "--pinned") {
options.pinned = true
continue
}
if (!arg.startsWith("--")) {
console.error(`错误:无法识别的参数 "${arg}"`)
process.exit(1)
}
const key = arg.slice(2)
if (!(key in options)) {
console.error(`错误:未知选项 --${key}`)
process.exit(1)
}
const value = args[i + 1]
if (value === undefined || value.startsWith("--")) {
console.error(`错误:--${key} 缺少值`)
process.exit(1)
}
options[key] = value
i++
}
const list = (value) =>
value
? value
.split(",")
.map((s) => s.trim())
.filter(Boolean)
: []
const images = list(options.images)
const tags = list(options.tags)
if (!fs.existsSync(TARGET_DIR)) {
fs.mkdirSync(TARGET_DIR, { recursive: true })
}
const fullPath = path.join(TARGET_DIR, `${fileStamp()}.md`)
if (fs.existsSync(fullPath)) {
console.error(`错误:${fullPath} 已存在,请稍后重试`)
process.exit(1)
}
// 字符串统一加引号,避免标题里的冒号、井号等破坏 YAML
const quote = (value) => `"${String(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`
const frontmatter = [
`published: ${nowIso()}`,
options.title ? `title: ${quote(options.title)}` : "",
options.location ? `location: ${quote(options.location)}` : "",
options.weather ? `weather: ${quote(options.weather)}` : "",
images.length > 0 ? `images:\n${images.map((img) => ` - ${quote(img)}`).join("\n")}` : "",
tags.length > 0 ? `tags:\n${tags.map((tag) => ` - ${quote(tag)}`).join("\n")}` : "",
options.pinned ? "pinned: true" : "",
]
.filter(Boolean)
.join("\n")
fs.writeFileSync(fullPath, `---\n${frontmatter}\n---\n\n${content}\n`, "utf8")
console.log(`已创建偶得: ${fullPath}`)
console.log("写入正文后,dev server 会自动刷新。")