During COVID I wrote up some math notes in HTML taking full advantage of the wide screen format of modern desktop systems to display large formulae. However now that I am back to commuting by train, it would be nice to display those notes on my mobile phone. The desktop mode of the original HTML does a poor job at displaying on such a device. Therefore I have designed and implemented a javascript preprocessor which converts $\TeX$ code into responsive HTML.
There are some obvious things that can be done to improve the display of math on small touch screens. From most desirable to least
- Text flow inline math, as has been done by KaTeX and MathJax4.
- Reduce margin and gutter sizes to allow more space for the text.
- Provide user with precise, fine grain control of the font size for the web site, and save it as a permanent setting on the device.
- Add horizontal scrolling to elements which are too wide to fit the viewport.
- Rewrite the math into a more compact format. For example replace $x_1+x_2+x_3$ with $\sum x_i$.
- Author multiple versions of each formula. For example a narrow and wide form, then switch between them based on device or viewport width.
However those things are not always enough for display equations. This is where the preprocessor comes in.
Preprocessor
The preprocessor converts TeX code to responsive HTML code. These are the steps in the process:
-
Author manually edits the TeX code to remove flow-unfriendly features that mess things up, in particular
-
remove outer level environment blocks like
\begin{equation}
-
replace paired
\left(
and\right)
brackets, which prevent splitting, with their explicitly sized alternatives, for example\big(
and\big)
-
remove most artificial spacing like
\quad
because it tends compromise the new layout - finally add a line indicating which flow algorithm to use
-
remove outer level environment blocks like
-
Preprocessor breaks the input TeX code into "lines" and "words" based on the flow algorithm.
This step is done with a heuristic algorithm which works well about 90% of the time.
To handle difficult cases, it can be assisted by the author inserting explicit
$
signs to mark word breaks and$$
signs to mark line breaks. - Preprocessor then converts each "word" into a standalone piece of TeX code. This step has some complications because when TeX code is split into pieces and run through a TeX to HTML layout engine the sum of the parts is not strictly equal to the whole. Those differences need to be taken into account to restore the correct visual appearance.
-
Preprocessor then inserts the pieces of TeX code into standard HTML templates for the specific flow algorithm.
These templates are made up of
flex
box andgrid
HTML elements, suitably styled with CSS rules. This step uses several new baseline responsive CSS features added to WWW Standards between 2019 and 2024. - The final HTML is then rendered using one of the standard TeX to HTML layout engines.
Algorithms
flow
The flow algorithm is very similar to normal text flow and is most suitable for homogenous text like polynomials. The left parameter tells the algorithm to break just before plus and minus signs (normally it breaks just after). The indent parameter tells the algorithm to indent lines after the first to the level of the first equals sign.
#flow,left,indent
\Delta = 256a^3e^3 - 192a^2bde^2 - 128a^2c^2e^2 + 144a^2cd^2e - 27a^2d^4 + 144ab^2ce^2 - 6ab^2d^2e - 80abc^2de
+ 18abcd^3 + 16ac^4e - 4ac^3d^2 - 27b^4e^2 + 18b^3cde - 4b^3d^3 - 4b^2c^3e + b^2c^2d^2
This is the above code rendered with an equation label.
To see the math respond to screen size change on a mobile device, rotate the device to switch between portrait and landscape mode.
fold
The fold algorithm is a text flow algorithm in which the line breaks occur at predetermined positions and in a predetermined order. It is better for inhomogenous text like matrices and integrals. For a large equation which won't fit on one line it usually looks best to do the first break after the top level equals sign. Then if needed, another break around the middle of what's remaining.
#fold
\begin{vmatrix}
1 & x_1 & x_1^3 & x_1^4 \\
1 & x_2 & x_2^3 & x_2^4 \\
1 & x_3 & x_3^3 & x_3^4 \\
1 & x_4 & x_4^3 & x_4^4 \\
\end{vmatrix} = $
\big(x_1x_2 + x_1x_3 + x_1x_4 + x_2x_3 + $
x_2x_4 + x_3x_4\big) \cdot \prod_{i\lt j} (x_j-x_i)
This is the above code rendered with an equation label.
stack
A stack is a set of equations which can be written on one line separated by comma's if there is room. Otherwise they can be stacked and aligned vertically at the equals signs. The width parameter is the container width which trigger's the transition from horizontal to vertical format.
#stack,width=500
x_3 = a \cdot \frac {x_1y_1 + x_2y_2} {x_1x_2 + y_1y_2}
y_3 = a \cdot \frac {x_1y_1 - x_2y_2} {x_1y_2 - x_2y_1}
This is the above code rendered with an equation label.
train
A train is a list of expressions coupled together with equals signs. On a wide screen they look good written on one line, but on a narrow screen they look better written as a vertical stack with the equals signs vertically aligned. The width parameter is the container width which trigger's the transition from horizontal to vertical format.
#train,width=700
g_2
= -4(\epsilon_1\epsilon_2 + \epsilon_2\epsilon_3 + \epsilon_3\epsilon_1)
= \tfrac {1} {24} (A^2 + B^2 + C^2)
= \tfrac {1} {12} (12ae - 3bd + c^2)
This is the above code rendered with an equation label.
Where To Next?
The above set of algorithms are a good starting point for implementing responsive layout features in a LaTeX to HTML javascript library. Implementing natively would have the following advantages
-
Most issues caused by breaking the TeX code into small pieces should vanish.
-
For example splitting
\left(
and\right)
pairs should be easy. - Inconsistent spacing around breaks should be easily eliminated.
-
For example splitting
- The algorithm for automatically choosing break points should work better because it would have more context to work with.
- More complex responsive structures could be created by nesting combinations of the basic algorithms.
- Performance should also be slightly better.