sexta-feira, 27 de maio de 2011

Botão para escolher entre "tree" e "places" no Nautilus Elementary

.
Você instalou o ótimo Nautilus Elementary, mas não gostou de perder aquele botãozinho que trocava entre a visão "tree" e "places", do painel da esquerda?

Nada mais fácil de resolver...

  • abra o terminal;
  • execute o gconf-editor;
  • abra o "diretório" apps;
  • dentro de apps, procure e abra o "diretório" nautilus;
  • dentro dele, clique em "preferences";
  • marque "sidebar_show_places_menu";
  • feche o gconf-editor
  • feche o terminal.... (dããã!)

Se tiver algum nautilus aberto, feche e reabra.

Tão fácil que nem vou colocar screenshots... :-)

Abraços!
Carlão

quinta-feira, 19 de maio de 2011

Programação de GUIs utilizando GTK - Parte 3

.
Back to life... :-)

Vamos estudar detalhadamente o programa "aloumundo" apresentado no post anterior. Também veremos alguns detalhes relacionados com a consulta a documentação da GTK. Por enquanto, estes artigos ainda serão baseados na GTK2, mas tentarei mostrar comparações com a nova GTK3, na medida do possível.

Falando em GTK3, algumas observações:
  • houve quebra da compatibilidade entre GTK2 e GTK3. Ou seja, não teremos 100% das coisas que funcionam em GTK2 funcionando diretamente (sem modificações) na GTK3;
  • devido a essa quebra de compatibilidade, é possível instalar no seu sistema as duas bibliotecas separadamente, e usar (na compilação) conforme o caso. Para instalar a nova GTK3 (para desenvolvimento) e suas dependências, basta instalar o pacote libgtk-3-dev;
  • já que estamos no gerenciador de pacotes... vamos instalar também devhelp (acesso a documentação das bibliotecas), libgtk2.0-doc (documentação offline da biblioteca GTK2), e libgtk3.0-doc (idem... GTK3);
  • para compilar com GTK3, basta alterar o parâmetro de pkg-config (veja post anterior) para "gtk+-3.0":


O programa funciona perfeitamente, a janela é criada e tals... mas note que, diferente do que acontece se compilarmos com GTK2, aparece uma mensagem de erro na execução:

Gtk-Message: Failed to load module "canberra-gtk-module"

Para resolver isso, basta instalar o pacote "libcamberra-gtk3-module" e suas dependências.

Mais do que simplesmente resolver um problema técnico imediato (um erro de compilação/execução), o fato acima gera a seguinte reflexão: "será que, ao instalarmos a biblioteca de desenvolvimento libgtk3-dev, já não deveria ser instalada também, automaticamente (como dependência), a biblioteca libcamberra-gtk3-module?" Ou seja, será que os desenvolvedores/empacotadores da GTK3 "comeram mosca" nessa questão ?

Feita esta reflexão, você pode ter 2 ações possíveis: reclamar da vida, reclamar dos desenvolvedores, dizer que a coisa tá mal feita, e ficar esperando alguém corrigir... ou ... entrar verdadeiramente no espírito do desenvolvimento colaborativo do software livre, e 1) identificar se isso é realmente um bug e 2) caso seja um bug, contribuir para seu conserto, que vai desde informar esse fato em uma lista de discussão apropriada ou em um sistema de gerenciamento de bugs, até efetivamente mudar o código. Nessa linha de ação, enviei um email para a lista "gnome-love" (específica para auxílio a novatos) para receber o feedback dos mais experientes sobre o fato. Depois coloco aqui a(s) resposta(s).


Segue então, o programa que iremos analisar:

1:  #include <gtk/gtk.h>
2:
3: int main (int argc, char *argv[])
4: {
5:
6: GtkWidget *window;
7:
8: gtk_init (&argc, &argv);
9:
10: window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11: gtk_window_set_title (GTK_WINDOW (window), "Alou, mundo!!");
12:
13: gtk_widget_show (window);
14:
15: gtk_main ();
16: return 0;
17:
18: }
19:

Para desenvolver com GTK, precisamos incluir (#include) o arquivo gtk.h. Apesar de gtk ser composta por várias bibliotecas de apoio, não precisamos indicá-las todas, o próprio gtk.h já faz isso pra gente. Claro que você precisará indicar outras bibliotecas (não relacionadas com GTK) que você quiser usar no seu programa.

Vamos então, nesse programa, criar e apresentar ao usuário uma simples janela. Precisamos então de uma variável para ser a referência desta janela. Criamos então a variável window, como um ponteiro para GtkWidget. A explicação de porque estamos criando esta variável como ponteiro para GtkWidget, e não GtkWindow, está no primeiro post desta série. Mas para relembrar rapidamente, todo objeto em gtk é construído a partir do objeto básico GtkWidget, utilizando o recurso de herança do paradigma de orientação a objetos. Logo, uma GtkWindow É um GtkWidget.

A função gtk_init é reponsável pela inicialização do ambiente GTK. Deve ser chamada antes de qualquer outra.

Vamos então, enfim, criar a janela. Atente para o fato que, neste passo, iremos criar a janela EM MEMÓRIA, ou seja, na verdade não vamos criar "o objeto gráfico janela, na tela", mas sim, criar as estruturas de dados em memória que vão armazenar e controlar o funcionamento deste futuro objeto gráfico. A função que faz isso é a gtk_window_new. Vamos ver na documentação qual é o protótipo desta função (ou seja, quais parâmetros precisamos passar para ela executar seu trabalho, e o que ela nos retorna). Vou utilizar para isso o DEVHELP, acessando dentro dele o "GTK+ 2 reference manual":


Para usar a função, então, precisaremos indicar um "GtkWindowType". O que é isso? É um parâmetro que diz que tipo de janela iremos criar, se uma janela principal (com tudo que tem direito, bordas, redimensionamento, título, etc...) ou uma janela "básica", sem esses recursos. Se clicarmos no próprio link "GtkWindowType, o DEVHELP vai nos mostrar que dados são válidos para este parâmetro (ou seja, quais os valores que estão definidos na enum GtkWindowType).


Podemos então passar para a função o valor GTK_WINDOW_TOPLEVEL (para uma janela normal, com tudo) ou GTK_WINDOW_POPUP (a janela básica "no osso"). O DEVHELP mostra uma descrição básica para esses valores.

Voltando a definição da função gtk_window_new, vemos que ela retorna um ponteiro para o tipo GtkWidget. Ou seja, vamos armazenar este retorno (que é efetivamente a referência para os dados da janela criados na memória) na variável window, criada anteriormente.

Vamos agora definir o texto que vai aparecer na barra de título da janela (Não esqueça que nossa janela ainda é um "projeto" de janela, na memória, e não um objeto gráfico bonitinho na tela do computador... ). Para isso utilizaremos a função gtk_window_set_title. Lá vamos nós novamente no DEVHELP...


A função não retorna nada (void), mas precisa de 2 parâmetros: um ponteiro para GtkWindow (referência da janela que vamos definir o texto na barra de título) e um ponteiro para "const gchar".

Como diria Jack, "vamos por partes": armazenamos a referência da janela num ponteiro para GtkWidget, e agora você diz que quer um ponteiro para GtkWindow? Bem, se você relembrar o primeiro post dessa série, verá que a hierarquia de objetos (widget hierarchy) começa em GtkWidget e, neste caso específico, termina em GtkWindow. Ou seja, uma GtkWindow É uma GtkWidget, então podemos usar uma variável no lugar da outra sem problemas! (ou quase...)

É "quase" sem problemas porque a linguagem C não foi construída levando em consideração o paradigma da orientação a objetos. Desta forma, algumas coisas não são tão transparentes como seriam numa linguagem especificamente projetada para este paradigma. No nosso caso, poderemos usar a variável window, que é GtkWidget, em um lugar que se espera uma GtkWindow, mas teremos que indicar que uma pequena conversão deverá ser feita. Isto é feito utilizando-se uma "função" que faz esse tipo de conversão pra gente. Neste caso, fica:

gtk_window_set_title ( GTK_WINDOW( window ) , ...

A função que "converte" algo em um GtkWindow é... GTK_WINDOW() !

(estou colocando "converte" entre aspas porque não é uma conversão propriamente dita, é mais uma indicação de tipo)

Mais devagar:
  • a variável window é um GtkWidget;
  • a "função" GTK_WINDOW( window ) indica que a variável window agora deverá ser tratada como uma GtkWindow. Nenhum problema aqui, pois como vimos, pelo paradigma de orientação a objetos, uma GtkWidget É um GtkWindow!
  • como window agora será tratada como um GtkWindow, podemos passar ela para a função gtk_window_set_title sem problemas!

Cuidado, se você consultar o livro de Andrew Krause, ele usa o termo "cast" para indicar essa operação de "conversão":
"... you can cast an object as a GtkWindow with GTK_WINDOW() ..."
Cuidado para não confundir com o cast básico da linguagem C, que tem outra sintaxe (tipo para o qual vamos converter entre parênteses, como em ... = (int) ... ).

Alguns "casts" disponíveis:

  • para GObject: G_OBJECT()
  • para GtkObject: GTK_OBJECT()
  • para GtkWidget: GTK_WIDGET() - Como sempre criaremos objetos do tipo GtkWidget, este "cast" raramente será usado.
  • para GtkContainer: GTK_CONTAINER()
  • para GtkBin: GTK_BIN()

... ou seja, uma função cujo nome é o tipo para o qual queremos "converter" em maiúsculas. Simples assim.

Falta o segundo parâmetro, o ponteiro para const gchar. Isso nada mais é que uma string, que será o texto da barra de título da janela. Se você lembrar, quando passamos algo como "blá blá blá" (uma string) para uma função, estamos na verdade passando o endereço inicial dessa string. Por exemplo, vamos lembrar a função fopen, que abre um arquivo para leitura e/ou escrita. Seu uso é, por exemplo:
arquivo = fopen ("dados_vendas.txt", "w");
Seu protótipo é:
FILE * fopen ( const char * filename, const char * mode )
... ou seja, a variável filename (ponteiro para caracter) recebe o endereço inicial da string "dados_vendas.txt".

Agora... porque gchar, e não apenas char?

Isso é feito para permitir compatibilidade em plataformas diferentes. Você lembra que, cada tipo de dado em C tem um tamanho em bytes específico, de acordo com a plataforma que está sendo usada. Por exemplo (hipotético), um int numa plataforma pode requerer 4 bytes de espaço, enquanto que em outra plataforma pode requerer 8 bytes. Para evitar esses problemas, e possibilitar uma compilação multiplataforma mais transparente, a biblioteca GLIB fornece tipos de dados padronizados, que serão "iguais" mesmo em plataformas diferentes. Assim, se no seu programa você utiliza os tipos de dados fornecidos pela GLIB, você poderá compilar em diversas plataformas diferentes sem se preocupar com as diferenças entre elas, no que diz respeito aos tipos de dados.

Alguns tipos fornecidos pela Glib:
  • gchar - equivalente ao char
  • gint - equivalente ao int
  • glong - equivalente ao long
  • gboolean - valores TRUE e FALSE (não tem equivalente no C)
Pra resumir:
gtk_window_set_title (GTK_WINDOW (window), "Alou, mundo!!");
... vai colocar a string "Alou mundo!!" na barra de título da janela indicada pela variável window.


Próxima linha:

gtk_widget_show (window);

Você deve estar pensando, "agora sim! beleza! um comando para efetivamente mostrar a janela na tela" !!!

No baby, ainda não...

Este comando apenas DEFINE a visibilidade de um certo objeto (isto é, se ele está visível ou invisível).

Essa questão da visibilidade é mais complexa do que parece num primeiro momento. Vejamos.

Neste nosso primeiro programa, estamos trabalhando apenas com um único objeto (uma janela). Não podemos esquecer que num programa "real", teremos vários objetos ao mesmo tempo, e esses objetos estarão organizados numa hierarquia: uma janela conterá outros objetos. Um desses objetos pode ser uma "frame" (caixa), que pode conter outros objetos (botões, labels, caixas de texto para digitação, etc).

Cada objeto individual possui seu próprio estado de visibilidade ou não. Mas um objeto ser configurado para estar visível não significa que ele vai certamente ser exibido... porque depende da visibilidade do objeto pai (o objeto que está "acima" na hierarquia) !

Vamos a um exemplo mais prático: imagine uma janela, e dentro dela, um único botão. Vamos definir esses 2 objetos como visíveis:

gtk_widget_show (window);
gtk_widget_show (button);

Quando o ambiente gráfico for efetivamente mostrar essas coisas na tela, os 2 objetos estarão visíveis.

Digamos agora que, por algum motivo, queremos esconder o botão do usuário (pra ele não poder clicar):

gtk_widget_hide (button);

Isso define que o botão está agora escondido ("hidden"). Quando o ambiente gráfico atualizar a tela, vai aparecer apenas a janela.

Vamos religar a exibição do botão:

gtk_widget_show (button);

Novamente, janela e botão visíveis na tela.

Agora vamos esconder A JANELA:

gtk_widget_hide (window);

Quando o ambiente gráfico atualizar a tela, não vai mostrar nem a janela, NEM O BOTÃO. Ué, mas o botão não está configurado para ser mostrado? Sim, mas como o botão poderia ser exibido, se ele está dentro da janela, e a própria janela não está visível?

Então, resumindo, definir a exibição ou não de um certo widget, não significa que ele vai ou não vai ser exibido. É preciso levar em consideração toda a estrutura da interface gráfica que você está construindo.

Antes de terminar esse comando, vejamos o protótipo:

void gtk_widget_show (GtkWidget *widget);

A função não devolve nada, e espera receber um ponteiro para GtkWidget. Como nossa variável window é deste tipo, podemos passar ela direto, nenhuma "conversão" necessária.

Último comando, e finalização do programa:

gtk_main();
return 0;

A função gtk_main() passa o controle do gerenciamento da interface gráfica que acabamos de montar e configurar (neste exemplo simples, apenas uma janela vazia) para o ambiente gráfico. Este, então, exibe a interface (a janela) e cuida dos "eventos", ou seja, da interação que o usuário fizer com ela. Note que podemos minimizar, maximizar, mover, redimensionar a janela, mesmo sem termos escrito nenhuma linha de código para tratar dessas questões. Não precisamos, porque quem cuida disso é o próprio ambiente gráfico. gtk_main(), portanto, geralmente é o último comando do nosso main. Quaisquer outros processamentos que nosso programa for realizar (para tratar as ações do usuário) deverá constar de funções, chamadas de "callback functions". Mas isso vai ser papo para outro post.

Note que a janela aparece e tals, mas quando clicamos no 'x' para fechar, ela até fecha, mas o programa continua rodando (o terminal fica "travado"). Isso acontece porque nosso programa não está tratando nenhum "evento" gerado pelo usuário. Para finalizar o programa, mesmo com a janela fechada, deveremos teclar control-C no terminal.

Fico por aqui. Lembrando que sugestões e correções são muito bem-vindas. Até a próxima!

Grande abraço!

Carlão

sexta-feira, 13 de agosto de 2010

Programação de GUIs utilizando GTK - Parte 2

.
Neste post vamos tratar da montagem do ambiente para programação GTK, exemplificando através de uma distribuição Ubuntu, versão 10.04 (GNU/Linux), recém instalada. Os requisitos para acompanhar este e os próximos posts são: conhecimentos (nível intermediário) da linguagem C (incluindo ponteiros), geração de arquivos-fonte e sua compilação pela linha de comando (terminal) utilizando o GCC.

Vamos começar com um programa simples, baseado em GTK+, uma espécie de "Hello World" dos programas em ambiente gráfico: mostra uma janela vazia na tela. O código segue abaixo:

 #include <gtk/gtk.h>
int main (int argc, char *argv[])
{
GtkWidget *window;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Alou, Mundo!!!");
gtk_widget_show (window);
gtk_main ();
return 0;
}

Não se preocupe com os detalhes do programa, veremos isso depois. O objetivo agora é apenas conseguir compilar e executar o dito cujo, pelo terminal. Gere um arquivo-fonte em C com o código acima, digamos, aloumundo.c, e tente compilar:

gcc -o aloumundo aloumundo.c

E receba um monte de mensagens de erro... :-)

 aloumundo.c:2:21: error: gtk/gtk.h: No such file or directory
aloumundo.c: In function ‘main’:
aloumundo.c:6: error: ‘GtkWidget’ undeclared (first use in this function)
aloumundo.c:6: error: (Each undeclared identifier is reported only once
aloumundo.c:6: error: for each function it appears in.)
aloumundo.c:6: error: ‘window’ undeclared (first use in this function)
aloumundo.c:10: error: ‘GTK_WINDOW_TOPLEVEL’ undeclared (first use in this function)

Bom, a coisa começa pelo fato de que o compilador não encontrou a biblioteca gtk (personificada, digamos assim, neste exemplo, pelo arquivo gtk.h). E a partir daí, nada relacionado com gtk foi interpretado.

O que acontece é que, apesar de estarmos usando um ambiente gráfico baseado em GTK (Gnome), ou seja, a biblioteca gtk está garantidamente instalada no sistema, precisamos instalar a biblioteca PARA DESENVOLVIMENTO. Em sistemas baseados no Debian, acho que em 99% dos casos, bibliotecas para desenvolvimento tem seu nome terminado em -dev (em outras distribuições, este tipo de biblioteca tem seu nome terminado em -devel).

Abrimos o gerenciador de pacotes Synaptic, e procuramos por libgtk:



Descobrimos que o nome correto é libgtk2.0-dev. Ao marcarmos para instalação, o Synaptic automaticamente seleciona outros pacotes que também são requeridos. Na verdade, quando falamos em GTK estamos falando em um conjunto de bibliotecas, como por exemplo, GLib (funções utilitárias de propósito geral), GDK (camada entre o sistema gráfico X e GTK), Pango (textos e fontes), ATK (acessibilidade), entre outras.



Agora, com as bibliotecas instaladas, podemos tentar compilar novamente, e.... ué?!?!? Erro de novo?

Isso acontece porque precisamos indicar ao GCC que queremos utilizar uma biblioteca extra, além da biblioteca-padrão, que ele já sabe usar diretamente. Isso significa indicar os seguintes itens:

  • caminho para o diretório onde estão os "includes" da(s) biblioteca(s) que você quer usar. Isso é feito utilizando-se a opção -I (letra "i" maiúscula);
  • caminho para o diretório onde estão as bibliotecas a serem utilizadas. Isso é feito utilizando-se a opção -L (letra "l" maiúscula);
  • finalmente, quais bibliotecas serão utilizadas, com a opção -l (letra "l" minúscula). Nomes de bibliotecas começam pelas letras "lib" (por exemplo, libblabla), e utilizamos com -lblabla (o nome depois do lib).

Já falamos que GTK é composta de várias bibliotecas de suporte. Isso significa dizer que, para compilar usando GTK, teremos que informar ao compilador, usando as opções acima, diretórios e bibliotecas para todas elas. Felizmente, temos um programa que nos auxilia nisso, chamado pkg-config, retornando as informações necessárias, para um pacote/biblioteca específico. Como nos diz o comando man,

"The pkg-config program is used to retrieve information about installed libraries in the system. It is typically used to compile and link against one or more libraries."

Então vamos experimentar, digite no terminal:

pkg-config --cflags --libs gtk+-2.0

A opção --cflags diz para retornar informações acerca dos includes, e --libs para bibliotecas, tudo isso relativo ao pacote indicado no final da linha, "gtk+-2.0".

Você deve ter obtido a seguinte saída:

-pthread -D_REENTRANT -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/directfb -I/usr/include/libpng12 -pthread -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lcairo -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0

... ou seja, todos os parâmetros necessários para você compilar um programa que utilize a biblioteca GTK (e suas companheiras).

E como utilizamos isso? Copio essa coisa toda e digito junto com o comando de compilação, gcc?? Não precisa. Podemos simplesmente indicar ao GCC que os parâmetros de compilação vão ser informados pelo pkg-config. Fazemos isso dessa forma:

gcc -o aloumundo aloumundo.c `pkg-config --cflags --libs gtk+-2.0`

A linha acima tem o seguinte efeito: o comando pkg-config é executado, e sua saída é integrada ao resto da linha (compilação com o gcc) como se tivesse sido digitada normalmente. Agora, CUIDADO!! O caracter que envolve o pkg-config é a CRASE (não é a aspa simples, não é o acento agudo!).

Agora, você deve obter uma compilação sem erros, já que todas as bibliotecas estão instaladas no sistema, e você indicou ao compilador como usá-las.

Falta só executar sua obra-prima.... :-)

