fix(attributes): fixed poor django attribute parsing

Allow multiple attribute styles inside a quoted value. Split the attribute name into a group to help
resolve #427

closes #438
This commit is contained in:
Christopher Pickering 2022-10-28 14:00:14 +02:00
parent b84ddeb1d0
commit bd90f08065
No known key found for this signature in database
GPG key ID: E14DB3B0A0FACF84
3 changed files with 48 additions and 17 deletions

View file

@ -258,7 +258,12 @@ def format_attributes(config: Config, html: str, match: re.match) -> str:
# format attributes as groups # format attributes as groups
attributes = (spacing).join( attributes = (spacing).join(
re.findall(config.attribute_pattern, match.group(3).strip(), re.VERBOSE) [
x.group()
for x in re.finditer(
config.attribute_pattern, match.group(3).strip(), re.VERBOSE
)
]
) )
close = match.group(4) close = match.group(4)

View file

@ -197,6 +197,7 @@ def indent_html(rawcode: str, config: Config) -> str:
# if a normal tag, we can try to expand attributes # if a normal tag, we can try to expand attributes
elif is_block_raw is False: elif is_block_raw is False:
# get leading space, and attributes # get leading space, and attributes
func = partial(format_attributes, config, item) func = partial(format_attributes, config, item)
tmp = re.sub( tmp = re.sub(

View file

@ -510,29 +510,54 @@ class Config:
self.template_if_for_pattern = ( self.template_if_for_pattern = (
r"(?:{%-?\s?(?:if|for)[^}]*?%}(?:.*?{%\s?end(?:if|for)[^}]*?-?%})+?)" r"(?:{%-?\s?(?:if|for)[^}]*?%}(?:.*?{%\s?end(?:if|for)[^}]*?-?%})+?)"
) )
self.attribute_pattern: str = ( self.attribute_pattern: str = (
r""" rf"""
(?:[^\s]+?[ ]*?=[ ]*?(?:\"[^\"]*?""" (?:
+ self.template_if_for_pattern (?:
+ r"""[^\"]*?\"|\'[^\']*?""" (?:\w|-|\.)+ | required | checked
+ self.template_if_for_pattern ) # attribute name
+ r"""[^\']*?\')) (?: [ ]*?=[ ]*? # followed by "="
| (?:[^\s]+?[ ]*?=[ ]*?(?:\"[^\"]*?{{.*?}}[^\"]*?\"|\'[^\']*?{{.*?}}[^\']*?\')) (?:
| """ \"[^\"]*? # double quoted attribute
+ self.template_if_for_pattern (?:
{self.template_if_for_pattern} # if or for loop
| {{{{.*?}}}} # template stuff
| {{%[^}}]*?%}}
| [^\"] # anything else
)*?
\" # closing quote
| '[^']*? # single quoted attribute
(?:
{self.template_if_for_pattern} # if or for loop
| {{{{.*?}}}} # template stuff
| {{%[^}}]*?%}}
| [^'] # anything else
)*?
\' # closing quote
| (?:\w|-)+ # or a non-quoted value
)
)? # attribute value
)
| {self.template_if_for_pattern}
"""
+ r""" + r"""
| (?:[^\s]+?[ ]*?=[ ]*?(?:\"(?:[^\"]*?{%[^}]*?%}[^\"]*?)+?\"))
| (?:[^\s]+?[ ]*?=[ ]*?(?:\'(?:[^\']*?{%[^}]*?%}[^\']*?)+?\'))
| (?:[^\s]+?[ ]*?=[ ]*?(?:\".*?\"|\'.*?\'))
| required
| checked
| (?:\w|-|\.)+
| (?:\w|-|\.)+[ ]*?=[ ]*?(?:\w|-)+
| {{.*?}} | {{.*?}}
| {%.*?%} | {%.*?%}
""" """
) )
# + r"""[^\"]*?\"|\'[^\']*?"""
# + self.template_if_for_pattern
# + r"""[^\']*?\'))
# | (?:[^\s]+?[ ]*?=[ ]*?(?:\"[^\"]*?{{.*?}}[^\"]*?\"|\'[^\']*?{{.*?}}[^\']*?\'))
# | """
# + self.template_if_for_pattern
# + r"""
# | (?:[^\s]+?[ ]*?=[ ]*?(?:\"(?:[^\"]*?{%[^}]*?%}[^\"]*?)+?\"))
## | (?:[^\s]+?[ ]*?=[ ]*?(?:\'(?:[^\']*?{%[^}]*?%}[^\']*?)+?\'))
# | (?:[^\s]+?[ ]*?=[ ]*?(?:\".*?\"|\'.*?\'))
self.attribute_style_pattern: str = r"^(.*?)(style=)([\"|'])(([^\"']+?;)+?)\3" self.attribute_style_pattern: str = r"^(.*?)(style=)([\"|'])(([^\"']+?;)+?)\3"
self.start_template_tags: str = ( self.start_template_tags: str = (