BlockMD 查询 API
一个功能强大的 BlockMD 文档链式查询 API,支持过滤、排序和多种视图格式。
特性
✅ 链式 API - 流畅的方法链式调用,支持复杂查询
✅ 文件/目录加载 - 从单个文件或整个目录加载
✅ 灵活过滤 - 按属性、层级、内容、自定义条件过滤
✅ Lambda 支持 - 使用 lambda 函数进行复杂条件判断
✅ 排序功能 - 按字段或自定义 lambda 函数排序
✅ 多种视图 - 树形、表格和列表输出格式
✅ 字段提取 - 提取特定字段为字典
安装
# 克隆仓库
git clone <repo-url>
cd wesleysbmd
# 运行测试
python tests/test_query_builder.py
快速开始
from query import query
# 加载并查询 BlockMD 文件
results = (query()
.from_path('docs/spec.bmd')
.where(level=lambda l: l >= 2)
.contains('TODO')
.order_by('title')
.view('table')
)
print(results)
API 参考
加载数据
from_path(path: str | Path) -> QueryBuilder
从文件或目录加载区块。
# 加载单个文件
query().from_path('document.bmd')
# 加载目录中所有 .bmd 文件
query().from_path('docs/')
from_blocks(blocks: List[Block]) -> QueryBuilder
从现有 Block 对象初始化。
from parser import parse_blockmd
blocks = parse_blockmd(text)
query().from_blocks(blocks)
过滤
where(**conditions) -> QueryBuilder
按属性条件过滤区块。
# 精确匹配
query().where(status='done', level=2)
# Lambda 函数
query().where(level=lambda l: l >= 2)
# 多个值
query().where(status=['todo', 'doing'])
# 特殊字段: title, level
query().where(title='Introduction')
has_property(*keys: str) -> QueryBuilder
过滤具有指定属性的区块。
# 单个属性
query().has_property('status')
# 多个属性 (AND)
query().has_property('status', 'priority')
contains(keyword: str, case_sensitive: bool = False) -> QueryBuilder
过滤内容包含关键词的区块。
# 不区分大小写 (默认)
query().contains('TODO')
# 区分大小写
query().contains('FIXME', case_sensitive=True)
filter(predicate: Callable[[Block], bool]) -> QueryBuilder
使用自定义条件函数过滤。
# 有子节点的区块
query().filter(lambda b: len(b.children) > 0)
# 叶子节点
query().filter(lambda b: b.is_leaf())
# 长内容
query().filter(lambda b: len(b.get_content_text()) > 100)
排序
order_by(key: str | Callable, reverse: bool = False) -> QueryBuilder
按字段或函数对区块排序。
# 按字段名排序
query().order_by('title')
query().order_by('level', reverse=True)
# 按属性排序
query().order_by('priority')
# 按 lambda 排序
query().order_by(lambda b: len(b.title))
query().order_by(lambda b: b.get_depth())
可用字段名:
title- 区块标题level- 标题层级 (1-6)depth- 树深度- 任何属性键
限制
limit(count: int) -> QueryBuilder
限制结果数量。
# 获取前 10 个结果
query().limit(10)
# 按优先级排序取前 5 个
query().order_by('priority').limit(5)
输出
view(format: 'tree' | 'table' | 'list', fields: List[str] = None) -> str
格式化结果以供显示。
# 树形视图 - 层级结构
print(query().view('tree'))
# └── Root [prop=value]
# ├── Child A
# └── Child B
# 表格视图 - 结构化列
print(query().view('table', fields=['title', 'level', 'status']))
# title | level | status
# ------+-------+--------
# Block | 2 | done
# 列表视图 - 简单编号列表
print(query().view('list', fields=['title', 'status']))
# 1. Block | status=done
# 2. Other | status=todo
select(*fields: str) -> List[dict]
提取特定字段为字典。
results = query().select('title', 'level', 'content')
# [
# {'title': 'Intro', 'level': 1, 'content': '...'},
# {'title': 'Overview', 'level': 2, 'content': '...'}
# ]
可用字段名:
title,level,content,path,depthid(来自属性)- 任何属性键
execute() -> List[Block]
获取匹配的 Block 对象列表。
blocks = query().where(status='done').execute()
for block in blocks:
print(block.title, block.level)
count() -> int
统计匹配的区块数量。
total = query().contains('TODO').count()
print(f"Found {total} TODOs")
示例
基础过滤
# 所有二级标题
query().from_path('doc.bmd').where(level=2)
# 已完成的任务
query().from_path('tasks.bmd').where(status='complete')
# 高优先级项目
query().from_path('tasks.bmd').where(priority='high')
Lambda 条件
# 二级或更高层级
query().where(level=lambda l: l >= 2)
# 多个状态值
query().where(status=['todo', 'doing'])
# 复杂条件
query().filter(lambda b:
b.level <= 3 and
len(b.children) > 0 and
'TODO' in b.get_content_text()
)
内容搜索
# 查找所有 TODOs
query().contains('TODO')
# 查找 FIXMEs (区分大小写)
query().contains('FIXME', case_sensitive=True)
# 提及 "database" 的区块
query().contains('database').where(level=2)
排序
# 按标题字母顺序
query().order_by('title')
# 按深度 (最深优先)
query().order_by('depth', reverse=True)
# 按内容长度
query().order_by(lambda b: len(b.get_content_text()))
# 按子节点数量
query().order_by(lambda b: len(b.children), reverse=True)
复杂链式调用
# 查找 2 级以上未完成的高优先级任务
results = (query()
.from_path('project/')
.where(
status='todo',
priority='high',
level=lambda l: l >= 2
)
.order_by('priority')
.limit(10)
.view('table', fields=['title', 'priority', 'status'])
)
# 搜索 TODOs,按层级过滤,按深度排序
results = (query()
.from_path('docs/')
.contains('TODO')
.where(level=lambda l: 2 <= l <= 3)
.order_by('depth')
.view('tree')
)
# 获取有子节点的模块,按名称排序
modules = (query()
.from_path('specs/')
.where(type='module')
.filter(lambda b: len(b.children) > 0)
.order_by('title')
.select('title', 'children_count')
)
视图格式
# 树形视图 - 查看层级结构
print(query()
.from_path('project.bmd')
.where(level=lambda l: l <= 2)
.view('tree')
)
# 表格视图 - 结构化数据
print(query()
.from_path('tasks.bmd')
.where(status='todo')
.view('table', fields=['title', 'priority', 'status'])
)
# 列表视图 - 简单输出
print(query()
.from_path('docs.bmd')
.has_property('section')
.view('list', fields=['title', 'section'])
)
统计
# 按状态统计
q = query().from_path('tasks.bmd')
print(f"总数: {q.count()}")
print(f"已完成: {q.where(status='done').count()}")
print(f"待办: {q.where(status='todo').count()}")
# 按层级统计区块
for level in range(1, 4):
count = q.where(level=level).count()
print(f"层级 {level}: {count} 个区块")
高级用法
从多个源加载
# 加载多个文件
q = query()
q.from_path('specs/api.bmd')
q.from_path('specs/database.bmd')
results = q.where(type='function').execute()
# 加载整个目录
q = query().from_path('docs/') # 递归 *.bmd
自定义过滤器
# 标题较长的区块
query().filter(lambda b: len(b.title) > 50)
# 特定深度的区块
query().filter(lambda b: b.get_depth() == 2)
# 有特定祖先的区块
def has_ancestor(block, title):
current = block.parent
while current:
if current.title == title:
return True
current = current.parent
return False
query().filter(lambda b: has_ancestor(b, 'API'))
属性继承
BlockMD 支持使用 key* 语法的属性继承:
# Parent
`status`: active
## Child
`status*`: working
结果: Child 的 status="active/working"
查询继承的属性:
# 查找具有继承状态的区块
query().filter(lambda b: '/' in b.get_property('status', ''))
运行测试
# 测试 QueryBuilder API
python tests/test_query_builder.py
# 运行所有解析器测试
python tests/test_parser.py
示例
查看 examples/query_demo.py 获取所有特性的完整示例:
python examples/query_demo.py
API 使用
# 链式、流畅的接口
query()
.from_path('docs/')
.where(level=lambda l: l >= 2)
.contains('TODO')
.order_by('title')
.view('table')
BlockMD 格式说明
什么是 BlockMD?
BlockMD 是一种与 Markdown 完全兼容的块状标记语言,为标准 Markdown 文件增加了结构化和元数据功能。
基本语法
# 区块标题
`property`: value
`status`: active
区块内容可以包含任何标准 Markdown 格式。
## 子区块
`status*`: working
子区块继承父区块的属性。
核心概念
- 区块(Block):由 Markdown 标题(
#、##等)定义 - 层级(Level):标题的
#数量(1-6)决定嵌套层级 - 属性(Properties):
`key`: value格式的键值对元数据 - 继承(Inheritance):
`key*`: value语法从父区块继承属性 - 内容(Content):标准 Markdown 文本
许可证
MIT
贡献
欢迎贡献!提交 PR 前请确保测试通过。
Metadata
Release files for wesleysbmd 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wesleysbmd-0.1.3.tar.gz | 23.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wesleysbmd-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.6 kB
Release files / wesleysbmd-0.1.3.tar.gz
| Download URL | wesleysbmd-0.1.3.tar.gz |
|---|---|
| Size | 23.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
adcf32d1f9ad7306151a52f631aa2d385e027c4ae784e1c77d2607a6ec17531d
|
|
BLAKE2b-256 checksum How to use checksums |
8da37d548450fec4b16aab549713e9131a92c3fcaad6a07d96e20d71db68b804
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.8
|
Release files / wesleysbmd-0.1.3-py3-none-any.whl
| Download URL | wesleysbmd-0.1.3-py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e4f1aaac00307e51a4160a9f2485e9f7cf5e3e753d89f760e388add43891206c
|
|
BLAKE2b-256 checksum How to use checksums |
59c4f559881b55aa0502e6e5b30b6ebe9c28d12124f4980b30ea7cdebbd10b3f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.8
|