32

I'd like to enclose one entry of an enumerate list in parentheses, with the opening parenthesis appearing before the index number. I can do this manually by using \item[(3.] Item text), but this requires hard-coding the item number. Is there a way to do this automatically?

\documentclass{article}

\begin{document}
\begin{enumerate}
  \item Really important
  \item Quite important
  \item[(3.] If we have time)
\end{enumerate}
\end{document}

In the answer to Modifying labels on some enumerated items, an approach is suggested for modifying the item label, which gets me quite close to the goal. The opening parenthesis is added and the counter is still automatic. I only need to add the closing parenthesis by hand. Could that be automated as well?

\documentclass{article}

\begin{document}
\newcommand{\parenitem}{\stepcounter{enumi}\item[(\theenumi.]}

\begin{enumerate}
  \item Really important
  \item Quite important
  \parenitem If we have time)
\end{enumerate}
\end{document}
3
  • 5
    You may look at this question.
    – egreg
    Sep 6, 2012 at 14:58
  • 2
    This is where ConTeXt's \startitem ... \stopitem approach is better (it's only optional in ConTeXt, but is required for some mechanisms to work).
    – mbork
    Sep 15, 2012 at 11:52
  • Related, yet unanswered question with respect to the "do not want to mark the end of item by hand" aspect.
    – Daniel
    Sep 20, 2012 at 6:55

5 Answers 5

13

Another attempt, counting the open parentheses.

\documentclass{article}
\usepackage{etoolbox}

