0

In listings and showexpl package, my problem is the code is go over the page and one another problem is that how can the image and the code be seperate that the image in previous page and the code in new page when ended the page?

enter image description here

Here is my code

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{vietnam}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage[width=0.00cm, height=0.00cm, left=2.00cm, right=2.00cm, top=2.00cm, bottom=2.00cm]{geometry}
\usepackage{tkz-euclide}
\usepackage{tikz-3dplot}
\usepackage{tikz,tkz-tab,tkz-linknodes}
\usetkzobj{all}
\usetikzlibrary{decorations.text,calc,intersections,patterns}

%sao chép y nguyên code
\usepackage{caption}
\usepackage{listings}
\usepackage{showexpl}
\usepackage{color,xcolor}
\lstset{ % General setup for the package
    language=TeX,
    breaklines=true,
    basicstyle=\small\sffamily,
    numbers=left,
    numberstyle=\tiny,
    frame=tb,
    tabsize=4,
    columns=fixed,
    showstringspaces=false,
    showtabs=false,
    commentstyle=\color{red},
    keywordstyle=\color{blue}
}
\begin{document}
\begin{LTXexample}[pos=t]
%Tree source: http://www.texample.net/tikz/examples/tree-pic/
%Man source: https://tex.stackexchange.com/questions/249588/node-below-icon-in-tikz
\usetikzlibrary{decorations.pathmorphing,shapes}
\tikzset{
    treetop/.style = {
        decoration={random steps, segment length=0.4mm},
        decorate
    },
    trunk/.style = {
        decoration={random steps, segment length=2mm, amplitude=0.2mm},
        decorate
    }
}
\tikzset{
    man/.pic={%
        \fill [rounded corners=1.5] (0,0.4) -- (0,0.8) -- (0.4,0.8) -- (0.4,0.4) --
        (0.325,0.4) -- (0.325,0.7) -- (0.3,0.7) -- (0.3,0) -- (0.225,0) --
        (0.225,0.4) -- (0.175,0.4) -- (0.175,0) -- (0.1,0) -- (0.1,0.7) --
        (0.075,0.7) -- (0.075,0.4) -- cycle;
        \fill (0.2,0.9) circle (0.1);
        \coordinate (-head) at (0.2,1);
        \coordinate (-foot) at (0.2,0);
    }
}

