【已解决】如何使用 Dataview 在嵌套 HTML 中使用代码块和 LaTeX 块?

遇到的问题

我使用Dataview创建嵌套HTML元素来实现一些特定视图效果。大部分MD标记都有对应的HTML标签可以顺利转换。但是我不清楚Obsidian中的代码块和latex块使用何种HTML标签。

预期的效果

我希望找到一种方法,可以将代码块或latex转换成HTML元素的形式以便通过Dataview追加到DOM中渲染实现视图效果。

弄到HTML 元素是可以实现的

比如

````dataviewjs
const rawcode = `
公式 = $abc$

代码块 = 

\`\`\`ts
import { App, Component, MarkdownPostProcessorContext, TFile } from "obsidian";
\`\`\`
`

const htmlclip = dv.paragraph(rawcode);
console.log(htmlclip, htmlclip.innerHTML)

dv.el('pre', `test ${htmlclip.innerHTML.replaceAll('<', '&lt;')} end test`)
````

这个可以把 htmlclip.innerHTML 输出到 <pre> 里, 拿到 htmlclip 就可以留作后用


有个麻烦是, 为了获取这个 htmlclip, 一定得用 dv.paragraph, dv.el, ... 把它输出了才能拿到变量, 怎么才能不让他显示这一遍?

目前我只会 const htmlclip = dv.el('p', rawcode, { attr: {style: "display: none" }});

举个例子,方法说明详见 render - Developer Documentation

const str = `
公式 = $abc$

代码块 = 

\`\`\`ts
import { App, Component, MarkdownPostProcessorContext, TFile } from "obsidian";
\`\`\`
`
const el = dv.container
const path = app.workspace.getActiveFile().path
await obsidian.MarkdownRenderer.render(app, str, el, path)
1 个赞

完美解决~

把楼上的const el = dv.container 改为了 const el = createSpan()

```dataviewjs
const str = `
公式 = $abc$

代码块 = 

\`\`\`ts
import { App, Component, MarkdownPostProcessorContext, TFile } from "obsidian";
\`\`\`
`
const el = createSpan();
const path = app.workspace.getActiveFile().path
await obsidian.MarkdownRenderer.render(app, str, el, path)
console.log(el.innerHTML);
```
1 个赞

@Probe @wilson @PlayerMiller
多谢几位朋友的回答。你们对 obsidian 库的使用指出了我的知识盲区。
我虽然有前端开发背景,但是没有开发过 obsidian 插件,不清楚相关API的用法。

不过我自己最近也研究出来了一种方法:通过DOM操纵组装视图。

const view = dv.el("div","",{cls:"card"});

const paragraph = dv.span("这是一个视图")
const latex = dv.span("$f(x)=x^2$")
const code = dv.span(`\`\`\`javascript
console.log("Hello,World!")
\`\`\``)

view.appendChild(paragraph);
view.appendChild(latex);
view.appendChild(code);
1 个赞

:+1: 学习了

原来appendChild除了追加,还有移动的意思,官方解释: appendChild() 方法将一个节点附加到指定父节点的子节点列表的末尾处。如果将被插入的节点已经存在于当前文档的文档树中,那么 appendChild() 只会将它从原先的位置移动到新的位置(不需要事先移除要移动的节点,它首先会被移除,再被插入到新的位置)see Node.appendChild

刚才又看了dataview的span实现,内部也是用MarkdownRenderer实现的 see ui/render.ts