feature request: align / align* support #61

Open
Pomax opened this Issue Sep 16, 2014 · 46 comments

Projects

None yet
@Pomax
Pomax commented Sep 16, 2014

for the simple reason that it's one of the most used environments (along with matrix and array) =)

@kevinbarabash
Contributor

I was doing some preliminary investigation into how this works in LaTeX and \begin{align} ... \end{align} is not allowed in math mode, only in paragraph mode. The problem is that we're in math mode by default.
Should we allow people to write things like 1 + \begin{align} ... \align{end}? What would that look like? Some possible solutions to this conundrum:

  • restriction how certain environments are used
    • e.g. if we recognize the align or equation environments then there can't be any math before or after them
  • start out in paragraph mode and requiring people to use $..$ or $$..$$ or \[..\] etc.
    • not ideal because it changes current behaviour which is nice because it's simple
    • also, having a paragraph mode opens a can of worms
@Pomax
Pomax commented Sep 28, 2014

on a (Xe)(La)TeX note, using align in running math mode would be curious, since the point of the align/align* environments is to set up a (by definition multi-line) box, so it shouldn't be usable inline. Requiring the $$...$$ or \[...\] to force a block would be quite sensible.

@episodeyang

@kevinb7, as soon as this is implemented, I am going to switch from MathJax to KaTeX!

@episodeyang

@kevinb7 ,
How is this feature going? haha I have been coming back here to check everyday for a week now:)

@jmeas
Contributor
jmeas commented Nov 19, 2014

How is this feature going? haha I have been coming back here to check everyday for a week now:)

fyi @episodeyang you can subscribe to the issue to get notifications sent to your email instead of manually checking all of the time. The button is in the right sidebar.

@kevinbarabash
Contributor

@episodeyang Sorry for the delayed reply. I haven't done any implementation work on this yet. I just did some investigating to see how difficult/easy it would be to implement this feature.

@episodeyang

I see, thanks for the reply! @jmeas I do get the notifications, but because I get emails from a lot of repos, I ended up just keeping this tab open.
@kevinb7 This feature is very much needed :)

@SirVer
SirVer commented Mar 15, 2015

+1. I am missing this feature too, otherwise KaTex works amazingly well.

@xymostech xymostech added a commit to xymostech/KaTeX that referenced this issue Jun 12, 2015
@xymostech xymostech Add environments (\begin/\end)
Summary:
Add basic support for some environments in KaTeX. To create
multiple columns of objects, we simply stack vlists next to each other,
and then manually manage the vertical alignment ourselves.

So far, this only supports `matrix` (to an artibrary size, where real
LaTeX only supports 10 columns!), and the `align*` environment with only
two columns in it. Support for more environments shouldn't be terribly
hard with this basic structure though.

Fixes #43
Partially fixes #61
Ping #206

Test Plan:
 - `make test`
 - Make sure screenshots look good

Reviewers: kevinb, alpert

Differential Revision: https://phabricator.khanacademy.org/D17235
422c77b
@gagern
Collaborator
gagern commented Jun 19, 2015

Since #246 got merged, we have support for environments, and with array and matrix environments also some experience on how to do this kind of alignment. So the main task here, the way I see it, is working out all the spacing rules. How does LaTeX typeset align*? How much space is there between rows? How much gap between columns? I guess the latter might be some \hfill, at least between pairs of columns, but is there some minimum or default? Where in the TeX, LaTeX or amsmath sources can all of these settings be found? Once we have the dimensions, implementing them should be easy.

@kevinbarabash
Contributor

I found this in amstex.sty:

