-
-
Notifications
You must be signed in to change notification settings - Fork 654
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
Add LaTeX support #3679
Add LaTeX support #3679
Conversation
00bb80b
to
45e5f8e
Compare
(Rebased to fix conflicts.) |
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.
Thanks @ray-kraesig ! Glad to see this. 😄
Comments below, on various aspects.
Strategy-wise:
- I would really like to get the essential parts of this in soon -- to deliver the feature for our users, and to reduce the complexity of stuff outstanding.
- Some of the later commits here (e.g. doctype) look like they're solving problems we can live with, and the solutions in turn cause complications. So I'd like to move those out of this branch, into followup issues.
- A number of the comments are on the bits of shell script.
- Some are simple to do, or potentially affect correctness, and it'd be good to just do them.
- For the more overall style aspects... after looking closer to try to understand how the
rsync
commands work, and work together, I found a way of rewriting them that I think makes this simpler. So rather than ask you to rework this in a different style, I think the most effective strategy might be:- I show you my sketch of that rewrite, and we agree on broad direction of how the style might go.
- We merge this as is. (Apart from the more-specific fixes as mentioned above.)
- I follow up by (finishing and) sending that rewrite of the
rsync
logic, which will make a lot of the style comments moot.
# KaTeX directory will be [re]built by tools/built-webview | ||
/katex/* | ||
|
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.
I think it's worked well to keep these all in the one root .gitignore file. Separate files can be helpful for organization, but when the separate file is so tiny like this there isn't much of that benefit.
Here, this would very naturally go in the stanza
# Intermediate directories for webview assets
/ios/webview
# /android/app/build/... is already covered above
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.
It's tiny today, but I expect it to grow soon.
I also don't think the root .gitignore
file is working very well, and that third line you posted is evidence of it: android/app/build
is only covered by chance, due to a line in the section labeled # Xcode
! If not for the comment in there about upgrading React Native, I'd already be inclined to break out the ios/
- and android/
-specific elements into subfiles.
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.
It's tiny today, but I expect it to grow soon.
In that case we can easily split it out when it does 🙂 It's super easy to move these lines around, and meanwhile we can avoid paying the cost of having things fragmented in tiny files.
I don't think the other bit is something that would be improved by splitting the file into tiny pieces. I started writing a longer reply, but this thread isn't the right format for that. I think it'd be reasonable to assimilate the whole file to a style that's explicit about rooted vs. unrooted patterns, and to our own choice of organizing it; a good place to discuss that would be a chat thread.
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.
No need to block this on having that discussion, though. Removed, assimilated, and amended.
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.
No need to block this on having that discussion, though. Removed, assimilated, and amended.
Sounds good! But I think this intended change may have gone missing.
tools/build-webview
Outdated
# Chdir to the current git repo's root. | ||
ROOT="$(git rev-parse --show-toplevel)" | ||
cd "$ROOT" |
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.
This comment doesn't add anything -- the code is just as short and says the same thing.
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.
It does if you're fluent in git
options. Not everyone is, though.
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.
(We just talked in person, and I understand your thinking better now! I think the below, which I'd written before that, is still meaningful as a direct reply to the point about the option. But another thing you like having this kind of comment for is as an outline or narrative of the code, for skimming and navigating it. The discussion about that was informative, and I won't try to summarize it here.)
We have this command in four other scripts, all in a similar context and for the same reason. Any nontrivial shell script uses a long list of features that most programmers don't know, and which are far harder to look up than this. It's impossible to comment everything, and at some point we have to trust the reader to take responsibility for understanding what they need to understand.
*/ | ||
const fixupKatex = (root: Element) => { | ||
Array.from(root.querySelectorAll('.katex-display')).forEach(kd => { | ||
// nodes returned by `querySelectorAll` will always have a valid parent node |
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.
Huh, is this true in general? Or do you mean for this particular query?
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.
This is true in general! root.querySelectorAll(...)
never returns root
as one of its values.
(It looks like it also doesn't return nodes from shadow DOM subtrees, although I admit I hadn't considered that at the time.)
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.
I see. Because it only returns descendants, and "descendant" is defined to exclude the ancestor itself.
As always, when I ask a question in code review because I'm confused, I would like the confusion cleared up in the branch itself. :-)
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.
As always, when I ask a question in code review because I'm confused, I would like the confusion cleared up in the branch itself. :-)
bump
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.
I've done some additional work on the auxiliary-script-file interface. I am more concerned now that flattening the script will be problematic than I was previously; this should at least be a better intermediate state, if we end up stuck in it.
Most, but not all, of the changes are in successor commits.
tools/build-webview
Outdated
# Chdir to the current git repo's root. | ||
ROOT="$(git rev-parse --show-toplevel)" | ||
cd "$ROOT" |
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.
It does if you're fluent in git
options. Not everyone is, though.
src/webview/css/css.js
Outdated
is cut off between two symbols.) | ||
*/ | ||
const katexScrollCss = `<style id="katex-mobile-scroll"> | ||
.zulip-katex-outer { display: block; overflow-x: auto; } |
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.
👍
tools/build-webview.d/katex.all.pre
Outdated
# See https://unix.stackexchange.com/a/2503 for an explanation of the rsync | ||
# include/exclude option list. | ||
${RSYNC} --delete --delete-excluded \ | ||
--include="*.${KATEX_FONT_TYPE}" --include='*/' --exclude='*' \ | ||
"${SRC}/fonts" "${DEST}/." |
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.
Because the source file specified here is ${SRC}/fonts
. It'll delete anything in there that's not specified.
This is a bug, though: files in ./katex
proper won't be deleted if they're wrong. (For example, the extraneous katex.js
after switching to katex.min.js
.)
Altered by unifying the two rsync
invocations in this file, partly by stealing your heredoc-filter-rules setup. :)
45e5f8e
to
6487e68
Compare
Addendum #n: So it turns out, despite the implications of the KaTeX installation guide, you don't need However. If I remove the 😞 |
Addendum to the addendum: this race condition is essentially existing behavior on Some tentative initial work involving |
Add KaTeX (the version currently used by the server) as a dependency.
In addition to README.md files, also don't copy .gitignore files into the staging directory.
Pre-sync (and, eventually, post-sync) scripts will be located in a subdirectory of tools/, named `build-webview.d` (following the modern Linux convention of placing configuration file-fragments or auxiliary scripts in similarly named directories). (This commit doesn't add any, though.)
Add a pre-build script to copy the KaTeX fonts and other support files into the staging directory for later bundling/packaging. (Also tell eslint to ignore that directory, since it'll contain minified source.) Add links to those files in the WebView HTML head. (At this point, most inline equations and many block equations are visible with their intended formatting.)
Wrap each block KaTeX equation in a small shim allowing it to be scrolled horizontally. Since the shim doesn't come with a visible scrollbar, add a visible border in lieu thereof.
KaTeX `.frac-line`s don't show up on some of our Android test devices and emulators. (This seems to be a perennial problem for KaTeX. See the commit-internal comments for references.) Resolve this by forcing all such lines to be 1px wide, disregarding the TeXbook spec.
... and eliminate the legacy meaning of an unspecified second parameter. This potentially involves some minor functional changes to `handleInitialLoad`, in that the order of actions therewithin is changed -- but if those actions don't commute, then we should probably have been rewriting the source HTML before scrolling anyway.
... which was only present to ensure that its directory existed in the intermediate commit.
... fixing a minor bug: stray files in the `katex` directory proper would not be deleted.
This only saves about 3K, but every little bit helps.
Refactor `rsync` invocations from `tools/build-webview` and its lone auxiliary script into a function. This arguably contains a functional change: the auxiliary script will now also exclude README.md and .gitignore files. (None presently exist.)
Add option to disable sanity checks for webview directory. These checks are mostly present to raise targeted alarms if something goes wrong with the build system after a change or upgrade; there's no need to have them in place if we're invoking it manually for testing purposes.
... which is a more generally accurate name, since our auxiliary scripts will be compiling or copying assets into $STAGING.
Rename script-global variables from ALL_CAPS to snake_case. (Environment variables, including those used for argument passing, remain ALL_CAPS.)
Although the installation directions just say to include katex.[min.]js unconditionally, the KaTeX JavaScript isn't actually needed just to display existing KaTeX blocks -- only to render new ones. Which is good, because that's ~242K of (uncompressed) JS code that we can do without.
The constants currently declared after argument parsing have no dependency on the arguments. Separate constant declarations into their own section. Reword or rewrite some of their comments, for clarity.
Make all values explicitly absolute paths. Avoid assuming that $CWD is any particular value in this script (at least until the auxiliary scripts are run). This also fixes a mostly-latent bug, in which `$dest` (if supplied as a relative path by a human) would be absolutized based on the project root rather than on $CWD.
522ece8
to
b028728
Compare
src/webview/css/css.js
Outdated
The added border functions as a UI hint to indicate that scrolling is | ||
possible and necessary. (This may not otherwise be apparent, if the equation | ||
is cut off between two symbols.) |
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.
after Safari 13.1 or so, the pseudoclasses in question don't work anymore. ¯_(ツ)_/¯
Well, that's pretty dispositive! We won't be able to use them, then.
I think the comment in the code is clear now, thanks. The key bit was that it's not the presence of the border that's supposed to mean "this is scrollable". Rather, the visibly-cut-off border signals "this is cut off and incomplete", and then maybe you try scrolling.
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.
I spent some time this afternoon loading much of this PR back into my head, and then we discussed in person how to move it forward. The existing state of the PR has grown past GitHub's narrow bounds of what the review UI here can really manage.
In order to get the review complexity down to something manageable, I think the plan (from what you said) is that you'll make a new PR for these changes. That will start the review threads afresh, and you'll also make some revisions to make the branch easier to review and merge. Particularly helpful will be rebasing fixes in later commits forward to squash them into earlier ones, where you can do so.
There were a handful of items where you replied saying you'd done them, but it looks like the changes didn't make it into the branch you pushed. So those would be quite helpful to take care of. I've pointed at two in the comments below, and there's one other I couldn't get into this format but it's the thread here (about a bit of formatting in CSS code):
#3679 (comment)
(It's also possible I've misunderstood one or more of these replies; in which case please clear up my confusion 🙂 )
Also a couple of other small comments below.
* Margin collapsing no longer works, causing rendering artifacts. (This is | ||
particularly visible on integral signs.) |
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.
Bump -- I think the added few words may have gone missing :-) because this appears to be the same as of b028728 as it is in the code at the start of this subthread.
# KaTeX directory will be [re]built by tools/built-webview | ||
/katex/* | ||
|
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.
No need to block this on having that discussion, though. Removed, assimilated, and amended.
Sounds good! But I think this intended change may have gone missing.
*/ | ||
const fixupKatex = (root: Element) => { | ||
Array.from(root.querySelectorAll('.katex-display')).forEach(kd => { | ||
// nodes returned by `querySelectorAll` will always have a valid parent node |
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.
As always, when I ask a question in code review because I'm confused, I would like the confusion cleared up in the branch itself. :-)
bump
border: 1px solid hsla(187, 35%, 51%, .5); | ||
border-radius: 0.25em; | ||
} | ||
.zulip-katex-inner .katex-display { margin: 0.5em 0.25em; } |
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 informative, thanks.
Thinking more about this, I really do want it to follow our style. (Policy? I said "style" originally but as I'm rereading what we have on this I realize that's inadequate -- it makes a visible difference, and overuse of em
is an accessibility issue.) There are good reasons for that style^W policy, and we can't (within reasonable effort) control how third-party libraries work but we can keep things 100% consistent within our own code.
And in this case, to the extent there's a clash between our usage and the one in KaTeX's CSS, I don't think the result is materially worse if this rule is on our side of the clash rather than KaTeX's; I expect it works out better, for the same reasons that our usage is preferable in general.
I'm also finding as I look at this that the writeups we have of the reasoning here are a bit scattered and not entirely satisfying. So I'll go and pull those together into a better doc, which hopefully will be helpful.
Yes indeed. As it turns out, I've actually squashed relatively few of them: a fair number were uncontroversial
That's only because the branch I pushed predates those items – both your comments and my replies – by several hours. 🙂 (I'd mentioned offline at the end of that day that I had marked a few things as done, but was still working on others and so hadn't pushed. In retrospect, that should have been written down here somewhere.) |
Adds LaTeX support via KaTeX.
Fixes #2660.