6

This question follows the one I asked here. I would like to override the following custom listings command from the tcolorbox package and be able to have the following features implemented using xkeyval:

  • Define the language I want in the nested listings environment (with the option key language=),
  • Be able to choose if I need numbers or not (with the option key withNumbers)
  • Be able to choose if I need a caption or not (defined with the titleoption)
  • Specify a type which will put a translation before the title (if applicable). Among the available types: codeSnippet, code, config, prompt. codeSnippet and config have numbers and title, the other two types haven't. And I should not be able to specify a title option if we are in a prompt for example (or at least that option must do nothing and must not override the type).

The idea is to have the more generic command as possible and the final command must have all optional arguments with default value (especially for language, if it isn't specified I don't want a specific language formatting), for example:

\begin{code}[withNumbers, title=Hello world.cpp, type=codeSnippet, language=C++]
#include <iostream>

int main(int argc, char *argv[]) {
    cout << "hello world" << endl;
}
\end{document}

In the afternoon, I also tried to have xkeyval boolkey in a way to achieve what I wanted to show in the example above.

If the key is present the value is true, if absent, the value is false. In this example, if I specify withNumbers, I want numbers. If it isn't specified, numbers should be absent of the final rendered listing environment.

The left statement from the newtcblisting caption must be removed if no numbers are present, in order to avoid an unneeded shift at the left of the listings environment.

By default, no language and no numbers. The modifications made to the following snippet of code does not have to break the feature brought in the aforementioned question, nor does it have to use a package other than tcolorbox as I might customize the box level a bit further in the future.

I tried the whole afternoon studying the xkeyval package and customizing the following command by enclosing it in a \renewcommand environment, but haven't succeeded at all :-(

The minimum working example with the \newtcblisting command I talked about:

\documentclass[oneside]{report}
\usepackage{fontspec}
\setmonofont{Bitstream Vera Sans Mono}[Scale=MatchLowercase]
\usepackage[margin=2.5cm]{geometry}
\usepackage{listings}
\usepackage{tcolorbox}
    \tcbuselibrary{breakable}
    \tcbuselibrary{skins}
    \tcbuselibrary{listings}
\usepackage{caption}

\usepackage{translations}
\DeclareTranslationFallback{codeSnippet}
{Code snippet}
\DeclareTranslation{English}{codeSnippet}
{Code snippet}
\DeclareTranslation{Dutch}{codeSnippet}
{Codefragment}
\DeclareTranslation{French}{codeSnippet}
{Extrait de code}

\usepackage[main=french, german]{babel}

% Let's create style to inherit from in other custom environments based on listings. Indeed, we do not want copy paste always the same customization for each environments.
\lstdefinestyle{custom}{
    % NoAutoSpacing prevents a space before colons to be added when the french
    % language is loaded with babel.
    % src.: https://tex.stackexchange.com/a/117767/66964
    %       https://tex.stackexchange.com/a/200215/66964
    basicstyle=\linespread{1}\normalsize\ttfamily\NoAutoSpacing,
    % Space separated words are not properly aligned on next lines if `columns` statement is set to
    % flexible. Default is 'fixed'.
    columns=fixed,
    breaklines=true,
    breakautoindent=false,
    breakindent=0pt,
    % Sets default tabsize to 4 spaces
    tabsize=4,
    % Normally used to define delimiters in code listings like begin and end
    % keywords, but it has a side effect allowing linebreaks. We are thus gonna
    % use that ugly trick to force lstinline statements to break the line at
    % the underscore character if there is not enough room for the string. This
    % is an ugly hack because it has a side effect: the _ character becomes
    % a suitable breakpoint for both sides. This can create either foo_\n bar
    % or foo\n _bar, but this cannot be avoided.
    %moredelim=[s]{_}{_},
    % Put in bold words surrounded by @@
    % [is] specifies the style.
    % i: standing for "invisible", ask for the delimiters @@ to invisible in the rendered version
    % s: standing for "string", ask for two delimiters, one starting the expression and the other closing the expression.
    moredelim={[is][keywordstyle]{@@}{@@}}
}

% Code environment. Does inherit from lstset settings thanks to style.
\newtcblisting[auto counter]{code}[2][]{%
    listing only,
    breakable,
    top=0.5pt,
    bottom=0.5pt,
    left=6mm,
    sharp corners,
    boxrule=0pt,
    bottomrule=1pt,
    toprule=1pt,
    enhanced jigsaw,
    listing options={
        style=custom,
        numbers=left,
        numberstyle=\tiny,
    },
    lefttitle=0pt,
    coltitle=black,
    colbacktitle=white,
    % Crashes on long lstlisting lines. \the\baselineskip reports 12.0pt. 1.2 * 12.0 = 14.4
    %borderline north={1pt}{1.2\baselineskip}{dashed},
    borderline north={1pt}{14.4pt}{dashed},
    title={\GetTranslation{codeSnippet} \thetcbcounter:  #2},#1
}

\begin{document}

\begin{code}{Some great title}
one
two
three
four
\end{code}
\end{document}

Thanks you in advance for your help.

EDIT: I'm now switching my own class file to pgfkeys (cf. my new question). So your solution can use pgfkeys instead of xkeyval.

5
  • 2
    I've not been digging deeper into your question (yet), but there's a problem -- (x)keyval (used by listings) and pgfkeys (used by tcolorbox) are not compatible.
    – user31729
    Dec 6, 2015 at 22:59
  • @ChristianHupfer I didn't know tcolorbox used pgfkeys: the documentation has only mentions of pgf. Indeed this can be a problem and have incompatibilities with xkeyval. Waiting on your ideas, I'm stuck here.
    – wget
    Dec 7, 2015 at 20:41
  • Sorry, I've got no idea so far, apart from something what I did about two years ago: mapping manually between xkevyal and pgfkeys :-(
    – user31729
    Dec 12, 2015 at 21:19
  • 2
    Is this question now irrelevant? I see you have answers to your new question. If so, I suggest deleting this one. If not, please edit the question to reflect whatever you want to still ask.
    – cfr
    Aug 3, 2016 at 21:56
  • @cfr Yes, it is still relevant. I'm currently updating this question to reflect the changes brought by the other question I asked and which has been solved.
    – wget
    Sep 4, 2017 at 13:57

0

You must log in to answer this question.

Browse other questions tagged .