(function()
{
var height;
if(typeof(window.getComputedStyle) == 'undefined')
{
return;
}
var pre = document.getElementsByTagName('pre');
for(var len = pre.length, i = 0; i < len; i ++)
{
var code = pre[i].getElementsByTagName('code').item(0);
var column = document.createElement('div');
column.setAttribute('aria-hidden', 'true');
for(var n = 0; n < code.innerHTML.split(/[\n\r]/g).length; n ++)
{
height=column.appendChild(document.createElement('span'));
console.log(height.offsetHeight);
}
pre[i].insertBefore(column, code);
pre[i].className = 'line-numbers';
}
})();
The actual code section you see is comprised of spans. Basically, I took the left columns numbers and got the length of it. Then I got the height of the numbers. Basically, if the height of the numbers were less than the total parents height, then there were lines that need adding.
So I took the leftover number from the math, divided it by one of the numbers height, and got that remainder. Added that many.
THis was all very confusing code and I do not feel ashamed by scrapping it. Anyway, could someone sort of take my logic, refine it, and show me where I can go from here?
Something of what I was dealing withā¦Note this is probably a bit broken due to my last attempts.
(function()
{
if(typeof(window.getComputedStyle) == 'undefined')
{
return;
}
var pre = document.getElementsByTagName('pre');
for(var len = pre.length, i = 0; i < len; i ++)
{
var code = pre[i].getElementsByTagName('code').item(0);
var column = document.createElement('div');
column.setAttribute('class', 'number-lines');
column.setAttribute('aria-hidden', 'true');
for(var n = 0; n < code.innerHTML.split(/[\n\r]/g).length; n ++)
{
column.appendChild(document.createElement('span'));
}
pre[i].insertBefore(column, code);
pre[i].className = 'line-numbers';
}
var child=document.getElementsByClassName('number-lines').item(0);
var child2=child.getElementsByTagName('span');
var child2List=Array.prototype.slice.call(child2);
var eleH=0;
var create;
var before;
var pre2=document.getElementsByTagName('pre');
var total;
for(var i=0;i<=child2List.length;i++)
{
eleH+=child2List[i].offsetHeight;
if(i==child2List.length-1)
{
if(eleH<child.offsetHeight)
{
total=child.offsetHeight-eleH;
create=document.getElementsByClassName('number-lines').item(0);
while(total>0)
{
for(var len = pre.length, i = 0; i < len; i ++)
{
var code2= pre[i].getElementsByTagName('code').item(0);
var column2 = document.createElement('div');
before=create.appendChild(document.createElement('span'));
total=total-child2List[0].offsetHeight;
}
}
}
}
})();
Decided to just double teh amount of spans Iām inputting, so itās 2x spans per span node found (yea yea, inoptimal) and then I just use nifty CSS to hide the leftovers (extras that I donāt need) from appearing. Band-aid fixing so sue me. IT WORKS THOUGH. Time for dinnerā¦
Glad you got it working. Sometimes we have to get to the ugly version of it before we can see a better alternative I still havenāt found one that Iām thrilled about, but at least you were able to get to a working one! (Iāve yet to do that)
Look at the code blocks. Ok, so the numbrers on the left. Right now itās supposed to, for each node on the right, add a span (which CSSthen auto counts). Please look at .http://www.codefundamentals.com/scripts/code-counter.js
I just double the amount of inputted spans . Every line counter requires that you scroll the line instead of it wrapping. I need my counter to detect whether the line has wrapped and add additional spans accordingly. Right now, yes it works, however I add unnecessary spans. Go in inspect element to see I have almost double needed.
Now, also, look at example 2. This highlightjs Iām using only detects one language per pre/code block. I put two languages per one code block. Is there any way to modify highlightjs to sort of āre lookā what language it is (or rather, re-detect) and highlight accordingly?
Now, the third example uses ONE pre, but two separate code blocks inside. Thatās sort of fine although it ruins my contenteditable attribute (try clicking each language to see you get different editable areas).
Not quite a good solution. The issue we were having was weād try the two separate code blcoks and itād reset the numbers. You donāt see it here because with double the amount of spans needed (my band-aid fix) you donāt see it.
So with the number resetting in example 3, it would go 1-15, then when the HTML startedā¦itād go back to #1ā¦So the line number needs to correctly detect whether it has wrapped, add accordingly, and depending on how highlightjs will be handled, get that numbering right.
Sorry for the delayed replies - Iām travelling this week and not always in front of a computer.
Could I ask what you want to use highlight.js for? Is it for code formatting on your blog? (apologies if you mentioned it in the thread already)
For example the issue with two languages in one code block could be solved by using two code blocks, but I guess there is a reason you donāt want to do this.
I could use two code blocks, but then that would make my contenteditable=true situation really weird looking. If I had two blocks, HTML and CSS for both, then whne I click HTML, Iād get an outline around that code, and not around the CSS.
I mean I could just remove that attribute since itās not a big deal.
The main issue Iām having is getting the line numbers to calculate correctly. Prism.jsās line-numbers script (along with every other) assumes that you want to scroll the data in a horizontal scrollbar. I do not want that. However when it does wrap (as I want), the numbers donāt match the actual lines of data since 3x lines of data is only getting 1 number (for example.)
I band-aid fixed this by just doubling the amount of spans that Iām inputting, and hiding the rest via CSS. Very band-aidy fix but it worked. Iād rather get it properly coded though. The highlight.js issue will need to be tackled secondly probably (and honestly I might just remove that attribute and have two code blocks inside of my PRE.)
I was thinking of detecting each nodes height (in my var j for loop) and if itās not equal to the rest (or perhaps have a constant, like the first node) then Iāll divide that and itāll either be 2,3,4,etc times big. Thatās how many I add to my counter. Thoughts? What would be the best way to determine wrapping?
Feels good to have this fixed properly so far. I ended up removing the contenteditable attributes and using two code blcoks inside of my PRE to get the highlighting right. Just had to update the linecounter script to change its criteria.
The only way I am aware of is to find an element which you are sure doesnāt wrap and compare the height of all other elements to the height of this one.
Iām having a little brain fart as to how to proceed with this. Canāt seem to get anything working. The console is giving me ā0ā when Iām looping out data.
http://www.codefundamentals.com/test.php
Iām trying to push my nodes to nodeHeights where I can then loop through the heights and figure out how much to add to lineNumbers. @James_Hibbard
This actually turns out to be a little more problematic than anticipated.
Iām still working on this, but so far the only way I could get it to behave as desired was to configure highlight.js to break on <br> elements, then iterate over these <br> elements, get the height of the previous child, then adjust the height of the line numbers accordingly.
This works, but is incredibly hackish.
If you wish, I can let you have this code as is, or I can carry on playing around with it later and see if I canāt come up with something a little more elegant.
Perhaps we can take a different approach Pullo. This way wouldnāt be optimal but what are your thoughts.
After the first initial appending, we will have x amount of spans there taking up y amount of height.
Letās say I have 12 lines of code, but only 10 spans. Those 10 spans are 20px height (I can find the first nodes height as a baseline.)
Now, that will be 200px of span height so far. If I have 12 lines of code, since the line-height/font etc is all the same, my code tag will be 248px tall (240 from the lines, 8px margin I set.)
So I could do some math to determine that I need 2 more from there and then do another append. Perhaps the appending could be put into a function and just call 2 more (in this case.) The first appending is going off the lineNumbers variable so I think if we wanted to move that to a function we couldā¦anywayā¦What are your thoughts? WOuld this be easier?
Ah right, so if the code is ten lines long, but one of those ten lines wraps over two lines (because the individual line is longer than the container), then you would like the line numbers to run from 1-11. Did I get that right?
This is in contrast to your latest demo, where we have that situation, but the numbering stops at 10.
I had been thinking that you wanted the line numbers to run from 1-10, and to skip the lines where a long line had been wrapped (which was what I had working).
[quote=āJames_Hibbard, post:39, topic:116981ā]
Ah right, so if the code is ten lines long, but one of those ten lines wraps over three lines (because it is too long), then you would like the line numbers to run from 1-12. Did I get that right?
[/quote]Yes, sorry for being confusing.