zref-clever で簡単に相互参照しよう

<!-- # zref-clever で簡単に相互参照しよう -->

## はじめに

[zref-clever][] は、カウンタの種類に応じて自動的に相互参照に参照タイプ名を追加して相互参照をより簡便するパッケージです。

非常に似たパッケージ、[cleveref][] の代替パッケージと思っても良いでしょう。cleveref は [Qiita][cleveref-qiita] 内でもいくつか取り上げられており、使っている人も多いのではないかと思います。

[cleveref-qiita]: https://qiita.com/search?q=cleveref "「cleveref」の検索結果 - Qiita"

本記事では、あまり知られていない zref-clever の基本的な使い方から日本語対応の方法などを紹介します。

:::note info
本記事は zref-clever v0.4.5 (2024-05-20) に準拠します。
:::

この節では、まず cleveref の気になる点と zref-clever の使い方について紹介します。

### cleveref の気になる点

実用上ほとんど問題はありませんが、cleveref では以下のような点が気になることもあるでしょう。

- [hyperref][] との読み込み順序がある
- [autonum][] と併用する場合：
    - 読み込み順序がある
    - cleveref に由来するいくつかのコマンドがサポートされていない（[参考][tse-471651]）
    - autonum が提供する数式環境しか使えない
- よく知られている方法で日本語に対応させている際、`\cref{fig:1}` としたときに “図” と “1” の間は `~` であり、和欧文間スペースにならない（[参考][miz-autoref]）
    ![miz-ar](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/5fb4297b-1a5e-7364-9ecf-c920a556c202.png "zref-clever では和欧文間スペースが適切に処理される")
    <details>
    <summary> 作成コード（折りたたみ）</summary>

    以下のコードを LuaLaTeX で実行し、当該箇所をスクリーンショットした。

    ```latex
    \documentclass{ltjsbook}
    \usepackage{amsthm}
    \usepackage[unicode]{hyperref}
    %%%%% ----- cleveref ----- %%%%%
    \usepackage[nameinlink]{cleveref}
    \crefname{theorem}{定理}{定理}
    \crefname{lemma}{補題}{補題}
    \crefname{chapter}{第}{第}
    \creflabelformat{chapter}{#2#1章#3}
    %%
    %%%%% ----- zref-clever ----- %%%%%
    \usepackage{zref-clever}
    \zcDeclareLanguage[allcaps]{japanese}
    \zcLanguageSetup{japanese}{
      type = chapter ,
        Name-sg = 第 ,
        Name-pl = 第 ,
        refbounds = {,,章,} ,
      type = theorem ,
        Name-sg = 定理 ,
        Name-pl = 定理 ,
      type = lemma ,
        Name-sg = 補題 ,
        Name-pl = 補題 ,
    }
    \zcsetup{lang=japanese}
    \AddToHook{env/lemma/begin}{%
      \zcsetup{countertype={theorem = lemma}}
    }
    %%
    \theoremstyle{definition}
    \newtheorem{theorem}{定理}[chapter]
    \newtheorem{lemma}[theorem]{補題}

    \title{すごい文章}
    \author{だめぽ}

    \begin{document}
    \maketitle

    \chapter{すごい内容}
    \label{chap:main}

    にゃーん。にゃにゃ？にゃーお。
    \begin{lemma}[すごい補題] \label{lem:bar}
        みゃおーん。
    \end{lemma}

    \begin{theorem}[すごい定理] \label{thm:foo}
        何がにゃーんですか。にゃおーん。
    \end{theorem}

    \chapter{あとがき}

      第\ref{chap:main}章の定理\ref{thm:foo}は……すごい！
      補題\ref{lem:bar}も、すごい！（手動）\par
      \zcref{chap:main}の\zcref{thm:foo}は……すごい！
      \zcref{lem:bar}も、すごい！（zref-clever）\par
      \cref{chap:main}の\cref{thm:foo}は……すごい！
      \cref{lem:bar}も、すごい！（cleveref）

    \end{document}
    ```

    </details>

[miz-autoref]: https://blog.miz-ar.info/2021/01/alternatives-to-autoref/ "\autoref の欠点と代替 | 雑記帳"

[zref-clever]: https://www.ctan.org/pkg/zref-clever "zref-clever - CTAN"
[cleveref]: https://www.ctan.org/pkg/cleveref "cleveref - CTAN"
[hyperref]: https://www.ctan.org/pkg/hyperref "hyperref - CTAN"
[autonum]: https://www.ctan.org/pkg/autonum "autonum - CTAN"
[zref]: https://www.ctan.org/pkg/zref "zref - CTAN"
[mathtools]: https://www.ctan.org/pkg/mathtools "mathtools - CTAN"
[tse-471651]: https://tex.stackexchange.com/questions/471651/cref-not-working-with-autonum-but-cref-without-the-capital-letter-works "cross referencing - \Cref not working with autonum (but \cref, without the capital letter, works...) - TeX - LaTeX Stack Exchange"

zref-clever ではこれらの気になる点がありません。
また、[mathtools][] の `showonlyrefs` オプションと併用できます。

### zref-clever の使い方

zref-clever は、多くの西欧言語にある文頭の case の違い (capitalization)、単数・複数形 (pluralization)、“equation” に対する “eq.” のような略称 (abbreviation)、名詞の性 (gender)、格変化 (declension) に対応することが出来ます。

