Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add content to the beginning of every line, like ::before does for the first line

I am trying to style my <code>/<pre> tags without preventing the user from being able to highlight and copy the code properly.

The way I was hoping to do this (see below) only works for the first line, and won't ever repeat.

I'm sure this could be made to work using JavaScript, but I'm not sure what the best way to do that without a large amount of processing would be.

body {
  font-family: sans-serif;
}

code, pre {
  background: #e5f3ff;
}

code.styled,
pre.styled {
  display: block;
  padding: 8px;
  margin: 8px 0;
  overflow-x: auto;
}

code.styled::before,
pre.styled::before {
  content: "–";
  padding-right: 8px;
}
<p>This is an example of using <code>::before</code> to add content,<br>
and still being able to highlight/copy text without copying prefix.</p>
<pre class="styled">
adb wait-for-device
adb reboot-bootloader
fastboot devices
</pre>
<p>Note: You can copy the code without having to worry about the prefix.</p>

What is the best way that I could achieve a similar effect, but spanning every line? I am looking for a vanilla JavaScript method if possible.

like image 601
Jsilvermist Avatar asked Feb 07 '23 04:02

Jsilvermist


2 Answers

Here is a pure javascript solution

var _pre = document.querySelector("pre.styled");
_pre.innerHTML="<span class='line'>"+(_pre.textContent.split("\n").filter(Boolean).join("</span>\n<span class='line'>"))+"</span>";
body {
  font-family: sans-serif;
}

code, pre {
  background: #e5f3ff;
}

code.styled,
pre.styled {
  display: block;
  padding: 8px;
  margin: 8px 0;
  overflow-x: auto;
}

code.styled .line::before,
pre.styled .line::before {
  content: "–";
  padding-right: 8px;
}
<p>This is an example of using <code>::before</code> to add content,<br>
and still being able to highlight/copy text without copying prefix.</p>
<pre class="styled">
adb wait-for-device
adb reboot-bootloader
fastboot devices
</pre>
<p>Note: You can copy the code without having to worry about the prefix.</p>

How this works: We retrieve the textContent from pre as string, split the string into an array of lines, filter out empty lines and join the lines back together by wrapping each in a span.

like image 159
jayms Avatar answered Feb 10 '23 08:02

jayms


If you don't want to wrap each line in it's own tag, you could try a background image technique similar to this answer:

styling each line inside pre with css

http://www.dte.web.id/2012/03/css-only-zebra-striped-pre-tag.html#.UUoV6lugkoM

UPDATE: added code sample

body {
  font-family: sans-serif;
}

code, pre {
  background: #e5f3ff;
}

code.styled,
pre.styled {
  display:block;
  font:normal 12px/22px Monaco,Monospace !important;
  color:#000;
  background-color:#e5f3ff;
  background-image: radial-gradient(circle at 50%, #333 0%, #333 10%, #e5f3ff 20%);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='22' height='22'><circle cx='11' cy='11' r='3' fill='green' stroke='black' stroke-weight='1' /></svg>");
  background-size: 22px 22px;
  background-repeat: repeat-y;
  padding:0em 20px;
  overflow:auto;
}
<pre class="styled">
adb wait-for-device
adb reboot-bootloader
fastboot devices
</pre>
<p>Note: You can copy the code without having to worry about the prefix.</p>
like image 26
andyvanee Avatar answered Feb 10 '23 07:02

andyvanee