scrivo / highlight.php

A port of highlight.js by Ivan Sagalaev to PHP
BSD 3-Clause "New" or "Revised" License
695 stars 45 forks source link

Fix splitCodeIntoArray when it has nested spans + newlines #79

Closed allejo closed 4 years ago

allejo commented 4 years ago

The splitCodeIntoArray function was generating broken HTML when there were deeply nested \n characters because it wasn't closing the correct number of <span> tags.

Marking this as a draft to see what the performance impact is by using XPath.

Originally, splitCodeIntoArray was working off the assumption that <span>s would only nest one level deep when splitting on new lines. Notice the span.hljs-params element is a child to span.hljs-function. Because of this assumption, we were closing the hljs-params span but not the hljs-function span.

Output from highlight

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">QuoteEntity</span><span class="hljs-params">(
)</span></span>

Current splitCodeIntoArray output:

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">QuoteEntity</span><span class="hljs-params">(</span>
<span class="hljs-params">)</span></span>

What it should look like (fix in this PR):

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">QuoteEntity</span><span class="hljs-params">(</span></span>
<span class="hljs-function"><span class="hljs-params">)</span></span>

See https://github.com/westonruter/syntax-highlighting-code-block/issues/193

allejo commented 4 years ago

Ran some benchmarks on calling splitCodeIntoArray 200000 times on different code snippets and the differences in performance are negligible.

test_original             : 35.122 sec.
test_xpath                : 36.956 sec.

test_original             : 35.362 sec.
test_xpath                : 35.501 sec.

test_original             : 54.900 sec.
test_xpath                : 55.953 sec.

test_original             : 24.244 sec.
test_xpath                : 22.913 sec.