Skip to content

Instantly share code, notes, and snippets.

@yarakos95
Last active July 7, 2021 10:43
Show Gist options
  • Save yarakos95/948720cb69d0baafe71e62ec6cb2cb54 to your computer and use it in GitHub Desktop.
Save yarakos95/948720cb69d0baafe71e62ec6cb2cb54 to your computer and use it in GitHub Desktop.
LaTeX Workshop のSyntax highlight を変更する

Customize Syntax Highlight for LaTeX Workshop

LaTeX Workshop では導入すればTeX ドキュメントに適切なシンタックスハイライトを与えてくれる.これで少し遊んでみよう.

LaTeX Workshop で数式環境のシンタックスハイライトを見てみるとなぜだが1色になってしまっている.なんだか奇妙なので,これを解決したいというのが一番の目的.

デフォルトでは以下のようになっており,いくつか奇妙な点がある.

  • 他の変数と\frac などのコマンドが同じハイライトとなっている
  • \frac\sum のハイライトが異なる
  • +- などが変数と同じハイライトとなっている

Sample math Image before

今回,VSCode の拡張機能Polacode でサンプル画像を作成した.同名の拡張機能が多すぎて驚いたが,以下の拡張機能を利用した.

pnp.polacode - VSCode Marketplace

本記事ではシンタックスハイライトの変更方法から始めています.最終的な成果物は# ここを参照してください.

TOC

Color theme and customize

このシンタックスハイライトはテーマにも依存している. しかしながら,実際に利用していても明らかだが,Visual Studio Dark/Light を利用しているとシンタックスハイライトがきちんと機能しない.

FAQ # Syntax Highlighting does not work for most elements - LaTeX Workshop | Wiki

Default Dark+/Light+ に変更して利用すると良いだろう.

  "workbench.colorTheme": "Default Dark+",
  // or "Default Light+"

しかし,これらのシンタックスハイライトでは少し気に入らない部分も出てくることがあるだろう.

今回は,いくつか個別にシンタックスハイライトを変更することを考えたい. LaTeX Workshop の公式ドキュメントでは以下のようにFAQ がなされている.

FAQ # Customizing a Color Theme - LaTeX Workshop | Wiki

シンタックスハイライトは拡張機能によってそれぞれ既定されている. これらの情報は*.tmLanguage.json ファイルに記されており,LaTeX Workshop では以下のディレクトリに格納されている.

~\.vscode\extensions\james-yu.latex-workshop-*.**.*\syntax
tmLanguage.json (折りたたみ)

~\.vscode\extensions\james-yu.latex-workshop-8.18.0\syntax>dir /b *tmLanguage.json
    BibTeX-style.tmLanguage.json
    Bibtex.tmLanguage.json
    cpp-grammar-bailout.tmLanguage.json
    DocTeX.tmLanguage.json
    JLweave.tmLanguage.json
    LaTeX-Expl3.tmLanguage.json
    LaTeX.tmLanguage.json
    RSweave.tmLanguage.json
    TeX.tmLanguage.json

*.tmLanguage.json ファイルの中身を見ればシンタックスハイライトについて明らかになるかもしれないが,あとで解説するエディタトークンとスコープの検査 コマンドを利用した方が簡単に確認することが出来る.

他の拡張機能であっても同様のディレクトリに配置されている.LaTeX 以外でも気になるシンタックスハイライトがあれば変更を加えても良いだろう.


*.tmLanguage.json ファイルにはマッチする文字列(シンタックス) とハイライトの情報が記載されている.このシンタックスとハイライトの情報というブロックの一つ一つにはTextMate rules にしたがったScope 名が与えられている.
ユーザ設定ではこのScope 名からハイライトの情報を変更することが出来る.(マッチする文字列を変更させることは出来ないことに注意が必要.)

これを利用して少しだけシンタックスハイライトに変更を加えたい.

User settings of syntax highlight

ここからはLaTeX Workshop に直接関係なく,VSCode の拡張機能全般のお話.

シンタックスハイライトをsettings.json から変更することが出来る. 方法は以下の通りになる.

"editor.tokenColorCustomizations" から以下のように"textMateRules" を変更していく.

  "editor.tokenColorCustomizations": {
    "textMateRules": [
      {
        "scope": [
          "scope.name.by.textmate.rules",
        ],
        "settings": {
          "foreground": "#00ff00",
          "fontStyle": "bold",
        },
      },
    ],
  }

TextMateRules

TextMate はテキストエディタの1つである.このルールは,そこで用いられるシンタックスハイライトを行うためのScope 名の記法を指している.

基本的な構成は,先頭にグループ名,末尾に言語名が与えられており. によって区切られている.

<group_name>.<subgroup_name>.<subsubgroup_name>.<language>

