Adicionando uma regra horizontal entre legenda e lstlisting dentro de um tcolorbox

Adicionando uma regra horizontal entre legenda e lstlisting dentro de um tcolorbox

Tenho listagens de exemplo de um livro.

insira a descrição da imagem aqui

Gostaria de uma regra horizontal na largura do tcolorbox entre a legenda e a listagem.

O código usado para produzi-lo:

\documentclass[letterpaper,oneside,12pt]{book}
\usepackage{listings}
\usepackage[most]{tcolorbox}
\usepackage{caption}
\usepackage{xcolor}

\definecolor{shadecolor}{gray}{0.95}
\definecolor{captionbox}{cmyk}{0.43, 0.35, 0.35,0.01}

\tcbset{colback=captionbox!5!white,colframe=captionbox!75!black}

\BeforeBeginEnvironment{lstlisting}{\begin{tcolorbox}[toprule=3mm]\vskip-.5\baselineskip}
\AfterEndEnvironment{lstlisting}{\end{tcolorbox}}

\DeclareCaptionFormat{listing}{\parbox{\textwidth}{#1#2#3}}

\captionsetup[lstlisting]{format=listing,skip=10pt}

\lstset{numbers=none}

\begin{document}

\begin{lstlisting}[caption=Sample code block]
This is a code block
\end{lstlisting}

\end{document}

Minha única restrição é que preciso usar o pacote de listagens e o lstlisting porque o Pandoc exige isso para listagens. Fico feliz em substituir qualquer outra coisa para produzir o mesmo efeito de uma caixa ao redor da legenda e da listagem pela regra entre a legenda e a listagem e uma sensação de estilo semelhante.

Responder1

Atualizar: alterado overlay firstpara overlay unbroken and firstpara que a linha também apareça em caixas inteiras. Meu erro.

Pena que você não pode usar o tcblistings, que parece ter sido feito especificamente para esse fim e de uso interno listings(li, mas não verifiquei isso).

Embora eu não goste de soluções "específicas" (ou seja, soluções que precisam de ajustes manuais), proponho isso a você simplesmente porque "funciona":

\documentclass[letterpaper,oneside,12pt]{book}

\usepackage{xcolor}

\usepackage{listings}
\usepackage{tcolorbox}
  \tcbuselibrary{breakable}
  \tcbuselibrary{skins}
\usepackage{caption}

\usepackage{tikz}

\usepackage{lipsum}

\definecolor{shadecolor}{gray}{0.95}
\definecolor{captionbox}{cmyk}{0.43, 0.35, 0.35,0.01}

\tcbset{%
    colback=captionbox!5!white,%
    colframe=captionbox!75!black,%
    top=1mm,%   %% Used to manually align the caption with the horizontal line
    %
    %% Create a new "style" for your titled listings tcolorbox
    mylistingwithtitle/.style = {%
        breakable,%
        %% Use tcolorbox's internal tikz object name (frame) to draw a horizontal line
        overlay unbroken and first={\draw[shorten >=1.4pt, shorten <=1.4pt] ([yshift=-3em]frame.north west) -- ([yshift=-3em]frame.north east);}%
    }%
}

\BeforeBeginEnvironment{lstlisting}{%
    \begin{tcolorbox}[enhanced, toprule=3mm, mylistingwithtitle]%
    \vskip-.5\baselineskip%
}

\AfterEndEnvironment{lstlisting}{\end{tcolorbox}}

\DeclareCaptionFormat{listing}{\parbox{\textwidth}{#1#2#3}}
\captionsetup[lstlisting]{format=listing,skip=15pt}


\begin{document}

%% This following line is only useful to execute \lipsum[1-4] inside the listing
\lstset{numbers=none, escapeinside={(*}{*)}}

\begin{lstlisting}[caption=Sample code block]
  This is a code block

  (*\lipsum[1-4]*)
\end{lstlisting}

\end{document}

Se você alterar a formatação da legenda, precisará mexer manualmente no espaçamento vertical, ou seja, a top=1mmopção para o tcolorbox e [yshift=-3em]para desenhar a linha horizontal. Você também terá que mexer na última opção, junto com as opções shorten >=1.4pte shorten <=1.4pt, se decidir alterar a formatação (linha superior, largura da borda, margens internas, etc.) do tcolorbox.

Tomei a liberdade de adicionar a breakableopção ao tcolorbox para permitir que ele se dividisse em várias páginas.

Saída:

Saída produzida pelo código acima

informação relacionada