Skip to content

Commit 211f4aa

Browse files
authored
support interpolation in sel"" macro. (#62)
1 parent a2e3fa0 commit 211f4aa

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

src/select.jl

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ Trivial selector that returns `true` for any structural element.
435435
allselector(el) = true
436436

437437
# Acts as a function when used within typical julia filtering functions
438-
# by converting a string selection into a query call
438+
# by converting a string selection into a query call
439439
struct Select{Q} <: Function
440440
query_string::String
441441
query::Q
@@ -450,9 +450,30 @@ end
450450

451451
Base.show(io::IO, ::MIME"text/plain", s::Select) = print(io, """Select("$(s.query_string)")""")
452452

453+
#
454+
# Parse selection string allowing interpolation in sel macro:
455+
# https://discourse.julialang.org/t/str-string-interpolation/125766/11?u=lmiq
456+
#
457+
_select(args...) = Select(string(args...))
453458
"String selection syntax."
454-
macro sel_str(str)
455-
Select(str)
459+
macro sel_str(s)
460+
ex = Expr(:call, GlobalRef(BioStructures, :_select))
461+
i = firstindex(s)
462+
buf = IOBuffer(maxsize=ncodeunits(s))
463+
while i <= ncodeunits(s)
464+
c = @inbounds s[i]
465+
i = nextind(s, i)
466+
if c === '$'
467+
position(buf) > 0 && push!(ex.args, String(take!(buf)))
468+
val, i = Meta.parse(s, i; greedy=false)
469+
Meta.isexpr(val, :incomplete) && error(val.args[1])
470+
val !== nothing && push!(ex.args, val)
471+
else
472+
print(buf, c)
473+
end
474+
end
475+
position(buf) > 0 && push!(ex.args, String(take!(buf)))
476+
return esc(ex)
456477
end
457478

458479
const operators = (

test/runtests.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,11 @@ end
928928
@test length(collectatoms(struc, sel"disordered")) == 68
929929
@test length(collectatoms(struc, sel"sscode E")) == 2448
930930
@test length(collectatoms(struc, sel"helix")) == 4047
931+
# check interpolation support
932+
ss_type = "helix"
933+
@test length(collectatoms(struc, sel"$ss_type")) == 4047
934+
sel_chains = ('A', 'B')
935+
@test length(collectresidues(struc, sel"chain $(first(sel_chains)) or chain $(last(sel_chains))")) == 544
931936

932937
@test length(collectresidues(struc, sel"chain A or chain B")) == 544
933938
@test length(collectresidues(struc, sel"standard")) == 1420

0 commit comments

Comments
 (0)