diff --git a/djhtml/__main__.py b/djhtml/__main__.py index c346b3b..ffb693f 100644 --- a/djhtml/__main__.py +++ b/djhtml/__main__.py @@ -71,7 +71,9 @@ def main(): # Indent input file try: - result = Mode(source).indent(options.tabwidth or guess or 4) + result = Mode(source, extra_blocks=options.extra_block).indent( + options.tabwidth or guess or 4 + ) except modes.MaxLineLengthExceeded: problematic_files += 1 _error(f"Maximum line length exceeded in {filename}") diff --git a/djhtml/modes.py b/djhtml/modes.py index d017da3..5f6238e 100644 --- a/djhtml/modes.py +++ b/djhtml/modes.py @@ -12,7 +12,7 @@ class BaseMode: MAX_LINE_LENGTH = 10_000 - def __init__(self, source=None, return_mode=None): + def __init__(self, source=None, return_mode=None, extra_blocks=None): """ Instantiate with source text before calling indent(), or with the return_mode when invoked from within another mode. @@ -24,6 +24,7 @@ def __init__(self, source=None, return_mode=None): self.source = source self.return_mode = return_mode or self self.token_re = compile_re(self.RAW_TOKENS) + self.extra_blocks = dict(extra_blocks or []) # To keep track of the current and previous offsets. self.offsets = dict(relative=0, absolute=0) @@ -241,6 +242,9 @@ def create_token(self, raw_token, src, line): return token, mode def _has_closing_token(self, name, raw_token, src): + endtag = self.extra_blocks.get(name) + if endtag: + return re.search(f"{{%[-+]? *{endtag}(?: .*?|)%}}", src) if not re.search(f"{{%[-+]? *(end_?|/){name}(?: .*?|)%}}", src): return False if regex := self.AMBIGUOUS_BLOCK_TAGS.get(name): @@ -406,6 +410,7 @@ def __init__(self, *args, **kwargs): self.haskell_re = re.compile(r"^ *, ([$\w-]+ *=|[$\w-]+;?)") self.variable_re = re.compile(r"^ *([$\w-]+ *=|[$\w-]+;?)") self.previous_line_ended_with_comma = False + self.extra_blocks = {} def create_token(self, raw_token, src, line): mode = self @@ -513,6 +518,7 @@ def __init__(self, endtag, *, mode, return_mode): self.mode = mode self.return_mode = return_mode self.token_re = compile_re([r"\n", endtag]) + self.extra_blocks = {} def create_token(self, raw_token, src, line): if re.match(self.endtag, raw_token): @@ -536,6 +542,7 @@ def __init__(self, tagname, line, return_mode, absolute, offsets): self.token_re = compile_re(self.RAW_TOKENS) self.inside_attr = False self.additional_offset = -len(tagname) - 1 if absolute else 0 + self.extra_blocks = {} def create_token(self, raw_token, src, line): mode = self diff --git a/djhtml/options.py b/djhtml/options.py index 3d05b85..831f9b0 100644 --- a/djhtml/options.py +++ b/djhtml/options.py @@ -58,6 +58,13 @@ ) parser.add_argument("-d", "--debug", action="store_true", help=argparse.SUPPRESS) parser.add_argument("-i", "--in-place", action="store_true", help=argparse.SUPPRESS) +parser.add_argument( + "-b", + "--extra-block", + action="append", + help="startblock,endblock pair", + type=lambda x: tuple(x.split(",")), +) # Parse arguments and assign attributes to self self = sys.modules[__name__] diff --git a/tests/suite/django.html b/tests/suite/django.html index bea3af6..73da8db 100644 --- a/tests/suite/django.html +++ b/tests/suite/django.html @@ -195,3 +195,8 @@