readOpeningTag(){
      //save previously collected text data to current node
      this.addTextNode();

      //create new tag
      let tagExp = readTagExp(this, ">" );
      
      // process and skip from tagsStack For unpaired tag, self closing tag, and stop node
      const tagDetail = new TagDetail(tagExp.tagName);
      if(this.isUnpaired(tagExp.tagName)) {
        //TODO: this will lead 2 extra stack operation
        this.outputBuilder.addTag(tagDetail);
        this.outputBuilder.closeTag();
      } else if(tagExp.selfClosing){
        this.outputBuilder.addTag(tagDetail);
        this.outputBuilder.closeTag();
      } else if(this.isStopNode(this.currentTagDetail)){
        // TODO: let's user set a stop node boundary detector for complex contents like script tag
        //TODO: pass tag name only to avoid string operations
        const content = source.readUptoCloseTag(`</${tagExp.tagName}`);
        this.outputBuilder.addTag(tagDetail);
        this.outputBuilder.addValue(content);
        this.outputBuilder.closeTag();
      }else{//paired tag
        //set new nested tag in scope.
        this.tagsStack.push(this.currentTagDetail);
        this.outputBuilder.addTag(tagDetail);
        this.currentTagDetail = tagDetail;
      }
      // console.log(tagExp.tagName,this.tagsStack.length);
      // this.options.onClose()

    }
Read paired, unpaired, self-closing, stop and special tags.
Create a new node
Push paired tag in stack.