\begin{center}
    \begin{tikzpicture}
    \tkzInit[xmin=-11,ymin=-5,xmax=3,ymax=3]
    \tkzClip\tkzGrid
    \tkzDefPoints{-11/-3/A,-9.8/-2.09/A',0/1.47/B', 2/-3/B,0/-2.09/C,-10.1/-3/M,0/-3/T}
    \pic[red] at (-10.1,-3) (myman) {man};
    \foreach \w/\f in {0.3/30,0.2/50,0.1/70} {
        \fill [brown!\f!black, trunk] (0,0) ++(-\w/2,0) rectangle +(\w,-3);
    }
    \foreach \n/\f in {1.4/40,1.2/50,1/60,0.8/70,0.6/80,0.4/90} {
        \fill [green!\f!black, treetop] ellipse (\n/1.5 and \n);
    }
    \tkzDrawSegments[dashed](A',B' A',C)
    \tkzDrawSegments(A,B T,B')
    \tkzMarkAngles[size=0.7cm,arc=ll,mark=|](C,A',B')
    \tkzLabelAngles[pos=1.5](C,A',B'){$30^{\circ}$}
    \tkzLabelSegment[below](M,T){$20$ cm}
    \tkzLabelPoints(A,B,C,A',B',C,M,T)
    \end{tikzpicture}
\end{center}
\end{LTXexample}
\end{document}
Bernard
  • 271,350

1 Answers1

1

Edit 2: This following line inside \g@addto@macro\SX@put@code@result in my patch

\expandafter\lstset\expandafter{\SX@@explpreset@saved}%

Should be

\edef\SX@@explpreset{\SX@@explpreset@saved}%

To prevent custom preset from being overwritten by the package preset.

And there's a missing \global before \@SX@pos@tbfalse and \@SX@pos@tb@pagebreakfalse

Edit:

After further diving into showexpl package, I've figured out its workflow: the LTXexample environment uses \lst@BeginWriteFile to write the input into \SX@codefile, and then call \SX@put@code@result, which renders result and code mainly by \SX@resultInput and \SX@codeInput respectively. The order of those two input is defined in \SX@put@<pos>.

So basically in my \SX@put@tb I drop argument #3 which is \SX@codeInput for later rendering. With this approach you need to save preset \SX@@explpreset because it's locally defined inside a group in \SX@put@code@result.

To make the solution neater, I added a pagebreak option (though vsep without this option might not be correct) and use \g@addto@macro to append the code part to \SX@put@code@result.

The MWE is shown below:

\documentclass[12pt,a4paper]{article}
\usepackage{listings}
\usepackage{showexpl}
\usepackage{xcolor}

\lstdefinestyle{customlatex}{ basicstyle=\small\ttfamily, language=[LaTeX]TeX, commentstyle=\color{Brown}, keywordstyle=\color{Green}\bfseries, texcsstyle=*\color{blue}\bfseries, numbers=none, keepspaces=true, columns=fixed, basewidth=0.5em }

\begin{document}

\makeatletter % option for force page break \lst@Key{pagebreak}f[t]{\lstKV@SetIf{#1}\if@SX@pagebreak} % if pos is 'tb', if force page break \newif\if@SX@pos@tb @SX@pos@tbfalse \newif\if@SX@pos@tb@pagebreak @SX@pos@tb@pagebreakfalse % Defines new position 'tb' \newcommand*\SX@put@tb[3]{% \SX@ResultArea{\linewidth}{#2}\endgraf% @tempdima=\dimexpr\SX@vsep\vskip@tempdima % Code area dropped \global@SX@pos@tbtrue% % Save preset for later rendering \xdef\SX@@explpreset@saved{\SX@@explpreset}% \if@SX@pagebreak\global@SX@pos@tb@pagebreaktrue\fi% }

% patch \SX@put@code@result for code area \g@addto@macro\SX@put@code@result{% \if@SX@pos@tb% \if@SX@pos@tb@pagebreak\clearpage\fi% \begingroup% % Bugfix: prevent custom preset from being overwritten %\expandafter\lstset\expandafter{\SX@@explpreset@saved}% \edef\SX@@explpreset{\SX@@explpreset@saved}% \SX@codeInput% \endgroup% \fi% % Bugfix: Misssing \global %@SX@pos@tbfalse %@SX@pos@tb@pagebreakfalse \global@SX@pos@tbfalse \global@SX@pos@tb@pagebreakfalse } \makeatother

% Width override \begin{LTXexample}[pos=tb, width=\linewidth, pagebreak, style=customlatex] \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX\ \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX\ \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX\ \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX\ \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \LaTeX \end{LTXexample}

\end{document}

The result is shown below:

New Result Image

Original Answer:

showexpl package put the code area and the result area in the same \makebox (See \SX@put@code@result), So \pagebreak[2] inside \SX@put@t won't work when you specify [pos=t].

My solution is to save the code area using \makebox, smuggle it to the global scope and then use it by \usebox. To prevent messing with the existing position setting macros, I named the new position tb for [t]op [b]reakable. Note that you'll need to use it with width=\linewidth because position settings other than t and b will result in half width. Also note that if result area or code area exceeds a page you'll still get a overfull box. Hope the package author will add long code and page break support later.

The MWE is shown below:

\documentclass[12pt,a4paper]{article}
\usepackage{listings}
\usepackage{showexpl}

\begin{document}

\makeatletter % Idea comes from https://tex.stackexchange.com/questions/283373 % Code area box to be saved \newsavebox{\SX@CodeLater} % Defines new position 'tb' \newcommand\SX@put@tb[3]{% \SX@ResultArea{\linewidth}{#2}\endgraf% @tempdima=\dimexpr\SX@vsep\vskip@tempdima % Save code area box and smuggle to global scope \newsavebox{\SX@CodeLaterLocal}% \savebox\SX@CodeLaterLocal{\SX@CodeArea{\linewidth}{#3}}% \global\expandafter\setbox\SX@CodeLater\box\SX@CodeLaterLocal% } \makeatother

% Result only, with width override \begin{LTXexample}[pos=tb, width=\linewidth] Hello, \LaTeX! \end{LTXexample}

% Page break \clearpage

% Use code area box \makeatletter \noindent\usebox{\SX@CodeLater}% \makeatother

\end{document}

The result is shown below:

Original Result Image

Tanimodori
  • 11
  • 4