1 pontos por GN⁺ 2024-11-19 | 1 comentários | Compartilhar no WhatsApp
  • Com apenas um arquivo HTML único executado pelo navegador, é possível reunir exploração, análise, visualização de dados, composição tipográfica e publicação em um só documento, reduzindo o fluxo tradicional notebook → ferramenta de publicação → PDF
  • A implementação central combina células de echo que exibem style e script na tela, contenteditable e o Observable Runtime para criar células reativas editáveis
  • cell(name, inputs, definition) segue o modelo de dependências do Observable para compor unidades de execução conectadas entre si, como counter, renderização de FizzBuzz, células ocultas e células intermediárias sem saída
  • Dentro do mesmo documento HTML, são demonstrados Observable Plot, TeX, Markdown, Graphviz, SQLite baseado em WASM, Python com Pyodide, R com WebR, Observable Inputs e até estado Mutable
  • O resultado é um documento científico ou técnico executado no navegador sem depender de plataforma separada, e a implementação depois foi publicada como a biblioteca @celine/celine

Reduzindo a separação entre notebook e publicação com um único arquivo HTML

  • O HTML é amplamente usado para composição tipográfica, mas foi relativamente menos explorado como plataforma de exploração, análise e visualização de dados
  • O fluxo de trabalho comum passa por várias ferramentas
    • Em notebooks interativos como Jupyter, RStudio, Pluto.jl e Observable, faz-se exploração, análise e visualização
    • Depois o conteúdo é levado para plataformas de publicação como Typst, Overleaf, LaTeX ou editores WYSIWYG para compor o material
    • Para distribuir, exporta-se para .pdf
  • Se um único arquivo HTML assumir essas três etapas, é possível reduzir procedimentos manuais, ferramentas de CLI, etapas de CI e dependência de plataformas de terceiros
  • A implementação foi fortemente influenciada por Anton Zhiyanov em In-browser code playgrounds, Cristóbal Sciutto em Self-modifying HTML notes, Quarto e Observable Framework

Criando células editáveis

  • A primeira etapa é usar a classe CSS echo para fazer com que elementos style e script fiquem visíveis dentro do documento
  • Com uma fonte com realce de sintaxe embutido e o atributo contenteditable, isso pode funcionar como um editor de código básico
  • Um script com contenteditable é reavaliado quando perde o foco
    • O script existente é clonado para criar um novo elemento script, e o original é removido
    • Isso é necessário porque eval não funciona com código que contém instruções import
  • Para execução baseada em Observable, duas bibliotecas são carregadas
  • Apenas dois símbolos são expostos no escopo global: library e cell

Fluxo de dados reativo com Observable Runtime

  • A função cell(name, inputs, definition, observerVisibility) define células usando o escopo de módulo do Observable Runtime
  • Se já existir uma variável com o mesmo nome, ela é reutilizada; caso contrário, cria-se uma nova variável para defini-la
    • Graças a essa estrutura, quando uma célula contenteditable é reavaliada, a nova definição se propaga para as células conectadas
  • O Inspector do Observable é usado para mostrar a saída das células acima do bloco script
  • A célula counter é composta como um gerador assíncrono que emite um número a cada segundo
    • O atributo id do script e o argumento name de cell são iguais
    • Se o valor inicial i for alterado e o foco for removido, o novo valor passa a ser refletido
  • Também é possível criar células que dependem de counter
    • Importa-se Hypertext Literal para renderizar o valor de counter no formato FizzBuzz
    • htl implementa um parser HTML5 e lida com escape automático, listeners de evento, objetos de estilo e interpolação de valores não serializáveis, como nós DOM

Células visíveis, ocultas e sem saída

  • Sem a classe echo, é possível ocultar a definição da célula e ainda assim observar a saída
    • Essas células podem ser usadas como primitivas de renderização
  • Também é possível criar um tipo de célula que não exibe a própria saída
    • silent(name, inputs, definition) define observerVisibility como oculto, podendo ser usada para armazenar valores intermediários ou estruturas de dados
  • As células podem funcionar independentemente da ordem de declaração
    • No exemplo, a célula reallyNegative depende da célula negative, declarada mais tarde
  • O mesmo valor de célula também pode ser usado em saídas mais complexas
    • Importa-se Observable Plot para desenhar um gráfico de linha a partir de um array numérico e mostrar uma linha vertical na posição counter % 40

