mirror of
https://github.com/zulip/zulip.git
synced 2025-11-05 22:43:42 +00:00
linter: Add support for automatic checking for 4 space indents in CSS.
In this commit we modify our CSS parser not only to render the text from
a given CSS tokens produced but also enforce 4 space indentation on it.
Also we enforce some basic rules we would like our CSS to follow such as
* Always have "\n" in between the starting of body({) and body itself
and ending of the body and the closing of body(}).
* Use 4 space indents while having but something within the block
structure ( { .... } ).
* Have single space after ',' in between multiple selectors.
* Have only a single space in between selector and the starting of
block structure ({ ... }) if block structure starts on same line as
of selector.
eg. body {
body content here
}
Notice single space between 'body' and '{'.
Fixes: #1659.
This commit is contained in:
@@ -257,6 +257,99 @@ def parse_value(tokens, start, end):
|
||||
post_fluff=post_fluff,
|
||||
)
|
||||
|
||||
def handle_prefluff(pre_fluff, indent=False):
|
||||
# type: (str, bool) -> str
|
||||
pre_fluff_lines = pre_fluff.split('\n')
|
||||
formatted_pre_fluff_lines = []
|
||||
comment_indent = ''
|
||||
general_indent = ''
|
||||
if indent:
|
||||
general_indent = ' '
|
||||
for i, ln in enumerate(pre_fluff_lines):
|
||||
line_indent = ''
|
||||
if ln.strip() != '':
|
||||
if not i:
|
||||
line_indent = general_indent
|
||||
comment_indent = ' '
|
||||
else:
|
||||
if comment_indent:
|
||||
if ('*/' in ln or '*' in ln) and (ln.strip()[:2] in ('*/', '* ', '*')):
|
||||
line_indent = general_indent
|
||||
if '*/' in ln:
|
||||
comment_indent = ''
|
||||
else:
|
||||
line_indent = general_indent + comment_indent
|
||||
else:
|
||||
line_indent = general_indent
|
||||
comment_indent = ' '
|
||||
elif len(pre_fluff_lines) == 1 and indent and ln != '':
|
||||
line_indent = ' '
|
||||
formatted_pre_fluff_lines.append(line_indent + ln.strip())
|
||||
if formatted_pre_fluff_lines[-1] != '':
|
||||
if formatted_pre_fluff_lines[-1].strip() == '' and indent:
|
||||
formatted_pre_fluff_lines[-1] = ''
|
||||
formatted_pre_fluff_lines.append('')
|
||||
pre_fluff = '\n'.join(formatted_pre_fluff_lines)
|
||||
res = ''
|
||||
if indent:
|
||||
if '\n' in pre_fluff:
|
||||
res = pre_fluff + ' '
|
||||
elif pre_fluff == '':
|
||||
res = ' '
|
||||
else:
|
||||
res = pre_fluff.rstrip() + ' '
|
||||
else:
|
||||
res = pre_fluff
|
||||
|
||||
return res
|
||||
|
||||
def handle_postfluff(post_fluff, indent=False, space_after_first_line=False):
|
||||
# type: (str, bool, bool) -> str
|
||||
post_fluff_lines = post_fluff.split('\n')
|
||||
formatted_post_fluff_lines = []
|
||||
comment_indent = ''
|
||||
general_indent = ''
|
||||
if indent:
|
||||
general_indent = ' '
|
||||
for i, ln in enumerate(post_fluff_lines):
|
||||
line_indent = ''
|
||||
if ln.strip() != '':
|
||||
if i:
|
||||
if comment_indent:
|
||||
if ('*/' in ln or '*' in ln) and (ln.strip()[:2] in ('*/', '* ', '*')):
|
||||
line_indent = general_indent
|
||||
if '*/' in ln:
|
||||
comment_indent = ''
|
||||
else:
|
||||
line_indent = general_indent + comment_indent
|
||||
else:
|
||||
line_indent = general_indent
|
||||
comment_indent = ' '
|
||||
elif indent and not i and len(post_fluff_lines) > 2:
|
||||
formatted_post_fluff_lines.append('')
|
||||
line_indent = general_indent
|
||||
comment_indent = ' '
|
||||
elif space_after_first_line:
|
||||
line_indent = ' '
|
||||
if not i:
|
||||
comment_indent = ' '
|
||||
elif not i:
|
||||
comment_indent = ' '
|
||||
formatted_post_fluff_lines.append(line_indent + ln.strip())
|
||||
if len(formatted_post_fluff_lines) == 1 and not space_after_first_line:
|
||||
if formatted_post_fluff_lines[-1].strip() == '':
|
||||
if formatted_post_fluff_lines[-1] != '':
|
||||
formatted_post_fluff_lines[-1] = ' '
|
||||
else:
|
||||
formatted_post_fluff_lines.append('')
|
||||
elif formatted_post_fluff_lines[-1].strip() == '':
|
||||
formatted_post_fluff_lines[-1] = ''
|
||||
if len(formatted_post_fluff_lines) == 1 and indent:
|
||||
formatted_post_fluff_lines.append('')
|
||||
elif space_after_first_line:
|
||||
formatted_post_fluff_lines.append('')
|
||||
post_fluff = '\n'.join(formatted_post_fluff_lines)
|
||||
return post_fluff
|
||||
|
||||
#### Begin CSS classes here
|
||||
|
||||
@@ -286,7 +379,14 @@ class CssNestedSection(object):
|
||||
res += self.pre_fluff
|
||||
res += self.selector_list.text()
|
||||
res += '{'
|
||||
res += self.section_list.text()
|
||||
section_list_lines = self.section_list.text().split('\n')
|
||||
formatted_section_list = []
|
||||
for ln in section_list_lines:
|
||||
if ln.strip() == '':
|
||||
formatted_section_list.append('')
|
||||
else:
|
||||
formatted_section_list.append(' ' + ln)
|
||||
res += '\n'.join(formatted_section_list)
|
||||
res += '}'
|
||||
res += self.post_fluff
|
||||
return res
|
||||
@@ -303,10 +403,10 @@ class CssSection(object):
|
||||
def text(self):
|
||||
# type: () -> str
|
||||
res = ''
|
||||
res += self.pre_fluff
|
||||
res += handle_prefluff(self.pre_fluff)
|
||||
res += self.selector_list.text()
|
||||
res += self.declaration_block.text()
|
||||
res += self.post_fluff
|
||||
res += handle_postfluff(self.post_fluff, space_after_first_line=True)
|
||||
return res
|
||||
|
||||
class CssSelectorList(object):
|
||||
@@ -317,7 +417,16 @@ class CssSelectorList(object):
|
||||
|
||||
def text(self):
|
||||
# type: () -> str
|
||||
res = ','.join(sel.text() for sel in self.selectors)
|
||||
res = ''
|
||||
for i, sel in enumerate(self.selectors):
|
||||
sel_list_render = sel.text()
|
||||
if i != 0 and sel_list_render[0] != '\n':
|
||||
res += ' '
|
||||
res += sel_list_render
|
||||
if i != len(self.selectors) - 1:
|
||||
res += ','
|
||||
if res[-1] != ' ' and res[-1] != '\n':
|
||||
res += ' '
|
||||
return res
|
||||
|
||||
class CssSelector(object):
|
||||
@@ -331,9 +440,9 @@ class CssSelector(object):
|
||||
def text(self):
|
||||
# type: () -> str
|
||||
res = ''
|
||||
res += self.pre_fluff
|
||||
res += handle_prefluff(self.pre_fluff)
|
||||
res += ' '.join(level.s for level in self.levels)
|
||||
res += self.post_fluff
|
||||
res += handle_postfluff(self.post_fluff)
|
||||
return res
|
||||
|
||||
class CssDeclarationBlock(object):
|
||||
@@ -363,7 +472,7 @@ class CssDeclaration(object):
|
||||
def text(self):
|
||||
# type: () -> str
|
||||
res = ''
|
||||
res += self.pre_fluff
|
||||
res += handle_prefluff(self.pre_fluff, True)
|
||||
res += self.css_property
|
||||
res += ':'
|
||||
value_text = self.css_value.text()
|
||||
@@ -374,7 +483,7 @@ class CssDeclaration(object):
|
||||
res += ' '
|
||||
res += value_text.strip()
|
||||
res += ';'
|
||||
res += self.post_fluff
|
||||
res += handle_postfluff(self.post_fluff, True, True)
|
||||
return res
|
||||
|
||||
class CssValue(object):
|
||||
|
||||
Reference in New Issue
Block a user