\newenvironment{aligned}{%
  \relax\ifmmode\else\nonmatherr@{\begin{aligned}}\fi
  \null\,\new@ifnextchar[{\aligned@}{\aligned@[c]}%
}{%
  \crcr\egroup\egroup
}
\def\aligned@[#1]{%
  \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi
  \bgroup
   \Let@\restore@math@cr
   \default@tag
   \ifinany@\else\openup\jot\fi
   \ialign\bgroup\hfil\strut@$\m@th\displaystyle{##}$&%
    $\m@th\displaystyle{{}##}$\hfil\crcr}

In "TeX for the Impatient" it states the following:

\ialign
This command behaves just like \halign, except that it first sets the \tabskip glue to zero and sets \everycr empty.

I take that to mean that there is no space between the columns or rows.

@Pomax
Pomax commented Jun 19, 2015

Note that that is not align/align*, but aligned. in the same tex/latex/abs/math/amstex.sty there is also

\def\align{\ifingather@
  {\ifnum0=`}\fi
  \DN@{\@nameuse{align (in \string\gather)}}%
  \else \ifmmode\nomath@env
    \DN@{\let\endalign\relax\@gobble}\else
  $$\stepcounter{equation}%
  \st@rredfalse\let\next@\align@\fi\fi
 \collect@body\next@}
\@namedef{align*}{\ifingather@
  {\ifnum0=`}\fi
  \DN@{\@nameuse{align* (in \string\gather)}}\else
   \ifmmode\nomath@env
    \DN@{\@namedef{endalign*}{}\@gobble}\else
   $$\st@rredtrue
  \let\next@\align@\fi\fi
 \collect@body\next@}

which are then unfortunately followed by a rather long and detailed alignment implementation

@gagern
Collaborator
gagern commented Jun 19, 2015

I found this in amstex.sty … I take that to mean that there is no space between the columns or rows.

OK, so there is no gap between rows or columns as far as \halign is concerned. But the {}## inserts an empty group at the beginning of the left-aligned columns, while the \strut@ will probably ensure some minimal row height and depth. Regarding the latter I read

\def\strut@{\copy\strutbox@}
\addto@hook\every@math@size{%
  \global\setbox\strutbox@\hbox{\lower.5\normallineskiplimit
         \vbox{\kern-\normallineskiplimit\copy\strutbox}}}

The \strutbox should be the same I referenced for arrays. In that case it has a height of 0.7\baselineskip and a depth of 0.3\baselineskip, as defined in ltfsstrc.dtx. The \vbox should shave the upper \normallineskiplimit off the top of the box, right? The \vbox aligns its bottom-most baseline with the surrounding baseline, but then it gets lowered by 0.5\nomallineskiplimit. So in effect we have the normal \strut but with 0.5\normallineskiplimit added to its depth and 1.5\normallineskiplimit removed from its top? This feels strange, I'd expect a symmetric change, 0.5\normallineskiplimit removed from either part. But TeX for the Impatient page 162 confirms:

For \vbox, the depth is the depth of its last item, if that item is a box or rule.

So yes, it agrees with my interpretation above. Fortunately, \normallineskiplimit appears to be 0pt by default (says ltplain.dtx) so we can probaböy forget all that manipulation, and treat \strut@ as a synonym for \strut.

@kevinbarabash
Contributor

I found this post on the tex stack exchange about the difference between aligned and align*. http://tex.stackexchange.com/questions/95402/what-is-the-difference-between-aligned-in-displayed-mode-and-starred-align

The basic difference AFAICT is that align* has extra vertical space. Maybe it would make sense to not include the extra vertical padding and let people handle that with their own CSS.

@Reflic
Reflic commented Jul 20, 2015

Whats the current position of implementing support for the align environment?

@kevinbarabash
Contributor

@Reflic environment support has been added so adding support for {align} is easier than it would've been in the past. If you're willing to take a stab it we'd love a pull request for this.

@RoyiAvital

Will you also include the numbering?

StackEdit made it work pretty well.
I think they use MathJax, so there is something to try imitate.

@gagern
Collaborator
gagern commented Sep 9, 2015

@RoyiAvital: I'd say equation numbers are a different issue, to be discussed in a separate ticket. We should avoid supporting the {align} environment before we have equation numbering, though.

@RoyiAvital

I see...

Well, I really hope you'll get there soon.

Thank You.

@xymostech
Member

@gagern In LaTeX, align and align* are only supported in paragraph (i.e. not math) mode, so the equation numbers in align work nicely and are aligned at the right side of the page. For display mode, we can do that reasonably, but how do we want to handle the numbers if we're in inline mode? MathJax just drops the equation numbers, but that doesn't seem correct...

@kevinbarabash
Contributor

We could add numbers in parens after the inline equations as suggested in http://tex.stackexchange.com/questions/78579/labelled-in-line-equation.

@gagern
Collaborator
gagern commented Sep 10, 2015

At least with LaTeX compatibility in mind, I'd say that the {align} and {align*} environments are only valid if they make up the whole body of the equation, and in this case the equation should be set in display mode. For inline mode, there is always {aligned}.

@kevinbarabash
Contributor

I've created a new issue for equation numbering: #350.

@Joe312341

+1 Align environment issue is the only thing keeping me from switching MathJax to Katex

@Pomax
Pomax commented Sep 17, 2015

landing this incrementally will be quote worth it, too. If equasion numbering comes "later", then simply having the general align environment available will benefit many people already.

@davidar davidar referenced this issue in davidar/TeX.js Oct 16, 2015
Closed

Replace MathJax with KaTeX #9

@pnsaevik

Should we allow people to write things like 1 + \begin{align} ... \align{end}?

Yes, I think we should, simply because it makes the implementation easier. The construct is not allowed in LaTeX, but that's no problem in my opinion.

If we allow the above construct, the implementation of \begin{align*} ... \end{align*} would basically be a copy-paste of the matrix environment -- just with right/left justification instead of centered justification, and without the extra space between columns.

@gagern
Collaborator
gagern commented Nov 20, 2015

I disagree: if we support this, we will be bound to support it forever. And it will be a real problem with equation numbering. If people do

\begin{align}a&=b\\c&=d\\e&=f\end{align}\qquad\begin{align}g&=h\\i&=j\end{align}

where would you place the equation numbers? Placing them in the right margin of the whole thing would be problematic, but for a plain {align} all by itself we might whish to place them in the margin one day, even if that's more difficult than using something matrix-like for now.

On the other hand, it would be fairly simple to mark environments which are only allowed at the outermost layer, and to verify that they are not preceded or followed by anything except possibly whitespace. I'd write this myself, except for the fact that I'm still waiting for a review on #386 (among others), which would make this even easier to express.

@Pomax
Pomax commented Nov 20, 2015

A simple guiding principle: "what does LaTeX do?". Run code you're unsure of through real LaTeX, see what it outputs, and then do the same in KaTeX: as an online LaTeX parser, that's what people will be expecting it to do.

@gagern
Collaborator
gagern commented Nov 20, 2015

@Pomax: well, this guiding principle kind of breaks down for LaTeX constructs which are meant to be started in text mode. People (in my experience) don't expect all of their HTML documents to suddenly follow LaTeX semantics. They do expect to delimit those portions which are meant for KaTeX in some way or other. And KaTeX traditionally starts out in math mode. Which means there is no clear analogon here. The alternatives are either to have some flag which tells KaTeX to start in text mode, or to deviate from exactly reproducing LaTeX behavior, and allow text mode constructs to span the top level of what would otherwise be considered a math environment.

@episodeyang

I'm trying to use this in a rich text editor as a component. I don't have
any issue with the comments above, but something might come up during the
implementation.

One of the potential problems is keeping track of equation numbering. When part of the document is updated, the new compiled math block with the updated equation should have the same equation number as the old version. We need a way to keep track of this and set it during compile.

@pnsaevik

@gagern, I see your point. Personally, I'd say equation numbering should be handled outside KaTeX, but MathJax and a lot of other people see it differently. But I like your idea of restricting certain environments to top-level.

MathJax handles this problem by starting out in text mode, which makes sense if one aims at being a more full-fledged LaTeX environment, with automatic equation numbering, figure numbering, bibliography etc. Personally, I'm fine with KaTeX being a lightweight, math-only rendering engine.

In the meantime, align* fills a very practical need, namely, the need for aligning consecutive equations. So if possible, I would vote for a temporary solution for align* (which may change in future releases), until the more fundamental question of equation numbering has been figured out ('cause this discussion is going to take time).

@RoyiAvital

From a user point of view, in the long run, equation numbering is a must.
You cannot let it somewhere in the background handle it since, in the case of array of equations, it can not be done.

Thank You.

@pnsaevik

@RoyiAvital, it's true that multi-line equation numbering would be hard to tackle by an outside script.. but it's certainly not trivial to implement within KaTeX!

If someone wants a KaTeX "hack" in the meantime, use

\begin{matrix} A + B & = & C \\ C & = & D + E \end{matrix}

which centers the columns and puts too much space around the equals sign, but it may work in some situations.

@pnsaevik

Regarding my previous comments: It turns out that what I'm really asking for is an implementation of LaTeX' aligned environment, http://tex.stackexchange.com/questions/95402/what-is-the-difference-between-aligned-in-displayed-mode-and-starred-align.

I guess this environment could be implemented fairly easily within the current KaTeX framework? And it may be sufficient for many users.

@gagern
Collaborator
gagern commented Nov 23, 2015

I've just created a branch https://github.com/gagern/KaTeX/tree/aligned which implements the aligned environment. Needs one visual test case and perhaps some parsing tests as well. And it will conflict with #386 which seems very close to being merged, so I won't post another pull request for aligned just now.

Note that we don't have rubber lengths in KaTeX. I fixed the column distance as one \qquad i.e. 2em, but that might be inappropriate in some environments. Is there a better suggestion?

@pnsaevik

Great! Precisely what I hoped for!

BTW, how do I "build" and test the code..? I've only used the katex.min.js and katex.min.css, which does not seem to be present in the directory tree.

@gagern
Collaborator
gagern commented Nov 23, 2015

Run make to get katex.min.js, or run npm install followed by node server.js to test it using a local development server.

@pnsaevik

I might give make a try, but I'm using a Windows computer and would have to install some additional software I guess. Perhaps another day!

@kevinbarabash
Contributor

@gagern awesome stuff!

@gagern
Collaborator
gagern commented Nov 23, 2015

I probably should have written this ages ago, seeing how many people seem to see this as the main missing feature of KaTeX.

@kevinbarabash, do you have an idea as to how much jasmine tests you'd like to see for this? The cases environment for example just has a single check, to see whether its input parses. Do we have any additional features of the aligned environment which we can test for at this level?

@kevinbarabash
Contributor

I think just that it parses is good enough for the jasmine tests. Having the image is more important.

@Pomax
Pomax commented Dec 29, 2015

Awesome work @gagern! Any idea if this will be landing in KaTeX itself soon? It's been a pretty long time since I filed this, and align has not become less important for a LaTeX converter to support =)

Small note on the build procedure: the Makefile right now will fail building if there are spaces in the path. Should be relatively easy to fix.

@spicyj
Member
spicyj commented Dec 29, 2015

#398 landed, though there hasn't been a KaTeX release with it yet. I think MathJax treats align* and aligned interchangeably so align* should be super easy (assuming we want to match that), though we should double check.

@Pomax
Pomax commented Dec 29, 2015

nice! Is there a way to require this unreleased version using node atm, pending a release? I tried an npm install https://github.com/Khan/KaTeX --save-dev so that it grabs the master branch, with a var katex = require('katex');, but then it still warns that align is not supported.

@spicyj
Member
spicyj commented Dec 29, 2015

I think aligned (not align) should work that way.

@kevinbarabash
Contributor

@Pomax if you add an entry to package.json manually you should be able to get the unreleased version, see https://docs.npmjs.com/files/package.json#git-urls-as-dependencies.

@Pomax
Pomax commented Dec 30, 2015

@kevinbarabash cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment