Crafting Interpreters: o livro de 640 páginas concluído em 15 meses
(journal.stuffwithstuff.com)- Mesmo depois do fim da série publicada na web, Crafting Interpreters ainda exigiu 15 meses adicionais de trabalho até virar um livro de verdade, concluído por fim em edições impressa, digital e PDF
- Para transformar um conjunto de arquivos Markdown e PNG em um livro, foi preciso criar do zero um sistema de build em Dart, importação de XML no InDesign, automação em JavaScript e validação de composição
- O resultado final tem formato de 8×10 polegadas, 640 páginas, mais de 200 mil palavras, 1.133 trechos de código e centenas de ilustrações, com restrições de layout muito mais exigentes do que conteúdo comum para web
- Em seguida vieram 5 meses de revisão completa, copyediting profissional, 2 meses de diagramação, 2 semanas de trabalho no índice, além da conferência das provas e da automação para comparar PDFs
- Em um livro técnico autopublicado, não basta apenas escrever: automação de build, layout, validação e distribuição determina a qualidade e o nível de acabamento da obra
Trabalho que ainda restava depois de concluir o conteúdo para a web
- O texto principal de Crafting Interpreters já estava concluído, mas o resultado naquele momento era um conjunto de arquivos Markdown e PNG convertidos por código Python em um site
- O objetivo desde o início era um livro físico de verdade, e depois de publicar o último capítulo na web houve cerca de um mês de descanso
- Depois de quase 4 anos escrevendo todos os dias, o autor estava bastante esgotado, e o começo de 2020 também não foi um período fácil para continuar o trabalho
Sistema de build refeito em Dart
- Primeiro, foram corrigidos erros de digitação e outros problemas relatados por leitores em issues no GitHub
- Depois disso, todo o sistema de build do livro foi reescrito em Dart
- No primeiro livro, o script de build era um único script em Python que renderizava arquivos Markdown de cada capítulo em HTML e inseria trechos de código
- Em Crafting Interpreters, era preciso montar progressivamente, ao longo de 30 capítulos, dois interpretadores completos, então foi necessário um build mais complexo
- O novo sistema de build passou a gerar por programa o código do interpretador até um capítulo específico ou até um ponto específico dentro dele, permitindo compilação e testes automáticos
- As ferramentas baseadas em Python traziam um custo alto de manutenção para o nível de familiaridade do autor e também eram mais lentas
- A versão em Dart gerava exatamente o HTML e o código de syntax highlighting desejados, além de ser 10 vezes mais rápida que a versão anterior em Python
- O maior controle sobre o processamento de Markdown também foi útil depois na exportação de XML para o InDesign
Design do livro e definição do formato
- O design do livro era mais parecido com desenvolvimento web ou de jogos: primeiro se cria um framework, e depois se despeja o conteúdo dentro dele
- No InDesign, definem-se os masters, que estabelecem margens e grade da página, e os styles, que definem fontes, estilos e cores de texto e objetos
- Crafting Interpreters tinha muitos elementos de alta complexidade de design
- Muito texto corrido
- Muitos asides longos explicando logo ao lado frases, código e ilustrações específicas
- Muito código, com uma indicação ao lado de cada trecho mostrando sua posição no programa final
- A largura horizontal precisava considerar ao mesmo tempo linhas longas de código, a área dos asides e a margem interna de um livro grosso
- Livros típicos de ciência da computação na estante do autor muitas vezes tinham 7,5 polegadas de largura, mas esse tamanho dificultava acomodar código, asides e margens, então foi escolhida a largura de 8 polegadas
- Na autopublicação, era preciso usar os formatos limitados aceitos por KDP e IngramSpark, e para 8 polegadas de largura a escolha mais razoável era 8×10 polegadas
- Na direção vertical, o texto foi alinhado a uma baseline grid clássica de 12pt
Pipeline de XML para levar o conteúdo ao InDesign
- O InDesign não entendia diretamente Markdown nem o sistema de build do autor, então copiar e colar manualmente não era viável
- O InDesign oferece suporte a importação de XML e aplicação automática de estilos por tag
- Mas o suporte a XML tinha limitações no tratamento de tags aninhadas, então não conseguia lidar bem, por exemplo, com uma tag em itálico aninhada dentro de um cabeçalho como em HTML
- Como controlava diretamente o sistema de build, o autor escreveu um exportador XML personalizado que gerava tags mais fáceis de o InDesign aceitar
Automação em JavaScript no InDesign e seus limites
- A importação de XML criava no InDesign uma “story”, ou seja, um fluxo contínuo único de texto seguindo a caixa principal de texto
- O corpo do texto e os trechos de código entravam no fluxo principal, mas os asides e os location markers precisavam ser deslocados para o lado
- No livro anterior, os asides foram recortados manualmente e colados em novas caixas de texto, mas neste livro havia 1.133 trechos de código, tornando isso inviável
- O InDesign oferece suporte a scripts em JavaScript, mas a documentação e o ambiente de depuração eram muito ruins
- Sem depurador
- Sem stack trace
- Sem debug print convencional
- Só era possível usar
alert(), e cada chamada interrompia o script
- O script em JavaScript localizava os asides e os location markers, removia-os do fluxo principal e criava caixas de texto separadas
- A automação de posicionamento não foi concluída até o fim
- Tentou-se usar o recurso de anchor do InDesign e Object Style para posicionar esses elementos, mas em alguns casos as bordas dos trechos de código ao redor desapareciam
- No fim, foi preciso posicionar manualmente algumas location tags
Edição e copyediting
- Foi feito um passe de edição relendo todo o texto do começo ao fim
- Cada capítulo já havia passado por três drafts durante a escrita, mas foi necessária mais uma revisão para observar o fluxo do livro como um todo
- Esse trabalho levou 5 meses, e a maior parte das piadas repetidas foi ajustada
- Depois disso, foi contratada a copyeditor profissional Kari Somerton
- O fluxo de edição mais comum costuma envolver Microsoft Word e Track Changes, mas o autor queria manter um processo baseado em plaintext e Git
- Kari Somerton aprendeu Git e o sistema de build personalizado, depois revisou o livro inteiro e encontrou centenas de erros
- Mesmo depois de quatro drafts e de centenas de issues enviadas por leitores, a copyeditor profissional ainda encontrou muitos problemas
As restrições da diagramação de 640 páginas
- Depois de lapidar suficientemente as palavras, a diagramação de cada capítulo foi feita no InDesign
- O processo por capítulo repetia o seguinte fluxo
- Criar um novo arquivo do InDesign
- Exportar XML
- Importar o XML para o InDesign
- Usar JavaScript para separar asides e location markers
- Definir anchors para elementos de barra lateral
- Ajustar os espaços em branco no fim das páginas
- As cinco primeiras etapas podiam ser feitas em cerca de 30 minutos por capítulo, mas o ajuste final dos espaços em branco era a parte mais difícil
- A diagramação do livro tinha várias restrições de posicionamento vertical
- Não era possível cortar ilustrações no meio da página
- Asides ficam mais fáceis de entender quando cabem em uma única página
- Trechos de código também, de preferência, não deveriam ser quebrados entre páginas
- Era preciso evitar situações em que só o cabeçalho fica no fim da página
- Também era melhor evitar widows and orphans
- Nesses casos, o InDesign empurrava conteúdo para a página seguinte, mas isso criava grandes áreas em branco no rodapé
- Ilustrações e trechos de código se comportavam como um problema interligado de bin-packing, e por isso a diagramação do livro inteiro levou 2 meses
- Para reduzir os espaços vazios, foi necessário dividir trechos de código em duas partes, ajustar margens ao redor de imagens ou alterar a altura de ilustrações
Ilustrações, índice e elementos preliminares e finais
- As ilustrações foram escolhidas como desenhos em caneta e tinta, amigáveis para impressão em preto e branco, e inicialmente escaneadas em 1200 DPI
- Exportá-las como bitmap em alta resolução foi fácil, mas posicioná-las no layout das páginas foi difícil
- Como o texto não usava referências do tipo “ver Figura 123”, e sim frases que apontavam diretamente para a ilustração ao lado, era importante que as imagens ficassem próximas
- Em vez de contratar um indexador profissional, o autor passou 2 semanas relendo todos os capítulos e montando o índice por conta própria
- O recurso de índice do InDesign podia transformar o texto selecionado em entradas de índice e gerar o índice completo, mas adicionar cada entrada era uma tarefa repetitiva e tediosa
- No fim do livro foi incluído o índice; no início vieram página de rosto, página de copyright, dedicatória, agradecimentos e um sumário gerado pelo InDesign
Design da capa
- O autor considerava que a parte artística de uma capa de livro técnico talvez não fosse tão importante quanto em romances, mas como ele não estava em posição de obrigar vendas por status de professor, dedicou bastante tempo à capa
- A ideia inicial era usar uma fotografia tirada por ele mesmo, mas ele não encontrou uma imagem adequada
- No fim, decidiu usar a linguagem visual do livro: ilustrações em caneta e tinta
- Redesenhou em tamanho maior e com mais detalhes a ilustração de montanha que explicava o processo de compilação, e também refez o título com um visual de escrita manual
- O título foi baseado em Acumin Pro Extra Condensed impresso e depois traçado à mão para dar uma sensação imperfeita, com uma paleta de cores inspirada em manuais escoteiros mimeografados dos anos 1950
Provas e verificação de mudanças em PDF
- O PDF foi enviado ao KDP, as provas foram encomendadas e, uma semana depois, chegou uma caixa pesada
- Só ao ver o livro físico o autor sentiu a escala do projeto como um objeto material, e não apenas como arquivos de dados
- Como houve muito trabalho manual no processo de diagramação, ele leu pessoalmente a prova para encontrar erros e marcá-los com sticky notes
- Os arquivos do InDesign foram colocados em um repositório Git, mas eram grandes arquivos binários opacos, então não era possível ver diffs como em código-fonte
- O InDesign às vezes alterava arquivos mesmo sem parecer haver mudanças reais, o que dificultava entender o que havia sido modificado
- O autor escreveu um script em Dart para extrair todas as páginas do PDF do livro e montá-las em uma única imagem PNG em mosaico
- A cada commit, ele exportava o PDF, gerava a imagem em mosaico e usava uma action do Photoshop para desenhar bordas vermelhas nos pixels diferentes entre duas imagens, identificando as páginas alteradas
- Esse método não mostrava diretamente os detalhes da mudança, mas indicava quais páginas precisavam de inspeção visual e ajudava a confirmar se só as alterações esperadas tinham entrado
E-book e lançamento
- Depois de concluir as correções da prova impressa, também foram produzidos os e-books em Kindle e EPUB
- O sistema de build próprio foi modificado para exportar o XHTML antigo, os metadados e o manifest exigidos pelo EPUB
- Com alguns comandos no terminal, foram gerados os e-books para Kindle e EPUB, depois testados em vários leitores enquanto o CSS era ajustado
- Depois de preparar os arquivos finais, a primeira página do site do livro foi atualizada para apontar para os pontos de compra, e as fotos e o layout responsivo também foram organizados
- Depois de concluir o upload para as lojas, a atualização do site e o aviso à mailing list, o livro passou a estar “realmente” pronto
Planos depois disso
- Mesmo depois de terminar o último capítulo, as pessoas continuaram perguntando sobre o próximo trabalho ou o tema do próximo livro
- Depois de passar 6 anos dedicado a um único projeto, o autor não pretende planejar um novo livro tão cedo
- Também havia muitas coisas adiadas durante a pandemia, e o plano era descansar por um tempo sem decidir de imediato o que fazer
- Ele menciona possibilidades como fazer música, pescar, passar tempo com amigos e família e trabalhar em um projeto de roguelike, mas sem tomar uma decisão imediata
- Diz que talvez algum dia volte a querer fazer um grande projeto, mas que não gostaria de dedicar outros 6 anos a um único trabalho
1 comentários
Opiniões no Hacker News
Esta página tem tanto o link para comprar o livro quanto o link para a versão online gratuita: https://craftinginterpreters.com/
Este livro definitivamente vale a compra. Só o cuidado que Nystrom dedicou ao design do livro físico já é suficiente para quem gosta de material impresso, e as ilustrações desenhadas à mão e a ótima escrita o tornam melhor do que 99% dos livros técnicos, na minha opinião
Foi um dos melhores livros técnicos que já li. A estrutura em que, a cada capítulo, fica um código que evolui gradualmente e um programa executável é uma concepção incrível, e admiro o autor por realmente ter conseguido fazer isso
Como eu já tinha escrito algo parecido antes, passei por cima da parte do interpretador por percurso de árvore e aprendi muito mais acompanhando o interpretador de bytecode baseado em C
Achei que o texto fosse recente e que tivesse saído uma segunda edição
Quero parabenizar o autor. Este livro é um excelente recurso não só pela profundidade técnica na área de linguagens, mas também pelos pequenos detalhes de layout e gráficos que mantêm a leitura envolvente. Parece um livro que continuará relevante por muito tempo
Comecei a acompanhar Crafting Interpreters em 2017 e, ao avançar pela primeira metade do livro, escrevi a implementação de lox em Scala em vez de Java; nesse processo, tokenizador/analisador léxico/parser/interpretador deixaram de ser algo completamente misterioso
Antes eu achava que era uma espécie de domínio visionário que só certo tipo de programador conseguia lidar, mas acho que isso se deveu à excelente escrita de Nystrom e à sua profunda compreensão do tema. Comecei a escrever o segundo interpretador em Rust, mas a vida ficou corrida, não avancei muito e acabei não terminando. Acho que agora é hora de voltar. Este texto é de alguns anos atrás, mas eu não sabia que ele tinha sido lançado como livro físico; embora não seja o formato ideal para a forma como eu aprendo, fiquei com vontade de comprar um exemplar para ter na coleção e apoiar o autor
Foi um dos melhores livros de tecnologia da computação que já li. Li com muito prazer e aprendi muita coisa
Além do excelente conteúdo técnico, o texto é bem escrito, divertido, e as ilustrações são boas. Acho uma conquista monumental
Vale a pena ouvir esta ótima entrevista em que Bob fala sobre o livro: https://corecursive.com/032-bob-nystrom-on-building-an-inter...
Ironicamente, levei 15 meses para ler o livro inteiro e terminá-lo :). Me identifiquei muito com a situação do autor. É um ótimo livro escrito por um autor dedicado e talentoso, e fiquei tão apegado a ele que até criei uma página com base no que aprendi: https://hexmos.com/compiler
O autor passou de designer gráfico a engenheiro de compiladores? Surpreendente e impressionante
Tenho este livro na estante. Deve ser meu próximo livro sobre interpretadores depois de “Writing an interpreter in Go”, que tem cerca de 200 páginas e de que gosto muito
Acabei de terminar o analisador léxico em Rust em vez de Java, e estou animado para o resto. Até agora, é um livro excelente