./aloumundo



Algumas observações finais:

  • se você clicar no 'X' para fechar a janela, ela fecha, mas o programa continua sendo executado (o terminal fica "travado"). Para liberar o terminal, precisamos finalizar o programa na marra, teclando CONTROL-C. Isso acontece porque o 'X' causa apenas a parte gráfica da coisa (a janela some da tela), mas não a finalização do programa. Isso é nossa responsabilidade, e veremos como fazer isso posteriormente.
  • note que você pode mover a janela, minimizar, maximizar, redimensionar.... como isso é possível, se não escrevemos código para isso? Isso é papo pro próximo artigo.

Abraços a todas e a todos!

Carlão

sexta-feira, 30 de julho de 2010

O openSUSE é Software Livre? Acho que não...

Esbarrei outro dia numa notícia sobre o lançamento de uma nova versão (11.3) da distribuição openSUSE. Como gosto muito de experimentar várias distribuições Linux, ainda mais com as facilidades trazidas pela virtualização, baixei a dita cuja pra brincar um pouco.

Criei a máquina virtual, bootei, escolhi linguagem... e cheguei numa página onde eu tinha que aceitar uma licença. Como eu brinco com meus alunos, "aquela página que ninguém lê, vai logo clicando em aceito...". Bom, eu parei pra ler.

Começou promissor... "The openSUSE Project grants to you a license to this collective work pursuant to the GNU General Public License version 2...". Bom, não entendo muito de licenciamento, mas até onde sei, GPL é a licença que garante as liberdades de um software livre. Beleza então, tudo certo!

Até que li mais um pouco... "As required by US law, you represent and warrant that you: (...) c) will not export, re-export, or transfer openSUSE 11.3 to any prohibited destination, entity... d) will not use or transfer openSUSE 11.3 for use in any sensitive nuclear, chemical, or biological weapons or missile technology end-uses... "

Parou, parou, parou.... Se me lembro bem, duas das quatro liberdades do software livre são "a liberdade de executar o programa, para qualquer propósito" e "a liberdade de redistribuir cópias de modo que você possa ajudar ao seu próximo".

Então, voltamos a pergunta do título... o openSUSE é Software Livre?

Abortei a instalação, desliguei a máquina virtual, apaguei o arquivo ISO. Fica pruma outra oportunidade...

Abraços a todas e a todos!
Carlão

quinta-feira, 22 de julho de 2010

"Esse pessoal de Piracicaba, não é mole não!!"


Costumo ouvir (e fazer...) muitas críticas à nossa Universidade, em especial por conta da burocracia absurda que assola nosso trabalho docente e de pesquisa, no dia-a-dia.

