-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Support stretchy wide elements. #670
Conversation
CLA signature looks good 👍 |
I have resolved all the lint errors. The error messages I'm getting now are, to me, cryptic. Any help would be appreciated. |
Cool. I feel like the arrows should be a tad thicker, but other than my gut, I have no reference atm. The errors from here: https://travis-ci.org/Khan/KaTeX/builds/218513949 don't seem cryptic to me. What errors are you refering to? |
Yes, I've looked the link you have provided. Yesterday, I cleaned up all the lint errors. The errors that remain start at line 858 of https://travis-ci.org/Khan/KaTeX/builds/218513949#L858. The typical remaining error says something such as: npm ERR! Linux 4.4.0-51-generic And though some may find that statement to be very informative, I confess that I find it cryptic. |
Can you push your fixes to the lint errors, which will trigger a rerun of travis? Those |
Well, @edemaine, I've made another commit, titled "Fix lint errors". I hope that qualifies as the "push" that you alluded to. If not, let me know. And I appreciate the help. |
Well, that's progress. The lint corrections have passed. Travis now fails on Sreenshotter. I have had no success running Screenshotter locally. If anyone else would like to try, that would be fine with me. |
Hmm. I can run screenshotter, but I couldn't reproduce the error that Travis is getting on your branch. My experience is that screenshotter occasionally fails randomly (on my second try, the Colors test failed), so perhaps if Travis tried again, it would work. (But I don't know how to get Travis to try again, other than another random commit.) Anyway, probably don't need to worry about this automatic check, and instead an actual maintainer should review this PR. |
src/stretchy.js
Outdated
} | ||
} else { | ||
// Add color. Use CSS mask, if possible | ||
if (maskIsSupported()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently this will not emit the mask when rendering server-side. It'd be nice to emit the mask, or both, perhaps using @supports
somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I run server.js and view it in http://localhost:7936/, I get the mask when I view it in Chrome, the background-image when I view it in Firefox, and the inline background-image when I view it in Edge. That's the same behavior I get when I view the web page.
I completely agree that we want a server side rendering to emit the mask, but my experience is that we already get that. Am I doing something wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The examples you describe both involve a web browser, a.k.a. a client. The point is that, if you run KaTeX from Node, it won't "support" mask, and so won't be omitted. You simply can't detect support for anything in a server-only environment. Can't you emit the mask in all cases, and it will just work when it's supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To always emit the mask for SSR, you could do something like:
function maskIsSupported() {
// If rendering server-side, assume the client supports CSS masks,
// as most clients do:
if (typeof document === "undefined") return true;
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@edemaine , I can omit the mask in all cases, but the non-mask solution relies on a XMLHttpRequest, which is slow.
@glebm, I would agree with your suggestion. If I interpret caniuse correctly, the upcoming version of Firefox will change from partial mask
support to full support. That would leave behind only IE and Edge. However, I'm not sure that the KaTeX owners would agree with you and me. If Edge does look at the output from such a server-side installation, it will render a span-wide blob of color instead of the subject matter.
So I thank both of you for the education on server-side behavior. This affects not just \color
but also \cancel
, another case where I have different code for IE and Edge.
Regarding \cancel
, I'm going to use background-image SVGs for server-side rendering, just as I use it now for IE and Edge. The only drawback of the SVGs in most browsers is that the line does not get thicker when giant fonts sizes are employed. A 1 px line looks good in most common font sizes, so that is a good fall-back.
On the subject of \color
, I need some guidance from the KaTeX owners as to what they will accept. The options are:
- Do not support
\color
. - Support
\color
by a (slow) XMLHttpRequest in all cases. - Use
mask
when it is supported. Usemask
for server-side installations even
though Edge will not render it properly. - Use
mask
when I can use feature detection to verify that it is supported. Use a XMLHttpRequest for all server-side installations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there isn't a good one-size-fits-all solution, it seems like the best thing to do would be to add an option that lets you decide between "work on Edge" vs. "work fast", when you can't autodetect it.
I'm a little confused why you need an XMLHttpRequest, though. Is it not worth just inlining the SVG into the JavaScript code (const mySVG = "..."
) and using that as needed? I remember we discussed this before, but why use external files at all, when you can embed it all in the JavaScript source?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a very good point. Since our conversation, I've added some SVG files. The tactic of making composite images via CSS was giving some poor rendering issues. So the SVG code is now 32 KB. Say about 40 KB once I add the URL escape codes. By inlining that into the JavaScript, we could eliminate all XMLHttpRequest's. So now we can add option:
- Add 40 KB of SVG code inline in the JavaScript. No XMLHttpRequest, ever.
I still need some guidance from KaTeX owners. Which option would you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Edge does look at the output from such a server-side installation, it will render a span-wide blob of color instead of the subject matter.
If we go with option 3, it is possible to always render a black arrow for browsers that do not support it:
@supports not (mask-image: #000) {
.stretchy {
background-color: transparent !important;
}
.x-arrow {
background-image: url(...) !important;
}
...
}
For IE, @supports
is not supported but the \9
hack can be used instead.
static/images/doubleleftarrow.svg
Outdated
@@ -0,0 +1,43 @@ | |||
<svg xmlns="http://www.w3.org/2000/svg"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These SVGs should be minified, ideally at build time. I recommend svgo for this, can easily shave off 30%.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
Here's a thought: If I inline the SVG code in the JavaScript (to enable server-side Comments? |
Not necessarily, as the browser would need to parse and render a separate SVG image for every arrow from scratch. The giant HTML payload would also make server-side rendered downloads much slower. I'd much prefer to always use CSS masks and render black arrows for browsers that do not support them (via |
@edemaine, I've created a local version with all the SVG code inline. It increases the JavaScript size by 20K, which is less than I expected. I took a pretty extreme approach to eliminating code duplication. For instance, I wrote the typical opening SVG tag only once and I wrote the path for a rightarrow only once. Then, for any specific image, I append these strings together on the fly to create the final complete SVG code. It's pretty compact code, but I suspect it would be hard to maintain and extend. @glebm, If were to summarize your thoughts in my own words, it would go like this:
That would complicate the CSS pretty substantially, but it is in every other way very attractive. I'll work up a prototype. I'm leaning towards this approach myself. |
@glebm, I now have How does one use |
@ronkok I believe the |
static/images/doubleleftarrow.svg
Outdated
@@ -0,0 +1,43 @@ | |||
<svg xmlns="http://www.w3.org/2000/svg"> | |||
<svg viewBox="0 0 400000 549" preserveAspectRatio="xMinYMin slice"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the extra <svg>
? Couldn't viewBox
and preserveAspectRatio
be set on the outer <svg>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kevinbarabash, Some of the SVGs are nested, so that the inner SVG can keep an undisturbed aspect ratio. For instance, we want an arrow head to be un-distorted when the arrow gets longer or shorter. In these files, each arrow SVG contains an arrow that is 400 ems long in the inner SVG. The outer SVG is set to match the dimensions defined for it by the CSS. The outer SVG clips the inner SVG; it does not stretch the inner SVG. That's the purpose of the preserveAspectRatio="xMinYMin slice"
notation.
Of course, we do want some of the SVGs, like \cancel
, to vary their aspect ratio. Those files do not get the nested SVG treatment.
@ronkok awesome PR. I haven't done a close reading of the changes yet, but we'll definitely want some screenshot tests for the new functionality. |
@kevinbarabash, Regarding screenshots, I agree. I also have some work underway that improves the sever-side rendering, as suggested by @glebm. I'm busy on other things for a couple of days, but sometime next week I'll get you some screenshots and a squashed PR. |
@kevinbarabash, I've updated PR #670 with my latest work, improving server-side rendering and minfying the SVG files. I've also squashed the PR. It's ready for your review whenever you find it convenient. You'll find that the JavaScript and the HTML are simpler, but the CSS is more complex. I've also added some Jasmine tests. I tried to add Screenshotter tests, but failed. I don't plan to try again. On the other hand, there is more than one way to contribute. If you want to assign some Screenshotter work to someone at KA, I would be happy to make a financial contribution that leaves KA whole. The Screenshotter code that I tried to add is:
|
@ronkok I'm sorry that |
As before, I have a web page up that describes the results of PR #670. I’ve spent some time with BrowserStack, and the page now includes accurate browser support data. |
@ronkok It looks like you did a merge with master? There's now a lot of irrelevant commits in this PR. You might try |
Yes, I needed to fix a bug -- extensible arrows should be REL, not ORD. So my attempt was to make the change, then squash all the work so that KaTeX maintainers could review it. As a new GitHub user, I have two comments:
Obviously, things went wrong. I’ll try to follow your suggestion. |
Apply CSS trickery to support functions that stretch in the horizontal direction
I believe that the latest commit has fixed my earlier error. @edemaine, thank you for the help. |
Not sure what happened with a couple of those screenshots. I've pulled the most recent changes to |
update screenshots one more time
I've already done the merge. I can do more. No worries. Sometimes the only virtue that matters is persistence. |
update Boxed-chrome.png with fully rendered image
@ronkok thank you for this awesome PR. I know there's lots of people waiting for all of these new commands, including Khan Academy. We'll have to do publish soon. |
@kevinbarabash , I realize that this PR has been more trouble for you than most. I appreciate your help and your patience. I'm glad that the value added from the PR is worth the trouble. If you need any adjustments to stretchy wide elements, I'll be glad to help. @edemaine , @glebm, thank you as well. Between the three of you, you pulled across the finish line someone who started this work knowing very little about JavaScript or SVG and nothing at all about Git. |
Congrats @ronkok and @kevinbarabash on this 1600-line commit! Excited to try out the new features. |
* Change \undeertilde to \utilde In PR #670, I made an error. The function that should have been `\utilde` I named instead `\undertilde`. There is an `\undertilde` from the `wsuipa` package, but it is a text-mode non-stretchy function. The proper command name is `\utilde`, a math-mode, stretchy function from packge `undertilde`. This PR fixes my error. * Fix screenshotter test
Fix a spelling mistake from PR #670.
This will fix issue #629 and possibly #529. Currently, Chrome will fail to render the arrow in
\vec
when CSS containstext-rendering: optimizeLegibility;
.