このScope 名はツリーを成しており,サブサブグループまでScope を狭めて設定するよりもサブグループでのScope を設定した方がよりグローバルな設定になる.ユーザ設定としてはより狭いScope 名を利用した方が安全だろう.

scope

Scope 名は既定されている.各トークンに与えられたScope 名は次の節で紹介するコマンドから表示させることが出来る.

foreground

文字色はHex 値(16進数カラーコード) による6桁の数字によって表現する.

どうやらbackground は変更することが出来ないようだ.

fontStyle

italic, bold, underline とこれらの組み合わせの計7種類とフォントスタイルを継承しないnone がある.ブランクにするとnone が選択される.

Inspect Editor Tokens and Scopes

シンタックスハイライトを設定するJSON ファイルをすべて見てどの文字列にどのハイライトが課してあるのかを確認するのは野暮である.

VSCode ではコマンドパレットから以下を実行すると,カーソルのある文字列のScope 名をホバーウィンドウから確認することが出来る.このウィンドウはEsc で表示をやめることが出来る.

> Developer: Inspect Editor Tokens and Scopes

公式ドキュメントではこのコマンドにキーボードショートカットを与えることも提案している.

Syntax Highlight Guide # Scope inspector | Visual Studio Code Extension API

上のコマンドでScope を確認して,settings.json からシンタックスハイライトに変更を加えるところまでの例を挙げてみたいと思う.

: \begin{document} にカーソルを置いて上のコマンドを実行する.

\begin{document}
  % ↑ ここにカーソルを置いてコマンドを実行する
\end{document}

ホバーウィンドウ

begin                   5 chars
------------------------------------------------------------
language                latex
standard token type     Other
foreground              #DCDCAA
background              #1E1E1E
contrast ratio          11.79
------------------------------------------------------------
textmate scopes         support.function.be.latex
                        meta.function.environment.math.latex
                        text.tex.latex
foreground              support.function
                        { "foreground": "#DCDCAA" }

foreground に指定されているScope 名によって文字色とフォントスタイルが指定されている. したがって,上の例ではsupport.function をsettings.json で以下のように変更を加えることを考えてみる.

  "editor.tokenColorCustomizations": {
    "textMateRules": [
      {
        "scope": [
          "support.function",
        ],
        "settings": {
          "foreground": "#00ff00",
          "fontStyle": "bold",
        },
      },
    ],
  }

上では緑#00ff00 でボールド体になるように設定している.(かなりどぎつい設定になっている) これで,\begin\end がこの文字装飾に変更される.

しかし,このScope 名で設定を課しているときにはsupport.function によって設定されている文字列は\begin の他にも与えられている.そのため,他の一般的なコマンド(\maketitle など) もこの文字装飾になってしまう.より狭いScope 名を指定しておきたい.

そこで,改めてホバーウィンドウを確認するとtextmate scopes の欄に3つのScope 名が表示されている.

textmate scopes         support.function.be.latex
                        meta.function.environment.math.latex
                        text.tex.latex

これらも"begin" を対象にしたScope となっている.これらのうち,"support.function" につづくようなScope 名を利用したい. したがって,\begin\end のみ変更しようという場合には"scope""support.function.be.latex" に変更する.

以下にシンタックスハイライトを確認するためのデモドキュメントを作成しておいた.適宜確認しながら設定を変更してみても良いだろう.

Syntax Highlight test .tex (折りたたみ)

LuaLaTeX またはupLaTeX +dvipdfmx でタイプセット可能.

\documentclass[a4paper,10pt]{jlreq}
\usepackage[top=10mm,bottom=25mm,left=30mm,right=30mm]{geometry}
\usepackage{amsmath}
\usepackage{mathtools}
\mathtoolsset{showonlyrefs}
\title{Syntax Highlight Test}
\author{Yarakashi Kikohshi}
\date{}
\renewcommand{\tablename}{Table:}
%%%%% ----- document ----- %%%%%
\begin{document}

\maketitle

Let's check syntax highlight for \textit{\LaTeX Workshop}.

\section{Quadratic equation}

We impose $ f(\xi) = 0 $ on the following quadratic equation $ f(\xi) $.

\begin{equation}
  f(\xi)
    =
      a\xi^2 +b\xi +c
\end{equation}

Derivation of the formula for the solution of the quadratic equation.

\begin{align}
  f(\xi) = a\xi^2 +b\xi +c
    & =
      0
      \\
  a
  \left(
    \xi^2 +\frac{b}{a}\xi
  \right)
  +c
    & =
      0
      \\
  a
  \left(
    \xi +\frac{b}{2a}
  \right)^2
  -\frac{b^2}{4a} +c
    & =
      0
      \\
  \left(
    \xi +\frac{b}{2a}
  \right)^2
    & =
      \frac{b^2 -4ac}{4a^2}
      \\
  \xi +\frac{b}{2a}
    & =
      \pm\frac{\sqrt{b^2 -4ac}}{2a}
      \\
  \xi
    & =
      \frac{-b \pm\sqrt{b^2 -4ac}}{2a}
