From 6b1554d970dc6ed0ce25a741b92eab5b669213ff Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Thu, 3 Feb 2022 12:43:05 +0000 Subject: [PATCH] Fix issue with css variables with multiple values --- examples/dev_sandbox.scss | 2 +- src/textual/css/parse.py | 6 +++--- tests/css/test_parse.py | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/examples/dev_sandbox.scss b/examples/dev_sandbox.scss index 4b18a120b..a7d65a7ca 100644 --- a/examples/dev_sandbox.scss +++ b/examples/dev_sandbox.scss @@ -11,7 +11,7 @@ $animation: offset $animation-speed in_out_cubic; App > View { docks: side=left/1; - text: on $foo; + text: $animation; } Widget:hover { diff --git a/src/textual/css/parse.py b/src/textual/css/parse.py index 0402bb95c..b3b821535 100644 --- a/src/textual/css/parse.py +++ b/src/textual/css/parse.py @@ -2,7 +2,6 @@ from __future__ import annotations from collections import defaultdict from functools import lru_cache -from itertools import dropwhile from typing import Iterator, Iterable from rich import print @@ -259,8 +258,9 @@ def substitute_references(tokens: Iterator[Token]) -> Iterable[Token]: ref_name = token.value[1:] if ref_name in variables: variable_tokens = variables[variable_name] - variable_tokens.extend(variables[ref_name]) - yield from variable_tokens + reference_tokens = variables[ref_name] + variable_tokens.extend(reference_tokens) + yield from reference_tokens else: raise _unresolved( variable_name=ref_name, location=token.location diff --git a/tests/css/test_parse.py b/tests/css/test_parse.py index 79c0ff7e5..01a78cc0b 100644 --- a/tests/css/test_parse.py +++ b/tests/css/test_parse.py @@ -74,6 +74,42 @@ class TestVariableReferenceSubstitution: Token(name='declaration_set_end', value='}', path='', code=css, location=(2, 20)) ] + def test_multi_value_variable(self): + css = "$x: 2 4\n$y: 6 $x 2\n.thing { border: $y }" + assert list(substitute_references(tokenize(css, ""))) == [ + Token(name='variable_name', value='$x:', path='', code=css, location=(0, 0)), + Token(name='whitespace', value=' ', path='', code=css, location=(0, 3)), + Token(name='number', value='2', path='', code=css, location=(0, 4)), + Token(name='whitespace', value=' ', path='', code=css, location=(0, 5)), + Token(name='number', value='4', path='', code=css, location=(0, 6)), + Token(name='variable_value_end', value='\n', path='', code=css, location=(0, 7)), + Token(name='variable_name', value='$y:', path='', code=css, location=(1, 0)), + Token(name='whitespace', value=' ', path='', code=css, location=(1, 3)), + Token(name='number', value='6', path='', code=css, location=(1, 4)), + Token(name='whitespace', value=' ', path='', code=css, location=(1, 5)), + Token(name='number', value='2', path='', code=css, location=(0, 4)), + Token(name='whitespace', value=' ', path='', code=css, location=(0, 5)), + Token(name='number', value='4', path='', code=css, location=(0, 6)), + Token(name='whitespace', value=' ', path='', code=css, location=(1, 8)), + Token(name='number', value='2', path='', code=css, location=(1, 9)), + Token(name='variable_value_end', value='\n', path='', code=css, location=(1, 10)), + Token(name='selector_start_class', value='.thing', path='', code=css, location=(2, 0)), + Token(name='whitespace', value=' ', path='', code=css, location=(2, 6)), + Token(name='declaration_set_start', value='{', path='', code=css, location=(2, 7)), + Token(name='whitespace', value=' ', path='', code=css, location=(2, 8)), + Token(name='declaration_name', value='border:', path='', code=css, location=(2, 9)), + Token(name='whitespace', value=' ', path='', code=css, location=(2, 16)), + Token(name='number', value='6', path='', code=css, location=(1, 4)), + Token(name='whitespace', value=' ', path='', code=css, location=(1, 5)), + Token(name='number', value='2', path='', code=css, location=(0, 4)), + Token(name='whitespace', value=' ', path='', code=css, location=(0, 5)), + Token(name='number', value='4', path='', code=css, location=(0, 6)), + Token(name='whitespace', value=' ', path='', code=css, location=(1, 8)), + Token(name='number', value='2', path='', code=css, location=(1, 9)), + Token(name='whitespace', value=' ', path='', code=css, location=(2, 19)), + Token(name='declaration_set_end', value='}', path='', code=css, location=(2, 20)) + ] + class TestParseLayout: def test_valid_layout_name(self):