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[...]в своем тексте, не опасаясь конфликта имен между различными типами плавающих объектов. Продолжайте читать, если хотите узнать о подводных камнях и о том, как они были решены.

Подводные камни


Во-первых, обратите внимание на знак процента ( %) после \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]%
}

Ответ в том, что это предотвратит только правый паразитный пробел, но один дополнительный паразитный пробел слева все равно останется. Поэтому важно сохранить вспомогательные макросы, заключенные в конструкцию выше, чтобы сохранить интервалы вокруг ссылок, набранных правильно.

Связанный контент