Process given start tag (including self-closing tags) at current position

@param  Tag  $tag Start tag (including self-closing)
@return void
778858
protected function processStartTag(Tag $tag)
	{
		$tagName   = $tag->getName();
		$tagConfig = $this->tagsConfig[$tagName];

		// 1. Check that this tag has not reached its global limit tagLimit
		// 2. Execute this tag's filterChain, which will filter/validate its attributes
		// 3. Apply closeParent, closeAncestor and fosterParent rules
		// 4. Check for nestingLimit
		// 5. Apply requireAncestor rules
		//
		// This order ensures that the tag is valid and within the set limits before we attempt to
		// close parents or ancestors. We need to close ancestors before we can check for nesting
		// limits, whether this tag is allowed within current context (the context may change
		// as ancestors are closed) or whether the required ancestors are still there (they might
		// have been closed by a rule.)
		if ($this->cntTotal[$tagName] >= $tagConfig['tagLimit'])
		{
			$this->logger->err(
				'Tag limit exceeded',
				[
					'tag'      => $tag,
					'tagName'  => $tagName,
					'tagLimit' => $tagConfig['tagLimit']
				]
			);
			$tag->invalidate();

			return;
		}

		FilterProcessing::filterTag($tag, $this, $this->tagsConfig, $this->openTags);
		if ($tag->isInvalid())
		{
			return;
		}

		if ($this->currentFixingCost < $this->maxFixingCost)
		{
			if ($this->fosterParent($tag) || $this->closeParent($tag) || $this->closeAncestor($tag))
			{
				// This tag parent/ancestor needs to be closed, we just return (the tag is still valid)
				return;
			}
		}

		if ($this->cntOpen[$tagName] >= $tagConfig['nestingLimit'])
		{
			$this->logger->err(
				'Nesting limit exceeded',
				[
					'tag'          => $tag,
					'tagName'      => $tagName,
					'nestingLimit' => $tagConfig['nestingLimit']
				]
			);
			$tag->invalidate();

			return;
		}

		if (!$this->tagIsAllowed($tagName))
		{
			$msg     = 'Tag is not allowed in this context';
			$context = ['tag' => $tag, 'tagName' => $tagName];
			if ($tag->getLen() > 0)
			{
				$this->logger->warn($msg, $context);
			}
			else
			{
				$this->logger->debug($msg, $context);
			}
			$tag->invalidate();

			return;
		}

		if ($this->requireAncestor($tag))
		{
			$tag->invalidate();

			return;
		}

		// If this tag has an autoClose rule and it's not paired with an end tag or followed by an
		// end tag, we replace it with a self-closing tag with the same properties
		if ($tag->getFlags() & self::RULE_AUTO_CLOSE
		 && !$tag->getEndTag()
		 && !$this->isFollowedByClosingTag($tag))
		{
			$newTag = new Tag(Tag::SELF_CLOSING_TAG, $tagName, $tag->getPos(), $tag->getLen());
			$newTag->setAttributes($tag->getAttributes());
			$newTag->setFlags($tag->getFlags());

			$tag = $newTag;
		}

		if ($tag->getFlags() & self::RULE_TRIM_FIRST_LINE
		 && !$tag->getEndTag()
		 && substr($this->text, $tag->getPos() + $tag->getLen(), 1) === "\n")
		{
			$this->addIgnoreTag($tag->getPos() + $tag->getLen(), 1);
		}

		// This tag is valid, output it and update the context
		$this->outputTag($tag);
		$this->pushContext($tag);

		// Apply the createChild rules if applicable
		$this->createChild($tag);
	}
796325
public function begin_tag($tag, $attributes = null) {
        // TODO: chek the tag name is valid
        $pre = $this->level ? "\n" . str_repeat(' ', $this->level * 2) : ''; // Indent
        $tag = $this->casefolding ? strtoupper($tag) : $tag; // Follow casefolding
        $end = $this->nullcontent ? ' /' : ''; // Tag without content, close it

        // Build attributes output
        $attrstring = '';
        if (!empty($attributes) && is_array($attributes)) {
            // TODO: check the attr name is valid
            foreach ($attributes as $name => $value) {
                $name = $this->casefolding ? strtoupper($name) : $name; // Follow casefolding
                $attrstring .= ' ' . $name . '="'.
                    $this->xml_safe_attr_content($value) . '"';
            }
        }

        // Optional xml schema definition (level 0 only)
        $schemastring = '';
        if ($this->level == 0 && !empty($this->xmlschema)) {
            $schemastring .= "\n    " . 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' .
                             "\n    " . 'xsi:noNamespaceSchemaLocation="' . $this->xml_safe_attr_content($this->xmlschema) . '"';
        }

        // Send to xml_output
        $this->write($pre . '<' . $tag . $attrstring . $schemastring . $end . '>');

        // Acumulate the tag and inc level
        if (!$this->nullcontent) {
            array_push($this->opentags, $tag);
            $this->level++;
        }
        $this->lastwastext = false;
    }
77715
function _tag_close( &$parser, $tag ) {
		$this->currentElement = '';

		switch( strtoupper( $tag ) ) {
			case 'TABLE':
				$this->parent->addSQL( $this->create( $this->parent ) );
				xml_set_object( $parser, $this->parent );
				$this->destroy();
				break;
			case 'FIELD':
				unset($this->current_field);
				break;

		}
	}
1193955
protected function publishTag($tag)
    {
        foreach ($this->pathsToPublish($tag) as $from => $to) {
            $this->publishItem($from, $to);
        }
    }
829398
def start_tag(self) -> str:
        """"""
        tag = '<' + self.tag
        attrs = self._get_attrs_by_string()
        if attrs:
            tag = ' '.join((tag, attrs))
        return tag + '>'
770877
public function removeTag($tag)
    {
        $this->tag = $tag;
        $this->getLogger()->info('Removing tag: ' . $tag . ' from layout ID ' . $this->layoutId);
        $this->doPost('/layout/' . $this->layoutId . '/untag', [
            'tag' => [$tag]
        ]);

        return $this;
    }
70866
public function pairWith(Tag $tag)
	{
		if ($this->name === $tag->name)
		{
			if ($this->type === self::START_TAG
			 && $tag->type  === self::END_TAG
			 && $tag->pos   >=  $this->pos)
			{
				$this->endTag  = $tag;
				$tag->startTag = $this;

				$this->cascadeInvalidationTo($tag);
			}
			elseif ($this->type === self::END_TAG
			     && $tag->type  === self::START_TAG
			     && $tag->pos   <=  $this->pos)
			{
				$this->startTag = $tag;
				$tag->endTag    = $this;
			}
		}
	}
1373247
public function removeTag(Tag $tag)
    {
        if ($this->tags->contains($tag)) {
            $this->tags->removeElement($tag);
            return true;
        }
        return false;
    }
877483
private function htmlEndHandler($tag): void
    {
        if ($tag === 'tempdoc') {
            return;
        }

        $this->print_data      = array_pop($this->print_data_stack);
        $this->current_element = $this->wt_report;
        $this->wt_report       = array_pop($this->wt_report_stack);
        if ($this->wt_report !== null) {
            $this->wt_report->addElement($this->current_element);
        } else {
            $this->wt_report = $this->current_element;
        }
    }
454251
public function detachTag(Tag $tag)
    {
        if (!$this->hasTag($tag)) {
            throw new OutOfBoundsException('Tag '.$tag->getName().' is not attached');
        }

        $this->_tags = array_filter($this->_tags, function ($knownTag) use ($tag) {
            return $tag->getId() != $knownTag->getId();
        });

        return $this;
    }
934674
public function clearTag(string $tag): void
    {
        // 指定标签清除
        $keys = $this->getTagItems($tag);

        $this->handler->deleteMulti($keys);

        $tagName = $this->getTagKey($tag);
        $this->rm($tagName);
    }
1246673
private void processTag(boolean start) {
    	if (start) {
    		nested++;
    		doc.startElement(tag,attributes);
    	}
    	else {
            nested--;
            doc.endElement(tag);
    	}
    }
652420
public function clearTag(string $tag): void
    {
        // 指定标签清除
        $keys = $this->getTagItems($tag);

        $this->handler->del($keys);

        $tagName = $this->getTagKey($tag);
        $this->handler->del($tagName);
    }
487594
public function normalizeTag(Tag $tag)
	{
		if (isset($tag->template) && !$tag->template->isNormalized())
		{
			$tag->template->normalize($this);
		}
	}
963161
public function withTag($tag) {
        if (is_null($this->tags)) {
            $this->tags = [];
        }

        array_push($this->tags, $tag);
        return $this;
    }
471687
protected function createChild(Tag $tag)
	{
		$tagConfig = $this->tagsConfig[$tag->getName()];
		if (isset($tagConfig['rules']['createChild']))
		{
			$priority = -1000;
			$tagPos   = $this->pos + strspn($this->text, " \n\r\t", $this->pos);
			foreach ($tagConfig['rules']['createChild'] as $tagName)
			{
				$this->addStartTag($tagName, $tagPos, 0, ++$priority);
			}
		}
	}
562249
protected function tearDown(): void
    {
        parent::tearDown();

        $this->resetDocCommentPos();

        $this->processedTagRules = null;
        $this->tags = null;
    }