[Tex/LaTex] Typeset source code with tcolorbox

sourcecodetcolorbox

I want to typeset source code with tcolorbox package. How is possible in this package not to create static boxes but rather boxes that adjust according to the width of the code I write both vertically and horizontally? Also I want if a line is too long to break into a new line. Can I do that?

Best Answer

With tcolorbox and its listings library you can use \newtcblisting to define a new environment for listings (using behind the scenes the listings package); if you use the hbox option for the tcolorbox, its width will dynamically adapt to the width of its content but, alas!, now the box doesn't admit page breaks and also automatic line breaks are not very well supported (the code will break if breaklines=true was passed as an option for the listing, but the box now won't behave nicely for long lines).

\documentclass{article}
\usepackage[many]{tcolorbox}
\tcbuselibrary{listings}

\newtcblisting{mylisting}{
  listing only,
  hbox,
  colframe=cyan,
  colback=cyan!10,
  listing options={
    basicstyle=\small\ttfamily,
    breaklines=true,
    columns=fullflexible
  },
}

\begin{document}

\begin{mylisting}
int main(int ac, char *av[]) 
{
  printf("Hello, World");
  return 0;
}
\end{mylisting}

\begin{mylisting}
int main(int ac, char *av[], char **ep,char *av[], char **ep) 
{
  printf("Hello, World");
  return 0;
}
\end{mylisting}

\end{document}

enter image description here

Perhaps then you can have breakable boxes with automatic line breaks by default, and selectively add the hbox option if you need variable width for short listings:

\documentclass{article}
\usepackage[a6paper]{geometry}% just for the example
\usepackage[many]{tcolorbox}
\tcbuselibrary{listings}

\newtcblisting{mylisting}[1][]{
  listing only,
  breakable,
  colframe=cyan,
  colback=cyan!10,
  listing options={
    language=C,
    basicstyle=\small\ttfamily,
    breaklines=true,
    columns=fullflexible
  },
  #1
}

\begin{document}

\begin{mylisting}[hbox]
int main(int ac, char *av[]) 
{
  printf("Hello, World");
  return 0;
}
\end{mylisting}

\begin{mylisting}
int main(int ac, char *av[],int ac, char *av[],int ac, char *av[],int ac, char *av[],int ac, char *av[],int ac, char *av[]) 
{
  printf("Hello, World");
  return 0;
}
int main(int ac, char *av[]) 
{
  printf("Hello, World");
  return 0;
}
{
  printf("Hello, World");
  return 0;
}
{
  printf("Hello, World");
  return 0;
}
{
  printf("Hello, World");
  return 0;
}
{
  printf("Hello, World");
  return 0;
}
{
  printf("Hello, World");
  return 0;
}
\end{mylisting}

\end{document}

enter image description here

The tcolorbox package also offers interaction with minted (another popular package for listings); minted, however, doesn't support automatic line breaking. A little example using now the minted library:

\documentclass{article}
\usepackage[many]{tcolorbox}
\tcbuselibrary{minted}

\newtcblisting{mylisting}{
  colframe=cyan,
  colback=cyan!10,
  listing only,
  listing engine=minted,
  minted language=cpp,
  minted options={fontsize=\small,linenos,numbersep=3mm},
}

\begin{document}

\begin{mylisting}
int main(int ac, char *av[]) 
{
  printf("Hello, World");
  return 0;
}
\end{mylisting}

\begin{mylisting}
int main(int ac, char *av[], char **ep,char *av[], char **ep) 
{
  printf("Hello, World");
  return 0;
}
\end{mylisting}

\end{document}

enter image description here

Related Question