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 trying to create an extendable command that can take in a single argument (possibly in the following form):

\menuentry{File:New:Class}

And generate something like:

\texttt{File -> New -> Class} 

The issue is that the arguments have to be flexible. I should be able to provide any depth of menus. The reason for doing this is that I might want to change the formatting later on and I don't want to have to replace all the texttts manually.

share|improve this question
add comment

5 Answers

up vote 13 down vote accepted

The etoolbox package is rich with list processing options. Here's one attempt.

enter image description here

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\menuitem}{\texttt}% Menu item formatting
\newcommand{\menusep}{\ensuremath{\rightarrow}}% Menu separator
\newcommand{\menuend}{\relax}% Menu end
\makeatletter
\newcommand{\menulist}[1]{% \menulist{<menu list>}
  \def\menu@sep{\def\menu@sep{\menusep}}% http://tex.stackexchange.com/a/89187/5764
  \renewcommand*{\do}[1]{\menu@sep\menuitem{##1}}%
  \menulistparser{#1}% Process list
  \menuend%
}
\makeatother
\DeclareListParser{\menulistparser}{:}% List separator is ':'
\begin{document}

\menulist{File:New:Class}% 3 menu items

\menulist{Tools:Options:Advanced:Properties:Document}% 5 menu items

\menulist{}% 0 menu items/empty list

\menulist{Help}% 1 menu item

\renewcommand{\menusep}{~\rule{1ex}{1ex}~}\renewcommand{\menuend}{!}% Different separator and end
\menulist{Your:Menu:Sequence:Here}

\end{document}

\DeclareListParser{<cmd>}{<sep>} declares a list parser command <cmd> that processes a single argument as a list, with list item separator <sep>. The use of this definition is to accommodate an item:item:item:... style list. For regular CSV lists, you could also use \docsvlist which is predefined as \DeclareListParser{\docsvlist}{,} by etoolbox.

The main command \menulist{<menu list>} parses the list and formats each entry using \menuitem{..} but also adds a custom separator \menusep. The last menu item is followed by \menuend. The \menusep is applied with a "single delay" using one of the Cunning LaTeX tricks.

share|improve this answer
    
All the answers are good but this one seems to be the most robust. So, I'll accept this one. –  recluze Jan 10 '12 at 6:25
add comment

A LaTeX3 solution; some input and output parameters are customizable via a key-value syntax. Notice that the default delimiter : must be set after \ExplSyntaxOff. Keys set in the optional argument of \menuentry are local to that command only.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\menuentry}{ O{} m }
  {
   \group_begin: % to segregate local changes to keys and font
   \keys_set:nn { menuentry } { #1 }
   \exp_args:NNx \seq_set_split:Nnn \l_menuentry_seq { \l_menuentry_inputsep_tl } { #2 }
   \tl_use:N \l_menuentry_font_tl
   \bool_set_false:N \l_tmpa_bool
   \seq_map_function:NN \l_menuentry_seq \menuentry_process:n
   \group_end:
  }
\NewDocumentCommand{\menuentryset} { m }
  { \keys_set:nn { menuentry } { #1 } }

\tl_new:N \l_menuentry_font_tl
\tl_new:N \l_menuentry_sep_tl
\tl_new:N \l_menuentry_inputsep_tl
\seq_new:N \l_menuentry_seq

\cs_new:Npn \menuentry_process:n #1
  {
   \bool_if:NTF \l_tmpa_bool 
     { \l_menuentry_sep_tl }
     { \bool_set_true:N \l_tmpa_bool }
   \tl_if_empty:nTF { #1 } {EMPTY~ARG!} { #1 }
  }
\keys_define:nn { menuentry }
  {
   menufont .tl_set:N = \l_menuentry_font_tl ,
   menusep  .tl_set:N = \l_menuentry_sep_tl,
   inputsep .tl_set:N = \l_menuentry_inputsep_tl,
  }
\keys_set:nn { menuentry }
  {
   menufont = \sffamily ,
   menusep  = ${}\to{}$
  }
\ExplSyntaxOff
\menuentryset{inputsep=:}

\begin{document}

\menuentry{}% 0 menu items/empty list

\menuentry{Help}% 1 menu item

\menuentry{File:New:Class}% 3 menu items

\menuentry{Tools:Options:Advanced:Properties:Document}% 5 menu items

\menuentryset{menufont=\ttfamily,menusep=~>{ },inputsep=/}

\menuentry{Help}% 1 menu item

\menuentry{File/New/Class}% 3 menu items

\menuentry[inputsep=|]{Tools|Options|Advanced|Properties|Document}% 5 menu items

\end{document}

enter image description here

share|improve this answer
add comment

Here's an example using the xstring package

enter image description here

Have a look at the documentation- there are a lot of other commands that could help you customize this command.

\documentclass{article}
\usepackage{xstring}

\newcommand{\menuentry}[1]{\StrSubstitute{#1}{:}{$\rightarrow$}[\dummy]\texttt{\dummy}}

\begin{document}

\menuentry{File:New:Class}

\menuentry{File:New:Class:SubClass}
\end{document}  
share|improve this answer
2  
If you're going to use math mode, isn't it better to write $\rightarrow$ instead of faux-arrows? –  Ryan Reich Jan 10 '12 at 5:38
    
@RyanReich yes, completely agree :) Looks like Werner did too- thanks! –  cmhughes Jan 10 '12 at 17:13
add comment

You can place the menu items in a list and iterate over it. Here is a short MWE as to how to iterate over the list. I have included for a small image uncomment the relevant line to include your own.

enter image description here

\documentclass[justified]{tufte-book}
\usepackage{lipsum}
\begin{document}
\def\spacer{\hspace{3pt}}
\def\test{}
%\def\test{\includegraphics[height=7pt]{./graphics/web/add.png}}
\def\alist{Dashboard, Content, Structure, Hello~yannis, Log Out, \test}
\makeatletter
\noindent\fbox{%
\begin{minipage}{9cm}
\noindent\colorbox{black}{\small
\@for \i:=\alist \do{\color{white}
  \texttt\i\spacer 
}}
\smallskip
\tiny \lipsum[1-2]
\end{minipage}}
\makeatother
\end{document}
share|improve this answer
add comment

Adapting my solution from Micro-graphics inline in text you can use the \foreach from the pgf package to iterate over the list:

enter image description here

\documentclass{article}
\usepackage{tikz}
\usepackage{etoolbox}

\newtoggle{FirstOne}%
\newcommand*{\Menu}[1]{%
   \toggletrue{FirstOne}%
   \foreach \x in {#1} {%
      \iftoggle{FirstOne}{}{${}\rightarrow{}$}%
      \texttt{\x}%
      \global\togglefalse{FirstOne}%
   }%
}%

\begin{document}
    \Menu{File,New,Class} and then more text.
\end{document}
share|improve this answer
    
@marc doesn't tikz load pgf? –  wasteofspace Jan 10 '12 at 8:32
    
As a minor comment, the construct a$\rightarrow$b doesn't look as good as $a \rightarrow b$. Perhaps you could change it to a${}\rightarrow{}$b? –  Marc van Dongen Jan 10 '12 at 8:36
    
@MarcvanDongen: Good suggestion. Have updated the solution. –  Peter Grill Jan 10 '12 at 20:13
add comment

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.