wtorek, 19 maja 2015

[UPGRADE][Blogger] Kolorowanie składni kodu - Google Code Prettify

TRUE
5633298314763569632
Jak widać na tej stronie, wszystkie listingi z kodem są ładnie pokolorowane. Blogger oczywiście nie oferuje tego domyślnie, trzeba zatroszczyć się o to samemu. Pokażę tutaj jak tego dokonać. Wykorzystałem do tego celu popularny skrypt do kolorowania składni kodu udostępniany za darmo przez wujka Google, czyli Google Code Prettify. Oczywiście skryptów tego typu jest cała masa, ja jednak wybrałem ten od Google, gdyż wydaje mi się najszybszy i najbardziej odporny na wszelkie różne dziwne konstrukcje znakowe. Opiszę też mój sposób na automatyczne kolorowanie kodu ubranego w znaczniki bezpośrednio w edytorze wizualnym Bloggera - takie podejście jest o wiele bardziej wygodne, nic dodawanie ręcznie znacznika <pre> dla każdego listingu.

Dołączenie skryptu .js

Pierwsze co musimy zrobić to wejść w edycję szablonu i w nagłówku <head> załaczyć link do skryptu:
[code]<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>[/code]
Od tej pory, wszystko co znajduje się na naszej stronie ujęte w znaczniki:
[code] <pre class="prettyprint linenums"></pre>[/code]będzie kolorowane przez skrypt Prettify.

Aby jednak nie musieć robić tego ręcznie, stworzymy sobie kod, który doda nam te znaczniki wszędzie tam, gdzie wystąpi ciąg:

Małe usprawnienie edytora

Po załączeniu skryptu zapisujemy szablon i edytujemy lub tworzymy nowy widźet HTML/Javascript w panelu Układ.
Wklejamy do niego to co poniżej:
[code]
<script>
function strip_tags(input, allowed) {
  allowed = (((allowed || '') + '')
    .toLowerCase()
    .match(/<[a-z][a-z0-9]*>/g) || [])
    .join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
  var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
    commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
  return input.replace(commentsAndPhpTags, '')
    .replace(tags, function($0, $1) {
      return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
    });
}


function phpeTag2Pre(html)
{
  return html.trim().replace(/\[code\](<br ?\/?>)*/gi, '<br /><pre class="prettyprint linenums">').replace(/(<br ?\/?>)*\[\/code\]/gi, '</pre>');  
}

$(document).ready(function() {
  $('div.post-body.entry-content').each(function() {
      $(this).html(phpeTag2Pre($(this).html()));
  });

  $('div.post-body.entry-content pre').each(function() {
    $(this).html(strip_tags($(this).html()));
  });
});
</script>[/code]

Przeanalizujmy teraz ten kod:
[code]
/*
  Funkcja strip_tags() to javascriptowy odpowiednik takiej samej funkcji w PHP.
  Obcina ona z tekstu wszystkie tagi HTML.
*/
function strip_tags(input, allowed) {
  allowed = (((allowed || '') + '')
    .toLowerCase()
    .match(/<[a-z][a-z0-9]*>/g) || [])
    .join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
  var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
    commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
  return input.replace(commentsAndPhpTags, '')
    .replace(tags, function($0, $1) {
      return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
    });
}

/*
A poniżej już moja funkcja, która zamienia każde wystąpienie ciągu:
[ code ]   (bez spacji)

na ciąg:

<pre class="prettyprint linenums">

a każde wystąpienie:
[ /code ]   (bez spacji)

na:

</pre>

Funkcja działa jak widać na wyrażeniach regularnych, przy okazji usuwając też nadmiarowe znaczniki <br> jakie może czasem wkleić edytor Bloggera.
Przełączniki /gi mówią naszemu wyrażeniu, że dopasowanie ciągu ma wystąpić dla wszystkich wystąpień i że ma być ignorowana wielkość liter.
Zmieniony ciąg, z przygotowanymi znacznikami <pre> następnie jest przez funkcję zwracany.
*/
function phpeTag2Pre(html)
{
  return html.trim().replace(/\[code\](<br ?\/?>)*/gi, '<br /><pre class="prettyprint linenums">').replace(/(<br ?\/?>)*\[\/code\]/gi, '</pre>');
  // opcjonalnie - jeśli nie chcemy numeracji linijek - usuwamy klasę linenums
}



