
Я нахожу очень раздражающим, что 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[...]
в своем тексте, не опасаясь конфликта имен между различными типами плавающих объектов. Продолжайте читать, если хотите узнать о подводных камнях и о том, как они были решены.
Подводные камни
Во-первых, обратите внимание на знак процента ( %
) после \dofigure[#1]{
and brothers. Он предотвращает появление дополнительного паразитного пространства перед ссылками. Попробуйте убрать его, и вы поймете, о чем я говорю.
Во-вторых, обратите внимание, как \infigure[figure:#1]
братья и сестры завернуты в
\leavevmode
\unskip
...
\ignorespaces
\unskip
Вы можете попробовать опустить их, чтобы увидеть, что произойдет. Вы должны заметить странные пробелы вокруг всех ваших ссылок: если быть более точным, кажется, что вокруг ссылок добавляются 2 дополнительных паразитных пробела. Это проблема, которую я заметил в чистом \in[...]
макросе, где бы он ни использовался, и в тех, которые определены с помощью \definereferenceformat
(например, наши вспомогательные макросы \infigure[...]
, \intable[...]
, \informula[...]
), только если они развернуты внутри других макросов, таких как наши \figure[...]
, \table[...]
, и \formula[...]
.
Вы могли бы сказать: «Хорошо, почему бы не попробовать традиционный способ»:
\def
\dofigure[#1]{%
\infigure[figure:#1]%
}
Ответ в том, что это предотвратит только правый паразитный пробел, но один дополнительный паразитный пробел слева все равно останется. Поэтому важно сохранить вспомогательные макросы, заключенные в конструкцию выше, чтобы сохранить интервалы вокруг ссылок, набранных правильно.