🔢

Next.jsでTeXを表示

2023/02/08に公開

はじめに

Next.js で react-katex を使い TeX の数式を表示する方法を紹介します。

ソースは以下を参照ください
https://github.com/hayato94087/nextjs-react-katex

TeXとは❓

TeX とは、テキストを数式に変換するためのプログラムです。

下記のように数式を記載します。

$$ \frac{1}{2} $$

以下のように変換されます。

\frac{1}{2}

下記のように数式を記載します。

$$ S=\sum_{n=1}^\infty a_n $$

以下のように変換されます。

S=\sum_{n=1}^\infty a_n

インラインで記載する場合は以下のように記載します。

x^2 + y^2 = 1 をインライン表示すると $x^2 + y^2 = 1$ になります。

以下のように変換されます。

x^2 + y^2 = 1 をインライン表示すると x^2 + y^2 = 1 になります。

react-katex

  • KaTeXとは、ウェブで TeX を表示するためのライブラリです。
  • react-katexというライブラリを使うと、KaTeX をコンポーネントとして利用できます。

Next.jsのプロジェクト作成

Next.js をインストールします。

コマンド
$ yarn create next-app nextjs-tex --typescript --eslint --src-dir --import-alias "@/*"

実施結果

yarn create v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Installed "create-next-app@13.1.6" with binaries:
      - create-next-app
? Would you like to use experimental `app/` directory with this project? › No / ✔ Would you like to use experimental `app/` directory with this project? … No / Yes
Creating a new Next.js app in /Users/hayato94087/Work/nextjs-tex.

Using yarn.

Installing dependencies:
- react
- react-dom
- next
- @next/font
- typescript
- @types/react
- @types/node
- @types/react-dom
- eslint
- eslint-config-next

yarn add v1.22.19
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
success Saved 196 new dependencies.
info Direct dependencies
├─ @next/font@13.1.6
├─ @types/node@18.13.0
├─ @types/react-dom@18.0.10
├─ @types/react@18.0.27
├─ eslint-config-next@13.1.6
├─ eslint@8.33.0
├─ next@13.1.6
├─ react-dom@18.2.0
├─ react@18.2.0
└─ typescript@4.9.5
info All dependencies
├─ @babel/runtime@7.20.13
├─ @eslint/eslintrc@1.4.1
├─ @humanwhocodes/config-array@0.11.8
├─ @humanwhocodes/module-importer@1.0.1
├─ @humanwhocodes/object-schema@1.2.1
├─ @next/env@13.1.6
├─ @next/eslint-plugin-next@13.1.6
├─ @next/font@13.1.6
├─ @next/swc-darwin-x64@13.1.6
├─ @nodelib/fs.scandir@2.1.5
├─ @nodelib/fs.stat@2.0.5
├─ @nodelib/fs.walk@1.2.8
├─ @pkgr/utils@2.3.1
├─ @rushstack/eslint-patch@1.2.0
├─ @swc/helpers@0.4.14
├─ @types/json5@0.0.29
├─ @types/node@18.13.0
├─ @types/prop-types@15.7.5
├─ @types/react-dom@18.0.10
├─ @types/react@18.0.27
├─ @types/scheduler@0.16.2
├─ @typescript-eslint/parser@5.51.0
├─ @typescript-eslint/scope-manager@5.51.0
├─ @typescript-eslint/typescript-estree@5.51.0
├─ acorn-jsx@5.3.2
├─ acorn@8.8.2
├─ ajv@6.12.6
├─ ansi-regex@5.0.1
├─ ansi-styles@4.3.0
├─ argparse@2.0.1
├─ aria-query@5.1.3
├─ array-includes@3.1.6
├─ array-union@2.1.0
├─ array.prototype.flat@1.3.1
├─ array.prototype.tosorted@1.1.1
├─ ast-types-flow@0.0.7
├─ axe-core@4.6.3
├─ axobject-query@3.1.1
├─ balanced-match@1.0.2
├─ brace-expansion@1.1.11
├─ braces@3.0.2
├─ callsites@3.1.0
├─ caniuse-lite@1.0.30001450
├─ chalk@4.1.2
├─ client-only@0.0.1
├─ color-convert@2.0.1
├─ color-name@1.1.4
├─ concat-map@0.0.1
├─ cross-spawn@7.0.3
├─ csstype@3.1.1
├─ damerau-levenshtein@1.0.8
├─ deep-is@0.1.4
├─ define-lazy-prop@2.0.0
├─ emoji-regex@9.2.2
├─ enhanced-resolve@5.12.0
├─ es-get-iterator@1.1.3
├─ es-set-tostringtag@2.0.1
├─ es-to-primitive@1.2.1
├─ escape-string-regexp@4.0.0
├─ eslint-config-next@13.1.6
├─ eslint-import-resolver-node@0.3.7
├─ eslint-import-resolver-typescript@3.5.3
├─ eslint-module-utils@2.7.4
├─ eslint-plugin-import@2.27.5
├─ eslint-plugin-jsx-a11y@6.7.1
├─ eslint-plugin-react-hooks@4.6.0
├─ eslint-plugin-react@7.32.2
├─ eslint-scope@7.1.1
├─ eslint-utils@3.0.0
├─ eslint@8.33.0
├─ esquery@1.4.0
├─ esrecurse@4.3.0
├─ estraverse@5.3.0
├─ fast-deep-equal@3.1.3
├─ fast-glob@3.2.12
├─ fast-json-stable-stringify@2.1.0
├─ fast-levenshtein@2.0.6
├─ fastq@1.15.0
├─ file-entry-cache@6.0.1
├─ fill-range@7.0.1
├─ find-up@5.0.0
├─ flat-cache@3.0.4
├─ flatted@3.2.7
├─ function.prototype.name@1.1.5
├─ get-symbol-description@1.0.0
├─ get-tsconfig@4.4.0
├─ glob-parent@6.0.2
├─ glob@7.1.7
├─ globalthis@1.0.3
├─ globalyzer@0.1.0
├─ globby@13.1.3
├─ globrex@0.1.2
├─ graceful-fs@4.2.10
├─ grapheme-splitter@1.0.4
├─ has-bigints@1.0.2
├─ has-flag@4.0.0
├─ has-proto@1.0.1
├─ import-fresh@3.3.0
├─ imurmurhash@0.1.4
├─ is-bigint@1.0.4
├─ is-boolean-object@1.1.2
├─ is-callable@1.2.7
├─ is-date-object@1.0.5
├─ is-docker@2.2.1
├─ is-extglob@2.1.1
├─ is-map@2.0.2
├─ is-negative-zero@2.0.2
├─ is-number-object@1.0.7
├─ is-number@7.0.0
├─ is-path-inside@3.0.3
├─ is-set@2.0.2
├─ is-string@1.0.7
├─ is-symbol@1.0.4
├─ is-weakmap@2.0.1
├─ is-weakref@1.0.2
├─ is-weakset@2.0.2
├─ is-wsl@2.2.0
├─ isexe@2.0.0
├─ js-sdsl@4.3.0
├─ js-tokens@4.0.0
├─ json-schema-traverse@0.4.1
├─ json-stable-stringify-without-jsonify@1.0.1
├─ json5@1.0.2
├─ jsx-ast-utils@3.3.3
├─ language-subtag-registry@0.3.22
├─ language-tags@1.0.5
├─ locate-path@6.0.0
├─ lodash.merge@4.6.2
├─ loose-envify@1.4.0
├─ lru-cache@6.0.0
├─ micromatch@4.0.5
├─ minimatch@3.1.2
├─ minimist@1.2.7
├─ ms@2.1.2
├─ nanoid@3.3.4
├─ natural-compare@1.4.0
├─ next@13.1.6
├─ object-assign@4.1.1
├─ object-inspect@1.12.3
├─ object-is@1.1.5
├─ object.hasown@1.1.2
├─ open@8.4.0
├─ optionator@0.9.1
├─ p-limit@3.1.0
├─ p-locate@5.0.0
├─ parent-module@1.0.1
├─ path-exists@4.0.0
├─ path-key@3.1.1
├─ path-type@4.0.0
├─ picomatch@2.3.1
├─ postcss@8.4.14
├─ prop-types@15.8.1
├─ punycode@2.3.0
├─ queue-microtask@1.2.3
├─ react-dom@18.2.0
├─ react-is@16.13.1
├─ react@18.2.0
├─ regenerator-runtime@0.13.11
├─ regexpp@3.2.0
├─ resolve-from@4.0.0
├─ reusify@1.0.4
├─ rimraf@3.0.2
├─ run-parallel@1.2.0
├─ safe-regex-test@1.0.0
├─ scheduler@0.23.0
├─ shebang-command@2.0.0
├─ shebang-regex@3.0.0
├─ slash@4.0.0
├─ source-map-js@1.0.2
├─ stop-iteration-iterator@1.0.0
├─ string.prototype.matchall@4.0.8
├─ string.prototype.trimend@1.0.6
├─ string.prototype.trimstart@1.0.6
├─ strip-ansi@6.0.1
├─ strip-bom@3.0.0
├─ strip-json-comments@3.1.1
├─ styled-jsx@5.1.1
├─ supports-color@7.2.0
├─ synckit@0.8.5
├─ tapable@2.2.1
├─ text-table@0.2.0
├─ tiny-glob@0.2.9
├─ to-regex-range@5.0.1
├─ tsconfig-paths@3.14.1
├─ tsutils@3.21.0
├─ type-check@0.4.0
├─ type-fest@0.20.2
├─ typed-array-length@1.0.4
├─ typescript@4.9.5
├─ unbox-primitive@1.0.2
├─ uri-js@4.4.1
├─ which-collection@1.0.1
├─ which@2.0.2
├─ word-wrap@1.2.3
├─ yallist@4.0.0
└─ yocto-queue@0.1.0
✨  Done in 8.05s.

