The HTML DTD allows a tag to implicitly close other tags.
          The list is kept in htmlStartClose array. This function
           checks if a tag is autoclosed by one of it's child
514610
def htmlIsAutoClosed(self, elem):
        
        ret = libxml2mod.htmlIsAutoClosed(self._o, elem)
        return ret
1136431
def removeHtmlTags(self, text):
		""""""
		sb = []
		text = self.removeHtmlComments(text)
		bits = text.split(u'<')
		sb.append(bits.pop(0))
		tagstack = []
		tablestack = tagstack
		for x in bits:
			m = _tagPattern.match(x)
			if not m:
				continue
			slash, t, params, brace, rest = m.groups()
			t = t.lower()
			badtag = False
			if t in _htmlelements:
				# Check our stack
				if slash:
					# Closing a tag...
					if t in _htmlsingleonly or len(tagstack) == 0:
						badtag = True
					else:
						ot = tagstack.pop()
						if ot != t:
							if ot in _htmlsingleallowed:
								# Pop all elements with an optional close tag
								# and see if we find a match below them
								optstack = []
								optstack.append(ot)
								while True:
									if len(tagstack) == 0:
										break
									ot = tagstack.pop()
									if ot == t or ot not in _htmlsingleallowed:
										break
									optstack.append(ot)
								if t != ot:
									# No match. Push the optinal elements back again
									badtag = True
									tagstack += reversed(optstack)
							else:
								tagstack.append(ot)
								# <li> can be nested in <ul> or <ol>, skip those cases:
								if ot not in _htmllist and t in _listtags:
									badtag = True
						elif t == u'table':
							if len(tablestack) == 0:
								bagtag = True
							else:
								tagstack = tablestack.pop()
					newparams = u''
				else:
					# Keep track for later
					if t in _tabletags and u'table' not in tagstack:
						badtag = True
					elif t in tagstack and t not in _htmlnest:
						badtag = True
					# Is it a self-closed htmlpair? (bug 5487)
					elif brace == u'/>' and t in _htmlpairs:
						badTag = True
					elif t in _htmlsingleonly:
						# Hack to force empty tag for uncloseable elements
						brace = u'/>'
					elif t in _htmlsingle:
						# Hack to not close $htmlsingle tags
						brace = None
					else:
						if t == u'table':
							tablestack.append(tagstack)
							tagstack = []
						tagstack.append(t)
					newparams = self.fixTagAttributes(params, t)
				if not badtag:
					rest = rest.replace(u'>', u'&gt;')
					if brace == u'/>':
						close = u' /'
					else:
						close = u''
					sb.append(u'<')
					sb.append(slash)
					sb.append(t)
					sb.append(newparams)
					sb.append(close)
					sb.append(u'>')
					sb.append(rest)
					continue
			sb.append(u'&lt;')
			sb.append(x.replace(u'>', u'&gt;'))

		# Close off any remaining tags
		while tagstack:
			t = tagstack.pop()
			sb.append(u'</')
			sb.append(t)
			sb.append(u'>\n')
			if t == u'table':
				if not tablestack:
					break
				tagstack = tablestack.pop()

		return u''.join(sb)
364932
boolean canContain(Tag parent, Tag child) {
    Validate.notNull(child);

    if (child.isBlock() && !parent.canContainBlock())
      return false;

    if (!child.isBlock() && parent.isData())
      return false;

    if (closingOptional.contains(parent.getName()) && parent.getName().equals(child.getName()))
      return false;

    if (parent.isEmpty() || parent.isData())
      return false;

    // head can only contain a few. if more than head in here, modify to have a list of valids
    // TODO: (could solve this with walk for ancestor)
    if (parent.getName().equals("head")) {
      if (headTags.contains(child.getName()))
        return true;
      else
        return false;
    }

    // dt and dd (in dl)
    if (parent.getName().equals("dt") && child.getName().equals("dd"))
      return false;
    if (parent.getName().equals("dd") && child.getName().equals("dt"))
      return false;

    return true;
  }
