Informática Numaboa - Tutoriais e Programação

GeSHi à moda da casa

Qui

9

Jul

2009


12:17

  • Imprimir
(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:


Lá na altura da linha 59 os parâmetros são analisados, então vamos criar um novo parâmetro neste ponto. Chamei-o de "inicio" e seu valor padrão é 1:

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

Logo depois de criar o objeto $geshi é verificado se as linhas de código devem ser numeradas ou não. Neste ponto é usado uma das propriedades da classe geshi para iniciar a numeração, a enable_line_numbers. Vamos usar mais uma propriedade, a start_line_numbers_at, para que a numeração comece a partir do número indicado:

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

Agora, se eu chamar o GeSHi com

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

o resultado será:

qualquer coisa

E viva "nóis"!!! O resultado não poderia ser melhor biggrin

A terceira etapa

Já sei. Agora vocês vão me cobrar como colocar um título nos blocos do GeSHi. É lógico que vamos precisar de mais um parâmetro, que eu chamei de tit. Para ciscar este parâmetro, voltamos para as linhas depois da linha 59:

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

Com isto, se o parâmetro tit existir, ele será considerado; se não, a string será nada ou vazia. Agora, novamente logo depois de criar o objeto geshi, vamos informá-lo do estilo que queremos para a área de título (fique à vontade para criar o seu). Para isto usamos a propriedade set_header_content_style:

$geshi = new GeSHi( $text, $lang ); if ($lines == 'true') { $geshi->enable_line_numbers( GESHI_NORMAL_LINE_NUMBERS ); $geshi->start_line_numbers_at( $inicio ); } $geshi->set_header_content_style("border-bottom: 1px dotted #aaaaaa; padding: 3pt; margin-bottom: 10px; font-size: 12px; font-weight: bold; color: #666666");

Depois de definido o estilo, vamos usar a propriedade set_header_content para incluir o título:

$geshi = new GeSHi( $text, $lang ); if ($lines == 'true') { $geshi->enable_line_numbers( GESHI_NORMAL_LINE_NUMBERS ); $geshi->start_line_numbers_at( $inicio ); } $geshi->set_header_content_style("border-bottom: 1px dotted #aaaaaa; padding: 3pt; margin-bottom: 10px; font-size: 12px; font-weight: bold; color: #666666"); if( $tit != '') { $geshi->set_header_content( $tit ); }

Agora, se eu chamar o GeSHi com

<geshi lines="true" inicio="10" tit="Título">qualquer coisa</geshi>

o resultado será:

qualquer coisa

Este é o plugin do GeSHi que uso, bem à moda da casa. Mostro a seguir o código completo do plugin modificado:

registerEvent( 'onPrepareContent', 'plgContentGeshi' ); /** * 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; } /** * Replaces the matched tags an image * @param array An array of matches (see preg_match_all) * @return string */ function plgContentGeshi_replacer( &$matches ) { $params =& $GLOBALS['_MAMBOT_GESHI_PARAMS']; jimport('geshi.geshi'); jimport('domit.xml_saxy_shared'); $args = SAXY_Parser_Base::parseAttributes( $matches[1] ); $text = $matches[2]; $lang = JArrayHelper::getValue( $args, 'lang', 'php' ); $lines = JArrayHelper::getValue( $args, 'lines', 'false' ); $inicio = JArrayHelper::getValue( $args, 'inicio', '1' ); $tit = JArrayHelper::getValue( $args, 'tit', '' ); $html_entities_match = array( "|\
|", "#<#", "#>#", "|'|", '#"#', '# #' ); $html_entities_replace = array( "\n", '<', '>', "'", '"', ' ' ); $text = preg_replace( $html_entities_match, $html_entities_replace, $text ); $text = str_replace('<', '<', $text); $text = str_replace('>', '>', $text); // Replace tabs with "   " so tabbed code indents sorta right without making huge long lines. $text = str_replace( "\t", ' ', $text ); $geshi = new GeSHi( $text, $lang ); if ($lines == 'true') { $geshi->enable_line_numbers( GESHI_NORMAL_LINE_NUMBERS ); $geshi->start_line_numbers_at( $inicio ); } $geshi->set_header_content_style("border-bottom: 1px dotted #aaaaaa; padding: 3pt; margin-bottom: 10px; font-size: 12px; font-weight: bold; color: #666666"); if( $tit != '') { $geshi->set_header_content( $tit ); } $text = $geshi->parse_code(); return $text; }
Леди Шармкастрюля вокофициальный никас сайт харьковпланшеты цена https://ru.topodin.com/seo/post/prodvizhenie-sajtov-prodayuschih-plastikovye-okna-osobennosti-i-etapy-raboty topodin отзывыресторан nikas