Hao Yellow Hao Yellow - 1 month ago 25
CSS Question

HTML - How do I insert a <span></span> tag into each line of a <pre></pre> block without hard coding?

I was just trying to add line numbers at the beginning of source code using CSS.
I realized the effect I wanted, as follows:
Effect implemented

However, the HTML code required continual use of

<span>...</span>
tags:

<pre class="code">
<span>var links = document.getElementsByClassName("link");</span>
<span>for(var i = 0; i &lt; links.length; i++){</span>
<span> links[i].onclick=function(){</span>
<span> alert(i+1);</span>
<span> };</span>
<span>}</span>
</pre>


With the
span
tags positioned at home/end of lines I can let the line numbers show as expected.
But I think there must be another better solution to prevent me adding all these
span
tags hard-coded, maybe using Javascript, or jQuery I don't mind but don't know how. Please help.

NOTE:
My problem is not how to display line numbers when the tags are already there. Instead, I wanted to know if the origin HTML code contains NO
<span>
tags, how can I automatically add them into the suitable places and so I can apply the CSS styles.

Answer

I have combined @Stewartside answer with what you have actually asked for.

Below you can see a simple plain JavaScript to replace any line in element with code class to be wrapped in span which applies @Stewartside css.

var codeElement = document.getElementsByClassName("code"); //array of code blocks
var formattedCode = codeElement[0].textContent.replace("\r\n", "\n").split("\n");
var codeLength = formattedCode.length;
formattedCode.forEach(function(line, index, array) {
  if (codeLength - 1 == index) return; 
  array[index] = "<span>" + line + "</span>";
});

codeElement[0].innerHTML = formattedCode.join("\n");

$(".code-jquery").each(function(index, codeElement) {
  var formattedCode = $(codeElement).html().replace("\r\n", "\n").split("\n");
  
  var codeLength = formattedCode.length;
  $(codeElement).text("");
  $.each(formattedCode, function(index, line) {
    if (codeLength - 1 == index) return;
    $(codeElement).append("<span>" + line + "</span>\n")
  });
});
pre {
  background: #eee;
  counter-reset: section; /* Reset the counter to 0 for each new pre */
}
pre span:before {
  counter-increment: section; /* Increment the section counter*/
  content: counter(section); /* Display the counter */
  padding: 0 5px;
  border-right: 1px solid #777;
  margin-right: 5px;
  color: #777
}

pre.code-jquery span {
  color: green;
}
<pre class="code">
  var links = document.getElementsByClassName("link");
  for(var i = 0; i &lt; links.length; i++) {
    links[i].onclick = function() {
    	alert(i+1);
  	};
  }
</pre>

//jQuery version
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre class="code-jquery">
  var links = document.getElementsByClassName("link");
  for(var i = 0; i &lt; links.length; i++) {
    links[i].onclick = function() {
    	alert(i+1);
  	};
  }
</pre>