加えて、英語、イタリア語、オランダ語、スペイン語、ドイツ語、フランス語、ポルトガル語、ロシア語の 8 ヶ国語に対応しています。（現状では日本語には対応していないため、[この節][sec-ja] で紹介します）

[sec-ja]: #zref-clever-の日本語対応 "zref-clever の日本語対応"

言語の切り替えは、プリアンブルで `\zcsetup` から以下のように記述します。

```latex
%% ドイツ語を指定する例
\usepackage{zref-clever}
\zcsetup{ lang = german }
```

zref-clever では `\zcref` を使って `\label` を参照します。

`\zcref` は、カウンタの種類に応じて “図” や “表” 等の参照タイプ名を与えたり、複数のラベルを同時に処理することが出来ます。
すなわち、次のような形で参照することが出来ます。（結果が分かりやすいようにラベルは通し番号にしています）

- single 参照
    ```latex
    \zcref{fig:1}
    ```
- pair 参照
    ```latex
    \zcref{fig:1, fig:2}
    ```
- range 参照
    ```latex
    \zcref{fig:1, fig:2, fig:3} % または
    \zcref[range]{fig:1, fig:3}
    ```
- list 参照
    ```latex
    \zcref{fig:1, fig:3, fig:4}
    ```

![example image of sigle type reference style](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/edad82bf-2986-2bb7-fa4e-b1adfe42aaa0.png "単参照タイプの参照スタイル例")

加えて、複数の参照タイプを同時に参照する場合、参照スタイルは以下の 2 つのパターンがあります。

- type pair 参照
    ```latex
    \zcref{fig:1, tbl:1}
    ```
- type list 参照
    ```latex
    \zcref{fig:1, tbl:2, tbl:3, eqn:1}
    ```

![example image of multiple type reference style](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/12003ac0-8607-226d-caec-58617b06642b.png "複参照タイプの参照スタイル例")

cleveref と同様に、カウンタに応じて参照タイプ名が与えられるため、非常に楽な相互参照ができます。

## zref-clever の日本語対応

zref-clever の言語構成では、capitalization [^allcaps]、abbreviation は省略できます。また、gender、declension はオプションのため必ずしも課す必要はありません。（単数・複数形は省略できません）
したがって、日本語対応では単数・複数形だけ気にすれば良いです。

[^allcaps]: capitalization は、`\zcDeclareLanguage` で `allcaps` オプションを課すことで省略されます。

具体的には、プリアンブルで `\zcDeclareLanguage` によって `japanese` を宣言し、`\zcLanguageSetup` に言語構成を記述します。（ちょっと長いため折りたたみにしておきます）

<!--
[^zcdeclarelanguagealias]: `\zcDeclareLanguageAlias` を構成することで `japanese` のエイリアスを構成できます。

    ```latex
    \zcDeclareLanguageAlias{japanese}{ja}
    ```

    これによって、`lang = japanese` の他に `lang = ja` でも日本語を指定できます。 -->

<details>
<summary>日本語を構成した zref-clever の使い方（折りたたみ）</summary>

```latex
\usepackage{zref-clever}
\zcDeclareLanguage[allcaps]{japanese}
\zcLanguageSetup{japanese}{
  namesep   = {\nobreak} ,
  pairsep   = {と} ,
  listsep   = {、} ,
  lastsep   = {、および} ,
  tpairsep  = {および} ,
  tlistsep  = {、} ,
  tlastsep  = {、および} ,
  notesep   = {：} ,
  rangesep  = {から} ,

  type = book ,
    Name-sg = 第 ,
    Name-pl = 第 ,
    refbounds = {,,編,},

  type = part ,
    Name-sg = 第 ,
    Name-pl = 第 ,
    refbounds = {,,部,},

  type = chapter ,
    Name-sg = 第 ,
    Name-pl = 第 ,
    refbounds = {,,章,} ,

  type = section ,
    Name-sg = 第 ,
    Name-pl = 第 ,
    refbounds = {,,節,} ,

  type = paragraph ,
    Name-sg = 第 ,
    Name-pl = 第 ,
    refbounds = {,,段落,} ,

  type = appendix ,
    Name-sg = 付録 ,
    Name-pl = 付録 ,

  type = page ,
    Name-sg = p. ,
    Name-pl = pp. ,
    rangesep = \textendash ,
    rangetopair = false ,

  type = line ,
    Name-sg = l. ,
    Name-pl = l. ,
    rangesep = \textendash ,
    rangetopair = false ,

  type = figure ,
    Name-sg = 図 ,
    Name-pl = 図 ,

  type = table ,
    Name-sg = 表 ,
    Name-pl = 表 ,

  type = item ,
    Name-sg = 項目 ,
    Name-pl = 項目 ,

  type = footnote ,
    Name-sg = 脚注 ,
    Name-pl = 脚注 ,

  type = endnote ,
    Name-sg = 後注 ,
    Name-pl = 後注 ,

  type = note ,
    Name-sg = 注意 ,
    Name-pl = 注意 ,

  type = equation ,
    Name-sg = 式 ,
    Name-pl = 式 ,
    refbounds = {,(,),} ,

  type = theorem ,
    Name-sg = 定理 ,
    Name-pl = 定理 ,

  type = lemma ,
    Name-sg = 補題 ,
    Name-pl = 補題 ,

  type = corollary ,
    Name-sg = 系 ,
    Name-pl = 系 ,

  type = proposition ,
    Name-sg = 命題 ,
    Name-pl = 命題 ,

  type = definition ,
    Name-sg = 定義 ,
    Name-pl = 定義 ,

  type = proof ,
    Name-sg = 証明 ,
    Name-pl = 証明 ,

  type = result ,
    Name-sg = 結果 ,
    Name-pl = 結果 ,

  type = remark ,
    Name-sg = 備考 ,
    Name-pl = 備考 ,

  type = example ,
    Name-sg = 例 ,
    Name-pl = 例 ,

  type = algorithm ,
    Name-sg = アルゴリズム ,
    Name-pl = アルゴリズム ,

  type = listing ,
    Name-sg = コード ,
    Name-pl = コード ,

  type = exercise ,
    Name-sg = 演習 ,
    Name-pl = 演習 ,

  type = solution ,
    Name-sg = 解法 ,
    Name-pl = 解法 ,
}
\zcsetup{ lang = japanese }
```

