2 pontos por GN⁺ 2024-03-06 | 1 comentários | Compartilhar no WhatsApp

A estrutura técnica interna do editor de texto da Apple

  • Aborda os detalhes de como o Paper funciona como um editor de texto baseado em TextView.
  • Atualmente, o Paper é construído sobre o framework TextKit 1, e no TextKit 2 os conceitos, abstrações e princípios são mantidos ou substituídos por APIs melhores.

View de texto

  • A classe TextView é o núcleo das operações de edição de texto no editor de texto da Apple.
  • NSTextView e UITextView têm diferenças, mas como a API é semelhante, são tratados como uma única classe TextView.
  • TextView é um componente de grande porte cuja complexidade aumenta a cada nova versão do sistema operacional.
  • A Apple divide o TextView em várias camadas para oferecer a experiência de edição de texto.

NSTextStorage

  • Armazena a string de texto bruta.
  • Armazena os atributos (pares string-valor) atribuídos a intervalos de texto.
  • Dispara eventos para alterações no texto e nos atributos.

NSTextContainer

  • Define a forma e o tamanho da área que hospeda os símbolos de texto (glifos).

NSLayoutManager

  • Calcula o tamanho e o espaçamento dos glifos com base nos intervalos de atributos aplicados à string de texto de NSTextStorage.
  • Faz o layout dos glifos e calcula onde cada linha do texto começa e termina, além da altura total do texto.

TextView

  • Desenha o layout dos glifos gerado por NSLayoutManager.
  • Sincroniza a altura da view com a altura atual do texto diagramado.
  • Gerencia a seleção de texto, o cursor e os atributos de digitação aplicados ao texto recém-inserido.

ScrollView

  • Exibe a parte visível de TextView.
  • Gerencia rolagem, barras de rolagem e zoom.

Atributos

  • NSAttributedString é a base da edição de texto rico nos frameworks da Apple.
  • É composto por uma string de texto simples e atributos (pares string-valor) anexados a intervalos do texto.
  • Os atributos são usados principalmente para estilização, mas não há restrição para atribuir pares string-valor personalizados.

Estilização

  • Estilização significa aplicar atributos especiais definidos pelo framework a intervalos de texto.
  • O Paper usa meta-atributos para identificar a estrutura do texto e então aplicar a estilização.
  • Os atributos são sincronizados com o texto Markdown de NSTextStorage, que muda com a entrada do usuário, e com as configurações que afetam o texto, ajustadas pelo usuário em itens de menu, sliders e gestos.

Desempenho

  • A separação entre atributos de meta, layout e decoração ajuda a manter rapidamente alterações específicas do editor.
  • A velocidade de digitação é o fator de desempenho mais importante em um editor de texto.
  • Devido à forma como o Markdown funciona, alterações no texto podem afetar a estilização de um parágrafo inteiro.

Meta-atributos

  • Além da lógica de destaque, os meta-atributos desempenham um papel importante em vários recursos que precisam conhecer a estrutura do texto.

Atalhos de formatação

  • Fornecem informações detalhadas necessárias para alternar o estilo do texto Markdown selecionado.

Navegação entre capítulos

  • Ajudam a encontrar títulos em relação à posição do cursor.

Estrutura de tópicos (Outline)

  • Depende de uma função que percorre todos os títulos.

Reorganização de capítulos

  • Fornece a funcionalidade de reorganizar capítulos na estrutura de tópicos.

Conversão de formato

  • É necessário conhecer a estrutura para converter conteúdo Markdown em RTF, HTML e DOCX.

Matemática do contêiner de texto

  • No contêiner de texto, a regra mais importante é manter o comprimento de linha preferido.
  • Às vezes é necessário simular simetria, como quando tags de título são colocadas fora do fluxo normal do texto.

Ancoragem da seleção

  • A seleção de texto sempre tem um ponto de ancoragem.
  • No Mac, é possível selecionar texto clicando e arrastando; no iOS, é possível arrastar uma das extremidades da seleção.

Afinidade da seleção

  • Na edição de texto, existe um conceito interessante chamado afinidade da seleção.
  • Ao mover o cursor com as teclas de seta, ele simplesmente muda de linha, mas ao usar atalhos para ir ao fim da linha, ele permanece na mesma linha e fica preso à direita.

Uniform Type Identifiers (UTIs)

  • Discute os UTIs, o sistema base para troca de dados entre aplicativos.
  • É um sistema hierárquico em que tipos de dados conform to (herdam de) tipos de dados pai.

Área de transferência (Pasteboard)

  • A área de transferência é um dicionário em que UTIs são mapeados para dados serializados.
  • Uma única operação de copiar grava várias representações do mesmo dado de uma vez.
  • Lidar com UTIs públicos e privados é relativamente simples, mas tratar formatos amplamente aceitos que não são definidos pela Apple é mais complexo.

Encerrando

  • Se você conferir o primeiro artigo, poderá obter mais informações sobre o app e o processo de desenvolvimento.