\end{align}

Therefore, the formula for the solution of the quadratic equation is as follows.

\begin{equation}
  \xi
    =
      \frac{-b \pm\sqrt{b^2 -4ac}}{2a}
\end{equation}

\section{Number of solutions}

Determine the number of real solutions by the positive or negative of $ D = b^2 -4ac $

\begin{table}[tbh]
  \centering
  \caption{Number of solutions}
  \label{tbl: number of solutions}
  %%%%% ----- tabler ----- %%%%%
  \begin{tabular}{cc} \hline
    Test condition
    & Number of solutions
    \\
    \hline
    $ D > 0 $
    & 2
    \\
    $ D = 0 $
    & 1
    \\
    $ D < 0 $
    & 0
    \\
    \hline
  \end{tabular}
  %%%%% -----  ----- %%%%%
\end{table}

\end{document}

Highlight settings

文字色とフォントスタイルを変更することが出来る.

しかしながら,デフォルトのシンタックスハイライトの様子をよく見ると7色程度しか利用されていない(次の項を参照) .エディタではあまりにも多色にすると目が散ってしまうためあまりよろしくないと思われる. 文字色の選択には非常に注意を払った方が良いだろう.

人によっては,デフォルトのシンタックスハイライトが多色すぎるように感じる場合もあるかもしれない.適当に色を少なくすることも出来るので,検討してみても良いだろう.

Default highlight color

Default Dark+ を利用している場合には背景は#1E1E1E となっている.以下のサンプルでは背景を#1E1E1E としてそれぞれの文字色でScope 名を挿入してみた.

scope name color code sample image
No theme selector #D4D4D4 D4D4D4
comment #6A9955 6A9955
constant.character #569CD6 569CD6
constant.numeric #B5CEA8 B5CEA8
keyword.control #C586C0 C586C0
support.class #4EC9B0 4EC9B0
support.function #DCDCAA DCDCAA
variable #9CDCFE 9CDCFE

Default Dark+ に含まれていた上記以外のカラーコードを書き出しておく.

Sample other color (折りたたみ)

もちろん,任意に色を設定することは可能だが,先人が考えて設定したカラーコードなので利用価値はあるかもしれない.

これらの文字色はエディタのハイライト以外に利用されているようだ.

color code sample image
#808080 808080
#646695 646695
#D7BA7D D7BA7D
#CE9178 CE9178
#D16969 D16969
#F44747 F44747

sample image provided by: https://placeholder.com/
画像は横幅が小さい端末を利用していると見づらい場合がある.画像のみを表示させるか拡大して確認してほしい.

Scope example

LaTeX Workshop に特異なお話.

例としていくつかのScope 名を挙げておくが,これらのScope が以下で示す文字列のみを対象としているとは限らない可能性があることを注意しておきたい.

Scope name Target character string
support.function.be.latex \begin\end
punctuation.math.operator.latex 数式環境内の演算子: +, - ...etc
constant.other.general.math.tex 数式環境内のコマンド: \frac, \sqrt ...etc
keyword.control.equation.align.latex 数式環境内のアンパサンド: &
keyword.control.table.cell.latex table 環境内のアンパサンド: &

これらのScope はすでに文字列が決められているため,任意の文字列に対してScope を設定することは出来ない.もしもScope を自ら設定したい場合には自力でシンタックスハイライトを作成していく必要がある. また,meta.text. につづくScope 名は大部分を対象としているため,これらを指定して設定を変更することは避けた方が良いだろう.

Settings example

筆者はDefault Dark+ を好きで利用しているので,このテーマを基準に変更する形を採る.したがって,文字色に関してはその他のテーマにそぐわない場合がある.注意してほしい.

既存のシンタックスハイライトの問題点を挙げておきたい.

  • 通常のコマンドと環境のコマンド(\begin\end ) が同一のハイライトとなっている
  • 数式環境
    • 行内数式の$ で囲う場合,数式環境内の文字色と同じ色となっている
    • 数式環境内の文字色が薄い緑色で少しうるさい
    • 数式環境内で四則演算子や_, ^ が区別しづらい
    • 数式環境内のコマンドで\sum\frac の文字色が異なる (どこに線引きがあるのかは不明)
  • コメントアウトの文字色が暗い

これらを解決するために,以下のような変更点を加えたい.

