Automatizando o controle de qualidade linguística na Transloadit
Este artigo descreve nossa configuração de publicação de 2015. Os nomes de pacotes e a configuração abaixo são históricos e não servem como guia de instalação para as ferramentas de hoje.
Eu estava escrevendo uma documentação interna sobre como configurei a verificação automatizada de linguagem na Transloadit. No meio do caminho, percebi que isso também poderia ser útil para o resto do mundo 🌎, então reescrevi tudo de forma mais genérica. Vou tentar primeiro dar uma visão geral do problema e depois descer até os detalhes práticos de como resolvê-lo. Espero que você goste, lá vamos nós!
Na Transloadit, temos extraído todos os trechos de texto de tamanho significativo (documentação, posts do blog, páginas estáticas) para um repositório de conteúdo separado.
Até essa migração, nosso texto estava espalhado por tabelas MySQL, templates e arquivos HTML. Uma grande sopa de conteúdo, layout, código e locais. Os desenvolvedores conseguiam acessar tudo isso, mas sem muito prazer. Quem não era desenvolvedor não tinha a menor chance.
Achamos que seria interessante ver se conseguiríamos atrair redatores técnicos e dar a eles acesso total ao nosso conteúdo. Imaginamos que eles poderiam usar a interface web do GitHub como se fosse uma wiki, para melhorar nossa linguagem sem se distrair com código, alterá-lo por acidente ou precisar de muita habilidade nessa área.
Isso ainda não atingiu todo o seu potencial, mas:
- como desenvolvedores, já estamos gostando de trabalhar no conteúdo (puramente em Markdown)
- ter todo o conteúdo em um repositório separado abre portas para outras possibilidades interessantes, como controle de qualidade automatizado, ou seja: integração contínua
Integração contínua
Integração contínua é um conceito normalmente associado a código. A ThoughtWorks explica assim:
A integração contínua (CI) é uma prática de desenvolvimento que exige que os desenvolvedores integrem código a um repositório compartilhado várias vezes ao dia. Cada check-in é então verificado por um build automatizado, o que permite que as equipes detectem problemas cedo.
Na Transloadit, já usávamos isso para todo o nosso código. Mas será que também poderíamos usar isso para o nosso inglês?
Essa pergunta era especialmente relevante para nós porque, embora a maioria dos nossos clientes more nos Estados Unidos, a Transloadit fica em Berlim, e ninguém da nossa equipe atual é falante nativo de inglês.
Considerando o quanto erros de linguagem podem prejudicar quando as pessoas ainda estão nas fases iniciais de avaliação de um produto, ter algumas verificações extras é ainda mais importante para nós.
Estamos combatendo a baixa qualidade de conteúdo em três áreas:
Escrita inconsiderada
Citando a npm weekly:
Provavelmente nenhum de nós tem a intenção de excluir ou magoar outros membros da comunidade, mas uma linguagem polarizadora e que favorece um gênero acaba se infiltrando no que escrevemos. Às vezes, ajuda muito ter um segundo par de olhos que revise tudo, perceba o que deixamos passar e nos incentive a ser mais atenciosos e inclusivos. O Alex ajuda a “detectar escrita insensível e inconsiderada” identificando linguagem possivelmente ofensiva e sugerindo alternativas úteis.
Para instalar o alex, executamos um simples npm install --save alex.
O Alex não é tão inteligente quanto um humano, mas faz o melhor que pode e às vezes fica feliz demais em avisar que algo pode ser insensível.
Isso significa que, ocasionalmente, pode haver falsos positivos e, como não queremos que os avisos do alex sejam fatais, usamos
node_modules/.bin/alex || true
Assim, conseguimos ver a linguagem que o alex acha que poderia ser melhorada, mas não tornamos essas sugestões críticas.
Por exemplo
74:74-74:76 warning $(he) may be insensitive, use $(they), $(it) instead
Graças a esse projeto, estamos reescrevendo nossa documentação para que seja mais inclusiva.
Formatação bagunçada
Nossos arquivos de texto estão no formato Markdown. Escolhemos esse formato porque ele:
- é razoavelmente fácil de entender para humanos e computadores,
- tem um ótimo ecossistema de ferramentas ao seu redor, e
- oferece uma boa separação entre a estrutura de um documento e o seu layout. Podemos especificar que algo está enfatizado, mas não que está em Comic Sans. Essas decisões ficam com os designers.
Muitas vezes, há várias maneiras de chegar ao mesmo resultado em Markdown. Assim como no código, ajuda definir uma convenção e obrigar todos os colaboradores a segui-la. Ao tirar um pouco dessa liberdade artística (inútil), o documento resultante parece bem cuidado e convida a novas contribuições.
Para isso, usamos o mdast com um plugin de lint:
npm install --save mdast mdast-lint
Como não queremos verificar projetos externos (como o próprio mdast) nem verificar de novo artefatos gerados no build, excluímos alguns locais
printf '%s\n' '_site/' 'node_modules/' >> .mdastignore
Em seguida, salvamos a seguinte convenção em .mdastrc, mas isso depende, é claro, das suas
configurações e
preferências de lint
{
"plugins": {
"lint": {
"blockquote-indentation": 2,
"emphasis-marker": "*",
"first-heading-level": false,
"link-title-style": "\"",
"list-item-indent": false,
"list-item-spacing": false,
"no-shell-dollars": false,
"maximum-heading-length": false,
"maximum-line-length": false,
"no-duplicate-headings": false,
"no-blockquote-without-caret": false,
"no-file-name-irregular-characters": true,
"no-file-name-outer-dashes": false,
"no-heading-punctuation": false,
"no-html": false,
"no-multiple-toplevel-headings": false,
"ordered-list-marker-style": ".",
"ordered-list-marker-value": "one",
"strong-marker": "*"
}
},
"settings": {
"gfm": true,
"yaml": true,
"rule": "-",
"ruleSpaces": false,
"ruleRepetition": 70,
"emphasis": "*",
"listItemIndent": "1",
"incrementListMarker": false,
"spacedTable": false
}
}
Depois, executamos o lint pela primeira vez
node_modules/.bin/mdast --frail .
Isso pode retornar
_posts/2015-09-15-spelling.md
246:1 warning Use spaces instead of hard-tabs no-tabs
Como bônus, o mdast pode até tentar corrigir isso automaticamente
node_modules/.bin/mdast --output .
Ficamos impressionados com o quanto o mdast conseguiu corrigir. No entanto, certifique-se de que seus arquivos estejam commitados no Git antes de executar esse comando. Você vai querer revisar as alterações feitas e revertê-las se necessário. Provavelmente serão necessárias algumas iterações para deixar tudo em bom estado.
Erros de ortografia
William Dutton, diretor do Oxford Internet Institute da Universidade de Oxford, afirma em Erros de ortografia ‘custam milhões’ em vendas online perdidas que, em algumas partes informais da internet, como o Facebook, há maior tolerância com ortografia e gramática.
No entanto, há outros aspectos, como uma página inicial ou uma oferta comercial, que não estão entre amigos e que levantam preocupações sobre confiança e credibilidade. Nesses casos, uma palavra escrita errado pode ser um problema fatal.
Bastou falar em ‘preocupações’ para me convencer. Mãos à obra. Para a verificação ortográfica em
documentos Markdown, usamos o npm install --save markdown-spellcheck.
Ele pode não detectar erros de gramática e muitas outras sutilezas (“it’s” vs. “its”), mas pelo menos muitos dos meus infelizes erros teimosos são detectados antes de chegar à produção:
- meu próprio inglês de fantasia (“symbiose” vs. “symbiosis”)
- erros teimosos de digitação (“editted” vs. “edited”), e
- mistura de inglês britânico com inglês americano (“summarise” vs. “summarize”)
(em minha defesa: inglês não é minha língua materna 😄)
O markdown-spellcheck até pula automaticamente blocos de código e outras coisas típicas do Markdown,
mas obviamente ainda tivemos que ignorar manualmente coisas como Transloadit e FFmpeg
printf '%s\n' 'Transloadit' 'FFmpeg' >> .spelling
Agora estamos prontos para verificar erros de ortografia nos nossos arquivos Markdown
node_modules/.bin/mdspell \
--report \
--en-us \
--ignore-numbers \
--ignore-acronyms \
**/*.md \
_layouts/*.html \
_includes/*.html \
*.html
Isso pode retornar que “editted” não é uma palavra.
Primeira execução
Há uma boa chance de a primeira execução revelar muitos problemas, tanto nos seus documentos quanto
no dicionário. Por isso, é uma boa ideia executar o mdspell sem a flag --report para que ele
entre no modo interativo padrão.

Isso permite excluir certos arquivos e montar um dicionário personalizado dentro de .spelling.
Provavelmente vai levar um tempo, mas pode ser uma ótima atividade quando você quiser ser produtivo
em uma tarde sem muita inspiração.
À medida que você adiciona novo conteúdo, às vezes também vai precisar adicionar palavras à lista de permissões. Mas pelo menos você saberá que todos os casos em que as palavras fogem do dicionário serão intencionais. E essa é uma boa sensação.
Combinar
Agora vamos juntar tudo isso.
Como instalamos todas essas ferramentas pelo npm, pode fazer sentido usar scripts do npm run. No entanto, no nosso caso, escolhi um Makefile, simplesmente porque gostamos de usar TAB no autocompletar do shell e para termos o mesmo ponto de entrada para desenvolvedores em todos os nossos projetos, sejam eles escritos em Node.js, Bash ou Go.
SHELL := /usr/bin/env bash
tstArgs :=
tstPattern := **/*.md _layouts/*.html _includes/*.html *.html
.PHONY: fix-markdown
fix-markdown:
@echo "--> Fixing Messy Formatting.."
@node_modules/.bin/mdast --output .
.PHONY: test-inconsiderate
test-inconsiderate:
@echo "--> Searching for Inconsiderate Writing (non-fatal).."
@node_modules/.bin/alex $(tstArgs) || true
.PHONY: test-spelling
test-spelling:
@$(MAKE) test-spelling-interactive tstArgs=--report
.PHONY: test-spelling-interactive
test-spelling-interactive:
@echo "--> Searching for Spelling Errors.."
@node_modules/.bin/mdspell \
$(tstArgs) \
--en-us \
--ignore-numbers \
--ignore-acronyms \
$(tstPattern)
.PHONY: test-markdown-lint
test-markdown-lint:
@echo "--> Searching for Messy Formatting.."
@node_modules/.bin/mdast --frail $(tstArgs) .
.PHONY: test
test: test-inconsiderate test-spelling test-markdown-lint
@echo "All okay : )"
Agora podemos executar make test para ver se todas as nossas verificações passam.
Podemos executar make test-spelling para focar apenas nos erros de ortografia, ou
make test-spelling-interactive se quisermos entrar no modo interativo depois de escrever conteúdo com
muitas palavras novas que provavelmente ainda não estão no dicionário.
Se você tiver o
Bash Completion, basta digitar
make, pressionar TAB e ver todos os atalhos disponíveis.
Automatizar
Para automatizar os testes, vamos precisar de um servidor de integração contínua.
Travis CI, Strider e Drone.io atendem bem. O importante é termos um local central que execute código de forma confiável e repetível sempre que uma alteração for feita no seu repositório.
Usamos o Jenkins para projetos privados, e criei três novas tarefas encadeadas para o nosso repositório de conteúdo:
content-buildtransforma nosso Markdown em conteúdo HTML estático via Jekyll e então dispara:content-testexecuta todos os comandos deste post e então dispara:content-injectarmazena o HTML no nosso site e então dispara:website-build,website-test,website-deploy. Uma cadeia que já tínhamos configurado para fazer o deploy do nosso site.

Agora, novo conteúdo só pode ser inserido e publicado se todas as verificações passarem. É uma cadeia bem longa, mas felizmente uma máquina cuida disso. 😄
E quando essa máquina detecta erros de digitação em conteúdo novo, temos uma integração com o Slack configurada para sermos notificados imediatamente.

Agora está perfeito?
Não. Humanos são falíveis, assim como suas máquinas e seus dicionários.
Vamos precisar continuar ajustando o .spelling, e “ele” precisa continuar me corrigindo. Mas, com esse
controle de qualidade linguística automatizado, um mantém o outro sob controle, e cometemos menos
erros do que antes.
No caso da Transloadit, conseguimos corrigir 151 erros na primeira execução

Sim… no fim das contas, somos éramos péssimos em ortografia!
O que vem a seguir
Se você conhece outras ferramentas legais de processamento de Markdown para adicionarmos à nossa cadeia de build, conte para nós no Twitter ou comente no HN.
Por fim, ainda estamos procurando um bom redator técnico para nos ajudar a melhorar nossa linguagem, já que os computadores só nos levam até certo ponto. 😄
Lembre-se de que você trabalharia apenas com arquivos Markdown; o resto é feito automaticamente. Escreva para nós se tiver interesse!
