FunkcjeCennikDokumentacjaBlog
Pobierz mote
← Blog
Technika·14 lipca 2026·4 min czytania

Jak szybko renderować wzory matematyczne bez silnika przeglądarkowego

Wiele aplikacji nosi ze sobą cały silnik przeglądarki tylko po to, żeby wyświetlić jeden wzór. W mote ta droga była zamknięta, więc trzeba było znaleźć inną.

m
mote
Wzory w trybie czytania. Wzór liniowy wpleciony w zdanie i wyśrodkowany wzór blokowy poniżej pochodzą z tego samego silnika układu.
Wzory w trybie czytania. Wzór liniowy wpleciony w zdanie i wyśrodkowany wzór blokowy poniżej pochodzą z tego samego silnika układu.

W mote obowiązuje jedna bezwzględna zasada. Nie polegać na silniku przeglądarki.

Odkryliśmy to podczas tworzenia prototypu. W tego rodzaju aplikacji wbudowany silnik przeglądarki odpowiada za większość kosztów. Dlatego od początku postanowiliśmy z niego zrezygnować.

Problemem były wzory. Zwykle do przeglądarki dodaje się KaTeX albo MathJax i za ich pomocą wyświetla wzory. W mote nie mogliśmy skorzystać z tej metody.

Inne rozwiązania również nie pasowały. Gdy używa się własnego mechanizmu renderowania fontów, wygląd liter różni się od tego w pozostałych aplikacjach systemowych. A w mote postanowiliśmy rysować wszystkie znaki za pomocą mechanizmu tekstowego platformy.

Ostatecznie wybraliśmy najtrudniejszą drogę.

Układ tworzy mote, znaki rysuje platforma

Składnia wzorów opiera się na dobrze znanej konwencji. W zdaniu wzór otacza się jedną parą znaków dolara, a gdy ma być wydzielony — dwiema parami.

Bezpośrednio po znaku otwierającym ani przed znakiem zamykającym nie może być spacji. Dzięki temu kwoty takie jak $5 i $6 nie są błędnie rozpoznawane jako wzory. W Markdownie pisanym ręcznie takie drobne rozróżnienia są ważne.

Wyświetlanie wzorów podzieliliśmy na dwie części.

Rdzeń mote oblicza położenie znaków i linii. Same znaki rysuje mechanizm tekstowy każdej platformy.

W rdzeniu zawarliśmy uproszczone reguły składu TeX-a. Obejmują one cztery poziomy rozmiaru, tabelę odstępów między symbolami podzielonymi na osiem kategorii, położenie indeksów, ułamków i pierwiastków oraz nawiasy, które powiększają się odpowiednio do zawartości.

Rdzeń nie określa jednak rzeczywistego rozmiaru znaków. Ten sam znak ma różne wymiary w zależności od fontu i platformy. Kiedy rdzeń pyta: „Jak duży będzie ten znak narysowany w tym rozmiarze?”, platforma odpowiada. Na podstawie tej wartości rdzeń finalizuje układ, a platforma rysuje znaki i linie w wyznaczonych miejscach.

Dzięki temu nawet po dodaniu kolejnych platform trzeba zarządzać tylko jednym układem.

Również w edytorze tekst źródłowy pozostaje bez zmian. Nawet gdy w trybie podglądu na żywo widać wzór, jego bajty źródłowe nadal znajdują się w wierszu. W tym miejscu rezerwowane jest jedynie tyle przestrzeni, ile zajmuje wzór.

Dzięki temu karetka stoi dokładnie we właściwym miejscu, a kliknięty znak można precyzyjnie odnaleźć. W ten sposób przestrzegamy zasady, że można upiększyć ekran, ale nie wolno zmieniać pliku. Tryb czytania i PDF korzystają z tego samego układu.

Wiersz z karetką w trybie podglądu na żywo — wzór liniowy jest widoczny w oryginalnej postaci, a wzór blokowy poniżej jest wyświetlany jako złożony ułamek
Wiersz z karetką w trybie podglądu na żywo — wzór liniowy jest widoczny w oryginalnej postaci, a wzór blokowy poniżej jest wyświetlany jako złożony ułamek

Kursywy również nie tworzymy przez sztuczne pochylanie znaków. Używamy matematycznych znaków Unicode, aby wyświetlać prawdziwe glify matematyczne zawarte w foncie.

Nie ukrywamy wzorów, których nie rozumiemy

Gdy wzór po cichu wyświetla się błędnie, trudno to zauważyć.

Jeśli nieobsługiwane polecenie zostanie pokazane jako puste miejsce, użytkownik nie wie, czy popełnił literówkę, czy natrafił na ograniczenie aplikacji. Dlatego mote pokazuje nieznane polecenia na czerwono, zachowując ich oryginalne nazwy.

Aplikacja nie zatrzymuje się również wtedy, gdy nawiasy są niedopasowane. Takie dane wejściowe zachowujemy jako testy, aby ten sam problem się nie powtórzył.

Przestrzegamy także zasad dotyczących wydajności. Dla każdej kombinacji wzoru i rozmiaru tekstu przechowujemy maksymalnie 512 wyników obliczeń. Podczas pisania ten sam wzór nie jest obliczany wielokrotnie, a gdy użytkownik niczego nie robi, nie są uruchamiane żadne zadania.

Podczas eksportu do HTML używamy MathML. Ponieważ przeglądarka sama wyświetla wzory, skrypty nie są potrzebne. Wzory są widoczne bez zmian nawet bez dostępu do internetu.

Są też rzeczy, których jeszcze nie można zrobić

Mote nie obsługuje całego TeX-a.

Polecenia definiowane przez użytkownika, określanie kolorów, numerowanie wzorów, wielowierszowe indeksy, symbole nad znakami oraz tekst nad strzałkami nie są jeszcze obsługiwane.

Nie ma też akcentów rozciągających się do szerokości zawartości. Szeroki daszek wygląda tak samo jak wąski. Duże symbole sumy i całki są wyświetlane przez powiększenie ich 1,45 raza zamiast użycia dedykowanych glifów. Nawiasy, które powinny rozciągać się wyłącznie w pionie, powiększają się jednocześnie w poziomie i w pionie.

Ułamki liniowe są wyświetlane w pomniejszeniu, tak jak w TeX-u. Aby wyglądały na większe, trzeba wskazać to osobnym poleceniem.

Nie będziemy mówić o tych funkcjach tak, jakby już istniały. Gdy pojawią się odpowiednie potrzeby, będziemy dodawać je pojedynczo.

Nie zmieniliśmy struktury kosztów całej aplikacji z powodu jednego wzoru. Zmieniliśmy za to sposób wyświetlania wzorów.

To była trudniejsza droga, ale wierzymy, że można nią podążać przez długi czas.

← StarszeUstaliliśmy reguły klawisza Enter, aby akapity wyglądały tak samo także w innych narzędziachNowsze →0.9.0-beta.1 — co zawiera pierwsza publiczna beta
Bądź na bieżąco przez RSS.
Nic poza pisaniem.
Polski
© 2026 mote