変更点

  • 環境コマンドの\begin\end$ の文字色を#D7BA7D に ($$ には変更を加えていない)
  • 数式環境
    • 数式環境内の本文の文字色を#D4D4D4 ,フォントスタイルをイタリックに
    • 数式環境内の+, -, *, /, _, ^& と同じ#C586C0
    • 数式環境内のコマンドを#569CD6 にして\frac などと\sum などとを同様の文字色に
  • コメントアウトの文字色を#F44747

その他適宜良くない部分があれば修正してください.

Sample Image before
BEFORE: Sample Code Syntax Highlight

Sample Image after
AFTER: Sample Code Syntax Highlight

Customize SyntaxHighlight settings.json (折りたたみ)

"[Default Dark+]" で囲むことでDefault Dark+ のみに変更を加えるようにしている.

また,数式環境内のフォントスタイルをイタリックにした関係で()\\ などもイタリックになってしまう.これを避けるために()\\ などのScope に"fontStyle": "" を追加している.

  "editor.tokenColorCustomizations": {
    "[Default Dark+]": {
        "comments": {
          "foreground": "#F44747",
          "fontStyle": "",
        },
      "textMateRules": [
        {
          "scope": [
            "constant.character.escape.tex",
          ],
          "settings": {
            "foreground": "#D7BA7D",
            "fontStyle": ""
          }
        },
        {
          "scope": [
            "keyword.control.label.latex",
          ],
          "settings": {
            "foreground": "#C586C0",
            "fontStyle": ""
          }
        },
        {
          "scope": [
            "variable.parameter.definition.label.latex",
            "constant.other.reference.label.latex",
          ],
          "settings": {
            "foreground": "#9CDCFE",
            "fontStyle": ""
          }
        },
        {
          // inline math element: abcxyz
          // display math element: abcxyz
          "scope": [
            "support.class.math.block.environment.latex",
            "support.class.math.block.tex"
          ],
          "settings": {
            "foreground": "#B5CEA8",
            "fontStyle": "italic"
          }
        },
        {
          // inline math: $
          // environment: \begin \end
          "scope": [
            "support.function.be.latex",
            "punctuation.definition.string.begin.tex",
            "punctuation.definition.string.end.tex",
          ],
          "settings": {
            "foreground": "#D7BA7D",
            "fontStyle": ""
          }
        },
        {
          // punctuation for math: + - * _ ^
          "scope": [
            "punctuation.math.operator.latex"
          ],
          "settings": {
            "foreground": "#C586C0",
            "fontStyle": ""
          }
        },
        {
          // commands for math: \frac \sqrt ...etc
          "scope": [
            "constant.character.math.tex",
            "constant.other.general.math.tex",
            "constant.other.math.tex",
          ],
          "settings": {
            "foreground": "#569CD6",
            "fontStyle": ""
          },
        },
        {
          // \\ and & for equations
          "scope": [
            "keyword.control.equation",
          ],
          "settings": {
            "foreground": "#C586C0",
            "fontStyle": ""
          }
        },
        {
          // () and {} and []
          "scope": [
            "punctuation.math.begin.bracket.curly",
            "punctuation.math.end.bracket.curly",
            "punctuation.math.begin.bracket.round",
            "punctuation.math.end.bracket.round",
            "punctuation.definition.brackets.tex",
            "punctuation.definition.arguments.begin.latex",
            "punctuation.definition.arguments.end.latex",
          ],
          "settings": {
            "foreground": "#D4D4D4",
            "fontStyle": "",
          }
        },
      ],
    },
  },

この他,括弧に関しては拡張機能Bracket Pair Colorizer を利用すれば対応する括弧を色で識別することが出来るようになる.

coenraads.bracket-pair-colorizer - VSCode Marketplace

Reference

Digression

今回の拡張機能によって設定されたシンタックスハイライトを変更する場合は,特定の言語の変更のみになる.

"editor.tokenColorCustomizations" ではよりグローバルな言語に対してシンタックスハイライトを変更することも可能である. textMateRules 以外にも以下の7つを変更することが出来る.

Contents Description
comments コメント
functions 関数やメソッド
keywords キーワード
numbers 数値リテラル
strings 文字列リテラル
types
variables 変数

以下のように設定する.

  "editor.tokenColorCustomizations": {
    "comments": {
      "foreground": "#00ff00",
      "fontStyle": "bold"
    },
    "functions": {
      "foreground": "#ff0000",
      "fontStyle": "italic"
    },
    // and more...
  }

TextMate rule を思えば,comment. から始まるScope 名に対して設定が適用される.つまり,かなり強いマッチの設定となっている.したがって,言語に問わずすべてに変更が加わる. 言語毎に設定したい場合にはScope 名を明らかにして各々設定していく必要がある.

あるいは,Workspace やフォルダごとに設定することで少し解消することが出来るだろう.(共有するプロジェクトではやらない方が良いかもしれない)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment