样式效果
通过修改 Html 语法中的 <details>评论区</details>
语法的样式来使它更像一个评论信息。
注意事项
存在问题:
一般来<details>评论区</details>
里面不支持 ob 的语法格式,单纯以文本形式展出,也就是不支持图片、双链、Markdown 语法等,只支持 Html 语法。
如何实现渲染
如果 <details>
在一个文本段落中可以渲染包括图片甚至是嵌入文档的渲染:
源码模式:
阅读模式:
实时模式直接隐藏:
实时模式我是直接隐藏不见的,鼠标放到注释区域才会显示,如果需要显示的话请自行修改 CSS 文件。
如何快捷输入
最好给 <details>
里面的添加标签,方便后期检索
注释选中的文本 by QuickAdd
效果
配置
配置 QuickAdd
的 Capture:
=={{selected}}==<details>#Details<br>{{mvalue}}</details>
配置高级输入框 (可添加标签) by QuickAdd + Modal Forms
效果
配置
配合 QuickAdd
+ Modal Forms
这 2 个插件使用,Modal Forms
的只需安装即可,QuickAdd
配置 Capture:
```js quickadd
// 🔴修改Zotero路径即可
const folderPath = 'D:/Zotero/storage';
const fs = require('fs');
const modalForm = app.plugins.plugins.modalforms.api;
const files = fs.readdirSync(folderPath);
const zoteroItems = [];
let selection = window.getSelection();
selection = selection.toString();
files.forEach((file) => {
const filePath = `${folderPath}/${file}`;
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
const subFiles = fs.readdirSync(filePath);
const pdfFiles = subFiles.filter((subFile) => subFile.endsWith('.pdf')).map((pdfFile) => pdfFile.replace('.pdf', ''));
if (pdfFiles.length > 0) {
const zoteroItem = {};
zoteroItem["item"] = file;
zoteroItem["link"] = `zotero://open-pdf/library/items/${file}`;
zoteroItem["file"] = pdfFiles[0];
zoteroItems.push(zoteroItem);
}
}
});
console.log(zoteroItems);
let zoteroItemNames = [];
zoteroItems.forEach((item) => {
zoteroItemNames.push(item["file"]);
});
// console.log(zoteroItemNames)
const values = {
ZoteroCites: selection,
};
const result = await modalForm.openForm({
title: "zoteroModalForms",
name: "zoteroModalForms",
version: "1",
fields: [
{
name: "ZoteroCites",
label: "通过引用匹配对应的Items",
description: "引用格式需要IEEE格式",
input: {
type: "textarea"
}
},
{
name: "ZoteroItems",
label: "",
description: "",
input: {
type: "multiselect",
source: "fixed",
multi_select_options: zoteroItemNames,
}
},
]
}, {values:values});
let getZoteroItems = result.getValue('ZoteroItems').value;
let getZoteroCites = result.getValue('ZoteroCites').value;
if (getZoteroCites) {
getZoteroItems = getZoteroItems.concat(matchZoteroItems(getZoteroCites));
}
console.log(getZoteroItems);
let zoteroItemsLinks = [];
getZoteroItems.forEach((item) => {
// const foundItem = zoteroItems.find((zoteroItem) => zoteroItem["file"].includes(item.substring(0, 10)));
const foundItem = zoteroItems.find((zoteroItem) => {
const similarityThreshold = 0.3; // 相似度阈值
const similarity = 1 - levenshteinDistance(zoteroItem["file"], item) / Math.max(zoteroItem["file"].length, item.length);
return similarity >= similarityThreshold;
});
if (foundItem) {
const zoteroLink = `[《${item}》](${foundItem["link"]})`;
zoteroItemsLinks.push(zoteroLink);
}
});
if (zoteroItemsLinks.length) {
const output = zoteroItemsLinks.join("\n");
console.log(output);
return output;
}
function matchZoteroItems(text) {
const regex = /《(.*?)》/gm;
const matches = text.match(regex);
return matches ? matches.map(match => match.slice(1, -1)) : "";
}
function levenshteinDistance(a, b) {
// Levenshtein距离计算相似度 by ChatGPT @2024-01-04
const m = a.length;
const n = b.length;
const dp = Array.from(Array(m + 1), () => Array(n + 1).fill(0));
for (let i = 0; i <= m; i++) {
dp[i][0] = i;
}
for (let j = 0; j <= n; j++) {
dp[0][j] = j;
}
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
if (a[i - 1] === b[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = Math.min(
dp[i - 1][j] + 1, // 删除操作
dp[i][j - 1] + 1, // 插入操作
dp[i - 1][j - 1] + 1 // 替换操作
);
}
}
}
return dp[m][n];
}
```
CSS 代码
/* ! details 样式修改 */
/* 2023-12-13 details样式修改 */
.theme-light .markdown-preview-view details {
background-color: rgba(252, 255, 203, 0.9);
}
.theme-dark .markdown-preview-view details {
background-color: rgba(56, 55, 56, 0.9);
}
.markdown-source-view.mod-cm6 details {
display: none;
}
/* 在better-search-views中正常显示 */
.markdown-preview-view:not(.better-search-views-file-match.markdown-rendered)
details {
position: absolute;
font-weight: lighter;
font-size: smaller;
border-width: 1px;
border-style: solid;
border-radius: 10px;
padding: 2px 3px 2px 3px;
display: block;
transform: translateY(-3rem);
z-index: 1;
border-inline-start: 5px solid;
white-space: pre-wrap;
}
.markdown-preview-view:not(.better-search-views-file-match.markdown-rendered)
details[open] {
max-width: 500px;
max-height: 400px;
overflow: auto;
z-index: 2;
}
details:not(details[open]) {
right: 1rem;
min-width: 20px;
}
:not(.callout-content)details[open] {
max-width: 400px;
z-index: 2;
}
details[open],
.popover.hover-editor details,
:not(.callout-conten) details {
right: 1rem;
}
/* 在callout中不生效 */
.callout-content details[open] {
transform: translateX(1rem) !important;
position: relative !important;
max-width: unset !important;
}