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'm documenting a software project using LyX and many of the "things" (classes, processes, etc.) that I'm describing don't yet have good names. As my understanding of these things improves, I want to give them better names. But I don't want to end up with a situation where a given thing is referred to by more than one name due to a botched search-and-replace.

I vaguely remember that there is a way in LyX to insert a reference to a term that will auto-update when the referenced term is modified. For example, if I have a section titled "All About Foobar", I can insert references to "Foobar" in the subsequent text. If ever I decide on a more descriptive name for Foobar, say Bazqux, I can simply update the section title and--poof!--every Foobar becomes a Bazqux.

It's a simple thing, but my Google-fu is weak this afternoon. Or maybe I'm crazy and no such feature exists.

share|improve this question

3 Answers 3

up vote 12 down vote accepted

It's not entirely clear what you want, exactly. But you can easily define a macro which spells out the name and can therefore be changed once in the document. For example, if you have something that for the moment you are calling 'class', you could define the following macro:

\newcommand*{\class}{class}

(The * here means that the macro can't contain any paragraph breaks; see the following question for more details on this.

What's the difference between \newcommand and \newcommand*?

In your text, you would then type \class in every place you want that object name. If you decide that you want to call a class a method, you would simply redefine the \class macro:

\newcommand*{\class}{method}

There are a couple of things you need to bear in mind with this sort of solution. First, spaces after macros are ignored, so if you your source has

In this \class we strip out spaces.

It will be rendered as In this classwe strip out spaces, which is not what you want. You can't simply add a space to the definition, since this will incorrectly add spaces before e.g. punctuation marks, where you don't want them. So there are two ways around this. One is to simply insert an overt space whenever you need one using \:

In this \class\ we strip out spaces.

The other solution is to use the xspace package, which inserts a space automatically and takes care not to insert the space before punctuation.

\usepackage{xspace}
\newcommand*{\class}{class\xspace}

Then you don't need to type the explicit space yourself. Note, however, that there are some drawbacks to using the xspace approach. See:

Drawbacks of xspace

The second pitfall with defining replacement macros this way, is that they don't adjust for things like plurals and capitalization. To capture these cases, it's probably easiest to simply define uppercase and plural version of the macros themselves. (You could do other fancier things, but at the expense of making your source less readable.) So you could define:

\newcommand*{\Class}{Class}
\newcommand*{\classes}{\class es}
\newcommand*{\Classes}{\Class es}

The following article by Will Robertson is a useful guide to these sorts of techniques:

Productivity with Macros and Packages

Here is a small document with all of the examples above included in it.

\documentclass{article}
\usepackage[margin=1in]{geometry}
\usepackage{xspace}
\newcommand*{\class}{class} % if your command will have multiple lines omit the *
\newcommand*{\Class}{Class} % uppercase version
\newcommand*{\classes}{\class es} % plural versions
\newcommand*{\Classes}{\Class es}

\begin{document}
If we don't add an explicit space after the \class macro it doesn't work as we expect.

We can make the \class\ macro work by adding the space explicitly.

Or if we change the macro to use the xspace package, it will insert the space automatically:
\renewcommand*{\class}{class\xspace}

Now the \class macro inserts a space, but not when there is punctuation following \class.
\end{document}

The only thing I haven't mentioned here is how to do all of this in LyX. The \newcommand definitions go into your document preamble the way you would add any other raw LaTeX code to a document. If you will be using them a lot it might be useful to create a LyX layout to do this. For more on how to add customized environments to LyX see:

Create new paragraph style in LyX

share|improve this answer
    
This is a great answer. This is what we need more of! –  Seamus Mar 6 '11 at 21:19
    
Thanks for pointing out Will's article! –  TH. Mar 7 '11 at 4:12
1  
You have to use a Tex code block to insert the macro in Lyx. –  Charles Stewart Mar 7 '11 at 7:06
    
@Charles and Alan, Could you please show how this is done in Lyx? (Or I could open a new question). –  macmadness86 May 13 '13 at 12:16
    
@macmadness86 We don't have many good LyX answers here because most of us (including me) don't use LyX (which doesn't mean that you shouldn't try to ask LyX questions here, however.) This question: Lyx: Quick way to insert Dirac bra-ket has a pretty good explanation of how to insert raw LaTeX code in LyX though. –  Alan Munn May 13 '13 at 14:17

LyX doesn't (yet) provide native support for LaTeX text macros. This is the subject of a nine-year old enhancement request. And it has been discussed on several occasions on the lyx-users ML, including in this thread.

This said, you can still use normal LaTeX macros in LyX by defining them in Document > Settings > Preamble, e.g.:

\newcommand{\mktd}{minimum KT distance}

and then putting \mktd in an ERT inset (Insert > TeX Code) anywhere in the document.

share|improve this answer
    
@scottkosty Is there a more LyX-ish way to do this? I thought that we could use the math macros, for which LyX has native support, but I'm not sure how useful they are in this context. –  landroni Jan 21 at 23:17
    
I think that's good. If someone wanted to avoid ERT they could use a module. Going to Insert > Custom Inset > ... is annoying each tie one would want to enter it though but it could be bound to a shortcut. (note that I was not notified of your comment, I just happened to see your update. I'm not sure why. If I don't respond to any of your questions in the future please email me.) –  scottkosty Jan 22 at 3:16
    
@scottkosty On lyx-users it was often suggested the use of layouts/modules for this, but I never really understood what they meant by that. Can we use local layout for this? And if so this could be useful, indeed. Could you provide an actual example in a separate answer? –  landroni Jan 22 at 8:06
    
sure, I'll do that. Yes you can use local layout. You can use local layout whenever you could use a module. –  scottkosty Jan 22 at 17:56

Put the following in Document > Settings > Local Layout:

InsetLayout "Flex:myTextMacroInset"
  LabelString         "My Text Macro"
  LatexType             Command
  LaTexName             myTextMacro
  LyxType                 "custom"
  Decoration            Classic
  Preamble
    \newcommand{\myTextMacro}{Foobar}
  EndPreamble
End

Then you can Insert > Custom Insets > myTextMacroInset anywhere in the LyX document. You could also add a shortcut for the command flex-insert "myTextMacroInset" in Tools > Prefs > Editing > Shortcuts.

A couple of comments:

  • I thought there was a way to create the inset without having a box to input text. I could not figure this out though.
  • You could make this a little more simple by using LatexType "None" and inserting the text directly (maybe with LeftDelim), but when exported to LaTeX the "constant" macro would not be preserved. This would just be a LyX constant.
share|improve this answer
    
Thanks! "I thought there was a way to create the inset without having a box to input text." That's likely my fault: lyx.org/trac/ticket/8442 . Otherwise, once the inset is inserted, you can click to the label to collapse it, and then use copy/paste to move it around. –  landroni Jan 22 at 21:32
    
@landroni That might be why I thought that. Although even with that one could still open and then insert text, but it would not be as hard to make the mistake. I like the change though because there are more insets that require input than do not so the default now makes sense. –  scottkosty Jan 22 at 21:35
    
Agreed, but I'd still prefer to have a layout arg for controlling that.. –  landroni Jan 22 at 21:38
    
@landroni yes that would be nice. –  scottkosty Jan 23 at 1:33

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.