Files
NewBlog/scripts/new-thought.mjs
T

139 lines
3.9 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") {
// 无参数进来时先说清楚原因:下面 pnpm 还会补一句
// "[ELIFECYCLE] Command failed with exit code 1",不点明的话很像脚本崩了
if (args.length === 0) {
console.log('缺少正文内容,没有创建任何文件。\n正确写法:pnpm new-thought "今天把树莓派的散热换掉了。"\n')
}
console.log(`创建一条新的「偶得」
用法:
pnpm new-thought "正文内容" [选项]
选项:
--title <标题> 可选标题
--location <地点> 地点,显示在日期旁
--weather <天气> 天气,与地点一起显示
--images <路径,路径> 配图,public 下的绝对路径,逗号分隔,或者使用图床url链接
--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 会自动刷新。")