我发现 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]%
}
答案是它只会阻止右侧寄生空间,但左侧仍会保留一个额外的寄生空间。因此,将辅助宏包装到上述构造中很重要,以保持引用周围的间距正确排版。