MathJax - przewodnik dla początkujących
Jeżeli tworzysz stronę internetową dotyczącą matematyki, fizyki, statystyki, uczenia maszynowego lub edukacji, prędzej czy później pojawi się problem wyświetlania wzorów matematycznych. Można oczywiście przygotować równania jako obrazki PNG lub SVG, ale takie rozwiązanie ma wiele wad:
- wzory nie skalują się dobrze,
- są trudniejsze do edycji,
- wyszukiwarki nie rozumieją ich treści,
- kopiowanie wzorów przez użytkownika jest praktycznie niemożliwe.
Jak działa MathJax?
Załóżmy, że w treści strony wpiszemy:$p = m \cdot v$Dla przeglądarki jest to zwykły tekst. Po załadowaniu strony MathJax wyszukuje takie fragmenty i zamienia je na estetyczne równania matematyczne. Użytkownik końcowy nie zobaczy więc:
p = m \cdot vlecz poprawnie sformatowany wzór.
Krok 1 – Dodanie MathJax do strony
Najprostszy sposób to użycie CDN. W sekcji head umieszczamy:
<script>
window.MathJax = {
tex: {
inlineMath: [['$', '$']],
displayMath: [['$$', '$$']]
}
};
</script>
<script
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
Najpierw mamy konfigurację a później skrypt mathjax z cdn. Konfiguracja musi zostać załadowana przed skryptem MathJax.
Jeżeli odwrócimy kolejność, biblioteka uruchomi się zanim pozna nasze ustawienia.
Zmiana separatorów wzorów
Domyślnie użuwany jest znak dolara ($) oraz podwójnego dolara ($$) ale można zdefiniować też własne znaczniki. Na przykład:
<script>
window.MathJax = {
tex: {
inlineMath: [
['\\(', '\\)']
],
displayMath: [
['\\[', '\\]']
]
}
};
</script>
Teraz wzór inline zapisujemy jako:
\( x^2 + y^2 \)natomiast blokowy:
\[ x^2 + y^2 \]
Automatyczne łamanie długich wzorów
Przy bardzo rozbudowanych równaniach możemy włączyć automatyczne zawijanie.
window.MathJax = {
svg: {
linebreaks: {
automatic: true
}
}
};
Jest to szczególnie przydatne na urządzeniach mobilnych.
Pierwszy działający przykład
Utwórzmy najprostszy przykład.
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<script>
window.MathJax = {
tex: {
inlineMath: [['$', '$']],
displayMath: [['$$', '$$']]
}
};
</script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
</head>
<body>
<h1>Mój pierwszy wzór</h1>
<p>
Twierdzenie Pitagorasa:
$a^2+b^2=c^2$
</p>
</body>
</html>
Po otwarciu strony wzór zostanie automatycznie wyrenderowany. [math]a^2+b^2=c^2[/math]
Wzory inline i wzory blokowe
To jedna z pierwszych rzeczy, które należy zrozumieć.Wzory inline
Inline oznacza "w linii tekstu". Zobacz poniższy przykład:<p> Pole koła wynosi $P=\pi r^2$ i zależy od promienia. </p>Wynik: Pole koła wynosi [math]P=\pi r^2[/math] i zależy od promienia.
Wzory blokowe
Jeżeli równanie ma być wyeksponowane, używamy podwójnych znaków $.$$ P=\pi r^2 $$Wzór zostanie wyśrodkowany w osobnym wierszu. Tak zapisuje się większość równań w artykułach naukowych.
Potęgi i indeksy
Potęga jest zapisywana za pomocą znaku ^.x^2Daje:
x²Większe wyrażenia należy otoczyć nawiasami klamrowymi:
x^{10}
Przykład:
$$
x^{10}+y^{10}
$$
Po wyrenderowaniu: [mathb]x^{10}+y^{10}[/mathb]
Do indeksów dolnych używamy znaku _.
x_1Przykład:
$$ x_1+x_2+x_3 $$Po wyrenderowaniu: [mathb]x_1+x_2+x_3[/mathb]
Ułamki
Jedną z najczęściej używanych komend jest \frac. Składnia:
\frac{licznik}{mianownik}
Przykład:
$$
\frac{a+b}{c+d}
$$
Bardziej zaawansowany przykład:
$$
\frac{x^2+2x+1}{x+1}
$$
Co dostaniemy:
[mathb]\frac{x^2+2x+1}{x+1}[/mathb]
Pierwiastki
Pierwiastek kwadratowy:
$$
\sqrt{x}
$$
Pierwiastek stopnia n:
$$
\sqrt[3]{x}
$$
Co otrzymamy: [math]\sqrt[3]{x}[/math]
Symbole greckie
W matematyce i fizyce używa się wielu liter greckich.\alpha \beta \gamma \delta \lambda \omega \piPrzykład:
$$ \alpha+\beta=\gamma $$Otrzymamy: [math]\alpha+\beta=\gamma[/math]
Sumy
Do zapisu sum służy komenda \sum.
$$
\sum_{i=1}^{n} i
$$
Wynik oznacza sumę wszystkich liczb od 1 do n. [mathb]\sum_{i=1}^{n} i[/mathb]
Całki
Przykład całki oznaczonej:$$ \int_0^1 x^2 dx $$Otrzymamy: [math]\int_0^1 x^2 dx[/math]
Macierze
MathJax obsługuje również macierze.
$$
\begin{bmatrix}
1 & 2 \\
3 & 4
\end{bmatrix}
$$
Wynik: [mathb]\begin{bmatrix}
1 & 2 \\
3 & 4
\end{bmatrix}[/mathb]
Znaczenie symboli:
- & oddziela kolumny
- \\ przechodzi do nowego wiersza
Równania wielowierszowe
$$
\begin{align}
a+b &= c \\
x+y &= z
\end{align}
$$
Operator & określa miejsce wyrównania.
Dzięki temu znaki równości tworzą jedną pionową linię.
Tak to wygląda w praktyce:
[mathb]\begin{align}
a+b &= c \\
x+y &= z
\end{align}[/mathb]
Dynamiczne dodawanie wzorów JavaScript
To funkcja szczególnie przydatna podczas budowy kalkulatorów i aplikacji edukacyjnych. Załóżmy, że mamy div, który dynamicznie modyfikujemy za pomocą javascriptu jakimś wzorem matematycznym.<div id="formula"></div>
document.getElementById("formula").innerHTML =
"$$E=mc^2$$";
MathJax.typeset();
Metoda MathJax.typeset() informuje bibliotekę, że pojawiły się nowe wzory i należy je przeliczyć.
Generowanie wzorów z formularzy
Jedną z ciekawszych funkcji MathJax jest możliwość generowania wzorów wpisywanych przez użytkownika. Załóżmy, że budujemy aplikację edukacyjną. Użytkownik wpisuje:
\frac{a+b}{c+d}
a strona natychmiast pokazuje wyrenderowany wynik. Zróbmy najprostszy przykład. To jest kod html:
<input id="formula"
value="\frac{a+b}{c+d}">
<div id="preview"></div>
a to JavaScript:
const input = document.getElementById("formula");
const preview = document.getElementById("preview");
function updateFormula() {
preview.innerHTML =
"$$" + input.value + "$$";
MathJax.typesetPromise([preview]);
}
input.addEventListener(
"input",
updateFormula
);
updateFormula();
Za każdym razem gdy użytkownik wpisze nowy tekst, wzór zostanie przerysowany. Warto zwrócić uwagę na użytą w przykładzie funkcję
MathJax.typesetPromise(). W Mathjax spotykamy dwie funkcje MathJax.typeset() oraz MathJax.typesetPromise().
Pierwsza działa synchronicznie. Druga zwraca Promise i jest zalecana w nowych projektach. Pozwala uniknąć problemów przy dużej liczbie wzorów.
Projekt końcowy - edytor równań z podglądem na żywo
Teraz wykorzystamy wszystkie poznane informacje do stworzenia mini aplikacji. Projekt będzie działał podobnie do internetowych edytorów LaTeX. Użytkownik wpisuje kod LaTex a na stronie natychmiast widzi wyrenderowany wynik. Pełny kod projektu:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Edytor równań MathJax</title>
<style>
body{
margin:0;
font-family:Arial;
height:100vh;
display:flex;
flex-direction:column;
}
header{
background:#222;
color:white;
padding:15px;
}
main{
flex:1;
display:flex;
}
#editor{
width:50%;
padding:20px;
border-right:1px solid #ddd;
box-sizing:border-box;
}
#preview{
width:50%;
padding:20px;
box-sizing:border-box;
overflow:auto;
}
textarea{
width:100%;
height:400px;
font-size:18px;
font-family:monospace;
}
button{
margin:5px;
padding:10px;
}
</style>
<script>
window.MathJax = {
tex: {
inlineMath: [['$', '$']],
displayMath: [['$$', '$$']]
}
};
</script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
</head>
<body>
<header>
<h1>Internetowy Edytor Równań</h1>
</header>
<main>
<div id="editor">
<h2>LaTeX</h2>
<textarea id="input">
\frac{a+b}{c+d}
</textarea>
<br>
<button onclick="insert('\\sqrt{x}')">
Pierwiastek
</button>
<button onclick="insert('\\frac{a}{b}')">
Ułamek
</button>
<button onclick="insert('\\int_0^1 x^2 dx')">
Całka
</button>
<button onclick="insert('\\sum_{i=1}^{n} i')">
Suma
</button>
</div>
<div id="preview"></div>
</main>
<script>
const input =
document.getElementById("input");
const preview =
document.getElementById("preview");
function render(){
preview.innerHTML =
"$$" + input.value + "$$";
MathJax.typesetPromise([preview]);
}
function insert(text){
input.value += text;
render();
}
input.addEventListener(
"input",
render
);
render();
</script>
</body>
</html>
Zobacz działanie edytora równań na żywo.