Expandindo a saída de documentos e visualizações

  • Uma célula pode retornar qualquer elemento DOM
  • As demos de TeX, Markdown e Graphviz retornam elementos de tipos diferentes
    • A célula tex retorna um elemento span
    • A célula md retorna um elemento table
    • A célula dot retorna um elemento svg
  • Uma célula pode retornar uma Promise ou lançar um Error
    • O Inspector do Observable aplica a classe observablehq--running à div externa da célula em execução
    • Em células com erro, aplica a classe observablehq--error
    • O documento define estilos de acordo com esses estados

SQLite, Python e R no navegador

Entradas e estado mutável

  • O tipo de célula viewof foi criado para uso com Observable Inputs
  • viewof declara duas células reativas
    • NAME: o valor da entrada
    • viewof NAME: o próprio elemento DOM
  • Para mostrar a entrada acima da célula, é preciso definir o id da célula como viewof NAME
  • No exemplo, cria-se uma entrada de faixa com Inputs.range([0, 100], { step: 1 }), e a célula rangePlot é atualizada de acordo com esse valor
  • O funcionamento do Observable Inputs é um pouco difícil de entender, e a demo Synchronized Inputs pode ajudar
  • Para casos em que um fluxo de dados puramente funcional não basta, também foi criado o helper mutable
    • mutable registra um objeto Mutable que emite um novo valor quando ele é alterado

Publicação da biblioteca e slides para apresentação

  • A implementação inicialmente pensou no nome incel, mas depois passou a ser chamada de celine
  • A biblioteca foi publicada como @celine/celine
  • Este documento foi demonstrado no SydJS
  • Também há código incluído para transformar o documento em apresentação de slides
    • Shift+N: iniciar o slideshow ou avançar para o próximo slide
    • Shift+B: slide anterior
    • Shift+E: encerrar o slideshow
  • O código da implementação está disponível como source code