</details>

<!-- - 外部ファイル (<samp>zref-clever-japanese.lang</samp>) に記述する
    ```latex
    \usepackage{zref-clever}
    \zcDeclareLanguage[allcaps]{japanese}
    \zcsetup{ lang = japanese }
    ```
    <samp>zref-clever-japanese.lang</samp> はタイプセットする TeX ファイルと同じディレクトリに配置してください。 -->

<!-- <details>
<summary><samp>zref-clever-japanese.lang</samp>（折りたたみ）</summary>

zref-clever が組み込みで構成している参照タイプをすべて日本語化しています。

</details> -->

----------

これによって、日本語文章で zref-clever を使えるようになりました。

以降では、日本語構成に関するより詳細な方法を紹介します。
上の日本語対応で十分な場合は [この節][sec-hyperlink] まで飛ばして大丈夫です。

[sec-hyperlink]: #相互参照のハイパーリンク "§ 相互参照のハイパーリンク"

## 複数参照の区切り

複数のラベルを参照する場合、(type) pair 参照や range 参照はラベルとラベルの間に “と” や “から” 等の区切りとなる並立助詞が入ります。これらはそれぞれ `(t)pairsep`、`rangesep` から構成されます。

```latex
%   pairsep
%    ↓
図 1 と 2
% ----- ----- ----- -----
%   rangesep
%     ↓
図 1 から 3
% ----- ----- ----- -----
%   tpairsep
%    ↓
図 1 と表 1
```

加えて、(type) list 参照は、“A, C and D” のようなスタイルになるため、最後の `(t)lastsep` と途中までの `(t)listsep` の 2 つあります。

```latex
%       lastsep
%          ↓
図 1、3、および 4
%   ↑
% listsep
% ----- ----- ----- -----
%         tlastsep
%            ↓
図 1、表 1、および式 (1)
%   ↑
% tlistsep
```

日本語に対応させるには、以下のような対応関係にあれば良いでしょう。[^cleveref]

[^cleveref]: zref-clever と cleveref を対応させると以下のようになります。

    | zref-clever |           cleveref            |
    | :---------: | :---------------------------: |
    |  `pairsep`  |    `\crefpairconjunction`     |
    |  `listsep`  |   `\crefmiddleconjunction`    |
    |  `lastsep`  |    `\creflastconjunction`     |
    | `rangesep`  |    `\crefrangeconjunction`    |
    | `tpairsep`  |  `\crefpairgroupconjunction`  |
    | `tlistsep`  | `\crefmiddlegroupconjunction` |
    | `tlastsep`  |  `\creflastgroupconjunction`  |

<!-- |         `\crefformat`         | `\zcRefTypeSetup` |
| `\crefname` | `Name-*` |
| `---------` | `------` | -->

| 参照の種類 | zref-clever |    例    |
| :--------: | :---------: | :------: |
|    pair    |  `pairsep`  |    と    |
|    list    |  `listsep`  |    、    |
|    list    |  `lastsep`  | 、および |
|   range    | `rangesep`  |   から   |
| type pair  | `tpairsep`  |    、    |
| type list  | `tlistsep`  |    、    |
| type list  | `tlastsep`  | 、および |

実際の構成では key-value 形式で次のようにします。

```key-value
pairsep   = {と} ,
listsep   = {、} ,
lastsep   = {、および} ,
rangesep  = {から} ,
tpairsep  = {、} ,
tlistsep  = {、} ,
tlastsep  = {、および} ,
```

加えて、参照タイプ名と参照番号の間で改行されるべきではないとされているため、`namesep` に `\nobreak` を課します。
これによって、` 図{\nobreak}1 ` のような状況になります。

```key-value
namesep = {\nobreak} ,
```

## 参照タイプ名

:::note info
ここではあまりに多くの構成が考えられるため、言語は日本語に限りかつ一部の参照タイプを用いた具体例で紹介します。
詳細はパッケージガイドを参照してください。
:::

特定の参照タイプに関する構成は、最小構成は次のような key-value 形式で表現します。（LaTeX の key-value 形式のためインデントに意味はありませんが、見た目の分かりやすさのためにインデントしています）

```key-value
type = <カウンタタイプ名> ,
  Name-sg = <参照タイプ名> ,
  Name-pl = <参照タイプ名> ,
```

`<カウンタタイプ名>` とはカウンタの種類を指します。カウンタそのものを指すこともあります。具体的には `figure` や `table` などです。
`<参照タイプ名>` は参照番号の前に付く “図” や “表” などです。

`Name-sg` は single 参照の場合、`Name-pl` は pair・range・list 参照の場合に利用される参照タイプ名です。[^sg-pl]
日本語では単数・複数に対して言い方を替えませんが、zref-clever でこれらを省略することは出来ません。

[^sg-pl]: `Name`・`name` における `-sg` と `-pl` は単数形と複数形を表しています。

    - `-sg`: single form（単数形）
    - `-pl`: plural form（複数形）

<details>
<summary> 組み込みで対応するカウンタタイプ一覧（折りたたみ）</summary>

組み込みで対応するカウンタタイプは基本的にカウンタ名に対応していますが、一部のカウンタタイプは複数のカウンタを総称しているものがあります。[^counter-type]

[^counter-type]: 対応するカウンタタイプがまとめられている経緯は [zref-clever-code.pdf][code-doc] の § 10 Language files に記載されています。

[code-doc]: http://mirrors.ctan.org/macros/latex/contrib/zref-clever/zref-clever-code.pdf "Code documentation (PDF)"

組み込みで対応するカウンタタイプは以下の 28 があります。

|                                                            カウンタタイプ                                                            | カウンタの意味                                                                        |
| :----------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------ |
|                                                                `book`                                                                | 編（`\book`：[memoir][] 文書クラス等で `\part` と同じレベルの見出しとして定義される） |
|                                                                `part`                                                                | 部（`\part`）                                                                         |
|                                                              `chapter`                                                               | 章（`\chapter`）                                                                      |
|                                                              `section`                                                               | 節（`\section`）                                                                      |
|                                                             `paragraph`                                                              | 段落（`\paragraph`）                                                                  |
|                                                              `appendix`                                                              | 付録（`\appendix`）                                                                   |
|                                                                `page`                                                                | ページ                                                                                |
|                                                                `line`                                                                | 行（memoir 文書クラスの `poemline` と [listings][] パッケージの `lstnumber` に対応）  |
|                                                               `figure`                                                               | 図（figure 環境）                                                                     |
|                                                               `table`                                                                | 表（table 環境）                                                                      |
|                                                                `item`                                                                | 番号付きリストの項目（enumerate 環境）                                                |
|                                                              `equation`                                                              | 数式                                                                                  |
|                                                              `footnote`                                                              | 脚注                                                                                  |
|                                                              `endnote`                                                               | 後注                                                                                  |
|                                                                `note`                                                                | `footnote`・`endnote` 以外のノート                                                    |
|                                                             `algorithm`                                                              | アルゴリズム（[algorithms][] パッケージなどのキャプション番号）                       |
|                                                              `listing`                                                               | コード（listings パッケージのキャプション番号）                                       |
| `theorem`, `corollary`, `definition`,<br> `example`, `exercise`, `lemma`, `proof`,<br> `proposition`, `remark`, `result`, `solution` | 定理環境で作成される                                                                  |

[algorithms]: https://www.ctan.org/pkg/algorithms "algorithms - CTAN"
[listings]: https://www.ctan.org/pkg/listings "listings - CTAN"
[memoir]: https://www.ctan.org/pkg/memoir "memoir - CTAN"

</details>

### 参照タイプ名のみの場合

図表など通し番号の前に参照タイプ名を置くだけの場合は、次のようにします。

```key-value
type = figure ,
  Name-sg = 図 ,
  Name-pl = 図 ,
type = table ,
  Name-sg = 表 ,
  Name-pl = 表 ,
```

![only reference type name](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/e9a71a98-1055-65ef-aacd-50f52a6aa58b.png "参照タイプ名のみの場合")

これが最も簡単な例です。

### 参照番号を括弧で囲う場合

数式を参照する場合、参照番号を丸括弧で囲うことが一般的です。このような場合は `refbounds` を用いて次のようにします。

```key-value
type = equation ,
  Name-sg = 式 ,
  Name-pl = 式 ,
  refbounds = {,(,),} ,
```

![around reference number by parenthesis](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/ccf69d26-7c91-51c3-1aa1-58d882e29b50.png "参照番号を括弧で囲う場合")

----------

もしも特定の参照を丸括弧とは異なるものにしたい場合は、`\zcref` のオプションでも `refbounds` の変更ができます。

```latex
\zcref[refbounds = {,[,],}]{eqn:1}
```

<details>
<summary> 作成コード（折りたたみ）</summary>

mathtools の `\newtagform`・`\usetagform` を使うことで、数式番号の丸括弧を変更できます。

`refbounds` オプションを課すと参照しているラベルのすべてに影響するため、single 参照以外では注意が必要です。

