一句话总结
使用QuickAdd的capture一键转换所选内容,到折叠好的callout中
使用方法
配置:QuickAdd设置,新建capture,如图设置,粘贴代码至Capture format栏即可
使用:选中文本,调出QuickAdd面板或直接使用快捷键触发配置好的capture命令,即可自动转换所选内容为折叠好的callout,第一行为callout标题
详细步骤/高级用法/配置快捷键见:QuickAdd JS & Templater JS 简介及相互修改
脚本源码
```js quickadd
// 获取选中的内容
const selectedContent = this.quickAddApi.utility.getSelectedText();
// 将内容按行分割
const lines = selectedContent.split('\n');
// 获取第一行
let firstLine = lines[0];
// 定义正则表达式,匹配Markdown标题(#、##、### 等)和无序列表(-、*、+)
const markdownPattern = /^(#{1,6}\s+|- |\* |\+ )/;
// 如果第一行匹配正则表达式,则去除相应的前缀
if (markdownPattern.test(firstLine)) {
firstLine = firstLine.replace(markdownPattern, ''); // 去掉匹配的部分
}
// 将除第一行以外的每一行前添加 "> " 进行引用
const formattedContent = lines.slice(1).map(line => '> ' + line).join('\n') + '\n';
// 在formattedContent之前加上 "> [!info]- \n",并保留第一行
const finalContent = '\n> [!info]- ' + firstLine + '\n' + formattedContent;
// 返回最终处理后的内容
return finalContent;
```
2 个赞
Moy
2
好东西!感谢~
多亏你提供思路,借着这个契机把之前一直想弄的功能给实现了,哈哈!
老早就想替换掉官方的那个「切换 Callout」快捷键了,但是没有办法像官方那样「自动扩散选择范围」,这次让AI搞了个改进版
说明:
- 增加了可配置项,可以自行设置「Callout类型、是否折叠、是否用第一行作为标题」
- 自动将转换的范围扩散到光标(或选中文本)上下的 非空行/非标题 范围,不需要很精确选择,随便点一下就可以把整段文本都转换成 Callout
改进代码:
<%*
// 配置选项
const CONFIG = {
calloutType: "info", // Callout 类型
collapsed: true, // 是否折叠
useFirstLineAsTitle: false // 是否使用第一行作为标题
};
// 获取编辑器实例
const editor = app.workspace.activeEditor.editor;
// 判断是否为标题行
const isHeading = (line) => /^#{1,6}\s+/.test(line);
// 判断是否为空行或标题行
const shouldStop = (line) => !line.trim() || isHeading(line);
// 获取当前选中的内容和范围
let selection = editor.getSelection();
let from, to;
if (!selection) {
// 如果没有选中文本,从光标所在行开始扩展
const cursor = editor.getCursor();
// 如果光标在标题行上,直接返回
if (isHeading(editor.getLine(cursor.line))) return;
// 设置初始范围为光标所在行的开始到结束
from = { line: cursor.line, ch: 0 };
to = { line: cursor.line, ch: editor.getLine(cursor.line).length };
} else {
// 如果有选中文本,获取选择范围
from = editor.getCursor('from');
to = editor.getCursor('to');
}
// 向上扩展选择范围直到遇到空行或标题行
let line = from.line;
while (line > 0) {
const prevLine = editor.getLine(line - 1);
if (shouldStop(prevLine)) break;
line--;
}
from.line = line;
from.ch = 0;
// 向下扩展选择范围直到遇到空行或标题行
line = to.line;
while (line < editor.lineCount() - 1) {
const nextLine = editor.getLine(line + 1);
if (shouldStop(nextLine)) break;
line++;
}
to.line = line;
to.ch = editor.getLine(line).length;
// 更新选择范围
editor.setSelection(from, to);
// 获取扩展后的选中内容
const selectedText = editor.getRange(from, to);
// 如果没有有效内容,直接返回
if (!selectedText.trim()) return;
// 将内容按行分割
const lines = selectedText.split('\n');
let firstLine = lines[0];
// 定义正则表达式,匹配Markdown标题(#、##、### 等)和无序列表(-、*、+)
const markdownPattern = /^(#{1,6}\s+|- |\* |\+ )/;
// 如果第一行匹配正则表达式,则去除相应的前缀
if (markdownPattern.test(firstLine)) {
firstLine = firstLine.replace(markdownPattern, '');
}
// 构建 Callout 标记
const calloutMark = `> [!${CONFIG.calloutType}]${CONFIG.collapsed ? '-' : ''}`;
// 根据配置决定是否添加标题
const titleLine = CONFIG.useFirstLineAsTitle ? ` ${firstLine}` : '';
// 确定要处理的内容行
const contentLines = CONFIG.useFirstLineAsTitle ? lines.slice(1) : lines;
// 将内容行添加引用前缀
const formattedContent = contentLines.map(line => '> ' + line).join('\n') + '\n';
// 组合最终内容
const finalContent = `\n${calloutMark}${titleLine}\n${formattedContent}`;
// 替换选中的内容
editor.replaceRange(finalContent, from, to);
// 计算新的光标位置
const newLines = finalContent.split('\n');
const lastContentLine = newLines.findLastIndex(line => line.startsWith('> ')); // 找到最后一个引用行
if (lastContentLine !== -1) {
const targetLine = from.line + lastContentLine;
const targetText = editor.getLine(targetLine);
// 设置光标到这一行引用内容的末尾
editor.setCursor({
line: targetLine,
ch: targetText.length
});
}
-%>
我习惯用 Tp 所以这里写的是 Templater 的脚本,不过好像没用啥 tp
接口,应该可以通用
1 个赞
七又四分之一
(七又四分之一)
3
在编辑区双击,会选中光标所在句子;
在编辑区三击,会选中光标所在行;
两个空行之间的是一个区,那么能不能直接捕获光标所在的区呢?
这样就不用从头选到尾了。能省不少操作