1 comentários

 
GN⁺ 2024-11-19
Comentários do Hacker News
  • Concordo fortemente com a premissa do texto. HTML pode ser uma excelente base para notebooks computacionais
    Dito isso, não gosto das escolhas de implementação feitas aqui. HTML dinâmico e reativo pode ser feito de forma muito mais declarativa do que isso, e o Observable é legal, mas em alguns pontos foge do JavaScript padrão
    Comecei a criar um sistema de HTML reativo chamado Heximal, e depois pretendo adicionar suporte a notebooks também. É um sistema declarativo baseado em templates HTML e elementos personalizados, com uma camada de expressões/reatividade baseada na proposta TC39 Signals por cima
    https://github.com/elematic/heximal
    É mais ou menos uma mistura de HTMX, Tangle, Curvenote e Polymer, e parece como o HTML seria se já tivesse sido reativo desde o início. Acho que combina muito bem com casos de uso de edição gráfica e notebooks

    • “Observable é legal, mas foge do JS padrão” faz sentido para o frontend, mas por baixo o runtime simplesmente executa JavaScript. O código-fonte também é praticamente JavaScript com uma pequena macro totalmente contida no parser acorn sob licença MIT
      Por isso, expressões normais de depuração em JavaScript funcionam corretamente no Observablehq
      https://github.com/observablehq/parser
      Gosto tanto do runtime do Observable que até criei um descompilador capaz de converter nos dois sentidos entre o código-fonte do frontend e sua representação compilada em JS puro
      https://observablehq.com/@tomlarkworthy/observablejs-toolcha...
    • Fico curioso se isso levou em conta também o Observable Framework. Ele saiu em março, e uma de suas principais características era justamente usar JavaScript padrão, em vez dos hacks de sintaxe criados nos Observable Notebooks: https://observablehq.com/blog/observable-2-0#a-better-develo...
  • Muito legal. Gostei especialmente da demo de Python e SQLite. É interessante que isso parta do loop de edição via web (TTW) e o chame de quine; faz sentido, mas a principal fraqueza é a persistência
    O TiddlyWiki essencialmente faz a mesma coisa, mas salvar o trabalho é um grande problema. Porque, no fim, para persistir qualquer coisa, você precisa de um processo de servidor headless separado
    Quando quis criar algo parecido[0], pessoalmente comecei pela persistência, e isso naturalmente significava arquivos. Eram arquivos de texto puro que podiam ser editados em um editor para programadores e salvos/publicados via sistema de arquivos. Isso evita o problema de ter de reimplementar um editor para programadores dentro do navegador, o que não é nada trivial
    Em troca, surge o problema de escrever um servidor rápido, mas esse também é um problema bem divertido[1]. Aqui isso foi contornado usando seções contenteditable básicas, mas esse é o segundo maior problema, depois da persistência
    O fato de não ser possível usar export dentro de scripts embutidos também parece ser a mesma barreira. Seria bom ter esse tipo de recurso para evitar bagunçar o objeto global window, e no meu caso de uso isso também tornaria a geração de código mais fácil
    0 - Literate Markdown: https://simpatico.io/lit.md
    1 - Reflector, um pequeno servidor node que transforma, comprime e faz cache de markdown, além de invalidar observação de arquivos: https://simpatico.io/reflector

  • Respeito as ideias e o esforço investidos, mas a usabilidade dessa abordagem é terrível. Não entendo por que eu teria que me preocupar até com elementos de estilo enquanto tento fazer análise exploratória de dados
    Esse é exatamente o motivo de ferramentas como o Jupyter Notebook funcionarem tão bem. Ainda assim, valorizo bastante o fato de terem implementado uma ideia alternativa por curiosidade

    • Autor: eu também acho uma pena, mas concordo que a usabilidade dessa abordagem é terrível, e uma boa parte da motivação para eu criar o @celine/celine veio daí (https://maxbo.me/celine, ou seja, empacotar escrita como uma biblioteca)
      Ainda não é suficiente como plataforma de análise exploratória de dados. Não tem a responsividade imediata de um editor de código web completo como o Observable Notebooks, nem é o Observable Framework, que oferece hot reloading baseado em monitoramento de arquivos. O novo kernel Jupyter para Deno + VSCode também proporciona uma experiência bem fluida
      Então, quanto à usabilidade para análise exploratória, é... concordo que é ruim, mas acho que a usabilidade para publicação não é tão ruim assim. Na verdade, é boa. Porque é simplesmente um arquivo único. Para enviar a alguém gráficos e resultados de processamento de dados, você não precisa manter uma cadeia enorme de ferramentas nem pagar por um serviço de terceiros; basta jogar um arquivo HTML no Slack ou hospedá-lo em algum lugar
      Graças à flexibilidade para estilizar os resultados da análise, também dá para publicar em contextos onde o estilo importa, como blogs ou artigos de pesquisa
    • À primeira vista, parece que a ideia é posicionar isso mais para o lado de “análise exploratória de DOM”. A demo de apresentação tem um clima de Scheme/Smalltalk no sentido de ir construindo estrutura e elementos básicos, e a cena em que trocar ivory por red altera o syntax highlighting em tempo real mostra isso
      Entendo o contexto que levou até aqui, mas é uma pena que ainda não seja fácil brincar com frameworks e bibliotecas JavaScript no navegador. No fim das contas, é só JS, então deveria dar para experimentar rápido em um ambiente leve. Essa abordagem tem força nesse ponto
      É uma forma de recuperar o potencial lúdico e experimental de HTML/JS. Queria ver mais tentativas assim do que TS, rollup, webpack e afins
      Adendo: lendo mais um pouco, vi que isso está sendo proposto para análise de dados. Para esse uso, não acho que se encaixe bem
    • Você diz “só quero fazer análise exploratória de dados”, mas acho que o ponto central não seria ter uma plataforma integrada para fazer análise exploratória de dados e publicar facilmente os resultados? Não é para notebooks Jupyter descartáveis
      Acho que há muito valor em uma alternativa ao Jupyter Notebook que não seja algo para jogar fora depois. A experiência do usuário está realmente péssima agora, mas isso pode melhorar. A questão é se essa configuração é melhor do que o caos em JSON do Jupyter Notebook, e pessoalmente acho que sim
  • O autor original do Lit saiu recentemente do Google e, pelo que sei, está trabalhando em algo muito parecido com isso
    https://github.com/elematic/heximal

    • Não sabia que ele tinha tornado público o que está fazendo depois disso. Valeu por avisar
  • Gosto do formato deste texto. Ele começa do básico e vai construindo até chegar a algo interessante. Não segue aquela onda exagerada de amontoar dependências ou colar frameworks por todo lado
    Para acompanhar, parece que basta copiar e colar os trechos apresentados e entender passo a passo como funcionam. Se eu fosse escrever algo assim, provavelmente faria com programação literária no org-mode e depois exportaria para HTML para virar um post de blog
    Ainda assim, continuo em dúvida sobre a fonte com syntax highlighting embutido

  • Chamam isso de HTML reativo, mas não é quase tudo JavaScript? Ou entendi algo errado?

    • A parte interativa/reativa é JavaScript, mas o notebook está implementado dentro de um arquivo HTML autocontido. Ele cuida de tudo, da estrutura do documento até edição e exibição
      Tirando o navegador, não depende de software de terceiros e, como o HTML, é duradouro, portátil e fácil de escrever
    • Passa uma sensação de “por que todo mundo tenta rodar notebooks no navegador usando Colab ou Observable? Enfim, vou apresentar uma alternativa que usa Observable para as partes difíceis”
  • Em breve quero tentar dar suporte a esse tipo de notebook HTML em Raku, ou para Raku
    No momento, as “soluções de notebook” de Raku são baseadas em Jupyter ou em Mathematica

  • Não entendo a lógica de usar tecnologias web para complicar esse processo. O que essa complexidade adicional resolve? Na verdade, parece mais algo que torna o processo mais lento e remove recursos necessários como autocompletar, snippets e extensões
    Além disso, é bem provável que outras pessoas não estejam familiarizadas com essa configuração, então colaborar também fica mais difícil
    O ambiente pode ser configurado uma vez e depois continuar sendo usado, acrescentando apenas pequenas melhorias conforme a tecnologia evolui
    Se você usa n/vim, o seguinte já é suficiente. 1- Exploração de dados: use https://github.com/untitled-ai/jupyter_ascending para conectar texto a notebooks Jupyter. Como usa jupytext, dá para editar e executar código com eficiência no editor de texto
    2- Escrita: para LaTeX, você pode usar https://github.com/lervag/vimtex
    Se adicionar tmux e tmuxp a isso, dá para abrir projetos instantaneamente. No Emacs, é possível montar um processo fluido com org mode[1][2] e/ou Auctex
    [1] https://sqrtminusone.xyz/posts/2021-05-01-org-python/
    [2] https://martibosch.github.io/jupyter-emacs-universe/

    • Quando você abre um notebook Jupyter no navegador, que tecnologia está usando? E quando abre o site do OP, que tecnologia está usando?
    • Em geral, são observações boas
      Só que eu não gosto tanto de Python, então quero usar ferramentas que não sejam centradas em Python. Foi por isso que mencionei Raku e Mathematica
      E obrigado por indicar https://github.com/imbue-ai/jupyter_ascending
    • Concordo. Quem quer notebooks reativos deveria considerar Emacs seriamente. Há muita gente que usa Emacs só para algumas finalidades, e notebooks reativos frequentemente são uma delas
  • Concordo em grande parte com a premissa deste texto, ou seja, que HTML não está sendo aproveitado o suficiente como meio de publicação para escrita científica
    Há um trabalho recente de Will Crichton relacionado a isso
    https://willcrichton.net/nota/
    https://willcrichton.net/notes/portable-epubs/

  • Notebooks estão em alta ultimamente. Nós também lançamos uma versão de notebook em TypeScript[1], mas escolhemos um lado bem diferente nos trade-offs
    Queríamos executar código node no backend, então, diferentemente da abordagem deste texto ou do Observable, não tentamos rodar no ambiente do navegador. Ainda assim, para muitas aplicações, essa ideia pode ser uma solução melhor
    Palmas para o autor
    https://github.com/srcbookdev/srcbook