Stare problemy powracają jak nowe. Już jakiś czas temu na jednym z kanałów IRCa miałem okazję uczestniczyć w dyskusji pt. jak umieścić kod na stronie Internetowej z numeracją wierszy, tak aby przy kopiowaniu tekstu uzyskać sam skopiowany tekst. Jeżeli po przeczytaniu tego zdania nie wiesz w czym problem, już wyjaśniam.

Otóż umieszczając kod na swojej stronie, możemy zrobić to na kilka sposobów. Za pomocą tagu <pre> lub stosując listę <ol> z naszym kodem otoczonym tagiem <code>. Jeżeli interesuje nas numerowanie wierszy rodem z profesjonalnego edytora, to niestety <pre> odpada.

  1. <ol>
  2.     <li><code>Linia 1</code></li>
  3.     <li><code>Linia 2</code></li>
  4. </ol>

W ten sposób uzyskujemy numeracje wierszy która jest niezależna od JavaScriptu czy nawet zadziała bez CSSa. Problem natomiast pojawia się przy próbie skopiowania do schowka owego kodu. Zaznacz powyższy kod i skopiuj go do jakiegoś edytora, uzyskasz mniej więcej taki efekt:

1. <ol>
2.     <li><code>Linia 1</code></li>
3.     <li><code>Linia 2</code></li>
4. </ol>

Tutaj nasuwa się pytanie: po co mi numeracja wierszy skoro chciałem SAM kod? Odpowiedź jest bardzo prosta: przeglądarka po prostu kopiowała treść z listy. Problem jest dosyć dotkliwy gdy kopiujemy w ten sposób dużą ilość kodu, usuwanie w każdym wierszu numeru wiersza jest dosyć nieprzyjemną sprawą.

Dlatego przyjęło się rozwiązywać ten problem na kilka sposobów:

  • Obok naszego ślicznego kodu umieszcza się przycisk konwertujący za pomocą JavaScriptu kod wewnątrz listy do tagu/pola które nie powoduje tego efektu (jak. <pre> czy <textarea>). Jednocześnie tracimy numerację wierszy, ale kod możemy skopiować jak trzeba.
  • Obok kodu umieszcza się przycisk który po kliknięciu otwiera nowe okno z czystym tekstem. Taki mechanizm znajdziemy np. w syntaxhighlighter.
  • Można się spotkać także z tworzeniem numeracji niezależnie. Czyli mamy z lewej w jednym tagu same numerki, z prawej kod umieszczony w <pre>. Albo nam się numerki wiersza będą nie zgadzać gdy przez przypadek zapomnimy o blokadzie łamania wierszy (white-space) albo na kilka sekund nasza przeglądarka będzie generować owe cyferki gdy postanowimy ten zabieg wykonać po stronie klienta. Nic już nie będę wspominał o wyglądzie strony bez CSS. Takie rozwiązanie stosuje np. wklej.org.

Istnieje jeszcze jedno rozwiązanie pozbawione powyższej wady którego niestety nie miałem okazji spotkać w Sieci. Mam na myśli właściwości counter-* które dostępne są już od CSS 2.1!

Co to takiego? Otóż CSS 2.1 pozwala wstawić za pomocą właściwości content:; nie tylko sztywny - wcześniej ustalony tekst. Ale oferuje również kilka ciekawych funkcji, między innymi: counter(nazwa_sekcji). Który wstawia w określony tag wartość, wcześniej zdefiniowanego licznika. Jeżeli połączymy tą właściwość z pseudoklasą :before możemy utworzyć przed każdym tagiem w sekcji, numer który rośnie w górę - w naszym przypadku jest to jednoznaczne z numerem wiersza.

  • Ze względu na to, że :before jest niewidzialne przez DOM, przeglądarka kopiując treść pomija wszystkie treści wstawione za pomocą tego elementu. Dlatego kopiując kod gdzie obok znajdują się cyfry, w systemowym schowku znajdziemy treść bez nich.

Nasz kod umieszczamy na stronie w ten sposób (<pre> i <span> chyba najbardziej pasują pod względem semantyki do omawianego rozwiązania):

<pre>
<span>Linia 1</span>
<span>Linia 2</span>
</pre>

Natomiast w CSS'ie strony musi się znaleźć ten kod:

pre {
	counter-reset:section 0;
}
pre span:before {
	counter-increment:section;
	content:counter(section);
}

Wystarczy, że wg. własnych kryteriów odpowiednio ostylizujemy nasz nowy codebox, a w rezultacie otrzymamy numerację wierszy, kod który po zaznaczeniu i skopiowaniu nie zawiera jakichkolwiek śmieci, a na dodatek przejrzysty i zgodny ze standardami kod dokumentu.

Powyższe rozwiązanie rzecz jasna nie działa w IE 6&7, ale na szczęście już IE 8 obsługuje kod poprawnie.

Powyższy kod w akcji możecie zobaczyć w tej małej prezentacji.

Komentarze do wpisu "Kod z numeracją wierszy na Twojej stronie":

1. MiMaS napisał(a):
12 lipca 2010, 18:11:42

Twoja "mała prezentacja" nie działa w Operze 10.60 jak oczekujesz - kopiowane są numery wierszy.

2. b4rtaz napisał(a):
12 lipca 2010, 18:34:11

Faktycznie, to samo w IE8. W Chrome i FF działa jak należy. Hmm...

Dop: widzę, że nie tylko ów problem dotyka mojego rozwiązania. Myślę, że z kolejnymi wydaniami browserów w końcu będzie jeden jedyny efekt.

3. koziolek napisał(a):
12 lipca 2010, 18:51:28

Dodam jeszcze, że w Operze 10.60 i Notepad++ 5.7 pierwszy kod bez problemu wkleja się bez numerków linii.

4. Bartosz "BTM" Szczeciński napisał(a):
12 lipca 2010, 19:27:42

@b4rtaz: wpisywanie dłuższych kodów w Twoim rozwiązaniu przyprawiło by mnie o chęć mordowania ;-)

5. b4rtaz napisał(a):
12 lipca 2010, 19:29:21

@BTM: rozwiązanie skierowane bardziej dla serwisów typu nopaste. Chodź niejednokrotnie spotkałem kod w <ol> na różny blogach czy serwisach...

6. GiM napisał(a):
12 lipca 2010, 20:31:49

proste, kod przed wklejaniem traktuje się odpowiednim do tego narzędziem. there, I've fixed it ;)

7. Szymon napisał(a):
13 lipca 2010, 05:14:44

@BTM, sugeruję coś bardziej rozbudowanego od pico ;)

Dodaj komentarz: