RNR

de Finibus Bonorum et Malorum


Reclamações recentes

Compilando LaTeX com latexmk

Este post é a parte 5 de 5 da série Workflow com LaTeX

Introdução

Nos posts anteriores, discutimos um pouco sobre LaTeX, falamos sobre escolha de editores, fizemos uma configuração inicial para o Emacs, e montamos um ambiente para escrita em LaTeX. Discutimos e montamos toda a lógica do ambiente dentro do Emacs, com AUCTeX, RefTeX, company, e todas as ferramentas que ele oferece.

Agora, no entanto, ainda nos falta otimizar o processo de compilação. Como vimos antes, vamos usar o LatexMk para fazer isso – é é justamente o tema deste post. Vamos criar a configuração no arquivo .latexmkrc, onde criamos a lógica que ele vai usar para criar o arquivo PDF que é resultado de todo o código que escrevemos no ambiente do Emacs.

O problema: compilar LaTeX manualmente

Compilar um arquivo LaTeX não é uma tarefa trivial: existem várias ferramentas que precisam ser usadas na ordem certa, para garantir que todos os elementos do texto saiam corretos. Isso acontece porque, para gerar itens como índices, referências e citações, é preciso passar mais de uma vez pelo texto para encontrar tudo que é necessário.

Normalmente, isso pode ser feito diretamente na linha de comando. No nosso caso, como usamos XeLaTeX, faríamos algo do tipo:

xelatex arquivo.tex
biber arquivo
xelatex arquivo.tex
xelatex arquivo.tex

Muitas vezes, no entanto, isso precisa ser repetido em ordens diversas – e mais vezes. Isso fica repetitivo e propenso a erro, além de demandar que fiquemos de olho no processo de compilação para ver qual deverá ser o próximo passo.

Automatizando o processo: LatexMk

A ideia por trás do LatexMk é automatizar esse processo, através de um processo de decisão que decide sozinho qual o próximo comando a rodar, quantas vezes ele é necessário e em qual ordem fazer isso. Ele rastreia a saída dos comandos de compilação e detecta padrões que indicam a necessidade de algum outro comando, ou que o documento está pronto. Então basta rodar o comando único:

latexmk arquivo.tex

E ele cuida do resto, inclusive rodar o LaTeX quantas vezes forem necessárias, montar a bibliografia, detectar mudanças e gerar o PDF no final. Isso não somente elimina a necessidade de ficar olhando toda a saída no terminal, mas também deixa o processo independente – se quiser, é possível fazer a compilação na linha de comando, fora do Emacs.

O arquivo de configuração: .latexmkrc

O arquivo de configuração do LatexMk é escrito em Perl, e descreve as regras que devem ser seguidas para a compilação. Começamos carregando algumas bibliotecas e definindo variáveis:

use strict;
use warnings;
use File::Path qw(make_path);

my $texfile = $ARGV[0] // '';
my $engine  = 'xelatex';
my $minted  = 0;

Definimos o nome do arquivo principal sendo compilado ($texfile), o engine padrão (xelatex) e uma flag para indicar se o pacote minted foi usado.

O minted é um pacote diferenciado: ele é usado para incluir listagens de programas em documentos LaTeX. Para fazer a colorização do código, ele usa o Pygments, um pacote Python. Esse pacote recebe o texto, faz um parse e coloriza, e devolve para o LaTeX. Mas, como esse é um processo externo à compilação do LaTeX, ele precisa de uma abordagem adaptada, através da flag -shell-escape, que indica ao compilador que esse documento pode executar programas externos.

Mas, por causa disso, ativar sempre essa opção pode ser perigoso: ela dá margem à execução de código malicioso, especialmente se estivermos copiando código de algum lugar sem prestar muita atenção – e às vezes isso pode acontecer, se o código for muito extenso por exemplo.

O próximo passo é a leitura do arquivo .tex:

if (-f $texfile) {
    open my $fh, '<', $texfile
      or die "Não foi possível abrir $texfile: $!";

    while (<$fh>) {
        if (/\\usepackage(?:\[[^\]]*\])?\{minted\}/) {
            $minted = 1;
        }

        if (/^\s*%\s*!TEX\s+TS-program\s*=\s*(\w+)/i) {
            $engine = lc $1;
        }
    }

    close $fh;
}

Depois da checagem de erro básica, vamos ler o arquivo e checar duas coisas:

  • Minted: se o pacote minted estiver sendo usado, levantamos a flag;
  • Engine: se o comentário mágico !TEX TS-program estiver no arquivo, seguimos a orientação dele e usamos o engine indicado.

Dessa forma, é possível controlar certos parâmetros da compilação diretamente de dentro do arquivo .tex. Isso facilita no caso de necessidade, já que o sistema de compilação se adapta a isso. Se um projeto precisa de outro engine – lualatex, por exemplo – não vamos precisar fazer nenhuma adaptação na hora de compilar.

