跳至主要內容

Selector (选择器)

LincZero大约 9 分钟

Selector (选择器)

很多人看到展示页面眼花缭乱的效果,认为 AnyBlock 提供的大量效果处理和渲染是这个插件的内容。

但这并非 AnyBlock 的精髓所在,AnyBlock 插件,看名字就知道,他的精髓在于任意地选择一段范围,并将这一段范围变为 “块”

即 AnyBlock 的精髓在于 —— 选择器

什么是选择器?

这是插件中的一个重要概念,对于 markdwon 的局部解析渲染,有两个重要的步骤

  1. 范围识别 (我将完成这一步骤的称为 选择器)
  2. 将这段范围中的内容进行处理或渲染 (我将完成这一步骤的称为 处理器)

八种选择器

传统代码块选择器

```js       // 这是开始位置 (包含该行)
var a = 0;
```         // 这是结束位置 (包含该行)

在obsidian中,大部分插件使用这种选择器识别范围。例子多不胜数,如:tabs标签页、col分栏、mermaid、plantuml 等等

anyblock除了扩展的六种选择器外,传统的代码块选择器也是支持的。这种选择器的优点在于官方自身提供,兼容性等问题都会非常不错。如果在使用过程中遇到了一些 AnyBllock 不生效的问题,可以尝试换用该方式看问题是否解决。

```anyblock   // 这是开始位置 (包含该行)
[list2table]  // 这是必须的,这有点类似于mermaid代码块中声明图表类型的语句

- 1
  - 2
  - 3
- 4
  - 5
  - 6
```           // 这是结束位置 (包含该行)

传统引用块选择器

其他内容

> [!note]   // 这是开始位置 (包含该行)
> 这是一个obsidian
> 的callout
> 语句       // 这是结束位置 (包含该行)

其他内容

这也是一种选择器,通过引用块选择。但相较于有很多代码选择器的插件,用引用块进行选择的,几乎就只有callout语句了。

那是因为 —— obsidian的开发API并没有提供关于使用这种方式选择范围的快捷API,如果你想要使用这种方式选择一段md文本并进行操作,几乎只能手撸了,而这很难

AB的列表选择器

而 AnyBlock 提供了非常多能够轻松选择范围的选择器,并提供了丰富的解析渲染的处理器。

例如列表选择器:

\[...]      // 这是开始位置 (包含该行)

- 1
  - 2
-3          // 这是结束位置 (包含该行)

其他内容
  • 触发方式:在 列表 的上一/两行增加一行 AB选择器头部 (由方括号扩起来的内容)
  • 范围选择:从AB选择器头部开始,到其后面的列表结束为止

AB的标题选择器

在前面的 “效果展示” 中,我总是使用列表选择器,是因为这种选择器最方便,并且为了避免在前面的章节中引入 “选择器” 这个概念,让刚接触这个插件的人感到迷惑。

事实上,对于像 “卡片”/“标签页”/“分栏” 这种处理来说,通常每一个子项的内容较多且较为混杂,使用标题选择器或 Mdit-Container 选择器是更好的选择!

例如标题选择器:

## 二级标题

\[...]      // 这是开始位置 (包含该行)

### 三级标题

#### 四级标题

### 三级标题

内容         // 这是结束位置 (包含该行)

## 二级标题
  • 触发方式:在 标题 的上一/两行增加一行 AB选择器头部 (由方括号扩起来的内容)
  • 范围选择:从AB选择器头部开始,记其下面的标题等级为X,选择至其后面出现大于X的标题等级为止

AB的代码块选择器


\[...]      // 这是开始位置 (包含该行)

```js
var a = 1;
```         // 这是结束位置 (包含该行)

其他内容
  • 触发方式:在 代码块 的上一/两行增加一行 AB选择器头部 (由方括号扩起来的内容)
  • 范围选择:从AB选择器头部开始,选择至其后面的代码块结束为止

AB的引用块选择器


\[...]      // 这是开始位置 (包含该行)

> ...
> ...
> ...       // 这是结束位置 (包含该行)

其他内容
  • 触发方式:在 引用块 的上一/两行增加一行 AB选择器头部 (由方括号扩起来的内容)
  • 范围选择:从AB选择器头部开始,选择至其后面的引用块结束为止

AB的表格选择器

\[...]      // 这是开始位置 (包含该行)

| a | b |
|---|---|
| c | d |   // 这是结束位置 (包含该行)

其他内容

Mdit-Container的:::头尾选择器

这是 markdwon-it-container 的语法,在 VuePress/VitePress 博客上较为多见。

虽然该语法并不是 AnyBlock 作者所设计的,但在 Obsidian 上,该语法也同样由 AnyBlock 插件提供

语法:


\::: ...    // 这是开始位置 (包含该行)

任意内容

\:::        // 这是结束位置 (包含该行)

其他内容

总结

几种选择器的比较

  • 传统代码开头选择器
    • 优点:自带代码着色、可嵌套。适合需要包含代码的内容
    • 缺点:若包含md内容则在无插件的情况下渲染结果不好
  • 传统引用块选择器
    • 缺点:无Obsidian支持的API,开发困难。书写稍麻烦 (每行带 >),嵌套也稍麻烦
  • AB选择器
    • 优点:格式统一。格式无感,没啥插件嵌入的语法污染。包含md内容时,在无插件的情况下渲染结果优秀
    • 缺点:对于复合内容,无法选择。用灵活性和功能性换来了便携性和无入侵性,导致前两者功能较mdit-container较差
  • Mdit-Container选择器
    • 优点:选择范围灵活。包含md内容时,在无插件的情况下渲染结果优秀。嵌套非常方便
    • 缺点:在对于简单范围的选择上不如AB选择器高效快捷,语法的入侵痕迹更重一些
Note

AB选择器的缺点并不是AnyBlock插件的缺点,AnyBlock本来也有自己的头尾选择器,只是后来看到 ::: 选择器更通用就把自己的 {} 头尾选择器语法扔了换用成那个。 更何况,在Obsidian中,::: 选择器同样是由 AnyBlock 所提供的

为什么说 AnyBlock 的精髓在于选择器

虽然 AnyBlock 支持非常丰富了效果,但这些效果其实很多别个插件也都能做。无论在Obsidian还是在Markdown-it中,例如图表的绘制、时间线、分栏等等

AnyBlock 的精髓在于 —— “选择器”

  1. 一是能够灵活地选择范围。解除了以往只能通过代码块的方式来实现额外语法 (特别是对于ob来说,vueperss好歹还有个mdit-conteiner选择器)
  2. 二是选择范围的方式极为便捷。其语法拥有便捷性和无入侵性
  3. 三是处理器和选择器脱藕。处理器并无需在意你选择范围使用的是哪种选择器

灵活地妙用

title = list

  1. 由于有 title2list 处理器以及对于串连处理器的支持:所有能够处理列表的处理器,同样能够处理标题
  2. 如果出现问题,可以用 title2list|code() 来方便地查看转化情况,并调试
  3. 不建议不用 title2tab,拆成 title2list|list2tab 来用。有现成 title2 指令就用现成的
  • (底层原因:这两者效果还是有些区别。因为 title2list 时需要将结构转化为了多层树,但 list2tab 只需要将结构转化为二层树)

例如:

Plugin effect (插件效果)

a

1

2

3

b

b1

5

6

7

container = list

container也可以表示为list (但只是一个二层的list)。这意味着关于二层list能做的事,用 container 选择器语法也一样可以做。只是语法上稍有不同:

例如:标签页

\::: tabs

@tab t1

content1

@tab t2

content2

\:::

例如:卡片或分栏

\::: card (or col)

@card t1

content1

@card t2

content2

\:::

串联语法、触发其他语法

例如有的插件使用的是代码块选择器,但内容却需要md内容,我们可以优化他:

例如 tabs标签页、col分栏插件等 (虽然这两其实你应该用anyblock的处理器,也有这两功能)

例如:引用块转代码块

Plugin effect (插件效果)
// 这是一段 **markdown** 文本
var a = 0; // 这是代码

例如:代码块转引用块:(这也是在obsidian的callout语法被支持前,Admonition 插件 所做的事情)

Plugin effect (插件效果)
Note

这是一段 markdown 文本

指令:Xcode|quote|add(> [!note])

指令解释:去除代码块|加入引用块|在第一行插入("> [!note]")

通过这套灵活的处理器语法,假如原插件的语法是X,你能够自己定义一个新语法Y,让Y语法替换X语法的同时让原插件生效!

别名系统

当然,你可能嫌弃这样的做法会让指令变得长而不可读,没关系 —— 我们还有别名系统。能够让你用自己定义一个别名来表示一串指令!

例如插件自带的 code2quote 指令,就是使用了别名系统,本质上,code2quote 完全等同于 Xcode|quote

插件自带了许多非常自然的别名(特别是中文别名),在实际使用中,更推荐你使用这些别名:

已支持的快捷别名:

flow
流程图
mindmap
思维导图
脑图
mdMindmap
md思维导图
md脑图
table
multiWayTable
multiCrossTable
crossTable
表格
多叉表格
多叉表
跨行表格
跨行表
listTable
treeTable
listGrid
treeGrid
列表格
树形表
树形表格
dirTree
dir
目录
目录树
目录结构
wbs
工作分解图
timeline
时间线
fakeList
仿列表
标签页
分栏
卡片

使用别名系统能让该插件的语法入侵性更低,例如:

Plugin effect (插件效果)

/

home

usr

etc

/network/interfaces

file