Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I find it very annoying that ConTeXt uses the same namespace for references of floating objects. In other words, if you give the same reference to a figure and a table, then you'd always refer to the one which was defined first, i.e. obvious clash of names. This is stupid from my point of view. On ConTeXt Wiki I've seen workarounds like \figure[figure:Your Reference], i.e. they propose to spam figure:, table: prefixes on all of your references, what I find quite annoying once again.

Here is what I want to do:

\let\corefigure\figure

\def
\figure{
  \dosingleargument
  \dofigure
}

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

and

\let\corestartplacefigure\startplacefigure

\def
\startplacefigure{
  \dotripleargument
  \dostartplacefigure
}

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

The same would go for table. So how to cleverly fulfill the TODO thingy?

Looking for suggestions and clarifications. Thanks.

share|improve this question
2  
Please: less drama, more useful information (i.e., full document showing your problem). –  Thomas May 11 at 12:25
1  
Post a complete minimal example. AFAIK, there is no core \figure macro. Is that supposed to be a replacement for \in? –  Aditya May 11 at 15:47
    
@Aditya: \figure wraps \in when one uses \definereferenceformat[figure]. Anyway, I've managed to tailor a good solution, see my answer if you are interested. –  Haroogan May 13 at 14:00

3 Answers 3

You can set a prefix for each float type with the referenceprefix key for the \setupcation command.

\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
share|improve this answer
    
Please post complete answers, not just fractions. –  Christian Hupfer May 11 at 16:14
1  
@ChristianHupfer as far as I can see this is a complete answer?! The code compiles fine and the first sentence explains the significant piece of code... –  cgnieder May 11 at 18:47
    
@Christian Hupfer: Agreed, this answer was a good hint, but not complete. See my own answer for the complete solution if you are interested. –  Haroogan May 13 at 13:53
2  
This answer provides a complete answer of the question, as far as one could understand the question. I have started a bounty that I will award to this clear and succinct answer. –  Aditya May 13 at 16:13
2  
@Haroogan: The only question in your post was So how to cleverly fulfill the TODO thingy?. The post answers that. –  Aditya May 13 at 19:58
\let\figure\corefigure

\def
\figure{

defines \figure twice, discarding the first definition to \corefigure, I suspect you intended the \let in the other direction to save the existing definition of \figure

 \let\corefigure\figure
share|improve this answer
1  
@Haroogan as for latex questions on the site it would be far easier for anyone to answer if you posted a small complete document and said exactly what doesn't work with the posted document typos in posted code indicates the posted code isn't generating the problem described. I don't know context that well, but posting a working example helps whether it's context or latex or Fortran for that matter. –  David Carlisle May 11 at 9:52
up vote 3 down vote accepted

Although Metafox's answer provided a very good hint with referenceprefix, it was still only a half of the solution. Here I would like to provide full robust solution with explanations because there were some nasty pitfalls before I could piece it all together. I will present the solutions for figures, tables, and formulas, other floating objects will obey the same scheme. I'm sure some people will find it useful.

P.S. God bless you, bittermen, who down voted my question.

Solution


So, the first things to define are captions:

\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},
]

There are plenty of settings, but they are listed just for the sake of completeness. The important ones for our discussion are referenceprefix. Next, we define reference formats:

\definereferenceformat
[infigure]

\definereferenceformat
[intable]

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

Pay attention that I gave all of them a prefix in. This is important because in fact commands above have defined new macros: \infigure[...], \intable[...], \informula[...]. These will be our auxiliary macros, and we are not going to use them directly in our text!

Finally, we define our custom macros with friendly names: \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
}

We are done. Now you can safely use \figure[...], \table[...], and \formula[...] in your text without fear of naming clash between different types of floating objects. Continue reading if you want to learn about pitfalls and how they were solved.

Pitfalls


First, notice the percent sign (%) after \dofigure[#1]{ and brothers. This one prevents additional parasite space in front of references. Try to remove it and you'll see what I'm talking about.

Secondly, notice how \infigure[figure:#1] and brothers are wrapped into

\leavevmode
\unskip
...
\ignorespaces
\unskip

You can try to omit them to see yourself what's going to happen. You should notice weird spacing around all of your references: to be more specific, it seems like 2 additional parasite spaces are added around references. This is the problem that I've noticed on pure \in[...] macro wherever it is used, and on the ones defined with \definereferenceformat (like our auxiliary macros \infigure[...], \intable[...], \informula[...]) only if they are expanded inside other macros like our \figure[...], \table[...], and \formula[...].

You could say, "OK, why not try conventional way:"

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

The answer is that it will prevent only right parasite space, but one additional parasite space from the left will still remain. Therefore it is important to keep auxiliary macros wrapped into above construct to keep spacing around references being typeset correctly.

share|improve this answer
1  
The space on the left is because you do not use % after the { in the first \def\figure{. You do not need all the \unskip and \ignorespaces. If you do not want to add % all over the code, look at \starttexdefinition, etc. –  Aditya May 13 at 19:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.