📜 ⬆️ ⬇️

Copy the source code without row numbering


It happens when outputting information that is required to decorate it for better perception, often the design is accompanied by text. When selecting and copying this information, the design is not necessary to copy, because only the information itself is needed, and preferably in its original form. That is, when copying a part of the selected text should not fall into the clipboard.
In my case, this is the source code, which is accompanied by the numbering of lines, so it is more obvious and there is an opportunity to refer to a line of code. However, if we want to copy part of the code, then it must be copied without a line number.
Many highlighters sin with this, when copying the code they also copy line numbers. They get out of the situation in different ways: they either use a cunning layout, which makes it possible for the numbering to coincide with the lines (as seen on github for example), or use a special button that shows the code in a separate window without formatting. I found these approaches unsatisfactory, so I decided to find another solution.
In this article I will describe the solution to which I finally came to. The solution is, of course, private, but it may be useful to someone in solving their own problems.

To begin with, we briefly go through the possible solutions.

The first method is obvious.


The easiest and most obvious way is to make a numbered list, where each element of the list is a separate line. The main advantage of this approach is that everything is simple and there is no need to even think about numbering. But at the same time it is impossible to control the format of the numbering, it is impossible to position the marker (line number) and in general somehow decorate it. In addition, Internet Explorer and Firefox copy the text along with the marker.
Actually the problem with copying crosses the possibility of using this approach.

The second method is less obvious.


The second thing that comes to mind is to use the generated content. You can even put up with the fact that in older IE it will not work (in this case, you can, of course, make a fallback). But the trouble is that Internet Explorer and Opera copy all the visible text, including the generated content.
It is difficult to say whether the developers of Internet Explorer / Opera are right or the developers of webkit and Firefox are right about copying the generated content. One can say with certainty that the method does not fit.
')

Small note


Webkit and Firefox support CSS properties such as user-select (with their -webkit-user-select and -moz-user-select prefixes), which can be used to prevent text selection. In Internet Explorer, there is an html attribute unselectable. However, all this only prevents the beginning of the selection process, that is, if the text is still in the selection area, it will be copied.
Moreover, all blocks that fall into the selection area, even invisible (display: none; or visibility: hidden;) also end up on the clipboard.
All this is very sad, since there is no normal way to determine which text to copy and which one does not.

The third way, abnormal.


Wandering around the Internet looking for a solution, something suggested using <input> to output a decorative text. Yes, an input field for text output. We write the necessary text in the value value, remove the padding, margin, border, background, set the rest of the styles - and no one will say that it is input. We select our text, copy it, paste it into notepad - all browsers behave the same, <input> tags with content are not inserted.
It remains to overcome an unpleasant moment, the input field can receive focus, and you cannot begin to select text with numbering — the text of the field is highlighted. But this is, in fact, little things.
To prevent the field from focusing with a mouse in webkit and Firefox, there is a pleasantness - this is the CSS property of pointer-events, which can be set to none. For Internet Explorer, you can add the attribute unselectable = "on" to the field. With Opera yet.
That it was impossible to transfer focus from the keyboard (and in other ways) we add the readonly and tabindex = "-1" attributes for <input>.
Everything is fine in Firefox and webkit, but in Internet Explorer it’s impossible to start a selection starting from the numbering area, and Opera still highlights the text of the field, not the source code. To solve the problem, add an additional block for each <input>, which will overlap the <input>. This block must have the same dimensions as <input>, as well as be transparent. Unfortunately (or fortunately), if the block has no background, then it is “shot through”, that is, it behaves as if it is not there, therefore it needs to add a background. You can add either a transparent gif file or just the path to a nonexistent file, for example background: url (#); (it would be possible to use rgba (), but in IE it is supported only starting from the 9th version).

That's basically it.

As a result, we have the following html for the block with the source code (line breaks for clarity, the target html should be without them, otherwise we can get unnecessary line breaks when copying):
<div class="code"> <div class="line"> <span class="lineContent"> <input class="lineNumber" value="01" unselectable="on" readonly tabindex="-1" /> <span class="over"></span> ..  .. </span> </div> <div class="line"> ... </div> ... </div> 

And the CSS for this “disgrace”:
  .code { border: 1px solid #E0E0E0; padding: 1px; margin: 0 1ex; overflow: hidden; font-family: Consolas, monospace; font-size: 100%; color: black; line-height: 1.4em; white-space: pre; /*     */ } .line { position: relative; /*  webkit,              */ zoom: 1; /*  IE6/7 */ white-space: pre; /*      IE7 */ } .even { background: #F8F8F8; } .odd { background: #F0F0F0; } .lineNumber { display: block; position: absolute; left: 0; padding: 0 .5ex; margin: 0; width: 6ex; line-height: 1.4em; height: 1.4em; background: none; border: none; font-family: Consolas, monospace; font-size: 100%; text-align: right; color: #666; -moz-user-select: none; /*  user-select  Firefox & webkit,       */ -webkit-user-select: none; user-select: none; pointer-events: none; /*       .over,       Firefox & webkit */ } .over { display: block; position: absolute; left: 0; width: 7ex; height: 1.4em; z-index: 1; background: url(.); /*  IE  Opera,    "" (    ) */ } .lineContent { margin-left: 7ex; padding-left: 2ex; border-left: 2px solid #33BB66; display: block; white-space: pre-wrap; /*  ,       */ } .token-string { color: blue; } .token-comment { color: #008200; } .token-keyword { color: #006699; font-weight: bold; } 


Demo


Demo on the example of the source code atomjs (I hope TheShock does not mind;)
There is a lot of html code, but it is generated by javascript (its own highlighter).
Tested under Chrome / Safari, Firefox 3.6, Opera 11, IE7-9 (mode switching in IE9 RC).

What you should pay attention to



I would welcome comments and suggestions for improvement.

UPDATE
Found workaroud so that when you insert into Word / Excel input fields are not inserted. To achieve this for <input>, you need to specify a non-existent value for the type attribute. In this case, browsers ignore the attribute and the field has a default type, that is, type = "text", and when copying (or pasting) scripts are not described how to deal with fields of unknown type - as a result, the field is ignored. So the code can be easily inserted, for example, in Word. Moreover, if the code is copied from Chrome / Safari or from IE, it will be inserted with coloring (the webkit also copies the background, and IE copies without the background), which may be useful in some cases.

Source: https://habr.com/ru/post/114322/


All Articles