499181
private function tag_close($tag)
	{
		if(!$this->current_tag instanceof Node_Container_Document
			&& $tag !== $this->current_tag->tag())
		{
			$closing_tags = $this->bbcodes[$this->current_tag->tag()]->closing_tags();

			if(in_array($tag, $closing_tags) || in_array('/' . $tag, $closing_tags))
				$this->current_tag = $this->current_tag->parent();
		}

		if($this->current_tag instanceof Node_Container_Document)
			return false;
		else if($tag !== $this->current_tag->tag())
		{
			// check if this is a tag inside another tag like
			// [tag1] [tag2] [/tag1] [/tag2]
			$node = $this->current_tag->find_parent_by_tag($tag);

			if($node !== null)
			{
				$this->current_tag = $node->parent();

				while(($node = $node->last_tag_node()) !== null)
				{
					$new_node = new Node_Container_Tag($node->tag(), $node->attributes());
					$this->current_tag->add_child($new_node);
					$this->current_tag = $new_node;
				}
			}
			else
				return false;
		}
		else
			$this->current_tag = $this->current_tag->parent();

		return true;
	}
254946
def handle_endtag(self, tagName):
        '''
            
        '''
        try:
            foundIt = False
            inTag = self._inTag
            for i in range(len(inTag)):
                if inTag[i].tagName == tagName:
                    foundIt = True
                    break

            if not foundIt:
                return
            # Handle closing tags which should have been closed but weren't
            while inTag[-1].tagName != tagName:
                inTag.pop()

            inTag.pop()
        except:
            pass
402087
@VisibleForTesting
  static String embedCssIntoHtml(String css) {
    // `</style` can close a containing style element in HTML.
    // `]]>` can similarly close a CDATA element in XHTML.

    // Scan for "</" and "]]>" and escape enough to remove the token seen by
    // the HTML parser.

    // For well-formed CSS, these string might validly appear in a few contexts:
    // 1. comments
    // 2. string bodies
    // 3. url(...) bodies.

    // Appending \ should be semantics preserving in comments and string bodies.
    // This may not be semantics preserving in url content.
    // The substring "]>" can validly appear in a selector
    //   a[href]>b
    // but the substring "]]>" cannot.

    // This should not affect how a CSS parser recovers from syntax errors.
    int indexOfEndTag = css.indexOf("</");
    int indexOfEndCData = css.indexOf("]]>");
    if (indexOfEndTag != -1) {
      if (indexOfEndCData != -1) {
        return embedCssIntoHtmlSlow(
            css,
            Math.min(indexOfEndTag, indexOfEndCData),
            /* searchForEndCData= */ true,
            /* searchForEndTag= */ true);
      }
      return embedCssIntoHtmlSlow(
          css, indexOfEndTag, /* searchForEndCData= */ false, /* searchForEndTag= */ true);
    } else if (indexOfEndCData != -1) {
      return embedCssIntoHtmlSlow(
          css, indexOfEndCData, /* searchForEndCData= */ true, /* searchForEndTag= */ false);
    }
    return css;
  }
1077352
function(tag, parent, interpolated){
    this.indents++;
    var name = tag.name
      , pp = this.pp
      , self = this;
    var ast = [];

    function bufferName() {
      if (interpolated) {
        if (tag.astExpr) return self.bufferAST(tag.astExpr);
        return self.bufferExpression(tag.expr);
      }
      else return self.buffer(name);
    }

    if (WHITE_SPACE_SENSITIVE_TAGS[tag.name] === true) this.escapePrettyMode = true;

    if (!this.hasCompiledTag) {
      if (!this.hasCompiledDoctype && 'html' == name) {
        push.apply(ast, this.visitDoctype());
      }
      this.hasCompiledTag = true;
    }
    // pretty print
    if (pp && !tag.isInline)
      push.apply(ast, this.prettyIndent(0, true));
    if (tag.selfClosing || (!this.xml && selfClosing[tag.name])) {
      push.apply(ast, this.buffer('<'));
      push.apply(ast, bufferName());
      push.apply(ast, this.visitAttributes(tag.attrs, this.attributeBlocks(tag.attributeBlocks)));
      if (this.terse && !tag.selfClosing) {
        push.apply(ast, this.buffer('>'));
      } else {
        push.apply(ast, this.buffer('/>'));
      }
      // if it is non-empty throw an error
      if (tag.code ||
          tag.block &&
          !(tag.block.type === 'Block' && tag.block.nodes.length === 0) &&
          tag.block.nodes.some(function (tag) {
            return tag.type !== 'Text' || !/^\s*$/.test(tag.val)
          })) {
        this.error(name + ' is a self closing element: <'+name+'/> but contains nested content.', 'SELF_CLOSING_CONTENT', tag);
      }
    } else {
      // Optimize attributes buffering
      push.apply(ast, this.buffer('<'));
      push.apply(ast, bufferName());
      push.apply(ast, this.visitAttributes(tag.attrs, this.attributeBlocks(tag.attributeBlocks)));
      push.apply(ast, this.buffer('>'));
      if (tag.code) push.apply(ast, this.visitCode(tag.code));
      push.apply(ast, this.visit(tag.block, tag));

      // pretty print
      if (pp && !tag.isInline && WHITE_SPACE_SENSITIVE_TAGS[tag.name] !== true && !tagCanInline(tag))
        push.apply(ast, this.prettyIndent(0, true));

      push.apply(ast, this.buffer('</'));
      push.apply(ast, bufferName());
      push.apply(ast, this.buffer('>'));
    }

    if (WHITE_SPACE_SENSITIVE_TAGS[tag.name] === true) this.escapePrettyMode = false;

    this.indents--;
    return ast;
  }
