>>54,55
Here's an HTML parsing rule for dealing with indirectly nested tags.
When the user agent is to apply the rules for the "in body" insertion mode, the user agent must handle the token as follows:
...
An end tag whose tag name is one of: "a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u"
Run these steps:
Let outer loop counter be zero.
Outer loop: If outer loop counter is greater than or equal to eight, then abort these steps.
Increment outer loop counter by one.
Let the formatting element be the last element in the list of active formatting elements that:
is between the end of the list and the last scope marker in the list, if any, or the start of the list otherwise, and
has the same tag name as the token.
If there is no such node, then abort these steps and instead act as described in the "any other end tag" entry below.
Otherwise, if there is such a node, but that node is not in the stack of open elements, then this is a parse error; remove the element from the list, and abort these steps.
Otherwise, if there is such a node, and that node is also in the stack of open elements, but the element is not in scope, then this is a parse error; ignore the token, and abort these steps.
Otherwise, there is a formatting element and that element is in the stack and is in scope. If the element is not the current node, this is a parse error. In any case, proceed with the algorithm as written in the following steps.
Let the furthest block be the topmost node in the stack of open elements that is lower in the stack than the formatting element, and is an element in the special category. There might not be one.
If there is no furthest block, then the UA must skip the subsequent steps and instead just pop all the nodes from the bottom of the stack of open elements, from the current node up to and including the formatting element, and remove the formatting element from the list of active formatting elements.
Let the common ancestor be the element immediately above the formatting element in the stack of open elements.
Let a bookmark note the position of the formatting element in the list of active formatting elements relative to the elements on either side of it in the list.
Let node and last node be the furthest block. Follow these steps:
Let inner loop counter be zero.
Inner loop: If inner loop counter is greater than or equal to three, then abort these steps.
Increment inner loop counter by one.
Let node be the element immediately above node in the stack of open elements, or if node is no longer in the stack of open elements (e.g. because it got removed by the next step), the element that was immediately above node in the stack of open elements before node was removed.
If node is not in the list of active formatting elements, then remove node from the stack of open elements and then go back to the step labeled inner loop.
Otherwise, if node is the formatting element, then go to the next step in the overall algorithm.
Create an element for the token for which the element node was created, replace the entry for node in the list of active formatting elements with an entry for the new element, replace the entry for node in the stack of open elements with an entry for the new element, and let node be the new element.
If last node is the furthest block, then move the aforementioned bookmark to be immediately after the new node in the list of active formatting elements.
Insert last node into node, first removing it from its previous parent node if any.
Let last node be node.
Return to the step labeled inner loop.
If the common ancestor node is a table, tbody, tfoot, thead, or tr element, then, foster parent whatever last node ended up being in the previous step, first removing it from its previous parent node if any.
Otherwise, append whatever last node ended up being in the previous step to the common ancestor node, first removing it from its previous parent node if any.
Create an element for the token for which the formatting element was created.
Take all of the child nodes of the furthest block and append them to the element created in the last step.
Append that new element to the furthest block.
Remove the formatting element from the list of active formatting elements, and insert the new element into the list of active formatting elements at the position of the aforementioned bookmark.
Remove the formatting element from the stack of open elements, and insert the new element into the stack of open elements immediately below the position of the furthest block in that stack.
Jump back to the step labeled outer loop.