A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Tutoriais e Programação

GeSHi à moda da casa

Qui

9

Jul

2009


12:17

(5 votos, média 4.00 de 5) 


Depois de usar o plugin do GeSHi por um tempo, esbarrei num pequeno problema. Como as tags <pre> são usadas como marcadores para o GeSHi, fiquei sem as ditas cujas para criar outros efeitos além do destaque de texto. De alguma forma eu não estava muito satisfeita com este "sequestro" da tag por que bateu uma espécie de sensação de perda...

A primeira etapa

Quem usa o CMS Joomla sabe que a maioria dos plugins que atuam no conteúdo das páginas são acionados por marcadores do tipo {nome do plugin}. Como minha primeira idéia foi a de recuperar a tag <pre>, o mais lógico seria alterar o plugin de forma que outro marcador chamasse o GeSHi. Poderia ser alguma coisa do tipo {geshi} ou até mesmo <geshi>. Abri o plugin /plugins/content/geshi.php para dar uma olhada no código. Logo no início, na função plgContentGeshi(), achei o que procurava:

... /** * Code Highlighting Plugin * * Replaces
...
tags with highlighted text */ function plgContentGeshi( &$row, &$params, $page=0 ) { // simple performance check to determine whether bot should process further if ( JString::strpos( $row->text, 'pre>' ) === false ) { return true; } // Get Plugin info $plugin =& JPluginHelper::getPlugin('content', 'geshi'); // define the regular expression for the bot $regex = "#
(.*?)
#s"; $GLOBALS['_MAMBOT_GESHI_PARAMS'] =& $params; // perform the replacement $row->text = preg_replace_callback( $regex, 'plgContentGeshi_replacer', $row->text ); return true; }

Observe a linha 35. Nesta linha é criado um regex todo complicado que identifica tudo o que estiver entre as tags <pre> e </pre>. Oba! É aí mesmo que precisamos mudar alguma coisa smile

Mas tem mais um pequeno detalhe. Para evitar que todo o código do plugin seja executado mesmo se não houver o marcador apropriado, a linha 27 faz uma checagem inicial: se no texto não existir nenhuma ocorrência da string 'pre>', então retorne.

Pois bem, agora precisamos decidir como o GeSHi será chamado. Só para ficar entre o modo tradicional de chamar plugins com {nome do plugin} e a forma tradicional de indicar as tags com <nome da tag>, resolvi ficar em cima do muro e criar os novos marcadores como <geshi>...</geshi>. Apenas duas pequenas alterações fizeram o milagre:

... /** * Code Highlighting Plugin * * Replaces
...
tags with highlighted text * Troquei por <geshi>...</geshi> */ function plgContentGeshi( &$row, &$params, $page=0 ) { // simple performance check to determine whether bot should process further if ( JString::strpos( $row->text, 'geshi>' ) === false ) { return true; } // Get Plugin info $plugin =& JPluginHelper::getPlugin('content', 'geshi'); // define the regular expression for the bot $regex = "#<geshi\s*(.*?)>(.*?)</geshi>#s"; $GLOBALS['_MAMBOT_GESHI_PARAMS'] =& $params; // perform the replacement $row->text = preg_replace_callback( $regex, 'plgContentGeshi_replacer', $row->text ); return true; }

Não vou entrar em maiores detalhes sobre o novo regex que criei por que isto foge do assunto principal. A única coisa que fiz foi eliminar o xml: e trocar pre por geshi. O fato é que, assim que alterei o código fonte, criei uma página de teste e as tags <geshi>...<geshi> funcionaram perfeitamente. A primeira estapa foi vencida biggrin

A segunda etapa

Como estava acostumada a usar o plugin indicando a linguagem de programação desejada, a linha 59 do código do plugin não foi nenhuma surpresa.

$lang = JArrayHelper::getValue( $args, 'lang', 'php' );

Esta linha "cisca" o parâmetro 'lang' que determina a linguagem que deve ser usada. Se não for especificada, será usada a linguagem default PHP; se for especificada, então a linguagem definida será usada. Por exemplo, se eu quiser um destaque para a linguagem Javascript, coloco o seguinte no texto:

<geshi lang="javascript">var i = 0;</geshi>

Olhando na linha seguinte, verifiquei que havia mais um parâmetro que poderia ser usado para que as linhas de código fossem numeradas. O trecho do plugin original que permite numerar as linhas é o seguinte:

$lang = JArrayHelper::getValue( $args, 'lang', 'php' ); $lines = JArrayHelper::getValue( $args, 'lines', 'false' );

Quando o parâmetro lines é verdadeiro, o plugin manda para o script do GeSHi o seguinte:

$geshi = new GeSHi( $text, $lang ); if ($lines == 'true') { $geshi->enable_line_numbers( GESHI_NORMAL_LINE_NUMBERS ); }

Toca conferir! Coloquei na página de teste uma chamada do tipo

<geshi lines="true">qualquer coisa</geshi>

e o resultado foi o seguinte:

qualquer coisa

Não é que deu certo? A linha foi numerada! E daí, sabe como é que é, "trair e coçar, é só começar". Assim que "traí" o plugin do GeSHi, a coceira começou - e a coceira foi a seguinte: toda vez que eu chamasse o GeSHi para que mostrasse o código com linhas numeradas, a primeira linha receberia o número 1. E se a primeira linha de código fosse a 81, como mostrei um pouco mais acima? Bem, aí é só fazer o seguinte:

Informações adicionais