DataviewJS 查询空文件、空文件夹、断裂双链、特定目录或全库未链接文件

实例一

image image

  • 默认删除至系统回收站,方便原路径还原反悔。任何疑问请查看系统回收站。
  • 空文档包括:大小为 0 的文件(全部后缀)。
  • 仅有空白字符的 MD 文档。
  • 仅有 YAML 的 MD 文档。默认前加“Y”标识,可自行更换标识。
代码
dv.el('button', '切换').onclick = ()=> qh()
//dv.el('button', '清空').onclick = ()=> items.filter(p=> isFile ? !p.extension : p.extension).map(p=> trash(p))
let table = dv.el('div'), isFile = true, items = [], trash = async p=> await app.vault.trash(p, true)
, getFC = file=> app.metadataCache.getFileCache(file), form = (p, note)=> { items.push(p)
    let btn = dv.el('button', '删除'); btn.onclick = ()=> { trash(p); btn.textContent = '已删' }
    return isFile ? [p.parent.path, `${note ? note : ''}[[${p.name}]]`, btn] : [p.path, btn] }
, qh = ()=> { table.empty(); let tdata = []; app.vault.getAllLoadedFiles().map(p=> {
    if (isFile) {
        if (p.stat?.size == 0 || p.extension == 'md' && !getFC(p).sections) tdata.push(form(p))
        //if (p.extension && getFC(p).frontmatter && !getFC(p).sections[1]) tdata.push(form(p, 'Y'))
    } else if (!p.extension && !p.children[0]) tdata.push(form(p))
}); dv.api.table(isFile ? ['路径', '空文档', ''] : ['空文件夹', ''], tdata, table, dv.component)
isFile = isFile ? false : true }; qh()

注释掉的两项依次为清空按钮及查找仅有 YAML 的文档,按需启用。

实例二

得益于 交流向实验性 QuickAdd 批量重命名小标题防止双链断裂 发现的 API。

  • 始终查找全库断裂双链(灰链、未创建链…),如示意图左上角。默认前加“:warning:︎”标识。
    排除 Templater 模板使用语法的双链。

  • 未选择时默认查找当前活动文档所在文件目录未被引文件(全部后缀)。
    故可把代码放在附件文件夹;
    也可把代码所在文档开在旁边,迅速查看多个文件夹。

    示例 GIF,点击展开

    20240305_190155

  • 240418 更新查找框 image

代码
const dc = str=> document.createElement(str), inpu = dc('input'), sele = dc('datalist')
, folders = app.vault.getAllLoadedFiles().filter(p=> !p.extension).map(p=> {
  const el = dc('option'); el.value = p.path; sele.appendChild(el); return p.path
})
inpu.style.width = '120px'; inpu.setAttribute('list', 'demo'); sele.id = 'demo'
inpu.onchange = ()=> folders.includes(inpu.value) && by(); [inpu, sele].map(el=> dv.container.appendChild(el))
//dv.el('button', '全库').onclick = ()=> { whole = true; by(); inpu.placeholder = `来源: 全库`; whole = false }
let whole = false; const table = dv.el('div'), by = ()=> { table.empty(); inpu.placeholder = '来源: ..'
  let tdata = [], r = [], folder = app.workspace.getActiveFile().parent.path
  if (folders.slice(1).includes(inpu.value)) { inpu.placeholder = `来源: ${inpu.value}`; folder = inpu.value }
  const arr = folder.split('/')
  app.vault.getFiles().filter(p=> whole ? p : p.path.split('/').slice(0, arr.length).every((x, i)=> x == arr[i])).map(p=> {
    app.fileManager.iterateAllRefs((rPath, rbj)=> { const err = `${rPath},,⚠︎[[${rPath}|${rbj.link}]]`
      , find = app.metadataCache.getFirstLinkpathDest(rbj.link.split('#')[0], rPath)
      if (find) { if (p.path == find.path) r.includes(p.path) || r.push(p.path)
      } else if (!rbj.link.startsWith('\<\%')) tdata.includes(err) || tdata.push(err)
    }); r.includes(p.path) || tdata.push(`${p.parent.path},,[[${p.path}|${p.name}]]`)
  }); dv.api.table(['路径', '未被引'], tdata.map(p=> p.split(',,')), table, dv.component); inpu.value = ''
}; by()

注释掉的一项为查找全库未被引文件按钮,按需启用。

彩蛋

使用 QuickAdd 正则保值替换选单 便捷格式化双链,主要适用于非嵌入的 Wiki 链接。

会,可在原帖示例代码上继续添加新项;

不会,将下面给出的 rgxform 组合分别覆盖替换原帖代码 sus[0]sus[1] 后面的内容。

1、imageimage [[文件路径/Wiki]][[文件路径/Wiki|Wiki]]

rgx = /(?<!!)\[\[([^\|]+?)]]/gm; form = (m, p1)=> `[[${p1}|${p1.split('/').slice(-1)}]]`

2、imageimage

rgx = /(?<!!)\[\[(.+?)]]/gm; form = (m, p1)=> p1.split('|').slice(-1)
3 个赞