Opinião do GN⁺

  • Este artigo explica em detalhes o funcionamento interno complexo de um editor de texto baseado em TextView nas plataformas da Apple, oferecendo informações interessantes para desenvolvedores de software e usuários interessados.
  • Os algoritmos e os métodos de gerenciamento de atributos para otimizar o desempenho do editor de texto são bons exemplos que desenvolvedores podem consultar ao projetar seus próprios aplicativos.
  • A abordagem técnica usada para melhorar o desempenho do editor de texto oferece orientações úteis para outros desenvolvedores ao resolver problemas semelhantes.
  • Ao desenvolver aplicativos que lidam com formatos de texto como Markdown, compreender UTIs é importante para troca de dados e compatibilidade.
  • O artigo ajuda a aumentar a compreensão da estrutura interna de um editor de texto, mas gerenciar essa complexidade na prática ainda pode ser um desafio considerável para desenvolvedores.

1 comentários

 
GN⁺ 2024-03-06
Comentários no Hacker News
  • Este texto é realmente muito bom. Acho que vai substituir https://www.objc.io como meu material introdutório padrão sobre TextKit.

    • Este comentário avalia que o texto é muito útil como uma introdução básica ao TextKit.
  • Estou um pouco confuso sobre os atributos decorativos aplicados fora das transações de edição. Ele diz: "E eles não têm consciência da transação, porque existem no próprio NSLayoutManager, não no NSTextStorage". Mas atributos decorativos, como cor, normalmente ficam no NSTextStorage! O autor está sugerindo que a cor aplicada aos caracteres de Markdown está sendo feita por meio do suporte a atributos temporários do NSLayoutManager, geralmente usado para colorir palavras com erro ortográfico? Se for isso, qual seria o propósito?

    • O autor do comentário demonstra confusão com detalhes técnicos relacionados à edição de texto e questiona a explicação do autor sobre como atributos decorativos são tratados entre NSLayoutManager e NSTextStorage.
  • Artigo realmente excelente (e, pessoalmente, em ótima hora; estou lidando com NSTextViews neste momento). Como você obteve essas informações? Código de outras pessoas? Experiência dolorosa? developer.apple.com?

    • O autor do comentário considera o artigo muito útil e tem curiosidade sobre como o autor adquiriu esse conhecimento.
  • Na era dos documentos baseados em DOM (por exemplo, notion, gitbook), eu frequentemente uso strings atribuídas para fazer coisas quase mágicas com parsing e manipulação de texto. É uma estrutura muito elegante, e não consigo entender por que isso é tão pouco conhecido. Aliás, o artigo é incrível.

    • O autor do comentário considera o uso de strings atribuídas uma abordagem elegante e diz não entender por que essa técnica não é mais conhecida. Também elogia o artigo.
  • No passado, já tentei escrever meu próprio editor de texto do zero, e ter um material desses teria sido fantástico.

    • O autor do comentário menciona sua experiência tentando criar um editor de texto do zero e diz que este artigo teria sido muito útil naquela época.
  • Como fui desenvolvedor de apps Android por muito tempo, achei interessante ver como a Apple aborda as coisas de um jeito um pouco diferente e mais cuidadoso. No Android, a classe Layout (e suas subclasses) cuida de tudo relacionado a layout e renderização, enquanto o TextView implementa parte da lógica de edição/seleção. A única diferença entre EditText e TextView é que o EditText “ativa” recursos de edição que já existem no TextView. O problema dessa abordagem mais monolítica (e da API ruim) é que, se o app precisar de mais controle sobre como renderiza texto, você está sem sorte. Por exemplo, quer acessar glifos individuais depois que o layout foi feito? Não, foi mal.

    • O autor do comentário descreve as diferenças entre as abordagens de renderização e edição de texto no Android e na Apple, apontando que o Android é mais limitado quando se precisa de controle mais fino.
  • O app TextEdit é composto quase inteiramente por um único TextView. Acho que o equivalente no Windows seria o WordPad. Ele é baseado no controle RichEdit. Outro fato curioso é que o RTF é basicamente a forma serializada de um NSAttributedString. O mesmo vale para o controle RichEdit do Windows. Na verdade, parece que a implementação do Windows veio primeiro: https://en.wikipedia.org/wiki/Rich_Text_Format

    • O autor do comentário menciona que o app TextEdit é baseado em TextView e que o RTF (Rich Text Format) é uma forma serializada de NSAttributedString. Também comenta que o controle RichEdit do Windows com funcionalidade semelhante pode ter surgido antes.
  • Eu realmente adoro este app. Ele substituiu todos os meus outros apps de Markdown, incluindo obsidian e ia Writer!

    • O autor do comentário demonstra grande satisfação, dizendo que o app substituiu todas as suas ferramentas anteriores para trabalhar com Markdown.
  • Ainda bem que pelo menos alguém continua usando Cocoa em 2024.

    • O autor do comentário expressa alívio ao ver que ainda existem desenvolvedores usando o framework Cocoa.
  • Queria que houvesse mais documentação desse tipo sobre componentes do iOS!

    • O autor do comentário expressa o desejo de ver mais documentação desse tipo sobre componentes do iOS.