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

Add LaTeX math support (v3) #4005

Merged
merged 9 commits into from
Apr 2, 2020
9 changes: 5 additions & 4 deletions android/app/webviewAssets.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,18 @@ gradle.projectsEvaluated {
// of what went wrong when it changed out from under us.
def assetsDir = "${buildDir}/intermediates/merged_assets/${variant.name}/out"

// See above note on Windows compatibility.
def destDir = normalizePath(relativizePath("${assetsDir}/webview", repoDir))

def variantTask = tasks.create(
name: "build${variant.name.capitalize()}StaticWebviewAssets",
type: Exec
) {
// All arguments to our script must be relative to `workingDir`.
workingDir repoDir
executable "bash"
args "./tools/build-webview",
"android", "--destination",
// See above note on Windows compatibility.
normalizePath(relativizePath("${assetsDir}/webview", repoDir))
args "./tools/build-webview", "android", "--check-path-name",
"--destination", destDir
}

// Run this task as part of assets merging for this variant.
Expand Down
2 changes: 1 addition & 1 deletion ios/ZulipMobile.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1761,7 +1761,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
shellScript = "exec $SRCROOT/../tools/build-webview ios --destination $SRCROOT/webview\n# See this script, or src/webview/static/README.md, for more information.\n";
shellScript = "exec $SRCROOT/../tools/build-webview ios --check-path-name --destination $SRCROOT/webview\n# See this script, or src/webview/static/README.md, for more information.\n";
};
/* End PBXShellScriptBuildPhase section */

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"blueimp-md5": "^2.10.0",
"color": "^3.0.0",
"date-fns": "^1.29.0",
"katex": "^0.11.1",
"lodash.escape": "^4.0.1",
"lodash.isequal": "^4.4.0",
"lodash.omit": "^4.5.0",
Expand Down
20 changes: 20 additions & 0 deletions src/webview/css/css.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
/* @flow strict-local */
import { Platform } from 'react-native';
import type { ThemeName } from '../../types';
import cssPygments from './cssPygments';
import cssEmojis from './cssEmojis';
import cssNight from './cssNight';

/**
* Fix KaTeX frac-line elements disappearing.
*
* This is a hack, but it's probably better than not having fraction lines on
* low-resolution phones. It's only known to be useful under Chrome and Android,
* so we only include it there.
*
* See, among others:
* https://github.com/KaTeX/KaTeX/issues/824
* https://github.com/KaTeX/KaTeX/issues/916
* https://github.com/KaTeX/KaTeX/pull/1249
* https://github.com/KaTeX/KaTeX/issues/1775
*/
const katexFraclineHackStyle = `<style id="katex-frac-line-hack">
.katex .mfrac .frac-line { border-bottom-width: 1px !important; }
</style>`;

export default (theme: ThemeName) => `
<link rel='stylesheet' type='text/css' href='./base.css'>
<link rel='stylesheet' type='text/css' href='./katex/katex.min.css'>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only line of any part of this commit — summary, message, or diff — that I can reasonably be said to have written.

Please adjust its Author: field accordingly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK -- changed.

Here's why I left your Author: line in place, though: this commit incorporates your work determining

  • we need the CSS but not the JS, despite the install instructions just saying to use both
  • we need the WOFF2 and not the other font formats, and the browser support details that make that the case
  • the choice of where and how to lay out the KaTeX files

So my inclination if marking myself as author would be to have a Co-authored-by: line for you. I've left that out in this revision, because that feels most consistent with the spirit of your request here, and I want to respect your preferences on whether to claim this authorship. But I'd be glad to add such a line if you're OK with that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, very belatedly: I do indeed feel that co-authorship would not have been appropriate here.

What I would probably write in a similar case would be something along the lines of "‍(Based in part on/Supersedes/Inspired by) earlier work by...", with no pseudoheader. (As a concrete example, see the commit message of 988736b.)

<style>
${theme === 'night' ? cssNight : ''}
${cssPygments(theme === 'night')}
Expand All @@ -16,5 +35,6 @@ ${cssEmojis}
display: none;
}
</style>
${Platform.OS === 'android' ? katexFraclineHackStyle : '<!-- Safari -->'}
<style id="generated-styles"></style>
`;
92 changes: 52 additions & 40 deletions tools/build-webview
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ unset CDPATH
# print usage message; do not die
usage() {
cat >&2 <<EOF
usage: $0 [ios | android] --destination DEST
usage: $0 [ios | android] --destination DEST [--check-path-name]

Builds a platform-local intermediate directory containing files used by the
message-list WebView. The target platform (either \`ios\` or \`android\`) must
be specified, along with the expected destination directory.
Build our webview assets, into directory DEST.

This script is mainly for internal use by our build scripts. They
go on to use the contents of DEST as the webview-assets folder,
which our message-list WebView relies on for its static assets.
See src/webview/MessageList.js for details.

With --check-path-name, make some defensive checks that DEST has
the form expected from the actual build scripts.

(This script is usually run automatically by the build system.)
EOF
}

Expand Down Expand Up @@ -57,7 +62,7 @@ readonly root
# Parse arguments. Sloppy, but sufficient for now.
unset target
unset dest
sanity_checks=1
check_path_name=0
while (( $# )); do
case "$1" in
--help|-h|help)
Expand All @@ -68,9 +73,8 @@ while (( $# )); do
--destination)
# note: this doesn't permit an equals sign after `--destination`
shift; dest="$1"; shift;;
--no-sanity-checks)
# disables target-directory sanity checks, for testing's sake
shift; sanity_checks=0;;
--check-path-name)
shift; check_path_name=1;;
*) usage; exit 2;;
esac
done
Expand All @@ -86,9 +90,9 @@ fi
dest=$(readlink -m "$dest")

# Argument parsing has concluded; argument variables are no longer mutable.
readonly target dest sanity_checks
readonly target dest check_path_name

if (( sanity_checks )); then
if (( check_path_name )); then
case "$target" in
ios)
if [ "$(uname)" != "Darwin" ]; then
Expand Down Expand Up @@ -127,45 +131,53 @@ if (( sanity_checks )); then
if [[ "$dest" != *"/webview" ]]; then
err "unexpected destination directory '$dest' (expected basename \"webview\")"
fi
fi # if $sanity_checks

# Set $staging. This is our local staging directory; once it's compiled, it will
# be synced over to $dest.
readonly staging="$root/src/webview/static"
if [ ! -d "$staging" ]; then
err "cannot find asset staging directory '$staging'";
fi
fi # if $check_path_name


################################################################################
# Pre-sync: additional build steps
# (Build and) sync
################################################################################

# Currently none, but this is where they'll go.
# Sync files from src to dest, reading rsync filter rules from stdin.
#
# TODO: Use something like `make -f src/webview/static.Makefile`, to ensure that
# complicated build steps are not run unconditionally.
# Both src and dest should be directories.
#
# TODO: split assets into build-time-generated and build-time-static?
# - rsync can sync from multiple directories, but has no collision-detection
# - might be too many layers of abstraction

# Files in dest not mentioned will be deleted by default. A rule
# like `-,r /foo` will override this to leave `foo` in place.
#
# For documentation on rsync filter rules, see `man rsync` or:
# https://dyn.manpages.debian.org/testing/rsync/rsync.1.en.html#FILTER_RULES
sync() {
# "_dest" because bash's `readonly` means can't shadow with `local`
local src="$1" _dest="$2"
mkdir -p "${_dest}"
rsync -aR --no-D --delete --delete-excluded \
"${src}/./" "${_dest}/." \
--filter='. /dev/stdin'
}

################################################################################
# Sync
################################################################################
# Copy over files from KaTeX.
sync "${root}/node_modules/katex/dist" "${dest}/katex" <<EOF
+ /katex.min.css

# Sync the directory structure, preserving metadata. (We ignore any files named
# 'README.md'; these should be strictly informative.)
#
# We use `rsync` here, as it will skip unchanged files.
mkdir -p "$dest"
rsync -a --no-D --delete --delete-excluded --exclude=README.md "$staging/." "$dest"
# The KaTeX JS renders LaTeX code into HTML and MathML.
# Our webview already has HTML and MathML, and just needs to style it.
#+ /katex.min.js

# The woff2 font format is preferred for browsers that support it,
# which include Chrome 36+ and Mobile Safari 10+. So that's all we need.
+ /fonts/
+ /fonts/*.woff2

- *
EOF

################################################################################
# Post-sync: additional build steps
################################################################################
# Copy over our own files.
sync "${root}/src/webview/static" "${dest}" <<EOF
# Leave alone the katex directory we just made.
-,r /katex

# None yet.
+ /index.html
+ /base.css
- *
EOF
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5660,6 +5660,13 @@ jszip@^3.1.5:
readable-stream "~2.3.6"
set-immediate-shim "~1.0.1"

katex@^0.11.1:
version "0.11.1"
resolved "https://registry.yarnpkg.com/katex/-/katex-0.11.1.tgz#df30ca40c565c9df01a466a00d53e079e84ffaa2"
integrity sha512-5oANDICCTX0NqYIyAiFCCwjQ7ERu3DQG2JFHLbYOf+fXaMoH8eg/zOq5WSYJsKMi/QebW+Eh3gSM+oss1H/bww==
dependencies:
commander "^2.19.0"

katex@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/katex/-/katex-0.7.1.tgz#06bb5298efad05e1e7228035ba8e1591f3061b8f"
Expand Down