4

Context

I am writing documentation for a package I developed (not LaTeX). Naturally one must define a bunch of functions, their arguments and associated return values, sometimes examples, etc.

To that end I am using tcolorbox to write up this information in a way I can described as not the worst aesthetically. (see image below).

enter image description here


Goal

My question is more or less the following: given the code below, how can I make this into a function so that it can be called like so

\function-blur{sort\_by}[
class                = OrderedNestedDictionary,
description          = Reorders....,
argument-list        = [subkey, reverse]
argument-description = [subkey = text...., reverse = text...]
returns              = returns None.
]

such that:

  • argument-list automatically color coats the arguments based off of a pre-defined order (e.g. eastern-blue, blue, magenta, dove-gray,...)

  • if an argument is referenced in the argument description or return it is highlighted appropriately (circled as in the main argument list).

Bonuses

Bonus points goes out to answering this subquestion.

  1. how to make tcbox appear in table of contents as if it were a section.

Update

As requested by Andrew I am including a MWE that compiles by itself. Accordingly I am removing the separate definitions.

\documentclass[]{article}
\usepackage[utf8]{inputenc}
\usepackage{MySpecialFonts} %This is where Anonymous comes from




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                         GRAPHICS AND COLORS                       %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{graphicx}
\usepackage{xcolor}     



\definecolor{eastern-blue}{cmyk}{0.80, 0.13, 0.14, 0.04, 1.00}
\definecolor{orient}{cmyk}{0.85, 0.44, 0.17, 0.14, 1.00}
\definecolor{dove-gray}{cmyk}{0.47, 0.39, 0.35, 0.01, 1.00}


%%  Default tcbox behavior
\usepackage{framed}
\usepackage{tcolorbox}
\tcbset{
colback=dove-gray!10!, 
coltitle=white, 
coltext=black,
colframe=eastern-blue, 
fonttitle=\bfseries\large,
titlerule=3mm,
boxrule=1mm,
subtitle style={
    colback=orient, 
    fonttitle=\bfseries,
    titlerule=.5mm,
    boxrule=.5mm
    }
}


