MathJax icon indicating copy to clipboard operation
MathJax copied to clipboard

Support for \hline and \cline in Arrays (\begin{array})

Open WizardMeow opened this issue 1 month ago • 1 comments

Is your feature request related to a problem? Please describe. I am looking to implement support for array/matrix commands like \cline{i-j} and &&\hline within MathJax, as they are currently unsupported, which hinders the rendering of structures like long division and matrices requiring partial horizontal separation.

\[
	\begin{array}{l}
		  &       &   & 6 & 8 \\
		  &       &    \hline
		8 & \big) & 5 & 4 & 4 \\
		  &       & 4 & 8 &   \\
		  &        \hline
		  &       &   & 6 & 4 \\
		  &       &   & 6 & 4 \\
		  &       &   &    \hline
		  &       &   &   & 0
	\end{array}
\]

Describe the solution you'd like I intend to add support for these commands. I believe that since MathJax already uses SVG output for \mtable , it should be technically feasible to draw the necessary horizontal lines (with appropriate starting positions, lengths, and heights) directly onto the existing SVG structure based on the parsed commands.

I would greatly appreciate any suggestions from the core developers on how to implement this.

Describe alternatives you've considered

Additional context Alternatively, if full implementation is not immediately feasible, what is the best way to handle these commands so they gracefully degrade to a full-row \hline ? This would ensure the array structure is not corrupted, even if the line rendering is technically incorrect.

WizardMeow avatar Nov 20 '25 11:11 WizardMeow

Your LaTeX example is invalid (in actual LaTeX) for two reasons: (1) you don't have enough entries in the template for the number of columns in your array, and (2) \hline must be at the beginning of a row, not the middle (it is usually used following \` as in

\begin{array}{lllll}
    &       &   & 6 & 8 \\ \hline
  8 & \big) & 5 & 4 & 4 \\
    &       & 4 & 8 &   \\ \hline
    &       &   & 6 & 4 \\
    &       &   & 6 & 4 \\ \hline
    &       &   &   & 0
\end{array}

which produces

Image

though that is still not what you want. I don't think that arrays, even with \cline, is the way to handle division layouts.

An approach that you can use with MathJax as it currently stands is the following:

\require{enclose}
\begin{array}{r}
   68\\[-3pt]
 8 \enclose{longdiv}{544}\kern-.5ex \\[-3pt]
    \underline{48\phantom{0}} \\[-3pt]
    64 \\[-3pt]
    \underline{\phantom{00}8} \\[-3pt]
    0
\end{array}

which produces

Image

If you want more space between the digits, you can do that with something like:

\require{enclose}
\begin{array}{r}
   6\;8\\[-3pt]
 8 \;\enclose{longdiv}{\;5\;4\;4}\kern-.5ex \\[-3pt]
    \underline{\;4\;8\phantom{\;0}\,\strut}\! \\[-1pt]
    6\;4 \\[-3pt]
    \underline{\phantom{0\;0\;}8\,\strut}\! \\[-1pt]
    0
\end{array}

which produces

Image

One could, of course, implement code to simplify the layout.

Some simple-minded definitions to do this are the following:

\require{enclose}

\def\div#1/#2=#3
{#3\\[-3pt]#2\enclose{longdiv}{#1}\kern-.5ex\\[-3pt]}
\def\by#1:#2:#3|#4:#5
{\underline{\phantom{#1}#2\phantom{#3}}\\[-3pt]#4\phantom{#5}\\[-3pt]}

\newenvironment{division}[1]{\begin{array}{r}\div#1
}{\end{array}}

Note that the newlines are important in these definitions. With these, you can do your division as

\begin{division}
{544 / 48 = 68}
\by :48:0 | 64:
\by 00:8: |  0:
\end{division}

A longer example is

\begin{division}
{500 / 4 = 125}
\by :4:00 | 10:0
\by 0:8:0 |  20:
\by 0:20: |   0:
\end{division}

producing

Image

The thing to note is the arguments to the \by command. The colons separate the first number into three pieces: the first is a phantom that goes before the number shown (in order to have the division line be wide enough), the second is the number to show, and the third is the phantom to the right of the number, moving it into the proper position from the right. Similarly, the second number has a colon that separates the shown number from the phantom digits that position it from the right.

If you want the wider spacing, that is possible, but takes a bit more care, since you need to insert the spacing in between each digit. That requires a bit of ingenuity, as MathJax doesn't have LaTeX's low-level looping structures. Here is one approach:

\require{enclose}

\def\div#1/#2=#3
{\addSpaces{#3}\\[-3pt]\addSpaces{#2}\enclose{longdiv}{\,\addSpaces{#1}\kern-.4ex}\\[-3pt]}
\def\by#1:#2:#3|#4:#5
{\underline{\strut\;\phantom{\addSpaces{#1}}\addSpaces{#2}\phantom{\addSpaces{#3}}}\\[-1pt]
\addSpaces{#4}\phantom{\addSpaces{#5}}\\[-3pt]}
\def\addSpaces#1{\recursiveSpaces#1:\addSpace:\skipSpace}
\def\recursiveSpaces#1#2:#3{#3#1#2:#3}
\def\addSpace#1{#1\;\recursiveSpaces}
\def\skipSpace#1\skipSpace{}

\newenvironment{division}[1]{\begin{array}{r}\div#1
}{\end{array}}

so that

\begin{division}
{500 / 4 = 125}
\by :4:00 | 10:0
\by 0:8:0 |  20:
\by 0:20: |   0:
\end{division}

now produces

Image

In terms of implementing \cline, that could be done, but not in the way you are suggesting. The MathJax input processors don't know what output processor is in use, and doesn't know about the size of any of the output sub-expressions. The input processors translate their input format in an internal MathML representation, so the TeX input processor converts LaTeX to MathML (not to actual SVG output). So an implementation of \cline would not produce lines itself, but would add the appropriate MathML attributes or tags that would produce the needed lines when the output is produced.

Unfortunately, the MathML specification doesn't have a simple means of doing this, as the rowlines attribute on the mtable element only handles full-width lines, not partial lines. The mechanism that would have to be used for partial lines would be to add border-bottom CSS styles via the styles attribute on the individual mtd elements that are part of the \cline.

That is possible to do, but would take a bit of care and some modifications to the internal classes that handle tables. That would take some study of the MathJax MathML structures and the TeX input jax processor.

I did some testing to see how well this would work, and it turns out that the handling of borders on the SVG mtd elements is broken, and would not produce the results you are looking for (the CHTML version is better, but still has some issues). I'm looking into fixing the display problems in both output formats, but it requires some significant changes and I'm not sure when that will be included in a formal release.

dpvc avatar Nov 21 '25 19:11 dpvc