\makeatletter
\newcounter{item@paren@depth}
\newcommand{\insert@item@paren}{%
\ifnum\value{item@paren@depth}>0
\addtocounter{item@paren@depth}{-1}\unskip) %
\fi%
}
\newcommand{\pitem}{%
\@noitemargtrue \item[\llap{(}\@itemlabel ]%
\stepcounter{item@paren@depth}%
}
\pretocmd{\endenumerate}{\insert@item@paren}{\relax}{\relax}
\pretocmd{\item}{\insert@item@paren}{\relax}{\relax}
\makeatother

\begin{document}

\begin{enumerate}
  \item  Really important
  \item  Quite important
  \pitem If we have time
  \item  Whatever it takes
  \begin{enumerate}
    \pitem maybe
    \item definitely
  \end{enumerate}
  \pitem first
  \pitem second

  \pitem third
\end{enumerate}

\end{document}

The result is the following

enter image description here

As shown in the example, empty lines still cause a deserted parenthesis. Right now I have no idea how to fix this.


EDIT (2012-09-16)

Just had time to look into the TeXbook: the end-of-line character \endlinechar can be set to a negative value to ignore empty lines (or actually line breaks). If one includes this in the \pitem macro, the lonesome paren artefact is fixed:

\newcommand{\pitem}{%
\@noitemargtrue \item[\llap{(}\@itemlabel ]%
\stepcounter{item@paren@depth}%
\ifnum\endlinechar>0\endlinechar=-1\fi
}

enter image description here

The behavior will only be activated when the \pitem macro is used and the effect will be limited to the scope of the enumerate environment. Note that explicit line breaks using \newline or \\ ans explicit paragraphs with \par still work.

22
\documentclass{article}
\def\Item(#1){\item[\llap{(}\refstepcounter{enumi}\theenumi.] #1)}
\begin{document}
\begin{enumerate}
  \item Really important
  \item Quite important
  \Item (If we have time)
\end{enumerate}
\end{document}
3
  • Ah yes, very nice, thank you! I guess it would be quite hard to do this in a way that doesn't require delimiters for the item text?
    – Jake
    Sep 6, 2012 at 15:09
  • yes, that is not really easy. However, you can use \def\Item#1) and use only one )
    – user2478
    Sep 6, 2012 at 15:45
  • 1
    @Herbert A very simple and elegant solution.
    – Sveinung
    Sep 20, 2012 at 6:37
20
+200

Since there is no \tikz answer I thought I felt obligated to provide one:

  1. To keep my reputation for the overkill solution. :-)
  2. But seriously, I interpreted that the goal of this question was to draw attention to a particular item in a list.

Adding a parenthesis is not the only way to highlight an \item in a list, and by using the infamous \tikzmark many other options are possible. Below I have used the term marker to refer to the the elements that are used to draw attention to a list member.

Basic:

To use the technique defined here, all you need to do is to use \SpecialItem instead of the usual \item in the list. This will by default make a call to \DrawParen which adds a parenthesis at the start and end of the list item as shown here:

\begin{enumerate}
    \SpecialItem Default behaviour of \verb|\SpecialItem.|
    \SpecialItem \verb|\SpecialItem| with longer text: 
            Lorem ipsum dolor sit amet, consectetur adipiscing elit
\end{enumerate}

As requested by Jake, there is no need to specify where the end parenthesis is placed. This is determined automatically based on where the text of the \item terminates. So, the code above generates (with the preamble used in the MWE below):

enter image description here

There is a question as to what to do when the text takes up more than one line, as in the second case above. To handle this case, I have defined a starred variant, \DrawParen* which takes into account the height of the lines of text and the parenthesis are re-sized appropriately:

To facilitate the use of different drawing macros, \SpecialItem accepts an optional first parameter to specify the macro that is to be used to do the actual drawing. This defaults to \DrawParen, so to use the starred variant we need to use \SpecialItem[\DrawParen*]. So, the code:

\begin{enumerate}
    \SpecialItem[\DrawParen*] \verb|\SpecialItem[\DrawParen*]| with longer text:        
        Lorem ipsum dolor sit amet, consectetur adipiscing elit
\end{enumerate}

yields:

enter image description here

Now the parenthesis are high enough to enclose the multiple lines and the right one is placed on the right side.

Extended:

The above was the basic usage, but you can define your own drawing macros. Below, I have defined several drawing macros.

  1. \SpecialItem[\DrawAsterix]:

    enter image description here

    Since there is no marker on the right hand side, \DrawAsterix and \DrawAsterix* are identical.

  2. \SpecialItem[\DrawBrace]:

    enter image description here

  3. \SpecialItem[\DrawBracket]:

    Similar to \DrawBrace, but draws a square bracket.

  4. \SpecialItem[\DrawBox]:

    enter image description here

    Note that it does not make sense to use \DrawBox (the un-starred variant) when the text requires multiple lines.

  5. \SpecialItem[\DrawShadedBox]:

    enter image description here

Custom Markers:

If the drawing options defined here are not enough, you can define your own and pass this macro to \SpecialItem. Any custom drawing macro would need to be defined with arg specs {s O{} m m}, where I have used the format from the xparse package. The parameters to this custom drawing macro are:

* starred variant sets the markers at the end of the line on the right
#2 = optional drawing parameter.
     This is actually not used in the code as of yet, at least not fully 
     used for its intended purpose.
#3 = name of `\tikzmark` that defines the location of the start of this `\item`,
#4 = name of `\tikzmark` that defines the location of the end of this `\item`.

So, assuming you want to stick with the xparse package, then \MyCustomDrawMacro would look like:

\NewDocumentCommand{\MyCustomDrawMacro}{s O{} m m}{%
    \begin{tikzpicture}[overlay, remember picture]
        \IfBooleanTF{#1}{%
            ... draw for starred variant ...
        }{%
            ... draw for un-starred variant ...
        }%
    \end{tikzpicture}%
}%

Then to use this you would provide this as the first optional parameter to \SpecialItem:

\SpecialItem[\MyCustomDrawMacro] ...text of item here...

Nested Usage:

Although not all combinations produce good results, it is now possible to have nested usage:

enter image description here

and even further nesting:

enter image description here

It should be noted that for nested usage there needs to be indenting on the right hand side so that the markers don't all overlap. To achieve this I used the enumitem package:

\setlist{before=\setlength{\rightmargin}{\leftmargin}}

Notes:

  • This does require two runs: the first to compute the positions of the drawing, and the second to draw it in the correct spot.

  • Since this is using tikz, you automatically get all the flexibility inherent in tikz, such as line styles, line thickness, line color, fill, etc.

  • Even though I used the the xparse package, this could certainly be done without this additional package if so desired.

  • I have used newtoggle from the etoolbox package as I prefer that syntax versus the \newif syntax. But if you don't want to include an additional package it should be pretty straightforward to adapt this to use \newif or some other conditional methods.

  • It should be noted that in this answer to strange interaction between mdframed and item, egreg mentions that

    Redefining \item can be dangerous and have impredictable results

    which is exactly what I have done here, so perhaps an alternate solution might be needed if this fails under certain circumstances.

References:

Known Issues:

  • Although the nested usage works as shown there is something that is nto getting properly reset after nested usage that affects the non-nested usage. In the MWE below I have commented out the test cases for the nested usage so that it produces useable results. However, if you un-comment the nested usage test cases you will notice that the subsequent usage is really messed up. Will look into this and try to post an update

Further Enhancements:

  • The use of \DrawBox without the * does not make sense for the case where the text is longer than one line. One could automate a test for this and automatically revert to \DrawBox* if the content was longer than one line. This should not be too difficult.

  • The drawing for \DrawParen using bend left can result in a large bracket if the text is over many lines. Perhaps some logic here to limit the amount of bending to some maximum?

  • There is a slight issue when you try to fill the text with a color in that the text is not placed via \tikz so that a low fill opacity needs to be used. To fix this issue, perhaps get \tikz to place the text and hence one could specify text opacity=1.0 so that a darker fill could be used.

  • The left brace is currently to the right of the margin, and the right brace (with the * variant is past the right margin. So perhaps some tweaking here is needed if that is a problem. Need to decide if both the drawing should just be on the margin, of if you want the drawing within the margin, then need to reduce the line width to which the text can flow.

  • Tweaks needed for placement of the markers in nested usage.

  • The current version requires that a new \Draw... macro be defined if you want to change any of the tikz settings. For instance \DrawShadedBox is really the same as \DrawBox[Shaded Box Style]..., but I do not know of a way to pass in optional parameters along with the macro name (but without passing the mandatory parameters as they are only known later).

Caveat:

This section can safely be ignored, and is ONLY relevant in case one tries to compare this to the earlier solution at Box around a few items in an itemize environment. Otherwise, please ignore this section as it will only result in confusion -- it certainly confused me and I wrote the other solution!!

Ok, since you are choosing to read on: The earlier solution accommodated boxing the content with either the label included or not included. In the earlier solution, there is \DrawBox, which does not include the label and \DrawBoxWide which does include the label in the box. In this solution I have decided to not provide the case where the label is not boxed. So, what this all means is that \DrawBox in this earlier solution does not have a corresponding macro here, and that the \DrawBoxWide from the earlier solution corresponds to \DrawBox in this solution.

If this section does not make sense, please ignore it -- it will help me in the future should I need to come back and make sense of these two solutions.

Code:

\documentclass{article}

\usepackage{etoolbox}%    \newtoggle (conditional processing)
\usepackage{letltxmacro}% Duplicate definitions of existing macros
\usepackage{xparse}%      \NewDocumentCommand and \RenewDocumentCommand
\usepackage{xstring}%     \IfEq
\usepackage{enumitem}%
\usepackage{tikz}%
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathreplacing}

%\usepackage{showframe}%

\newcommand{\Text}{%  Dummy text for testing purposes
   Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
   Sed accumsan nulla ac ipsum elementum interdum. 
}%

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}


% -------------------------------------------------- Drawing Settings
\newcommand*{\RightTweak}{0.2em,-0.3em}%
\newcommand*{\LeftTweak}{-\labelwidth,0.9em}%
\newcommand*{\BraceAmplitude}{0.25em}%

% -------------------------------------------------- Drawing Macros

\tikzset{Box Style/.style={draw=red}}%
\NewDocumentCommand{\DrawBox}{%
    s  % *  = box drawn to full line width
    O{}% #2 = optional tikz draw/fill paramaters
    m  % #3 = name of left \tikzmark
    m  % #4 = name of right \tikzmark
    }{%
    %
    \tikz[overlay,remember picture]{%
    \IfBooleanTF{#1}{%
        \coordinate (SWPoint) at ($(#3 |- #4)+(\linewidth,0)$);
    }{%
        \coordinate (SWPoint) at (#4);
    }%
    \draw[Box Style, #2] ($(#3)+(\LeftTweak)$) rectangle ($(SWPoint)+(\RightTweak)$);}
}%

\tikzset{Shaded Box Style/.style={thick, draw=violet, fill=yellow!20, fill opacity=0.1}}%
\NewDocumentCommand{\DrawShadedBox}{%
    s  % *  = box drawn to full line width
    O{}% #2 = optional tikz draw/fill paramaters
    m  % #3 = name of left \tikzmark
    m  % #4 = name of right \tikzmark
    }{%
    %
    % Note that the fill opacity needs to be quite small as this fill
    % is done on top of the text (which was not placed here via tikz.
    \IfBooleanTF{#1}{%
        \DrawBox*[Shaded Box Style, #2]{#3}{#4}%
    }{%
        \DrawBox[Shaded Box Style, #2]{#3}{#4}%
    }%
}%

% To properly place the left brace, paren, bracket, this needs tweaking
\newcommand*{\LeftTweakBrackets}{\labelwidth}%

% This is shared with the bracket/paren drawing macros
\NewDocumentCommand{\ComputeCoordinates}{%
    s%
    O{}% #2 = Unused here -- makes the #3, #4 compatible with macros below
    m%   #3 = name of left \tikzmark
    m%   #4 = name of right \tikzmark
    }{%
    \IfBooleanTF{#1}{%
        \coordinate (NEPoint) at ($(#3.north)+(-\LeftTweakBrackets, 0.5*\baselineskip)$);
        \coordinate (SEPoint) at ($(#3 |- #4)+(-\LeftTweakBrackets,-0.5*\baselineskip)$);
        %
        \coordinate (NWPoint) at ($(#3.north)+(\linewidth, 0.5*\baselineskip)$);
        \coordinate (SWPoint) at ($(#3 |- #4)+(\linewidth,-0.5*\baselineskip)$);
    }{%
        \coordinate (NEPoint) at ($(#3.north)+(-\LeftTweakBrackets, 0.5*\baselineskip)$);
        \coordinate (SEPoint) at ($(#3)      +(-\LeftTweakBrackets,-0.5*\baselineskip)$);
        %
        \coordinate (NWPoint) at ($(#4.north)+(0, 0.5*\baselineskip)$);
        \coordinate (SWPoint) at ($(#4)      +(0,-0.5*\baselineskip)$);
    }%
}%


\tikzset{Brace Style/.style={
    decoration={brace,amplitude=\BraceAmplitude}, decorate, 
    ultra thick, blue
    }%
}%
\NewDocumentCommand{\DrawBrace}{%
    s  % *  = draw to full line width
    O{}% #2 = optional tikz draw/fill paramaters
    m  % #3 = name of left \tikzmark
    m  % #4 = name of right \tikzmark
    }{%
    \begin{tikzpicture}[overlay, remember picture]
        \IfBooleanTF{#1}{%
            \ComputeCoordinates*{#3}{#4}%
        }{%
            \ComputeCoordinates{#3}{#4}%
        }%

        \draw [Brace Style, #2] (SEPoint) -- (NEPoint);
        \draw [Brace Style, #2] (NWPoint) -- (SWPoint);
    \end{tikzpicture}%
}%


% https://tex.stackexchange.com/questions/55068/is-there-a-tikz-equivalent-to-the-pstricks-ncbar-command
\tikzset{
    ncbar/.style={% easy way to get sqaure brackets
        to path=(\tikztostart)
        -- ($(\tikztostart)!#1!90:(\tikztotarget)$)
        -- ($(\tikztotarget)!#1!-90:(\tikztostart)$)
        -- (\tikztotarget)
    },
    ncbar/.default=0.5cm
}

\tikzset{Bracket Style/.style={ultra thick, brown}}%
\NewDocumentCommand{\DrawBracket}{s O{} m m}{%
    \begin{tikzpicture}[overlay, remember picture]
        \IfBooleanTF{#1}{%
            \ComputeCoordinates*{#3}{#4}%
        }{%
            \ComputeCoordinates{#3}{#4}%
        }%

        \draw [Bracket Style, #2] (SEPoint) to [ncbar=\BraceAmplitude] (NEPoint);
        \draw [Bracket Style, #2] (NWPoint) to [ncbar=\BraceAmplitude] (SWPoint);
    \end{tikzpicture}%
}%

\tikzset{Paren Style/.style={ultra thick, red}}%
\NewDocumentCommand{\DrawParen}{s O{} m m}{%
    \begin{tikzpicture}[overlay, remember picture]
        \IfBooleanTF{#1}{%
            \ComputeCoordinates*{#3}{#4}%
        }{%
            \ComputeCoordinates{#3}{#4}%
        }%

        \draw [Paren Style, #2] (SEPoint) to [bend left] (NEPoint);
        \draw [Paren Style, #2] (NWPoint) to [bend left] (SWPoint);
    \end{tikzpicture}%
}%

\tikzset{Asterix Style/.style={text=red}}%
\NewDocumentCommand{\DrawAsterix}{s O{} m m}{%
    \begin{tikzpicture}[overlay, remember picture]
        \IfBooleanTF{#1}{%
            \ComputeCoordinates*{#3}{#4}%
        }{%
            \ComputeCoordinates{#3}{#4}%
        }%

        \node [Asterix Style, #2] at ($(SEPoint)!0.5!(NEPoint)$) {\Huge$\ast$};
    \end{tikzpicture}%
}%

% -------------------------------------------------- Non-Drawing Macros

% This toggle is set when we are within a "\SpecialItem" so that we
% can do the appropriate drawing when we get to the end of this item.
% To allow for nesting we need one of these for each nesting depth
% So, to allow for more levels of nesting declare more of these.
\newtoggle{InSpecialItem1}\togglefalse{InSpecialItem1}%
\newtoggle{InSpecialItem2}\togglefalse{InSpecialItem2}%
\newtoggle{InSpecialItem3}\togglefalse{InSpecialItem3}%
\newtoggle{InSpecialItem4}\togglefalse{InSpecialItem4}%

% To allow for nesting we need to use different names for the tikzmarks,
% and the toggles (defined above).  So we use the vallue of this counter
% to name those. This counted is incremented at the \begin{enumerate} and
% decremented at \end{enumerate} 
\newcounter{EnumerateDepth}% 

\makeatletter
% https://tex.stackexchange.com/questions/20655/how-to-undo-a-def-i-e-need-a-undef-capability
\newcommand*\ResetToUndefined[1]{\expandafter\gdef\csname#1\endcsname{\@undefined}}%
\makeatother

\newcommand*{\EndTikzMarkAndDrawIfNeeded}{%
    \iftoggle{InSpecialItem\arabic{EnumerateDepth}}{%
        % We have reached the end of a \SpecialItem, which could be
        % either due to a subsequent \item, a subsequent \SpecialItem,
        % to an end{enumerate}.  
        \global\togglefalse{InSpecialItem\arabic{EnumerateDepth}}%
        \ifcsname MarkEnd\Alph{EnumerateDepth}\endcsname%
            % The location of the end \tikzmark was already marked, 
            % which would be the case if we were coming out of a nested 
            % \end{enumerate}).
            %
            % We need to clear this defintion so that it can be used
            % again if needed:
            \ResetToUndefined{MarkEnd\Alph{EnumerateDepth}}%
        \else%
            % The location of the end \tikzmark was not already marked 
            % Hence, we need to mark this current point as the end 
            % \tikzmark location.
            \tikzmark{MarkEnd\Alph{EnumerateDepth}}%
        \fi%
        % -----------------------------------------------------------
        % Draw whatever was specified to be drawn by \SpecialItem
        % and draw whatever was specified to be drawn by \SpecialItem       
        \SpecialItemStyle[thick]%
            {MarkStart\Alph{EnumerateDepth}}%
            {MarkEnd\Alph{EnumerateDepth}}%
    }{}%
}%

% To be able to handle nested use of \SpecialItem we need to know
% what enumerate depth we are at, so we increment that counter at
% every \begin{enumerate}.  Hence first level has count=1.
\LetLtxMacro\OriginalEnumerate{\enumerate}%
\renewcommand*{\enumerate}{%
    \addtocounter{EnumerateDepth}{1}% Increase enumerate nesting depth
    \OriginalEnumerate%
}%

% Special Case: If we are ending a nested enumerarte, but the last item
% in the parent list is a SpecialItem we need to close those as well.
\newcounter{NestingDepthCounter}
\newcommand*{\EndAnyParentTikzMarks}{%
    \edef\NestingDepth{\arabic{EnumerateDepth}}%
    \IfStrEq{\NestingDepth}{0}{}{%
        \foreach \x in {1,...,\NestingDepth} {%
            \setcounter{NestingDepthCounter}{\x}%
            \iftoggle{InSpecialItem\arabic{NestingDepthCounter}}{%
                % Note that we do NOT togglefalse{InSpecialItem\x} here as 
                % the drawing needs to be done we come out of this enumerate 
                % so that the line widths are correct, and that the correct
                % drawing macro is used for that enumerated depth.
                %% \global\togglefalse{InSpecialItem\x}%  No!! Not for this special case!
                \ifcsname MarkEnd\Alph{EnumerateDepth}\endcsname%
                    % The location of the end \tikzmark was already marked, 
                    % which would be the case if we were coming out of a nested 
                    % \end{enumerate}).  So don't mark it again.
                \else%
                    \tikzmark{MarkEnd\Alph{NestingDepthCounter}}%
                    %
                    % So that we know that we have already marked an end for this 
                    % \tikzmark and don't overwrite the current location.
                    % If there is a way to check if a \tikzmark is already defined
                    % then this \gdef here could be elimianted.
                    \expandafter\gdef\csname MarkEnd\Alph{NestingDepthCounter}\endcsname{}%
                \fi%
            }{}%
        }%
    }%
}%

% If last \item was a special \tikzmark, then at the end of
% enumerate we need to add the other end of the \tikzmark,
% and do the appropriate drawing.
\let\OriginalEndEnumerate\endenumerate%
\renewcommand*{\endenumerate}{%
    \EndTikzMarkAndDrawIfNeeded%
    %
    \EndAnyParentTikzMarks%
    \addtocounter{EnumerateDepth}{-1}% Decrease enumerate nesting depth
    %
    \OriginalEndEnumerate% end the enumerate
}%

% If previous \item was a special \tikzmark, then at the
% subsequent \item we need to add the other end of the 
% \tikzmark, and do the appropriate drawing
\LetLtxMacro\OriginalItem{\item}%
\RenewDocumentCommand{\item}{o}{%
    \EndTikzMarkAndDrawIfNeeded%
    \IfNoValueTF{#1}{%
        \OriginalItem% start the usual item
    }{%
        \OriginalItem[#1]% start the usual item with given label
    }%
}%

\NewDocumentCommand{\SpecialItemStyle}{O{} m m}{}%
\NewDocumentCommand{\SpecialItem}{%
    O{\DrawParen}% #1 = highlighting type
    o%   #2 = optional paramater to \item
    }{%
    \EndTikzMarkAndDrawIfNeeded% In case previous item was also a \SpecialItem
    % --------------------------------------------------
    % Redefine how this particular special item is to be marked when it ends.
    \RenewDocumentCommand{\SpecialItemStyle}{O{} m m}{#1[##1]{##2}{##3}}%
    % --------------------------------------------------
    \global\toggletrue{InSpecialItem\arabic{EnumerateDepth}}%
    \IfNoValueTF{#2}{%
        \OriginalItem% start a special item
    }{%
        \OriginalItem[#2]% start a special item with given label
    }%
    \tikzmark{MarkStart\Alph{EnumerateDepth}}%
    \ignorespaces% As per https://tex.stackexchange.com/questions/73434
}%

\setlist{before=\setlength{\rightmargin}{\leftmargin}}
\begin{document}
\begin{enumerate}
    \item Normal Item
    \item[A.] Normal Item with custon label [A.]
    \SpecialItem \verb|\DrawParen|
    \SpecialItem \verb|\DrawParen| \Text
    \SpecialItem[\DrawParen*] \verb|\DrawParen*| 
    \SpecialItem[\DrawParen*] \verb|\DrawParen*| \Text
    \SpecialItem[\DrawAsterix] \verb|\DrawAsterix|
    \SpecialItem[\DrawBrace] \verb|DrawBrace|
    \SpecialItem[\DrawBrace*] \verb|DrawBrace*|
    \item A normal item in between special items
    \SpecialItem[\DrawBrace] DrawBrace with text: \Text
    \SpecialItem[\DrawBrace*] DrawBrace* with text:  \Text
    \SpecialItem[\DrawBracket] DrawBracket with text: \Text
    \SpecialItem[\DrawBracket*] DrawBracket* with text:  \Text
    \SpecialItem[\DrawBox] DrawBox Item
    \SpecialItem[\DrawBox*] DrawBox*
    \SpecialItem[\DrawBox]  DrawBox with text - Does not make sense.
    \SpecialItem[\DrawBox*] DrawBox with text:  \Text
    \SpecialItem[\DrawShadedBox][B.] DrawShaded box with custom label [B.]
    \SpecialItem[\DrawShadedBox*] DrawShaded box with text:  \Text
\end{enumerate}

%\newpage
%Check nesting:
%\begin{enumerate}
%   \SpecialItem[\DrawBrace] \verb|\DrawBrace| of parent with nested list
%   \begin{enumerate}
%       \SpecialItem[\DrawBracket] \verb|\DrawBracket| nested in above list
%   \end{enumerate}
%   %
%   \SpecialItem[\DrawBrace*] \verb|\DrawBrace*| of parent with nested list: \Text
%   \begin{enumerate}
%       \SpecialItem[\DrawBracket*] \verb|\DrawBracket*| nested in above list: \Text
%   \end{enumerate}
%   %
%   \SpecialItem[\DrawBracket*] \verb|\DrawBracket*| of parent with nested list
%   \begin{enumerate}
%       \SpecialItem[\DrawBrace*] \verb|\DrawBrace*| nested in above list
%       \begin{enumerate}
%           \SpecialItem[\DrawBox*] \verb|\DrawBox*| nested in above list
%           \begin{enumerate}
%               \SpecialItem[\DrawParen] \verb|\DrawParen| nested in above list \Text
%               \item Regular item
%           \end{enumerate}
%       \end{enumerate}
%   \end{enumerate}
%\end{enumerate}

\newpage
Test cases given in description:

\begin{enumerate}
    \SpecialItem Default behaviour of \verb|\SpecialItem.|
    \SpecialItem \verb|\SpecialItem| with longer text: 
            Lorem ipsum dolor sit amet, consectetur adipiscing elit
\end{enumerate}


\begin{enumerate}
    \SpecialItem[\DrawParen*] \verb|\SpecialItem[\DrawParen*]| with longer text:        
        Lorem ipsum dolor sit amet, consectetur adipiscing elit
\end{enumerate}


\begin{enumerate}
    \SpecialItem[\DrawAsterix] \verb|\SpecialItem[\DrawAsterix]| with longer text:        
        Lorem ipsum dolor sit amet, consectetur adipiscing elit
\end{enumerate}

\begin{enumerate}
    \SpecialItem[\DrawBrace] \verb|\SpecialItem[\DrawBrace]| with short text.
    \SpecialItem[\DrawBrace] \verb|\SpecialItem[\DrawBrace]| with longer text:        
        Lorem ipsum dolor sit amet, consectetur adipiscing elit
    \SpecialItem[\DrawBrace*] \verb|\SpecialItem[\DrawBrace*]| with longer text:        
        Lorem ipsum dolor sit amet, consectetur adipiscing elit
\end{enumerate}

\begin{enumerate}
    \SpecialItem[\DrawBox] \verb|\SpecialItem[\DrawBox]| with short text.
    \SpecialItem[\DrawBox*] \verb|\SpecialItem[\DrawBox*]| with longer text:        
        Lorem ipsum dolor sit amet, consectetur adipiscing elit
\end{enumerate}


\begin{enumerate}
    \SpecialItem[\DrawShadedBox] \verb|\SpecialItem[\DrawShadedBox]| with short text.
    \SpecialItem[\DrawShadedBox*] \verb|\SpecialItem[\DrawShadedBox*]| with longer text:        
        Lorem ipsum dolor sit amet, consectetur adipiscing elit
\end{enumerate}
\end{document}
8
  • I would love to use this with beamer, but looking at the redefinitions of item and the list environments, I have a feeling that it would not work. (Can't check at the moment – no LaTeX for the iPad...)
    – Daniel
    Sep 20, 2012 at 5:21
  • @Daniel: Probably requires someone more knowledgeable than me to redefine those macros properly. Alternatively, could define a new macro Item and use that instead of \item, similar to what @Herbert did. Sep 20, 2012 at 5:52
  • Now this goes into CTAN, right?
    – percusse
    Sep 20, 2012 at 6:40
  • +1 for overkill... Although if this solution does not allow a \SpecialItem into an enumerate into a \SpecialItem! Sep 20, 2012 at 6:48
  • 6
    @percusse: Yep, it's \usepackage{overkill}. :-) Sep 20, 2012 at 7:01
10

Here is an attempt. The following code defines a \pitem that encloses everything until the next occurence of \item, \pitem or \end (whatever comes first) with parentheses. It uses egreg's definition of \sitem in his answer to “Modifying labels on some enumerated items”.

\documentclass{article}
\makeatletter
\long\def\ifinstring#1#2#3#4{%
  \long\def\instr@tmpa##1#2{}%
  \expandafter\if\expandafter\relax\expandafter\detokenize\expandafter{\instr@tmpa#1{}{}#2}\relax%
    \expandafter\@secondoftwo
  \else
    \expandafter\@firstoftwo
  \fi
  {#3}{#4}%
}

% this is \sitem from https://tex.stackexchange.com/a/52718/5049
\def\@pitem{%
  \expandafter\let\expandafter\originallabel\csname labelenum\romannumeral\@enumdepth\endcsname
  \expandafter\def\csname labelenum\romannumeral\@enumdepth\expandafter\endcsname\expandafter{%
    \expandafter(\originallabel}%
  \item
  \expandafter\let\csname labelenum\romannumeral\@enumdepth\endcsname\originallabel
}

\long\def\pitem#1\end{%
  \ifinstring{#1}{\item}
    {\pitem@i#1\end}
    {\pitem@ii#1\end}}

\long\def\pitem@i#1\item{%
  \ifinstring{#1}{\pitem}
    {\pitem@iii#1\item}
    {\@pitem #1\unskip)\item}}
\long\def\pitem@ii#1\end{%
  \ifinstring{#1}{\pitem}
    {\pitem@iii#1\end}
    {\@pitem #1\unskip)\end}}
\long\def\pitem@iii#1\pitem{%
  \@pitem #1\unskip)\pitem}
\makeatother

\begin{document}

\begin{enumerate}
  \item Really important
  \item Quite important
  \pitem If we have time
  \pitem If we have time
  \item Really important
  \begin{enumerate}
    \item Really important
    \item Quite important
    \pitem If we have time\par or change our mind
    \item Really important
    \item Quite important
    \pitem If we have time
  \end{enumerate}
  \item Quite important
  \pitem If we have time
\end{enumerate}

\end{document}

enter image description here

2
  • This has the same problem with blank lines between \item's that @egreg pointed out in my approach.
    – StrongBad
    Sep 14, 2012 at 14:06
  • Yes, of course. But a blank line in a \pitem starts a new paragraph which naturally is also enclosed and thus places the closing parenthesis on the line below. Solution: don't end a \pitem with an empty line or comment the blank line if you want the visual separation of your items in the source.
    – cgnieder
    Sep 14, 2012 at 14:13
6

I define two new macros \pitem and \@pitem and modify \@item. The \pitem macro is the same as \item, except it uses \@pitem. The \@pitem macro is the same as the modified \@item, except it sets a boolean to be true while the modified \@item sets the boolean to be false. I modify the enumerate environment to add a closing parenthesis if needed.

Blank line are allowed, although I am a little hesitant about the redefinition of \par to \relax if the next token is \end. I have no idea what \@endparenv does so I am ot happy that I just delete it, but it seems to work

\documentclass{article}
\usepackage{lipsum}
\usepackage{etoolbox}
\newbool{@pitem}

\makeatletter
\def\pitem{\@inmatherr\pitem\@ifnextchar[\@pitem{\@noitemargtrue \@pitem[(\@itemlabel]}}
\let\@pitem\@item
\pretocmd{\@item}{\ifbool{@pitem}{\unskip)}{}\boolfalse{@pitem}}{}{}
\pretocmd{\@pitem}{\ifbool{@pitem}{\unskip)}{}\booltrue{@pitem}}{}{}

\BeforeBeginEnvironment{enumerate}{%
  \def\@endparenv{}
  \let\item@par\par
  \def\par{\@ifnextchar\item{\relax}{\@ifnextchar\pitem{\relax}{\@ifnextchar\par{\relax}{\@ifnextchar\end{\relax}{\item@par}}}}}
}
\AtEndEnvironment{enumerate}{\ifbool{@pitem}{\unskip)}{}\boolfalse{@pitem}}

\begin{document}
  \begin{enumerate}
    \item  Really important
    \item  Quite important
    \pitem If we have time
    \item  Whatever it takes

    \begin{enumerate}
      \pitem maybe
      \item definitely
    \end{enumerate}
    \pitem first
    \pitem second





    \pitem third


  \end{enumerate}
\lipsum[1-3]
\end{document}

enter image description here

5
  • You can't have two consecutive \pitem and no blank line is allowed before \pitem or \item.
    – egreg
    Sep 14, 2012 at 13:45
  • @egreg thanks I had planned on testing consecutive \pitem's, but forgot. The blank line is a problem for my approach.
    – StrongBad
    Sep 14, 2012 at 14:03
  • This approach does not accept nested \pitem. Sep 15, 2012 at 13:29
  • @PaulGaborit what is a nested \pitem?
    – StrongBad
    Sep 15, 2012 at 13:41
  • @DanielE.Shub a "nested \pitem" is a \pitem into an enumerate into a \pitem... Sep 15, 2012 at 14:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .