Notebook HTML phản ứng
(maxbo.me)- Chỉ với một tệp HTML duy nhất chạy trong trình duyệt, có thể gói việc khám phá dữ liệu, phân tích, trực quan hóa, dàn trang và triển khai vào trong một tài liệu, qua đó rút gọn luồng notebook truyền thống → công cụ xuất bản → PDF
- Cốt lõi triển khai là kết hợp các ô echo hiển thị
stylevàscriptngay trên màn hình,contenteditablevà Observable Runtime để tạo các ô phản ứng có thể chỉnh sửa cell(name, inputs, definition)tuân theo mô hình phụ thuộc của Observable để cấu thành các đơn vị thực thi liên kết với nhau, nhưcounter, phần render FizzBuzz, ô ẩn và ô giá trị trung gian không có đầu ra- Trong cùng một tài liệu HTML, bản demo trình diễn Observable Plot, TeX, Markdown, Graphviz, SQLite dựa trên WASM, Python dựa trên Pyodide, R dựa trên WebR, Observable Inputs và cả trạng thái Mutable
- Kết quả là một tài liệu khoa học/kỹ thuật chạy trong trình duyệt mà không cần nền tảng riêng; phần triển khai sau đó được công bố thành thư viện
@celine/celine
Thu hẹp khoảng cách giữa notebook và xuất bản bằng một tệp HTML duy nhất
- HTML được dùng rộng rãi cho dàn trang, nhưng tương đối ít được tận dụng như một nền tảng khám phá, phân tích và trực quan hóa dữ liệu
- Quy trình làm việc thông thường đi qua nhiều công cụ
- Nếu một tệp HTML đảm nhận cả ba bước này, có thể giảm bớt thao tác thủ công, công cụ CLI, các bước CI và sự phụ thuộc vào nền tảng bên thứ ba
- Phần triển khai chịu ảnh hưởng mạnh từ In-browser code playgrounds của Anton Zhiyanov, Self-modifying HTML notes của Cristóbal Sciutto, Quarto và Observable Framework
Tạo các ô có thể chỉnh sửa
- Bước đầu tiên là dùng lớp CSS
echođể hiển thị nguyên trạng các phần tửstylevàscripttrong tài liệu - Khi thêm một phông chữ có tô sáng cú pháp tích hợp và thuộc tính
contenteditable, chúng có thể được dùng như một trình chỉnh sửa mã cơ bản scriptcó áp dụngcontenteditablesẽ được đánh giá lại khi mất focus- Nhân bản
scripthiện có để tạo phần tửscriptmới rồi xóa bản gốc - Cách này là cần thiết vì
evalkhông hoạt động với mã có câu lệnhimport
- Nhân bản
- Để thực thi dựa trên Observable, hai thư viện được nạp vào
- Trên phạm vi toàn cục chỉ để lộ hai symbol là
libraryvàcell
Luồng dữ liệu phản ứng dựa trên Observable Runtime
- Hàm
cell(name, inputs, definition, observerVisibility)định nghĩa ô bằng module scope của Observable Runtime - Nếu đã có biến cùng tên thì lấy biến hiện có; nếu chưa có thì tạo biến mới và định nghĩa nó
- Nhờ cấu trúc này, khi đánh giá lại một ô
contenteditable, định nghĩa mới sẽ được truyền tới các ô liên kết
- Nhờ cấu trúc này, khi đánh giá lại một ô
- Observable
Inspectorđược dùng để hiển thị đầu ra của ô phía trên khốiscript - Ô
counterđược cấu thành như một async generator phát ra số mỗi giây- Thuộc tính
idcủascriptgiống với đối sốnamecủacell - Sau khi thay đổi giá trị ban đầu
ivà bỏ focus, giá trị mới sẽ được phản ánh
- Thuộc tính
- Cũng có thể tạo ô phụ thuộc vào
counter- Nạp Hypertext Literal để render giá trị
countertheo dạng FizzBuzz htltriển khai bộ phân tích HTML5, xử lý tự động escape và nội suy các giá trị không tuần tự hóa như event listener, đối tượng style và DOM node
- Nạp Hypertext Literal để render giá trị
Ô hiển thị, ô ẩn và ô không có đầu ra
- Nếu không gắn lớp
echo, có thể ẩn định nghĩa ô nhưng vẫn quan sát được đầu ra- Những ô như vậy có thể dùng làm primitive render
- Cũng có thể tạo kiểu ô không hiển thị chính đầu ra
silent(name, inputs, definition)đặtobserverVisibilitythành ẩn, dùng để lưu giá trị trung gian hoặc cấu trúc dữ liệu
- Ô có thể hoạt động bất kể thứ tự khai báo
- Trong ví dụ, ô
reallyNegativephụ thuộc vào ônegativeđược khai báo sau đó
- Trong ví dụ, ô
- Cùng một giá trị ô cũng được dùng cho đầu ra phức tạp hơn
- Nạp Observable Plot để vẽ mảng số thành biểu đồ đường và hiển thị một đường quy tắc dọc tại vị trí
counter % 40
- Nạp Observable Plot để vẽ mảng số thành biểu đồ đường và hiển thị một đường quy tắc dọc tại vị trí
Mở rộng đầu ra tài liệu và trực quan hóa
- Ô có thể trả về bất kỳ phần tử DOM nào
- Các bản demo TeX, Markdown và Graphviz lần lượt trả về các dạng phần tử khác nhau
- Ô
textrả về phần tửspan - Ô
mdtrả về phần tửtable - Ô
dottrả về phần tửsvg
- Ô
- Ô có thể trả về
Promisehoặc némError- Observable
Inspectoráp dụng lớpobservablehq--runningchodivbên ngoài ô đang chạy - Áp dụng lớp
observablehq--errorcho ô lỗi - Tài liệu định kiểu theo các trạng thái này
- Observable
SQLite, Python và R trong trình duyệt
- Bản demo SQLite đưa cơ sở dữ liệu mẫu Chinook lên
https://maxbo.me/chinook.dbvà truy vấn bằng SQLite client dựa trên WASM- Có thể thử thêm
WHERE Milliseconds < 1000000vào truy vấn SQL
- Có thể thử thêm
- Bản demo Python dùng bản phân phối CPython WASM Pyodide
- Pyodide bao gồm NumPy, Pandas, Matplotlib, scikit-learn và Scipy
- Tái tạo biểu đồ đã tạo trước đó bằng Matplotlib và module Python
sqlite3
- Bản demo R dùng WebR
Đầu vào và trạng thái biến đổi
- Kiểu ô
viewofđược tạo để dùng cùng Observable Inputs viewofkhai báo hai ô phản ứngNAME: giá trị của inputviewof NAME: chính phần tử DOM
- Để hiển thị input phía trên ô, đặt
idcủa ô thànhviewof NAME - Trong ví dụ, tạo range input bằng
Inputs.range([0, 100], { step: 1 }), và ôrangePlotđược cập nhật theo giá trị đó - Cách hoạt động của Observable Inputs khá khó hiểu; bản demo Synchronized Inputs có thể hữu ích
- Với những trường hợp chỉ dùng luồng dữ liệu thuần hàm là chưa đủ, một helper
mutablecũng được tạomutableđăng ký một đối tượngMutablephát ra giá trị mới khi giá trị thay đổi
Công bố thư viện và slide thuyết trình
- Ban đầu phần triển khai này được cân nhắc đặt tên là
incel, nhưng sau đó định gọi làceline - Thư viện được công bố dưới tên @celine/celine
- Tài liệu này đã được demo tại SydJS
- Cũng có mã để biến tài liệu thành slideshow
Shift+N: bắt đầu slideshow hoặc chuyển sang slide tiếp theoShift+B: quay lại slide trướcShift+E: kết thúc slideshow
- Mã nguồn triển khai được công bố tại source code
1 bình luận
Ý kiến trên Hacker News
Tôi rất đồng ý với tiền đề của bài viết. HTML có thể là một nền tảng tuyệt vời cho notebook tính toán
Tuy nhiên, tôi không thích các lựa chọn triển khai ở đây. HTML động, phản ứng có thể được làm theo cách khai báo hơn thế này rất nhiều, và Observable tuy rất hay nhưng có phần đi lệch khỏi JavaScript chuẩn
Tôi đã bắt đầu xây dựng một hệ thống HTML phản ứng tên là Heximal, sau này cũng dự định bổ sung hỗ trợ notebook. Đây là một hệ thống khai báo dựa trên mẫu HTML và phần tử tùy chỉnh, bên trên là hệ thống biểu thức/phản ứng dựa trên đề xuất TC39 Signals
https://github.com/elematic/heximal
Nó gần giống như sự pha trộn giữa HTMX, Tangle, Curvenote và Polymer; nếu HTML vốn dĩ đã phản ứng từ đầu thì có lẽ nó sẽ trông như thế này. Tôi nghĩ nó khá phù hợp với các trường hợp sử dụng chỉnh sửa đồ họa và notebook
Vì vậy các biểu thức debug JavaScript thông thường hoạt động đúng trong Observablehq
https://github.com/observablehq/parser
Vì thích runtime của Observable, tôi còn làm cả một decompiler có thể chuyển đổi hai chiều giữa mã nguồn frontend và biểu diễn JS thuần đã biên dịch
https://observablehq.com/@tomlarkworthy/observablejs-toolcha...
Thật sự rất tuyệt. Tôi đặc biệt thích demo Python và SQLite. Việc bắt đầu từ vòng lặp chỉnh sửa qua web (TTW) rồi gọi nó là quine khá thú vị; dù hợp lý, điểm yếu cốt lõi vẫn là tính bền vững dữ liệu
TiddlyWiki thực ra cũng làm gần như điều tương tự, nhưng việc lưu công việc là một vấn đề đau đầu. Vì để duy trì thứ gì đó lâu dài thì rốt cuộc vẫn cần một tiến trình server headless riêng
Khi muốn làm một thứ tương tự[0], cá nhân tôi bắt đầu từ tính bền vững, và điều đó dĩ nhiên có nghĩa là tệp. Đó là các tệp văn bản thuần có thể chỉnh sửa bằng editor dành cho lập trình viên và lưu/triển khai qua hệ thống tệp. Cách này tránh được vấn đề phải triển khai lại một editor cho lập trình viên ngay trong trình duyệt, vốn không hề dễ
Đổi lại sẽ phát sinh vấn đề phải viết một server nhanh, nhưng đó cũng là một bài toán khá thú vị[1]. Ở đây họ tránh vấn đề đó bằng cách dùng các section contenteditable cơ bản, nhưng đây là vấn đề lớn tiếp theo sau tính bền vững dữ liệu
Việc không thể export bên trong script nhúng cũng có vẻ là cùng một bức tường. Nếu không muốn làm lộn xộn đối tượng window toàn cục thì có tính năng như vậy sẽ tốt hơn, và trong trường hợp sử dụng của tôi, việc sinh mã cũng sẽ dễ hơn
0 - Literate Markdown: https://simpatico.io/lit.md
1 - Reflector, một server node nhỏ chuyển đổi, nén, cache markdown và vô hiệu hóa theo dõi tệp: https://simpatico.io/reflector
Tôi tôn trọng suy nghĩ và công sức đã bỏ ra, nhưng tính khả dụng của cách tiếp cận này thật tệ. Tôi không hiểu vì sao khi đang muốn làm phân tích dữ liệu khám phá lại còn phải bận tâm cả các yếu tố styling
Đây chính là lý do những công cụ như Jupyter Notebook hoạt động hiệu quả. Dù vậy, tôi đánh giá cao việc tác giả tò mò và hiện thực hóa các ý tưởng thay thế
Nó vẫn chưa đủ tốt như một nền tảng phân tích dữ liệu khám phá. Nó không có tính phản ứng tức thì của một trình biên tập mã web hoàn chỉnh như Observable Notebooks, cũng không phải Observable Framework cung cấp hot reload dựa trên theo dõi tệp. Kernel Jupyter mới cho Deno + VSCode cũng mang lại trải nghiệm khá mượt
Vì vậy, về tính khả dụng cho phân tích khám phá thì ừm… tôi đồng ý là tệ, nhưng tôi cho rằng tính khả dụng khi triển khai thì không tệ đến vậy. Thật ra là tốt. Vì nó chỉ là một tệp duy nhất. Khi muốn gửi biểu đồ và kết quả xử lý dữ liệu cho ai đó, bạn không cần duy trì một toolchain khổng lồ hay trả tiền cho dịch vụ bên thứ ba; chỉ cần thả một tệp HTML vào Slack hoặc host nó ở đâu đó
Nhờ sự linh hoạt trong việc styling kết quả phân tích, bạn cũng có thể xuất bản trong những môi trường mà phong cách trình bày quan trọng, như blog hoặc bài báo nghiên cứu
ivorythànhredkhiến tô sáng cú pháp thay đổi theo thời gian thực cho thấy điều đóTôi hiểu bối cảnh dẫn đến hướng này, nhưng thật tiếc là không thể dễ dàng nghịch thử các framework và thư viện JavaScript trong trình duyệt hơn nữa. Rốt cuộc nó cũng chỉ là JS, nên đáng ra phải có thể thử nghiệm nhanh trong một môi trường nhẹ. Cách tiếp cận này có thế mạnh ở điểm đó
Đây là một cách đưa trở lại khả năng vui đùa và thử nghiệm của HTML/JS. Tôi mong có nhiều thử nghiệm kiểu này hơn, thay vì TS, rollup, webpack
Bổ sung: đọc thêm một chút thì thấy họ đề xuất nó cho phân tích dữ liệu. Tôi nghĩ nó không hợp với mục đích đó
Tôi nghĩ các lựa chọn thay thế Jupyter Notebook không bị bỏ đi sau khi dùng có giá trị rất lớn. Trải nghiệm người dùng hiện tại thật sự tệ thì có thể cải thiện được. Vấn đề là cấu hình này có tốt hơn mớ hỗn độn JSON của Jupyter Notebook không; cá nhân tôi nghiêng về câu trả lời là có
Tác giả gốc của Lit gần đây đã rời Google, và theo tôi biết thì đang làm một thứ rất giống với cái này
https://github.com/elematic/heximal
Tôi thích hình thức của bài này. Nó bắt đầu từ tầng thấp nhất rồi xây dần lên thành một thứ thú vị. Không phải kiểu thổi phồng bằng cách gắn một đống dependency hay framework chỗ này chỗ kia
Nếu muốn theo dõi, có lẽ chỉ cần copy-paste các mảnh được đưa ra và hiểu từng bước chúng hoạt động thế nào. Nếu tôi viết thứ như thế này, chắc tôi sẽ dùng literate programming của org-mode rồi xuất ra HTML để làm bài blog
Tuy nhiên, tôi vẫn thấy khó hiểu về phông chữ có tô sáng cú pháp tích hợp
Gọi là HTML phản ứng nhưng gần như toàn bộ chẳng phải là JavaScript sao, hay tôi đang hiểu nhầm điều gì?
Ngoài trình duyệt ra thì không phụ thuộc vào phần mềm bên thứ ba, và giống như HTML, nó bền lâu, dễ mang đi và dễ dùng
Sắp tới tôi muốn thử hỗ trợ loại HTML notebook này trong Raku, hoặc dành cho Raku
Hiện tại “giải pháp notebook” của Raku dựa trên Jupyter hoặc Mathematica
Tôi không hiểu logic của việc dùng công nghệ web để làm phức tạp hóa quy trình này. Độ phức tạp được thêm vào giải quyết vấn đề gì? Ngược lại, nó có vẻ gần với việc làm quy trình chậm hơn và loại bỏ các tính năng cần thiết như tự động hoàn thành, snippet, extension
Hơn nữa, rất có thể người khác không quen với thiết lập này, nên việc cộng tác cũng khó hơn
Môi trường chỉ cần thiết lập một lần, rồi tiếp tục dùng, chỉ thêm các cải tiến nhỏ khi công nghệ thay đổi
Nếu là người dùng n/vim thì những thứ sau là đủ. 1- Khám phá dữ liệu: dùng https://github.com/untitled-ai/jupyter_ascending để kết nối văn bản với Jupyter Notebook. Vì dùng jupytext, có thể chỉnh sửa và chạy mã hiệu quả trong trình soạn thảo văn bản
2- Viết lách: có thể dùng https://github.com/lervag/vimtex cho LaTeX
Thêm tmux và tmuxp vào đó là có thể mở dự án ngay lập tức. Trong Emacs, có thể tạo một quy trình mượt mà bằng org mode[1][2] và/hoặc Auctex
[1] https://sqrtminusone.xyz/posts/2021-05-01-org-python/
[2] https://martibosch.github.io/jupyter-emacs-universe/
Tuy nhiên tôi không thích Python lắm, nên muốn dùng công cụ không lấy Python làm trung tâm. Vì vậy tôi mới nói đến Raku và Mathematica
Nhân tiện, cảm ơn vì đã giới thiệu https://github.com/imbue-ai/jupyter_ascending
Tôi phần lớn đồng ý với tiền đề của bài viết này, tức là HTML chưa được tận dụng đủ như một phương tiện phân phối cho viết lách khoa học
Có một số công việc gần đây của Will Crichton liên quan đến điều này
https://willcrichton.net/nota/
https://willcrichton.net/notes/portable-epubs/
Dạo này notebook quả là đang nóng. Chúng tôi cũng đã phát hành một phiên bản TypeScript notebook[1], nhưng đã chọn một hướng khá khác trong các đánh đổi
Vì muốn chạy mã node ở backend, chúng tôi không cố chạy trong môi trường trình duyệt, khác với cách của bài viết này hay Observable. Dù vậy, với nhiều ứng dụng, ý tưởng này có thể là lời giải tốt hơn
Xin dành lời khen cho tác giả
https://github.com/srcbookdev/srcbook