Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 9 down vote accepted

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

share|improve this answer
    
I second the integration of the listings package. It gives many possibilities to typeset the code in a more readable way. –  Rüdiger Voigt Apr 30 at 13:30
    
Thank you very much I will try it further. Why the "breaking" don't work if you modify the box? Also do you know another package to typeset source code in the way I want it? Shouldn't be the default way to write code like the one I ask for? –  Adam Apr 30 at 16:30
    
@Adam You're welcome. To answer: 1) When hbox is used the boxing mechanism used (which allows the width calculation) doesn't support page breaks. 2) The most popular packages are listings, minted and fancyvrb (tcolorbox offers interaction with the first two); none of them will do exactly all what you want; the closest results can be achieved using my second example and manually using the hbox option in case of short listings that won't have page breaks. 3) No, I don't think it shouldn't be the default. Many people don't like colorized boxes of variable width for their listings. –  Gonzalo Medina Apr 30 at 17:20
    
@GonzaloMedina I didn't mean color boxes should be the default. I meant all the properties I mentioned should be. I don't like color boxes either (I use white color in tcolorbox package)! I just like the freedom for custom boxes it provides. –  Adam Apr 30 at 17:24
    
@Adam Ah, I see; in any case, boxes of variable width is also not a widely used feature. Listings allowing page breaks and automatic line breaks can be achieved using the listings package or tcolorbox with its listings library. –  Gonzalo Medina Apr 30 at 17:28

While I don't know how to do it in tcolorbox, I showed at Seemingly trivial: verbatim, newenvironment, and colorbox how to make colored verbatim boxes with my verbatimbox package. I haven't yet upgraded the package to provide these by default, so they are herein contained in the preamble.

Note that this answer does NOT support automatic line breaking. And being in a box, it does not support page breaking either.

I modify that answer (which provided a single environment) by providing two environments, cverbbox and mycverbbox, the latter of which allows you to specify the unique name of the box holding the result. I also show, in the 3rd example, how to number code lines through the use of the optional argument.

