Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request: align / align* support #61

Closed
Pomax opened this issue Sep 16, 2014 · 51 comments
Closed

feature request: align / align* support #61

Pomax opened this issue Sep 16, 2014 · 51 comments
Labels

Comments

@Pomax
Copy link

@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
Copy link
Member

@kevinbarabash kevinbarabash commented Sep 28, 2014

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
Copy link
Author

@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.

@geyang
Copy link

@geyang geyang commented Oct 25, 2014

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

@geyang
Copy link

@geyang geyang commented Nov 19, 2014

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

@jamesplease
Copy link
Contributor

@jamesplease jamesplease 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
Copy link
Member

@kevinbarabash kevinbarabash commented Nov 19, 2014

@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.

@geyang
Copy link

@geyang geyang commented Nov 19, 2014

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
Copy link

@SirVer SirVer commented Mar 15, 2015

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

xymostech pushed a commit to xymostech/KaTeX that referenced this issue Jun 12, 2015
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 KaTeX#43
Partially fixes KaTeX#61
Ping KaTeX#206

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

Reviewers: kevinb, alpert

Differential Revision: https://phabricator.khanacademy.org/D17235
@gagern
Copy link
Collaborator

@gagern 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
Copy link
Member

@kevinbarabash kevinbarabash commented Jun 19, 2015

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
Copy link
Author

@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
Copy link
Collaborator

@gagern 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
Copy link
Member

@kevinbarabash kevinbarabash commented Jun 19, 2015

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
Copy link

@Reflic Reflic commented Jul 20, 2015

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

@kevinbarabash
Copy link
Member

@kevinbarabash kevinbarabash commented Jul 20, 2015

@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
Copy link

@RoyiAvital RoyiAvital commented Sep 9, 2015

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
Copy link
Collaborator

@gagern 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
Copy link

@RoyiAvital RoyiAvital commented Sep 9, 2015

I see...

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

Thank You.

@xymostech
Copy link
Contributor

@xymostech xymostech commented Sep 10, 2015

@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
Copy link
Member

@kevinbarabash kevinbarabash commented Sep 10, 2015

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

@gagern
Copy link
Collaborator

@gagern 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
Copy link
Member

@kevinbarabash kevinbarabash commented Sep 10, 2015

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

@geyang
Copy link

@geyang geyang commented Nov 20, 2015

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
Copy link

@pnsaevik pnsaevik commented Nov 22, 2015

@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
Copy link

@RoyiAvital RoyiAvital commented Nov 22, 2015

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
Copy link

@pnsaevik pnsaevik commented Nov 23, 2015

@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
Copy link

@pnsaevik pnsaevik commented Nov 23, 2015

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
Copy link
Collaborator

@gagern 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
Copy link

@pnsaevik pnsaevik commented Nov 23, 2015

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
Copy link
Collaborator

@gagern 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
Copy link

@pnsaevik pnsaevik commented Nov 23, 2015

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
Copy link
Member

@kevinbarabash kevinbarabash commented Nov 23, 2015

@gagern awesome stuff!

@gagern
Copy link
Collaborator

@gagern 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
Copy link
Member

@kevinbarabash kevinbarabash commented Nov 23, 2015

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

@Pomax
Copy link
Author

@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.

@sophiebits
Copy link
Contributor

@sophiebits sophiebits 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
Copy link
Author

@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.

@sophiebits
Copy link
Contributor

@sophiebits sophiebits commented Dec 29, 2015

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

@kevinbarabash
Copy link
Member

@kevinbarabash kevinbarabash commented Dec 30, 2015

@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
Copy link
Author

@Pomax Pomax commented Dec 30, 2015

@kevinbarabash cheers!

@RoyiAvital
Copy link

@RoyiAvital RoyiAvital commented Feb 7, 2018

Any new ideas how to tackle the 'align' environment and equation numbering?

@edemaine
Copy link
Member

@edemaine edemaine commented Feb 7, 2018

For align/align*, I'd say #604 is my current approach (as opposed to aligned/aligned*). Sadly I still haven't gotten to doing it, though there I've written code in another project to do it.

For equation numbering, the first step would be to implement \tag (#899). There's a question there that could use your feedback. I haven't thought deeply about adding automatic numbering, but it seems plausible to do once we have \tag...

@kevinbarabash
Copy link
Member

@kevinbarabash kevinbarabash commented Feb 7, 2018

This is, at the moment, not shared state between invocations of render() or renderToString(). We'd have to introduce the concept of rendering a "document". We might look at having a way to create a document renderer which can:

  • \begin a "document"
  • render() multiple pieces of LaTeX
  • \end a "document"
@edemaine
Copy link
Member

@edemaine edemaine commented Feb 7, 2018

#604 is roughly along those lines.

We could also have some kind of shared state between invocations of render, with variables etc. This is similar to #687 (\setlength), but also for \setcounter; it's also similar to the already specified macro mapping. One could imagine that you pass in the counters map (initially {equation: 0}), then this gets incremented when equation numbers get used, then the new mapping gets returned. Perhaps it would be most natural to actually modify the passed-in counter map?

@qnxor
Copy link

@qnxor qnxor commented Jul 2, 2020

Still not possible in 2020?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.