Mas dessa vez, devemos aplaudir de pé!! O motivo é a nomeação, feita pelo CONSU/UESC, do novo prédio da Pós-Graduação como PAVILHÃO PROF. MAX DE MENEZES.

Não tive, infelizmente, muito contato com o Max no dia a dia. Mas nesse pouco contato já dava pra sentir aquela simpatia infinita, acompanhada daquele sorriso maroto piracicabano... O cara era, simplesmente, muito gente boa!!

Vai ser bom entrar no Pavilhão Prof. Max de Menezes. Vai ser como estar perto do coração dele mais uma vez.

Tchau Max! A gente se esbarra por aí um dia desses!

Abraços!

Carlão

segunda-feira, 7 de junho de 2010

Propaganda azul da morte...

.
Sábado passado, num monitor de propaganda no aeroporto de Congonhas...




Hehehehehehehehehehehehehe... Tenta Linux da próxima vez... :-)

Abraços!
Carlão

quinta-feira, 3 de junho de 2010

Como inserir código-fonte em uma postagem de um blog

.
No post anterior, precisei colocar vários códigos-fonte de exemplos, o que foi uma tarefa árdua. Por algum motivo que os experts em html devem saber (mas eu não...), o Blogger cismava de estragar minha formatação. Identação então, nem pensar... o bicho teimava em colocar tudo alinhado a esquerda! Achei que tinha resolvido isso, usando a dupla <> e < / pre >, e colocando um pontinho na primeira posição, pra ele respeitar meus espaços da identação...

Tava indo tudo muito bem, até que tentei colocar um exemplo de um laço for... rapaiz, nem com reza braba!! O bicho simplesmente sumia com um pedaço do código! Alguma combinação de caracteres no for deve significar alguma coisa doida pra ele...

Enfim, acho que encontrei a solução para o dilema: sites que formatam código fonte, gerando código html prontinho pra você colocar no post. São eles:

Source code formatter
http://codeformatter.blogspot.com/2009/06/about-code-formatter.html

Format my source code
http://formatmysourcecode.blogspot.com

Em ambos, o funcionamento é o mesmo: você digita seu código-fonte numa caixa, aperta um botão, e ele gera o código html que formata seu código. Os sites geram também um preview, pra você conferir o resultado.

A partir daí, é só copiar o código em html gerado, e levar para seu post. No caso do blogger, quando você estiver na tela de digitação do post, clique na aba "editar html", e cole o código gerado na posição correta.

Abraços!

Carlão