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

Line breaks sometimes happen immediately after an inline KaTeX block #1233

Open
akalin opened this issue Mar 21, 2018 · 12 comments · May be fixed by #3133
Open

Line breaks sometimes happen immediately after an inline KaTeX block #1233

akalin opened this issue Mar 21, 2018 · 12 comments · May be fixed by #3133
Labels

Comments

@akalin
Copy link

@akalin akalin commented Mar 21, 2018

This is undesirable if e.g. a comma follow an inline equation.

This seems to happen to me most often on Chrome for Linux (Ubuntu 17.10), but I'm not 100% sure I haven't seen it on Chrome for Mac.

Example gist with display. If you adjust the right border of the browser window, you can get it to break between "A = (ε_0 + H)/2" and its following comma.

I'm not sure if KaTeX has much control over this behavior, but I figure I'd report it in case anyone has any ideas.

Screenshot:

screenshot from 2018-03-20 23-36-23

@akalin
Copy link
Author

@akalin akalin commented Mar 21, 2018

Writing the equation as "A = (ε_0 + H)/2\text{,}" does work in this case, but it would be nice not to have to do that. (Also, I'm not 100% sure that it sometimes doesn't break between the two anyway.)

Loading

@edemaine
Copy link
Member

@edemaine edemaine commented Mar 21, 2018

I've encountered this too, and tweaked my own KaTeX preprocessor to put following punctuation inside any math blocks. This definitely works, as KaTeX doesn't support any line breaks within a math block.

It'd be nice if there'd be a pure CSS workaround... Alternatively, auto-render and a solution to #604 (which I'm imagining roughly following the code linked above) could implement this hacky solution.

Loading

@akalin
Copy link
Author

@akalin akalin commented Mar 22, 2018

Ah, cool, glad to hear this is a known thing. I was considering modifying auto-render, too, but I don't quite understand what #604 has to do with it. My idea would be as follows:

  1. After autorender splits up a piece of text into a list of text and math blocks, but before it renders the math...
  2. For each text block following an inline math block, if some option is set with a string of punctuation, or a regexp or something...
  3. If the beginning of the text block matches the punctuation string/regexp, wrap it in a \text{...} fragment and append it to the previous inline math block. Looks like you use a nobr span; that might work, too.

Would this be something that would be useful to have in auto-render (i.e., would a patch be accepted), or should I expect to just have it for myself?

Loading

@kevinbarabash
Copy link
Member

@kevinbarabash kevinbarabash commented Apr 4, 2018

I'm surprised/disappointed that browsers don't keep the punctuation on the same line unless it follows a space.

Loading

@Reedbeta
Copy link

@Reedbeta Reedbeta commented Sep 24, 2018

I'm seeing this issue too. From a bit of experimentation in Firefox dev tools, it appears this is related to the use of display: inline-block on KaTeX spans. If I remove that property from .katex .base, then the browser no longer puts line breaks between inline math and punctuation.

However, removing display: inline-block also messes with the vertical spacing around math blocks (both display and inline), so that's not a complete fix in itself.

Loading

@vincentbernat
Copy link

@vincentbernat vincentbernat commented Oct 11, 2020

Adding .katex-html { white-space: nowrap; } solves the issue, but it prevents inline formula to have a break inside the formula.

Loading

@ekzhang
Copy link

@ekzhang ekzhang commented May 30, 2021

I was able to fix this issue by combining @vincentbernat's solution with a script that inserts zero-width spaces between each child of the span.katex-html element, which solves the problem of inline formulae not allowing breaks within the formula.

try {
  katex.render(value, element, {
    displayMode: false,
    throwOnError: false,
  });

  /**
   * Set `white-space` on the parent element to `nowrap`, and then insert
   * zero-width spaces between children to enable line breaks.
   *
   * Fix for: https://github.com/KaTeX/KaTeX/issues/1233
   */
  for (const span of element.getElementsByClassName("katex-html")) {
    span.setAttribute("style", "white-space: nowrap");
    const children = Array.from(span.children).slice(1);
    for (const child of children) {
      const spacer = document.createElement("span");
      spacer.innerText = "\u200b"; // Zero-width space
      spacer.style.whiteSpace = "normal";
      span.insertBefore(spacer, child);
    }
  }
} catch (error) {
  // Sometimes KaTeX throws with undefined environments; this is a bug in KaTeX.
  element.innerHTML =
    '<span style="color: rgb(204, 0, 0);">Unknown math error.</span>';
}

It's not a beautiful workaround, but hopefully this helps someone with a similar problem.

Loading

@edemaine
Copy link
Member

@edemaine edemaine commented May 30, 2021

If this is documented behavior (white-space: normal within white-space: nowrap can actually break lines?), it seems like something KaTeX could adopt directly. Would be neat to solve this long-standing issue.

Loading

@ekzhang
Copy link

@ekzhang ekzhang commented May 31, 2021

Sounds good. I would be happy to try to contribute a PR for this. Whether this is "documented behavior" - I agree it's somewhat surprising, honestly just tried different things until Chrome was happy with it. The CSS Text Module Level 3 spec has a section on the white-space property:

normal
This value directs user agents to collapse sequences of white space into a single character (or in some cases, no character). Lines may wrap at allowed soft wrap opportunities, as determined by the line-breaking rules in effect, in order to minimize inline-axis overflow.

pre
This value prevents user agents from collapsing sequences of white space. Segment breaks such as line feeds are preserved as forced line breaks. Lines only break at forced line breaks; content that does not fit within the block container overflows it.

nowrap
Like normal, this value collapses white space; but like pre, it does not allow wrapping.

It does appear that inserting a zero-width space counts as a soft-wrap opportunity.

Wrapping is only performed at an allowed break point, called a soft wrap opportunity. When wrapping is enabled (see white-space), the UA must minimize the amount of content overflowing a line by wrapping the line at a soft wrap opportunity, if one exists.

In most writing systems, in the absence of hyphenation a soft wrap opportunity occurs only at word boundaries. Many such systems use spaces or punctuation to explicitly separate words, and soft wrap opportunities can be identified by these characters. Scripts such as Thai, Lao, and Khmer, however, do not use spaces or punctuation to separate words. Although the zero width space (U+200B) can be used as an explicit word delimiter in these scripts, this practice is not common. As a result, a lexical resource is needed to correctly identify soft wrap opportunities in such texts.

I'll try to make a reproducible example that works on other browsers.

Loading

@ekzhang
Copy link

@ekzhang ekzhang commented Jun 6, 2021

I'm running the dev server at localhost:7936, but it only shows display math rendering, and this issue/change specifically is for inline math line breaks. Is there a way I can inspect the inline math rendering?

Loading

@edemaine
Copy link
Member

@edemaine edemaine commented Jun 7, 2021

@ekzhang Yes, modify the URL to http://localhost:7936/?display=0. See static/main.js for other available options.

Loading

ekzhang added a commit to ekzhang/KaTeX that referenced this issue Jul 24, 2021
@ekzhang ekzhang linked a pull request that will close this issue Jul 24, 2021
ekzhang added a commit to ekzhang/KaTeX that referenced this issue Jul 24, 2021
@ekzhang
Copy link

@ekzhang ekzhang commented Jul 24, 2021

Apologies for the delay, but I found some time to work on this. Just filed #3133, which should fix the issue - let me know how it looks!

Loading

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

Successfully merging a pull request may close this issue.

6 participants