Essa abordagem é extensível, inclusive: podemos até mesmo criar nossos próprios comentários mágicos e influenciar o funcionamento do processo de compilação da forma que acharmos conveniente, desde que isso seja possível dentro das limitações do latexmk, claro.

Organização de diretórios

Nesta configuração, o diretório aux/ vai receber os arquivos auxiliares da compilação:

  • .aux
  • .log
  • .bbl
  • .bcf
  • etc
$aux_dir = 'aux';
make_path($aux_dir) unless -d $aux_dir;

$out_dir = '.';

Isso evita sobrecarregar o diretório principal do projeto com um monte de arquivos e deixa tudo mais limpo e fácil de encontrar. Além disso, em caso de necessidade, é só apagar o diretório aux/, em vez de correr o risco de apagar o arquivo errado. No diretório principal ficam o fonte, a bibliografia, o PDF e o arquivo-guia do SyncTeX.

Escolha do engine

A partir da variável $engine, esse condicional define qual vai ser o compilador a ser usado. É meio redundante fazer as coisas desse jeito, afinal poderíamos só usar a variável diretamente; mas meu cérebro ligeiramente paranoico prefere deixar opções abertas para o caso de eventualmente, num futuro distante, termos uma necessidade estranha.

my $compiler;
if ($engine eq 'lualatex') {
    $compiler = 'lualatex';
}
elsif ($engine eq 'pdflatex') {
    $compiler = 'pdflatex';
}
else {
    $compiler = 'xelatex';
}

Definição do comando

Não é muito intuitivo, mas a variável que o latexmk usa se chama $pdflatex – não confundir com o engine de mesmo nome. Aqui, temos algumas opções importantes:

$pdflatex = "$compiler -interaction=nonstopmode -file-line-error -synctex=1 %O %S";
  • -interaction=nonstopmode: não pára em erros, o que pode causar problemas em um ambiente integrado como o nosso. Essa opção gera um relatório que diz o que deu errado, e portanto é mais útil que um processo que pára de responder.
  • -file-line-error: essa opção instrui o LaTeX a nos dizer em qual linha está o ponto onde o erro aconteceu. Na hora de encontrar a falha no código, essa informação salva vidas. Sem saber onde está o problema teríamos que varrer o arquivo todo até achar o problema.
  • -synctex=1: ativa o SyncTeX, gerando um arquivo auxiliar (*.synctez.gz) que mapeia posições correspondentes no fonte e no PDF.

Ativação de shell-escape para o minted

Se o pacote minted foi detectado no preâmbulo, precisamos adicionar mais uma opção ao comando de compilação:

if ($minted) {
    $pdflatex =~ s/^(\S+)/$1 -shell-escape/;
    print "Detectado uso de minted — ativando -shell-escape.\n";
}

Isso ativa o -shell-escape apenas quando necessário, de acordo com a flag que levantamos ao ler o arquivo.

Bibliografia: BibLaTeX + Biber

A justificativa do uso do BibLaTeX com Biber é parecida com a do uso do XeLaTeX: são sistemas mais modernos e que têm melhor suporte de forma geral. O BibTeX depende de estilos de formatação que são muito complexos e trabalhosos de configurar, tem pouca flexibilidade e dificuldade com Unicode. O BibLaTeX resolve isso trazendo as opções de formatação para dentro do fonte, tendo melhor integração com pacotes modernos, suportando Unicode e sendo mais flexível nas formas de citação que podemos usar no texto.

$bibtex_use = 2;
$biber = "biber %O %B";

O Biber, por sua vez, é responsável por ler o arquivo .bib, que contém os dados bibliográficos, processar os dados (nomes, datas, títulos, etc) e gerar um arquivo .bbl, no formato esperado pelo biblatex.

Conclusão

Usando o LatexMk e com uma configuração planejada, o fluxo da composição de um documento se torna natural e automático. Mais importante, ele sai de cena e trabalha nos bastidores, enquanto nosso foco fica mantido no que interessa – o conteúdo do documento.

A compilação se torna um passo natural, e podemos acompanhar a evolução do documento final diretamente no mesmo ambiente onde trabalhamos o código, visualizando o PDF e podendo encontrar rapidamente as correspondências entre fonte e PDF.

Agora, nosso workflow está funcional e completo. Nos resta, agora, revisar o processo e entender como fazer uso de tudo isso. No próximo post, vamos ver quais os atalhos de teclado e opções podemos usar enquanto escrevemos um documento. Depois, vamos além, falando de alguns tópicos mais avançados, como controle de versão, uso de templates, organização de projetos e outras ferramentas.

Workflow com LaTeX

Ensinando LaTeX para o Emacs

Comentários

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *