You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅选择普通列表项而非任务列表项?

如何在mdast中仅选择普通列表项(非任务列表项)

我需要从mdast AST中筛选出普通的listItem节点(即不属于任务列表的项),目前已通过selectAll("[checked]", tree)成功选中任务列表项,但尝试以下方法均无法获取普通列表项:

  • selectAll("[checked=null]", tree) 返回空数组
  • selectAll(":not([checked])", tree) 会选中所有节点而非仅普通列表项
  • filter(listItems, node => node.checked === null) 结果为undefined
  • filter(listItems, node => node.checked !== true && node.checked !== false) 结果为undefined

我的初始代码及AST输出如下:

import {fromMarkdown} from 'mdast-util-from-markdown'
import {inspect} from 'unist-util-inspect'
import {selectAll} from 'unist-util-select'
import {gfm} from 'micromark-extension-gfm'
import {gfmFromMarkdown, gfmToMarkdown} from 'mdast-util-gfm'

const doc = `
## List 
- One
- Two 
## Tasklist
* [ ] to do
* [x] done
`
const tree = fromMarkdown(doc, {
  extensions: [gfm()],
  mdastExtensions: [gfmFromMarkdown()]
})

const listItems = selectAll("listItem", tree)
console.log(inspect(listItems))

输出结果:

├─0 listItem[1] (3:1-3:6, 10-15)
│   │ spread: false
│   │ checked: null
│   └─0 paragraph[1] (3:3-3:6, 12-15)
│       └─0 text "One" (3:3-3:6, 12-15)
├─1 listItem[1] (4:1-4:7, 16-22)
│   │ spread: false
│   │ checked: null
│   └─0 paragraph[1] (4:3-4:7, 18-22)
│       └─0 text "Two" (4:3-4:6, 18-21)
├─2 listItem[1] (6:1-6:12, 35-46)
│   │ spread: false
│   │ checked: false
│   └─0 paragraph[1] (6:7-6:12, 41-46)
│       └─0 text "to do" (6:7-6:12, 41-46)
└─3 listItem[1] (7:1-7:11, 47-57)
    │ spread: false
    │ checked: true
    └─0 paragraph[1] (7:7-7:11, 53-57)
        └─0 text "done" (7:7-7:11, 53-57)

解决方案1:正确使用unist-util-filter

filter方法返回undefined是因为未导入对应的工具库unist-util-filter,安装并导入后即可正常过滤:

import {fromMarkdown} from 'mdast-util-from-markdown'
import {inspect} from 'unist-util-inspect'
import {selectAll} from 'unist-util-select'
import {filter} from 'unist-util-filter' // 导入过滤工具
import {gfm} from 'micromark-extension-gfm'
import {gfmFromMarkdown, gfmToMarkdown} from 'mdast-util-gfm'

// ... 其余代码不变

const listItems = selectAll("listItem", tree)
// 筛选出checked为null的普通列表项
const regularItems = filter(listItems, node => node.checked === null)
console.log(inspect(regularItems))

解决方案2:使用复合:not()选择器

利用unist-util-select支持的CSS选择器语法,通过排除checked为布尔值的节点,直接选中普通列表项:

// ... 其余代码不变

// 排除checked为true或false的任务列表项
const regularItems = selectAll("listItem:not([checked=true]):not([checked=false])", tree)
console.log(inspect(regularItems))

这两种方法都能精准获取到checked为null的普通列表项,无需通过文本解析的方式实现。

内容的提问来源于stack exchange,提问作者Ooker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 01:55:13