jkuczm / mmacells

Mathematica cells in TeX
63 stars 18 forks source link

Reference a code block like the listings package? #36

Closed jkissl closed 5 years ago

jkissl commented 7 years ago

Is there a way to reference the mathematica cell/code block like you would when using the regular listings package? Would an extension of this allow the creation of a list of code blocks like the \lstlistoflistings function does?

jkuczm commented 7 years ago

mmacells is using listings, but only through fancyvrb interface.

mmaCell is based on fancyvrbs Verbatim environment, so while we can pass options for listings using morelst key, we need some additional code to call listings captioning and labeling functions in Verbatim environment.

We can use morefv key to pass formatcom* option, with relevant code, to fancyvrb.

Putting it together:

\documentclass[12pt]{article}
\usepackage{mmacells}

\makeatletter
\mmaSet{morefv={formatcom*={%
  % Advance listings counter
  \refstepcounter{lstlisting}%
  % Use `\label` if `label` option was used.
  \ifx\lst@label\@empty\else
    \label{\lst@label}
  \fi
  % Add entry to list of listings if `caption` option was used.
  \ifx\lst@@caption\@empty\else
    \addcontentsline{lol}{lstlisting}{\protect\numberline{\thelstlisting}\lst@@caption}
  \fi
}}}
\makeatother

\begin{document}

Cell with entry in list of listings:
\begin{mmaCell}[morelst={caption=mma}]{Input}
a+b
\end{mmaCell}

Labeled cell:
\begin{mmaCell}[morelst={label=myCell}]{Input}
c+d
\end{mmaCell}

Link to \hyperref[myCell]{labeled cell}.

\lstlistoflistings

\end{document}

If you don't want to mix Mathematica cells with other code listings you'd need separate counter and separate table of contents.

jkuczm commented 7 years ago

If one wants to use automatically named references using \nameref command provided by hyperref bundle, following code will use caption as name of reference, or, if caption is not given, In[...] or Out[..] label.

\documentclass[12pt]{article}
\usepackage{mmacells}

\ExplSyntaxOn
\makeatletter

\newcounter { mmacells }

\clist_put_right:Nn \l_mmacells_fv_keyval_clist
  {
    formatcom* =
      {
        \refstepcounter { mmacells }
        \cs_if_eq:NNF \lst@label \@empty
          {
            \cs_if_eq:NNTF \lst@@caption \@empty
              {
                \bool_if:NT \l_mmacells_indexed_bool
                  {
                    \cs_set:Npx \@currentlabelname
                      {
                        \bool_if:NTF \l_mmacells_intype_bool { In } { Out }
                        [ \int_use:N \g_mmacells_index_int ]
                      }
                  }
              }
              { \cs_set:Npx \@currentlabelname { \lst@@caption } }
            \label { \lst@label }
          }
      }
  }

\makeatother
\ExplSyntaxOff

\begin{document}

\begin{mmaCell}[morelst={label=twoLineInput}]{Input}
2 + 2
a+x+a
\end{mmaCell}

\begin{mmaCell}[morelst={label=numericOutput}]{Output}
4
\end{mmaCell}

\begin{mmaCell}[morelst={label=symbolicOutput}]{Output}
2 a + x
\end{mmaCell}

\begin{mmaCell}[morelst={label=favCell,caption=my favorite cell}]{Input}
c
\end{mmaCell}

Input cell: \nameref{twoLineInput}.\\
Numeric output cell: \nameref{numericOutput}.\\
Symbolic output cell: \nameref{symbolicOutput}.\\
Last cell: \nameref{favCell}.

\end{document}