3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Latex-workshopにサポートされていないパッケージ(physics2)の補完を追加する

Last updated at Posted at 2024-02-05

Abstract

LatexをVSCodeで書いていますか?もちろん書いていますよね?
VSCodeでLatexを書く上で、Latex Workshopを使っていない人はいないでしょう。

またVSCodeを用いて論文を書く上で、physicsパッケージを使っている人は多いでしょう。しかしながら、近年では脱physicsパッケージが叫ばれています。

physicsの代わりにphysics2パッケージを使おうという提案がなされていますが、実はLatex Workshopからはコマンドや環境の補完が提供されていません。

2024/03/14追記: issueを立てたところ、補完が追加されました! 対応するcommitはこれです。

補完を増やすためには、専用のjson形式が必要ですが、これについて解説している日本語情報は知る限り一つしかありません。
また既存パッケージに対して、補完のためのjsonファイルを生成する方法を解説した記事はありません。

そこで本記事では、physics2をパッケージの補完をLatex Workshopに追加する方法を紹介します。
Latex Workshopに補完を追加するために、専用の形式のjsonファイルが必要です。
そのため、補完のためのphysics2.jsonを、Latex Workshopが提供する公式のPythonスクリプトを用いて生成します。

環境

本記事では、下記の環境で作業を行います。

VSCode 1.86.0
Latex Workshop 9.18.0
Python 3.10.9
Windows 10

一番大事なのは、Latex Workshopのバージョンです。
補完ファイルの形式が直近に変更されているようです。

Latex-Workshop

Latex Workshopは、言わずと知れた最強のLatex用拡張機能です。
通常、\usepackage{hoge}とすることで、hogeパッケージのコマンドが補完に出ます。
ただし、もちろんですが自作のスタイルファイルやパッケージの場合は、補完ファイルを自作する必要があります。

ただ、physics2パッケージとか、既存のパッケージの補完jsonファイルを手打ちするのは嫌ですね!
というわけで公式リポジトリを眺めていると、cwlファイルからjsonを生成する仕組みがありました。

Pythonスクリプトのpkgcommand.pyが、補完用jsonを生成するようです。
つまりcwlファイルさえあればオッケーです!

LAtex Workshopにパッケージの補完の追加

ファイルの生成と、Latex Workshopが補完ファイルを読み込むフォルダに配置するステップからなります。

補完ファイル(physics2.json)を生成

下記の流れで作成します。

  1. 公式リポジトリをclone
  2. cwlを探してダウンロード
  3. 公式リポジトリのdevフォルダーのPythonスクリプトを実行

PowerShellでは次のコマンドに相当します。

# 公式リポジトリのclone
git clone https://github.com/James-Yu/LaTeX-Workshop.git
cd LaTeX-Workshop\dev
# 「physics2 cwl」で検索すると、texstudio 用の補完ファイルが見つかりました。
Invoke-WebRequest https://github.com/texstudio-org/texstudio/blob/master/completion/physics2.cwl -OutFile physics2.cwl

# 下準備
python -u .\unimathsymbols.py
mkdir out

# json生成!
python -u .\pkgcommand.py -i .\physics2.cwl -o out

これでoutフォルダにphysics2.jsonが生成されています。