$(document).ready(function() {

  /* Lecimy pętlą do wszystkich postach na stronie, a właściwie po ich 'body': */
  $('div.post-body.entry-content').each(function() {

      /* Dla każdego posta pobieramy jego zawartość, wrzucamy do naszej funkcji zamieniajacej [ code ] na <pre>, a następnie podmieniamy treść za pomocą metody html().
        W tym momencie mamy już gotowy do kolorowania tekst. */
     
      $(this).html(phpeTag2Pre($(this).html()));
  });

  // Pozostaje jeszcze jedna kwestia - pozbywamy się tagów HTML z każdego wnętrza bloku <pre> za pomocą funkcji strip_tags, następnie znowu podmieniamy zawartość każdego DIV-a z treścią:
  $('div.post-body.entry-content pre').each(function() {
    $(this).html(strip_tags($(this).html()));
  });
});[/code]

Dzięki takiemu zabiegowi, wszystko to co ujmiemy w naszym poście pomiędzy:


zostanie ładnie pokolorowanie przez skrypt.

Przykład:


wyświetli się jako:

...................
To jest jakiś tekst
[code]
// To jest jakiś tekst
// Tutaj też jakiś kod:
<?php
$a = 1234;
$str = 'hello';
for(i=0; i<5; i++)
{
  $newArray[] = $myClass->getData('view');
  if($c == $_POST['d'])
  {
    echo 'blablabla';
  }
}
?>
[/code]
Tutaj inny tekst
...................

CSS

Pozostaje jeszcze kwestia dostosowania wyglądu do własnych potrzeb.
Skrypt kolorujący korzysta z następujących styli, więc można je nadpisać po załaczeniu skryptu w nagłówku:
[code]
/* Pretty printing styles. Used with prettify.js. */

/* SPAN elements with the classes below are added by prettyprint. */
.pln { color: #000 }  /* plain text */

@media screen {
  .str { color: #080 }  /* string content */
  .kwd { color: #008 }  /* a keyword */
  .com { color: #800 }  /* a comment */
  .typ { color: #606 }  /* a type name */
  .lit { color: #066 }  /* a literal value */
  /* punctuation, lisp open bracket, lisp close bracket */
  .pun, .opn, .clo { color: #660 }
  .tag { color: #008 }  /* a markup tag name */
  .atn { color: #606 }  /* a markup attribute name */
  .atv { color: #080 }  /* a markup attribute value */
  .dec, .var { color: #606 }  /* a declaration; a variable name */
  .fun { color: red }  /* a function name */
}

/* Use higher contrast and text-weight for printable form. */
@media print, projection {
  .str { color: #060 }
  .kwd { color: #006; font-weight: bold }
  .com { color: #600; font-style: italic }
  .typ { color: #404; font-weight: bold }
  .lit { color: #044 }
  .pun, .opn, .clo { color: #440 }
  .tag { color: #006; font-weight: bold }
  .atn { color: #404 }
  .atv { color: #060 }
}

/* Put a border around prettyprinted code snippets. */
pre.prettyprint { padding: 2px; border: 1px solid #888 }

/* Specify class=linenums on a pre to get line numbering */
ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */
li.L0,
li.L1,
li.L2,
li.L3,
li.L5,
li.L6,
li.L7,
li.L8 { list-style-type: none }
/* Alternate shading for lines */
li.L1,
li.L3,
li.L5,
li.L7,
li.L9 { background: #eee }
[/code]

Pełny FAQ dotyczący używania skryptu Google Code Prettify znajdziecie tutaj:
http://google-code-prettify.googlecode.com/svn/trunk/README.html

Brak komentarzy:

Prześlij komentarz

Masz sugestię? Znalazłeś błąd? Napisz komentarz! :)

webmaester.pl - profesjonalne projektowanie WWW i webaplikacji
webmaester.pl - profesjonalne projektowanie WWW i webaplikacji