0

I would like to create a new environment to create small tables to use in a cheatsheet.

I want it to look pretty much like this enter image description here

and would like to invoke it with something like:

\begin{commandtable}

\name{apt-get}{option}{name}
\description{Here should be a brief function description.}
\option{install}{Brief description}
\option{update}{Brief description}
\option{remove}{Brief description}
\example{apt-get install newpackage}
\example{apt-get install anotherpackage}

\end{commandtable}

My guess is that I would have to define a new environment with its own macros, but I don't really know how to get all of this in a table format or even where to start. Can someone advise me as to which building blocks I need here?

EDIT: More specifically the cells should have the following properties:

Header:

  • is always one line
  • should contain the name and a variable number of items in <> brackets
  • should be of the colors as in the image

Description:

  • starts with "Description:"
  • The description should be allowed to go over two lines

Options:

  • starts with "Options:"
  • followed by a variable number of options with descriptions
  • if possible, these descriptions should also be able to go over multiple lines
  • if possible, there should be an option for coloring a an option (maybe even automatically color every 2nd)

Examples:

  • shows a variable number of examples
  • examples are one line each
3
  • 1
    Welcome to TeX.SX! Could you please edit your question to inlcude more information on the desired output? For example: How flexible does the solution have to be? How long are the descirptions (Do the need automatic linebreaks)? How wide should the table be? Are there always only three description items or can there be more or less? How important is the alternating coloring of these rows?
    – leandriis
    Jun 22, 2019 at 12:06
  • Maybe a small minimal working example with bibliography (MWEB) that shows ho one would typeset the table without the new environment would also help. For some general information on how o define your own commands, you can have a look here: tex.stackexchange.com/a/172511/134144
    – leandriis
    Jun 22, 2019 at 12:07
  • 1
    tcolorbox documentation might be a good starting point
    – gigi
    Jun 22, 2019 at 12:23

4 Answers 4

2

Here is a possible solution that fulfills parts of your requirements. What is not (yet) covered are: variable number of items in <> brackets in the header line and automatically alternating ccolors for the options.

enter image description here

\documentclass{article}
\usepackage{array}
\usepackage{ragged2e}
\usepackage[table,dvipsnames]{xcolor}
\usepackage{calc}

\newenvironment{commandtable}{\begin{tabular}{|@{\quad\quad}p{3cm}p{6cm}|}\hline}{\hline
\end{tabular}
}

\newcommand{\tabname}[3]{\multicolumn{2}{|>{\centering\arraybackslash}p{10cm}|}{\cellcolor{blue}\textcolor{white}{\textbf{#1 \textless #2\textgreater~\textless #3\textgreater}}} \\
\hline}

\newcommand{\tabstartdescription}{\hline \multicolumn{2}{|@{}p{10cm}|}{\textbf{Description:}}  \\}
\newcommand{\tabdescription}[1]{\multicolumn{2}{|@{\quad\quad}p{10cm-\widthof{2\quad}}|}{#1} \\
\hline}

\newcommand{\tabstartoption}{\hline \multicolumn{2}{|@{}p{10cm}|}{\textbf{Options:}}  \\}

\newcommand{\taboption}[2]{#1 & #2\\}

\newcommand{\tabstartexample}{\hline
\multicolumn{2}{|@{}p{10cm}|}{\textbf{Example:}}  \\}
\newcommand{\tabexample}[1]{\multicolumn{2}{|@{\quad\quad}p{10cm-\widthof{2\quad}}|}{\textit{#1}}\\}

\begin{document}

\begin{commandtable}
\tabname{apt-get}{option}{name}
\tabstartdescription
\tabdescription{Here should be a brief function description.}
\tabstartoption
\taboption{install}{brief description}
\taboption{update}{brief description}
\taboption{remove}{brief description}
\tabstartexample
\tabexample{apt-get install new package}
\tabexample{apt-get install another package}
\end{commandtable}

\end{document}

UPDATE:

The following code allows for coloring the background of the option rows using an optional argument. The default color is white:

enter image description here

\documentclass{article}
\usepackage{array}
\usepackage{ragged2e}
\usepackage[table]{xcolor}
\usepackage{calc}

\definecolor{myblue}{RGB}{42, 96, 153}

\newenvironment{commandtable}{\setlength{\tabcolsep}{\widthof{\quad\quad}}\begin{tabular}{|p{3cm-2\tabcolsep}p{7cm-2\tabcolsep}|}\hline}{\hline
\end{tabular}
}

\newcommand{\tabname}[3]{\multicolumn{2}{|>{\centering\arraybackslash}p{10cm-2\tabcolsep}|}{\cellcolor{myblue}\textcolor{white}{\textbf{#1 \textless #2\textgreater~\textless #3\textgreater}}} \\
\hline}

\newcommand{\tabstartdescription}{\hline \multicolumn{2}{|@{}p{10cm-2\tabcolsep}|}{\textbf{Description:}}  \\}
\newcommand{\tabdescription}[1]{\multicolumn{2}{|p{10cm-2\tabcolsep}|}{#1} \\
\hline}

\newcommand{\tabstartoption}{\hline \multicolumn{2}{|@{}p{10cm-2\tabcolsep}|}{\textbf{Options:}}  \\}

\newcommand{\taboption}[3][white]{\cellcolor{#1}#2 & \cellcolor{#1}#3\\}

\newcommand{\tabstartexample}{\hline
\multicolumn{2}{|@{}p{10cm-2\tabcolsep}|}{\textbf{Example:}}  \\}
\newcommand{\tabexample}[1]{\multicolumn{2}{|p{10cm-2\tabcolsep}|}{\textit{#1}}\\}

\begin{document}

\begin{commandtable}
\tabname{apt-get}{option}{name}
\tabstartdescription
\tabdescription{Here should be a brief function description.}
\tabstartoption
\taboption[myblue!20]{install}{brief description}
\taboption{update}{brief description}
\taboption[myblue!20]{remove}{brief description}
\tabstartexample
\tabexample{apt-get install new package}
\tabexample{apt-get install another package}
\end{commandtable}

\end{document}
3

Here is a tikz approach and is a variation of something I put together in quite a different context. It is relatively simple, easily modified and with a reasonably efficient input format. The two samples show a simple keyval implementation.

\documentclass{article}

\usepackage{graphicx}
\usepackage[table]{xcolor}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{xparse}
\usepackage{tabularx}
\usepackage{keyval}

\usetikzlibrary{shapes.multipart}

\newsavebox{\subcomm}
\newsavebox{\xmpls}
\newlength{\boxwidth}

%% Change defaults here:
\setlength{\boxwidth}{4in}
\def\boxcolor{blue}

\makeatletter
\define@key{cheat}{boxwidth}{\setlength{\boxwidth}{#1}}
\define@key{cheat}{boxcolor}{\def\boxcolor{#1}}
\makeatother

%% egreg: https://tex.stackexchange.com/questions/487572/obeylines-and-gappto-from-etoolbox
\begingroup
    \lccode`~=`\^^M
    \lowercase{%
\endgroup
    \def\sep#1;#2~{%
        \xappto{\tabbody}{% Collect rows of tabular[x] in \tabbody
            \unexpanded{#1&#2\\}
        }~
    }%
}

\NewDocumentEnvironment{cheatsheet}{sO{}mmm}{%
    \gdef\tabbody{}%
    \setkeys{cheat}{#2}%
}{%
        \end{minipage}%
    \end{lrbox}%
    \noindent
    \tikz{%
    \node[name=Z,draw=\boxcolor,very thick,rounded corners=3pt, inner xsep=6pt,
        rectangle split,rectangle split part fill={\boxcolor,white},
        rectangle split draw splits=false,rectangle split part align={left}]
        {%
            \nodepart{one}\mbox{\strut\bfseries\color{white}\texttt{#3}\quad<#4>\quad<#5>}%
            \nodepart{two}
                \begin{minipage}{\boxwidth}
                \textbf{Description}%
                \par
                \smallskip
                \tmpdesc
                \end{minipage}
            \nodepart{three}\usebox{\subcomm}
            \nodepart{four}\usebox{\xmpls}
        };%
    \draw[\boxcolor,thick] (Z.two split west)--(Z.two split east)
        (Z.three split west)--(Z.three split east) ;%
    }%
}

\NewDocumentCommand{\mydesc}{m}{%
    \def\tmpdesc{#1}%
}

\NewDocumentCommand{\mysubcomm}{}{%
    \begingroup
        \offinterlineskip %% <<<---
        \obeylines
        \everypar={\sep}
}

\NewDocumentCommand{\myxmpls}{}{%
    \endgroup
    \begin{lrbox}{\subcomm}%
        \begin{minipage}{\boxwidth}%
            \textbf{Subcommands}\par\smallskip
            \rowcolors{1}{}{\boxcolor!20}
            \begin{tabularx}{\linewidth}{@{\qquad}lX}%% 
                \tabbody
            \end{tabularx}%
        \end{minipage}%
    \end{lrbox}%
    \begin{lrbox}{\xmpls}%
        \begin{minipage}{\boxwidth}%
        \textbf{Examples}\par\smallskip
        \slshape
        \obeylines
}

\begin{document}

\begin{cheatsheet}[]{apt-get}{subcommand}{name}
\mydesc{Here should be a brief description.}
\mysubcomm %% semicolon separates subcommand from description. Uses \obeylines
    install; Brief description lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    update; Brief description again.
    remove; Brief description yet again.
\myxmpls %% Uses \obeylines.
    apt-get install newpackage
    apt-get install anotherpackage
\end{cheatsheet}

\begin{cheatsheet}[boxcolor=red,boxwidth=3.75in]{apt-get}{subcommand}{name}
\mydesc{Here should be a brief description.}
\mysubcomm %% semicolon separates subcommand from description. Uses \obeylines
    install; Brief description lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    update; Brief description again.
    remove; Brief description yet again.
\myxmpls %% Uses \obeylines.
    apt-get install newpackage
    apt-get install anotherpackage
\end{cheatsheet}

\end{document}

Update

I added a \strut to the \mbox in \nodepart{one} to ensure its consistent size.

TikZ solution.

2

Implementation wrote independently of leandriis' answer (I noticed his answer after I wrote mine). Every text inside of commandtable that is not in the arguments of \name, \description, \option, or \example isn't printed (\nullfont). The input macros are redefined inside a very narrow scope, namely only during the input in commandtable, their definitions are restored during the output, therefore you can use macros with the same name as arguments of those macros, e.g. if you need to use a description environment inside any argument that should be possible.

For the list elements of the second argument of \name surrounding spaces are stripped.

\documentclass[]{article}

\usepackage[]{longtable}
\usepackage[table]{xcolor}
\usepackage{array}

\makeatletter
\definecolor{cmdblue}{HTML}{2a6099}
\newcommand\cmdtbl@error[2]%>>=
  {%
    \GenericError{(commandtable)}{commandtable Error: #1}{#2}{}%
  }%=<<
\newcommand\cmdtbl@smuggle[1]%>>=
  {%
    \edef\cmdtbl@smuggled{\unexpanded\expandafter{\cmdtbl@smuggled#1}}%
  }%=<<
\newif\if@cmdtbl@long
\newlength\cmdtbl@width
\newlength\cmdtbl@fullwidth
\long\def\cmdtbl@fiBTb\fi#1#2#3{\fi#2}
\begingroup
\xdef\q@stop
  {\expandafter\noexpand\csname Error: \detokenize{\q@stop}expanded\endcsname}
\endgroup
\newcommand\cmdtbl@smugglemacro[3]%>>=
  {%
    \ifnum#2=0
      \cmdtbl@fiBTb
    \fi
    \@secondoftwo
    {\def#1}%
    {%
      \def\cmdtbl@smugglemacro@args##1#2##2\relax{##1#2}%
      \long\expandafter\def\expandafter#1%
      \cmdtbl@smugglemacro@args##1##2##3##4##5##6##7##8##9\relax
    }%
    {\cmdtbl@smuggle{#3}\ignorespaces}%
  }%=<<
\newcommand\cmdtbl@ifempty[1]%>>=
  {%
    \if\relax\detokenize{#1}\relax
      \cmdtbl@fiBTb
    \fi
    \@secondoftwo
  }%=<<
\newcommand\cmdtbl@ifblank[1]%>>=
  {%
    \if\relax\detokenize\expandafter{\@gobble#1.}\relax
      \cmdtbl@fiBTb
    \fi
    \@secondoftwo
  }%=<<
\newcommand\cmdtbl@stupidtrim[1]%>>=
  {%
    \cmdtbl@stupidtrim@a{}#1 \q@stop
  }%=<<
\long\def\cmdtbl@stupidtrim@a#1#2 #3\q@stop%>>=
  {%
    \cmdtbl@ifempty{#2} % there was a space at the beginning
      {\cmdtbl@stupidtrim@a{#1}#3\q@stop}
      {%
        \cmdtbl@ifblank{#3} % space only at the end
          {\unexpanded{#1#2}}
          {\cmdtbl@stupidtrim@a{#1#2 }#3\q@stop}%
      }%
  }%=<<
\newcommand\cmdtbl@name[2]%>>=
  {%
    \ifx\cmdtbl@name@\@empty
      \def\cmdtbl@name@{#1}%
      \cmdtbl@ifempty{#2}{}
        {%
          \@for\cmdtbl@tmp:={#2}\do
            {%
              % trim the spaces
              \edef\cmdtbl@tmp
                {\expandafter\cmdtbl@stupidtrim\expandafter{\cmdtbl@tmp}}%
              \edef\cmdtbl@name@
                {%
                  \unexpanded\expandafter{\cmdtbl@name@} % space is intended
                  \noexpand\cmdtbl@arg
                  {\unexpanded\expandafter{\cmdtbl@tmp}}%
                }%
            }%
        }%
    \else
      \cmdtbl@error{Name used twice}{}%
    \fi
  }%=<<
\newcommand\cmdtbl@desc[1]%>>=
  {%
    \ifx\cmdtbl@desc@\@empty
      \def\cmdtbl@desc@{#1}%
    \else
      \cmdtbl@error{Description used twice}{}%
    \fi
  }%=<<
\newcommand\cmdtbl@opt[2]%>>=
  {%
    \ifx\cmdtbl@opt@color\@empty
      \def\cmdtbl@opt@color{\rowcolor{cmdblue!15}}%
    \else
      \let\cmdtbl@opt@color\@empty
    \fi
    \edef\cmdtbl@opt@
      {%
        \unexpanded\expandafter{\cmdtbl@opt@}%
        \unexpanded\expandafter{\cmdtbl@opt@color #1&#2\\}%
      }%
  }%=<<
\newcommand\cmdtbl@ex[1]%>>=
  {%
    \edef\cmdtbl@ex@
      {%
        \unexpanded\expandafter
          {%
            \cmdtbl@ex@
            \multicolumn{2}{|@{\hskip4\tabcolsep}>{\let\\\newline}p{\cmdtbl@fullwidth}|}{\itshape#1}%
            \\
          }%
      }%
  }%=<<
\newcommand*\cmdtbl@place@sec[1]%>>=
  {%
    \multicolumn{2}
      {%
        |@{\hskip.5\tabcolsep}
        p{\dimexpr\cmdtbl@fullwidth+3\tabcolsep}
        @{\hskip.5\tabcolsep}|
      }
      {\textbf{#1:}}%
  }%=<<
\newcommand*\cmdtbl@place@name%>>=
  {%
    \rowcolor{cmdblue}%
    \multicolumn{2}{|>{\centering}p{\dimexpr\cmdtbl@fullwidth+3\tabcolsep}|}
      {\textcolor{white}{\textbf{\cmdtbl@name@}}}%
  }%=<<
\newcommand*\cmdtbl@place@desc%>>=
  {%
    \ifx\cmdtbl@desc@\@empty
    \else
      \cmdtbl@place@sec{Description}\\
      \multicolumn{2}{|@{\hskip4\tabcolsep}>{\let\\\newline}p{\cmdtbl@fullwidth}|}{\cmdtbl@desc@}\\
      \hline
    \fi
  }%=<<
\newcommand*\cmdtbl@place@opt%>>=
  {%
    \ifx\cmdtbl@opt@\@empty
    \else
      \cmdtbl@place@sec{Options}\\
      \cmdtbl@opt@
      \hline
    \fi
  }%=<<
\newcommand*\cmdtbl@place@ex%>>=
  {%
    \ifx\cmdtbl@ex@\@empty
    \else
      \cmdtbl@place@sec{Example}\\
      \cmdtbl@ex@
      \hline
    \fi
  }%=<<
\newcommand*\cmdtbl@arg[1]%>>=
  {%
    \texttt{<}\textit{#1}\texttt{>}%
  }%=<<
\newenvironment{commandtable}[1][\linewidth]
  {% begin >>=
    \let\cmdtbl@name@\@empty
    \let\cmdtbl@name@args\@empty
    \let\cmdtbl@desc@\@empty
    \let\cmdtbl@opt@\@empty
    \let\cmdtbl@opt@color\@empty
    \let\cmdtbl@ex@\@empty
    \@cmdtbl@longfalse
    \setlength\cmdtbl@fullwidth{#1}%
    \advance\cmdtbl@fullwidth -2\arrayrulewidth
    \cmdtbl@width\cmdtbl@fullwidth%
    \advance\cmdtbl@fullwidth -5\tabcolsep
    \advance\cmdtbl@width -8\tabcolsep
    \divide\cmdtbl@width by 2
    \def\arraystretch{1.2}%
    \begingroup
    \nullfont
    \let\cmdtbl@smuggled\@empty
    \cmdtbl@smugglemacro\name2{\cmdtbl@name{##1}{##2}}%
    \cmdtbl@smugglemacro\description1{\cmdtbl@desc{##1}}%
    \cmdtbl@smugglemacro\option2{\cmdtbl@opt{##1}{##2}}%
    \cmdtbl@smugglemacro\example1{\cmdtbl@ex{##1}}%
    \@ifstar{\cmdtbl@smuggle{\@cmdtbl@longtrue}\ignorespaces}\ignorespaces
  }%=<<
  {% end >>=
    \expandafter
    \endgroup
    \cmdtbl@smuggled
    \ifx\cmdtbl@name@\@empty
      \cmdtbl@error{no name given}{}%
    \else
      \if@cmdtbl@long
        \begin{longtable}{|@{\hskip4\tabcolsep}*2{p{\cmdtbl@width}}|}%
          \hline
          \cmdtbl@place@name \\
          \hline
          \endhead
          \cmdtbl@place@desc
          \cmdtbl@place@opt
          \cmdtbl@place@ex
        \end{longtable}%
      \else
        \begin{tabular}{|@{\hskip4\tabcolsep}*2{p{\cmdtbl@width}}|}%
          \hline
          \cmdtbl@place@name \\
          \hline
          \cmdtbl@place@desc
          \cmdtbl@place@opt
          \cmdtbl@place@ex
        \end{tabular}%
      \fi
    \fi
  }%=<<
\makeatother

\begin{document}
\noindent
\begin{commandtable}[10cm] % the optional argument specifies the width
  \name{cp}{option,in,out}
  \description{Copy the file \textit{in} to the location \textit{out}}
  \option{-r}{Copy folders recursively}
  \option{-f}{forced}
  \example{cp -r Dir1 /to/Dir2}
  \example{cp source destination}
\end{commandtable}%

\vspace{10cm}
\noindent
\begin{commandtable}* % with star the environment is page breakable (star after optional arg)
  \name{apt-get}{option,name}
  \description{Here should be a brief function description}
  \option{install}{Brief description}
  \option{update}{Brief description}
  \option{remove}{Brief description}
  \example{apt-get install newpackage}
  \example{apt-get install anotherpackage}
\end{commandtable}
\end{document}

enter image description here

2

Here is a possible starting point using expl3 and tcolorbox. If you look at the manual, you'll see that the options for configuring the appearance are endless—it's even possible and easy to make the box breakable across pages, see below.

Note: I renamed your “options“ to “subcommands”, because the term “options” in this context is customarily used for arguments like -f or --force, not for mandatory arguments such as install or remove here; the term “subcommands” is used as I do in Python's argparse module, at the very least. It's just a name, anyway—you can easily change it back if you care about “options”.

Main code

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tabularx}
\usepackage[table]{xcolor}
\usepackage{tcolorbox}
\usepackage{xparse}
\usepackage{lipsum}

% cf. <https://tex.stackexchange.com/questions/297345/why-is-the-start-row-of-rowcolors-ignored-in-tabularx/297357>
\newcounter{tblerows}
\expandafter\let\csname c@tblerows\endcsname\rownum

\colorlet{mycommandboxBg}{blue!3!white}
\colorlet{mycommandboxTitle}{blue!3!white}
\colorlet{mycommandboxSubcommand}{black}
\colorlet{mycommandboxSubcmdOdd}{blue!15!white}
\colorlet{mycommandboxSubcmdEven}{mycommandboxBg}

% Define a tcolorbox-based environment called 'mycommandbox'
\newtcolorbox{mycommandbox}[1]{colback=mycommandboxBg,
                               colframe=blue!75!black,
                               fonttitle=\bfseries,
                               title={\textcolor{mycommandboxTitle}{#1}},
                               coltitle=black,
                               subtitle style={
                                 toprule=0.4pt,
                                 bottomrule=0pt,
                                 colback=mycommandboxBg,
                               }
                              }

\ExplSyntaxOn

\tl_new:N \g__lmz_synopsis_tl
\tl_new:N \g__lmz_description_tl
\seq_new:N \g__lmz_subcommands_seq
\seq_new:N \g__lmz_examples_seq

\seq_new:N \l__lmz_start_cmdbox_tmp_seq
\seq_new:N \l__lmz_start_cmdbox_table_rows_seq
\tl_new:N \l__lmz_start_cmdbox_table_row_tl

% How to prepare a row for the table containing the subcommands
\cs_new_protected:Npn \lmz_set_subcmd_table_row:Nnn #1#2#3
  {
    \tl_set:Nn #1 { #2 & #3 }
  }

\cs_generate_variant:Nn \lmz_set_subcmd_table_row:Nnn { Nxx }

% Start the tcolorbox containing all the formatting
%
% #1: box title
\cs_new_protected:Npn \lmz_start_cmdbox:n #1
  {
    \mycommandbox {#1}
    \tcbsubtitle [toprule=0pt] { Description }
    \g__lmz_description_tl

    \tcbsubtitle { Subcommands }
    \lmz_write_subcommands_table:

    \tcbsubtitle { Examples }
    \lmz_write_examples:
  }

\cs_generate_variant:Nn \lmz_start_cmdbox:n { V }

% End the tcolorbox containing all the formatting
\cs_new_protected:Npn \lmz_end_cmdbox:
  { \endmycommandbox }

% Write the contents of the Subcommands section
\cs_new_protected:Npn \lmz_write_subcommands_table:
  {
    \seq_map_inline:Nn \g__lmz_subcommands_seq
      {
        % Get the two elements of the current subcommand in a seq
        \seq_set_split:Nnn \l__lmz_start_cmdbox_tmp_seq { } {##1}
        % Use them to form a table row
        \lmz_set_subcmd_table_row:Nxx \l__lmz_start_cmdbox_table_row_tl
          { \seq_item:Nn \l__lmz_start_cmdbox_tmp_seq {1} }
          { \seq_item:Nn \l__lmz_start_cmdbox_tmp_seq {2} }
        % Append the prepared row to \l__lmz_start_cmdbox_table_rows_seq
        \seq_put_right:NV \l__lmz_start_cmdbox_table_rows_seq
                          \l__lmz_start_cmdbox_table_row_tl
      }

    \group_begin:
    \rowcolors{1}{mycommandboxSubcmdOdd}{mycommandboxSubcmdEven}
    \begin{tabularx}{\linewidth} { @{\hspace{1em}} l  X }
      % Expand all prepared rows, separate them with \\
      \seq_use:Nn \l__lmz_start_cmdbox_table_rows_seq { \\ }
    \end{tabularx}
    \group_end:
  }

% Write the contents of the Examples section
\cs_new_protected:Npn \lmz_write_examples:
  {
    \group_begin:
    \slshape
    \seq_use:Nn \g__lmz_examples_seq { \\ }
    \group_end:
  }

% Start command for our 'commandtable' environment
\cs_new_protected:Npn \lmz_start_commandtable:
  {
    \tl_gclear:N \g__lmz_synopsis_tl
    \tl_gclear:N \g__lmz_description_tl
    \seq_gclear:N \g__lmz_subcommands_seq
    \seq_gclear:N \g__lmz_examples_seq

    \group_begin:
    \cs_set_eq:NN \synopsis \lmz_cmd_synopsis:n
    \cs_set_eq:NN \description \lmz_cmd_description:n
    \cs_set_eq:NN \subcommand \lmz_cmd_subcommand:nn
    \cs_set_eq:NN \example \lmz_cmd_example:n

    \ignorespaces
  }

% End command for our 'commandtable' environment
\cs_new_protected:Npn \lmz_end_commandtable:
  {
    \unskip
    \group_end:
    % Pass the *value* of token list variable \g__lmz_synopsis_tl
    \lmz_start_cmdbox:V \g__lmz_synopsis_tl
    \lmz_end_cmdbox:
    \ignorespacesafterend
  }

% Implementation for the \synopsis, \description, \subcommand and \example
% commands when used inside the 'commandtable' environment

\cs_new_protected:Npn \lmz_cmd_synopsis:n #1
  { \tl_gset:Nn \g__lmz_synopsis_tl {#1} }

\cs_new_protected:Npn \lmz_cmd_description:n #1
  { \tl_gset:Nn \g__lmz_description_tl {#1} }

\cs_new_protected:Npn \lmz_cmd_subcommand:nn #1#2
  {
    \seq_gput_right:Nn \g__lmz_subcommands_seq { {#1} {#2} }
  }

\cs_new_protected:Npn \lmz_cmd_example:n #1
  {
    \seq_gput_right:Nn \g__lmz_examples_seq {#1}
  }

\NewDocumentEnvironment { commandtable } { }
  { \lmz_start_commandtable: }
  { \lmz_end_commandtable: }

\ExplSyntaxOff

% Simple formatting commands for consistency (they could of course be defined
% using xparse's \NewDocumentCommand as well).
\newcommand*{\mycmd}[1]{\texttt{#1}}
\newcommand*{\mysubcommand}[1]{\textit{<#1>}}
\newcommand*{\myargument}[1]{\textit{<#1>}}

\begin{document}

\begin{commandtable}
\synopsis{\mycmd{apt-get} \mysubcommand{subcommand} \myargument{name}}
\description{Here should be a brief function description.}
\subcommand{install}{Brief description. \lipsum[1][1-3]}
\subcommand{update}{Brief description}
\subcommand{remove}{Brief description}
\example{apt-get install newpackage}
\example{apt-get install anotherpackage}
\end{commandtable}

\end{document}

Screenshot

Customizing the appearance

As said, the possibilities for changing the style of the box are numerous with tcolorbox, here is a simple change from the above look:

\colorlet{mycommandboxBg}{blue!3!white}
\colorlet{mycommandboxSubtitleBg}{orange!20!white}
\colorlet{mycommandboxTitle}{blue!3!white}
\colorlet{mycommandboxSubcommand}{black}
\colorlet{mycommandboxSubcmdOdd}{blue!15!white}
\colorlet{mycommandboxSubcmdEven}{mycommandboxBg}

% Define a tcolorbox-based environment called 'mycommandbox'
\newtcolorbox{mycommandbox}[1]{colback=mycommandboxBg,
                               colframe=blue!75!black,
                               fonttitle=\bfseries,
                               title={\textcolor{mycommandboxTitle}{#1}},
                               coltitle=black,
                               subtitle style={
                                  boxrule=0.4pt,
                                 colback=mycommandboxSubtitleBg,
                               }
                              }

(...)

\cs_new_protected:Npn \lmz_start_cmdbox:n #1
  {
    \mycommandbox {#1}
    \tcbsubtitle { Description }

(...)

Screenshot with other appearance

To suppress the subtitle rules, use boxrule=0pt in the subtitle style option.

Making the box breakable

In case you want to make the box breakable (not inside the tabularx used for the subcommands), you can use:

\documentclass{article}

(...)

\usepackage{tcolorbox}
\tcbuselibrary{breakable, skins}

(...)

\newtcolorbox{mycommandbox}[1]{...,
                               subtitle style={
                                 ...
                               },
                               enhanced jigsaw, breakable
                              }

(...)

with the following result:

Breakable, part 1 Breakable, part 2

Notes

As in Skillmon's answer, it's possible to use a description environment, a \synopsis, \subcommand or \example command inside the actual contents, because the special redefinitions for \description and these commands are very localized. For instance, with:

\subcommand{install}{Brief description. \lipsum[1][1-3]}
\subcommand{update}{Brief description}
\subcommand{remove}{Brief description.
  \begin{description}
  \item[foo] This performs foo.
  \item[bar] This does bar very well.
  \end{description}
}

one obtains:

With description env

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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