兰 亭 墨 苑
期货 · 量化 · AI · 终身学习
首页
归档
编辑文章
标题 *
URL 别名 *
内容 *
(支持 Markdown 格式)
下面是已修改的完整 Taio Action 脚本:优先自动读取剪切板内容作为 Markdown 发文;若剪切板为空,再回退到动作输入。其余逻辑保持不变。 ```javascript // Taio Action: Publish Markdown to Blog via /api/publish (blog only) - smart title - clipboard first const BASE_URL = "https://yourdomain"; // 修改为你的后端地址 const ENDPOINT = `${BASE_URL}/api/publish`; const TARGETS = ["blog"]; // 标题最长长度(中文/英文字符都按 1 计) const TITLE_MAX_LEN = 40; function defaultTags() { const d = new Date(); return `${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, "0")}`; } // 优先从剪切板读取 Markdown,若为空再使用动作输入 const rawInput = ($clipboard && $clipboard.text) ? $clipboard.text : $actions.inputValue; const md = (rawInput || "").trim(); if (!md) { $actions.reject("没有内容:请把要发布的 Markdown 放到剪贴板,或作为动作输入。"); } // 智能截断为标题:优先按句号/问号/感叹号/换行截断,再按长度截断 function smartCut(str, maxLen) { const s = str.replace(/\s+/g, " ").trim(); const punctIdx = (() => { const idx = [ s.indexOf("。"), s.indexOf("!"), s.indexOf("?"), s.indexOf(". "), s.indexOf("! "), s.indexOf("? "), s.indexOf("\n") ].filter(i => i >= 0); return idx.length ? Math.min(...idx) : -1; })(); let cut = punctIdx >= 0 ? s.slice(0, punctIdx) : s; if (cut.length > maxLen) cut = cut.slice(0, maxLen); return cut || "Untitled"; } // 解析 YAML Front Matter 与标题 function parseMeta(markdown) { const meta = {}; let body = markdown; // 兼容 \n 和 \r\n 的 front matter const fm = markdown.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/); if (fm) { body = markdown.slice(fm[0].length); fm[1].split(/\r?\n/).forEach(line => { const m = line.match(/^([^:#\s][^:]*):\s*(.*)$/); if (m) { const k = m[1].trim().toLowerCase(); let v = m[2].trim(); if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) { v = v.slice(1, -1); } if (k === "tags") { try { meta.tags = v.startsWith("[") ? JSON.parse(v.replace(/'/g, '"')) : v.split(",").map(s => s.trim()).filter(Boolean); } catch { meta.tags = v.split(",").map(s => s.trim()).filter(Boolean); } } else { meta[k] = v; } } }); } // 标题:front matter -> 第一个 H1 -> 正文智能截断 let title = meta.title; if (!title) { const h1 = body.match(/^\s{0,3}#\s+(.+?)\s*$/m); if (h1) title = h1[1].trim(); } if (!title) { const firstNonEmptyLine = body.split(/\r?\n/).find(l => l.trim().length > 0) || ""; title = smartCut(firstNonEmptyLine, TITLE_MAX_LEN); } else if (title.length > TITLE_MAX_LEN) { title = smartCut(title, TITLE_MAX_LEN); } return { title: title || "Untitled", tags: Array.isArray(meta.tags) ? meta.tags : [], body, }; } // Markdown 转纯文本(供 content 字段) function mdToPlain(markdown) { return markdown .replace(/```[\s\S]*?```/g, " ") .replace(/`+/g, "") .replace(/^\s{0,3}#{1,6}\s+/gm, "") .replace(/!\[([^\]]*)\]\((?:[^()]|\([^()]*\))*\)/g, "$1") .replace(/\[([^\]]+)\]\((?:[^()]|\([^()]*\))*\)/g, "$1") .replace(/(\*\*|__|\*|_)/g, "") .replace(/<[^>]+>/g, "") .replace(/[ \t]+\n/g, "\n") .replace(/\n{3,}/g, "\n\n") .trim(); } function httpPostJSON(url, json) { return new Promise((resolve, reject) => { $http.request({ method: "POST", url, header: { "Content-Type": "application/json" }, body: json, handler: resp => { try { const status = resp.response ? resp.response.statusCode : resp.statusCode; const data = resp.data; if (status >= 200 && status < 300) resolve(data); else reject(new Error(`HTTP ${status}: ${typeof data === "string" ? data : JSON.stringify(data)}`)); } catch (e) { reject(e); } } }); }); } (async () => { try { const { title, tags, body } = parseMeta(md); const content_md = body; const content_plain = mdToPlain(content_md); const tagStr = (Array.isArray(tags) && tags.length) ? tags.join(",") : defaultTags(); const payload = { title, // 改进后的智能标题 content: content_plain, content_md: content_md, tags: tagStr, targets: TARGETS }; const result = await httpPostJSON(ENDPOINT, payload); const blog = result && result.blog; if (blog && blog.status === "success") { const url = blog.redirect_url || "(无跳转链接)"; $actions.resolve(`博客发布成功:${url}`); } else { const msg = blog ? (blog.message || JSON.stringify(blog)) : JSON.stringify(result); $actions.reject(`博客发布失败:${msg}`); } } catch (err) { $actions.reject(`发布失败:${err.message || err}`); } finally { $actions.finish(); } })(); ```
配图 (可多选)
选择新图片文件或拖拽到此处
标签
更新文章
删除文章