ConTeXt: 異なるタイプの浮動オブジェクトにおける参照名の衝突を防ぐ

ConTeXt: 異なるタイプの浮動オブジェクトにおける参照名の衝突を防ぐ

ConTeXt がフローティング オブジェクトの参照に同じ名前空間を使用するのは非常に迷惑です。言い換えると、図と表に同じ参照を与えると、常に最初に定義されたものを参照することになります。つまり、明らかに名前が衝突します。これは私の観点からすると愚かなことです。ConTeXt Wiki では、 のような回避策を見ました。つまり、すべての参照に というプレフィックスを\figure[figure:Your Reference]スパムすることを提案していますが、これもまた非常に迷惑です。figure:table:

私がやりたいことは次のとおりです:

\let\corefigure\figure

\def
\figure{
  \dosingleargument
  \dofigure
}

\def
\dofigure[#1]{
  \corefigure[figure:#1]
}

そして

\let\corestartplacefigure\startplacefigure

\def
\startplacefigure{
  \dotripleargument
  \dostartplacefigure
}

\def
\dostartplacefigure[#1][#2][#3]{
  # TODO: Somehow insert "figure:" into #1 after "reference="...
  \corestartplacefigure[#1][#2][#3]
}

テーブルについても同じことが言えます。では、TODOそれを巧みに実現するにはどうすればいいのでしょうか?

提案と説明をお待ちしています。 ありがとうございます。

答え1

referenceprefixコマンドのキーを使用して、各 float タイプのプレフィックスを設定できます\setupcation

\setupexternalfigures[location=default]

\setupcaption[figure][referenceprefix=figure]
\setupcaption[table] [referenceprefix=table]

\starttext

\dorecurse{3}{\input knuth\par}

\startplacefigure[title=Test figure,reference=test]
  \externalfigure[cow][width=4cm]
\stopplacefigure

\dorecurse{3}{\input zapf\par}

\startplacetable[title=Test table,reference=test]
  \starttabulate[|l|l|]
  \HL
  \NC One \NC Two \NC\NR
  \NC Three \NC Four \NC\NR
  \HL
  \stoptabulate
\stopplacetable

\dorecurse{3}{\input tufte\par}

\page

This documents contains a figure on \at{page}[figure:test] and a table on \at{page}[table:test].

\stoptext

答え2

\let\figure\corefigure

\def
\figure{

を2回定義し\figure、最初の定義を破棄すると、既存の定義を保存するために逆方向に\corefigure定義したのではないかと思います。\let\figure

 \let\corefigure\figure

答え3

Metafox の回答は で非常に良いヒントを提供しましたがreferenceprefix、それでもまだ解決策の半分にすぎませんでした。ここでは、すべてをまとめる前に厄介な落とし穴があったので、説明付きの完全な堅牢な解決策を提供したいと思います。図、表、数式の解決策を提示しますが、他のフローティング オブジェクトも同じスキームに従います。役に立つと思う人もいると思います。

追伸:私の質問に反対票を投じた苦い人たちに神のご加護がありますように。

解決


したがって、最初に定義するのはキャプションです。

\setupcaption
[figure][
            style={small},
        headstyle={bold},
            width={\textwidth},
            align={middle},
         location={bottom},
              way={bysection},
           prefix={yes},
   prefixsegments={chapter:section},
  referenceprefix={figure},
]

\setupcaption
[table][
            style={small},
        headstyle={bold},
            width={\textwidth},
            align={right},
         location={top},
              way={bysection},
           prefix={yes},
   prefixsegments={chapter:section},
  referenceprefix={table},
]

\setupformulas[
      numberstyle={bold},
              way={bysection},
           prefix={yes},
   prefixsegments={chapter:section},
  referenceprefix={formula},
]

設定はたくさんありますが、完全性のためにリストされています。ここでの説明で重要なのは ですreferenceprefix。次に、参照形式を定義します。

\definereferenceformat
[infigure]

\definereferenceformat
[intable]

\definereferenceformat
[informula][
   left={(},
  right={)},
]

これらすべてにプレフィックス を付けたことに注目してくださいin。これは重要です。なぜなら、実際に上記のコマンドは新しいマクロ 、 、 を定義しているからです\infigure[...]\intable[...]これら\informula[...]は補助マクロであり、テキスト内で直接使用することはありません。

最後に、カスタムマクロをわかりやすい名前で定義します: \figure[...]\table[...]\formula[...]:

\def
\figure{
  \dosingleargument
  \dofigure
}

\def
\dofigure[#1]{%
  \leavevmode
  \unskip
  \infigure
  [figure:#1]
  \ignorespaces
  \unskip
}

\def
\table{
  \dosingleargument
  \dotable
}

\def
\dotable[#1]{%
  \leavevmode
  \unskip
  \intable
  [table:#1]
  \ignorespaces
  \unskip
}

\def
\formula{
  \dosingleargument
  \doformula
}

\def
\doformula[#1]{%
  \leavevmode
  \unskip
  \informula
  [formula:#1]
  \ignorespaces
  \unskip
}

これで完了です。これで、異なるタイプのフローティング オブジェクト間で名前が衝突する心配なく、テキスト内で、 、を安全に使用できます。落とし穴とその解決方法について知りたい場合は、読み続けてください\figure[...]\table[...]\formula[...]

落とし穴


まず、 and brothers の後のパーセント記号 ( %)に注目してください\dofigure[#1]{。これは、参照の前に余分なパラサイト スペースが入るのを防ぎます。これを削除してみると、私が何を言っているのかがわかるでしょう。

第二に、\infigure[figure:#1]兄弟がどのように包まれているかに注目してください

\leavevmode
\unskip
...
\ignorespaces
\unskip

これらを省略して、何が起こるか自分で確認してみてください。すべての参照の周囲に奇妙なスペースがあることに気づくはずです。具体的に言うと、参照の周囲に 2 つの余分な寄生スペースが追加されているように見えます。これは、純粋なマクロが使用されている場所で私が気づいた問題であり、 (補助マクロ、、など)\in[...]で定義されたマクロでは、、、などの他のマクロ内で展開される場合にのみ発生します。\definereferenceformat\infigure[...]\intable[...]\informula[...]\figure[...]\table[...]\formula[...]

「OK、従来の方法を試してみませんか」と言うこともできます。

\def
\dofigure[#1]{%
  \infigure[figure:#1]%
}

答えは、右側の寄生スペースのみが防止されますが、左側からの追加の寄生スペースが 1 つ残ります。したがって、参照の周囲のスペースが正しくタイプセットされるようにするには、上記の構造に補助マクロをラップしておくことが重要です。

関連情報