# Creating a cross referencing shortcut

I believe I have gather all the pieces of information I need to create what I want but yet I cannot make the connection. Let me start with the goal.

# Simple Cross referencing

Let us start by creating a new notebook. Here we create a "DisplayFormulaNumbered" cell. Enter whatever contents you want here. Then press command+J or control+J in windows and enter the tag that you want to give your equation. Here is a screenshot of what I have so far:

To be able to see the tag go to Cell > Cell Tags > Show Cell Tags. What we want now is to refer to eq1. Here is a text cell:

Notice here that I'm using the exact $\LaTeX$ notation. What I want to do now, is to be able to select the text cell, press some button in a palette and obtain this:

# Tools gathered so far

jVincent showed me here how to create the a button that executes a function to replace a selected part of the text. Notice here that I do not want to be selecting parts of text manually, I want to apply the function to the whole cell and replace the part containing ref with CounterBox["DisplayFormulaNumbered", "eq1"]. In other words, the ref parts will tell it to put "DisplayFormulaNumbered" and the text in between the brackets next to ref is the tag.

To find the cases where I have ref we can use something like this:

StringCases["Reference \\ref{tag1} goes here. Reference \\ref{tag2} \here.", "\\ref{" ~~ __ ~~ "}"]

{"\\ref{tag1} goes here. Reference \\ref{tag2}"}


Unfortunately, I'm not quite making a good use of it. But the idea is to maybe use something like this to obtain the tag. Next we have to check if this is a valid tag in the notebook (given that we were able to locate the tag in the whole string):

MemberQ[NotebookToolsNotebookCellTags[EvaluationNotebook[]], "tagName"]


This is thanks to Rojo's answer. I feel a little ashamed that I cannot combine the tools that you guys have provided me yet but I'd rather get this out of the way so that I can be more efficient when doing cross referencing. What do you guys think? Is this worth the trouble of creating a palette button that does this?

# EDIT:

The idea I was suggesting for making the shortcut is by no means what I wanted to see. I guess I should have clarified that really all I wanted to see was an easy and fast method of dealing with cross referencing. Albert Retey has shown two methods in his answer and makes a good point that if you were to keep typing large chunks of text and evaluate everything in one go then my suggestion would be justified. In any case, I'm satisfied with Retey's method but other neat ideas are still welcomed.

-

What I would suggest is not exactly doing what you want, but I don't see much sense in sticking to $\LaTeX$ notation whe working in a Mathematica notebook and believe the following is even more convenient. What I'd do is this:

• Define this:

ref[tag_] := NotebookWrite[SelectedNotebook[],
RowBox[{"[", CounterBox["DisplayFormulaNumbered", ToString@tag],"]"}]
]

• When I need a reference to tag eq1 within some text type: ref@eq1

• Select ref@eq1, presumably by Ctrl-Shift-backarrow on Windows (Opt-Shift-backarrow on a Mac)

• Evaluate in place with Ctrl-Shift-Return on Windows (Command-Return on a Mac).

That way I could enter these references when typing with my fingers on the keyboard. Here is a button which also does something useful, but not exactly what you asked for (which has some subtletys I'm trying to avoid, as you might have recognized :-):

CreatePalette[
Button["Enter Reference",
Module[{tag = ToString@Input["Enter Tag:"]},
If[MemberQ[NotebookToolsNotebookCellTags[SelectedNotebook[]], tag],
NotebookWrite[SelectedNotebook[],
RowBox[{"[", CounterBox["DisplayFormulaNumbered", tag], "]"}]
],
MessageDialog["could not find tag: " <> tag]
]
],
Method -> "Queued"
]
]


you would press the button, enter a tag in the dialog box, hit Enter (or press the "OK" button) and the CounterBox will be inserted at the current cursor position (be aware that it will replace everything that has been selected).

One thing that would justify a solution as you suggest would be if you have a large text written in the above form and process it in one go. If that's what you'r after maybe you want to make that clear in your question to motiviate someone to write something...

-
You know, I actually thought about doing your first suggestion but I had no idea how to do it. I'm really loving entering the references with my fingers on the keyboard. On a mac you use option+shift+left arrow to select the last string you typed. To evaluate in place you use command+return. The palette is a welcomed method also. Thank you. –  jmlopez Jun 9 '12 at 0:08
One last thing, to make use of your palette and to make it all in the keyboard, is there a way to assign a keyboard shortcut to activate the button? That way we can be typing, then enter the shortcut, the dialog box opens, you type the reference press enter and you continue typing. –  jmlopez Jun 9 '12 at 0:20
I don't think there is a way to press a button from the keyboard (except for external tools). What you can do within Mathematica is to define a keyboard shortcut to automatically evaluate what is in the buttons "action". There are several answers which show you how to do that by editing KeyEventTranslations.tr, e.g. here, but you can search for KeyEventTranslations.tr to find other examples. –  Albert Retey Jun 9 '12 at 8:53