diff --git a/src/builder.nim b/src/builder.nim index 876d270..4c0bd9e 100644 --- a/src/builder.nim +++ b/src/builder.nim @@ -1,39 +1,38 @@ -import cursor, parser, types +import cursor, parser, types, tables type Builder* = ref object of RootObj parser*: Parser cursor: Cursor tags: seq[Tag] -method find_closer(this: Builder, tag: Token): bool {.base.} = +method find_closers(this: Builder) {.base.} = var initial_index = this.cursor.get_index() - var name = tag.name - var closer_expected = 1 + var opened_tags = initTable[string, seq[Token]]() for token in this.cursor.iter(): - if token.kind == TokenType.TagCloser and token.name == name: - dec closer_expected - elif token.kind == TokenType.TagOpener and token.name == name: - inc closer_expected - if closer_expected == 0: - this.cursor.go_to(initial_index) - return true + if token.kind == TokenType.TagOpener: + if opened_tags.hasKey token.name: + opened_tags[token.name].add(token) + else: + opened_tags[token.name] = @[token] + elif token.kind == TokenType.TagCloser: + if opened_tags.hasKey(token.name) and len(opened_tags[token.name]) > 0: + opened_tags[token.name][len(opened_tags[token.name]) - 1].self_closing = false + opened_tags[token.name].delete(len(opened_tags[token.name]) - 1) this.cursor.go_to(initial_index) - return false method build*(this: Builder) {.base.} = this.cursor = Cursor(data: this.parser.tokens) + this.find_closers() var opened_tags: seq[Tag] - var closer_tag = false var tag: Tag for token in this.cursor.iter(): if token.kind == TokenType.TagOpener: - closer_tag = this.find_closer(token) - tag = Tag(name: token.name, args: token.args, level: len(opened_tags), no_closer: not closer_tag, index: len(this.tags)) - if closer_tag: + tag = Tag(name: token.name, args: token.args, level: len(opened_tags), no_closer: token.self_closing, index: len(this.tags)) + if not tag.no_closer: opened_tags.add(tag) this.tags.add(tag) elif token.kind == TokenType.TagCloser: - if opened_tags[len(opened_tags)-1].name == token.name: + if len(opened_tags) > 0 and opened_tags[len(opened_tags)-1].name == token.name: opened_tags.delete(len(opened_tags)-1) elif token.kind == TokenType.Text: if len(opened_tags) > 0: