diff --git a/__pycache__/nginxfmt.cpython-37.pyc b/__pycache__/nginxfmt.cpython-37.pyc new file mode 100644 index 0000000..67f9adf Binary files /dev/null and b/__pycache__/nginxfmt.cpython-37.pyc differ diff --git a/nginxfmt.py b/nginxfmt.py index 24e9160..57c7c35 100755 --- a/nginxfmt.py +++ b/nginxfmt.py @@ -20,6 +20,8 @@ INDENTATION = ' ' * 4 TEMPLATE_VARIABLE_OPENING_TAG = '___TEMPLATE_VARIABLE_OPENING_TAG___' TEMPLATE_VARIABLE_CLOSING_TAG = '___TEMPLATE_VARIABLE_CLOSING_TAG___' +TEMPLATE_BRACKET_OPENING_TAG = '___TEMPLATE_BRACKET_OPENING_TAG___' +TEMPLATE_BRACKET_CLOSING_TAG = '___TEMPLATE_BRACKET_CLOSING_TAG___' def strip_line(single_line): """Strips the line and replaces neighbouring whitespaces with single space (except when within quotation marks).""" @@ -85,6 +87,37 @@ def strip_variable_template_tags(line: str) -> str: line, flags=re.UNICODE) +def apply_bracket_template_tags(content: str) -> str: + """ Replaces bracket { and } with tags, so subsequent formatting is easier.""" + result = "" + in_quotes = False + last_c = "" + + for c in content: + if (c == "\'" or c == "\"") and last_c != "\\": + in_quotes = reverse_in_quotes_status(in_quotes) + if in_quotes: + if c == "{": + result += TEMPLATE_BRACKET_OPENING_TAG + elif c == "}": + result += TEMPLATE_BRACKET_CLOSING_TAG + else: + result += c + else: + result += c + last_c = c + return result + +def reverse_in_quotes_status(status: bool) -> bool: + if status: + return False + return True + +def strip_bracket_template_tags(content: str) -> str: + """ Replaces tags back with { and } respectively.""" + content = content.replace(TEMPLATE_BRACKET_OPENING_TAG, "{", -1) + content = content.replace(TEMPLATE_BRACKET_CLOSING_TAG, "}", -1) + return content def clean_lines(orig_lines) -> list: """Strips the lines and splits them if they contain curly brackets.""" @@ -147,12 +180,14 @@ def perform_indentation(lines): def format_config_contents(contents): """Accepts the string containing nginx configuration and returns formatted one. Adds newline at the end.""" + contents = apply_bracket_template_tags(contents) lines = contents.splitlines() lines = clean_lines(lines) lines = join_opening_bracket(lines) lines = perform_indentation(lines) text = '\n'.join(lines) + text = strip_bracket_template_tags(text) for pattern, substitute in ((r'\n{3,}', '\n\n\n'), (r'^\n', ''), (r'\n$', '')): text = re.sub(pattern, substitute, text, re.MULTILINE) diff --git a/test_nginxfmt.py b/test_nginxfmt.py index 6eb9da7..69c1f83 100644 --- a/test_nginxfmt.py +++ b/test_nginxfmt.py @@ -89,6 +89,14 @@ class TestFormatter(unittest.TestCase): self.assertEqual('lorem ipsum " foo bar zip " or " dd aa " mi', strip_line(' lorem ipsum " foo bar zip " or \t " dd aa " mi')) + def test_apply_bracket_template_tags(self): + self.assertEqual("\"aaa___TEMPLATE_BRACKET_OPENING_TAG___dd___TEMPLATE_BRACKET_CLOSING_TAG___bbb\"", apply_bracket_template_tags("\"aaa{dd}bbb\"")) + self.assertEqual("\"aaa___TEMPLATE_BRACKET_OPENING_TAG___dd___TEMPLATE_BRACKET_CLOSING_TAG___bbb\"cc{cc}cc\"dddd___TEMPLATE_BRACKET_OPENING_TAG___eee___TEMPLATE_BRACKET_CLOSING_TAG___fff\"", apply_bracket_template_tags("\"aaa{dd}bbb\"cc{cc}cc\"dddd{eee}fff\"")) + + def test_strip_bracket_template_tags(self): + self.assertEqual("\"aaa{dd}bbb\"", strip_bracket_template_tags("\"aaa___TEMPLATE_BRACKET_OPENING_TAG___dd___TEMPLATE_BRACKET_CLOSING_TAG___bbb\"")) + self.assertEqual("\"aaa{dd}bbb\"cc{cc}cc\"dddd{eee}fff\"", apply_bracket_template_tags("\"aaa___TEMPLATE_BRACKET_OPENING_TAG___dd___TEMPLATE_BRACKET_CLOSING_TAG___bbb\"cc{cc}cc\"dddd___TEMPLATE_BRACKET_OPENING_TAG___eee___TEMPLATE_BRACKET_CLOSING_TAG___fff\"")) + def test_variable_template_tags(self): self.assertEqual("foo bar ___TEMPLATE_VARIABLE_OPENING_TAG___myvar___TEMPLATE_VARIABLE_CLOSING_TAG___", apply_variable_template_tags("foo bar ${myvar}"))