def bitdepth_aware_tokenize_expr(
clips: Sequence[vs.VideoNode], expr: str, chroma: bool, func: FuncExceptT | None = None
) -> str:
from .exprop import ExprToken
func = func or bitdepth_aware_tokenize_expr
if not expr or len(expr) < 4:
return expr
replaces = list[tuple[str, Callable[[vs.VideoNode, bool, ColorRange], float]]]()
for token in sorted(ExprToken, key=lambda x: len(x), reverse=True):
if token.value in expr:
replaces.append((token.value, token.get_value))
if token.name in expr:
replaces.append(
(f'{token.__class__.__name__}.{token.name}', token.get_value)
)
if not replaces:
return expr
clips = list(clips)
ranges = [ColorRange.from_video(c, func=func) for c in clips]
mapped_clips = list(reversed(list(zip(['', *EXPR_VARS], clips[:1] + clips, ranges[:1] + ranges))))
for mkey, function in replaces:
if mkey in expr:
for key, clip, crange in [
(f'{mkey}_{k} ' if k else f'{mkey} ', clip, crange)
for k, clip, crange in mapped_clips
]:
expr = expr.replace(key, str(function(clip, chroma, crange) * 1.0) + ' ')
if mkey in expr:
raise CustomIndexError('Parsing error or not enough clips passed!', func, reason=expr)
return expr