Is there a way to inspect a selector?
To be specific, how to distinguish between table.cell.where(…) and grid.cell.where(…) selectors?
The selector type does not support .fields.
I’ve also tried repr, but table.cell and grid.cell give identical results.
#let t-1 = table.cell.where(x: 1)
#let g-1 = grid.cell.where(x: 1)
#let g-2 = grid.cell.where(x: 2)
#repr(t-1) == #repr(g-1)
#assert.ne(t-1, g-1)
#assert.eq(g-1, g-1)
#assert.ne(g-1, g-2)
![]()
Is it even possible? Thanks in advance.
Background
I am developing a numbly-like typst package that simplies the use of selector.
-
Canonical Typst:
#show ( heading .where(level: 1) .or(heading.where(level: 2)) .or(heading.where(level: 3)) ): set align(center) -
Canonical Typst + Programming:
#show selector.or( ..(1, 2, 3).map(n => heading.where(level: n)), ): set align(center) -
Typst + My package:
#show sel( heading.where(level: any(1, 2, 3)) ): set align(center)
I implement it by eval-regex-repr. I know this is a quadruple hack, but the scope is limited and we don’t put complicated things in where selectors, so I think it’s okay.
Prototype implementation
(will be MIT licensed)
#let any(..values) = {
assert.eq(values.named(), (:))
assert.ne(values.pos(), ())
metadata(values.pos())
}
#let sel(target, debug: false) = {
assert.eq(type(target), selector)
let expr = repr(target)
let matches = expr
.matches(regex(`metadata\(value: \((.*?)\)\)`.text))
.map(
m => (
any: m.text,
values: m.captures.first().split(", "),
),
)
// Replace each `any` by any of its possible `values`
let expanded = matches.fold(
(expr,),
(expanded, (any, values)) => values
.map(v => expanded.map(e => e.replace(any, v, count: 1)))
.flatten(),
)
if debug { expanded } else {
selector.or(..expanded.map(eval))
}
}
#sel(heading.where(level: any(1, 2, 3), numbering: any("1.1", "A.1")))
#show sel(heading.where(level: any(..range(1, 4)))): set text(red)
= 甲
== 乙
=== 丙
==== 丁
#show sel(figure.where(kind: any(table, "atom"))): set figure.caption(
position: top,
)
#figure(table[Table], caption: [caption])
#figure(circle(), caption: [caption], kind: "atom", supplement: "Atom")
#figure(rect[Image], caption: [caption])
Update: Submitted in sela:0.1.0 by YDX-2147483647 · Pull Request #3167 · typst/packages · GitHub.