Skip to content

Commit

Permalink
experiment with shlex instead of regex
Browse files Browse the repository at this point in the history
  • Loading branch information
falkoschindler committed Jun 10, 2024
1 parent 005513c commit 2ff401b
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 39 deletions.
42 changes: 5 additions & 37 deletions nicegui/element.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from __future__ import annotations

import ast
import inspect
import re
import shlex
from copy import copy, deepcopy
from pathlib import Path
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, Iterator, List, Optional, Sequence, Union, overload
Expand All @@ -22,32 +22,6 @@
if TYPE_CHECKING:
from .client import Client

PROPS_PATTERN = re.compile(r'''
# Match a key-value pair optionally followed by whitespace or end of string
([:\w\-]+) # Capture group 1: Key
(?: # Optional non-capturing group for value
= # Match the equal sign
(?: # Non-capturing group for value options
( # Capture group 2: Value enclosed in double quotes
" # Match double quote
[^"\\]* # Match any character except quotes or backslashes zero or more times
(?:\\.[^"\\]*)* # Match any escaped character followed by any character except quotes or backslashes zero or more times
" # Match the closing quote
)
|
( # Capture group 3: Value enclosed in single quotes
' # Match a single quote
[^'\\]* # Match any character except quotes or backslashes zero or more times
(?:\\.[^'\\]*)* # Match any escaped character followed by any character except quotes or backslashes zero or more times
' # Match the closing quote
)
| # Or
([\w\-.,%:\/]+) # Capture group 4: Value without quotes
)
)? # End of optional non-capturing group for value
(?:$|\s) # Match end of string or whitespace
''', re.VERBOSE)

# https://www.w3.org/TR/xml/#sec-common-syn
TAG_START_CHAR = r':|[A-Z]|_|[a-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]|[\U00010000-\U000EFFFF]'
TAG_CHAR = TAG_START_CHAR + r'|-|\.|[0-9]|\u00B7|[\u0300-\u036F]|[\u203F-\u2040]'
Expand Down Expand Up @@ -327,16 +301,10 @@ def default_style(cls,

@staticmethod
def _parse_props(text: Optional[str]) -> Dict[str, Any]:
dictionary = {}
for match in PROPS_PATTERN.finditer(text or ''):
key = match.group(1)
value = match.group(2) or match.group(3) or match.group(4)
if value is None:
dictionary[key] = True
else:
if (value.startswith("'") and value.endswith("'")) or (value.startswith('"') and value.endswith('"')):
value = ast.literal_eval(value)
dictionary[key] = value
dictionary: dict[str, Any] = {}
for token in shlex.split(text or ''):
words = token.split('=', 1)
dictionary[words[0]] = True if len(words) == 1 else words[1]
return dictionary

def props(self,
Expand Down
4 changes: 2 additions & 2 deletions tests/test_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ def test_props_parsing():
assert ui.element._parse_props('empty=""') == {'empty': ''}
assert ui.element._parse_props("empty=''") == {'empty': ''}

assert ui.element._parse_props("""hint='Your \\"given\\" name'""") == {'hint': 'Your "given" name'}
assert ui.element._parse_props("""hint='Your \"given\" name'""") == {'hint': 'Your "given" name'}
assert ui.element._parse_props("one two=1 three='abc def'") == {'one': True, 'two': '1', 'three': 'abc def'}
assert ui.element._parse_props('''three='abc def' four="hhh jjj"''') == {'three': 'abc def', 'four': 'hhh jjj', }
assert ui.element._parse_props('''foo="quote'quote"''') == {'foo': "quote'quote"}
assert ui.element._parse_props("""foo='quote"quote'""") == {'foo': 'quote"quote'}
assert ui.element._parse_props("""foo="single '" bar='double "'""") == {'foo': "single '", 'bar': 'double "'}
assert ui.element._parse_props("""foo="single '" bar='double \\"'""") == {'foo': "single '", 'bar': 'double "'}
assert ui.element._parse_props("""foo="single '" bar='double \"'""") == {'foo': "single '", 'bar': 'double "'}
assert ui.element._parse_props("input-style='{ color: #ff0000 }'") == {'input-style': '{ color: #ff0000 }'}
assert ui.element._parse_props("""input-style='{ myquote: "quote" }'""") == {'input-style': '{ myquote: "quote" }'}

Expand Down

0 comments on commit 2ff401b

Please sign in to comment.