出てくるphysics2.jsonの中身
physics2.json
{
  "includes": {
    "keyval": [],
    "amsmath": []
  },
  "macros": {
    "usephysicsmodule{}": {
      "snippet": "usephysicsmodule{${1:modules}}"
    },
    "usephysicsmodule[]{}": {
      "snippet": "usephysicsmodule[${2:options}]{${1:modules}}",
      "keyvalindex": 0,
      "keyvalpos": 0
    },
    "ab": {
      "snippet": "ab( $1 )$0"
    },
    "pab{}": {
      "snippet": "pab{${1:arg}}"
    },
    "pab*{}": {
      "snippet": "pab*{${1:arg}}"
    },
    "pab[]{}": {
      "snippet": "pab[${2:size}]{${1:arg}}"
    },
    "bab{}": {
      "snippet": "bab{${1:arg}}"
    },
    "bab*{}": {
      "snippet": "bab*{${1:arg}}"
    },
    "bab[]{}": {
      "snippet": "bab[${2:size}]{${1:arg}}"
    },
    "Bab{}": {
      "snippet": "Bab{${1:arg}}"
    },
    "Bab*{}": {
      "snippet": "Bab*{${1:arg}}"
    },
    "Bab[]{}": {
      "snippet": "Bab[${2:size}]{${1:arg}}"
    },
    "vab{}": {
      "snippet": "vab{${1:arg}}"
    },
    "vab*{}": {
      "snippet": "vab*{${1:arg}}"
    },
    "vab[]{}": {
      "snippet": "vab[${2:size}]{${1:arg}}"
    },
    "aab{}": {
      "snippet": "aab{${1:arg}}"
    },
    "aab*{}": {
      "snippet": "aab*{${1:arg}}"
    },
    "aab[]{}": {
      "snippet": "aab[${2:size}]{${1:arg}}"
    },
    "Vab{}": {
      "snippet": "Vab{${1:arg}}"
    },
    "Vab*{}": {
      "snippet": "Vab*{${1:arg}}"
    },
    "Vab[]{}": {
      "snippet": "Vab[${2:size}]{${1:arg}}"
    },
    "ketbra": {
      "snippet": "ketbra|subformula1>${1:optional}<subformula2|"
    },
    "ketbra*": {
      "snippet": "ketbra*|subformula1>${1:optional}<subformula2|"
    },
    "diagmat{}": {
      "snippet": "diagmat{${1:entry1,entry2,...}}"
    },
    "diagmat[]{}": {
      "snippet": "diagmat[${2:empty=entry}]{${1:entry1,entry2,...}}"
    },
    "pdiagmat{}": {
      "snippet": "pdiagmat{${1:entry1,entry2,...}}"
    },
    "pdiagmat[]{}": {
      "snippet": "pdiagmat[${2:empty=entry}]{${1:entry1,entry2,...}}"
    },
    "bdiagmat{}": {
      "snippet": "bdiagmat{${1:entry1,entry2,...}}"
    },
    "bdiagmat[]{}": {
      "snippet": "bdiagmat[${2:empty=entry}]{${1:entry1,entry2,...}}"
    },
    "Bdiagmat{}": {
      "snippet": "Bdiagmat{${1:entry1,entry2,...}}"
    },
    "Bdiagmat[]{}": {
      "snippet": "Bdiagmat[${2:empty=entry}]{${1:entry1,entry2,...}}"
    },
    "vdiagmat{}": {
      "snippet": "vdiagmat{${1:entry1,entry2,...}}"
    },
    "vdiagmat[]{}": {
      "snippet": "vdiagmat[${2:empty=entry}]{${1:entry1,entry2,...}}"
    },
    "Vdiagmat{}": {
      "snippet": "Vdiagmat{${1:entry1,entry2,...}}"
    },
    "Vdiagmat[]{}": {
      "snippet": "Vdiagmat[${2:empty=entry}]{${1:entry1,entry2,...}}"
    },
    "doublecross": {},
    "doubledot": {},
    "xmat{}{}{}": {
      "snippet": "xmat{${1:entry}}{${2:rows shown}}{${3:cols shown}}"
    },
    "xmat[]{}{}{}": {
      "snippet": "xmat[${4:options}]{${1:entry}}{${2:rows shown}}{${3:cols shown}}",
      "keyvalindex": 1,
      "keyvalpos": 0
    },
    "pxmat{}{}{}": {
      "snippet": "pxmat{${1:entry}}{${2:rows shown}}{${3:cols shown}}"
    },
    "pxmat[]{}{}{}": {
      "snippet": "pxmat[${4:options}]{${1:entry}}{${2:rows shown}}{${3:cols shown}}",
      "keyvalindex": 1,
      "keyvalpos": 0
    },
    "bxmat{}{}{}": {
      "snippet": "bxmat{${1:entry}}{${2:rows shown}}{${3:cols shown}}"
    },
    "bxmat[]{}{}{}": {
      "snippet": "bxmat[${4:options}]{${1:entry}}{${2:rows shown}}{${3:cols shown}}",
      "keyvalindex": 1,
      "keyvalpos": 0
    },
    "Bxmat{}{}{}": {
      "snippet": "Bxmat{${1:entry}}{${2:rows shown}}{${3:cols shown}}"
    },
    "Bxmat[]{}{}{}": {
      "snippet": "Bxmat[${4:options}]{${1:entry}}{${2:rows shown}}{${3:cols shown}}",
      "keyvalindex": 1,
      "keyvalpos": 0
    },
    "vxmat{}{}{}": {
      "snippet": "vxmat{${1:entry}}{${2:rows shown}}{${3:cols shown}}"
    },
    "vxmat[]{}{}{}": {
      "snippet": "vxmat[${4:options}]{${1:entry}}{${2:rows shown}}{${3:cols shown}}",
      "keyvalindex": 1,
      "keyvalpos": 0
    },
    "Vxmat{}{}{}": {
      "snippet": "Vxmat{${1:entry}}{${2:rows shown}}{${3:cols shown}}"
    },
    "Vxmat[]{}{}{}": {
      "snippet": "Vxmat[${4:options}]{${1:entry}}{${2:rows shown}}{${3:cols shown}}",
      "keyvalindex": 1,
      "keyvalpos": 0
    },
    "abs{}": {
      "snippet": "abs{${1:arg}}"
    },
    "abs*{}": {
      "snippet": "abs*{${1:arg}}"
    },
    "abs[]{}": {
      "snippet": "abs[${2:size}]{${1:arg}}"
    },
    "norm{}": {
      "snippet": "norm{${1:arg}}"
    },
    "norm*{}": {
      "snippet": "norm*{${1:arg}}"
    },
    "norm[]{}": {
      "snippet": "norm[${2:size}]{${1:arg}}"
    },
    "eval{}": {
      "snippet": "eval{${1:arg}}"
    },
    "eval*{}": {
      "snippet": "eval*{${1:arg}}"
    },
    "eval[]{}": {
      "snippet": "eval[${2:size}]{${1:arg}}"
    },
    "peval{}": {
      "snippet": "peval{${1:arg}}"
    },
    "peval*{}": {
      "snippet": "peval*{${1:arg}}"
    },
    "peval[]{}": {
      "snippet": "peval[${2:size}]{${1:arg}}"
    },
    "beval{}": {
      "snippet": "beval{${1:arg}}"
    },
    "beval*{}": {
      "snippet": "beval*{${1:arg}}"
    },
    "beval[]{}": {
      "snippet": "beval[${2:size}]{${1:arg}}"
    },
    "order{}": {
      "snippet": "order{${1:arg}}"
    },
    "order*{}": {
      "snippet": "order*{${1:arg}}"
    },
    "order[]{}": {
      "snippet": "order[${2:size}]{${1:arg}}"
    },
    "bm{}": {
      "snippet": "bm{${1:letter}}"
    },
    "grad": {},
    "curl": {},
    "laplacian": {},
    "asin": {},
    "acos": {},
    "atan": {},
    "acsc": {},
    "asec": {},
    "acot": {},
    "Tr": {},
    "tr": {},
    "rank": {},
    "erf": {},
    "Res": {},
    "res": {},
    "PV": {},
    "pv": {},
    "Resymbol": {},
    "Imsymbol": {},
    "qqtext{}": {
      "snippet": "qqtext{${1:text}}"
    },
    "qqtext*{}": {
      "snippet": "qqtext*{${1:text}}"
    },
    "qq{}": {
      "snippet": "qq{${1:text}}"
    },
    "qq*{}": {
      "snippet": "qq*{${1:text}}"
    },
    "qcomma": {},
    "qc": {},
    "qcc": {},
    "qcc*": {},
    "qif": {},
    "qthen": {},
    "qelse": {},
    "qotherwise": {},
    "qunless": {},
    "qgive": {},
    "qusing": {},
    "qassume": {},
    "qsince": {},
    "qlet": {},
    "qfor": {},
    "qall": {},
    "qeven": {},
    "qodd": {},
    "qinteger": {},
    "qand": {},
    "qor": {},
    "qas": {},
    "qin": {}
  },
  "envs": {},
  "options": [],
  "keyvals": [
    [
      "ab.braket",
      "ab.legacy",
      "ab",
      "bm-um.legacy",
      "braket",
      "diagmat",
      "doubleprod",
      "nabla.legacy",
      "op.legacy",
      "qtext.legacy",
      "xmat"
    ],
    [
      "showtop=${1:rows}",
      "showleft=${1:columns}",
      "format=${1:format code}"
    ]
  ]
}

jsonファイルの配置

拡張機能が補完ファイルを読み込むフォルダにphysics2.jsonを配置します。
Windowsでは、次のようなフォルダに相当します。
C:\Users\TakeMe\.vscode\extensions\james-yu.latex-workshop-x.x.x\data\packages

これで\usepackage{physics2}とするとLatexを書くときに補完が有効になります!
usephysicsmodule{}のコマンド自体と読み込むモジュールの選択肢も補完されます!

結論

本記事では、Latex Workshopが対応していないパッケージの補完を追加する方法を紹介しました。
特に、pyhsicsの代替として有効なphysics2パッケージに注目して、その補完ファイルの作成を行いました。
本記事の方法は、cwlファイルさえあればどんなパッケージでもLatex Workshopに対応できるので、参考にしてください。

参考文献

  • LaTeX Workshop を使いこなす
    • Latex Workshopを用いたVSCodeの環境構築記事

  • LaTeX Workshop のインテリセンスをカスタマイズする
    • マジで聖書
    • 日本語でインテリセンスのカスタマイズについて紹介している記事は貴重

  • 脱physics パッケージして physics2 パッケージを使おう
    • 脱physicsパッケージしようという話

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?