```latex
\documentclass{jlreq}
\usepackage{amsmath, mathtools}
\usepackage{zref-clever}
\zcDeclareLanguage[allcaps]{japanese}
\zcLanguageSetup{japanese}{
  %% ...省略
}
\zcsetup{ lang = japanese }
\newtagform{bracket}{[}{]}
\begin{document}

\begin{align}
  f(x)
    & = ax^2 + bx + c
    \label{eqn:1}
    \\
    & = a \left( x + \frac{b}{2a} \right)^2 - \frac{b^2}{4a} + c
    \label{eqn:2}
\end{align}

\zcref[refbounds={,[,],}]{eqn:qf}は、\zcref{eqn:2}を\( f(x) = 0 \)の下で\( x \)について解くことで得られます。

\usetagform{bracket}

\begin{equation}
  x = \frac{- b \pm\sqrt{b^2 - 4ac}}{2a}
  \label{eqn:qf}
\end{equation}

\end{document}
```

</details>

![change refbounds configuration](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/ad782787-1489-4aac-6235-ddb459448153.png "refbounds を変更する例")

### 参照ブロックの後にも続く場合

章節を参照する場合、「第 1 章」のように参照番号の後ろにも続きます。このような場合も `refbounds` を用いて次のようにします。

```key-value
type = chapter ,
  Name-sg = 第 ,
  Name-pl = 第 ,
  refbounds = {,,章,} ,
```

![post reference type name](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/5c110a57-8fbc-535a-1b92-866b08e6cca4.png "参照ブロックの後にも続く場合")

ここで “第” を省略すれば、“章” だけが付くようになります。（`Name-sg`・`Name-pl` は空でも構いません）

----------

次のようにすれば常に「第 1 節」のようになります。

```key-value
type = section ,
  Name-sg =  ,
  Name-pl =  ,
  refbounds = {,第,節,} ,
```

![pre and post reference type name](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/3e116ee8-3158-4bf3-5821-cbfb486acb8e.png "常に参照番号の前後に参照タイプ名がある場合")

----------

より高度な構成として、ページ参照の「5 ページ」、「2 〜 3 ページ」のように、常に参照ブロックの最後に参照タイプ名を置く場合、`refbounds` のオプション [^refbounds-var] を用いて次のように構成します。[^wave-dash]

[^refbounds-var]: `refbounds` には 16 のオプションがあります。若干難解ですが、これらを利用することで複雑な参照スタイルを表現できます。(cf. Table 2: Advanced reference format options and their scopes - § 9.1 Advanced reference formatting - [zref-clever-doc.pdf][manual-doc])

[manual-doc]: http://mirrors.ctan.org/macros/latex/contrib/zref-clever/zref-clever-doc.pdf "User manual (PDF)"

[^wave-dash]: `rangesep` を ` 〜 ` にするなら、アラビア数字との間を和欧文間スペースにした方が良さそうです。

```key-value
type = page ,
  Name-sg =  ,
  Name-pl =  ,
  rangesep = 〜 ,
  rangetopair = false ,
  refbounds-first-sg = {,,ページ,} ,
  +refbounds-last = {,,ページ,} ,
  +refbounds-re = {,,ページ,} ,
```

![only post reference type name](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/67579c17-e786-6b5a-b245-d7af0a221ea2.png "参照番号の後のみに参照タイプ名がある場合")

pege タイプでは、`rangetopair = false` としているので、連続したページを `\zcpageref[range]{page:1, page:2}` のように `range` オプション付きで参照すると、pair 参照ではなく range 参照になります。

## 相互参照のハイパーリンク

zref-clever でも [hyperref][] パッケージと併用することで自動的に相互参照にハイパーリンクを与えることが出来ます。読み込み順序はありません。

hyperref によって簡単にハイパーリンクを与えることが出来ますが、zref-clever でのハイパーリンクは次の 2 点に気を付ける必要があります。

- <ins> 参照タイプ名まで含めるか </ins>

    この挙動は `nameinlink` オプションによって制御できます。

    |    `nameinlink` 値     | ハイパーリンクを与える範囲                                                             |
    | :--------------------: | :------------------------------------------------------------------------------------- |
    | `tsingle`<br>(default) | single 参照、type pair・type list 参照内の single 参照のみ参照タイプ名から参照番号まで |
    |        `single`        | single 参照のみ参照タイプ名から参照番号まで                                            |
    |         `true`         | すべての参照タイプ名から参照番号まで                                                   |
    |        `false`         | 参照番号のみ                                                                           |

    <details>
    <summary> 参考画像（折りたたみ）</summary>

    `lang = english` の `equation` では、single 参照のみ丸括弧がハイパーリンクに含まれるようになっています。

    ![difference of link style by nameinlink](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/b3e8c18b-827e-0e7c-038e-7b6dc46365af.png "nameinlink の値による違い")

    </details>

- <ins>`refbounds` をハイパーリンクに含めるか </ins>

    `refbounds` 系は常にハイパーリンクを課す部分と課さない部分があります。

    例えば、以下のような `refbounds` が課された数式の参照があった場合、`\zcref{eqn:1}` の参照結果は “式 ab1cd” となります。

    ```latex
    refbounds = {a,b,c,d}
    ```

    このとき、ハイパーリンクは `b1c` に与えられ、`a`・`d` には与えられません。

本記事で示す日本語対応例では、`nameinlink = true` を前提とし、`refbounds` に含まれる文字はすべてハイパーリンクに含まれるように構成しています。

## 独自の参照タイプ

基本的な参照タイプの構成は紹介したので、発展的な独自の参照タイプの構成方法を紹介します。

zref-clever がデフォルトでサポートしていないカウンタやカウンタタイプに対して、独自にカウンタタイプを構成することが出来ます。

実用上、特に [`\newtheorem`][newtheorem] による新しいカウンタの作成はよく行われると思われます。そのため、以下では `\newtheorem` による 3 つの具体例からそれぞれの対応を紹介します。

[newtheorem]: https://latexref.xyz/_005cnewtheorem.html "\newtheorem (LaTeX2e unofficial reference manual (May 2024))"

### 新しい参照タイプの追加

新たなカウンタを追加したい場合も、組み込みのカウンタタイプと同じように指定すれば良いです。

例えば、`\newtheorem` で conjecture 環境を定義したとします。

```latex
\newtheorem{conjecture}{予想}
```

この場合のカウンタは `conjecture` となるので、日本語構成としては次のようにします。これを `\zcLanguageSetup{japanese}` に追加します。

```latex
type = conjecture ,
  Name-sg = 予想 ,
  Name-pl = 予想 ,
```

これによって、`\zcref{cnjc:1}` は “予想 1” となります。

----------

日本語の言語構成は 1 から作成しているので、それらに含めてしまえば良いですが、組み込みで提供されている言語では `\zcRefTypeSetup` を使うと便利です。

```latex
%% lang = english に対する対応例
\zcRefTypeSetup{conjecture}{
    Name-sg = Conjecture ,
    Name-pl = Conjectures ,
    name-sg = conjecture ,
    name-pl = conjectures ,
  }
```

### カウンタをカウンタタイプに一致させる

`\zcsetup` で `countertype` オプションを構成することで、任意のカウンタを既存のカウンタタイプに一致させることができます。

例えば、定理環境を以下のように定義している場合、カウンタは `thm`・`lem` となっています。

```latex
\newtheorem{thm}{定理}
\newtheorem{lem}{補題}
```

そのままではカウンタ `thm`・`lem` が theorem・lemma タイプであると認識されないため、以下のように `countertype` を構成します。

```latex
\zcsetup{
  countertype = {
    thm = theorem ,
    lem = lemma ,
  }
}
```

これによって、thm 環境は theorem タイプとして、lem 環境は lemma タイプとして扱われます。（もちろん、zref-clever が提供するカウンタタイプ名に倣った定理環境名にすれば、このような変更は不要です）

### カウンタの共有

`\newtheorem{lemma}[theorem]{補題}` などとしてカウンタを別の環境と共有している場合、プリアンブルでちょっとしたトリックを課します。(ref. Share counter - § 11.2 `\newtheorem` - [zref-clever-doc.pdf][manual-doc])

```latex
\AddToHook{env/lemma/begin}{%
  \zcsetup{ countertype = { theorem = lemma }}
  %% lemma 環境の直前で
  %% カウンタ theorem のカウンタタイプは lemma だとしている
}
\newtheorem{theorem}{定理}
\newtheorem{lemma}[theorem]{補題}
```

これによって、theorem 環境と lemma 環境のカウンタが共有されるようになります。

<details>
<summary> 作成例コード（折りたたみ）</summary>

```latex
\documentclass{jlreq}
\usepackage{zref-clever}
%%%%% ----- 日本語対応 ----- %%%%%
\zcDeclareLanguage[allcaps]{japanese}
\zcLanguageSetup{japanese}{
  %% ...省略
}
\zcsetup{lang = japanese, countertype = { thm = theorem } }
%%
%%%%% ----- theorem と lemma を構成 ----- %%%%%
\AddToHook{env/lemma/begin}{%
  \zcsetup{ countertype = { theorem = lemma } }
}
\newtheorem{theorem}{定理}
\newtheorem{lemma}[theorem]{補題}
\begin{document}

\begin{theorem} \label{thm:1} これは非常によく知られた定理です。 \end{theorem}
\begin{lemma} \label{lem:1} これはあまり知られていない補題です。 \end{lemma}

\zcref{thm:1, lem:1}

\end{document}
```

</details>

![theorem and lemma](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/9bc1715b-cf3c-cb33-e072-5ba98401dd9b.png "theorem と lemma のカウンタが共有されている例")

### 組み合わせ

以上 3 つの例を踏まえると、2 つの fact 環境と claim 環境をカウンタを thm 環境のカウンタ `thm` と共通させて定義した場合、以下のように構成すれば良いです。

```latex
\AddToHook{env/fact/begin}{%
  \zcsetup{ countertype = { thm = fact } }
}
\AddToHook{env/claim/begin}{%
  \zcsetup{ countertype = { thm = claim } }
}
\zcsetup{ countertype = { thm = theorem } }
\newtheorem{thm}{定理}
\newtheorem{fact}[thm]{事実}
\newtheorem{claim}[thm]{主張}
\zcRefTypeSetup{fact}{
  Name-sg = 事実 ,
  Name-pl = 事実 ,
}
\zcRefTypeSetup{claim}{
  Name-sg = 主張 ,
  Name-pl = 主張 ,
}
```

これによって、thm 環境と fact 環境、claim 環境のカウンタが共有されるようになります。

<details>
<summary> 作成例コード（折りたたみ）</summary>

