mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	linter: Make multiline handlebar singleton tags use 2 space indentation.
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							2fe012ffff
						
					
				
				
					commit
					550222dede
				
			@@ -39,7 +39,7 @@ def pretty_print_html(html, num_spaces=4):
 | 
			
		||||
    # we proceed, we will push/pop info dictionaries on/off a stack.
 | 
			
		||||
    for token in tokens:
 | 
			
		||||
 | 
			
		||||
        if token.kind in ('html_start', 'handlebars_start',
 | 
			
		||||
        if token.kind in ('html_start', 'handlebars_start', 'handlebars_singleton',
 | 
			
		||||
                          'html_singleton', 'django_start') and stack[-1]['tag'] != 'pre':
 | 
			
		||||
            # An HTML start tag should only cause a new indent if we
 | 
			
		||||
            # are on a new line.
 | 
			
		||||
@@ -95,7 +95,7 @@ def pretty_print_html(html, num_spaces=4):
 | 
			
		||||
                    )
 | 
			
		||||
                stack.append(info)
 | 
			
		||||
        elif (token.kind in ('html_end', 'handlebars_end', 'html_singleton_end',
 | 
			
		||||
                             'django_end') and
 | 
			
		||||
                             'django_end', 'handlebars_singleton_end') and
 | 
			
		||||
              (stack[-1]['tag'] != 'pre' or token.tag == 'pre')):
 | 
			
		||||
            info = stack.pop()
 | 
			
		||||
            if info['block']:
 | 
			
		||||
@@ -123,10 +123,12 @@ def pretty_print_html(html, num_spaces=4):
 | 
			
		||||
                    elif (start_line + info['line_span'] - 1 == end_line and
 | 
			
		||||
                            (info['line_span'] > 2 or
 | 
			
		||||
                                (info['line_span'] == 2 and
 | 
			
		||||
                                    token.kind == 'html_singleton_end'))):
 | 
			
		||||
                                    token.kind in
 | 
			
		||||
                                    ('html_singleton_end',
 | 
			
		||||
                                     'handlebars_singleton_end')))):
 | 
			
		||||
                        offsets[end_line] = (1 + info['extra_indent'] +
 | 
			
		||||
                                             (info['depth'] + 1) * num_spaces) - adjustment
 | 
			
		||||
                        if token.kind == 'html_singleton_end':
 | 
			
		||||
                        if token.kind in ('html_singleton_end', 'handlebars_singleton_end'):
 | 
			
		||||
                            # We would like singleton tags to have 2 space
 | 
			
		||||
                            # indentation in case they span over multiple lines.
 | 
			
		||||
                            offsets[end_line] -= 2
 | 
			
		||||
@@ -146,7 +148,7 @@ def pretty_print_html(html, num_spaces=4):
 | 
			
		||||
                            extra_indent = info['extra_indent']
 | 
			
		||||
                            adjustment = len(line)-len(line.lstrip()) + 1
 | 
			
		||||
                            offset = (1 + extra_indent + new_depth * num_spaces) - adjustment
 | 
			
		||||
                            if token.kind == 'html_singleton_end':
 | 
			
		||||
                            if token.kind in ('html_singleton_end', 'handlebars_singleton_end'):
 | 
			
		||||
                                # We would like singleton tags to have 2 space
 | 
			
		||||
                                # indentation in case they span over multiple lines.
 | 
			
		||||
                                offset -= 2
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,9 @@ def tokenize(text):
 | 
			
		||||
        # type: () -> bool
 | 
			
		||||
        return looking_at("{#")
 | 
			
		||||
 | 
			
		||||
    def looking_at_handlebarpartial() -> bool:
 | 
			
		||||
        return looking_at("{{partial")
 | 
			
		||||
 | 
			
		||||
    def looking_at_html_start():
 | 
			
		||||
        # type: () -> bool
 | 
			
		||||
        return looking_at("<") and not looking_at("</")
 | 
			
		||||
@@ -101,6 +104,10 @@ def tokenize(text):
 | 
			
		||||
                s = get_django_comment(text, state.i)
 | 
			
		||||
                tag = s[2:-2]
 | 
			
		||||
                kind = 'django_comment'
 | 
			
		||||
            elif looking_at_handlebarpartial():
 | 
			
		||||
                s = get_handlebar_partial(text, state.i)
 | 
			
		||||
                tag = s[9:-2]
 | 
			
		||||
                kind = 'handlebars_singleton'
 | 
			
		||||
            elif looking_at_html_start():
 | 
			
		||||
                s = get_html_tag(text, state.i)
 | 
			
		||||
                tag_parts = s[1:-1].split()
 | 
			
		||||
