mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-04 18:58:39 +00:00
build: move font generation to the main repo (#2837)
* build: move font generation to the main repo * Update fonts * chore: remove submodules * Update paths * Update fonts.yml Co-authored-by: Kevin Barabash <kevinb@khanacademy.org>
This commit is contained in:
@@ -10,5 +10,5 @@
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash"
|
||||
},
|
||||
"postCreateCommand": "git submodule update --init --recursive && CI=true yarn install"
|
||||
"postCreateCommand": "CI=true yarn install"
|
||||
}
|
||||
|
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -16,7 +16,6 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false # minimize exposure and prevent accidental pushes
|
||||
|
||||
- name: Use Node.js 12.x
|
||||
@@ -64,7 +63,6 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js 12.x
|
||||
|
122
.github/workflows/fonts.yml
vendored
Normal file
122
.github/workflows/fonts.yml
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
name: Fonts
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches: [ master ]
|
||||
types: [ labeled ] # 'build fonts' label
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
if: contains(github.event.pull_request.labels.*.name, 'build fonts')
|
||||
outputs:
|
||||
image: ${{ steps.check-image.outputs.result }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ format('refs/pull/{0}/merge', github.event.pull_request.number) }}
|
||||
persist-credentials: false # minimize exposure and prevent accidental pushes
|
||||
|
||||
- name: Remove label
|
||||
uses: actions/github-script@v3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
github.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: "build fonts",
|
||||
});
|
||||
|
||||
- name: Check image
|
||||
id: check-image
|
||||
uses: actions/github-script@v3
|
||||
with:
|
||||
# https://github.community/t/github-token-has-no-access-to-new-container-rest-apis/170395
|
||||
github-token: ${{ secrets.GH_PACKAGES_TOKEN }}
|
||||
result-encoding: string
|
||||
script: |
|
||||
/* eslint-disable camelcase, max-len, no-console */
|
||||
const org = context.repo.owner;
|
||||
const package_name = "fonts";
|
||||
const version = "${{ hashFiles('dockers/fonts/Dockerfile') }}";
|
||||
|
||||
let packages;
|
||||
try {
|
||||
packages = (await github.request('GET /orgs/{org}/packages/{package_type}/{package_name}/versions', {
|
||||
org,
|
||||
package_type: "container",
|
||||
package_name,
|
||||
})).data;
|
||||
} catch (e) {
|
||||
packages = [];
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
core.setOutput("exists", packages.some(p => p.metadata.container.tags.includes(version)));
|
||||
return `ghcr.io/${org}/${package_name}:${version}`.toLowerCase();
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: ${{ !fromJSON(steps.check-image.outputs.exists) }}
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: KaTeX-bot
|
||||
# https://github.community/t/cant-authenticate-with-actions-token-for-pr-event/170752
|
||||
password: ${{ secrets.GH_PACKAGES_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
if: ${{ !fromJSON(steps.check-image.outputs.exists) }}
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: dockers/fonts
|
||||
tags: ${{ steps.check-image.outputs.result }}
|
||||
push: true
|
||||
|
||||
fonts:
|
||||
runs-on: ubuntu-latest
|
||||
needs: docker
|
||||
container:
|
||||
image: ${{ needs.docker.outputs.image }}
|
||||
credentials:
|
||||
username: KaTeX-bot
|
||||
# https://github.community/t/cant-authenticate-with-actions-token-for-pr-event/170752
|
||||
password: ${{ secrets.GH_PACKAGES_TOKEN }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ format('refs/pull/{0}/merge', github.event.pull_request.number) }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Build fonts
|
||||
run: |
|
||||
export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct -- src/fonts)
|
||||
make -C src/fonts all
|
||||
rm -f fonts/*.*
|
||||
cp src/fonts/ttf/*.ttf fonts
|
||||
cp src/fonts/woff/*.woff fonts
|
||||
cp src/fonts/woff2/*.woff2 fonts
|
||||
echo $SOURCE_DATE_EPOCH > fonts/VERSION
|
||||
|
||||
- name: Build metrics
|
||||
run: ./dockers/fonts/buildMetrics.sh
|
||||
|
||||
- name: Run git diff
|
||||
run: |
|
||||
printf '[diff "font"]\n\tbinary = true\n\ttextconv = ttx -q -i -o -' >> ~/.gitconfig
|
||||
git diff --exit-code
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: fonts
|
||||
path: fonts
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: metrics
|
||||
path: src/fontMetricsData.js
|
1
.github/workflows/screenshotter.yml
vendored
1
.github/workflows/screenshotter.yml
vendored
@@ -40,7 +40,6 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event_name == 'pull_request_target' && format('refs/pull/{0}/merge', github.event.pull_request.number) || '' }}
|
||||
submodules: recursive
|
||||
persist-credentials: false # do not persist credentials
|
||||
|
||||
- name: Use Node.js 14
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -40,3 +40,7 @@ website/.yarn/*
|
||||
!website/.yarn/plugins
|
||||
!website/.yarn/sdks
|
||||
!website/.yarn/versions
|
||||
|
||||
fonts.tar
|
||||
fonts.tar.gz
|
||||
temp/
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "submodules/katex-fonts"]
|
||||
path = submodules/katex-fonts
|
||||
url = https://github.com/KaTeX/katex-fonts
|
@@ -151,21 +151,6 @@ Flow by running `yarn test:flow`. See [Flow](https://flow.org/) for more details
|
||||
- commits should be squashed before merging
|
||||
- large pull requests should be broken into separate pull requests (or multiple logically cohesive commits), if possible
|
||||
|
||||
## Working with submodules
|
||||
|
||||
The fonts for KaTeX live in a submodule stored in `submodules/katex-fonts`.
|
||||
When you first clone the KaTeX repository, use
|
||||
`git submodule update --init --recursive` to download the corresponding
|
||||
fonts repository. After running `yarn`, you should have Git hooks that
|
||||
will automatically run this command after switching to branches
|
||||
where `submodules/katex-fonts` point to different commits.
|
||||
|
||||
When submitting pull requests that update katex-fonts, you'll need to submit
|
||||
two pull requests: one for [KaTeX/katex-fonts](https://github.com/KaTeX/katex-fonts) and one for [KaTeX/KaTeX](https://github.com/KaTeX/KaTeX).
|
||||
|
||||
For more info about how to use git submodules,
|
||||
see https://chrisjean.com/git-submodules-adding-using-removing-and-updating/.
|
||||
|
||||
## CLA
|
||||
|
||||
In order to contribute to KaTeX, you must first sign the CLA, found at www.khanacademy.org/r/cla
|
||||
|
40
dockers/fonts/Dockerfile
Normal file
40
dockers/fonts/Dockerfile
Normal file
@@ -0,0 +1,40 @@
|
||||
FROM ubuntu:14.04
|
||||
MAINTAINER xymostech <xymostech@gmail.com>
|
||||
|
||||
# Install things
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get -y upgrade \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get -y install \
|
||||
--no-install-recommends --auto-remove \
|
||||
software-properties-common \
|
||||
texlive \
|
||||
wget \
|
||||
fontforge \
|
||||
mftrace \
|
||||
man-db \
|
||||
build-essential \
|
||||
python-fontforge \
|
||||
python-dev \
|
||||
python-pip \
|
||||
pkg-config \
|
||||
libharfbuzz-dev \
|
||||
libfreetype6-dev \
|
||||
libjson-perl \
|
||||
&& add-apt-repository ppa:git-core/ppa \
|
||||
&& apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get -y install \
|
||||
--no-install-recommends --auto-remove \
|
||||
git \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& pip install fonttools==3.28.0 brotli zopfli
|
||||
|
||||
# Download and compile ttfautohint
|
||||
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-*
|
31
dockers/fonts/README.md
Normal file
31
dockers/fonts/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
### How to generate KaTeX fonts and metrics
|
||||
|
||||
Originally based on MathJax font generation
|
||||
|
||||
#### Fonts
|
||||
|
||||
The `buildFonts.sh` script should do everything automatically,
|
||||
as long as Docker is installed.
|
||||
|
||||
If you want to try out a change
|
||||
to [the katex-fonts repository](https://github.com/KaTeX/katex-fonts),
|
||||
create a local clone (or download and unpack the ZIP file)
|
||||
and specify the path to this directory as an argument to `buildFonts.sh`.
|
||||
You can also specify a local or remote tarball,
|
||||
e.g. a GitHub download of your own personal feature branch.
|
||||
|
||||
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)`.
|
||||
|
||||
#### Metrics
|
||||
|
||||
The script `buildMetrics.sh` generates [metrics](../../src/fontMetricsData.js)
|
||||
(dimensions of each character) for the generated fonts.
|
||||
See [detailed requirements for running this script](../../src/metrics/).
|
||||
|
||||
If there is a problem, file a bug report.
|
101
dockers/fonts/buildFonts.sh
Executable file
101
dockers/fonts/buildFonts.sh
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env bash
|
||||
shopt -s extglob
|
||||
|
||||
usage() {
|
||||
while [[ $# -gt 1 ]]; do
|
||||
echo "$1" >&2
|
||||
shift
|
||||
done
|
||||
echo "Usage: ${0##*/} [OPTIONS]"
|
||||
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-Regular
|
||||
KaTeX_Main-Bold
|
||||
KaTeX_Main-Italic
|
||||
KaTeX_Main-BoldItalic
|
||||
KaTeX_Math-Italic
|
||||
KaTeX_Math-BoldItalic
|
||||
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 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
|
||||
|
||||
LAST_COMMIT_DATE="$(git log -1 --format=%ct -- src/fonts)"
|
||||
IMAGE="katex/fonts:DF-$(openssl sha1 $(dirname "$0")/Dockerfile | tail -c 9)"
|
||||
TMPFILE="$(mktemp "${TMPDIR:-/tmp}/mjf.XXXXXXXX")"
|
||||
FILE="$TMPFILE"
|
||||
pushd "src"
|
||||
if [[ ! -f fonts/Makefile ]]; then
|
||||
echo "src does not look like katex-fonts" >&2
|
||||
exit 1
|
||||
fi
|
||||
tar cfP "$FILE" ../package.json fonts
|
||||
popd
|
||||
|
||||
# build image if missing
|
||||
if [[ $(docker images "$IMAGE" | wc -l) -lt 2 ]]; then
|
||||
echo "Need to build docker image $IMAGE"
|
||||
docker build --tag "$IMAGE" "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
CMDS="set -ex
|
||||
export SOURCE_DATE_EPOCH=${LAST_COMMIT_DATE}
|
||||
tar xfP katex-fonts.tar.gz
|
||||
make -C fonts all
|
||||
tar cf /fonts.tar ${filetypes[*]/#/fonts/}"
|
||||
|
||||
echo "Creating and starting docker container from image $IMAGE"
|
||||
CONTAINER=$(docker create "$IMAGE" /bin/sh -c "${CMDS}")
|
||||
if [[ ${FILE} ]]; then
|
||||
docker cp "${FILE}" $CONTAINER:/katex-fonts.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
|
||||
mv fonts temp
|
||||
mkdir fonts
|
||||
for filetype in "${filetypes[@]}"; do
|
||||
for font in "${used_fonts[@]}"; do
|
||||
echo "$filetype/$font"
|
||||
mv "temp/$filetype/$font".* ./fonts/
|
||||
done
|
||||
done
|
||||
rm -rf temp fonts.tar
|
||||
|
||||
echo $LAST_COMMIT_DATE > fonts/VERSION
|
7
dockers/fonts/buildMetrics.sh
Executable file
7
dockers/fonts/buildMetrics.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
# Generates fontMetricsData.js
|
||||
PERL="perl"
|
||||
PYTHON=`python2 --version >/dev/null 2>&1 && echo python2 || echo python`
|
||||
|
||||
cd src/metrics
|
||||
$PERL ./mapping.pl | $PYTHON ./extract_tfms.py | $PYTHON ./extract_ttfs.py | $PYTHON ./format_json.py --width > ../fontMetricsData.js
|
@@ -2,7 +2,7 @@
|
||||
id: font
|
||||
title: Font
|
||||
---
|
||||
By changing the variables in the `fonts.less` file at the [katex-fonts submodule](https://github.com/KaTeX/katex-fonts/),
|
||||
By changing the variables in the `src/fonts.less` file,
|
||||
several properties of the way fonts are used can be changed.
|
||||
|
||||
## Font size and lengths
|
||||
|
@@ -24,9 +24,9 @@ yarn global add katex
|
||||
### Building from Source
|
||||
To build you will need Git, Node.js 10 or later, and Yarn.
|
||||
|
||||
Clone a copy of the GitHub source repository and its submodules:
|
||||
Clone a copy of the GitHub source repository:
|
||||
```bash
|
||||
git clone --recursive https://github.com/KaTeX/KaTeX.git
|
||||
git clone https://github.com/KaTeX/KaTeX.git
|
||||
cd KaTeX
|
||||
```
|
||||
|
||||
|
BIN
fonts/KaTeX_AMS-Regular.ttf
Normal file
BIN
fonts/KaTeX_AMS-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_AMS-Regular.woff
Normal file
BIN
fonts/KaTeX_AMS-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_AMS-Regular.woff2
Normal file
BIN
fonts/KaTeX_AMS-Regular.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Caligraphic-Bold.ttf
Normal file
BIN
fonts/KaTeX_Caligraphic-Bold.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Caligraphic-Bold.woff
Normal file
BIN
fonts/KaTeX_Caligraphic-Bold.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Caligraphic-Bold.woff2
Normal file
BIN
fonts/KaTeX_Caligraphic-Bold.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Caligraphic-Regular.ttf
Normal file
BIN
fonts/KaTeX_Caligraphic-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Caligraphic-Regular.woff
Normal file
BIN
fonts/KaTeX_Caligraphic-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Caligraphic-Regular.woff2
Normal file
BIN
fonts/KaTeX_Caligraphic-Regular.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Fraktur-Bold.ttf
Normal file
BIN
fonts/KaTeX_Fraktur-Bold.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Fraktur-Bold.woff
Normal file
BIN
fonts/KaTeX_Fraktur-Bold.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Fraktur-Bold.woff2
Normal file
BIN
fonts/KaTeX_Fraktur-Bold.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Fraktur-Regular.ttf
Normal file
BIN
fonts/KaTeX_Fraktur-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Fraktur-Regular.woff
Normal file
BIN
fonts/KaTeX_Fraktur-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Fraktur-Regular.woff2
Normal file
BIN
fonts/KaTeX_Fraktur-Regular.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-Bold.ttf
Normal file
BIN
fonts/KaTeX_Main-Bold.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-Bold.woff
Normal file
BIN
fonts/KaTeX_Main-Bold.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-Bold.woff2
Normal file
BIN
fonts/KaTeX_Main-Bold.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-BoldItalic.ttf
Normal file
BIN
fonts/KaTeX_Main-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-BoldItalic.woff
Normal file
BIN
fonts/KaTeX_Main-BoldItalic.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-BoldItalic.woff2
Normal file
BIN
fonts/KaTeX_Main-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-Italic.ttf
Normal file
BIN
fonts/KaTeX_Main-Italic.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-Italic.woff
Normal file
BIN
fonts/KaTeX_Main-Italic.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-Italic.woff2
Normal file
BIN
fonts/KaTeX_Main-Italic.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-Regular.ttf
Normal file
BIN
fonts/KaTeX_Main-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-Regular.woff
Normal file
BIN
fonts/KaTeX_Main-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Main-Regular.woff2
Normal file
BIN
fonts/KaTeX_Main-Regular.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Math-BoldItalic.ttf
Normal file
BIN
fonts/KaTeX_Math-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Math-BoldItalic.woff
Normal file
BIN
fonts/KaTeX_Math-BoldItalic.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Math-BoldItalic.woff2
Normal file
BIN
fonts/KaTeX_Math-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Math-Italic.ttf
Normal file
BIN
fonts/KaTeX_Math-Italic.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Math-Italic.woff
Normal file
BIN
fonts/KaTeX_Math-Italic.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Math-Italic.woff2
Normal file
BIN
fonts/KaTeX_Math-Italic.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_SansSerif-Bold.ttf
Normal file
BIN
fonts/KaTeX_SansSerif-Bold.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_SansSerif-Bold.woff
Normal file
BIN
fonts/KaTeX_SansSerif-Bold.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_SansSerif-Bold.woff2
Normal file
BIN
fonts/KaTeX_SansSerif-Bold.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_SansSerif-Italic.ttf
Normal file
BIN
fonts/KaTeX_SansSerif-Italic.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_SansSerif-Italic.woff
Normal file
BIN
fonts/KaTeX_SansSerif-Italic.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_SansSerif-Italic.woff2
Normal file
BIN
fonts/KaTeX_SansSerif-Italic.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_SansSerif-Regular.ttf
Normal file
BIN
fonts/KaTeX_SansSerif-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_SansSerif-Regular.woff
Normal file
BIN
fonts/KaTeX_SansSerif-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_SansSerif-Regular.woff2
Normal file
BIN
fonts/KaTeX_SansSerif-Regular.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Script-Regular.ttf
Normal file
BIN
fonts/KaTeX_Script-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Script-Regular.woff
Normal file
BIN
fonts/KaTeX_Script-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Script-Regular.woff2
Normal file
BIN
fonts/KaTeX_Script-Regular.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size1-Regular.ttf
Normal file
BIN
fonts/KaTeX_Size1-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size1-Regular.woff
Normal file
BIN
fonts/KaTeX_Size1-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size1-Regular.woff2
Normal file
BIN
fonts/KaTeX_Size1-Regular.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size2-Regular.ttf
Normal file
BIN
fonts/KaTeX_Size2-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size2-Regular.woff
Normal file
BIN
fonts/KaTeX_Size2-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size2-Regular.woff2
Normal file
BIN
fonts/KaTeX_Size2-Regular.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size3-Regular.ttf
Normal file
BIN
fonts/KaTeX_Size3-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size3-Regular.woff
Normal file
BIN
fonts/KaTeX_Size3-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size3-Regular.woff2
Normal file
BIN
fonts/KaTeX_Size3-Regular.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size4-Regular.ttf
Normal file
BIN
fonts/KaTeX_Size4-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size4-Regular.woff
Normal file
BIN
fonts/KaTeX_Size4-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Size4-Regular.woff2
Normal file
BIN
fonts/KaTeX_Size4-Regular.woff2
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Typewriter-Regular.ttf
Normal file
BIN
fonts/KaTeX_Typewriter-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Typewriter-Regular.woff
Normal file
BIN
fonts/KaTeX_Typewriter-Regular.woff
Normal file
Binary file not shown.
BIN
fonts/KaTeX_Typewriter-Regular.woff2
Normal file
BIN
fonts/KaTeX_Typewriter-Regular.woff2
Normal file
Binary file not shown.
1
fonts/VERSION
Normal file
1
fonts/VERSION
Normal file
@@ -0,0 +1 @@
|
||||
1615612969
|
@@ -114,9 +114,7 @@
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "yarn test:lint",
|
||||
"post-merge": "git submodule update --init --recursive",
|
||||
"post-checkout": "git submodule update --init --recursive"
|
||||
"pre-commit": "yarn test:lint"
|
||||
}
|
||||
},
|
||||
"jest": {
|
||||
|
@@ -6,9 +6,6 @@
|
||||
":prNotPending",
|
||||
"group:linters"
|
||||
],
|
||||
"git-submodules": {
|
||||
"enabled": true
|
||||
},
|
||||
"lockFileMaintenance": {
|
||||
"enabled": true,
|
||||
"schedule": ["at any time"],
|
||||
|
@@ -30,7 +30,7 @@ import buildCommon from "./buildCommon";
|
||||
import {getCharacterMetrics} from "./fontMetrics";
|
||||
import symbols from "./symbols";
|
||||
import utils from "./utils";
|
||||
import fontMetricsData from "../submodules/katex-fonts/fontMetricsData";
|
||||
import fontMetricsData from "./fontMetricsData";
|
||||
|
||||
import type Options from "./Options";
|
||||
import type {CharacterMetrics} from "./fontMetrics";
|
||||
|
@@ -96,7 +96,7 @@ const sigmasAndXis = {
|
||||
// metrics, including height, depth, italic correction, and skew (kern from the
|
||||
// character to the corresponding \skewchar)
|
||||
// This map is generated via `make metrics`. It should not be changed manually.
|
||||
import metricMap from "../submodules/katex-fonts/fontMetricsData";
|
||||
import metricMap from "./fontMetricsData";
|
||||
|
||||
// These are very rough approximations. We default to Times New Roman which
|
||||
// should have Latin-1 and Cyrillic characters, but may not depending on the
|
||||
|
2076
src/fontMetricsData.js
Normal file
2076
src/fontMetricsData.js
Normal file
File diff suppressed because it is too large
Load Diff
64
src/fonts.less
Normal file
64
src/fonts.less
Normal file
@@ -0,0 +1,64 @@
|
||||
@font-folder: "../fonts";
|
||||
@use-ttf: true;
|
||||
@use-woff: true;
|
||||
@use-woff2: true;
|
||||
|
||||
.use-woff2(@family, @family-suffix) when (@use-woff2 = true) {
|
||||
src+: url('@{font-folder}/KaTeX_@{family}-@{family-suffix}.woff2') format('woff2')
|
||||
}
|
||||
|
||||
.use-woff(@family, @family-suffix) when (@use-woff = true) {
|
||||
src+: url('@{font-folder}/KaTeX_@{family}-@{family-suffix}.woff') format('woff')
|
||||
}
|
||||
|
||||
.use-ttf(@family, @family-suffix) when (@use-ttf = true) {
|
||||
src+: url('@{font-folder}/KaTeX_@{family}-@{family-suffix}.ttf') format('truetype')
|
||||
}
|
||||
|
||||
.generate-suffix(@weight, @style) when (@weight = normal) and (@style = normal) {
|
||||
@suffix: 'Regular';
|
||||
}
|
||||
.generate-suffix(@weight, @style) when (@weight = normal) and (@style = italic) {
|
||||
@suffix: 'Italic';
|
||||
}
|
||||
.generate-suffix(@weight, @style) when (@weight = bold) and (@style = normal) {
|
||||
@suffix: 'Bold';
|
||||
}
|
||||
.generate-suffix(@weight, @style) when (@weight = bold) and (@style = italic) {
|
||||
@suffix: 'BoldItalic';
|
||||
}
|
||||
|
||||
.font-face(@family, @weight, @style) {
|
||||
.generate-suffix(@weight, @style);
|
||||
@font-face {
|
||||
font-family: 'KaTeX_@{family}';
|
||||
.use-woff2(@family, @suffix);
|
||||
.use-woff(@family, @suffix);
|
||||
.use-ttf(@family, @suffix);
|
||||
font-weight: @weight;
|
||||
font-style: @style;
|
||||
}
|
||||
}
|
||||
|
||||
.font-face('AMS', normal, normal);
|
||||
.font-face('Caligraphic', bold, normal);
|
||||
.font-face('Caligraphic', normal, normal);
|
||||
.font-face('Fraktur', bold, normal);
|
||||
.font-face('Fraktur', normal, normal);
|
||||
.font-face('Main', bold, normal);
|
||||
.font-face('Main', bold, italic);
|
||||
.font-face('Main', normal, italic);
|
||||
.font-face('Main', normal, normal);
|
||||
//.font-face('Math', bold, normal);
|
||||
.font-face('Math', bold, italic);
|
||||
.font-face('Math', normal, italic);
|
||||
//.font-face('Math', normal, normal);
|
||||
.font-face('SansSerif', bold, normal);
|
||||
.font-face('SansSerif', normal, italic);
|
||||
.font-face('SansSerif', normal, normal);
|
||||
.font-face('Script', normal, normal);
|
||||
.font-face('Size1', normal, normal);
|
||||
.font-face('Size2', normal, normal);
|
||||
.font-face('Size3', normal, normal);
|
||||
.font-face('Size4', normal, normal);
|
||||
.font-face('Typewriter', normal, normal);
|
9
src/fonts/.gitignore
vendored
Normal file
9
src/fonts/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
lib/blacker.mf
|
||||
lib/mftrace-modified
|
||||
lib/Space.otf
|
||||
ff
|
||||
otf
|
||||
pfa
|
||||
ttf
|
||||
woff
|
||||
woff2
|
139
src/fonts/Makefile
Normal file
139
src/fonts/Makefile
Normal file
@@ -0,0 +1,139 @@
|
||||
#!gmake
|
||||
#
|
||||
# Version: Apache License 2.0
|
||||
#
|
||||
# Copyright (c) 2013 MathJax Project
|
||||
# Copyright (c) 2013 The MathJax Consortium
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
CUSTOM=custom.cfg
|
||||
|
||||
-include $(CUSTOM)
|
||||
|
||||
MFTRACE_MODIFIED=lib/mftrace-modified
|
||||
|
||||
all: config fonts
|
||||
|
||||
$(CUSTOM):
|
||||
@cp default.cfg $(CUSTOM);
|
||||
|
||||
$(CUSTOM).pl: $(CUSTOM)
|
||||
@echo "Creating Perl config file..."
|
||||
@cp $(CUSTOM) $(CUSTOM).pl
|
||||
@echo >> $(CUSTOM).pl # ensure that the config file ends by a new line
|
||||
@echo "MFTRACE_PATH=`$(WHICH) $(MFTRACE)`" >> $(CUSTOM).pl
|
||||
@$(SED) -i "s|^\([A-Z_0-9]*\)=\(.*\)|$$\1='\2';|" $(CUSTOM).pl
|
||||
@echo "1;" >> $(CUSTOM).pl
|
||||
|
||||
.PHONY: config
|
||||
config: $(CUSTOM).pl
|
||||
|
||||
blacker: $(MFTRACE_MODIFIED)
|
||||
$(MFTRACE_MODIFIED):
|
||||
$(PERL) makeBlacker 15 # values between 10 and 30 seem best
|
||||
|
||||
pfa: $(MFTRACE_MODIFIED)
|
||||
@echo "cmr10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify cmr10
|
||||
|
||||
@echo "cmmi10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --encoding $(TETEXENCODING)/aae443f0.enc --simplify cmmi10
|
||||
|
||||
@echo "cmsy10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --encoding $(TETEXENCODING)/10037936.enc --simplify cmsy10
|
||||
|
||||
@echo "cmex10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify cmex10
|
||||
|
||||
@echo "cmbx10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify cmbx10
|
||||
|
||||
@echo "cmbxti10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify cmbxti10
|
||||
|
||||
@echo "cmti10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify cmti10
|
||||
|
||||
@echo "msam10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify --encoding $(TETEXENCODING)/10037936.enc msam10
|
||||
|
||||
@echo "msbm10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify --encoding $(TETEXENCODING)/10037936.enc msbm10
|
||||
|
||||
@echo "cmmib10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --encoding $(TETEXENCODING)/aae443f0.enc --simplify cmmib10
|
||||
|
||||
@echo "cmbsy10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --encoding $(TETEXENCODING)/10037936.enc --simplify cmbsy10
|
||||
|
||||
@echo "cmtt10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify cmtt10
|
||||
|
||||
@echo "cmss10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify cmss10
|
||||
@echo "cmssi10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify cmssi10
|
||||
@echo "cmssbx10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify cmssbx10
|
||||
|
||||
@echo "eufm10"
|
||||
cp "`$(KPSEWHICH) eufm10.pfb`" eufm10.pfb
|
||||
@echo "eufb10"
|
||||
cp "`$(KPSEWHICH) eufb10.pfb`" eufb10.pfb
|
||||
|
||||
# echo "eusm10"
|
||||
# $(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify eusm10
|
||||
# echo "eusb10"
|
||||
# $(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify eusb10
|
||||
|
||||
@echo "rsfs10"
|
||||
$(PYTHON) $(MFTRACE_MODIFIED) --magnification 1000 --simplify --encoding $(BASEENCODING)/tex256.enc rsfs10
|
||||
|
||||
mkdir -p pfa
|
||||
rm -f pfa/*
|
||||
mv *.pfa pfa
|
||||
mv *.pfb pfa
|
||||
|
||||
ff: pfa
|
||||
mkdir -p ff otf
|
||||
rm -f ff/* otf/*
|
||||
$(PERL) makeFF
|
||||
|
||||
.PHONY: fonts
|
||||
fonts: ff
|
||||
mkdir -p ttf woff woff2
|
||||
rm -f ttf/* woff/* woff2/*
|
||||
|
||||
@for file in `ls ff/*.ff | $(SED) 's|ff/\(.*\)\.ff|\1|'`; do \
|
||||
echo ""; \
|
||||
echo $$file; \
|
||||
$(FONTFORGE) -lang=ff -script ff/$$file.ff; \
|
||||
\
|
||||
echo "Hinting $$file"; \
|
||||
if echo "$$file" | $(GREP) -q -e "Size[1-4]" -e "Typewriter"; then \
|
||||
$(TTFAUTOHINT) --windows-compatibility --symbol ttf/$$file.ttf ttf/$$file.ttf.hinted; \
|
||||
else \
|
||||
$(TTFAUTOHINT) --windows-compatibility ttf/$$file.ttf ttf/$$file.ttf.hinted; \
|
||||
fi; \
|
||||
mv ttf/$$file.ttf.hinted ttf/$$file.ttf; \
|
||||
\
|
||||
echo "Generating $$file..."; \
|
||||
$(PYTHON) generate_fonts.py ttf/$$file.ttf; \
|
||||
done
|
||||
|
||||
clean:
|
||||
rm -f $(CUSTOM).pl
|
||||
rm -f $(MFTRACE_MODIFIED) lib/blacker.mf
|
||||
rm -rf pfa ff otf ttf woff woff2
|
20
src/fonts/default.cfg
Normal file
20
src/fonts/default.cfg
Normal file
@@ -0,0 +1,20 @@
|
||||
# Note: paths should be absolute, unless they point to programs in your $PATH.
|
||||
|
||||
##### Standard programs #####
|
||||
GREP=grep
|
||||
PERL=perl
|
||||
PYTHON=python
|
||||
SED=sed
|
||||
WHICH=which
|
||||
KPSEWHICH=kpsewhich
|
||||
|
||||
##### Font tools #####
|
||||
# Most of the tools below are standard and should be available from your package manager.
|
||||
FONTFORGE=fontforge
|
||||
MFTRACE=mftrace
|
||||
TTX=ttx
|
||||
TTFAUTOHINT=ttfautohint
|
||||
|
||||
##### TeXLive Encoding
|
||||
TETEXENCODING=/usr/share/texlive/texmf-texlive/fonts/enc/dvips/tetex/
|
||||
BASEENCODING=/usr/share/texlive/texmf-texlive/fonts/enc/dvips/base/
|
61
src/fonts/generate_fonts.py
Executable file
61
src/fonts/generate_fonts.py
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
|
||||
from fontTools.ttLib import TTFont, sfnt
|
||||
from fontTools.misc.timeTools import timestampNow
|
||||
sfnt.USE_ZOPFLI = True
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print "Usage: %s <font file>" % sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
font_file = sys.argv[1]
|
||||
font_name = os.path.splitext(os.path.basename(font_file))[0]
|
||||
|
||||
# now or SOURCE_DATE_EPOCH, if present
|
||||
timestamp = timestampNow()
|
||||
|
||||
font = TTFont(font_file, recalcBBoxes=False, recalcTimestamp=False)
|
||||
|
||||
font['head'].created = timestamp
|
||||
font['head'].modified = timestamp
|
||||
|
||||
# remove fontforge timestamps
|
||||
if 'FFTM' in font:
|
||||
del font['FFTM']
|
||||
|
||||
# remove redundant GDEF table
|
||||
if 'GDEF' in font:
|
||||
del font['GDEF']
|
||||
|
||||
# remove Macintosh table
|
||||
# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html
|
||||
font['name'].names = [record for record in font['name'].names if record.platformID != 1]
|
||||
font['cmap'].tables = [table for table in font['cmap'].tables if table.platformID != 1]
|
||||
|
||||
font['name'].setName(unicode('Version ' + str(timestamp)), 5, 3, 1, 1033)
|
||||
|
||||
# fix OS/2 and hhea metrics
|
||||
glyf = font['glyf']
|
||||
ascent = int(max(glyf[c].yMax for c in font.getGlyphOrder() if hasattr(glyf[c], "yMax")))
|
||||
descent = -int(min(glyf[c].yMin for c in font.getGlyphOrder() if hasattr(glyf[c], "yMin")))
|
||||
|
||||
font['OS/2'].usWinAscent = ascent
|
||||
font['OS/2'].usWinDescent = descent
|
||||
|
||||
font['hhea'].ascent = ascent
|
||||
font['hhea'].descent = -descent
|
||||
|
||||
# save TTF
|
||||
font.save(font_file, reorderTables=None)
|
||||
|
||||
# save WOFF
|
||||
font.flavor = 'woff'
|
||||
font.save(os.path.join('woff', font_name + '.woff'), reorderTables=None)
|
||||
|
||||
# save WOFF2
|
||||
font.flavor = 'woff2'
|
||||
font.save(os.path.join('woff2', font_name + '.woff2'), reorderTables=None)
|
BIN
src/fonts/lib/Extra.otf
Normal file
BIN
src/fonts/lib/Extra.otf
Normal file
Binary file not shown.
234
src/fonts/lib/Space.ttx
Normal file
234
src/fonts/lib/Space.ttx
Normal file
@@ -0,0 +1,234 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ttFont sfntVersion="OTTO" ttLibVersion="3.28">
|
||||
|
||||
<GlyphOrder>
|
||||
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
|
||||
<GlyphID id="0" name=".notdef"/>
|
||||
<GlyphID id="1" name="space"/>
|
||||
<GlyphID id="2" name="uni00A0"/>
|
||||
</GlyphOrder>
|
||||
|
||||
<head>
|
||||
<!-- Most of this table will be recalculated by the compiler -->
|
||||
<tableVersion value="1.0"/>
|
||||
<fontRevision value="1.0"/>
|
||||
<checkSumAdjustment value="0xa98c8795"/>
|
||||
<magicNumber value="0x5f0f3cf5"/>
|
||||
<flags value="00000000 00000011"/>
|
||||
<unitsPerEm value="1000"/>
|
||||
<created value="Sun Jan 24 23:04:46 2010"/>
|
||||
<modified value="Sat May 14 12:26:22 2011"/>
|
||||
<xMin value="50"/>
|
||||
<yMin value="0"/>
|
||||
<xMax value="200"/>
|
||||
<yMax value="533"/>
|
||||
<macStyle value="00000000 00000000"/>
|
||||
<lowestRecPPEM value="8"/>
|
||||
<fontDirectionHint value="2"/>
|
||||
<indexToLocFormat value="0"/>
|
||||
<glyphDataFormat value="0"/>
|
||||
</head>
|
||||
|
||||
<hhea>
|
||||
<tableVersion value="0x00010000"/>
|
||||
<ascent value="800"/>
|
||||
<descent value="-200"/>
|
||||
<lineGap value="90"/>
|
||||
<advanceWidthMax value="250"/>
|
||||
<minLeftSideBearing value="50"/>
|
||||
<minRightSideBearing value="50"/>
|
||||
<xMaxExtent value="200"/>
|
||||
<caretSlopeRise value="1"/>
|
||||
<caretSlopeRun value="0"/>
|
||||
<caretOffset value="0"/>
|
||||
<reserved0 value="0"/>
|
||||
<reserved1 value="0"/>
|
||||
<reserved2 value="0"/>
|
||||
<reserved3 value="0"/>
|
||||
<metricDataFormat value="0"/>
|
||||
<numberOfHMetrics value="1"/>
|
||||
</hhea>
|
||||
|
||||
<maxp>
|
||||
<tableVersion value="0x5000"/>
|
||||
<numGlyphs value="3"/>
|
||||
</maxp>
|
||||
|
||||
<OS_2>
|
||||
<!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
|
||||
will be recalculated by the compiler -->
|
||||
<version value="2"/>
|
||||
<xAvgCharWidth value="225"/>
|
||||
<usWeightClass value="400"/>
|
||||
<usWidthClass value="5"/>
|
||||
<fsType value="00000000 00000000"/>
|
||||
<ySubscriptXSize value="650"/>
|
||||
<ySubscriptYSize value="700"/>
|
||||
<ySubscriptXOffset value="0"/>
|
||||
<ySubscriptYOffset value="140"/>
|
||||
<ySuperscriptXSize value="650"/>
|
||||
<ySuperscriptYSize value="700"/>
|
||||
<ySuperscriptXOffset value="0"/>
|
||||
<ySuperscriptYOffset value="480"/>
|
||||
<yStrikeoutSize value="49"/>
|
||||
<yStrikeoutPosition value="258"/>
|
||||
<sFamilyClass value="0"/>
|
||||
<panose>
|
||||
<bFamilyType value="0"/>
|
||||
<bSerifStyle value="0"/>
|
||||
<bWeight value="0"/>
|
||||
<bProportion value="0"/>
|
||||
<bContrast value="0"/>
|
||||
<bStrokeVariation value="0"/>
|
||||
<bArmStyle value="0"/>
|
||||
<bLetterForm value="0"/>
|
||||
<bMidline value="0"/>
|
||||
<bXHeight value="0"/>
|
||||
</panose>
|
||||
<ulUnicodeRange1 value="10000000 00000000 00000000 11101111"/>
|
||||
<ulUnicodeRange2 value="00010000 00000000 11101100 11101101"/>
|
||||
<ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
|
||||
<ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
|
||||
<achVendID value="PfEd"/>
|
||||
<fsSelection value="00000000 01000000"/>
|
||||
<usFirstCharIndex value="32"/>
|
||||
<usLastCharIndex value="160"/>
|
||||
<sTypoAscender value="800"/>
|
||||
<sTypoDescender value="-200"/>
|
||||
<sTypoLineGap value="90"/>
|
||||
<usWinAscent value="533"/>
|
||||
<usWinDescent value="0"/>
|
||||
<ulCodePageRange1 value="00100000 00000000 00000000 10001111"/>
|
||||
<ulCodePageRange2 value="01011110 00000011 00000000 00000000"/>
|
||||
<sxHeight value="0"/>
|
||||
<sCapHeight value="0"/>
|
||||
<usDefaultChar value="32"/>
|
||||
<usBreakChar value="32"/>
|
||||
<usMaxContext value="1"/>
|
||||
</OS_2>
|
||||
|
||||
<name>
|
||||
<namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
|
||||
Copyright (c) 2009-2010 Design Science, Inc.
|
||||
Copyright (c) 2014-2018 Khan Academy
|
||||
</namerecord>
|
||||
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
|
||||
*NAME*
|
||||
</namerecord>
|
||||
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
|
||||
*WEIGHT_S*
|
||||
</namerecord>
|
||||
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
|
||||
FontForge 2.0 : *NAME*-*WEIGHT*
|
||||
</namerecord>
|
||||
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
|
||||
*NAME*-*WEIGHT*
|
||||
</namerecord>
|
||||
<namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
|
||||
Version 1.1
|
||||
</namerecord>
|
||||
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
|
||||
*NAME*-*WEIGHT*
|
||||
</namerecord>
|
||||
<namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
|
||||
Copyright (c) 2009-2010, Design Science, Inc. (<www.mathjax.org>)
|
||||
Copyright (c) 2014-2018 Khan Academy (<www.khanacademy.org>),
|
||||
with Reserved Font Name *NAME*.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
</namerecord>
|
||||
<namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
|
||||
http://scripts.sil.org/OFL
|
||||
</namerecord>
|
||||
</name>
|
||||
|
||||
<cmap>
|
||||
<tableVersion version="0"/>
|
||||
<cmap_format_4 platformID="0" platEncID="3" language="0">
|
||||
<map code="0x20" name="space"/><!-- SPACE -->
|
||||
<map code="0xa0" name="uni00A0"/><!-- NO-BREAK SPACE -->
|
||||
</cmap_format_4>
|
||||
<cmap_format_4 platformID="3" platEncID="1" language="0">
|
||||
<map code="0x20" name="space"/><!-- SPACE -->
|
||||
<map code="0xa0" name="uni00A0"/><!-- NO-BREAK SPACE -->
|
||||
</cmap_format_4>
|
||||
</cmap>
|
||||
|
||||
<post>
|
||||
<formatType value="3.0"/>
|
||||
<italicAngle value="0.0"/>
|
||||
<underlinePosition value="-125"/>
|
||||
<underlineThickness value="50"/>
|
||||
<isFixedPitch value="0"/>
|
||||
<minMemType42 value="0"/>
|
||||
<maxMemType42 value="0"/>
|
||||
<minMemType1 value="0"/>
|
||||
<maxMemType1 value="0"/>
|
||||
</post>
|
||||
|
||||
<CFF>
|
||||
<major value="1"/>
|
||||
<minor value="0"/>
|
||||
<CFFFont name="*NAME*-*WEIGHT*">
|
||||
<version value="001.001"/>
|
||||
<Notice value="Copyright (c) 2009-2010 Design Science, Inc., Copyright (c) 2014-2018 Khan Academy"/>
|
||||
<FullName value="*NAME*-*WEIGHT*"/>
|
||||
<FamilyName value="*NAME*"/>
|
||||
<Weight value="*NORMAL*"/>
|
||||
<isFixedPitch value="0"/>
|
||||
<ItalicAngle value="0"/>
|
||||
<UnderlinePosition value="-150"/>
|
||||
<UnderlineThickness value="50"/>
|
||||
<PaintType value="0"/>
|
||||
<CharstringType value="2"/>
|
||||
<FontMatrix value="0.001 0 0 0.001 0 0"/>
|
||||
<FontBBox value="50 0 200 533"/>
|
||||
<StrokeWidth value="0"/>
|
||||
<!-- charset is dumped separately as the 'GlyphOrder' element -->
|
||||
<Encoding name="StandardEncoding"/>
|
||||
<Private>
|
||||
<BlueScale value="0.03963"/>
|
||||
<BlueShift value="0"/>
|
||||
<BlueFuzz value="1"/>
|
||||
<StdHW value="50"/>
|
||||
<StdVW value="50"/>
|
||||
<ForceBold value="0"/>
|
||||
<LanguageGroup value="0"/>
|
||||
<ExpansionFactor value="0.06"/>
|
||||
<initialRandomSeed value="0"/>
|
||||
<defaultWidthX value="250"/>
|
||||
<nominalWidthX value="193"/>
|
||||
</Private>
|
||||
<CharStrings>
|
||||
<CharString name=".notdef">
|
||||
0 50 433 50 hstem
|
||||
50 50 50 50 vstem
|
||||
50 hmoveto
|
||||
150 533 -150 hlineto
|
||||
50 -483 rmoveto
|
||||
433 50 -433 vlineto
|
||||
endchar
|
||||
</CharString>
|
||||
<CharString name="space">
|
||||
endchar
|
||||
</CharString>
|
||||
<CharString name="uni00A0">
|
||||
endchar
|
||||
</CharString>
|
||||
</CharStrings>
|
||||
</CFFFont>
|
||||
|
||||
<GlobalSubrs>
|
||||
<!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
|
||||
</GlobalSubrs>
|
||||
</CFF>
|
||||
|
||||
<hmtx>
|
||||
<mtx name=".notdef" width="250" lsb="50"/>
|
||||
<mtx name="space" width="250" lsb="0"/>
|
||||
<mtx name="uni00A0" width="250" lsb="0"/>
|
||||
</hmtx>
|
||||
|
||||
</ttFont>
|
49
src/fonts/makeBlacker
Executable file
49
src/fonts/makeBlacker
Executable file
@@ -0,0 +1,49 @@
|
||||
#! /usr/bin/perl
|
||||
|
||||
# Creates the metafont file needed for darker copies of the TeX fonts,
|
||||
# and modifies mftrace to use it.
|
||||
#
|
||||
# Usage: ./makeBlacker blackness
|
||||
|
||||
require "custom.cfg.pl";
|
||||
|
||||
$blacker = shift;
|
||||
unless ($blacker) {
|
||||
print stderr "Usage: ./makeBlacker blackness\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
sub editMftrace {
|
||||
my $oldMFTRACE = $MFTRACE_PATH;
|
||||
$MFTRACE = "./lib/mftrace-modified";
|
||||
print "Editing mftrace\n";
|
||||
open(MFT,$oldMFTRACE) || die "Can't read '$oldMFTRACE': $!\n";
|
||||
my $MFT = join("",<MFT>);
|
||||
close(MFT);
|
||||
$MFT =~ s!r"mf '\\mode:=(?:[^;]*)(; [^"]*)"!r"""mf '\\smode:="lib/blacker.mf"$1"""!;
|
||||
open(MFT,">$MFTRACE") || die "Can't write '$MFTRACE': $!\n";
|
||||
print MFT $MFT;
|
||||
close(MFT);
|
||||
chmod 0755, $MFTRACE;
|
||||
}
|
||||
|
||||
sub makeBlackerMF {
|
||||
my $blacker = shift;
|
||||
print "Using blacker = $blacker\n";
|
||||
open(BLACKER,">lib/blacker.mf") || die "Can't write 'lib/blacker.mf': $!\n";
|
||||
print BLACKER << " END";
|
||||
proofing:=0;
|
||||
fontmaking:=1;
|
||||
tracingtitles:=0;
|
||||
pixels_per_inch:=1200;
|
||||
blacker:=$blacker;
|
||||
fillin:=0;
|
||||
o_correction:=1;
|
||||
END
|
||||
close(BLACKER);
|
||||
}
|
||||
|
||||
editMftrace();
|
||||
makeBlackerMF($blacker);
|
||||
|
||||
1;
|
2003
src/fonts/makeFF
Executable file
2003
src/fonts/makeFF
Executable file
File diff suppressed because it is too large
Load Diff
182
src/fonts/xbbold.mf
Normal file
182
src/fonts/xbbold.mf
Normal file
@@ -0,0 +1,182 @@
|
||||
%% filename: xbbold.mf
|
||||
%% version: 2.2
|
||||
%% date: 1995/01/04
|
||||
%%
|
||||
%% (katex-fonts) The line 69 is modified to prevent overflow
|
||||
%%
|
||||
%% American Mathematical Society
|
||||
%% Technical Support
|
||||
%% Publications Technical Group
|
||||
%% 201 Charles Street
|
||||
%% Providence, RI 02904
|
||||
%% USA
|
||||
%% tel: (401) 455-4080
|
||||
%% (800) 321-4267 (USA and Canada only)
|
||||
%% fax: (401) 331-3842
|
||||
%% email: tech-support@ams.org
|
||||
%%
|
||||
%% Copyright 1995, 2009 American Mathematical Society.
|
||||
%%
|
||||
%% This Font Software is licensed under the SIL Open Font License,
|
||||
%% Version 1.1. This license is in the accompanying file OFL.txt, and
|
||||
%% is also available with a FAQ at: http://scripts.sil.org/OFL.
|
||||
%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Changes of minimal parameters in outlined characters for version 2.1
|
||||
% done by Stefan Lindner, 18-April-1991
|
||||
|
||||
input xbbase;
|
||||
%%mode_setup; %called by amsyb.mf; two calls confuse Metafont. NGB 15-OCT-1991
|
||||
|
||||
%%%%designsize:= font_size; % was 10pt#;
|
||||
width#:= designsize; % was 10pt#;
|
||||
unit#:= width#/18;
|
||||
u#:= width#/54;
|
||||
smallu#:= width#/162;
|
||||
ascender#:= 37/3*unit#;
|
||||
cap#:= 37/3*unit#;
|
||||
number#:= 36/3*unit#;
|
||||
xheight#:= 25/3*unit#;
|
||||
descender#:= 12/4*unit#;
|
||||
define_whole_vertical_pixels
|
||||
(width,unit,u,smallu,ascender,cap,number,xheight,descender);
|
||||
wpix(1.90u) (linethickness);
|
||||
wpix(0.65u) (Sover_bot);
|
||||
wpix(1.00u) (Aapex,Napex,Vapex,Wapex,Cover,Gover,Oover,Sover_top,Uover);
|
||||
wpix(9.00u) (Uthin_bracket);
|
||||
wpix(8.00u) (Kthin_diag_bracket,Xthin_diag_bracket,Ythin_diag_bracket);
|
||||
wpix(7.00u) (k_thin_diag);
|
||||
wpix(6.00u) (c_thin_stem_bracket);
|
||||
wpix(5.00u) (c_thick_stem_bracket,c_inner_bracket,lc_thick_stem_bracket);
|
||||
wpix(4.00u) (c_round_bracket);
|
||||
adjpix(1.35u) (serif_thickness);
|
||||
adjpix(1.30u) (Emid_tip,inbeak);
|
||||
adjpix(1.50u) (Atip,Btopthin,Bmidthin,Ebot_tip,Ltip,Mapex,
|
||||
Ntip,Ttip,Vtip,Wtip,Ztip,outbeak);
|
||||
adjpix(1.65u) (Bbotthin,Gbotthin,Stopthin);
|
||||
adjpix(1.75u) (Dtopthin,Ebotarm,Lthin,Tthin);
|
||||
adjpix(1.80u) (Abar,Ctopthin,Dbotthin,Gtopthin,Jbotthin,Pmidarm,Sbotthin);
|
||||
adjpix(1.90u) (Emidarm,Etoparm,Othin,Pthin,Rthin,Ydiag,Zthin);
|
||||
adjpix(2.00u) (kthin,Mthin_diag,Wleftthin);
|
||||
adjpix(2.10u) (Ctip);
|
||||
adjpix(2.25u) (Athin,Kthin,Mthin_vert,Nthin,Uthin,Vthin,Wrightthin,Xthin);
|
||||
adjpix(2.50u) (Hbar);
|
||||
adjpix(2.60u) (Cbotthin);
|
||||
|
||||
|
||||
%%%% Begin of changes for version 2.1
|
||||
%(katex-fonts) Originally was pixels_per_inch*designsize < 1500:
|
||||
if pixels_per_inch < 1500/designsize:
|
||||
if pixels_per_inch*designsize < 1000:
|
||||
if pixels_per_inch*designsize < 800:
|
||||
if pixels_per_inch*designsize < 700:
|
||||
minadjpix(0)(8.80u) (stem);
|
||||
minadjpix(0)(6.80u) (kdiag);
|
||||
minadjpix(0)(7.40u) (kstem);
|
||||
minadjpix(0)(7.80u) (Jbulb,Mdiag);
|
||||
minadjpix(0)(8.20u) (Kdiag);
|
||||
minadjpix(0)(8.30u) (Gstem,Mstem);
|
||||
minadjpix(0)(8.60u) (Lstem,Ustem,Ythick_diag);
|
||||
minadjpix(0)(8.50u) (Bstem,Estem,Fstem,Ndiag,Rdiag,Xdiag,Zdiag);
|
||||
minadjpix(0)(8.90u) (Btopcurve);
|
||||
minadjpix(1)(9.30u) (Bbotcurve,Pcurve,Rcurve);
|
||||
minadjpix(1)(9.50u) (Ccurve,Dcurve,Gcurve,Ocurve);
|
||||
else:
|
||||
minadjpix(1)(8.80u) (stem);
|
||||
minadjpix(1)(6.80u) (kdiag);
|
||||
minadjpix(1)(7.40u) (kstem);
|
||||
minadjpix(1)(7.80u) (Jbulb,Mdiag);
|
||||
minadjpix(1)(8.20u) (Kdiag);
|
||||
minadjpix(1)(8.30u) (Gstem,Mstem);
|
||||
minadjpix(1)(8.60u) (Lstem,Ustem,Ythick_diag);
|
||||
minadjpix(1)(8.50u) (Bstem,Estem,Fstem,Ndiag,Rdiag,Xdiag,Zdiag);
|
||||
minadjpix(1)(8.90u) (Btopcurve);
|
||||
minadjpix(2)(9.30u) (Bbotcurve,Pcurve,Rcurve);
|
||||
minadjpix(2)(9.50u) (Ccurve,Dcurve,Gcurve,Ocurve);
|
||||
fi
|
||||
else:
|
||||
adjpix(3.0u) (Mapex);
|
||||
minadjpix(1)(8.80u) (stem);
|
||||
minadjpix(2)(6.80u) (kdiag);
|
||||
minadjpix(2)(7.40u) (kstem);
|
||||
minadjpix(2)(7.80u) (Jbulb);
|
||||
minadjpix(1)(6.00u) (Mdiag);
|
||||
minadjpix(2)(8.20u) (Kdiag);
|
||||
minadjpix(2)(8.30u) (Gstem)
|
||||
minadjpix(2)(8.30u) (Mstem);
|
||||
minadjpix(2)(8.60u) (Lstem,Ustem,Ythick_diag);
|
||||
minadjpix(2)(8.50u) (Bstem,Ndiag,Rdiag,Xdiag,Zdiag);
|
||||
minadjpix(1)(8.50u) (Estem, Fstem);
|
||||
minadjpix(2)(8.90u) (Btopcurve);
|
||||
minadjpix(3)(9.30u) (Bbotcurve,Pcurve,Rcurve);
|
||||
minadjpix(3)(9.50u) (Ccurve,Dcurve,Gcurve,Ocurve);
|
||||
fi
|
||||
else:
|
||||
adjpix(3.0u) (Mapex);
|
||||
minadjpix(2)(8.80u) (stem);
|
||||
minadjpix(3)(6.80u) (kdiag);
|
||||
minadjpix(3)(7.40u) (kstem);
|
||||
minadjpix(3)(7.80u) (Jbulb);
|
||||
minadjpix(1)(5.00u) (Mdiag);
|
||||
minadjpix(3)(8.20u) (Kdiag);
|
||||
minadjpix(3)(8.30u) (Gstem);
|
||||
minadjpix(2)(8.30u) (Mstem);
|
||||
minadjpix(3)(8.60u) (Lstem,Ustem,Ythick_diag);
|
||||
minadjpix(3)(8.50u) (Estem,Fstem,Ndiag,Rdiag,Xdiag,Zdiag);
|
||||
minadjpix(2)(8.50u) (Bstem);
|
||||
minadjpix(3)(8.90u) (Btopcurve);
|
||||
minadjpix(3)(9.30u) (Bbotcurve,Pcurve,Rcurve);
|
||||
minadjpix(3)(9.50u) (Ccurve,Dcurve,Gcurve,Ocurve)
|
||||
fi
|
||||
else:
|
||||
minadjpix(4)(8.80u) (stem);
|
||||
minadjpix(4)(6.80u) (kdiag);
|
||||
minadjpix(4)(7.40u) (kstem);
|
||||
minadjpix(4)(7.80u) (Jbulb,Mdiag);
|
||||
minadjpix(4)(8.20u) (Kdiag);
|
||||
minadjpix(4)(8.30u) (Gstem,Mstem);
|
||||
minadjpix(4)(8.60u) (Lstem,Ustem,Ythick_diag);
|
||||
minadjpix(4)(8.50u) (Bstem,Estem,Fstem,Ndiag,Rdiag,Xdiag,Zdiag);
|
||||
minadjpix(4)(8.90u) (Btopcurve);
|
||||
minadjpix(5)(9.30u) (Bbotcurve,Pcurve,Rcurve);
|
||||
minadjpix(5)(9.50u) (Ccurve,Dcurve,Gcurve,Ocurve)
|
||||
fi;
|
||||
%%%% end of changes for version 2.1
|
||||
|
||||
boolean lowres; lowres:=width<50;
|
||||
highres_lowres(pullin) (.85)(1); % Emidarm
|
||||
highres_lowres(pulleven) (1)(1.3); % Etoparm,Tarms,Zarms
|
||||
highres_lowres(pullout) (1.1)(1); % Ebotarm,Lbotarm
|
||||
highres_lowres(bracket0) (.0)(0); % Ntopleft
|
||||
highres_lowres(bracket3) (.3)(0); % Nthinstems
|
||||
highres_lowres(bracket01) (.0)(.1); % Uthin
|
||||
highres_lowres(bracket32) (.3)(.2); % Vstems
|
||||
highres_lowres(bracket4) (.4)(0); % P-all,R-all,I-all,F-all
|
||||
highres_lowres(bracket42) (.4)(.2); % Xdiag
|
||||
|
||||
bool(ctrls):=false;
|
||||
entasis:=inlimit(0)(0,1);
|
||||
serif_constant_amt:=0pt;
|
||||
join_radius:=1;
|
||||
bool(softpath):=true;
|
||||
|
||||
c_thick_stem_bracket:=min(.5cap-eps,c_thick_stem_bracket);
|
||||
rulepen:=pensquare scaled 1;
|
||||
extra_beginchar:=extra_beginchar&"save t,p,ref; path p[],p[]',p[]'',ref[];";
|
||||
extra_beginchar:=extra_beginchar&"pickup pencircle scaled linethickness;";
|
||||
|
||||
for x:="R":
|
||||
wanted[byte x]:=true; endfor % test these characters
|
||||
let iff=always_iff; % tests all chars in the file
|
||||
|
||||
font_normal_space .3width#; % TeX fontdimen 2 normal word space
|
||||
font_normal_stretch .15width#; % TeX fontdimen 3 interword stretch
|
||||
font_normal_shrink .1width#; % TeX fontdimen 4 interword shrink
|
||||
font_x_height xheight#; % Tex fontdinem 5 for accents
|
||||
font_quad width#; % TeX fontdimen 6 quad width
|
||||
font_extra_space .1width#; % TeX fontdimen 7 extra space(period)
|
||||
|
||||
|
||||
input xbcaps
|
||||
bye % changed from "end" 26 Aug 93; bnb
|
@@ -1,5 +1,5 @@
|
||||
/* stylelint-disable font-family-no-missing-generic-family-keyword */
|
||||
@import "../submodules/katex-fonts/fonts.less";
|
||||
@import "fonts.less";
|
||||
|
||||
// The mu unit is defined as 1/18 em
|
||||
@mu: (1em / 18);
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* This can be used to define some commands in terms of others.
|
||||
*/
|
||||
|
||||
import fontMetricsData from "../submodules/katex-fonts/fontMetricsData";
|
||||
import fontMetricsData from "./fontMetricsData";
|
||||
import functions from "./functions";
|
||||
import symbols from "./symbols";
|
||||
import utils from "./utils";
|
||||
|
1
src/metrics/.gitignore
vendored
Normal file
1
src/metrics/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.pyc
|
23
src/metrics/README.md
Normal file
23
src/metrics/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
### How to generate new metrics
|
||||
-------------------------------
|
||||
|
||||
There are several requirements for generating the metrics used by KaTeX.
|
||||
|
||||
- You need to have an installation of TeX which supports kpathsea. You can check
|
||||
this by running `tex --version`, and seeing if it has a line that looks like
|
||||
> kpathsea version 6.2.0
|
||||
|
||||
- You need the Perl module `JSON`. You can install this either from CPAN
|
||||
(e.g. using the `cpan` command line tool: `cpan install JSON`)
|
||||
or with your package manager.
|
||||
|
||||
- You need the Python module `fonttools`. You can install this either from PyPI
|
||||
(using `easy_install` or `pip`: `pip install fonttools`)
|
||||
or with your package manager.
|
||||
|
||||
Once you have these things, run the following command from the root directory:
|
||||
|
||||
sh ./docker/fonts/buildMetrics.sh
|
||||
|
||||
which should generate new metrics and place them into `fontMetricsData.json`.
|
||||
You're done!
|
114
src/metrics/extract_tfms.py
Executable file
114
src/metrics/extract_tfms.py
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import collections
|
||||
import json
|
||||
import parse_tfm
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def find_font_path(font_name):
|
||||
try:
|
||||
font_path = subprocess.check_output(['kpsewhich', font_name])
|
||||
except OSError:
|
||||
raise RuntimeError("Couldn't find kpsewhich program, make sure you" +
|
||||
" have TeX installed")
|
||||
except subprocess.CalledProcessError:
|
||||
raise RuntimeError("Couldn't find font metrics: '%s'" % font_name)
|
||||
return font_path.strip()
|
||||
|
||||
|
||||
def main():
|
||||
mapping = json.load(sys.stdin)
|
||||
|
||||
fonts = [
|
||||
'cmbsy10.tfm',
|
||||
'cmbx10.tfm',
|
||||
'cmbxti10.tfm',
|
||||
'cmex10.tfm',
|
||||
'cmmi10.tfm',
|
||||
'cmmib10.tfm',
|
||||
'cmr10.tfm',
|
||||
'cmsy10.tfm',
|
||||
'cmti10.tfm',
|
||||
'msam10.tfm',
|
||||
'msbm10.tfm',
|
||||
'eufm10.tfm',
|
||||
'cmtt10.tfm',
|
||||
'rsfs10.tfm',
|
||||
'cmss10.tfm',
|
||||
'cmssbx10.tfm',
|
||||
'cmssi10.tfm',
|
||||
]
|
||||
|
||||
# Extracted by running `\font\a=<font>` and then `\showthe\skewchar\a` in
|
||||
# TeX, where `<font>` is the name of the font listed here. The skewchar
|
||||
# will be printed out in the output. If it outputs `-1`, that means there
|
||||
# is no skewchar, so we use `None` here.
|
||||
font_skewchar = {
|
||||
'cmbsy10': None,
|
||||
'cmbx10': None,
|
||||
'cmbxti10': None,
|
||||
'cmex10': None,
|
||||
'cmmi10': 127,
|
||||
'cmmib10': None,
|
||||
'cmr10': None,
|
||||
'cmsy10': 48,
|
||||
'cmti10': None,
|
||||
'msam10': None,
|
||||
'msbm10': None,
|
||||
'eufm10': None,
|
||||
'cmtt10': None,
|
||||
'rsfs10': None,
|
||||
'cmss10': None,
|
||||
'cmssbx10': None,
|
||||
'cmssi10': None,
|
||||
}
|
||||
|
||||
font_name_to_tfm = {}
|
||||
|
||||
for font_name in fonts:
|
||||
font_basename = font_name.split('.')[0]
|
||||
font_path = find_font_path(font_name)
|
||||
font_name_to_tfm[font_basename] = parse_tfm.read_tfm_file(font_path)
|
||||
|
||||
families = collections.defaultdict(dict)
|
||||
|
||||
for family, chars in mapping.iteritems():
|
||||
for char, char_data in chars.iteritems():
|
||||
char_num = int(char)
|
||||
|
||||
font = char_data['font']
|
||||
tex_char_num = int(char_data['char'])
|
||||
yshift = float(char_data['yshift'])
|
||||
|
||||
if family == "Script-Regular":
|
||||
tfm_char = font_name_to_tfm[font].get_char_metrics(tex_char_num,
|
||||
fix_rsfs=True)
|
||||
else:
|
||||
tfm_char = font_name_to_tfm[font].get_char_metrics(tex_char_num)
|
||||
|
||||
height = round(tfm_char.height + yshift / 1000.0, 5)
|
||||
depth = round(tfm_char.depth - yshift / 1000.0, 5)
|
||||
italic = round(tfm_char.italic_correction, 5)
|
||||
width = round(tfm_char.width, 5)
|
||||
|
||||
skewkern = 0.0
|
||||
if (font_skewchar[font] and
|
||||
font_skewchar[font] in tfm_char.kern_table):
|
||||
skewkern = round(
|
||||
tfm_char.kern_table[font_skewchar[font]], 5)
|
||||
|
||||
families[family][char_num] = {
|
||||
'height': height,
|
||||
'depth': depth,
|
||||
'italic': italic,
|
||||
'skew': skewkern,
|
||||
'width': width
|
||||
}
|
||||
|
||||
sys.stdout.write(
|
||||
json.dumps(families, separators=(',', ':'), sort_keys=True))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
119
src/metrics/extract_ttfs.py
Executable file
119
src/metrics/extract_ttfs.py
Executable file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from fontTools.ttLib import TTFont
|
||||
import sys
|
||||
import json
|
||||
|
||||
# map of characters to extract
|
||||
metrics_to_extract = {
|
||||
# Font name
|
||||
"AMS-Regular": {
|
||||
u"\u21e2": None, # \dashrightarrow
|
||||
u"\u21e0": None, # \dashleftarrow
|
||||
},
|
||||
"Main-Regular": {
|
||||
# Skew and italic metrics can't be easily parsed from the TTF. Instead,
|
||||
# we map each character to a "base character", which is a character
|
||||
# from the same font with correct italic and skew metrics. A character
|
||||
# maps to None if it doesn't have a base.
|
||||
|
||||
#u"\u2209": None, # \notin
|
||||
#u"\u2260": None, # \neq
|
||||
u"\u2245": None, # \cong
|
||||
u"\u2026": None, # \ldots
|
||||
u"\u22ef": None, # \cdots
|
||||
u"\u22f1": None, # \ddots
|
||||
u"\u22ee": None, # \vdots
|
||||
u"\u22ee": None, # \vdots
|
||||
u"\u22a8": None, # \models
|
||||
u"\u22c8": None, # \bowtie
|
||||
u"\u2250": None, # \doteq
|
||||
u"\u23b0": None, # \lmoustache
|
||||
u"\u23b1": None, # \rmoustache
|
||||
u"\u27ee": None, # \lgroup
|
||||
u"\u27ef": None, # \rgroup
|
||||
u"\u27f5": None, # \longleftarrow
|
||||
u"\u27f8": None, # \Longleftarrow
|
||||
u"\u27f6": None, # \longrightarrow
|
||||
u"\u27f9": None, # \Longrightarrow
|
||||
u"\u27f7": None, # \longleftrightarrow
|
||||
u"\u27fa": None, # \Longleftrightarrow
|
||||
u"\u21a6": None, # \mapsto
|
||||
u"\u27fc": None, # \longmapsto
|
||||
u"\u21a9": None, # \hookleftarrow
|
||||
u"\u21aa": None, # \hookrightarrow
|
||||
u"\u21cc": None, # \rightleftharpoons
|
||||
},
|
||||
"Size1-Regular": {
|
||||
u"\u222c": u"\u222b", # \iint, based on \int
|
||||
u"\u222d": u"\u222b", # \iiint, based on \int
|
||||
},
|
||||
"Size2-Regular": {
|
||||
u"\u222c": u"\u222b", # \iint, based on \int
|
||||
u"\u222d": u"\u222b", # \iiint, based on \int
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
start_json = json.load(sys.stdin)
|
||||
|
||||
for font in start_json:
|
||||
fontInfo = TTFont("../../fonts/KaTeX_" + font + ".ttf")
|
||||
glyf = fontInfo["glyf"]
|
||||
widths = fontInfo.getGlyphSet()
|
||||
unitsPerEm = float(fontInfo["head"].unitsPerEm)
|
||||
|
||||
# We keep ALL Unicode cmaps, not just fontInfo["cmap"].getcmap(3, 1).
|
||||
# This is playing it extra safe, since it reports inconsistencies.
|
||||
# Platform 0 is Unicode, platform 3 is Windows. For platform 3,
|
||||
# encoding 1 is UCS-2 and encoding 10 is UCS-4.
|
||||
cmap = [t.cmap for t in fontInfo["cmap"].tables
|
||||
if (t.platformID == 0)
|
||||
or (t.platformID == 3 and t.platEncID in (1, 10))]
|
||||
|
||||
chars = metrics_to_extract.get(font, {})
|
||||
chars[u"\u0020"] = None # space
|
||||
chars[u"\u00a0"] = None # nbsp
|
||||
|
||||
for char, base_char in chars.iteritems():
|
||||
code = ord(char)
|
||||
names = set(t.get(code) for t in cmap)
|
||||
if not names:
|
||||
sys.stderr.write(
|
||||
"Codepoint {} of font {} maps to no name\n"
|
||||
.format(code, font))
|
||||
continue
|
||||
if len(names) != 1:
|
||||
sys.stderr.write(
|
||||
"Codepoint {} of font {} maps to multiple names: {}\n"
|
||||
.format(code, font, ", ".join(sorted(names))))
|
||||
continue
|
||||
name = names.pop()
|
||||
|
||||
height = depth = italic = skew = width = 0
|
||||
glyph = glyf[name]
|
||||
if glyph.numberOfContours:
|
||||
height = glyph.yMax / unitsPerEm
|
||||
depth = -glyph.yMin / unitsPerEm
|
||||
width = widths[name].width / unitsPerEm
|
||||
if base_char:
|
||||
base_char_str = str(ord(base_char))
|
||||
base_metrics = start_json[font][base_char_str]
|
||||
italic = base_metrics["italic"]
|
||||
skew = base_metrics["skew"]
|
||||
width = base_metrics["width"]
|
||||
|
||||
start_json[font][str(code)] = {
|
||||
"height": height,
|
||||
"depth": depth,
|
||||
"italic": italic,
|
||||
"skew": skew,
|
||||
"width": width
|
||||
}
|
||||
|
||||
sys.stdout.write(
|
||||
json.dumps(start_json, separators=(',', ':'), sort_keys=True))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
28
src/metrics/format_json.py
Normal file
28
src/metrics/format_json.py
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import json
|
||||
|
||||
props = ['depth', 'height', 'italic', 'skew']
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
if sys.argv[1] == '--width':
|
||||
props.append('width')
|
||||
|
||||
data = json.load(sys.stdin)
|
||||
sys.stdout.write(
|
||||
"// This file is GENERATED by buildMetrics.sh. DO NOT MODIFY.\n")
|
||||
sep = "export default {\n "
|
||||
for font in sorted(data):
|
||||
sys.stdout.write(sep + json.dumps(font))
|
||||
sep = ": {\n "
|
||||
for glyph in sorted(data[font], key=int):
|
||||
sys.stdout.write(sep + json.dumps(glyph) + ": ")
|
||||
|
||||
values = [value if value != 0.0 else 0 for value in
|
||||
[data[font][glyph][key] for key in props]]
|
||||
|
||||
sys.stdout.write(json.dumps(values))
|
||||
sep = ",\n "
|
||||
sep = ",\n },\n "
|
||||
sys.stdout.write(",\n },\n};\n")
|
1224
src/metrics/mapping.pl
Executable file
1224
src/metrics/mapping.pl
Executable file
File diff suppressed because it is too large
Load Diff
211
src/metrics/parse_tfm.py
Normal file
211
src/metrics/parse_tfm.py
Normal file
@@ -0,0 +1,211 @@
|
||||
class CharInfoWord(object):
|
||||
def __init__(self, word):
|
||||
b1, b2, b3, b4 = (word >> 24,
|
||||
(word & 0xff0000) >> 16,
|
||||
(word & 0xff00) >> 8,
|
||||
word & 0xff)
|
||||
|
||||
self.width_index = b1
|
||||
self.height_index = b2 >> 4
|
||||
self.depth_index = b2 & 0x0f
|
||||
self.italic_index = (b3 & 0b11111100) >> 2
|
||||
self.tag = b3 & 0b11
|
||||
self.remainder = b4
|
||||
|
||||
def has_ligkern(self):
|
||||
return self.tag == 1
|
||||
|
||||
def ligkern_start(self):
|
||||
return self.remainder
|
||||
|
||||
|
||||
class LigKernProgram(object):
|
||||
def __init__(self, program):
|
||||
self.program = program
|
||||
|
||||
def execute(self, start, next_char):
|
||||
curr_instruction = start
|
||||
while True:
|
||||
instruction = self.program[curr_instruction]
|
||||
(skip, inst_next_char, op, remainder) = instruction
|
||||
|
||||
if inst_next_char == next_char:
|
||||
if op < 128:
|
||||
# Don't worry about ligatures for now, we only need kerns
|
||||
return None
|
||||
else:
|
||||
return 256 * (op - 128) + remainder
|
||||
elif skip >= 128:
|
||||
return None
|
||||
else:
|
||||
curr_instruction += 1 + skip
|
||||
|
||||
|
||||
class TfmCharMetrics(object):
|
||||
def __init__(self, width, height, depth, italic, kern_table):
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.depth = depth
|
||||
self.italic_correction = italic
|
||||
self.kern_table = kern_table
|
||||
|
||||
|
||||
class TfmFile(object):
|
||||
def __init__(self, start_char, end_char, char_info, width_table,
|
||||
height_table, depth_table, italic_table, ligkern_table,
|
||||
kern_table):
|
||||
self.start_char = start_char
|
||||
self.end_char = end_char
|
||||
self.char_info = char_info
|
||||
self.width_table = width_table
|
||||
self.height_table = height_table
|
||||
self.depth_table = depth_table
|
||||
self.italic_table = italic_table
|
||||
self.ligkern_program = LigKernProgram(ligkern_table)
|
||||
self.kern_table = kern_table
|
||||
|
||||
def get_char_metrics(self, char_num, fix_rsfs=False):
|
||||
"""Return glyph metrics for a unicode code point.
|
||||
|
||||
Arguments:
|
||||
char_num: a unicode code point
|
||||
fix_rsfs: adjust for rsfs10.tfm's different indexing system
|
||||
"""
|
||||
if char_num < self.start_char or char_num > self.end_char:
|
||||
raise RuntimeError("Invalid character number")
|
||||
|
||||
if fix_rsfs:
|
||||
# all of the char_nums contained start from zero in rsfs10.tfm
|
||||
info = self.char_info[char_num - self.start_char]
|
||||
else:
|
||||
info = self.char_info[char_num + self.start_char]
|
||||
|
||||
char_kern_table = {}
|
||||
if info.has_ligkern():
|
||||
for char in range(self.start_char, self.end_char + 1):
|
||||
kern = self.ligkern_program.execute(info.ligkern_start(), char)
|
||||
if kern:
|
||||
char_kern_table[char] = self.kern_table[kern]
|
||||
|
||||
return TfmCharMetrics(
|
||||
self.width_table[info.width_index],
|
||||
self.height_table[info.height_index],
|
||||
self.depth_table[info.depth_index],
|
||||
self.italic_table[info.italic_index],
|
||||
char_kern_table)
|
||||
|
||||
|
||||
class TfmReader(object):
|
||||
def __init__(self, f):
|
||||
self.f = f
|
||||
|
||||
def read_byte(self):
|
||||
return ord(self.f.read(1))
|
||||
|
||||
def read_halfword(self):
|
||||
b1 = self.read_byte()
|
||||
b2 = self.read_byte()
|
||||
return (b1 << 8) | b2
|
||||
|
||||
def read_word(self):
|
||||
b1 = self.read_byte()
|
||||
b2 = self.read_byte()
|
||||
b3 = self.read_byte()
|
||||
b4 = self.read_byte()
|
||||
return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4
|
||||
|
||||
def read_fixword(self):
|
||||
word = self.read_word()
|
||||
|
||||
neg = False
|
||||
if word & 0x80000000:
|
||||
neg = True
|
||||
word = (-word & 0xffffffff)
|
||||
|
||||
return (-1 if neg else 1) * word / float(1 << 20)
|
||||
|
||||
def read_bcpl(self, length):
|
||||
str_length = self.read_byte()
|
||||
data = self.f.read(length - 1)
|
||||
return data[:str_length]
|
||||
|
||||
|
||||
def read_tfm_file(file_name):
|
||||
with open(file_name, 'rb') as f:
|
||||
reader = TfmReader(f)
|
||||
|
||||
# file_size
|
||||
reader.read_halfword()
|
||||
header_size = reader.read_halfword()
|
||||
|
||||
start_char = reader.read_halfword()
|
||||
end_char = reader.read_halfword()
|
||||
|
||||
width_table_size = reader.read_halfword()
|
||||
height_table_size = reader.read_halfword()
|
||||
depth_table_size = reader.read_halfword()
|
||||
italic_table_size = reader.read_halfword()
|
||||
|
||||
ligkern_table_size = reader.read_halfword()
|
||||
kern_table_size = reader.read_halfword()
|
||||
|
||||
# extensible_table_size
|
||||
reader.read_halfword()
|
||||
# parameter_table_size
|
||||
reader.read_halfword()
|
||||
|
||||
# checksum
|
||||
reader.read_word()
|
||||
# design_size
|
||||
reader.read_fixword()
|
||||
|
||||
if header_size > 2:
|
||||
# coding_scheme
|
||||
reader.read_bcpl(40)
|
||||
|
||||
if header_size > 12:
|
||||
# font_family
|
||||
reader.read_bcpl(20)
|
||||
|
||||
for i in range(header_size - 17):
|
||||
reader.read_word()
|
||||
|
||||
char_info = []
|
||||
for i in range(start_char, end_char + 1):
|
||||
char_info.append(CharInfoWord(reader.read_word()))
|
||||
|
||||
width_table = []
|
||||
for i in range(width_table_size):
|
||||
width_table.append(reader.read_fixword())
|
||||
|
||||
height_table = []
|
||||
for i in range(height_table_size):
|
||||
height_table.append(reader.read_fixword())
|
||||
|
||||
depth_table = []
|
||||
for i in range(depth_table_size):
|
||||
depth_table.append(reader.read_fixword())
|
||||
|
||||
italic_table = []
|
||||
for i in range(italic_table_size):
|
||||
italic_table.append(reader.read_fixword())
|
||||
|
||||
ligkern_table = []
|
||||
for i in range(ligkern_table_size):
|
||||
skip = reader.read_byte()
|
||||
next_char = reader.read_byte()
|
||||
op = reader.read_byte()
|
||||
remainder = reader.read_byte()
|
||||
|
||||
ligkern_table.append((skip, next_char, op, remainder))
|
||||
|
||||
kern_table = []
|
||||
for i in range(kern_table_size):
|
||||
kern_table.append(reader.read_fixword())
|
||||
|
||||
# There is more information, like the ligkern, kern, extensible, and
|
||||
# param table, but we don't need these for now
|
||||
|
||||
return TfmFile(start_char, end_char, char_info, width_table,
|
||||
height_table, depth_table, italic_table,
|
||||
ligkern_table, kern_table)
|
Submodule submodules/katex-fonts deleted from 56e79c93c8
@@ -15,7 +15,6 @@ module.exports = function(wallaby) {
|
||||
"src/**/*.js",
|
||||
"test/**/*.js",
|
||||
"contrib/**/*.js",
|
||||
"submodules/**/*.js",
|
||||
"katex.js",
|
||||
|
||||
// These paths are excluded.
|
||||
|
Reference in New Issue
Block a user