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您可以使用命令的键为每种浮点类型设置一个前缀\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{

定义\figure两次,丢弃第一个定义\corefigure,我怀疑你打算\let在另一个方向保存现有的定义\figure

 \let\corefigure\figure

答案3

尽管 Metafox 的答案提供了很好的提示referenceprefix,但它仍然只是解决方案的一半。在这里,我想提供完整可靠的解决方案并附上解释,因为在将它们拼凑在一起之前,有一些令人讨厌的陷阱。我将介绍图形、表格和公式的解决方案,其他浮动对象将遵循相同的方案。我相信有些人会觉得它很有用。

PS:上帝保佑你们,苦涩者们,你们对我的问题投了反对票。

解决方案


因此,首先要定义的是标题:

\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[...]

您可能会说:“好吧,为什么不尝试传统方法呢:”

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

答案是它只会阻止右侧寄生空间,但左侧仍会保留一个额外的寄生空间。因此,将辅助宏包装到上述构造中很重要,以保持引用周围的间距正确排版。

相关内容