@@ -155,12 +162,10 @@ def tokenize(text):
 | 
			
		||||
        )
 | 
			
		||||
        tokens.append(token)
 | 
			
		||||
        advance(len(s))
 | 
			
		||||
        if kind == 'html_singleton':
 | 
			
		||||
            # Here we insert a Pseudo html_singleton_end tag so as to have
 | 
			
		||||
            # ease of detection of end of singleton html tags which might be
 | 
			
		||||
            # needed in some cases as with our html pretty printer.
 | 
			
		||||
 | 
			
		||||
        def add_pseudo_end_token(kind: str) -> None:
 | 
			
		||||
            token = Token(
 | 
			
		||||
                kind='html_singleton_end',
 | 
			
		||||
                kind=kind,
 | 
			
		||||
                s='</' + tag + '>',
 | 
			
		||||
                tag=tag,
 | 
			
		||||
                line=state.line,
 | 
			
		||||
@@ -169,6 +174,16 @@ def tokenize(text):
 | 
			
		||||
            )
 | 
			
		||||
            tokens.append(token)
 | 
			
		||||
 | 
			
		||||
        if kind == 'html_singleton':
 | 
			
		||||
            # Here we insert a Pseudo html_singleton_end tag so as to have
 | 
			
		||||
            # ease of detection of end of singleton html tags which might be
 | 
			
		||||
            # needed in some cases as with our html pretty printer.
 | 
			
		||||
            add_pseudo_end_token('html_singleton_end')
 | 
			
		||||
        if kind == 'handlebars_singleton':
 | 
			
		||||
            # We insert a pseudo handlbar end tag for singleton cases of
 | 
			
		||||
            # handlebars like the partials. This helps in indenting multi line partials.
 | 
			
		||||
            add_pseudo_end_token('handlebars_singleton_end')
 | 
			
		||||
 | 
			
		||||
    return tokens
 | 
			
		||||
 | 
			
		||||
def validate(fn=None, text=None, check_indent=True):
 | 
			
		||||
@@ -382,3 +397,15 @@ def get_django_comment(text, i):
 | 
			
		||||
            unclosed_end = end
 | 
			
		||||
        end += 1
 | 
			
		||||
    raise TokenizationException('Unclosed comment', text[i:unclosed_end])
 | 
			
		||||
 | 
			
		||||
def get_handlebar_partial(text, i):
 | 
			
		||||
    # type: (str, int) -> str
 | 
			
		||||
    end = i + 10
 | 
			
		||||
    unclosed_end = 0
 | 
			
		||||
    while end <= len(text):
 | 
			
		||||
        if text[end-2:end] == '}}':
 | 
			
		||||
            return text[i:end]
 | 
			
		||||
        if not unclosed_end and text[end] == '<':
 | 
			
		||||
            unclosed_end = end
 | 
			
		||||
        end += 1
 | 
			
		||||
    raise TokenizationException('Unclosed partial', text[i:unclosed_end])
 | 
			
		||||
 
 | 
			
		||||
@@ -420,6 +420,24 @@ GOOD_HTML15 = """
 | 
			
		||||
</div>
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
BAD_HTML16 = """
 | 
			
		||||
<div>
 | 
			
		||||
  {{partial "settings_checkbox"
 | 
			
		||||
  "setting_name" "realm_name_in_notifications"
 | 
			
		||||
  "is_checked" page_params.realm_name_in_notifications
 | 
			
		||||
  "label" settings_label.realm_name_in_notifications}}
 | 
			
		||||
</div>
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
GOOD_HTML16 = """
 | 
			
		||||
<div>
 | 
			
		||||
    {{partial "settings_checkbox"
 | 
			
		||||
      "setting_name" "realm_name_in_notifications"
 | 
			
		||||
      "is_checked" page_params.realm_name_in_notifications
 | 
			
		||||
      "label" settings_label.realm_name_in_notifications}}
 | 
			
		||||
</div>
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
class TestPrettyPrinter(unittest.TestCase):
 | 
			
		||||
    def compare(self, a: str, b: str) -> None:
 | 
			
		||||
        self.assertEqual(a.split('\n'), b.split('\n'))
 | 
			
		||||
@@ -442,3 +460,4 @@ class TestPrettyPrinter(unittest.TestCase):
 | 
			
		||||
        self.compare(pretty_print_html(BAD_HTML13), GOOD_HTML13)
 | 
			
		||||
        self.compare(pretty_print_html(BAD_HTML14), GOOD_HTML14)
 | 
			
		||||
        self.compare(pretty_print_html(BAD_HTML15), GOOD_HTML15)
 | 
			
		||||
        self.compare(pretty_print_html(BAD_HTML16), GOOD_HTML16)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user