\newtcbox{\xmybox}[1][red]{on line, arc=7pt,colback=#1!10!white,colframe=#1!50!black, before upper={\rule[-3pt]{0pt}{10pt}},boxrule=1pt, boxsep=0pt,left=6pt,right=6pt,top=2pt,bottom=2pt}

\usepackage{tikz}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                         MATH PACKAGES                             %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\usepackage{amssymb}
\usepackage{amsmath}   %braces
\usepackage{mathtools} %brackets


\begin{document}




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                            My-Class                               %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                                                                   %%
%%                          my\_function                             %%
%%                                                                   %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{my\_function}
\begin{tcolorbox}[title={\anonymous MyClass.my\_function}]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                           DESCRIPTION                             %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
This is a description of what this functions does when called by an instance of {\anonymous MyClass} based on some of the arguments. 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                            ARGUMENTS                              %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tcbsubtitle{Arguments}
 $\langle$\xmybox[eastern-blue]{arg1}, \xmybox[blue]{arg2}, \xmybox[magenta]{arg3}$\rangle$
\begin{description}
    \item[arg1] is a string that does something
    \item[arg2] is an iterator that is used in conjuction with \xmybox[eastern-blue]{arg1}
    \item[arg3] is an optional parameter that may act on \xmybox[eastern-blue]{arg1}
\end{description}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                             RETURNS                               %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tcbsubtitle{Returns}
{\anonymous my\_function} returns a thing which is determined by  \xmybox[eastern-blue]{arg1} and \xmybox[blue]{arg2}. If \xmybox[magenta]{arg3} is given with a value $X$ then $Y$ occurs to   \xmybox[eastern-blue]{arg1}.
\end{tcolorbox}



\end{document}

Definitions

Fonts

\newfontfamily\anonymous{AnonymousPro}[
Path            =   ./Fonts/Anonymous/,
Extension       =   .ttf,
UprightFont     =   *-Regular,
BoldFont        =   *-Bold,
ItalicFont      =   *-Italic,
BoldItalicFont  =   *-BoldItalic
]  
6

To pass the various code block parameters to a macro as you describe the easiest way is to use one of the many key-value systems. As you are using tcolorbox we could use \tcbset but this just calls \pgfkeys so I have used that.

I have created a new family /function of pgfkeys. This family accepts keys for the function name, the class name, a description of the function, the return values and the remaining keys are assumed to be the arguments of the function with the values being a description of them. To specify your example function, use:

  \Function{sort\_by}[%
     class=OrderedNestedDictionary,
     description=Reorders the calling {\anonymous OrderedNestedDictionary} based on a 
             subkey found in each element of the calling 
             {\anonymous OrderedNestedDictionary},
     subkey=a strings representing a subkey found in the values of the callings
             {\anonymous OrderedNestedDictionary} associated keys,
     reverse=a boolean of whether or not to reverse the resulting sorted collection,
  ]

The way the \Function macro works is that it starts by setting the keys. When it hits an unknown key it is assumed to be an argument to the function. The .unknown/.code handler is called and it (recursively) defines keys argument line and argument description that list the arguments and their descriptions. In these two keys the arguments appear in the order that they are given to the \Function macro. Once this is done, the macro constructs your tcolorbox much as in the OP, except that it uses the data stored in the pgfkeys. As a bonus, the \Function macro also adds a section entry to the table of contents.

Here is the full code:

\documentclass{article}
\usepackage{xparse}
\usepackage{framed}
\usepackage{tcolorbox}

\definecolor{eastern-blue}{cmyk}{0.80, 0.13, 0.14, 0.04, 1.00}
\definecolor{orient}{cmyk}{0.85, 0.44, 0.17, 0.14, 1.00}
\definecolor{dove-gray}{cmyk}{0.47, 0.39, 0.35, 0.01, 1.00}

\tcbset{
colback=dove-gray!10!,
coltitle=white,
coltext=black,
colframe=eastern-blue,
fonttitle=\bfseries\large,
titlerule=3mm,
boxrule=1mm,
subtitle style={
    colback=orient,
    fonttitle=\bfseries,
    titlerule=.5mm,
    boxrule=.5mm
    }
}
\pgfkeys{/function/.is family, /function,
  function/.initial=unknown function,
  class/.initial=unknown class,
  description/.initial=no description,
  returns/.initial=None,
  % the remaining code deals with arguments
    arguments/.initial=0, % number of arguments
    % any unknowns are assumed to be arguments with their descriptions
    argument line/.initial={},
    argument description/.initial={},
    .unknown/.code = {
      \pgfmathsetmacro\args{int(\pgfkeysvalueof{/function/arguments}+1)}
      \pgfkeyssetvalue{\pgfkeyscurrentpath/arguments}{\args}
      \xdef\argcol{\pgfkeysvalueof{/function/argument color \args}}
      \xdef\argument{\pgfkeyscurrentname}
      \ifnum\args>1\pgfkeys{/function/argument line/.append code={,\space}}\fi
      \pgfkeys{/function/argument line/.append code/.expanded={\noexpand\xmybox[\argcol]{\argument}}}
      \pgfkeys{/function/argument description/.append code/.expanded={\noexpand\item[\argument]#1}}
    },
    % list of colours used for arguments
    argument color 1/.initial=eastern-blue,
    argument color 2/.initial=blue,
    argument color 3/.initial=orient,
    argument color 4/.initial=dove-gray,
}

\newtcbox{\xmybox}[1][red]{
  on line, arc=7pt,colback=#1!10!white,colframe=#1!50!black,
  before upper={\rule[-3pt]{0pt}{10pt}},boxrule=1pt,
  boxsep=0pt,left=6pt,right=6pt,top=2pt,bottom=2pt
}
\let\anonymous\relax

\DeclareDocumentCommand\SetArguments{ > {\SplitArgument{1}{ = }} m}{\setarguments#1}
\newcommand\setarguments[2]{\def\arg{#1}\def\argdesc{#2}}
\NewDocumentCommand\Function{ m o}{%
  \bgroup% do everything inside a group so that we do not need to reset function values
    \pgfkeys{/function, function=#1}% set function name
    \IfNoValueF{#2}{\pgfkeys{/function, #2}}% set other parameters
    \addcontentsline{toc}{section}{% add toc entry
       \pgfkeysvalueof{/function/class}.\pgfkeysvalueof{/function/function}}
    \begin{tcolorbox}[title={\anonymous\pgfkeys{/function/class}.\pgfkeys{/function/function}}]
       \pgfkeys{/function/description} % add description
       \edef\args{\pgfkeysvalueof{/function/arguments}}
       \ifnum\args>0% add argument block if the function has arguments
         \tcbsubtitle{Arguments}        
         $\Bigl\langle$\pgfkeys{/function/argument line}$\Bigr\rangle$
         \begin{description}\pgfkeys{/function/argument description}\end{description}
       \fi
       \tcbsubtitle{Returns}
       {\anonymous \pgfkeys{/function/function}} returns %
             $\langle$\,\pgfkeys{/function/returns}\,$\rangle$.
    \end{tcolorbox}
  \egroup% close group
}

\begin{document}

  \tableofcontents

  \Function{sort\_by}[%
     class=OrderedNestedDictionary,
     description=Reorders the calling {\anonymous OrderedNestedDictionary} based on a subkey
                 found in each element of the calling {\anonymous OrderedNestedDictionary},
     subkey=a strings representing a subkey found in the values of the callings
             {\anonymous OrderedNestedDictionary} associated keys,
     reverse=a boolean of whether or not to reverse the resulting sorted collection,
  ]

\end{document}

and here is the output:

enter image description here

Note that I have not used your fancy anonymous font as I don't have this (instead I set \let\anonymous\relax).

Finally, the OP also says "if an argument is referenced in the argument description or return it is highlighted appropriately (circled as in the main argument list)" but it is not clear to me what this means as no examples were given. I would suggest asking another question if this has not already been addressed:)

  • New question here: tex.stackexchange.com/questions/342601/… – SumNeuron Dec 6 '16 at 4:42
  • Might I inquire about an addendum? 1.) I do not yet see in your code where it is defined as either a section or subsection. Basically, how do you define it to be part of the TOC and how could one alter it? and 2.) how would one automate the creation of a label: \label{fxn:ClassName.function_name} ? – SumNeuron Dec 6 '16 at 5:33
  • @SumNeuron It's done by the \addcontentsline command. I did not actually create a new section or give it a section number as I didn't realise that you wanted these. It's easy enough to add these. Btw, I noticed that you have accepted only one answer for all of the questions that you have asked. I'd recommend accepting a few answers or people will stop answering your questions:) I am not saying that you should accept mine but rather that you should accept answers that answer your questions. Regarding explanations, if I have time to look at your other question I will ad more explanations. – Andrew Dec 6 '16 at 6:41
  • in regards to the few TeX Q's I have asked yes; on other S.E. sites it is generally not the case. While there are many ways to approach a problem & there are likely many alternative or superior solutions that use an alt. method than what I am asking, I want to learn how to do a specific thing. So if there is an obvious answer e.g. search & replace instead of a macro, or just writing out the code in length, I specify that I am not looking for these e.g. here, I made the tcbox from reading the docs. but that function which templates it, I needed your assistance. – SumNeuron Dec 6 '16 at 7:07
  • 1
    @SumNeuron I've played around a little trying to solve your highlighting issue but I keep running into problems. An "honest" solution probably has to use l3regex but I don't understand enough of latex3 to use this... – Andrew Dec 7 '16 at 13:12

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.