```latex
\documentclass{jlreq}
\usepackage{zref-clever}
%%%%% ----- 日本語対応 ----- %%%%%
\zcDeclareLanguage[allcaps]{japanese}
\zcLanguageSetup{japanese}{
  %% ...省略
}
\zcsetup{ lang = japanese }
%%
%%%%% ----- thm・fact・claim 環境を構成する ----- %%%%%
\AddToHook{env/fact/begin}{%
  \zcsetup{ countertype = { thm = fact } }
}
\AddToHook{env/claim/begin}{%
  \zcsetup{ countertype = { thm = claim } }
}
\zcsetup{ countertype = { thm = theorem } }
%% zcRefTypeSetup の内容は、上の zcLanguageSetup に含めていても良い
\zcRefTypeSetup{fact}{
  Name-sg = 事実 ,
  Name-pl = 事実 ,
}
\zcRefTypeSetup{claim}{
  Name-sg = 主張 ,
  Name-pl = 主張 ,
}
\newtheorem{thm}{定理}
\newtheorem{fact}[thm]{事実}
\newtheorem{claim}[thm]{主張}
%%
\begin{document}

\begin{thm} \label{thm:1} これは遠い昔の偉い人が示した定理です。 \end{thm}
\begin{fact} \label{fact:1} これは私が見つけた驚愕の事実です。 \end{fact}
\begin{claim} \label{claim:1} これは私のスゴイ主張です。 \end{claim}

\zcref{thm:1, fact:1, claim:1}

\end{document}
```

</details>

![theorem and fact and claim](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/efe87d6e-294e-0284-cbef-f459283d9df3.png "theorem と fact と claim のカウンタが共有されている例")

## 余談

日本では cleveref がほとんど覇権を握っているらしいので、zref-clever を使っている人はいなさそうでした <sup>[要出典]</sup>。
もし興味があれば使ってみてはどうでしょうか。

現在 zref-clever の組み込みの言語構成に日本語はありません。これも興味があれば、[開発リポジトリ][zref-clever-GitHub] に PR を出すと良いでしょう。
実際、日本語の言語構成が組み込まれれば、本記事のおよそ半分は不要になります。

[zref-clever-GitHub]: https://github.com/gusbrs/zref-clever "gusbrs/zref-clever: Clever LaTeX cross-references based on zref"

言語の構成方法の詳細はパッケージガイドを参照してほしいですが、他言語の構成も見ておくとより理解できるでしょう。
zref-clever に組み込みのそれぞれの言語が構成されているコードは以下にあります。

|                                                                                                                                                                                                    |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [英語][en-zclang]、[イタリア語][it-zclang]、[オランダ語][nl-zclang]、[スペイン語][es-zclang]、<br>[ドイツ語][de-zclang]、[フランス語][fr-zclang]、[ポルトガル語][pt-zclang]、[ロシア語][ru-zclang] |

[de-zclang]: https://github.com/gusbrs/zref-clever/blob/8127832a4546d57a55c242eb074c12ea8652166c/zref-clever.dtx#L8703-L9159 "ドイツ語 - zref-clever.dtx/GitHub"
[en-zclang]: https://github.com/gusbrs/zref-clever/blob/8127832a4546d57a55c242eb074c12ea8652166c/zref-clever.dtx#L8476-L8684 "英語 - zref-clever.dtx/GitHub"
[es-zclang]: https://github.com/gusbrs/zref-clever/blob/8127832a4546d57a55c242eb074c12ea8652166c/zref-clever.dtx#L9668-L9885 "スペイン語 - zref-clever.dtx/GitHub"
[fr-zclang]: https://github.com/gusbrs/zref-clever/blob/8127832a4546d57a55c242eb074c12ea8652166c/zref-clever.dtx#L9185-L9403 "フランス語 - zref-clever.dtx/GitHub"
[it-zclang]: https://github.com/gusbrs/zref-clever/blob/8127832a4546d57a55c242eb074c12ea8652166c/zref-clever.dtx#L10161-L10397 "イタリア語 - zref-clever.dtx/GitHub"
[nl-zclang]: https://github.com/gusbrs/zref-clever/blob/8127832a4546d57a55c242eb074c12ea8652166c/zref-clever.dtx#L9902-L10144 "オランダ語 - zref-clever.dtx/GitHub"
[pt-zclang]: https://github.com/gusbrs/zref-clever/blob/8127832a4546d57a55c242eb074c12ea8652166c/zref-clever.dtx#L9421-L9653 "ポルトガル語 - zref-clever.dtx/GitHub"
[ru-zclang]: https://github.com/gusbrs/zref-clever/blob/8127832a4546d57a55c242eb074c12ea8652166c/zref-clever.dtx#L10417-L11655 "ロシア語 - zref-clever.dtx/GitHub"

----------

以降では、これまで紹介していなかった zref-clever の基本的な情報に関して紹介します。

### オプションのデフォルト

代表的なオプションのデフォルト値は以下のようになってます。これらはパッケージオプションとコマンドオプションの両方で使用できます。

| オプション <br>（デフォルト値） | 説明                                                                              |
| :-----------------------------: | :-------------------------------------------------------------------------------- |
|       `sort`<br>(`true`)        | 順序通りの並び替え                                                                |
|       `comp`<br>(`true`)        | 3 つ以上連続するラベルを list 参照から range 参照にする                           |
|      `range`<br>(`false`)       | pair・list 参照を range 参照にする                                                |
|    `rangetopair`<br>(`true`)    | `range = true` 下で range 参照を pair 参照にする                                  |
|       `cap`<br>(`false`)        | 参照タイプ名をタイトルケースに変更                                                |
|      `abbrev`<br>(`false`)      | 参照タイプ名を略称に変更                                                          |
|   `nameinlink`<br>(`tsingle`)   | 参照タイプ名をハイパーリンクに含めるか <br>(`tsingle`, `single`, `true`, `false`) |
|      `lang`<br>(`english`)      | 参照タイプ名の言語                                                                |

この他に、type list 参照において出力する参照タイプの順序を制御する `sorttype` などがあります。

### `\zcref` のオプション

cleveref ではコマンドに多くのバリエーションがありましたが、zref-clever の `\zcref` はコマンドオプションで表現します。
ここでは cleveref のコマンドに対比する形でいくつか紹介します。

| 参照の種類         |     zref-clever      |   cleveref   |
| :----------------- | :------------------: | :----------: |
| 範囲参照           |       `range`        | `\crefrange` |
| ページ参照         |        `page`        | `\cpageref`  |
| 参照タイプのみ参照 |       `noref`        | `\namecref`  |
| ラベルのみ参照     | `noname` [^namewith] | `\labelcref` |
| 行頭用             | `S` (`cap noabbrev`) |   `\Cref`    |
| ハイパーリンク無し |      `\zcref*`       |   `\cref*`   |

[^namewith]: `noname` オプションでは、`refbounds` が付随します。そのため、`refbounds` を課している参照タイプで参照番号のみを得たい場合は、以下のようにします。

    ```latex
    \zcref[noname, refbounds = {}]{eqn:1}
    ```

加えて、`\zcref[page]` と等価な `\zcpageref` も提供されています。

この他の cleveref のコマンドはオプションを組み合わせれば良いので、例えば、`\Cpagerefrange` は `\zcref[S, page, range]` あるいは `\zcpageref[S, range]` と等価になります。

### 対応パッケージと互換モジュール

zref-clever は以下の機能と 8 のパッケージに対応しています。細かな対応方法に関しては [パッケージガイド][manual-doc] を参照してください。

|                                                                                                                              |
| ---------------------------------------------------------------------------------------------------------------------------- |
| `\newtheorem`, [amsmath][], [breqn][], [enumitem][], [listings][], [newfloat][], [tcolorbox][], [zref-vario][], [zref-xr][]. |

[amsmath]: https://www.ctan.org/pkg/amsmath "amsmath - CTAN"
[breqn]: https://www.ctan.org/pkg/breqn "breqn - CTAN"
[enumitem]: https://www.ctan.org/pkg/enumitem "enumitem - CTAN"
[newfloat]: https://www.ctan.org/pkg/newfloat "newfloat - CTAN"
[tcolorbox]: https://www.ctan.org/pkg/tcolorbox "tcolorbox - CTAN"
[zref-vario]: https://www.ctan.org/pkg/zref-vario "zref-vario - CTAN"
[zref-xr]: https://www.ctan.org/pkg/zref-xr "zref-xr - CTAN"

加えて、以下の機能と 9 のパッケージの互換モジュールがあります。

|                                                                                                                                         |
| --------------------------------------------------------------------------------------------------------------------------------------- |
| [`\appendix`][appendix], amsmath, [appendices][], breqn, enumitem, [listings][], [mathtools][], [memoir][], [subcaption][], [subfig][]. |

[appendix]: https://latexref.xyz/_005cappendix.html "\appendix (LaTeX2e unofficial reference manual (May 2024))"
[appendices]: https://www.ctan.org/pkg/appendices "appendices - CTAN"
[subcaption]: https://www.ctan.org/pkg/subcaption "subcaption - CTAN"
[subfig]: https://www.ctan.org/pkg/subfig "subfig - CTAN"

デフォルトでこれらの互換モジュールは有効になっています。
もしもこれを無効化したい場合は、`nocompat` オプションから無効化したいモジュールを指定します。

beamer に関しては公式に対応していませんが、対処方法が § 14 Work-arounds - [zref-clever-doc.pdf][manual-doc] に記載されています。

### `\label` と `\zlabel`

zref-clever は zref を使って作成されているため、本来 `\zlabel` を使ってラベルを作成します。

しかし、zref-clever は `\label` とすることで `\zlabel` も呼び出されるようになっています。これは `labelhook` オプションで制御されています。
そのため、`\label` でラベリングしたものを `\zcref` で参照することが出来ます。

より詳細な話は [パッケージガイド][manual-doc] の § 6 を参照してください。

#### LaTeX Workshop での対応

デフォルトの LaTeX Workshop では、`\zlabel` を使っても `\label` と同じように `\ref` 系で参照する際に候補としてラベル名を表示しません。
そのため、以下の設定で `zlabel` を追加します。

```jsonc
  "latex-workshop.intellisense.label.command": [
    "label",
    "linelabel",
    "zlabel", // <-- これを追加
  ]
```

`\zlabel` を使う人は追加しておくと便利でしょう。