Initializing project with template: default

Initialized a git repository.

Success! Created nextjs-tex at /Users/hayato94087/Work/nextjs-tex

✨  Done in 12.46s.

KaTexのインストール

KaTex は TeX の数式を HTML に変換するライブラリです。

react-katexは React から KaTex を使うためのライブラリです。

$ yarn add react-katex
$ yarn add -D @types/react-katex

実行結果

yarn add v1.22.19
warning ../package.json: No license field
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
warning " > react-katex@3.0.1" has unmet peer dependency "prop-types@^15.8.1".
[4/4] 🔨  Building fresh packages...
success Saved 1 new dependency.
info Direct dependencies
└─ @types/react-katex@3.0.0
info All dependencies
└─ @types/react-katex@3.0.0
✨  Done in 1.23s.

ページの作成

src/pages/index.tsx
import { InlineMath, BlockMath } from 'react-katex';
import 'katex/dist/katex.min.css';

const Home = () => {
  return (
    <>
      <InlineMath>\int_0^\infty x^2 dx</InlineMath>
    </>
  );
};

export default Home;

動作確認

ローカルで動作確認を行います。

$ yarn dev

実行結果

yarn run v1.22.19
warning ../package.json: No license field
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
event - compiled client and server successfully in 1426 ms (165 modules)
wait  - compiling / (client and server)...

以下が実行結果です。数式が表示されています。

まとめ

Next.js で react-katex を使い TeX の数式を表示する方法を紹介しました。

参考

KaTeX の公式サイト
https://katex.org/

KaTeX の Github
https://github.com/KaTeX/KaTeX

KaTeX の使い方
https://manabitimes.jp/katex

react-katex の npm
https://www.npmjs.com/package/react-katex

react-katex の Github リポジトリ
https://github.com/talyssonoc/react-katex

Discussion