JBBCode/Parser.php
protected function parseTag(ElementNode $parent, Tokenizer $tokenizer, $tagContent)
    {
        if (!$tokenizer->hasNext() || ($next = $tokenizer->next()) != ']') {
            /* This is a malformed tag. Both the previous [ and the tagContent
             * is really just plain text. */
            $this->createTextNode($parent, '[');
            $this->createTextNode($parent, $tagContent);
            return $parent;
        }

        /* This is a well-formed tag consisting of [something] or [/something], but
         * we still need to ensure that 'something' is a valid tag name. Additionally,
         * if it's a closing tag, we need to ensure that there was a previous matching
         * opening tag.
         */
        /* There could be attributes. */
        list($tmpTagName, $options) = $this->parseOptions($tagContent);

        // $tagPieces = explode('=', $tagContent);
        // $tmpTagName = $tagPieces[0];

        $actualTagName = $tmpTagName;
        if ('' != $tmpTagName && '/' == $tmpTagName[0]) {
            /* This is a closing tag name. */
            $actualTagName = substr($tmpTagName, 1);
        }

        if ('' != $tmpTagName && '/' == $tmpTagName[0]) {
            /* This is attempting to close an open tag. We must verify that there exists an
             * open tag of the same type and that there is no option (options on closing
             * tags don't make any sense). */
            $elToClose = $parent->closestParentOfType($actualTagName);
            if (null == $elToClose || count($options) > 1) {
                /* Closing an unopened tag or has an option. Treat everything as plain text. */
                $this->createTextNode($parent, '[');
                $this->createTextNode($parent, $tagContent);
                $this->createTextNode($parent, ']');
                return $parent;
            } else {
                /* We're closing $elToClose. In order to do that, we just need to return
                 * $elToClose's parent, since that will change our effective parent to be
                 * elToClose's parent. */
                return $elToClose->getParent();
            }
        }

        /* Verify that this is a known bbcode tag name. */
        if ('' == $actualTagName || !$this->codeExists($actualTagName, !empty($options))) {
            /* This is an invalid tag name! Treat everything we've seen as plain text. */
            $this->createTextNode($parent, '[');
            $this->createTextNode($parent, $tagContent);
            $this->createTextNode($parent, ']');
            return $parent;
        }

        /* If we're here, this is a valid opening tag. Let's make a new node for it. */
        $el = new ElementNode();
        $code = $this->getCode($actualTagName, !empty($options));
        $el->setCodeDefinition($code);
        if (!empty($options)) {
            /* We have an attribute we should save. */
            $el->setAttribute($options);
        }
        $parent->addChild($el);
        return $el;
    }
protected function parseTag(ElementNode $parent, Tokenizer $tokenizer, $tagContent)
    {
        if (!$tokenizer->hasNext() || ($next = $tokenizer->next()) != ']') {
            /* This is a malformed tag. Both the previous [ and the tagContent
             * is really just plain text. */
            $this->createTextNode($parent, '[');
            $this->createTextNode($parent, $tagContent);
            return $parent;
        }

        /* This is a well-formed tag consisting of [something] or [/something], but
         * we still need to ensure that 'something' is a valid tag name. Additionally,
         * if it's a closing tag, we need to ensure that there was a previous matching
         * opening tag.
         */
        /* There could be attributes. */
        list($tmpTagName, $options) = $this->parseOptions($tagContent);

        // $tagPieces = explode('=', $tagContent);
        // $tmpTagName = $tagPieces[0];

        $actualTagName = $tmpTagName;
        if ('' != $tmpTagName && '/' == $tmpTagName[0]) {
            /* This is a closing tag name. */
            $actualTagName = substr($tmpTagName, 1);
        }

        if ('' != $tmpTagName && '/' == $tmpTagName[0]) {
            /* This is attempting to close an open tag. We must verify that there exists an
             * open tag of the same type and that there is no option (options on closing
             * tags don't make any sense). */
            $elToClose = $parent->closestParentOfType($actualTagName);
            if (null == $elToClose || count($options) > 1) {
                /* Closing an unopened tag or has an option. Treat everything as plain text. */
                $this->createTextNode($parent, '[');
                $this->createTextNode($parent, $tagContent);
                $this->createTextNode($parent, ']');
                return $parent;
            } else {
                /* We're closing $elToClose. In order to do that, we just need to return
                 * $elToClose's parent, since that will change our effective parent to be
                 * elToClose's parent. */
                return $elToClose->getParent();
            }
        }

        /* Verify that this is a known bbcode tag name. */
        if ('' == $actualTagName || !$this->codeExists($actualTagName, !empty($options))) {
            /* This is an invalid tag name! Treat everything we've seen as plain text. */
            $this->createTextNode($parent, '[');
            $this->createTextNode($parent, $tagContent);
            $this->createTextNode($parent, ']');
            return $parent;
        }

        /* If we're here, this is a valid opening tag. Let's make a new node for it. */
        $el = new ElementNode();
        $code = $this->getCode($actualTagName, !empty($options));
        $el->setCodeDefinition($code);
        if (!empty($options)) {
            /* We have an attribute we should save. */
            $el->setAttribute($options);
        }
        $parent->addChild($el);
        return $el;
    }
protected function parseTag ( ElementNode $ parent , Tokenizer $ tokenizer , $ tagContent ) { if ( ! $ tokenizer -> hasNext ( ) || ( $ next = $ tokenizer -> next ( ) ) != ']' ) { /* This is a malformed tag. Both the previous [ and the tagContent
             * is really just plain text. */ $ this -> createTextNode ( $ parent , '[' ) ; $ this -> createTextNode ( $ parent , $ tagContent ) ; return $ parent ; } /* This is a well-formed tag consisting of [something] or [/something], but
         * we still need to ensure that 'something' is a valid tag name. Additionally,
         * if it's a closing tag, we need to ensure that there was a previous matching
         * opening tag.
         */ /* There could be attributes. */ list ( $ tmpTagName , $ options ) = $ this -> parseOptions ( $ tagContent ) ; // $tagPieces = explode('=', $tagContent); // $tmpTagName = $tagPieces[0]; $ actualTagName = $ tmpTagName ; if ( '' != $ tmpTagName && '/' == $ tmpTagName [ 0 ] ) { /* This is a closing tag name. */ $ actualTagName = substr ( $ tmpTagName , 1 ) ; } if ( '' != $ tmpTagName && '/' == $ tmpTagName [ 0 ] ) { /* This is attempting to close an open tag. We must verify that there exists an
             * open tag of the same type and that there is no option (options on closing
             * tags don't make any sense). */ $ elToClose = $ parent -> closestParentOfType ( $ actualTagName ) ; if ( null == $ elToClose || count ( $ options ) > 1 ) { /* Closing an unopened tag or has an option. Treat everything as plain text. */ $ this -> createTextNode ( $ parent , '[' ) ; $ this -> createTextNode ( $ parent , $ tagContent ) ; $ this -> createTextNode ( $ parent , ']' ) ; return $ parent ; } else { /* We're closing $elToClose. In order to do that, we just need to return
                 * $elToClose's parent, since that will change our effective parent to be
                 * elToClose's parent. */ return $ elToClose -> getParent ( ) ; } } /* Verify that this is a known bbcode tag name. */ if ( '' == $ actualTagName || ! $ this -> codeExists ( $ actualTagName , ! empty ( $ options ) ) ) { /* This is an invalid tag name! Treat everything we've seen as plain text. */ $ this -> createTextNode ( $ parent , '[' ) ; $ this -> createTextNode ( $ parent , $ tagContent ) ; $ this -> createTextNode ( $ parent , ']' ) ; return $ parent ; } /* If we're here, this is a valid opening tag. Let's make a new node for it. */ $ el = new ElementNode ( ) ; $ code = $ this -> getCode ( $ actualTagName , ! empty ( $ options ) ) ; $ el -> setCodeDefinition ( $ code ) ; if ( ! empty ( $ options ) ) { /* We have an attribute we should save. */ $ el -> setAttribute ( $ options ) ; } $ parent -> addChild ( $ el ) ; return $ el ; }
This is the next step in parsing a tag. It's possible for it to still be invalid at this
point but many of the basic invalid tag name conditions have already been handled.

@param ElementNode $parent  the current parent element
@param Tokenizer   $tokenizer  the tokenizer we're using
@param string      $tagContent  the text between the [ and the ], assuming there is actually a ]

@return ElementNode the new parent element
This is the next step in parsing a tag . It s possible for it to still be invalid at this point but many of the basic invalid tag name conditions have already been handled .