<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bit a Bit &#187; Tutorial</title>
	<atom:link href="http://www.bitabit.eng.br/categorias/tecnologia/tutorial-tecnologia/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bitabit.eng.br</link>
	<description>O Blog da Engenharia de Computação da POLI-USP</description>
	<lastBuildDate>Wed, 11 Jan 2012 16:12:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Apache Solr: how to search sorting accented fields</title>
		<link>http://www.bitabit.eng.br/2011/03/16/sunspot-solr-how-to-sort-accented-fields/</link>
		<comments>http://www.bitabit.eng.br/2011/03/16/sunspot-solr-how-to-sort-accented-fields/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 20:28:18 +0000</pubDate>
		<dc:creator>Rafael Barbolo Lopes, Coop10</dc:creator>
				<category><![CDATA[Busca]]></category>
		<category><![CDATA[Coop10]]></category>
		<category><![CDATA[Cooperativo]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tecnologia]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[ascii]]></category>
		<category><![CDATA[ASCIIFoldingFilterFactory]]></category>
		<category><![CDATA[HTMLStripCharFilterFactory]]></category>
		<category><![CDATA[KeywordTokenizer]]></category>
		<category><![CDATA[KeywordTokenizerFactory]]></category>
		<category><![CDATA[latin]]></category>
		<category><![CDATA[LowerCaseFilterFactory]]></category>
		<category><![CDATA[Normalizing]]></category>
		<category><![CDATA[queries]]></category>
		<category><![CDATA[schema]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[solr]]></category>
		<category><![CDATA[StandardFilterFactory]]></category>
		<category><![CDATA[StandardTokenizerFactory]]></category>
		<category><![CDATA[string field]]></category>
		<category><![CDATA[sunspot]]></category>
		<category><![CDATA[TextField]]></category>
		<category><![CDATA[token]]></category>
		<category><![CDATA[tokenizer]]></category>

		<guid isPermaLink="false">http://www.bitabit.eng.br/?p=2054</guid>
		<description><![CDATA[We are using Apache Solr and Sunspot in a brazilian portuguese project and wanted it to work with accented chars. Normalizing latin chars (á, é, ç, &#8230;) to ASCII chars (a, e, c, &#8230;) in our search index and queries was pretty easy. We changed the text field definition to the following schema: 1 2 [...]]]></description>
			<content:encoded><![CDATA[<p>We are using <a href="http://lucene.apache.org/solr/">Apache Solr</a> and <a href="http://outoftime.github.com/sunspot/">Sunspot</a> in a brazilian portuguese project and wanted it to work with accented chars.</p>
<p><a href="http://www.bitabit.eng.br/wp-content/uploads/2011/03/apache_solr_logo.jpg"><img src="http://www.bitabit.eng.br/wp-content/uploads/2011/03/apache_solr_logo.jpg" alt="" title="Apache SOLR Logo" width="283" height="156" class="aligncenter size-full wp-image-2070" /></a></p>
<p>Normalizing latin chars (á, é, ç, &#8230;) to ASCII chars (a, e, c, &#8230;) in our search index and queries was pretty easy. We changed the text field definition to the following schema:</p>
<p><br/><br/></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fieldType</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;solr.TextField&quot;</span> <span style="color: #000066;">omitNorms</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;analyzer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;charFilter</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;solr.HTMLStripCharFilterFactory&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> <span style="color: #808080; font-style: italic;">&lt;!-- strip HTML --&gt;</span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tokenizer</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;solr.StandardTokenizerFactory&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;solr.StandardFilterFactory&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;solr.LowerCaseFilterFactory&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;solr.ASCIIFoldingFilterFactory&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> <span style="color: #808080; font-style: italic;">&lt;!-- convert accented chars to ASCII --&gt;</span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/analyzer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fieldType<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p><br/><br/></p>
<p>A more difficult problem was to sort accented string fields. By default, the class of the sunspot&#8217;s string field is <em>solr.StrField</em>. The string field is used for sorting, but was showing problems to sort accented inputs. For the inputs &#8220;árvore&#8221;, &#8220;bola&#8221;, &#8220;ano&#8221; it was showing the sorted result: &#8220;ano&#8221;, &#8220;bola&#8221;, &#8220;árvore&#8221; (the correct result would be &#8220;ano&#8221;, &#8220;árvore&#8221;, &#8220;bola&#8221;).</p>
<p>The problem with accented chars sorting is that non-ASCII chars are represented as HTML entites (for example, <em>&amp;aacute; </em>instead of<em> á</em>) and special chars as &#8220;&#038;&#8221; goes after alphanumeric chars in a sort.</p>
<p>To solve this, we changed the string field&#8217;s class to <em>solr.TextField</em> but making sure that its tokenizer would not create more than one token for each entry. The tokenizer we used was the <em>KeywordTokenizer</em>. The final schema for the string field was:</p>
<p><br/><br/></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fieldType</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;string&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;solr.TextField&quot;</span> <span style="color: #000066;">omitNorms</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;analyzer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;tokenizer</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;solr.KeywordTokenizerFactory&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;solr.LowerCaseFilterFactory&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;filter</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;solr.ASCIIFoldingFilterFactory&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/analyzer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fieldType<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p><br/><br/></p>
<img src="http://www.bitabit.eng.br/?ak_action=api_record_view&id=2054&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.bitabit.eng.br/2011/03/16/sunspot-solr-how-to-sort-accented-fields/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Yahoo Pipes</title>
		<link>http://www.bitabit.eng.br/2011/01/24/yahoo-pipes/</link>
		<comments>http://www.bitabit.eng.br/2011/01/24/yahoo-pipes/#comments</comments>
		<pubDate>Mon, 24 Jan 2011 10:10:51 +0000</pubDate>
		<dc:creator>Eduardo Russo, Coop10</dc:creator>
				<category><![CDATA[Busca]]></category>
		<category><![CDATA[Coop10]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tecnologia]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[filtro]]></category>
		<category><![CDATA[fluxo]]></category>
		<category><![CDATA[mac os x]]></category>
		<category><![CDATA[pipes]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[séries]]></category>
		<category><![CDATA[yahoo]]></category>

		<guid isPermaLink="false">http://www.bitabit.eng.br/?p=1767</guid>
		<description><![CDATA[Olá, meu nome é Eduardo Russo e faz 3 minutos que não acesso o Google Reader. Sim, sou um viciado em RSS e esse vício me fez querer filtrar o que acesso e até transformar o que não é RSS em RSS. A melhor maneira que encontrei para fazer isso foi o Yahoo Pipes, que, [...]]]></description>
			<content:encoded><![CDATA[<p>Olá, meu nome é Eduardo Russo e faz 3 minutos que não acesso o <a href="http://pt.wikipedia.org/wiki/Google_Reader" target="_blank">Google Reader</a>. Sim, sou um viciado em <a href="http://pt.wikipedia.org/wiki/RSS" target="_blank">RSS</a> e esse vício me fez querer filtrar o que acesso e até transformar o que não é RSS em RSS.</p>
<p><a href="http://www.bitabit.eng.br/wp-content/uploads/2011/01/pipeslogo_whitebg.gif"><img class="alignright size-full wp-image-1768" title="pipeslogo_whitebg" src="http://www.bitabit.eng.br/wp-content/uploads/2011/01/pipeslogo_whitebg.gif" alt="" width="119" height="45" /></a>A melhor maneira que encontrei para fazer isso foi o <a href="http://pipes.yahoo.com/pipes/" target="_blank">Yahoo Pipes</a>, que, de maneira resumida, é um gerador de fluxo, com diversas possibilidades de filtros e ações.Para explicar melhor o que o Pipes faz, é mais fácil dar exemplos.</p>
<p>Assinava o <a href="http://pt.wikipedia.org/wiki/Feeds" target="_blank">feed</a> do <a href="http://lifehacker.com/" target="_blank">Lifehacker</a> completo, mas, meu real interesse eram dicas sobre Macs. Para tal, filtrava com o poder do meu cérebro, tentando, rapidamente, achar a palavra &#8220;Mac&#8221; nas notícias. Obviamente perdia muito tempo e a taxa de erro era imensa. Fazer um programa em PHP, Ruby on Rails ou qualquer outra coisa similar, seria fácil, mas, não tanto quanto criar um fluxo no Yahoo Pipes.</p>
<p>Para isso, basta ter uma conta do Yahoo, acessar o Pipes e começar a criar. Ou, ainda, buscar por fluxos que outros criaram e que servem ao seu propósito.</p>
<p>Esse do Lifehacker é bem simples, mas dá pra fazer coisas inacreditáveis. Cheguei a criar um fluxo que dava <a href="http://pt.wikipedia.org/wiki/An%C3%A1lise_sint%C3%A1tica_%28computa%C3%A7%C3%A3o%29" target="_blank">parse </a>num HTML para gerar um RSS. Não é a coisa mais fácil do mundo – qualquer um que já tentou encontrar lógica num HTML sabe do que estou falando –, mas, é bem mais fácil do que fazer seu próprio programa, arrumar um local na web para colocá-lo e só então poder usá-lo.</p>
<p>Como se vê a seguir, meu fluxo pega o feed do Lifehacker e busca em cada campo pelas palavras &#8220;mac&#8221;, &#8220;os x&#8221; ou &#8220;ios&#8221; e colocam isso no output.</p>
<div id="attachment_1770" class="wp-caption aligncenter" style="width: 764px"><a href="http://www.bitabit.eng.br/wp-content/uploads/2011/01/yahoo-pipes-mac-on-lifehacker.png"><img class="size-full wp-image-1770" title="yahoo pipes - mac on lifehacker" src="http://www.bitabit.eng.br/wp-content/uploads/2011/01/yahoo-pipes-mac-on-lifehacker.png" alt="Filtros e output do Yahoo Pipes do Lifehacker" width="754" height="410" /></a><p class="wp-caption-text">Filtros e output do Yahoo Pipes do Lifehacker.</p></div>
<p style="text-align: left;">A ferramenta funciona com <a href="http://pt.wikipedia.org/wiki/Drag-and-drop" target="_blank">drag-and-drop</a>. Na esquerda, existem diversas opções de entrada, filtros e lógicas que podem ser aplicadas. Basta selecionar e juntar de maneira sequencial as ações.</p>
<p style="text-align: left;">Outra sequencia que criei foi para filtrar as novas legendas do <a href="http://legendas.tv/" target="_blank">Legendas.tv</a> para ver apenas as séries que eu acompanho. Não está 100% ainda, pois a busca é com &#8220;ous&#8221; e, portanto, tenho que remover coisas como &#8220;desperate&#8221; para que ele ache &#8220;house&#8221;, mas não &#8220;desperate housewifes&#8221;. Mas, com certeza filtrar manualmente algumas coisas incorretas é bem mais fácil do que o processo antigo.</p>
<div id="attachment_1771" class="wp-caption aligncenter" style="width: 767px"><a href="http://www.bitabit.eng.br/wp-content/uploads/2011/01/yahoo-pipes-series-on-legendas.tv_.png"><img class="size-full wp-image-1771" title="yahoo pipes - series on legendas.tv" src="http://www.bitabit.eng.br/wp-content/uploads/2011/01/yahoo-pipes-series-on-legendas.tv_.png" alt="Filtros e output do Yahoo Pipes do Legendas.tv" width="757" height="406" /></a><p class="wp-caption-text">Filtros e output do Yahoo Pipes do Legendas.tv</p></div>
<p style="text-align: left;">Neste exato momento, estou criando um Pipe para tentar transformar em RSS as <a href="http://cetsp1.cetsp.com.br/institucional/rodizio/default.asp" target="_blank">suspensões de rodízio de SP da CET</a>. Será um parto, mas, sei que é possível. Para ver meus Pipes, basta entrar no <a href="http://pipes.yahoo.com/pipes/person.info?guid=LJQTE6242D6UEDHWIVVCALWPJI" target="_blank">meu perfil</a>. Se você tem algum Pipe interessante ou alguma dica e quer compartilhar, deixe nos comentários.</p>
<img src="http://www.bitabit.eng.br/?ak_action=api_record_view&id=1767&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.bitabit.eng.br/2011/01/24/yahoo-pipes/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Inserção de código fonte em LaTeX usando Bundles do TextMate</title>
		<link>http://www.bitabit.eng.br/2010/11/03/insercao-de-codigo-fonte-em-latex-usando-bundles-do-textmate/</link>
		<comments>http://www.bitabit.eng.br/2010/11/03/insercao-de-codigo-fonte-em-latex-usando-bundles-do-textmate/#comments</comments>
		<pubDate>Wed, 03 Nov 2010 22:38:25 +0000</pubDate>
		<dc:creator>Eduardo Russo, Coop10</dc:creator>
				<category><![CDATA[Coop10]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tecnologia]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[bundle]]></category>
		<category><![CDATA[cvódigo fonte]]></category>
		<category><![CDATA[latex]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[mac os x]]></category>
		<category><![CDATA[png]]></category>
		<category><![CDATA[textmate]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.bitabit.eng.br/?p=1403</guid>
		<description><![CDATA[Um pouco depois de criar o comando para inserir PNGs no LaTeX usando os Bundles do TextMate, pensei que poderia fazer o mesmo para inserir códigos fonte. Aliás, inserção de código fonte foi o que me fez querer usar LaTeX a primeira vez. Não fosse isso, estaria fazendo o TCC no Word, sou fã de [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.bitabit.eng.br/wp-content/uploads/2010/11/TextMate.png"><img class="alignright size-full wp-image-1399" title="TextMate" src="http://www.bitabit.eng.br/wp-content/uploads/2010/11/TextMate.png" alt="" width="128" height="128" /></a>Um pouco depois de criar o comando para <a href="http://www.bitabit.eng.br/2010/11/02/insercao-de-png-em-latex-usando-bunddles-to-textmate/" target="_blank">inserir PNGs no LaTeX usando os Bundles do TextMate</a>, pensei que poderia fazer o mesmo para inserir códigos fonte.</p>
<p>Aliás, inserção de código fonte foi o que me fez querer usar LaTeX a primeira vez. Não fosse isso, estaria fazendo o TCC no Word, sou fã de GUI, prefiro GUI, mas a facilidade de deixar as coisas bonitas no LaTeX pra um texto monstro como a monografia de conclusão de curso me convenceram.Antes de tudo, algumas coisas em relação aos arquivos e definições: lí, sei lá aonde, que a melhor coisa é usar <a href="http://pt.wikipedia.org/wiki/UTF-8" target="_blank">UTF-8</a> para os arquivos, mas, se você fizer isso em TODOS os arquivos, perceberá que acentuação não funcionará com códigos fonte! Então seus arquivos vão ficar meio misturados: Texto e <a href="http://www.bibtex.org/" target="_blank">Bibliografia</a> em UTF-8 e códigos em <a href="http://pt.wikipedia.org/wiki/Latin1" target="_blank">Latin1</a>.</p>
<p>Para isso, você precisa prestar atenção na hora de salvar os arquivos no TextMate:</p>
<div id="attachment_1408" class="wp-caption aligncenter" style="width: 228px"><a href="http://www.bitabit.eng.br/wp-content/uploads/2010/11/latex-textmate-file_format.png"><img class="size-full wp-image-1408" title="latex-textmate-file_format" src="http://www.bitabit.eng.br/wp-content/uploads/2010/11/latex-textmate-file_format.png" alt="" width="218" height="162" /></a><p class="wp-caption-text">Codificações do TextMate na hora de salvar</p></div>
<p>Agora vamos às definições que você precisa colocar no sue LaTeX pra poder inserir códigos fonte &#8220;bonitinhos&#8221;. Esses são os pacotes que você precisará para isso:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="latex" style="font-family:monospace;"><span style="color: #E02020; ">\</span><span style="color: #800000;">usepackage</span><span style="color: #E02020; ">[</span><span style="color: #C08020; font-weight: normal;">&lt;strong&gt;utf8&lt;/strong&gt;</span><span style="color: #E02020; ">]{</span><span style="color: #2020C0; font-weight: normal;">inputenc</span><span style="color: #E02020; ">}</span>
<span style="color: #E02020; ">\</span><span style="color: #800000;">usepackage</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">color</span><span style="color: #E02020; ">}</span> <span style="color: #2C922C; font-style: italic;">% permite cores nos gráficos e códigos</span>
<span style="color: #E02020; ">\</span><span style="color: #800000;">usepackage</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">listings</span><span style="color: #E02020; ">}</span> <span style="color: #2C922C; font-style: italic;">% para importação de códigos fonte</span></pre></td></tr></table></div>

<p>Depois disso, você precisará criar o comando de inserção de código (perceba que aqui foi selecionado <strong>latin1</strong>):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="latex" style="font-family:monospace;"><span style="color: #E02020; ">\</span><span style="color: #800000;">renewcommand</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;"><span style="color: #800000; font-weight: normal;">\lstlistingname</span></span><span style="color: #E02020; ">}{</span><span style="color: #2020C0; font-weight: normal;">Código</span><span style="color: #E02020; ">}</span> <span style="color: #2C922C; font-style: italic;">% definição visual dos códigos fonte</span>
<span style="color: #800000; font-weight: normal;">\lstset</span><span style="color: #E02020; ">{</span>
 extendedchars=<span style="color: #800000; font-weight: normal;">\true</span>, <span style="color: #2C922C; font-style: italic;">% permite acentos</span>
 &lt;strong&gt;inputencoding=latin1&lt;/strong&gt;, <span style="color: #2C922C; font-style: italic;">% usa Latin1 nos códigos fonte</span>
 commentstyle=<span style="color: #800000; font-weight: normal;">\it</span>, <span style="color: #2C922C; font-style: italic;">% deixa os comentários em itálico</span>
 stringstyle=<span style="color: #800000; font-weight: normal;">\bf</span>, <span style="color: #2C922C; font-style: italic;">% não lembro o que faz, mas está funcionando</span>
 belowcaptionskip=5pt, <span style="color: #2C922C; font-style: italic;">% não lembro o que faz, mas está funcionando</span>
 numbers=left, <span style="color: #2C922C; font-style: italic;">% coloca a numeração na esquerda</span>
 stepnumber=1, <span style="color: #2C922C; font-style: italic;">% passos da numeração</span>
 firstnumber=1, <span style="color: #2C922C; font-style: italic;">% primeira linha</span>
 numberstyle=<span style="color: #800000; font-weight: normal;">\tiny</span>, <span style="color: #2C922C; font-style: italic;">% tamanho da fonte da numeração</span>
 breaklines=true, <span style="color: #2C922C; font-style: italic;">% permitir quebra de linha</span>
 frame=tb, <span style="color: #2C922C; font-style: italic;">% borda em cima e em baixo</span>
 basicstyle=<span style="color: #800000; font-weight: normal;">\footnotesize</span>, <span style="color: #2C922C; font-style: italic;">% estilo básico</span>
 stringstyle=<span style="color: #E02020; ">\</span><span style="color: #800000;">ttfamily</span>, <span style="color: #2C922C; font-style: italic;">% não lembro o que faz, mas está funcionando</span>
 showstringspaces=false, <span style="color: #2C922C; font-style: italic;">% não mostrar os espaços</span>
 mathescape, <span style="color: #2C922C; font-style: italic;">% não lembro o que faz, mas está funcionando</span>
 tabsize=3 <span style="color: #2C922C; font-style: italic;">% tamanho da tabulação</span>
<span style="color: #E02020; ">}</span></pre></td></tr></table></div>

<p>Com isso, basta alguns comandos e você consegue inserir um código fonte no seu LaTeX e, para facilitar ainda mais a vida, um Bundle de drag and drop pro TextMate.</p>
<p>Essa inserção de código fonte <a href="http://en.wikibooks.org/wiki/LaTeX/Packages/Listings" target="_blank">reconhece algumas linguagens</a> nativamente, mas, mesmo tipos não reconhecidos ficam bem com isso.</p>
<p>Seguindo os mesmos passos do artigo de inserção de PNGs, aperte <strong>CMD+OPTION+CNTRL+B</strong>, troque de “<strong>show all</strong>” para “<strong>drag commands</strong>”, vá até “<strong>LaTeX</strong>”.</p>
<p>Agora clique no botão de <strong>+</strong> e adicione um “<strong>New Drag Command</strong>”. chame como quiser… adicione as extensões de código fonte que prentende usar,  eu coloquei o seguinte:<strong> ada, ant, asm, as, c, cpp, htm, html, java, js, json, pl, php, py, rb, sh, sql, xml, vhdl</strong>.</p>
<p>Coloque no &#8220;Scope Selector&#8221;:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">text.tex.latex</pre></div></div>

<p>Agora insira o seguinte código:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'pathname'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;#{ENV['TM_BUNDLE_SUPPORT']}/lib/LaTeXUtils.rb&quot;</span>
filename = ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;TM_DROPPED_FILEPATH&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
relative_to = ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;TM_DIRECTORY&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
startfile = ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'TM_LATEX_MASTER'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">||</span> ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'TM_FILEPATH'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
master = <span style="color:#CC00FF; font-weight:bold;">Pathname</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>LaTeX.<span style="color:#9900CC;">master</span><span style="color:#006600; font-weight:bold;">&#40;</span>startfile<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">unless</span> master.<span style="color:#9900CC;">absolute</span>?
 master = master.<span style="color:#9900CC;">expand_path</span><span style="color:#006600; font-weight:bold;">&#40;</span>ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'TM_PROJECT_DIRECTORY'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
path = <span style="color:#CC00FF; font-weight:bold;">Pathname</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>filename<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">relative_path_from</span><span style="color:#006600; font-weight:bold;">&#40;</span>master.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">if</span> ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;TM_MODIFIER_FLAGS&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">match</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>SHIFT<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span>
 <span style="color:#CC0066; font-weight:bold;">print</span> <span style="color:#996600;">&quot;<span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>input{&quot;</span> <span style="color:#006600; font-weight:bold;">+</span> path <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot;}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">else</span>
 ext = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">extname</span><span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span>
 file_type = <span style="color:#9966CC; font-weight:bold;">case</span> ext
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.ada&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;Ada&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.ant&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;Ant&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.asm&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;Assembler&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.as&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;Assembler&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.c&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;C&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.cpp&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;C++&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.htm&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;HTML&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.html&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;HTML&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.java&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;Java&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.js&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;Java&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.json&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;Java&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.pl&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;Perl&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.php&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;PHP&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.py&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;Python&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.rb&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;Ruby&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.sh&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;sh&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.sql&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;SQL&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.xml&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;XML&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#996600;">&quot;.vhdl&quot;</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#996600;">&quot;VHDL&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#996600;">&quot;linguagem&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">end</span>
 <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;<span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>lstinputlisting[language=<span style="color:#000099;">\$</span>{1:#{file_type}}, tabsize = <span style="color:#000099;">\$</span>{2:4}, caption={<span style="color:#000099;">\$</span>{3:caption}}, label = {code:<span style="color:#000099;">\$</span>{4:#{path.to_s.gsub(/(<span style="color:#000099;">\.</span>[^.]*$)|(<span style="color:#000099;">\.</span><span style="color:#000099;">\.</span><span style="color:#000099;">\/</span>)/,&quot;</span><span style="color:#996600;">&quot;).gsub(/<span style="color:#000099;">\/</span>/,&quot;</span>_<span style="color:#996600;">&quot;)}}}]{#{path}}&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;<span style="color:#000099;">\n</span>&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Se você entende um pouquinho de programação, percebeu que é só acrescentar mais uma linha no case para inserir outras linguagens.</p>
<p>O meu ficou assim:</p>
<p style="text-align: center;">
<div id="attachment_1411" class="wp-caption aligncenter" style="width: 653px"><a href="http://www.bitabit.eng.br/wp-content/uploads/2010/11/latex-textmate-code-bundle.png"><img class="size-full wp-image-1411 " title="latex-textmate-code-bundle" src="http://www.bitabit.eng.br/wp-content/uploads/2010/11/latex-textmate-code-bundle.png" alt="" width="643" height="540" /></a><p class="wp-caption-text">Criação do Bundle para inserção de código fonte com drag and drop</p></div>
<p>Dessa forma, sempre que arrastar um código com uma dessas extensões, automaticamente a linha de inserção de código fonte já vai aparecer parcialmente preenchida, bastando apertar <strong>TAB</strong> para ir para o próximo campo.</p>
<img src="http://www.bitabit.eng.br/?ak_action=api_record_view&id=1403&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.bitabit.eng.br/2010/11/03/insercao-de-codigo-fonte-em-latex-usando-bundles-do-textmate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inserção simplificada de PNGs em LaTeX usando Bundles to TextMate</title>
		<link>http://www.bitabit.eng.br/2010/11/02/insercao-de-png-em-latex-usando-bunddles-to-textmate/</link>
		<comments>http://www.bitabit.eng.br/2010/11/02/insercao-de-png-em-latex-usando-bunddles-to-textmate/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 12:27:40 +0000</pubDate>
		<dc:creator>Eduardo Russo, Coop10</dc:creator>
				<category><![CDATA[Coop10]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tecnologia]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[bundle]]></category>
		<category><![CDATA[imagem]]></category>
		<category><![CDATA[latex]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[mac os x]]></category>
		<category><![CDATA[png]]></category>
		<category><![CDATA[textmate]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.bitabit.eng.br/?p=1388</guid>
		<description><![CDATA[O TextMate (Mac only…) tem uns comandos (Bundles) bem úteis pra Latex. Hoje descobri que basta arrastar uma imagem para um texto &#8220;.tex&#8221; que o TM automaticamente insere o contexto da imagem, bastando alterar os textos e apertar TAB pra ir pro próximo campo. Mas, o TCC do Anauê Costa, que usei como base, tinha [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.bitabit.eng.br/wp-content/uploads/2010/11/TextMate.png"><img class="alignright size-full wp-image-1399" title="TextMate" src="http://www.bitabit.eng.br/wp-content/uploads/2010/11/TextMate.png" alt="" width="128" height="128" /></a>O <a href="http://macromates.com/" target="_blank">TextMate</a> (Mac only…) tem uns comandos (<a href="http://manual.macromates.com/en/bundles" target="_blank">Bundles</a>) bem úteis pra <a href="http://www.tug.org/mactex/" target="_blank">Latex</a>. Hoje descobri  que basta arrastar uma imagem para um texto &#8220;.tex&#8221; que o TM  automaticamente insere o contexto da imagem, bastando alterar os textos e  apertar TAB pra ir pro próximo campo.</p>
<p>Mas, o TCC do <a href="http://twitter.com/#!/anauecosta" target="_blank">Anauê Costa</a>, que usei como base, tinha um &#8220;\newcommand&#8221; que simplificava o processo de inserção de imagens (adicione isso nas definições do seu LaTeX):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="latex" style="font-family:monospace;"><span style="color: #E02020; ">\</span><span style="color: #800000;">newcommand</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;"><span style="color: #800000; font-weight: normal;">\inputpng</span></span><span style="color: #E02020; ">}[</span><span style="color: #C08020; font-weight: normal;">4</span><span style="color: #E02020; ">]{</span><span style="color: #2C922C; font-style: italic;">%</span>
 <span style="color: #C00000; font-weight: normal;">\begin</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;"><span style="color: #0000D0; font-weight: normal;">figure</span></span><span style="color: #E02020; ">}[</span><span style="color: #C08020; font-weight: normal;">!htb</span><span style="color: #E02020; ">]</span>
 <span style="color: #E02020; ">\</span><span style="color: #800000;">centering</span>
 <span style="color: #E02020; ">\</span><span style="color: #800000;">includegraphics</span><span style="color: #E02020; ">[</span><span style="color: #C08020; font-weight: normal;">width=#4\<span style="color: #800000;">textwidth</span></span><span style="color: #E02020; ">]{</span><span style="color: #2020C0; font-weight: normal;">#1.png</span><span style="color: #E02020; ">}</span>
 <span style="color: #E02020; ">\</span><span style="color: #800000;">caption</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;"><span style="color: #800000; font-weight: normal;">\it</span> #3.</span><span style="color: #E02020; ">}</span>
 <span style="color: #E02020; ">\</span><span style="color: #800000;">label</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">fig:#2</span><span style="color: #E02020; ">}</span>
 <span style="color: #C00000; font-weight: normal;">\end</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;"><span style="color: #0000D0; font-weight: normal;">figure</span></span><span style="color: #E02020; ">}</span>
 <span style="color: #E02020; ">}</span></pre></td></tr></table></div>

<p>então, em vez de:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="latex" style="font-family:monospace;"><span style="color: #E02020; ">\</span><span style="color: #800000;">includegraphics</span><span style="color: #E02020; ">[</span><span style="color: #C08020; font-weight: normal;">width=1.0\<span style="color: #800000;">textwidth</span></span><span style="color: #E02020; ">]{</span><span style="color: #2020C0; font-weight: normal;">figuras/p-30-1-multiplataforma-marketshare_gartner.png</span><span style="color: #E02020; ">}</span>
 <span style="color: #E02020; ">\</span><span style="color: #800000;">caption</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">caption</span><span style="color: #E02020; ">}</span>
 <span style="color: #E02020; ">\</span><span style="color: #800000;">label</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">fig:figuras_p-30-1-multiplataforma-marketshare_gartner</span><span style="color: #E02020; ">}</span>
 <span style="color: #C00000; font-weight: normal;">\end</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;"><span style="color: #0000D0; font-weight: normal;">figure</span></span><span style="color: #E02020; ">}</span></pre></td></tr></table></div>

<p>você fica com:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="latex" style="font-family:monospace;"><span style="color: #800000; font-weight: normal;">\inputpng</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">figuras/p-30-1-multiplataforma-marketshare_gartner</span><span style="color: #E02020; ">}{</span><span style="color: #2020C0; font-weight: normal;">figuras_p-30-1-multiplataforma-marketshare_gartner</span><span style="color: #E02020; ">}{</span><span style="color: #2020C0; font-weight: normal;">caption</span><span style="color: #E02020; ">}{</span><span style="color: #2020C0; font-weight: normal;">1.0</span><span style="color: #E02020; ">}</span></pre></td></tr></table></div>

<p>Fiz então uma alteração no comando de inserção de imagem pra ele gerar o novo tipo quando arrastar uma imagem.</p>
<p>Para inseri-lo, no TM, aperte <strong>CMD+OPTION+CNTRL+B</strong>. Isso abrirá o editor de bundles.</p>
<p>Troque de &#8220;<em>show all</em>&#8221; para &#8220;<em>drag commands</em>&#8220;, vá até &#8220;LaTeX&#8221; e selecione o &#8220;<em>Include Image</em>&#8220;.</p>
<p>Tire a extensão &#8220;png&#8221; de lá, já que o comando novo só serve para PNG!</p>
<p>Agora clique no botão de + e adicione um &#8220;<em>New Drag Command</em>&#8221;</p>
<p>chame como quiser… adicione a extensão PNG e cole o código abaixo nele:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
 <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'pathname'</span>
 <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;#{ENV['TM_BUNDLE_SUPPORT']}/lib/LaTeXUtils.rb&quot;</span>
 filename = ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;TM_DROPPED_FILEPATH&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
 relative_to = ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;TM_DIRECTORY&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
 startfile = ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'TM_LATEX_MASTER'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">||</span> ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'TM_FILEPATH'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
 master = <span style="color:#CC00FF; font-weight:bold;">Pathname</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>LaTeX.<span style="color:#9900CC;">master</span><span style="color:#006600; font-weight:bold;">&#40;</span>startfile<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
 <span style="color:#9966CC; font-weight:bold;">unless</span> master.<span style="color:#9900CC;">absolute</span>?
 master = master.<span style="color:#9900CC;">expand_path</span><span style="color:#006600; font-weight:bold;">&#40;</span>ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'TM_PROJECT_DIRECTORY'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
 <span style="color:#9966CC; font-weight:bold;">end</span>
 path = <span style="color:#CC00FF; font-weight:bold;">Pathname</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>filename<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">relative_path_from</span><span style="color:#006600; font-weight:bold;">&#40;</span>master.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#41;</span>
 <span style="color:#9966CC; font-weight:bold;">case</span> ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'TM_MODIFIER_FLAGS'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006600; font-weight:bold;">/</span>OPTION<span style="color:#006600; font-weight:bold;">/</span>
 <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;<span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>begin{center}&quot;</span>,
 <span style="color:#996600;">&quot; <span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>includegraphics[height=<span style="color:#000099;">\$</span>{1:3in}]{#{path}}&quot;</span>,
 <span style="color:#996600;">&quot;<span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>end{center}&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;<span style="color:#000099;">\n</span>&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
 <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006600; font-weight:bold;">/</span>SHIFT<span style="color:#006600; font-weight:bold;">/</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;<span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>begin{figure}[<span style="color:#000099;">\$</span>{1:htbp}]&quot;</span>,
 <span style="color:#996600;">&quot;    <span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>centering&quot;</span>,
 <span style="color:#996600;">&quot;        <span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>includegraphics[height=<span style="color:#000099;">\$</span>{2:3in}]{#{path}}&quot;</span>,
 <span style="color:#996600;">&quot;    <span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>caption{<span style="color:#000099;">\$</span>{4:caption}}&quot;</span>,
 <span style="color:#996600;">&quot;    <span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>label{fig:<span style="color:#000099;">\$</span>{5:#{path.to_s.gsub(/(<span style="color:#000099;">\.</span>[^.]*$)|(<span style="color:#000099;">\.</span><span style="color:#000099;">\.</span><span style="color:#000099;">\/</span>)/,&quot;</span><span style="color:#996600;">&quot;).gsub(/<span style="color:#000099;">\/</span>/,&quot;</span>_<span style="color:#996600;">&quot;)}}}&quot;</span>,
 <span style="color:#996600;">&quot;<span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>end{figure}&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;<span style="color:#000099;">\n</span>&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
 <span style="color:#9966CC; font-weight:bold;">else</span>
 <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;<span style="color:#000099;">\\</span><span style="color:#000099;">\\</span>inputpng{#{path.to_s.gsub(&quot;</span>.<span style="color:#9900CC;">png</span><span style="color:#996600;">&quot;, &quot;</span><span style="color:#996600;">&quot;)}}{<span style="color:#000099;">\$</span>{1:#{path.to_s.gsub(/(<span style="color:#000099;">\.</span>[^.]*$)|(<span style="color:#000099;">\.</span><span style="color:#000099;">\.</span><span style="color:#000099;">\/</span>)/,&quot;</span><span style="color:#996600;">&quot;).gsub(/<span style="color:#000099;">\/</span>/,&quot;</span>_<span style="color:#996600;">&quot;)}}}{<span style="color:#000099;">\$</span>{2:caption}}{<span style="color:#000099;">\$</span>{3:1.0}<span style="color:#000099;">\}</span>&quot;</span>
 <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Adicione também no &#8220;<em>Scope Selector</em>&#8221; o seguinte:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">text.tex.latex</pre></td></tr></table></div>

<p>Com isso, sempre que você arrastar um PNG pro .tex, ele já vai gerar o código <em>automagicamente</em>!</p>
<p>Segue a imagem de como ficou aqui.</p>
<p style="text-align: left;">
<div id="attachment_1389" class="wp-caption aligncenter" style="width: 606px"><a href="http://www.bitabit.eng.br/wp-content/uploads/2010/11/textmate-latex-image-bunddle.png"><img class="size-full wp-image-1389   " title="textmate-latex-image-bundle" src="http://www.bitabit.eng.br/wp-content/uploads/2010/11/textmate-latex-image-bunddle.png" alt="" width="596" height="392" /></a><p class="wp-caption-text">Novo Bundle do TextMate para inserção de imagem em Latex.</p></div>
<p>Para inserir &#8220;PNGs&#8221; da forma &#8220;original&#8221;, basta pressionar <strong>SHIFT</strong> quando arrastar a imagem.</p>
<p>Observação: Esse é um post transcrito de um e-mail, na pressa, no meio  da correria de escrever o TCC da Poli, então, não está bem formatado,  cheio de imagens ilustrativas ou coisas do tipo… sorry <img src='http://www.bitabit.eng.br/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<img src="http://www.bitabit.eng.br/?ak_action=api_record_view&id=1388&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.bitabit.eng.br/2010/11/02/insercao-de-png-em-latex-usando-bunddles-to-textmate/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Explorando o software por trás do Facebook, a maior rede social do mundo</title>
		<link>http://www.bitabit.eng.br/2010/07/28/explorando-o-software-por-tras-do-facebook-a-maior-rede-social-do-mundo/</link>
		<comments>http://www.bitabit.eng.br/2010/07/28/explorando-o-software-por-tras-do-facebook-a-maior-rede-social-do-mundo/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 19:12:39 +0000</pubDate>
		<dc:creator>Rafael Barbolo Lopes, Coop10</dc:creator>
				<category><![CDATA[Busca]]></category>
		<category><![CDATA[Coop10]]></category>
		<category><![CDATA[Cooperativo]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tecnologia]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[bigpipe]]></category>
		<category><![CDATA[busca]]></category>
		<category><![CDATA[caches]]></category>
		<category><![CDATA[cassandra]]></category>
		<category><![CDATA[escalabilidade]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[haystack]]></category>
		<category><![CDATA[hive]]></category>
		<category><![CDATA[labs]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[MapReduce]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[scribe]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[thrift]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[varnish]]></category>

		<guid isPermaLink="false">http://www.bitabit.eng.br/?p=1263</guid>
		<description><![CDATA[Na escala em que o Facebook opera, muitas abordagens tradicionais para servir conteúdo web falham ou não são práticas. O desafio para os engenheiros do Facebook tem sido manter o site no ar com mais de meio bilhão de usuários ativos. Este artigo analisa técnicas e softwares que o Facebook usa para funcionar nesse nível. [...]]]></description>
			<content:encoded><![CDATA[<p>Na escala em que o <a href="http://www.facebook.com">Facebook</a> opera, muitas abordagens tradicionais para servir conteúdo web falham ou não são práticas. O desafio para os engenheiros do Facebook tem sido manter o site no ar com mais de <a href="http://blog.facebook.com/blog.php?post=409753352130" target="_blank"><strong>meio bilhão de usuários ativos</strong></a>.</p>
<p>Este artigo analisa técnicas e softwares que o Facebook usa para funcionar nesse nível.</p>
<p><a href="http://www.bitabit.eng.br/wp-content/uploads/2010/07/facebook_logo_bit_a_bit.jpg"><img class="alignright size-full  wp-image-1264" title="Logo do Facebook (Bit a Bit)" src="http://www.bitabit.eng.br/wp-content/uploads/2010/07/facebook_logo_bit_a_bit.jpg" alt="" width="205" height="68" /></a></p>
<p><br/></p>
<h2>Facebook: desafio de escalabilidade</h2>
<p>Antes de entrar em detalhes, aqui estão alguns <a href="http://michaelis.uol.com.br/moderno/portugues/index.php?lingua=portugues-portugues&#038;palavra=fact%F3ide&#038;CP=73594&#038;typeToSearchRadio=exactly&#038;pagRadio=50">factóides</a> para dar uma idéia do desafio de escalabilidade com o qual o Facebook tem que lidar:</p>
<ul>
<li>
<p>O Facebook serve mais de <a href="https://www.google.com/adplanner/planning/site_profile#siteDetails?identifier=www.facebook.com&amp;lp=true" target="_blank"><strong>550 bilhões de visualizações de páginas por mês</strong></a>;</p>
</li>
<li>
<p>Há mais fotos no Facebook do que em todos os outros sites de fotos juntos (<a href="http://www.watblog.com/2010/07/12/facebook-photos-leave-flickr-picasa-way-behind/" target="_blank">incluindo sites como o Flickr</a>);</p>
</li>
<li>
<p>Mais de <strong><a href="http://blog.facebook.com/blog.php?post=2406207130" target="_blank">3 bilhões de fotos</a></strong> são visualizadas por dia;</p>
</li>
<li>
<p>Mais de <a href="http://www.facebook.com/press/info.php?statistics" target="_blank"><strong>25 bilhões de tipos de conteúdo</strong></a> (atualizações de status, comentários, etc) são compartilhados todo mês;</p>
</li>
<li>
<p>O Facebook tem mais de <a href="http://www.datacenterknowledge.com/archives/2010/06/28/facebook-server-count-60000-or-more/" target="_blank"><strong>60 mil servidores</strong></a>.</p>
</li>
</ul>
<p><br/></p>
<h2>Softwares para escalar</h2>
<p>A infraestrutura de software que o Facebook usa pode ser vista como a de um site <a href="http://pt.wikipedia.org/wiki/LAMP" target="_blank">LAMP</a>, mas com melhorias e extensões de vários serviços. Por exemplo:</p>
<ul>
<li>
<p>O Facebook usa PHP, mas tem um compilador que permite que o sistema execute código nativo nos servidores web, aumentando significativamente seu desempenho;</p>
</li>
<li>
<p>O Facebook usa Linux, mas é um Linux otimizado para garantir alta vazão de rede;</p>
</li>
<li>
<p>O Facebook usa MySQL, mas principalmente para persistência de chaves-valores (<a href="http://pt.wikipedia.org/wiki/Hash" target="_blank">Hashes</a>), movendo lógicas de consultas e JOINS para a camada de aplicação dos servidores web em que otimizações são mais fáceis de implementar, usando por exemplo caches em memória;</p>
</li>
<li>
<p>Por fim, há sistemas customizados, como o <a href="http://www.facebook.com/note.php?note_id=76191543919" target="_blank">Haystack</a>, um objeto de armazenamento altamente escalável usado para servir a imensa quantidade de fotos do Facebook, e o <a href="http://github.com/facebook/scribe" target="_blank">Scribe</a>, um sistema de logging (registro de ações) que consegue operar na escala do Facebook (nada trivial).</p>
</li>
</ul>
<p>Vamos ao que interessa. Abaixo são apresentados os softwares (alguns) que o Facebook usa para fornecer a todos nós a maior rede social do mundo.</p>
<h3>Memcached<a href="http://www.bitabit.eng.br/wp-content/uploads/2010/07/memcached.png"><img class="alignright size-full wp-image-1302" title="Logo do Memcached" src="http://www.bitabit.eng.br/wp-content/uploads/2010/07/memcached.png" alt="" width="91" height="85" /></a></h3>
<p>O <a href="http://memcached.org/" target="_blank">Memcached</a> é no momento um dos softwares mais famosos na Internet. É um sistema de cache em memória distribuído que o Facebook (e vários outros sites) usam como uma camada de cache entre aplicação web e banco de dados (já que acesso a disco rígido é relativamente lento). Ao longo dos anos, o Facebook realizou diversas otimizações no Memcached e nos softwares que rodam em conjunto com ele.</p>
<p>O Facebook roda milhares de servidores Memcached com <a href="http://felipenasc.blogspot.com/2010/03/escalabilidade-de-aplicacoes-web-futuro.html" target="_blank">dezenas de tearabytes de dados em cache</a> a todo momento. É provavelmente a maior instalação de Memcached do mundo.</p>
<h3>HipHop for PHP<a href="http://www.bitabit.eng.br/wp-content/uploads/2010/07/hiphop.png"><img class="alignright size-full wp-image-1304" title="HipHop for PHP Logo" src="http://www.bitabit.eng.br/wp-content/uploads/2010/07/hiphop.png" alt="" width="86" height="113" /></a></h3>
<p>PHP é uma linguagem interpretada e por isso seu código quando executado é relativamente lento quando comparado com código que executa nativamente. O <a href="http://github.com/facebook/hiphop-php" target="_blank">HipHop</a> converte PHP em código C++ que pode ser então compilado e apresentar um desempenho melhor. Isso permite que o Facebook aproveite muito melhor seus servidores web já que dependem demais de PHP para servir conteúdo.</p>
<p>Uma pequena equipe de engenheiros no Facebook (inicialmente, apenas três) passou 18 meses <a href="http://developers.facebook.com/blog/post/358" target="_blank">desenvolvendo o HipHop</a>, que agora é usado em produção.</p>
<h3>Haystack</h3>
<p><a href="http://www.facebook.com/note.php?note_id=76191543919" target="_blank">Haystack</a> é o sistema de armazenamento e recuperação de fotos de alto desempenho do Facebook (a rigor, o Haystack é um armazenador de objetos, então ele não armazena apenas fotos). Existem mais de 20 bilhões de fotos no Facebook e cada uma é armazenada em quatro diferentes resoluções, resultando em mais 80 bilhões de fotos.</p>
<p>O desafio do Haystack não é apenas  armazenar bilhões de fotos, mas também executar tarefas com elas em que o desempenho é crítico, como por exemplo remoção, atualização ou acesso.</p>
<h3>BigPipe</h3>
<p>O <a href="http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919" target="_blank">BigPipe</a> é um sistema dinâmico para servir páginas web que o Facebook desenvolveu. Ele é capaz de dividir uma página em seções (chamadas &#8220;<em>pagelets</em>&#8220;) e servi-las em paralelo com desempenho ideal.</p>
<p>Por exemplo, a janela de chat é carregada separadamente, o feed de notícias é carregado separadamente, e assim por diante. Esses &#8220;<em>pagelets</em>&#8221; podem ser carregados em paralelo, que é de onde vem o ganho de desempenho, e os usuários recebem um site que funciona mesmo se uma parte dele for desativada ou estiver com defeitos.</p>
<h3>Cassandra<a href="http://www.bitabit.eng.br/wp-content/uploads/2010/07/cassandra.png"><img class="alignright size-full wp-image-1305" title="Logo do Cassandra NoSQL" src="http://www.bitabit.eng.br/wp-content/uploads/2010/07/cassandra.png" alt="" width="200" height="43" /></a></h3>
<p><a href="http://cassandra.apache.org/" target="_blank">Cassandra</a> é um sistema de armazenamento distribuído baseado no projeto do <a href="http://labs.google.com/papers/bigtable.html" target="_blank">BigTable</a>. Ele é um dos filhos de destaque do movimento <a href="http://escalabilidade.com/2010/03/08/introducao-ao-nosql-parte-i/" target="_blank">NoSQL</a> e se tornou open source (virou um projeto Apache). O Facebook o usa na  pesquisa Inbox.</p>
<p>Além do Facebook, uma série de outros sites também o usam, como o Twitter e o Digg. É um sistema capaz de armazenar uma quantidade imensa de dados sem comprometer o tempo de busca e acesso a eles.</p>
<h3>Scribe</h3>
<p><a href="http://github.com/facebook/scribe" target="_blank">Scribe</a> é um sistema de logging flexível e escalável que o Facebook usa para uma infinidade de propósitos internos. Ele foi criado para ser capaz de registrar todas as ações ocorridas no Facebook, e automaticamente lida com novas categorias de ações registradas conforme aparecem (o Facebook tem centenas).</p>
<h3>Hadoop e Hive<a href="http://www.bitabit.eng.br/wp-content/uploads/2010/07/hadoop.png"><img class="alignright size-full wp-image-1306" title="Logo do Hadoop" src="http://www.bitabit.eng.br/wp-content/uploads/2010/07/hadoop.png" alt="" width="200" height="48" /></a></h3>
<p>O <a href="http://hadoop.apache.org/" target="_blank">Hadoop</a> é uma implementação open source de <a href="http://labs.google.com/papers/mapreduce.html" target="_blank">MapReduce</a> que permite a execução de cálculos em uma quantidade massiva de dados. O Facebook o usa para análise de dados de sua rede. O <a href="http://hadoop.apache.org/hive/" target="_blank">Hive</a> é uma interface de acesso ao Hadoop através de consultas SQL, facilitando seu uso, e teve origem dentro do Facebook.</p>
<p>Tanto o Hadoop quanto o Hive são open source (projetos Apache) e são usados por uma série de grandes sites, como o Yahoo e o Twitter.</p>
<h3>Thrift</h3>
<p>O Facebook usa diferentes linguagens para os seus diferentes serviços. PHP é usada para front-end, Erlang é usada para Chat, Java e C++ são usados em diversas áreas. <a href="http://incubator.apache.org/thrift/" target="_blank">Thrift</a> é um framework cross-language desenvolvido internamente que junta todas as diferentes linguagens, permitindo que elas conversem entre si. Isso facilita enormemente o desenvolvimento cross-language no Facebook.</p>
<p>O Facebook tornou o Thrift open source e adicionou suporte a mais linguagens de programação.</p>
<h3>Varnish<a href="http://www.bitabit.eng.br/wp-content/uploads/2010/07/varnish.png"><img class="alignright size-full wp-image-1309" title="Logo do Varnish" src="http://www.bitabit.eng.br/wp-content/uploads/2010/07/varnish.png" alt="" width="200" height="54" /></a></h3>
<p>O <a href="http://varnish-cache.org/" target="_blank">Varnish</a> é um acelerador HTTP, que pode agir como um balanceador de carga e também realiza cache de conteúdo para servi-lo rapidamente.</p>
<p>O Facebook usa o Varnish para servir fotos, lidando com bilhões de requisições todos os dias. Como quase tudo que o Facebook usa, o Varnish também é open source.</p>
<p><br/></p>
<h2>Outras coisas que ajudam o Facebook a funcionar bem</h2>
<p>Foram mencionados os softwares que constituem o Facebook e o ajudam a escalar. Mas operar um sistema tão grande é uma tarefa complexa, por isso serão listadas outras coisas que ajudam o Facebook a funcionar sem problemas:</p>
<h3>Lançamento gradual de novas funcionalidades e execuções no escuro</h3>
<p>O Facebook tem um sistema chamado de &#8220;<em>Gatekeeper</em>&#8221; (porteiro) que permite que eles rodem diferentes versões do sistema para diferentes conjuntos de usuários. Ele permite que o Facebook lance novas funcionalidades gradualmente e que testes A/B sejam realizados com usuários.</p>
<p>O &#8220;<em>Gatekeeper</em>&#8221; também é responsável por realizar o que é chamado de &#8220;<em>dark launches</em>&#8221; (lançamentos no escuro), que é a ativação de elementos de uma nova funcionalidade antes de ela ir pro ar. É uma maneira de realizar testes de carga do sistema antes de uma funcionalidade ser oficialmente lançada. Normalmente os &#8220;<em>dark launches</em>&#8221; são realizados duas semanas antes do lançamento oficial da funcionalidade.</p>
<h3>Monitoramento do sistema em produção</h3>
<p>O Facebook cuidadosamente monitora seu sistema e o desempenho de cada função PHP executada em ambiente de produção. Com isso é possível projetar um perfil do sistema que está no ar com a ajuda de uma ferramenta chamada <a href="http://pecl.php.net/package/xhprof" target="_blank">XHProf</a> e identificar gargá-los ou áreas que estão operando incorretamente.</p>
<h3>Desativação gradual de recursos para aumento de desempenho</h3>
<p>Se o Facebook tiver algum problema de desempenho, existe um grande número de recursos não-críticos que podem ser desativados para aumentar o desempenho de funcionalidades vitais da rede social. Desta forma, em uma situação de emergência, o núcleo da rede social poderá continuar funcionando normalmente.</p>
<h3>Coisas que não foram mencionadas</h3>
<p>O hardware usado pelo Facebook não entrou em discussão neste artigo, mas é um aspecto importante de analisar quando se pensa em escalabilidade. Por exemplo, o Facebook usa a rede CDN para servir conteúdo estático e possui enormes <em>data centers</em> que hospedam milhares de servidores.</p>
<p>E além do que foi mencionado, existem diversos outros softwares envolvidos na operação do Facebook. Neste artigo foram destacadas as escolhas mais interessantes que o Facebook fez.</p>
<p><br/></p>
<h2>Facebook e projetos open source</h2>
<p>Antes de encerrar o artigo, é importante mencionar o quanto o Facebook, assim como outras grandes empresas de Internet, apoia projetos open source. O Facebook não apenas usa e contribui com software open source como Linux, Memcached, MySQL e Hadoop, como também desenvolve internamente diversas ferramentas que são disponibilizadas como projetos open source.</p>
<p>Uma lista com todos os projetos  open source em que o Facebook atua pode ser encontrada na página <a href="http://facebook.com/opensource" target="_blank"><em>Open Source &#8211; Desenvolvedores do Facebook</em></a>.</p>
<p><br/></p>
<h2>Mais desafios de escalabilidade por vir</h2>
<p>O Facebook cresce a passos incríveis. Sua base de usuários aumenta quase que exponencialmente e já superou <strong>500 milhões de usuários</strong>. Ele tem mantido uma taxa de cerca de <strong>100 milhões de novos usuários a cada 6 meses</strong>.</p>
<p>O rápido crescimento significa que o Facebook vai ter problemas e diversos desafios de desempenho para apresentar cada vez mais páginas, buscas, imagens, mensagens e todos os outros recursos com os quais os usuários interagem. Para um site como o Facebook, este sempre será um fato com o qual ele terá que viver, e seus engenheiros estarão sempre atentos e criando novas maneiras de fazer o sistema escalar.</p>
<p>Vamos acompanhar o que os engenheiros do Facebook estão desenvolvendo! Com certeza surgirão coisas interessantes, afinal de contas, eles estão escalando uma montanha que muitos de nós podemos apenas sonhar; um site com mais pessoas do que a maioria dos países. Quando isso acontece, é preciso ser criativo.</p>
<p><br/><br />
Este artigo é uma adaptação/atualização para o português do artigo em inglês <a href="http://royal.pingdom.com/2010/06/18/the-software-behind-facebook/" target="_blank"><em>Exploring the software behind Facebook, the world&#8217;s largest site</em></a>.<br />
<br/></p>
<img src="http://www.bitabit.eng.br/?ak_action=api_record_view&id=1263&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.bitabit.eng.br/2010/07/28/explorando-o-software-por-tras-do-facebook-a-maior-rede-social-do-mundo/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Captura de páginas com Nokogiri</title>
		<link>http://www.bitabit.eng.br/2010/06/29/captura-de-paginas-com-nokogiri/</link>
		<comments>http://www.bitabit.eng.br/2010/06/29/captura-de-paginas-com-nokogiri/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 03:00:51 +0000</pubDate>
		<dc:creator>Rafael Barbolo Lopes, Coop10</dc:creator>
				<category><![CDATA[Busca]]></category>
		<category><![CDATA[Coop10]]></category>
		<category><![CDATA[Cooperativo]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tecnologia]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[biblioteca]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[libxml2]]></category>
		<category><![CDATA[mac os x]]></category>
		<category><![CDATA[nokogiri]]></category>
		<category><![CDATA[parse]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[rubygems]]></category>
		<category><![CDATA[screen scraping]]></category>
		<category><![CDATA[sistemas operacionais]]></category>

		<guid isPermaLink="false">http://www.bitabit.eng.br/?p=1217</guid>
		<description><![CDATA[Neste artigo, vou explicar de forma prática como utilizar a biblioteca Nokogiri com a linguagem de programação Ruby para extrair informações de páginas na Internet. O exemplo que vai guiar este artigo é a criação de um aplicativo que extrai o preço de um produto qualquer do site da Fast Shop. Ele será usado para [...]]]></description>
			<content:encoded><![CDATA[<p>Neste artigo, vou explicar de forma  prática como utilizar a biblioteca <a href="http://nokogiri.org/">Nokogiri</a> com a linguagem de programação <a href="http://www.ruby-lang.org/pt/">Ruby</a> para extrair informações de páginas na Internet.</p>
<p>O exemplo que vai guiar este artigo é a criação de um aplicativo que extrai o preço de um produto qualquer do site da Fast Shop. Ele será usado para encontrarmos o preço do <a href="http://www.fastshop.com.br/MACBOOK-WHITE-COM-INTEL-CORE-2-DUO--2GB--HD-250GB--TELA-133--PLACA-GRAFICA-NVIDIA-GEFORCE-320M-COM-256MB--SISTEMA-OPERACIONAL-MAC-OS-X-LEOPARD---APPLE---MC516BZA,product,AEMC516BZA,3.aspx">MacBook White</a>.</p>
<p><br/></p>
<h2>1. Instalando Ruby + RubyGems</h2>
<p>Se você usa <strong>Windows</strong>, baixe e instale a última versão estável do interpretador Ruby  <a href="http://www.ruby-lang.org/pt/downloads/">clicando aqui</a>.</p>
<p>Se você usa <strong>Mac OS X</strong>, <strong>Solaris</strong> ou uma distro <strong>linux</strong> popular, seu sistema já vem com Ruby instalado.</p>
<p>RubyGems é um gerenciador de pacotes (programas e bibliotecas) para Ruby. Para instalá-lo, baixe a última versão do aplicativo <a href="http://rubyforge.org/frs/?group_id=126" target="_blank">clicando aqui</a> e execute o comando abaixo no diretório com o arquivo descompactado:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ruby setup.rb
gem update <span style="color: #660033;">--system</span></pre></div></div>

<p><br/></p>
<h2>2. Instalando Nokogiri</h2>
<p><strong>Mac OS X</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> port <span style="color: #c20cb9; font-weight: bold;">install</span> libxml2 libxslt
<span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> nokogiri</pre></div></div>

<p><strong>Ubuntu/Debian</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># pacotes de desenvolvimento ruby</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> ruby1.8-dev ruby1.8 ri1.8 rdoc1.8 irb1.8
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> libreadline-ruby1.8 libruby1.8 libopenssl-ruby
&nbsp;
<span style="color: #666666; font-style: italic;"># requisitos do nokogiri</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> libxslt-dev libxml2-dev
<span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> nokogiri
&nbsp;
<span style="color: #666666; font-style: italic;"># requisitos do nokogiri para Hardy (8.04) ou uma versão mais atual</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> libxslt1-dev libxml2-dev</pre></div></div>

<p><strong>Windows</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">gem <span style="color: #c20cb9; font-weight: bold;">install</span> nokogiri</pre></div></div>

<p><br/></p>
<h2>3. Baixando a página do produto</h2>
<p>O trecho de código que baixa a página do <a href="http://www.fastshop.com.br/MACBOOK-WHITE-COM-INTEL-CORE-2-DUO--2GB--HD-250GB--TELA-133--PLACA-GRAFICA-NVIDIA-GEFORCE-320M-COM-256MB--SISTEMA-OPERACIONAL-MAC-OS-X-LEOPARD---APPLE---MC516BZA,product,AEMC516BZA,3.aspx">MacBook</a> se encontra abaixo:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># url do produto</span>
url = <span style="color:#996600;">'http://www.fastshop.com.br/MACBOOK-WHITE-COM-INTEL-CORE-2-DUO--2GB--HD-250GB--TELA-133--PLACA-GRAFICA-NVIDIA-GEFORCE-320M-COM-256MB--SISTEMA-OPERACIONAL-MAC-OS-X-LEOPARD---APPLE---MC516BZA,product,AEMC516BZA,3.aspx'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># html da página</span>
html = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">get</span> <span style="color:#CC00FF; font-weight:bold;">URI</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># html analisado pelo nokogiri</span>
doc = <span style="color:#6666ff; font-weight:bold;">Nokogiri::HTML</span><span style="color:#006600; font-weight:bold;">&#40;</span>html<span style="color:#006600; font-weight:bold;">&#41;</span></pre></td></tr></table></div>

<p><br/></p>
<h2>4. Extraindo o preço do produto</h2>
<p>Para extrair o preço do produto a partir do HTML baixado, vamos utilizar o plugin <a href="https://addons.mozilla.org/pt-BR/firefox/addon/1843/">Firebug</a> para analisar a estrutura do HTML. Ele permitirá que encontremos o <a href="http://www.w3.org/TR/xpath/">XPath</a> (XML Path Language) do elemento que contém o preço do produto.</p>
<p>Na captura de tela abaixo, podemos ver como isso é feito:</p>
<p><a href="http://www.bitabit.eng.br/wp-content/uploads/2010/06/fastshop-firebug.png"><img class="size-large wp-image-1245" title="Análise de produto na FastShop com Firebug" src="http://www.bitabit.eng.br/wp-content/uploads/2010/06/fastshop-firebug.png" alt="" width="768" height="480" /></a></p>
<p>Verificamos que a seguinte estrutura de nós de HTML guarda o preço do produto:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;</span>div <span style="color: #007800;">id</span>=<span style="color: #ff0000;">&quot;boxInfosPagamento&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span>
   <span style="color: #000000; font-weight: bold;">&lt;</span>p <span style="color: #007800;">class</span>=<span style="color: #ff0000;">&quot;preco&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span>
        <span style="color: #000000; font-weight: bold;">&lt;</span>span<span style="color: #000000; font-weight: bold;">&gt;</span>PRECO DO PRODUTO<span style="color: #000000; font-weight: bold;">&lt;/</span>span<span style="color: #000000; font-weight: bold;">&gt;</span>
   <span style="color: #000000; font-weight: bold;">&lt;/</span>p<span style="color: #000000; font-weight: bold;">&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;/</span>div<span style="color: #000000; font-weight: bold;">&gt;</span></pre></div></div>

<p>Podemos traduzir essa estrutura para o seguinte XPath:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#996600;">&quot;//div[@id='boxInfosPagamento']/p[@class='preco']/span&quot;</span></pre></div></div>

<p><br/></p>
<h2>5. Aplicativo final</h2>
<p>O aplicativo final que imprime o preço do produto pode ser visto abaixo:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># importando bibliotecas necessárias:</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;rubygems&quot;</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;nokogiri&quot;</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;net/http&quot;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># url do produto</span>
url = <span style="color:#996600;">'http://www.fastshop.com.br/MACBOOK-WHITE-COM-INTEL-CORE-2-DUO--2GB--HD-250GB--TELA-133--PLACA-GRAFICA-NVIDIA-GEFORCE-320M-COM-256MB--SISTEMA-OPERACIONAL-MAC-OS-X-LEOPARD---APPLE---MC516BZA,product,AEMC516BZA,3.aspx'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># html da página</span>
html = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">get</span> <span style="color:#CC00FF; font-weight:bold;">URI</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># html analisado pelo nokogiri</span>
doc = <span style="color:#6666ff; font-weight:bold;">Nokogiri::HTML</span><span style="color:#006600; font-weight:bold;">&#40;</span>html<span style="color:#006600; font-weight:bold;">&#41;</span>
doc.<span style="color:#9900CC;">encoding</span> = <span style="color:#996600;">'utf-8'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># preço do produto</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> doc.<span style="color:#9900CC;">xpath</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;//div[@id='boxInfosPagamento']/p[@class='preco']/span&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">inner_html</span></pre></td></tr></table></div>

<p>A captura de tela abaixo mostra a execução do aplicativo:</p>
<p><a href="http://www.bitabit.eng.br/wp-content/uploads/2010/06/execucao-fastshop.png"><img class="aligncenter size-full wp-image-1246" title="Execução do aplicativo que extrai preço da FastShop" src="http://www.bitabit.eng.br/wp-content/uploads/2010/06/execucao-fastshop.png" alt="" width="745" height="559" /></a></p>
<p><br/></p>
<h2>6. Conclusões</h2>
<p>Nokogiri é uma biblioteca muito robusta que suporta seleção de elementos com XPath ou seletor CSS3 de forma simples e eficiente. Sempre que precisar analisar XML ou HTML, considere usá-la em seu projeto.</p>
<p>Em artigos futuros vou falar mais sobre extração e análise de informações da Internet. Se tiver alguma dúvida ou sugestão de tema, deixe seu comentário!<br />
<br/><br/><br/></p>
<img src="http://www.bitabit.eng.br/?ak_action=api_record_view&id=1217&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.bitabit.eng.br/2010/06/29/captura-de-paginas-com-nokogiri/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>CloudApp: uploader + encurtador de url para Mac</title>
		<link>http://www.bitabit.eng.br/2010/04/15/cloudapp-uploader-encurtador-de-url-para-mac/</link>
		<comments>http://www.bitabit.eng.br/2010/04/15/cloudapp-uploader-encurtador-de-url-para-mac/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 10:27:50 +0000</pubDate>
		<dc:creator>Eduardo Russo, Coop10</dc:creator>
				<category><![CDATA[Coop10]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tecnologia]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[barra de menus]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[cloudapp]]></category>
		<category><![CDATA[dica]]></category>
		<category><![CDATA[encurtador de url]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[produtividade]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[uploader]]></category>
		<category><![CDATA[url shortner]]></category>

		<guid isPermaLink="false">http://www.bitabit.eng.br/?p=1190</guid>
		<description><![CDATA[A moda dos encurtadores de URL vieram para ficar, porém, conheci o CloudApp como um uploader rápido, que fica na sua cara o tempo todo e, com o uso, descobri que ele também é um encurtador de URL. Lançado no começo do mês, o aplicativo facilita muito subir arquivos para compartilhar com quem você quiser, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-1194" title="cloudapp-icone" src="http://www.bitabit.eng.br/wp-content/uploads/2010/04/cloudapp-icone.png" alt="cloudapp-icone" width="128" height="128" />A moda dos encurtadores de URL vieram para ficar, porém, conheci o <a href="http://www.getcloudapp.com/" target="_blank">CloudApp</a> como um <em>uploader</em> rápido, que fica na sua cara o tempo todo e, com o uso, descobri que ele também é um encurtador de URL.</p>
<p>Lançado no <a href="http://www.getcloudapp.com/blog/" target="_blank">começo do mês</a>, o aplicativo facilita muito subir arquivos para compartilhar com quem você quiser, seja usando o <a href="http://twitter.com/russoedu" target="_blank">Twitter</a>, seja enviando um e-mail com o link.</p>
<p style="text-align: center;">
<div id="attachment_1192" class="wp-caption aligncenter" style="width: 336px"><img class="size-full wp-image-1192" title="cloudapp-barra-de-menus" src="http://www.bitabit.eng.br/wp-content/uploads/2010/04/cloudapp-barra-de-menus.png" alt="CloudApp instalado na barra de menus" width="326" height="286" /><p class="wp-caption-text">CloudApp instalado na barra de menus</p></div>
<p>Depois de se cadastrar no site – grátis, com a única limitação de arquivos não serem maiores que 50 MB – e instalar o programa, que fica alojado na <a href="http://support.apple.com/kb/HT2473?viewlocale=pt_BR" target="_blank">barra de menus</a>, basta arrastar &#8220;qualquer coisa&#8221; para cima dele ou usar a tecla de atalho (você pode definir a que quiser – eu estou usando <strong>CMD+SHIFT+2</strong>, já que isso se parece com os atalhos para tirar fotos da tela – para &#8220;qualquer coisa&#8221; ser enviada para os servidores deles.</p>
<p style="text-align: center;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="608" height="501" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="quality" value="high" /><param name="src" value="http://www.youtube.com/v/IfDyoeDYs2k" /><embed type="application/x-shockwave-flash" width="608" height="501" src="http://www.youtube.com/v/IfDyoeDYs2k" quality="high"></embed></object></p>
<p>Assim que o arquivo termina de subir, o endereço do tipo &#8220;http://cl.ly/xxx&#8221; é colocado no seu <em>clipboard</em>, bastando um <strong>CMD+V</strong> para colar o endereço. Além disso, ele te avisa, com som ou usando o <a href="http://growl.info/" target="_blank">Growl</a> que o <em>upload</em> terminou.</p>
<div id="attachment_1193" class="wp-caption aligncenter" style="width: 338px"><img class="size-full wp-image-1193" title="cloudapp-com-growl" src="http://www.bitabit.eng.br/wp-content/uploads/2010/04/cloudapp-com-growl.png" alt="Growl avisando que o arquivo foi enviado" width="328" height="104" /><p class="wp-caption-text">Growl avisando que o arquivo foi enviado</p></div>
<p style="text-align: left;">O programa ainda conta com <a href="http://www.getcloudapp.com/app/download" target="_blank">Raindrops</a>, <em>plugins</em> que permitem que o atalho de envio de arquivo funcione com diversos programas. Basta baixar, clicar duas vezes e sair usando!</p>
<div id="attachment_1196" class="wp-caption aligncenter" style="width: 343px"><img class="size-full wp-image-1196 " title="cloudapp-raindrops-instalados" src="http://www.bitabit.eng.br/wp-content/uploads/2010/04/cloudapp-raindrops-instalados.png" alt="Raindrops instalados" width="333" height="288" /><p class="wp-caption-text">Raindrops instalados</p></div>
<p>Para completar o pacote, como todo bom encurtador de URL, o <a href="http://www.getcloudapp.com/" target="_blank">CloudApp</a> te mostra quantas vezes cada link foi clicado, tanto pelo aplicativo na barra de menus, quanto pelo site.</p>
<p style="text-align: center;">
<div id="attachment_1197" class="wp-caption aligncenter" style="width: 536px"><img class="size-full wp-image-1197 " title="cloudapp-site-com-estatisticas-de-downloads" src="http://www.bitabit.eng.br/wp-content/uploads/2010/04/cloudapp-site-com-estatisticas-de-downloads.png" alt="Estatísticas de download" width="526" height="385" /><p class="wp-caption-text">Estatísticas de downloads no site</p></div>
<p style="text-align: left;">Quando se clica num link de arquivo que não pode ser aberto nativamente pelo browser (PDFs, DOCs, ZIPs e coisas do tipo), você é levado para uma tela com opção de download, já, quando é uma imagem ou uma URL, o programa abre o link diretamente no lugar.</p>
<div id="attachment_1195" class="wp-caption aligncenter" style="width: 294px"><img class="size-full wp-image-1195 " title="cloudapp-opacao-de-download" src="http://www.bitabit.eng.br/wp-content/uploads/2010/04/cloudapp-opacao-de-download.png" alt="Download de arquivo &quot;não nativo&quot; do browser " width="284" height="97" /><p class="wp-caption-text">Download de arquivo &quot;não nativo&quot; do browser </p></div>
<p>Resumindo… se você tem um Mac, baixe o <a href="http://www.getcloudapp.com/" target="_blank">CloudApp</a> agora, que é, até o momento, totalmente grátis.</p>
<p>Fonte: <a href="http://macmagazine.com.br/2010/04/08/cloudapp-armazene-arquivos-do-mac-na-nuvem-via-drag-drop/" target="_blank">MacMagazine</a> e <a href="http://lifehacker.com/5508611/cloudapp-instantly-shares-any-file-is-my-new-favorite-timesaver" target="_blank">Lifehacker</a></p>
<img src="http://www.bitabit.eng.br/?ak_action=api_record_view&id=1190&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.bitabit.eng.br/2010/04/15/cloudapp-uploader-encurtador-de-url-para-mac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Instalando o OpenCV 1.1 no Ubuntu 8.10, 9.04 e 9.10</title>
		<link>http://www.bitabit.eng.br/2010/02/17/instalando-o-opencv-1-1-no-ubuntu-8-10-9-04-e-9-10/</link>
		<comments>http://www.bitabit.eng.br/2010/02/17/instalando-o-opencv-1-1-no-ubuntu-8-10-9-04-e-9-10/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 15:06:31 +0000</pubDate>
		<dc:creator>Filipe M. S. de Campos, Coop10</dc:creator>
				<category><![CDATA[Coop10]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Outros]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Visão Computacional]]></category>
		<category><![CDATA[computer vision]]></category>
		<category><![CDATA[Ctypes OpenCV]]></category>
		<category><![CDATA[instalação]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[visão computacional]]></category>
		<category><![CDATA[wrapper]]></category>

		<guid isPermaLink="false">http://www.bitabit.eng.br/?p=966</guid>
		<description><![CDATA[Logo do OpenCV Neste post irei dividir com você as experiências que já tive com a instalação da bibliteca OpenCV no Ubuntu. Vou relatar o processo de instalação do OpenCV 1.1 nas versões 8.10, 9.04 e 9.10 do Ubuntu. Apesar do OpenCV ser tipicamente utilizado com C ou C++, também é possível utilizá-lo com Python (ou Octave) graças [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_976" class="wp-caption alignright" style="width: 190px"><br />
<img class="size-medium wp-image-976 " title="OpenCV logo" src="http://www.bitabit.eng.br/wp-content/uploads/2010/02/opencv_logo-300x277.gif" alt="Logo do OpenCV" width="180" height="166" /><p class="wp-caption-text">Logo do OpenCV</p></div>
<p>Neste <em>post</em> irei dividir com você as experiências que já tive com a instalação da bibliteca <a title="OpenCV Wiki" href="http://opencv.willowgarage.com/wiki/" target="_blank">OpenCV</a> no Ubuntu. Vou relatar o processo de instalação do <a title="OpenCV11 - Download" href="http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/1.1pre1/opencv-1.1pre1.tar.gz/download" target="_blank">OpenCV 1.1</a> nas versões 8.10, 9.04 e 9.10 do Ubuntu.</p>
<p>Apesar do OpenCV ser tipicamente utilizado com C ou C++, também é possível utilizá-lo com Python (ou Octave) graças aos wrappers criados por <a title="Ctypes OpenCV" href="http://code.google.com/p/ctypes-opencv/" target="_blank">terceiros</a> ou ao que já acompanha a versão 1.1 da biblioteca.  Neste texto, focarei a instalação para o uso de Python com o wrapper <a title="Ctypes OpnCV" href="http://code.google.com/p/ctypes-opencv/" target="_blank">Ctypes OpenCV</a>.  Por que o Ctypes OpenCV? Pois o que acompanha a biblioteca me &#8220;deixou na mão&#8221; durante o desenvolvimento do último projeto.</p>
<p><span style="color: #ffffff;">.<br />
</span></p>
<h2><span style="color: #ffffff;"><strong><span style="color: #000000;">Passo zero:</span></strong></span></h2>
<p>(vale para todos as três versões do Ubuntu)</p>
<ul>
<li>O OpenCV, funciona com Python, apenas para as versões 2.5.x ou 2.6.x da linguagem. A versão 3.x ainda não tem suporte oficial. Logo, verifique se você possui ele instalado em seu computador, caso contrário, instale o Python 2.6.4.</li>
<li>Mais umas coisinhas a serem instaladas. Digite no terminal (Aplicativos -&gt; Acessórios -&gt; Terminal) o comando abaixo. Sim, são várias coisas. Algumas são realmente requisitos para a instalação, outras servem apenas para diminuirmos chances de problemas depois. Instale, não dói nada <img src='http://www.bitabit.eng.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<pre class="brush: plain; light: true; title: ; notranslate"> sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev
libavformat-dev libavfilter-dev libswscale-dev libtiff-dev libjasper libgstreamer0.10-dev
libxine-dev libunicap-dev libdc1394-22-dev swig ffmpeg mplayer vlc </pre>
<ul>
<li> Baixe o <a title="OpenCV - Download" href="http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/1.1pre1/opencv-1.1pre1.tar.gz/download" target="_blank">OpenCV 1.1</a>, o <a title="Ctypes OpenCV - Download" href="http://ctypes-opencv.googlecode.com/files/ctypes-opencv-0.8.0-src.7z" target="_blank">Ctypes-OpenCV</a> e os <a title="Ctypes OpenCV - Exemplos" href="http://ctypes-opencv.googlecode.com/files/ctypes-opencv-0.8.0-demo.7z" target="_self">exemplos de códigos</a> do Ctypes OpenCV, você vai querer testar e consultar depois.</li>
</ul>
<p><span style="color: #ffffff;">.</span></p>
<h2>Ubuntu 8.10:</h2>
<p>Nesta versão do Ubuntu, a instalação é bem simples e funciona bem. <img src='http://www.bitabit.eng.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   Basta seguir os passos abaixo:</p>
<ul>
<li>Após o passo zero, no início desse <em>post</em>, descomprima o OpenCV e, pelo terminal,  entre na pasta criada. Se ela estiver em seu desktop, será algo próximo a:</li>
</ul>
<pre class="brush: plain; light: true; title: ; notranslate"> cd Desktop/opencv-1.1.0 </pre>
<ul>
<li>Agora, digite:</li>
</ul>
<pre class="brush: plain; light: true; title: ; notranslate"> ./configure --disable-sse2 --with-python --with-swig --with-ffmpeg </pre>
<p>Obs.: Para processadores antigos, como o AMD de uns quase dez anos atrás que usei no laboratório, era necessários desativar instruções do tipo <a title="Instruções SSE2" href="http://en.wikipedia.org/wiki/SSE2" target="_blank">SSE2</a>, caso contrário, ao rodar algum programa que usasse o OpenCV você obteria a mensagem: Illegal instruction. Eu não expliquei isso antes de você escrever o comando pois obtive problemas com os wrappers de python caso não desativasse esse tipo de instrução no Ubuntu 9.04 e 9.10, imagino que na versão 8.10 isso também ocorra apesar de não ter testado. Então, se você irá usar o OpenCV com C ou C++, não existe necessidade do &#8211;disable-sse2, caso contrário, é melhor desativar esse tipo de instrução.</p>
<ul>
<li>Agora preste atenção ao pequeno relatório que apareceu em seu terminal. Verifique, principalmente, se o python e o ffmpeg estão com &#8220;<em>yes</em>&#8220;. Seu relatório deve se parecer bastante como o da figura abaixo:</li>
</ul>
<div id="attachment_977" class="wp-caption aligncenter" style="width: 450px"><img class="size-full wp-image-977  " title="Relatório do configure" src="http://www.bitabit.eng.br/wp-content/uploads/2010/02/saida-do-configure-OK.png" alt="Relatório do configure com as opções corretamente marcadas." width="440" height="389" /><p class="wp-caption-text">Figura 1 - Relatório do configure com as opções corretamente marcadas.</p></div>
<p>Caso o Python ou o ffmpeg não tenham aparecido com o &#8220;<em>yes</em>&#8220;, tente as soluções mostradas nas outras versões do Ubuntu que estão abaixo.</p>
<ul>
<li>Agora, digite:</li>
</ul>
<pre class="brush: plain; light: true; title: ; notranslate"> make </pre>
<ul>
<li>Depois que terminar, digite:</li>
</ul>
<pre class="brush: plain; light: true; title: ; notranslate"> sudo make install </pre>
<h3>Será que funcionou? Vamos testar.</h3>
<p>O OpenCV acompanha alguns programas exemplo, tanto em C quanto em Python, para você testar a instalação e aprender a usar a biblioteca.  Siga os passos abaixo.</p>
<ul>
<li>Se sua pasta do OpenCV estiver no desktop, digite:</li>
</ul>
<pre class="brush: plain; light: true; title: ; notranslate"> cd Desktop/opencv-1.1.0/samples/c </pre>
<ul>
<li>Agora compile os exemplos com:</li>
</ul>
<pre class="brush: plain; light: true; title: ; notranslate"> . build_all.sh </pre>
<ul>
<li>Agora rode um dos programas:</li>
</ul>
<pre class="brush: plain; light: true; title: ; notranslate"> ./delaunay </pre>
<p>Se surgiu uma nova janela e &#8220;coisas coloridas&#8221; estão aparecendo nela, a biblioteca foi instalada com sucesso.</p>
<h3>Instalando o Ctypes OpenCV</h3>
<p>Será bem simples. Descomprima o arquivo que você ja baixou no passo zero para o desktop e, pelo terminal, entre na pasta <em>src</em>. Após isso, digite:</p>
<pre class="brush: plain; light: true; title: ; notranslate"> sudo python setup.py install </pre>
<p>Depois de instalado, veja os exemplos que você também baixou do Ctypes OpenCV no passo zero. Dê duplo clique em algum deles, por exemplo o delaunay.py. Ou então rode via terminal com o comando</p>
<pre class="brush: plain; light: true; title: ; notranslate"> python delaunay.py </pre>
<p><span style="color: #ffffff;">.</span></p>
<h2>Ubuntu 9.04:</h2>
<p>Nessa versão do Ubuntu as coisas já não são mais tão simples. Apesar do processo de instalação ser o mesmo da versão 8.10, surgem alguns problemas no meio do caminho.</p>
<p><strong>Primeiro problema</strong>:  O Python não é reconhecido ao rodar o <em>configure</em>.</p>
<p>Se você rodar o <em>configure</em>, verá que no relatório que ele exibe aparece &#8220;<em>no</em>&#8221; para o Python. Se você verficar melhor a saída completa verá:</p>
<div id="attachment_1010" class="wp-caption aligncenter" style="width: 745px"><img class="size-full wp-image-1010" title="Problema com o Python" src="http://www.bitabit.eng.br/wp-content/uploads/2010/02/problema-com-o-python.png" alt="Figura 2 - Problema com o Python" width="735" height="260" /><p class="wp-caption-text">Figura 2 - Problema com o Python</p></div>
<p><strong>Resolução</strong>:  Provavelmente deve existir uma solução melhor, mas esta funcionou para mim. Baixei o <em>source</em> do <a title="Python 2.6.4 - Download" href="http://www.python.org/ftp/python/2.6.4/Python-2.6.4.tgz" target="_blank">Python 2.6.4</a>, compilei e reinstalei via terminal, da seguinte forma:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
./configure
make
sudo make install
</pre>
<p>Obs.: Se seu computador não possuir suporta a instruções SSE2, utilize para o primeiro comando: ./configure &#8211;diable-sse2</p>
<p><span style="color: #ffffff;">.</span></p>
<p><strong>Segundo problema</strong>:  O ffmpeg não é reconhecido ao rodar o <em>configure</em>. Resultado, não é possível manipular vídeos com a biblioteca.</p>
<p>Se você rodar o <em>configure</em>, verá que é exibido &#8220;<em>no</em>&#8220; para o ffmpeg no relatório. Se você verficar melhor a saída completa verá:</p>
<div id="attachment_1011" class="wp-caption aligncenter" style="width: 401px"><img class="size-full wp-image-1011" title="Problema com o ffmpeg" src="http://www.bitabit.eng.br/wp-content/uploads/2010/02/problema-com-o-ffmpeg.png" alt="Figura 3 - Problema com o ffmpeg" width="391" height="88" /><p class="wp-caption-text">Figura 3 - Problema com o ffmpeg</p></div>
<p><strong>Resolução</strong>: Basta seguir os passos abaixo em seu terminal:</p>
<pre class="brush: plain; light: true; title: ; notranslate">
sudo mkdir /usr/include/ffmpeg
cd /usr/include/ffmpeg
sudo ln -s ../libavcodec/avcodec.h avcodec.h
sudo ln -s ../libavformat/avformat.h avformat.h
sudo ln -s ../libavformat/avio.h avio.h
sudo ln -s ../libavutil/avutil.h avutil.h
sudo ln -s ../libswscale/swscale.h swscale.h
</pre>
<p>Com os problemas resolvidos, e o passo zero realizado, siga o procedimento básico da instalação.</p>
<pre class="brush: plain; light: true; title: ; notranslate"> ./configure --disable-sse2 --with-python --with-swig --with-ffmpeg --enable-swscale --enable-shared </pre>
<p>Antes dos próximos comandos, não esqueça de verificar no relatório do <em>configure</em> se o python e o ffmpeg estão com &#8220;<em>yes</em>&#8220;. Seu relatório deve se parecer bastante como o da Figura 1 desse <em>post</em>.</p>
<pre class="brush: plain; light: true; title: ; notranslate">
make
sudo make install
</pre>
<p>Ao terminar, teste e instale o Ctypes OpenCV para programar com Python. Para isso, siga as instruções dos tópicos &#8220;<strong>Será que funcionou? Vamos testar.</strong>&#8221; e &#8220;<strong>Instalando o Ctypes Opencv</strong>&#8221; que estão na instalação para o Ubuntu 8.10, acima neste mesmo <em>post.</em></p>
<p><span style="color: #ffffff;">.</span></p>
<h2 style="font-size: 1.5em;">Ubuntu 9.10:</h2>
<p>Nessa versão, existe mais um problema além dos já existentes para o Ubuntu 9.04.</p>
<p><strong>Problema</strong>: Erro durante a compilação do código.</p>
<p><strong>Resolução</strong>: Entre na pasta que você descomprimiu o OpenCV1.1, vá em <em>cxcore</em>, <em>include</em> e abra o arquivo <em>cxmisc.h</em>. Na linha 133, troque o</p>
<pre class="brush: plain; light: true; title: ; notranslate">#elif</pre>
<p>por:</p>
<pre class="brush: plain; light: true; title: ; notranslate">#else</pre>
<p>Para completar a instalação, basta seguir o texto acima sobre a instalação no Ubuntu 9.04.</p>
<p><span style="color: #ffffff;">.</span></p>
<p><span style="color: #ffffff;">.</span></p>
<img src="http://www.bitabit.eng.br/?ak_action=api_record_view&id=966&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.bitabit.eng.br/2010/02/17/instalando-o-opencv-1-1-no-ubuntu-8-10-9-04-e-9-10/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Compilando o OpenOffice</title>
		<link>http://www.bitabit.eng.br/2010/02/06/compilando-o-openoffice/</link>
		<comments>http://www.bitabit.eng.br/2010/02/06/compilando-o-openoffice/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 21:10:26 +0000</pubDate>
		<dc:creator>Rodrigo Rodrigues da Silva, Coop08</dc:creator>
				<category><![CDATA[Coop8]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[compilação]]></category>
		<category><![CDATA[open office]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.bitabit.eng.br/?p=945</guid>
		<description><![CDATA[Compilar o OpenOffice a partir do código fonte da linha de desenvolvimento poderia tornar-se um pesadelo há algum tempo. Com o novo build system da linha 3.0 e a migração para o repositório mercurial durante o desenvolvimento da próxima versão (3.2), o processo ficou muito mais fácil. Passado o martírio, é só começar a se divertir com os quase 70 mil arquivos-fonte.]]></description>
			<content:encoded><![CDATA[<p>Compilar o OpenOffice a partir do código fonte da linha de desenvolvimento poderia tornar-se um pesadelo há algum tempo. Com o novo build system da linha 3.0 e a migração para o repositório mercurial durante o desenvolvimento da próxima versão (3.2), o processo ficou muito mais fácil. Passado o martírio, é só começar a se divertir com os quase 70 mil arquivos-fonte.</p>
<p>Hoje à noite, em um momento iluminado (depois de ler um e-mail do <a href="http://jucablues.blogspot.com/">Juca</a> entitulado “<a href="http://groups.google.com/group/polignu/browse_thread/thread/d139bf2d4835e903">algumas coisas demandam coragem</a>”, sugerindo o que se segue), pensei: bom, se eu já uso as versões de desenvolvimento do Firefox e do Thunderbird cotidianamente, por que não o OpenOffice? Afinal, qual a graça de usar um OpenOffice 3.1 estável?!</p>
<p>Há cerca de dois anos eu tentei completar esse rito de passagem: na época ainda usavam <em>CVS</em>. Um grande problema de <em>CVS</em> em tutoriais é que sempre colocam umas linhas de comando do tipo:</p>
<p><code>cvs -d :pserver:anoncvs@anoncvs.services.openoffice.org:/cvs checkout <em>"modulename"</em></code></p>
<p><a href="http://www.bitabit.eng.br/wp-content/uploads/2010/02/comp_ooffice1.png"><img class="alignright size-full wp-image-953" src="http://www.bitabit.eng.br/wp-content/uploads/2010/02/comp_ooffice1.png" alt="comp_ooffice" width="402" height="477" /></a>e nunca nos dizem o que colocar em <em>&#8220;modulename&#8221;</em>, o que acaba por custar ao benevolente hacker mais duas horas varrendo o repositório em busca do módulo correto. Além disso, era necessário baixar e compilar separadamente todo o<em> build system</em> do open office.</p>
<p>A boa notícia é que a cada <em>major version</em> o OpenOffice.org tem refeito o seu <em>build system</em>, para melhor. Além disso, descobri que nesses dois anos eles passaram o repositório de código pelo <em>svn</em> e  finalmente adotaram o <em>mercurial</em> em outubro de 2009.</p>
<p>Fazer um <em>checkout</em> de todo o repositório <em>mercurial</em> seria muito demorado, e por isso eles disponibilizam um <em>bundle</em> diário do repositório, isto é, um arquivo com todo o repositório empacotado.</p>
<p>Hora de se sujar: baixe o <em>bundle</em> , “<em>unbundle</em>” e “<em>update</em>”:</p>
<p><code>sudo apt-get install mercurial</code> (caso não tenha o <em>mercurial</em> instalado)<br />
<code>mkdir devel &amp;&amp; cd devel</code> (ou como vc quiser chamar o seu parque de diversões hacker, caso ainda não o tenha)<br />
<code>wget http://hg.services.openoffice.org/bundle/DEV300.hg<br />
mkdir openoffice<br />
cd openoffice<br />
hg init<br />
hg unbundle ../DEV300.hg<br />
hg pull http://hg.services.openoffice.org/DEV300<br />
hg update</code></p>
<p>Além do tempo de baixar o<em> bundle</em>, que tem quase 1GB, o resto do processo demora cerca de 30 minutos.</p>
<p>De agora em diante, você é livre para compilar como quiser, com os itens opcionais que quiser (ou não). Vou apenas reproduzir o que eu fiz para executar um <em>full build</em> padrão, já que os tutoriais oficiais nunca são suficientes. Tudo isso foi executado em um Ubuntu GNU/Linux 9.04 (jaunty) 64bits, e pode mudar ligeiramente de distribuição para distribuição. Caso você use uma distribuição que não seja derivada do Debian (isto é, sem <em>apt</em>), use o gerenciador de pacotes padrão da sua distribuição. Os pacotes devem ter nomes iguais ou parecidos.</p>
<p><strong>Dependências</strong></p>
<p>No tutorial disponível no wiki eles sugerem algumas dependências:</p>
<ul>
<li>glibc:<br />
for OOo&lt;=3.1: 2.2.x or higher  for OOo&gt;3.1: 2.3.2 or higher</li>
<li>C/C++ Compiler:<br />
gcc &gt;= 3.3<br />
gcc 4.2.3 is the current reference compiler</li>
<li>The X11 development libraries and header files</li>
<li>PAM including the development headers</li>
<li>bash</li>
<li>gtk2 and libtiff including the development headers</li>
</ul>
<p>Se você não estiver usando um Debian Sarge da vida, ignore e prossiga. Ah, caso você não tenha o <em>gcc</em> instalado, 1. você não devia estar aqui (<a href="http://instantbazinga.com">bazzinga!</a>) 2. já que está aqui, rode um <code>sudo apt-get install build-essential</code> e seus problemas acabaram.</p>
<p>Isso é uma mão na roda para instalar a maioria das (infinitas) dependências:</p>
<p><code>sudo apt-get build-dep openoffice.org</code></p>
<p>Como de praxe, há coisas novas em relação à versão estável que obviamente o <em>build-dep</em> não pegou:</p>
<p><code>sudo apt-get install mingw32 libgraphite3 libgraphite-dev</code></p>
<p>De volta ao seu diretório <code>openoffice</code>:</p>
<p><code>./configure --with-use-shell=bash --with-system-libs --without-system-jars --without-system-icu --without-system-agg --without-system-lpsolve --without-system-mspack --disable-mozilla --with-mingwin=/usr/bin/i586-mingw32msvc-g++</code></p>
<p>Isso diz aos scripts de compilação para utilizarem o maior número possível de libs do sistema e evitar incompatibilidades. O palavrão <code>/usr/bin/i586-mingw32msvc-g++</code> é para o <em>cross</em>-compilador mingw32, necessário para <em>cross</em>-compilar algo que não sei o que é. Ao final, veja se não ocorreram muitos <em>warnings</em> e se aparece a seguinte mensagem:</p>
<p><code>Configure completed<br />
You may now run ./bootstrap in <em>[pasta onde estão os sources]</em></code></p>
<p>Agora, com as variáveis de sistema configuradas, precisamos gerar os scripts de compilação (<em>Makefiles</em>):</p>
<p><code>./bootstrap<br />
source LinuxX86-64Env.Set.sh</code><br />
(ou <code>source LinuxX86Env.Set.sh</code> se seu processador for 32 bits)</p>
<p><strong>Agora, aos finalmentes</strong></p>
<p>Tendo configurado as variáveis de ambiente e gerado os <em>build scripts</em>, vamos à compilação:<br />
<code>time make</code></p>
<p># vá tomar um chá que vai demorar (eu fui!). O <em>time</em> antes do <em>make</em> vai marcar o tempo gasto na compilação.</p>
<p><strong>Depois do chá</strong></p>
<p>Se tudo correr bem, depois do seu chá e mais algumas horas você chegará em algo assim:</p>
<p><code>***********************************************************<br />
Successful packaging process!<br />
***********************************************************<br />
... creating log file log_DEV300_en-US.log<br />
Fri Feb  5 12:30:15 2010 (00:07 min.)<br />
real    357m1.283s<br />
user    274m55.902s<br />
sys    42m31.595s<br />
rodrigo@snowball2:~/devel/openoffice$</code></p>
<p><strong>Sim, foram 6 horas mesmo.</strong> Isso num Intel Core2 Duo T7250 2.00GHz com 4M de cache, mas utilizando apenas um núcleo. Coloque aí nos comentários os seus resultados para compararmos.</p>
<p>Caso você tenha um processador com dois ou mais núcleos, é possível fazer um <em>build</em> paralelo, que teoricamente iria mais rápido. Eu estava fazendo outras coisas no computador, então me contentei com um único <em>core</em> compilando o bichinho. No link ao final da página há instruções sobre como fazer isso, entre outros hacks.</p>
<p>Como executamos um full build, o processo gerou pacotes prontos para instalação. Os pacotes para GNU/Linux 64bit ficam em <code>~/devel/openoffice/instsetoo_native/unxlngx6.pro/OpenOffice/deb/install/</code> (para 32bits é unxlngi6.pro ou algo que o valha). Na pasta <code>en-US_download</code> há um <code>tar.gz</code> que pode ser distribuído. A pasta <code>en-US</code> possui o mesmo conteúdo, porém não compactado.</p>
<p><strong>Instalação</strong></p>
<p>Como executamos um <em>build</em> padrão, o <code>configure</code> gerou os pacotes nativos da distribuição: <em>.deb</em>. Caso você queira instalar o OO que compilou (óbvio que quer!) será necessário remover o OpenOffice que vem com a distribuição (se souber como gerar o build desempacotado e evitar isso, por favor faça um comentário).</p>
<p><code><strong>sudo apt-get remove openoffice.org-common</strong></code><br />
(Caso você não remova o open office atual, pode haver conflito de pacotes. <strong>Remova!</strong>)</p>
<p><code>cd ~/devel/openoffice/instsetoo_native/unxlngx6.pro/OpenOffice/deb/install/en-US/DEBS</code><br />
<code>sudo dpkg -i *.deb</code> <em>(pacotes do OO.org)</em><br />
<code>cd destop-integration</code><br />
<code>sudo dpkg -i *.deb</code><em> (ícones no menu do KDE/GNOME)</em></p>
<p>Lembre-se de autalizar o código (<code>hg pull &amp;&amp; hg update</code>) e recompilar (<code>make</code>) de tempos em tempos. A linha de desenvolvimento está em constante&#8230; desenvolvimento (!), e se sua intenção vai além de fazer uma graça é importante estar com o código em dia. Vale lembrar que, a princípio, os <em>rebuilds</em> devem demorar muito menos, pois apenas os arquivos modificados (e os dependentes deles) são recompilados. Veja o link abaixo para maiores informações.</p>
<p>Agora, se suas intenções são realmente corajosas e vão além de testar e reportar bugs, entre na lista de e-mails <a href="http://www.openoffice.org/servlets/SummarizeList?listName=dev">dev@openoffice.org</a>, dê uma olhada no <a href="http://qa.openoffice.org/issues/">bugtracker</a> e na página de <a href="http://wiki.services.openoffice.org/wiki/To-Dos">TODO&#8217;s</a>. O <a href="http://wiki.services.openoffice.org/wiki/Development">wiki</a> também é um ótimo ponto de partida.</p>
<p><em><strong>happy hacking!</strong></em></p>
<p>Referência:<br />
<a href="http://wiki.services.openoffice.org/wiki/Documentation/Building_Guide/Building_on_Linux">http://wiki.services.openoffice.org/wiki/Documentation/Building_Guide/Building_on_Linux</a></p>
<p><code>© 2010 Rodrigo Rodrigues da Silva. Este texto pode ser compartilhado sob os termos da licença <a href="//creativecommons.org/licenses/by-sa/2.5/”">Creative Commons By-Sa </a></code></p>
<img src="http://www.bitabit.eng.br/?ak_action=api_record_view&id=945&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.bitabit.eng.br/2010/02/06/compilando-o-openoffice/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Interrupção do x86, Minix e, de quebra, uma pitada de estouro de pilha</title>
		<link>http://www.bitabit.eng.br/2009/11/11/interrupcao-do-x86-minix-e-de-quebra-uma-pitada-de-estouro-de-pilha/</link>
		<comments>http://www.bitabit.eng.br/2009/11/11/interrupcao-do-x86-minix-e-de-quebra-uma-pitada-de-estouro-de-pilha/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 09:58:23 +0000</pubDate>
		<dc:creator>Eduardo Russo, Coop10</dc:creator>
				<category><![CDATA[Acadêmico]]></category>
		<category><![CDATA[Computação]]></category>
		<category><![CDATA[Coop10]]></category>
		<category><![CDATA[Sistemas Operacionais]]></category>
		<category><![CDATA[Tecnologia]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Bochs]]></category>
		<category><![CDATA[estouro de pilha]]></category>
		<category><![CDATA[exceções]]></category>
		<category><![CDATA[idt]]></category>
		<category><![CDATA[interrupção de hardware]]></category>
		<category><![CDATA[Minix]]></category>
		<category><![CDATA[prezi]]></category>
		<category><![CDATA[stack overflow]]></category>
		<category><![CDATA[tabela de interrupção]]></category>
		<category><![CDATA[x86]]></category>

		<guid isPermaLink="false">http://www.bitabit.eng.br/?p=430</guid>
		<description><![CDATA[Um dos trabalhos que tivemos (eu, o João Misko e o Rafael Medeiros) que fazer para a disciplina de Sistemas Operacionais foi sobre estouro de pilhas no Minix. Como e onde ocorria, e como era tratado. O grande salto quântico disso, era entender a tabela de interrupções do x86. Onde fica, para onde aponta e [...]]]></description>
			<content:encoded><![CDATA[<p>Um dos trabalhos que tivemos (eu, o João Misko e o Rafael Medeiros) que fazer para a <a href="http://www.pcs.usp.br/~jkinoshi/2009/so-09.txt" target="_blank">disciplina de Sistemas Operacionais</a> foi sobre estouro de pilhas no Minix. Como e onde ocorria, e como era tratado.</p>
<p>O grande salto quântico disso, era entender a tabela de interrupções do x86. Onde fica, para onde aponta e o que faz. Salto dado graças à imensa ajuda do <strong>Mestre Jorge Sabaliauskas</strong>! Se você não conhece o Jorjão, sinto muito!</p>
<h1>Tabela de interrupção</h1>
<p>Todo processador moderno possui uma tabela de interrupção (chamada de IDT &#8211; <em>Interrupt Description Table</em> &#8211; a partir daqui), que tem a função principal de executar uma determinada rotina (definida pelo SO) quando ocorre uma interrupção de hardware.</p>
<p>No x86, a tabela de interrupções é descrita conforme a tabela abaixo:</p>
<div id="attachment_769" class="wp-caption aligncenter" style="width: 547px"><img class="size-full wp-image-769" title="exception-and-interrupts" src="http://www.bitabit.eng.br/wp-content/uploads/2009/11/exception-and-interrupts.png" alt="Tabela de exceções e interrupções retirada do manual &quot;IA32-System-Programming-3A.pdf&quot;, Vol 3 5-3, para ser mais exato" width="537" height="659" /><p class="wp-caption-text">Tabela de exceções e interrupções retirada do manual &quot;IA32-System-Programming-3A.pdf&quot;, Vol 3 5-3, para ser mais exato</p></div>
<p>Para entender um pouco melhor o que isso faz, usaremos o exemplo clássico da divisão por zero (não, não pode dividir por zero).</p>
<p>Sempre que algum programador tosco (como eu) solicitar uma divisão por zero (não pode mesmo!), o processador dá um berro e passa aponta o PC (<em>Program Counter</em> &#8211; o cara que aponta para o próximo trecho da memória a ser executado) para o endereço armazenado na posição zero da IDT.</p>
<p>A partir daí, o SO passa a tratar isso, inserindo o código de como quer tratar esse erro na posição apontada pela IDT.</p>
<h1><a href="http://pt.lostpedia.wikia.com/wiki/Live_Together,_Die_Alone" target="_blank">Use Bochs, die alone</a></h1>
<p>Antes de tudo, para conseguir encontrar o código apontado pela tabela de interrupção, você precisa usar o <a href="http://bochs.sourceforge.net/" target="_blank">Bochs</a> e com a versão de <em>debug</em>. Por que? Porque ele é um <a href="http://pt.wikipedia.org/wiki/Emulador" target="_blank">emulador</a> e não um <a href="http://pt.wikipedia.org/wiki/M%C3%A1quina_virtual" target="_blank">virtualizador</a>. Dessa forma, você consegue ver as chamadas feitas ao hardware e manipular coisas que você não conseguiria manipular num virtualizador ou num computador real.</p>
<p>Direto da Wikipedia: &#8220;Num emulador, todos os recursos do sistema são processados nele (SIC) ao contrário da virtualização (SIC) que é uma ponte entre o hardware nativo e as chamadas do sistema operacional.&#8221;</p>
<p>Recomendo o Bochs de Windows, já que ele já vem compilado em sua última versão. Testei tanto pra OS X através do <a href="http://bochs.darwinports.com/" target="_blank">DarwinPorts</a>, como pro Linux, mas a versão de Windows foi a que rodou mais tranquila. No Mac, o programa rodava extremamente lento, no Linux, tive diversos problemas durante a compilação para conseguir ativar o <em>debuger</em>. No Windows, foi só clicar duas vezes.</p>
<h1>Achando a IDT e vendo a interrupção</h1>
<p>Até então, vimos a parte teórica, relativamente fácil de entender&#8230; Conseguir achar isso na prática requer um pouco mais de paciência e ajuda do Jorjão (ou de um blog como esse, se você não conhece o Jorjão).</p>
<p>Para proteger o código apontado pela IDT, o x86 usa algumas artimanhas. Em vez de simplesmente apontar para o endereço da memória, ele utiliza uma base e um <em>offset.</em></p>
<p>Para explicar melhor isso, vou usar o exemplo do trabalho sobre estouro de pilhas que fiz, e mostrar na prática o endereço usado pelo x86. Você pode ver na tabela acima que <em>Stack-Segment Fault</em> encontra-se na <strong>12ª posição</strong> da IDT. Então pare a execução do Bochs (com CONTROL+C) e digite o seguinte na janela do do emulador (não na do sistema em andamento):</p>
<pre class="brush: plain; light: true; title: ; notranslate">info idt 0xc</pre>
<div id="attachment_771" class="wp-caption aligncenter" style="width: 679px"><img class="size-full wp-image-771" title="info-idt-0xc" src="http://www.bitabit.eng.br/wp-content/uploads/2009/11/info-idt-0xc.png" alt="Saída do Bochs após o pedido de informação do IDT" width="669" height="338" /><p class="wp-caption-text">Saída do Bochs após o pedido de informação do IDT</p></div>
<p>Da resposta &#8220;<strong>Interrupt Gate target = 0&#215;30:0x4b4</strong>&#8221; tiraremos duas informações que nos levarão ao endereço real apontado pela IDT.</p>
<p>O &#8220;<strong>0&#215;30</strong>&#8221; é o <strong>16 bit segment selector</strong> e o &#8220;<strong>0x4b4</strong>&#8221; o <strong>offset</strong>.</p>
<p>O <strong>segmente selector</strong> é dividido conforme a figura abaixo:</p>
<p style="text-align: center;">
<div id="attachment_772" class="wp-caption aligncenter" style="width: 445px"><img class="size-full wp-image-772  " title="segment-selector" src="http://www.bitabit.eng.br/wp-content/uploads/2009/11/segment-selector.png" alt="Divisão do segment selector" width="435" height="322" /><p class="wp-caption-text">Divisão do segment selector</p></div>
<p>Portanto, a informação que procuramos está no GDT, na posição 6 (se você não entende como 12 virou c e 110 virou 6, estude um pouco sobre bases <a href="http://pt.wikipedia.org/wiki/Sistema_hexadecimal" target="_blank">hexadecimal</a> e <a href="http://pt.wikipedia.org/wiki/Sistema_binário_(matemática)" target="_blank">binária</a>)</p>
<p>Passe agora o seguinte comando para o Bochs:</p>
<pre class="brush: plain; light: true; title: ; notranslate">info gdt 0x6</pre>
<div id="attachment_770" class="wp-caption aligncenter" style="width: 679px"><img class="size-full wp-image-770" title="info-gdt-0x6" src="http://www.bitabit.eng.br/wp-content/uploads/2009/11/info-gdt-0x6.png" alt="Saída do Bochs após o pedido de informação do GDT (Global Description Table)" width="669" height="338" /><p class="wp-caption-text">Saída do Bochs após o pedido de informação do GDT (Global Description Table)</p></div>
<p>O valor &#8220;<strong>0&#215;1000</strong>&#8221; é o <strong>linear address</strong>, que usaremos junto ao <strong>offset</strong> para encontrar o endereço real de onde fica a rotina de interrupção.</p>
<p>Se você tiver um interesse masoquista por conhecimento, pode entender todas essas siglas e posições lendo os manuais da Intel que <a href="http://www.intel.com/products/processor/manuals/" target="_blank">encontram-se aqui</a>. É nele que toda essa loucura de proteção do endereço real é explicada.</p>
<p>Finalmente, com <strong>linear addres</strong> + <strong>offset</strong>, temos o endereço real, que é <strong>0x14b4</strong>.</p>
<p>Para confirmar isso, digite o seguinte na janela de emulação do Bochs:</p>
<pre class="brush: plain; light: true; title: ; notranslate">u 0x14b4</pre>
<div id="attachment_773" class="wp-caption aligncenter" style="width: 679px"><img class="size-full wp-image-773" title="u-0x14b4" src="http://www.bitabit.eng.br/wp-content/uploads/2009/11/u-0x14b4.png" alt="Saída do Bochs após o pedido de informação do endereço 0x14b4" width="669" height="338" /><p class="wp-caption-text">Saída do Bochs após o pedido de informação do endereço 0x14b4</p></div>
<p>A resposta é que na posição &#8220;<strong>0x14b4</strong>&#8220;, encontra-se <strong>&#8220;push 0x0c&#8221;</strong> em <em>assembly</em>. Para confirmar que esse é o início da rotina de interrupção de estouro de pilha do Minix, temos que olhar para dois arquivos:</p>
<p><strong>kernel/mpx386.s</strong> e <strong>kernel/protect.h</strong></p>
<p>No primeiro, na linha 457, vemos o seguinte comando em assembly: <strong>push STACK_FAULT_VECTOR</strong> e no segundo, na linha 58, <strong>#define STACK_FAULT_VECTOR  12<strong> </strong><strong> </strong></strong>.</p>
<p>Juntando tudo, verificamos que estamos exatamente na posição de início do código que o Minix executará caso uma interrupção de estouro de pilha ocorra.</p>
<p>Se você quiser brincar um pouco e ver uma interrupção ocorrendo, pode inserir uma pausa no Bochs usando:</p>
<pre class="brush: plain; light: true; title: ; notranslate">b 0x14b4</pre>
<p>Com isso, caso PC aponte para 0x14b4, o emulador será pausado.</p>
<p>Agora faça um programa eternamente recursivo como o abaixo para ver a interrupção ocorrendo:</p>
<pre class="brush: cpp; title: ; notranslate">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
void meChama(int i){
	printf(&quot;iteracao %d\n&quot;, i++);
	meChama(i);
}

int main (int argc, const char * argv[]) {
	printf(&quot;iteracao 1\n&quot;);
	meChama(1);
	return 0;
}</pre>
<p><a href="http://coop10.wordpress.com/2009/05/12/como-compilar-programa-em-c-no-minix/" target="_blank">Salve, compile, execute</a> e veja a mágica.</p>
<div id="attachment_768" class="wp-caption aligncenter" style="width: 679px"><img class="size-full wp-image-768" title="breakpoint-em-acao" src="http://www.bitabit.eng.br/wp-content/uploads/2009/11/breakpoint-em-acao.png" alt="Breackpoint em 0x14b4 mostrando sua mágica" width="669" height="338" /><p class="wp-caption-text">Breackpoint em 0x14b4 mostrando sua mágica</p></div>
<p>A imagem acima mostra o exato momento em que o código que trata a interrupção de estouro de pilha começa a ser executado. Isso ocorre no momento em que o programa recursivo começaria a destruir toda sua memória e o processador (no caso, o emulador do processador) grita &#8220;PARA TUDO!!!&#8221; pro Minix e este passa a lidar com a bucha!</p>
<p>Tudo isso pode ser visto também <a href="http://prezi.com/qynywmzf-ag5/view" target="_blank">nessa apresentação</a> do <a href="http://prezi.com" target="_blank">Prezi</a> que fizemos sobre estouro de pilha, mas que dependeu do entendimento da IDT e de todo o caminho tortuoso para achar o endereço real apontado por ela.</p>
<img src="http://www.bitabit.eng.br/?ak_action=api_record_view&id=430&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.bitabit.eng.br/2009/11/11/interrupcao-do-x86-minix-e-de-quebra-uma-pitada-de-estouro-de-pilha/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