\documentclass{article}
\usepackage{xcolor}
\usepackage{verbatimbox}
\makeatletter
\newenvironment{mycverbbox}[5][]{%
  \setcounter{VerbboxLineNo}{0}%fx
  \def\verbatim@processline{%
% THE FIRST #1 ACCOUNTS FOR NON-PRINTING COMMANDS; THE SECOND #1 IS FOR
% PRINTED OPTIONAL MATERIAL
    {\addtocounter{VerbboxLineNo}{1}%
    #1\setbox0=\hbox{#1\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\par}}%
  \@minipagetrue%
  \@tempswatrue%
  \global\edef\sv@name{\@macro@name{#5}}%
  \global\edef\cverbboxColor{#3}%
  \global\edef\cverbboxFColor{#4}%
  \@ifundefined{\sv@name content}{%
    \expandafter\newsavebox\expandafter{\csname\sv@name content\endcsname}%
  }%
  \expandafter\global\expandafter\edef\csname\sv@name\endcsname{\usebox{%
  \csname\sv@name content\endcsname}}%
  \setbox0=\vbox\bgroup\color{#2} \verbatim
}
{%
  \endverbatim%
  \unskip\setbox0=\lastbox %
  \egroup%
  \setbox1=\hbox{%
    \colorbox{\cverbboxColor}{\box0}}%
  \global\sbox{\csname\sv@name content\endcsname}%
    {\fboxsep=\fboxrule\colorbox{\cverbboxFColor}{\box1}}%
}
\newenvironment{cverbbox}[4][]{%
  \setcounter{VerbboxLineNo}{0}%fx
  \def\verbatim@processline{%
% THE FIRST #1 ACCOUNTS FOR NON-PRINTING COMMANDS; THE SECOND #1 IS FOR
% PRINTED OPTIONAL MATERIAL
    {\addtocounter{VerbboxLineNo}{1}%
    #1\setbox0=\hbox{#1\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\par}}%
  \@minipagetrue%
  \@tempswatrue%
  \global\edef\sv@name{theverbbox}%
  \global\edef\cverbboxColor{#3}%
  \global\edef\cverbboxFColor{#4}%
  \@ifundefined{\sv@name content}{%
    \expandafter\newsavebox\expandafter{\csname\sv@name content\endcsname}%
  }%
  \expandafter\global\expandafter\edef\csname\sv@name\endcsname{\usebox{%
  \csname\sv@name content\endcsname}}%
  \setbox0=\vbox\bgroup\color{#2} \verbatim
}
{%
  \endverbatim%
  \unskip\setbox0=\lastbox %
  \egroup%
  \setbox1=\hbox{%
    \colorbox{\cverbboxColor}{\box0}}%
  \global\sbox{\csname\sv@name content\endcsname}%
    {\fboxsep=\fboxrule\colorbox{\cverbboxFColor}{\box1}}%
}
\makeatother
\parskip 1ex
\begin{document}

\fboxrule=3pt\fboxsep=1pt
\begin{cverbbox}[\scriptsize\textcolor{black}{$\bullet$}]{red!80}{blue!10}{cyan}
here is \verbatim Text
Here
%$#@&^* \macros
xa
\end{cverbbox}
\fbox{An} inline verbatimbox\theverbbox is here.

\fboxrule=0pt\fboxsep=3pt
\begin{cverbbox}{blue}{cyan!40}{cyan}
here is frameless colorboxed \verbatim Text
by setting \fboxsep to 0pt.
No conditioning is performed with
an \optional argument
\end{cverbbox}
\theverbbox


\fboxrule=1pt\fboxsep=3pt\relax
\begin{mycverbbox}[\tiny\textcolor{black!50}{\tiny\makebox[4ex][r]{%
  \theVerbboxLineNo:~}}]{black}{blue!10}{cyan}{\mycvbox}
      subroutine cubic (p,q,r,rts)
c     SOLVES CUBIC EQUATION x^3 + px^2 + qx + r = 0
c     WITH REAL COEFFICIENTS.  SOLUTION MAY BE COMPLEX.
      implicit none
      double precision p,q,r,rts(2,3)
      double precision Ar, Ai, arg, ang, Br, Bi, SUMr, SUMi, DIFr,
     &                 DIFi, a,b, radicand, term,   PI
      PARAMETER (PI=3.14159 26535 89793 23846 d0)
c
      a = (3.d0*q - p**2)/3.d0
      b = (2.d0*p**3 - 9.d0*p*q + 27.d0*r)/27.d0
      radicand = b**2 /4.d0 + a**3 /27.d0
      if (radicand .ge. 0.d0) then
        term = -b/2.d0 + sqrt(radicand)
        if (term .ge. 0.d0) then
          Ar = term**(1.d0/3.d0)
        else
          Ar = -(-term)**(1.d0/3.d0)
        end if
        Ai = 0.d0
        term = b/2.d0 + sqrt(radicand)
        if (term .ge. 0.d0) then
          Br = -(term**(1.d0/3.d0))
        else
          Br = (-term)**(1.d0/3.d0)
        end if
        Bi = 0.d0
      else
        arg = (sqrt((b/2.d0)**2 - radicand))**(1.d0/3.d0)
        ang = atan(sqrt(-radicand)/(-b/2.d0))
        if (ang .lt. 0.d0) ang = ang + PI
        ang = ang/3.d0
        Ar = arg*cos(ang)
        Ai = arg*sin(ang)
        Br = Ar
        Bi = -Ai
      end if
      SUMr = Ar + Br
      SUMi = Ai + Bi
      DIFr = Ar - Br
      DIFi = Ai - Bi
      rts(1,1) = SUMr - p/3.d0
      rts(2,1) = SUMi
      rts(1,2) = -(SUMr - DIFi*sqrt(3.d0))/2.d0 - p/3.d0
      rts(2,2) = -(SUMi + DIFr*sqrt(3.d0))/2.d0
      rts(1,3) = -(SUMr + DIFi*sqrt(3.d0))/2.d0 - p/3.d0
      rts(2,3) = -(SUMi - DIFr*sqrt(3.d0))/2.d0
      return
      end
c********************************************************************
\end{mycverbbox}
\mycvbox

\end{document}

enter image description here

Note that frameless boxes can be obtained by setting \fboxrule to 0pt.

share|improve this answer
    
Thank you this is helpful but it is a bit complex for what I am trying to achieve. –  Adam Apr 30 at 16:31
    
Understood. The preamble definitions can be just cut and paste into your document, but I understand the desire for simplicity. Cheers. –  Steven B. Segletes Apr 30 at 16:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.