gpoore / minted

minted is a LaTeX package that provides syntax highlighting using the Pygments library. Highlighted source code can be customized using fancyvrb.
1.73k stars 125 forks source link

Use a \def macro as the value for the style option #357

Open Bigaluca opened 1 year ago

Bigaluca commented 1 year ago

I use minted together with the tcolorbox package and therefore, choosing a code highlighting style, I then need to set the tcb background and frame colors appropriately.

In order not to have to modify each option by hand every time I want to change the style, I decided to define a macro in such a way that only that one has to be modified.

The problem is that by passing the macro to the style option, I raise these errors:

Package catchfile: File `_minted-main/\codeSnippetStyleName .pygstyle' not found.

Package minted: Cannot find Pygments style \codeSnippetStyleName .

I add a snippet of code to better explain the situation limiting it to the use of minted only:

\def\codeSnippetStyleName{emacs}

[...]

\begin{minted}[style=\codeSnippetStyleName]{bash}
    ...some code...
\end{minted}

Is there any solution to solve the problem?

muzimuzhi commented 1 year ago

Since v2.6, style name is \detokenized without any expansion. The change is introduced in https://github.com/gpoore/minted/commit/334fb94ab8228dea38c2b76387e461ca972258d8, see definition and use of \minted@def@opt@detok.

Doing fully expansion before detokenization will break cases when the style name contains active characters (probably - and/or _). And since the key-value scheme used by minted doesn't provide ways to control expansion of value, unlike key handlers /.expand once and /.expanded in pgfkeys, a quick workaround would be to provide a new key, like style/expand fully. (estyle is a good short-form but may cause misunderstanding since it carries out different meaning in other packages.)

\documentclass{article}
\usepackage{minted}

\makeatletter
% #1 default value, #2 real key, #3 user key, #4 wrapped ##1
% provide user key which actually alters real key
\newcommand{\minted@def@opt@general}[4]{%
  \define@key{minted@opt@g}{#3}{%
    \@namedef{minted@opt@g:#2}{#4}}
  \define@key{minted@opt@g@i}{#3}{%
    \@namedef{minted@opt@g@i:#2}{#4}}
  \define@key{minted@opt@lang}{#3}{%
    \@namedef{minted@opt@lang\minted@lang:#2}{#4}}
  \define@key{minted@opt@lang@i}{#3}{%
    \@namedef{minted@opt@lang\minted@lang @i:#2}{#4}}
  \define@key{minted@opt@cmd}{#3}{%
    \@namedef{minted@opt@cmd:#2}{#4}}
  \ifstrempty{#1}{}{\@namedef{minted@opt@g:#2}{#1}}%
}

% \renewcommand{\minted@def@opt}[2][]{%
%   \minted@def@opt@general{#1}{#2}{#2}{##1}}
% \renewcommand{\minted@def@opt@detok}[2][]{%
%   \minted@def@opt@general{#1}{#2}{#2}{\detokenize{##1}}}

% "o" stands for "one-step expansion"
\newcommand{\minted@def@opt@detok@o}[3][]{%
  \minted@def@opt@general{#1}{#2}{#3}{\detokenize\expandafter{##1}}}
% "e" stands for "fully expansion by \expanded"
\newcommand{\minted@def@opt@detok@e}[3][]{%
  \minted@def@opt@general{#1}{#2}{#3}{\detokenize\expandafter{\expanded{##1}}}}

% \minted@def@opt@detok{style}
\minted@def@opt@detok@o{style}{style/expand once}
\minted@def@opt@detok@e{style}{style/expand fully}
\makeatother

\begin{document}
\begin{minted}[style=default]{latex}
\begin{align}
  a + b = c
\end{align}
\end{minted}

\def\mystyle{emacs}
\begin{minted}[style/expand once=\mystyle]{latex}
\begin{align}
 a + b = c
\end{align}
\end{minted}

\def\mystyle{autumn}
\def\mynestedstyle{\mystyle}
\begin{minted}[style/expand fully=\mynestedstyle]{latex}
\begin{align}
 a + b = c
\end{align}
\end{minted}
\end{document}

image

Bigaluca commented 1 year ago

Thanks for the suggestion, it solved my problem.

muzimuzhi commented 1 year ago

Ah perhaps you can leave it to the package maintainer to decide if minted wants to provide some "official" support for this usage. After all what I previously provided is just a(n) attempt or workaround from community.