Modernize font creation (#624)

* Modernize font creation

* Automate the build process, instead of writing a complicated manual
* Update sources used by the docker image away from google code
* Exclude MathJax-dev checkout from docker image, to allow image reuse
* Try to keep the individual image layers small by combining RUN commands
  and removing temporary files used only during each individual step

* Allow creating fonts from local directory

Also use hash of Dockerfile to compute image tag, in order to ensure
creation of a new image if the Dockerfile changes.

* make glob syntax work on MacOS
This commit is contained in:
Martin von Gagern
2017-08-20 06:45:34 +01:00
committed by Kevin Barabash
parent a4b1bf01be
commit a9708a25f2
4 changed files with 196 additions and 123 deletions

View File

@@ -2,7 +2,10 @@ FROM ubuntu:14.04
MAINTAINER xymostech <xymostech@gmail.com>
# Install things
RUN apt-get -qq update && apt-get -qqy install \
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get -y upgrade \
&& DEBIAN_FRONTEND=noninteractive apt-get -y install \
--no-install-recommends --auto-remove \
git \
dvipng \
default-jre \
@@ -23,39 +26,41 @@ RUN apt-get -qq update && apt-get -qqy install \
woff-tools \
pkg-config \
libharfbuzz-dev \
libfreetype6-dev || true
RUN gem install ttfunk --version 1.1.1
libfreetype6-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& gem install ttfunk --version 1.1.1
# Download yuicompressor
RUN mkdir /usr/share/yui-compressor/
RUN wget "https://github.com/yui/yuicompressor/releases/download/v2.4.8/yuicompressor-2.4.8.jar" -O /usr/share/yui-compressor/yui-compressor.jar
ADD https://github.com/yui/yuicompressor/releases/download/v2.4.8/yuicompressor-2.4.8.jar /usr/share/yui-compressor/yui-compressor.jar
# Download batik-ttf2svg.jar
RUN wget "https://archive.apache.org/dist/xmlgraphics/batik/batik-1.7.zip"
RUN unzip -qq batik-1.7.zip
RUN mv batik-1.7/batik-ttf2svg.jar /usr/share/java/
RUN wget "https://archive.apache.org/dist/xmlgraphics/batik/batik-1.7.zip" \
&& unzip batik-*.zip batik-*/batik-ttf2svg.jar \
&& mv batik-*/batik-ttf2svg.jar /usr/share/java/ \
&& rm -r batik-*
# Download and compile ttf2eof (note we add a patch to make it compile)
RUN wget "https://ttf2eot.googlecode.com/files/ttf2eot-0.0.2-2.tar.gz"
RUN tar -xzf ttf2eot-0.0.2-2.tar.gz
RUN sed -i "1s/^/#include <cstddef>/" ttf2eot-0.0.2-2/OpenTypeUtilities.h
RUN make -C ttf2eot-0.0.2-2/
RUN mv ttf2eot-0.0.2-2/ttf2eot /usr/bin/
RUN wget "https://github.com/wget/ttf2eot/archive/v0.0.2-2.tar.gz" -O ttf2eot.tar.gz\
&& tar -xzf ttf2eot.tar.gz \
&& sed -i "1s/^/#include <cstddef>/" ttf2eot-*/OpenTypeUtilities.h \
&& make -C ttf2eot-*/ \
&& mv ttf2eot-*/ttf2eot /usr/bin/ \
&& rm -r ttf2eot*
# Download and compile ttfautohint
RUN wget "http://download.savannah.gnu.org/releases/freetype/ttfautohint-1.3.tar.gz"
RUN tar -xzf ttfautohint-1.3.tar.gz
RUN cd ttfautohint-1.3/ && ./configure --without-qt
RUN make -C ttfautohint-1.3/
RUN mv ttfautohint-1.3/frontend/ttfautohint /usr/bin
RUN wget "http://download.savannah.gnu.org/releases/freetype/ttfautohint-1.3.tar.gz" \
&& tar -xzf ttfautohint-*.tar.gz \
&& cd ttfautohint-*/ \
&& ./configure --without-qt \
&& make \
&& mv frontend/ttfautohint /usr/bin \
&& cd .. \
&& rm -r ttfautohint-*
# Download and compile woff2_compress
RUN git clone "https://code.google.com/p/font-compression-reference/" woff2_compress
RUN make -C woff2_compress/woff2/
RUN mv woff2_compress/woff2/woff2_compress /usr/bin/
# Download and setup MathJax-dev
RUN git clone "https://github.com/khan/MathJax-dev.git"
RUN cp MathJax-dev/default.cfg MathJax-dev/custom.cfg
RUN make -C MathJax-dev custom.cfg.pl
RUN wget "https://github.com/google/woff2/archive/d9a74803fa884559879e3205cfe6f257a2d85519.tar.gz" -O woff2.tar.gz \
&& tar -xzf woff2.tar.gz \
&& make -C woff2-*/woff2/ \
&& mv woff2-*/woff2/woff2_compress /usr/bin \
&& rm -r woff2*

View File

@@ -1,55 +1,22 @@
### How to generate MathJax fonts
---------------------------------
It's really simple (now)! Just make a docker image from the included Dockerfile
using a command like
The `buildFonts.sh` script should do everything automatically,
as long as Docker is installed.
sudo docker build --tag=mathjaxfonts .
If you want to try out a change
to [the MathJax-dev repository](https://github.com/Khan/MathJax-dev),
create a local clone (or download and unpack the ZIP file)
and specify the path to this directory as an arument to `buildFonts.sh`.
You can also specify a local or remote tarball,
e.g. a GitHub download of your own personal feature branch.
from within this directory (note you need to have docker installed and running
for this to work). This will build a docker image with the mathjaxfonts tag,
which you can then use to run dockers based on them. Then, run a mathjaxfonts
docker with
The script `buildFonts.sh` automatically creates Docker images
from the supplied `Dockerfile`.
It uses the hash of the file to tag the image, so a change to the file
will result in the creation of a new image.
If you want to see all created images, run `docker images katex/fonts`.
To remove all generated images, you can run
`docker rmi $(docker images --format '{{.Repository}}:{{.Tag}}' katex/fonts)`.
sudo docker run --interactive --tty --name mjf mathjaxfonts /bin/bash
We name this docker "mjf" so we can reference it later when we want to copy the
files off. (If you get an error about the name being in use, perhaps because you
are trying to create another docker, you can either delete the old docker with
sudo docker rm mjf
or use a different name.) This will get you into the docker in the root
directory. From there, cd into the `/MathJax-dev/fonts/OTF/TeX` directory, and
run
make ttf eot woff woff2
to build all of the fonts that we need. Finally, leave the docker and copy all
the files off with the `copy_fonts.sh` script:
./copy_fonts.sh mjf
And you're good to go! Don't forget to update the font metrics with `make
metrics`.
### General Docker Help
-----------------------
When you quit the docker, it will stop the docker from running. If you want to
reattach to the docker, you can start it again with
sudo docker start mjf
and then attach with
sudo docker attach mjf
Alternatively, if you want to detach from the docker when you're done instead of
quitting and stopping it, you can detach with `C-p C-q`, and then re-attach with
sudo docker attach mjf
To see a list of your current dockers, you can run
docker ps
If there is a problem, file a bug report.

View File

@@ -0,0 +1,148 @@
#!/usr/bin/env bash
shopt -s extglob
usage() {
while [[ $# -gt 1 ]]; do
echo "$1" >&2
shift
done
echo "Usage: ${0##*/} [OPTIONS] [SOURCE]"
echo ""
echo "SOURCE may be"
echo " - a URL for a tarball, or"
echo " - a local tarball file, or"
echo " - a local directory"
echo "with a layout compatible to MathJax-dev."
echo "It defaults to ${URL}"
echo ""
echo "OPTIONS:"
echo " -h|--help display this help"
echo " --image NAME:TAG use the named docker image [$IMAGE]"
exit $1
}
used_fonts=(
KaTeX_AMS-Regular
KaTeX_Caligraphic-Bold
KaTeX_Caligraphic-Regular
KaTeX_Fraktur-Bold
KaTeX_Fraktur-Regular
KaTeX_Main-Bold
KaTeX_Main-Italic
KaTeX_Main-Regular
KaTeX_Math-BoldItalic
KaTeX_Math-Italic
KaTeX_Math-Regular
KaTeX_SansSerif-Bold
KaTeX_SansSerif-Italic
KaTeX_SansSerif-Regular
KaTeX_Script-Regular
KaTeX_Size1-Regular
KaTeX_Size2-Regular
KaTeX_Size3-Regular
KaTeX_Size4-Regular
KaTeX_Typewriter-Regular
)
filetypes=( ttf eot woff woff2 )
set -e
cd "$(dirname "$0")"
cleanup() {
[[ "${CONTAINER}" ]] \
&& docker stop "${CONTAINER}" >/dev/null \
&& docker rm "${CONTAINER}" >/dev/null
CONTAINER=
[[ -f "${TMPFILE}" ]] && rm "${TMPFILE}"
TMPFILE=
}
CONTAINER=
trap cleanup EXIT
IMAGE="katex/fonts:DF-$(openssl sha1 Dockerfile | tail -c 9)"
URL=https://github.com/Khan/MathJax-dev/archive/master.tar.gz
TMPFILE=
FILE=
NARGS=0
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage 0
;;
--image=*)
IMAGE="${1#*=}"
;;
--image)
shift
IMAGE="$1"
;;
-*)
usage "Invalid option: $1" "" 1
;;
*)
case $NARGS in
0)
if [[ -d "$1" ]]; then
TMPFILE="$(mktemp "${TMPDIR:-/tmp}/mjf.XXXXXXXX")"
FILE="$TMPFILE"
pushd "$1"
if [[ ! -f fonts/OTF/TeX/Makefile ]]; then
echo "$1 does not look like MathJax-dev" >&2
exit 1
fi
tar cf "$FILE" Makefile default.cfg fonts/OTF/TeX
popd
elif [[ -f "$1" ]]; then
FILE="$1"
elif [[ "$1" = http?(s)://* ]]; then
URL="$1"
else
echo "'$1' is not a valid source" >&2
exit 1
fi
NARGS=1
;;
*)
usage "Too many arguments: $1" "" 1
;;
esac
;;
esac
shift
done
# build image if missing
if [[ $(docker images "$IMAGE" | wc -l) -lt 2 ]]; then
echo "Need to build docker image $IMAGE"
docker build --tag "$IMAGE" .
fi
CMDS="set -ex
test -f MathJax-dev.tar.gz || wget -O MathJax-dev.tar.gz '${URL}'
mk=\$(tar tf MathJax-dev.tar.gz | grep 'fonts/OTF/TeX/Makefile\$')
tar xf MathJax-dev.tar.gz
cd \"\${mk%fonts/*}\"
cp default.cfg custom.cfg
make custom.cfg.pl
make -C fonts/OTF/TeX ${filetypes[*]}
tar cf /fonts.tar ${filetypes[*]/#/fonts/OTF/TeX/}"
echo "Creating and starting docker container from image $IMAGE"
CONTAINER=$(docker create "$IMAGE" /bin/sh -c "${CMDS}")
if [[ ${FILE} ]]; then
docker cp "${FILE}" $CONTAINER:/MathJax-dev.tar.gz
fi
docker start --attach $CONTAINER
docker cp $CONTAINER:/fonts.tar .
cleanup
echo "Docker executed successfully, will now unpack the fonts"
tar xf fonts.tar
for filetype in "${filetypes[@]}"; do
for font in "${used_fonts[@]}"; do
echo "$filetype/$font"
mv "fonts/OTF/TeX/$filetype/$font".* ../../static/fonts/
done
done
rm -rf fonts fonts.tar

View File

@@ -1,47 +0,0 @@
#!/usr/bin/env bash
set -e
if [ -z "$1" ]; then
echo "Usage: $(basename $0) <docker name>"
echo " If you followed the README, the docker name would be 'mjf'"
exit 1
else
DOCKER_NAME="$1"
fi
mkdir fonts
used_fonts=(
KaTeX_AMS-Regular
KaTeX_Caligraphic-Bold
KaTeX_Caligraphic-Regular
KaTeX_Fraktur-Bold
KaTeX_Fraktur-Regular
KaTeX_Main-Bold
KaTeX_Main-Italic
KaTeX_Main-Regular
KaTeX_Math-BoldItalic
KaTeX_Math-Italic
KaTeX_Math-Regular
KaTeX_SansSerif-Bold
KaTeX_SansSerif-Italic
KaTeX_SansSerif-Regular
KaTeX_Script-Regular
KaTeX_Size1-Regular
KaTeX_Size2-Regular
KaTeX_Size3-Regular
KaTeX_Size4-Regular
KaTeX_Typewriter-Regular
)
for filetype in ttf eot woff woff2; do
echo "Copying $filetype"
docker cp "$DOCKER_NAME":/MathJax-dev/fonts/OTF/TeX/"$filetype" fonts
for font in ${used_fonts[*]}; do
mv fonts/"$filetype"/"$font"* fonts/
done
rm -rf fonts/"$filetype"
done