if (![[range startContainer] isEqualNode:[range endContainer]])

return NO; // does not work with cross-node selections

if ([range startOffset] == [range endOffset])

return NO; // no selection.

// remove any heading tags from parents.

NSString *textContent = [[range startContainer] textContent];

NSString *leftStr = nil;

NSString *midStr = nil;

NSString *rightStr = nil;

// there is always a mid part, that's selected

midStr = [textContent substringWithRange:NSMakeRange([range startOffset], [range endOffset]-[range startOffset])];

// is any text left on the left

if ([range startOffset] > 0)

leftStr = [textContent substringToIndex:[range startOffset]];

// is any text left on the right

if ([range endOffset] < [[[range startContainer] textContent] length])

rightStr = [textContent substringFromIndex:[range endOffset]];

DOMNode *mid = [[range startContainer] parentElement]; // parent elements contains the tags wrapping the DOMText

[mid setTextContent:midStr];

if (leftStr != nil) {

DOMNode *first = [mid cloneNode:YES];

[first setTextContent:leftStr];

[[mid parentNode] insertBefore:first refChild:mid];


if (rightStr != nil) {

DOMNode *last = [mid cloneNode:YES];

[last setTextContent:rightStr];

[[mid parentNode] appendChild:last];


if (level > 0) {

[self wrapNewTag:[NSString stringWithFormat:@"h%d", level] aroundContentsOfElementNode:(DOMElement *)mid];

} else {

[self wrapNewTag:[NSString stringWithFormat:@"p", level] aroundContentsOfElementNode:(DOMElement *)mid];


[self HTMLUpdated];

return YES;