← Blog

Fontes FIGlet no Text.js

@textjs/font interpreta fontes FIGlet .flf e organiza seu layout como o programa figlet. Seus testes reproduzem 273 saídas registradas do figlet 2.2.5, e todas coincidem.

Adam

O Text.js 0.3 adicionou @textjs/font, um parser e renderizador de fontes FIGlet. Ele inclui as 17 fontes da distribuição FIGlet 2.2.5, cada uma em um módulo ES, e sua saída corresponde exatamente à do binário figlet 2.2.5.

import { FigletText } from "@textjs/font/react";import { slant } from "@textjs/font/slant";export default function Page() {  return <FigletText font={slant} color="accent">Text.js</FigletText>;}
  ______          __      _ /_  __/__  _  __/ /_    (_)____  / / / _ \| |/_/ __/   / / ___/ / / /  __/>  </ /__   / (__  )/_/  \___/_/|_|\__(_)_/ /____/                   /___/

Por que FIGlet

<AsciiFont> tem dois estilos de letras integrados, block e compact, desde a versão 0.1. FIGlet é o padrão para esse tipo de lettering desde 1991, e existem centenas de fontes .flf. O suporte ao formato permite incluir qualquer uma delas em um app de console.

Uma fonte FIGlet é um arquivo de texto simples. Uma linha de cabeçalho define a altura, o caractere hardblank e as regras de layout; em seguida, cada caractere é desenhado como um bloco de linhas com um marcador no fim de cada linha. Nos layouts padrão, o FIGlet move cada caractere para a esquerda até encostar no anterior e usa as regras de fusão da fonte para decidir se os dois subcaracteres que se tocam se fundem em um só.

Modos de layout

figlet tem cinco layouts horizontais, e renderFiglet aceita os mesmos cinco por meio de layout:

layoutfigletEfeito
"default"-sLayout da própria fonte, geralmente com fusão
"full"-WLargura total; os caracteres nunca se tocam
"fitted"-kCaracteres aproximados até se tocarem
"smushed"-SFusão com as regras da fonte
"universal"-oCaracteres posteriores sobrepostos aos anteriores

Um número de -1 a 63 é um modo de layout -m bruto: -1 é largura total, 0 é ajustado, e 1 a 63 selecionam regras de fusão. Todas as seis regras de fusão horizontal estão implementadas: caractere igual, sublinhado, hierarquia, par oposto, X grande e hardblank. O parser também processa o restante do formato: linhas de comentário, caracteres identificados por código em decimal, octal e hexadecimal, o glifo de caractere ausente e fontes da direita para a esquerda, como ivrit.

A quebra de linha também segue o FIGlet. width quebra nos limites das palavras e dentro de uma palavra quando ela é mais larga que a linha, nos mesmos pontos que figlet -w. figlet -w 80 imprime no máximo 79 colunas, então -w N corresponde a width: N - 1.

Correspondência com o binário

packages/font/test/fixtures/references.json contém 273 saídas geradas ao executar o figlet 2.2.5 real com cada fonte incluída em todos os modos de layout, com quebra de linha, justificação, texto da direita para a esquerda, modo de parágrafo e a própria entrada de regressão do FIGlet com as flags de seu run-tests.sh. Cada caso armazena os argumentos, a entrada e a saída exata, e o teste converte a linha de comando de volta em opções:

for (const f of flags) {  if (f === "W") opts.layout = "full";  else if (f === "k") opts.layout = "fitted";  else if (f === "S") opts.layout = "smushed";  else if (f === "o") opts.layout = "universal";  else if (f === "s") opts.layout = "default";  else if (f === "c") opts.align = "center";  else if (f === "r") opts.align = "right";  else if (f === "l") opts.align = "left";  else if (f === "R") opts.direction = "rtl";  else if (f === "L") opts.direction = "ltr";  else if (f === "p") opts.paragraph = true;  else throw new Error(`unsupported flag -${f}`);}

Todas as 273 correspondem. Para gerar os dados de teste novamente, coloque figlet 2.2.5 no seu PATH e execute bun run --cwd packages/font references.

Fontes na grade de células

Todas as fontes incluídas desenham com ASCII imprimível ou Latin-1, então cada subcaractere ocupa exatamente uma célula em Menlo e se alinha à grade. <FigletText> mede suas linhas em células, então o lettering ocupa um layout flexbox como qualquer outro <Text>, e columns e align controlam a quebra e a justificação dentro de sua caixa.

Cada fonte tem seu próprio módulo, então um app inclui apenas as fontes que importa, e uma fonte é analisada na primeira renderização, em vez de na importação. @textjs/font/all exporta todas as fontes para galerias.

Qualquer outra FIGfont pode ser buscada e analisada em tempo de execução:

import { parseFont } from "@textjs/font";const doom = parseFont(await (await fetch("/fonts/doom.flf")).text(), "Doom");

Licenciamento

As fontes incluídas são idênticas byte a byte às de figlet-2.2.5.tar.gz e são distribuídas sob a licença BSD de 3 cláusulas do FIGlet. Cada uma mantém seus créditos nas linhas de comentário, disponíveis em font.comment. Fontes populares sem permissão de redistribuição, como Doom, Larry 3D, ANSI Shadow e Calvin S, não estão incluídas.

A referência completa está em Fontes.