952392
private static String outerHtml(List<Element> elements) {

		switch (elements.size()) {
		case 0:
			return "";
		case 1:
			return elements.get(0).outerHtml();
		default: {
			// more than one element
			// wrap into <div> which we will remove afterwards
			Element root = new Element(Tag.valueOf("div"), "");
			for (Element elem : elements) {
				root.appendChild(elem);
			}

			return root.html();
		}
		}
	}
143214
def handle_starttag(self, tag, attrs):
        
        # Parse the tag attributes
        attrs_dict = dict(t for t in attrs)

        # If the tag is a predefined parent element
        if tag in PARENT_ELEMENTS:
            # If parser is parsing another parent element
            if self.current_parent_element['tag'] != '':
                # close the parent element
                self.cleaned_html += '</{}>'.format(self.current_parent_element['tag'])

            self.current_parent_element['tag'] = tag
            self.current_parent_element['attrs'] = {}

            self.cleaned_html += '<{}>'.format(tag)

        # If the tag is a list item
        elif tag == 'li':
            self.parsing_li = True

            # Parse the class name & subsequent type
            class_name = attrs_dict['class']
            list_type = class_name[10:]

            # Check if parsing a list
            if self.current_parent_element['tag'] == 'ul' or self.current_parent_element['tag'] == 'ol':
                cur_list_type = self.current_parent_element['attrs']['class']
                # Parsing a different list
                if cur_list_type != list_type:
                    # Close that list
                    self._close_list()

                    # Open new list
                    self._open_list(list_type)
            # Not parsing a list
            else:
                # if parsing some other parent
                if self.current_parent_element['tag'] != '':
                    self.cleaned_html += '</{}>'.format(self.current_parent_element['tag'])
                # Open new list
                self._open_list(list_type)

            self.cleaned_html += '<{}>'.format(tag)

        # If the tag is a line break
        elif tag == 'br':
            # If parsing a paragraph, close it
            if self.current_parent_element['tag'] == 'p':
                self.cleaned_html += '</p>'
                self.current_parent_element['tag'] = ''
                self.current_parent_element['attrs'] = {}
            # If parsing a list, close it
            elif self.current_parent_element['tag'] == 'ul' or self.current_parent_element['tag'] == 'ol':
                self._close_list()
            # If parsing any other parent element, keep it
            elif self.current_parent_element['tag'] in PARENT_ELEMENTS:
                self.cleaned_html += '<br />'
            # If not in any parent element, create an empty paragraph
            else:
                self.cleaned_html += '<p></p>'

        # If the tag is something else, like a <b> or <i> tag
        else:
            # If not parsing any parent element
            if self.current_parent_element['tag'] == '':
                self.cleaned_html += '<p>'
                self.current_parent_element['tag'] = 'p'
            self.cleaned_html += '<{}'.format(tag)

            for attr in sorted(attrs_dict.keys()):
                self.cleaned_html += ' {k}="{v}"'.format(
                    k=attr,
                    v=attrs_dict[attr]
                )

            self.cleaned_html += '>'
902781
public DslPart closeArray() {
      if (parent != null) {
        parent.putArray(this);
      } else {
        getMatchers().applyMatcherRootPrefix("$");
        getGenerators().applyRootPrefix("$");
      }
      closed = true;
      return parent;
    }
1255067
function tag(name, attrs, close, content) {
  var end = close ? '/>' : '>';
  var pairs = [];
  var tag;

  for (var key in attrs) {
    if (Object.prototype.hasOwnProperty.call(attrs, key)) {
      pairs.push(key + '="' + escape(attrs[key]) + '"');
    }
  }

  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
  if (content) {
    tag += content + '</' + name + end;
  }
  return tag;
}
823272
function Tag(page, startPosition, endPosition, attributes) {
        var self = this;
        self.childNodes = [];
        self.firstChild = null;
        self.lastChild = null;
        self.attributes = attributes || [];
        self.nodeType = 1;
        if (typeof page === 'string') {
            createTag.apply(null, [self].concat(util.makeArray(arguments)));
        } else {
            Tag.superclass.constructor.apply(self, arguments);
            attributes = self.attributes;    // first attribute is actually nodeName
            // first attribute is actually nodeName
            if (attributes[0]) {
                self.nodeName = attributes[0].name.toLowerCase();    // end tag (</div>) is a tag too in lexer , but not exist in parsed dom tree
                // end tag (</div>) is a tag too in lexer , but not exist in parsed dom tree
                self.tagName = self.nodeName.replace(/\//, '');
                self._updateSelfClosed();
                attributes.splice(0, 1);
            }
            var lastAttr = attributes[attributes.length - 1], lastSlash = !!(lastAttr && /\/$/.test(lastAttr.name));
            if (lastSlash) {
                attributes.length = attributes.length - 1;
            }    // self-closing flag
            // self-closing flag
            self.isSelfClosed = self.isSelfClosed || lastSlash;    // whether has been closed by its end tag
                                                                   // !TODO how to set closed position correctly
            // whether has been closed by its end tag
            // !TODO how to set closed position correctly
            self.closed = self.isSelfClosed;
        }
        self.closedStartPosition = -1;
        self.closedEndPosition = -1;
    }
85404
protected function _tag_close_THEAD($param)
    {
        if ($this->_isForOneLine) {
            return false;
        }

        $this->parsingCss->load();
        $this->parsingCss->fontSet();

        // if we are in a sub HTM, construct the list of the TR in the thead
        if ($this->_subPart) {
            $min = self::$_tables[$param['num']]['thead']['tr'][0];
            $max = self::$_tables[$param['num']]['tr_curr']-1;
            self::$_tables[$param['num']]['thead']['tr'] = range($min, $max);
        }

        return true;
    }
148493
def handle_starttag(self, tag, attrs):
        """"""
        if tag.lower() in self.allowed_tag_whitelist:
            if tag.lower() == 'ol':
                # we need a list to store the last
                # number used  in the previous ordered lists
                self.previous_nbs.append(self.nb)
                self.nb = 0
                # we need to know which is the tag list
                self.previous_type_lists.append(tag.lower())
                # we must remove any non-relevant spacing and end of
                # line before
                self.result = self.result.rstrip()
            elif tag.lower() == 'ul':
                self.previous_type_lists.append(tag.lower())
                # we must remove any non-relevant spacing and end of
                # line before
                self.result = self.result.rstrip()
            elif tag.lower() == 'li':
                # we must remove any non-relevant spacing and end of
                # line before
                self.result = self.result.rstrip()
                if self.previous_type_lists[-1] == 'ol':
                    self.nb += 1
                    self.result += '\n' + self.line_quotation + \
                                   '  ' * len(self.previous_type_lists) + \
                        str(self.nb) + '. '
                else:
                    self.result += '\n' + self.line_quotation + \
                                   '  ' * len(self.previous_type_lists) + '* '
            elif tag.lower() == 'a':
                # self.previous_type_lists.append(tag.lower())
                for (attr, value) in attrs:
                    if attr.lower() == 'href':
                        self.url = value
                        self.result += '<' + value + '>'
1033393
public static String safeRemoveAllTags(String html) {
        html = removeNonTextTags(html);
        html = unsafeRemoveAllTags(html);
        return html;
    }
278656
function() {
					var range = self.getRanges()[ 0 ].clone(),
						enclosed, selected;

					// Check first any enclosed element, e.g. <ul>[<li><a href="#">item</a></li>]</ul>
					for ( var i = 2; i && !( ( enclosed = range.getEnclosedNode() ) && ( enclosed.type == CKEDITOR.NODE_ELEMENT ) && styleObjectElements[ enclosed.getName() ] && ( selected = enclosed ) ); i-- ) {
						// Then check any deep wrapped element, e.g. [<b><i><img /></i></b>]
						range.shrink( CKEDITOR.SHRINK_ELEMENT );
					}

					return selected && selected.$;
				}
439643
def innerHTML(self):
        '''
            
        '''

        # If a self-closing tag, there are no contents
        if self.isSelfClosing is True:
            return ''

        # Assemble all the blocks.
        ret = []

        # Iterate through blocks
        for block in self.blocks:
            # For each block:
            #   If a tag, append the outer html (start tag, contents, and end tag)
            #   Else, append the text node directly

            if isinstance(block, AdvancedTag):
                ret.append(block.outerHTML)
            else:
                ret.append(block)
        
        return ''.join(ret)