% \iffalse meta-comment
% SPDX-FileCopyrightText: Copyright (c) 2021-2026 Yegor Bugayenko
% SPDX-License-Identifier: MIT
% \fi

% \CheckSum{0}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}

% \GetFileInfo{docshots.dtx}
% \DoNotIndex{\endgroup,\begingroup,\let,\else,\s,\n,\r,\\,\1,\fi}

% \iffalse
%<*driver>
\ProvidesFile{docshots.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{docshots}
%<*package>
[2026-10-08 0.5.1 TeX Samples Next to Their PDF Snapshots in DTX]
%</package>
%<*driver>
\documentclass{ltxdoc}
\usepackage{lmodern}
\usepackage{fail-fast}
\usepackage{silence}
\WarningFilter{latex}{Marginpar on page}
\usepackage{microtype}
\AddToHook{env/verbatim/begin}{\microtypesetup{protrusion=false}}
\usepackage[dtx]{docshots}
\PassOptionsToPackage{hyperindex=false}{hyperref}
\usepackage{href-ul}
\usepackage{bookmark}
\renewcommand{\RerunFileCheck}[3]{\AddToHook{enddocument/info}{#2}}
\usepackage{xcolor}
\PageIndex
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
  \DocInput{docshots.dtx}
  \PrintChanges
  \PrintIndex
\end{document}
%</driver>
% \fi

% \title{|docshots|: \LaTeX{} Package that Renders \\ \TeX{} Samples Next to Their \\ PDF Snapshots\thanks{The sources are in GitHub at \href{https://github.com/yegor256/docshots}{yegor256/docshots}}}
% \author{Yegor Bugayenko \\ \texttt{yegor256@gmail.com}}
% \date{\filedate, \fileversion}
%
% \maketitle
%
% The \TeX{} processor must be invoked with the |--shell-escape| option,
% and the following must be installed on the host system:
% |pdflatex|,
% \href{https://www.perl.org}{Perl},
% \href{https://www.ghostscript.com}{Ghostscript},
% and \href{https://ctan.org/pkg/pdfcrop}{pdfcrop}.
% The |--shell-escape| option is required because the package launches these
% external programs from within the \TeX{} run in order to compile and crop each snippet.
% The package operates on Windows as well as on Unix, provided these tools are on the |PATH|.

% \section{Introduction}
%
% When demonstrating to the readers of a document how certain \TeX{}
% commands are to be employed, the most cogent approach is to display
% precisely how the entire document will be rendered as a PDF, by means
% of a subprocess (such as |pdflatex|) that performs the rendering.
% To the \href{https://tex.stackexchange.com/questions/661027}{author's
% best} knowledge, no existing package addresses this need; hence the
% present, modest package was devised.

% For instance, the following code:
%\iffalse%
%<*verb>%
%\fi%
\begin{verbatim}
\begin{docshot}
\documentclass{article}
\usepackage{xcolor}
\pagestyle{empty}
\begin{document}
  Hello, {\color{orange}\LaTeX}!
\end{document}
\end{docshot}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% is rendered thus:
% \begin{docshot}
% \documentclass{article}
% \usepackage{xcolor}
% \pagestyle{empty}
% \begin{document}
%   Hello, {\color{orange}\LaTeX}!
% \end{document}
% \end{docshot}

% A more elaborate example follows:
% \begin{docshot}
% \documentclass{article}
% \usepackage{tikz}
% \pagestyle{empty}
% \begin{document}
% \begin{tikzpicture}
% \node [circle,draw] (v0) {$v_0$};
% \node [circle,draw=orange,thick,
%   below right of=v0] (v1) {$v_1$};
% \draw [->] (v0) -- (v1);
% \end{tikzpicture}
% \end{document}
% \end{docshot}

% The body of every |docshot| environment must be a complete, self-contained
% \LaTeX{} document: it begins with |\documentclass|, loads whatever packages it
% requires, and wraps its content in |\begin{document}| and |\end{document}|. The
% body is written verbatim to a separate |.tex| file and compiled on its own, exactly
% as the two examples above demonstrate.

% The figure on the left is produced by a subprocess that executes
% |pdflatex| on the |.tex| content extracted from the source file.
% Once the \TeX{} sources have been successfully processed,
% \href{https://ctan.org/pkg/pdfcrop}{pdfcrop} is invoked to trim the document.

% |pdflatex| is run with the |-interaction=errorstopmode| and |-halt-on-error| options.
% Consequently, \TeX{} processing halts at the first error encountered. The \TeX{}
% log should be consulted to ascertain the cause of any failure; the |log| option,
% described below, copies the full output of |pdflatex| into that log.

% Whenever text rather than a single figure is to be rendered, the
% \href{https://ctan.org/pkg/geometry}{geometry} package is recommended for
% adjusting the page dimensions:
% \begin{docshot}
% \documentclass{article}
% \usepackage[paperwidth=2in,
%   paperheight=2.3in]{geometry}
% \begin{document}
% ``There is no sadder thing than
% a young pessimist, except an old
% pessimist'' --- \emph{Mark Twain}
% \end{document}
% \end{docshot}
% The use of |\pagestyle{empty}|, as in the preceding docshots, is likewise possible.

% \section{Package Options}

% All options listed below are supplied to the package in the usual way, within the
% optional argument of |\usepackage[...]{docshots}|.

% \DescribeMacro{pdflatex}
% The default command-line tool for converting |.tex| into
% |.pdf| is |pdflatex|. This may, however, be altered by means of the |pdflatex| package option,
% for example:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\documentclass{article}
\usepackage[pdflatex=/usr/local/bin/pdflatex]{docshots}
\begin{document}
\begin{docshot}
Hello, world!
\end{docshot}
\end{document}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{gs}
% The default location of Ghostscript is simply |gs| on Unix and |gswin64c| on Windows.
% This may be altered by means of the |gs| package option,
% for example:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[gs=/usr/bin/ghostscript]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{pdfcrop}
% The default location of |pdfcrop| is simply |pdfcrop|.
% This may be altered by means of the |pdfcrop| package option,
% for example:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[pdfcrop=/bin/pdfcrop]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{margin}
% When the rendered PDF is cropped, a margin is preserved around the content. The
% default value may be modified by the |margin| package option:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[margin=10]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{nocrop}
% Cropping may be disabled by means of the |nocrop| option:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[nocrop]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{hspace}
% The horizontal distance between the image and its verbatim \TeX{} source
% may be configured by means of the |hspace| package option:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[hspace=1em]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{left}
% \DescribeMacro{right}
% The default width of the image may be altered by the |left| option, while
% the width of the verbatim \TeX{} source may be adjusted by the |right| option:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[left=2in,right=.5\linewidth]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{snippet}
% By default, the verbatim \TeX{} source is placed to the right of the snapshot.
% The |snippet| option accepts one of three values---|left|, |right|, or
% |none|---to place the source on either side of the snapshot or to suppress it
% entirely, leaving the snapshot alone:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[snippet=left]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{dtx}
% Whenever this package is employed within |.dtx| documentation, the |dtx| package option must be added. Under
% this option, all leading comment symbols (the |%| characters) are removed from the start of each line:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[dtx]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{tmpdir}
% The default location for temporary files is |_docshots|. This may be altered by means of the |tmpdir| option:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[tmpdir=/tmp/foo]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{runs}
% By default, |pdflatex| is invoked but once per docshot. This number may be modified by means of the |runs| package
% option, which proves serviceable when Bib\TeX{} processing is required, for example:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[runs=3]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{small}
% \DescribeMacro{tiny}
% The latitude available for formatting verbatim texts is limited; nevertheless, the font
% may be reduced somewhat by means of the |small| package option, or made considerably
% smaller still by the |tiny| option:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[small]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{log}
% By means of the |log| option, the package writes all available logs into the main \TeX{} log.
% By default, this is not done, and the output of |pdflatex| compilation, for instance, remains hidden.
% The option is employed thus:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[log]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{inputminted}
% By default, the verbatim text is rendered by means of the |\VerbatimInput| command. This
% may be substituted with |\inputminted|
% from the \href{https://ctan.org/pkg/minted}{minted} package, for example:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage{minted}
\setminted[java]{frame=lines,framesep=2mm}
\usepackage[inputminted=java]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{lstinputlisting}
% By default, the verbatim text is rendered by means of the |\VerbatimInput| command. This
% may be substituted with |\lstinputlisting| from the
% \href{https://ctan.org/pkg/listings}{listings} package, for example:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage{listings}
\lstset{basicstyle=\small}
\usepackage[lstinputlisting]{docshots}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \section{Fine-tuning Options}

% \DescribeEnv{docshot}
% \changes{0.6.0}{2026/07/16}{The environment gains an optional argument that carries the per-docshot settings, replacing the docshotSnippet, docshotOptions, docshotAfter, and docshotPrerequisite commands.}
% Every |docshot| environment accepts an optional argument, in which per-docshot
% settings are supplied as a comma-separated list of |key=value| pairs. Four keys
% are recognised: |snippet|, |options|, |after|, and |prerequisite|. Each applies
% solely to the environment that carries it, leaving the defaults intact for the
% docshots that follow:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\begin{docshot}[snippet=left, options={firstline=4}]
...
\end{docshot}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{snippet}
% The |snippet| key overrides the package-wide |snippet| option for a single
% docshot, accepting |left|, |right|, or |none|:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\begin{docshot}[snippet=none]
...
\end{docshot}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{options}
% By default, the verbatim text is rendered by means of the |\VerbatimInput|
% command with no options. Additional options may be supplied through the
% |options| key:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\begin{docshot}[options={firstline=4}]
...
\end{docshot}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{prerequisite}
% Whenever a file is required to be present alongside the |.tex| snippet during
% rendering by |pdflatex|, the |prerequisite| key names a file to be copied from
% the current directory to the temporary directory in which all snippets are
% rendered. The key may be repeated for several files:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\begin{docshot}[prerequisite=duck.jpg]
  \documentclass{article}
  \usepackage{graphicx}
  \pagestyle{empty}
  \begin{document}
    A favoured photograph of a duck:
    \includegraphics[width=2in]{duck.jpg}
  \end{document}
\end{docshot}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{after}
% Should some action be required after each |pdflatex| run of a docshot, the
% |after| key supplies the command to run. For example, when a bibliography is to
% remain available to a snippet and \href{https://ctan.org/pkg/biber}{biber} is
% to be invoked on it in order to process citations:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\begin{docshot}[prerequisite=main.bib, after={biber $2}]
  \documentclass{acmart}
  \usepackage[natbib=true]{biblatex}
  \addbibresource{main.bib}
  \pagestyle{empty}
  \begin{document}
    The book of \citet{knuth1984} is essential reading.
    \printbibliography
  \end{document}
\end{docshot}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% The command supplied to the |after| key receives three arguments at runtime:
% \begin{description}\setlength\itemsep{0em}
% \item[|\$1|] the cycle of |pdflatex| processing (1, 2, ...),
% \item[|\$2|] the hash of the snippet,
% \item[|\$3|] the name of the |.tex| file.
% \end{description}
% |$3| is, in essence, |$2| with an appended |.tex| suffix.

% \StopEventually{}

% \section{Implementation}
% \changes{0.0.1}{2022/10/09}{Initial version}

% First, we include \href{https://ctan.org/pkg/iexec}{iexec}
% in order to execute shell commands, such as |pdflatex| and |pdfcrop|:
%    \begin{macrocode}
\RequirePackage{iexec}
%    \end{macrocode}

% Then, we include \href{https://ctan.org/pkg/fancyvrb}{fancyvrb}
% in order to render verbatim texts:
%    \begin{macrocode}
\RequirePackage{fancyvrb}
%    \end{macrocode}

% Then, we include \href{https://ctan.org/pkg/xcolor}{xcolor}
% in order to make borders gray:
%    \begin{macrocode}
\RequirePackage{xcolor}
%    \end{macrocode}

% Then, we include \href{https://ctan.org/pkg/graphicx}{graphicx}
% in order to be able to use the |\includegraphics| command:
%    \begin{macrocode}
\RequirePackage{graphicx}
%    \end{macrocode}

% Then, we include \href{https://ctan.org/pkg/tikz}{tikz}
% in order to be able to position elements:
%    \begin{macrocode}
\RequirePackage{tikz}
%    \end{macrocode}

% Then, we process package options with the help of \href{https://ctan.org/pkg/pgfopts}{pgfopts}:
% \changes{0.0.4}{2022/10/18}{Package options "lstinputlisting" and "inputminted" introduced to enable printing of verbatim text via either the listings or the minted package.}
% \changes{0.0.5}{2022/10/24}{Package option "log" added, which enables detailed logging via exec. By default, there is no logging at all.}
% \changes{0.2.0}{2022/10/26}{New package option "nocrop" added to allow disabling of "pdfcrop" execution.}
% \changes{0.6.0}{2026/07/16}{Package option "snippet" added, with values "left", "right", and "none", to place the verbatim source on either side of the snapshot or to omit it entirely.}
% We also detect Windows, in order to pick the right default for Ghostscript,
% the right file separator for shell commands (a backslash, since |cmd.exe|
% rejects forward slashes in redirection targets), and an expanding variant of
% the string-replacement command for later use by the |after| key:
% \changes{0.5.0}{2026/07/13}{Windows compatibility: file operations go through Perl, and the "gs" default becomes "gswin64c" on Windows.}
%    \begin{macrocode}
\RequirePackage{pgfopts}
\RequirePackage{ifluatex}
\RequirePackage{ifxetex}
\RequirePackage{expl3}
\newif\ifdocshots@windows
\ExplSyntaxOn
\sys_if_platform_windows:TF{\docshots@windowstrue}{\docshots@windowsfalse}
\cs_generate_variant:Nn \str_replace_all:Nnn { Nne }
\newcommand\docshots@aftercmd[3]{%
  \str_set:Nx \l_tmpa_str { \docshots@after }%
  \str_replace_all:Nne \l_tmpa_str { $1 } { #1 }%
  \str_replace_all:Nne \l_tmpa_str { $2 } { #2 }%
  \str_replace_all:Nne \l_tmpa_str { $3 } { #3 }%
  \cs_set:Npx \docshots@aftersh { \str_use:N \l_tmpa_str }%
}
\ExplSyntaxOff
\ifdocshots@windows
  \def\docshots@gsdefault{gswin64c}%
  \edef\docshots@sep{\@backslashchar}%
\else
  \def\docshots@gsdefault{gs}%
  \def\docshots@sep{/}%
\fi
%    \end{macrocode}
% On Unix we render inside the temporary directory. On Windows we cannot, since
% |cmd.exe| keeps a |cd| in effect after the parentheses close, which would send
% iexec's exit-code file to the wrong place; instead we stay put and point
% |pdflatex| at the directory with |-output-directory|. The |pdflatex| arguments
% keep forward slashes, since \TeX{} reads a backslash as an escape character:
%    \begin{macrocode}
\ifdocshots@windows
  \def\docshots@render{"\docshots@pdflatex"
    -interaction=errorstopmode -halt-on-error -shell-escape
    -output-directory="\docshots@tmpdir/\jobname"
    "\docshots@tmpdir/\jobname/\hash.tex"}%
\else
  \def\docshots@render{cd "\docshots@tmpdir/\jobname" &&
    "\docshots@pdflatex"
    -interaction=errorstopmode -halt-on-error -shell-escape
    \hash.tex}%
\fi
\def\docshots@log{}
\pgfkeys{
  /docshots/.cd,
  dtx/.store in=\docshots@dtx,
  log/.code=\def\docshots@log{log},
  nocrop/.code=\def\docshots@nocrop{},
  lstinputlisting/.store in=\docshots@lstinputlisting,
  inputminted/.store in=\docshots@inputminted,
  tmpdir/.store in=\docshots@tmpdir,
  tmpdir/.default=_docshots\ifxetex-xe\else\ifluatex-lua\fi\fi,
  small/.store in=\docshots@small,
  tiny/.store in=\docshots@tiny,
  runs/.store in=\docshots@runs,
  runs/.default=1,
  pdflatex/.store in=\docshots@pdflatex,
  pdflatex/.default=pdflatex,
  gs/.store in=\docshots@gs,
  gs/.default=\docshots@gsdefault,
  pdfcrop/.store in=\docshots@pdfcrop,
  pdfcrop/.default=pdfcrop,
  margin/.store in=\docshots@margin,
  margin/.default=5,
  hspace/.store in=\docshots@hspace,
  hspace/.default=.05\linewidth,
  left/.store in=\docshots@left,
  left/.default=.3\linewidth,
  right/.store in=\docshots@right,
  right/.default=.55\linewidth,
  snippet/.store in=\docshots@snippet,
  snippet/.default=right,
  tmpdir,pdflatex,gs,pdfcrop,margin,hspace,left,right,snippet,runs
}
\ProcessPgfOptions{/docshots}
%    \end{macrocode}
% We remember the three admissible values of the |snippet| option, so that a
% docshot may later compare its own placement against them:
%    \begin{macrocode}
\def\docshots@snippetleft{left}
\def\docshots@snippetright{right}
\def\docshots@snippetnone{none}
%    \end{macrocode}

% Then, we print the version of |pdflatex| to the \TeX{} log:
%    \begin{macrocode}
\iexec[\docshots@log,quiet]{"\docshots@pdflatex" --version}%
%    \end{macrocode}

% Then, we print the version of \href{https://ctan.org/pkg/pdfcrop}{pdfcrop} to the \TeX{} log:
%    \begin{macrocode}
\ifdefined\docshots@nocrop\else%
  \iexec[\docshots@log,quiet]{"\docshots@pdfcrop" --version}%
\fi%
%    \end{macrocode}

% Then, we print the version of |ghostscript| to the \TeX{} log, ignoring a
% failure, since Ghostscript is not strictly required for rendering:
%    \begin{macrocode}
\iexec[\docshots@log,quiet,ignore]{"\docshots@gs" --version}%
%    \end{macrocode}

% Then, we make a directory where all temporary files will be kept. We use
% Perl instead of |mkdir|, so that the code works on Windows too:
%    \begin{macrocode}
\iexec[null]{perl -MFile::Path=make_path -e "make_path(shift)"
  "\docshots@tmpdir/\jobname"}%
%    \end{macrocode}

% \begin{macro}{\docshots@mdfive}
% \changes{0.1.1}{2022/10/26}{New supplementary command added to calculate MD5 sum of a file.}
% Then, we define a command for MD5 hash calculating of a file, with
% the help of \href{https://ctan.org/pkg/pdftexcmds}{pdftexcmds}:
%    \begin{macrocode}
\RequirePackage{pdftexcmds}
\makeatletter
\newcommand\docshots@mdfive[1]{\pdf@filemdfivesum{#1}}
\makeatother
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\docshots@prereq}
% \changes{0.0.3}{2022/10/14}{New supplementary command added to copy prerequisite files into the rendering directory.}
% Then, we define an internal command that copies a prerequisite file from the
% current directory into the temporary one, so that |pdflatex| finds it during
% rendering:
%    \begin{macrocode}
\makeatletter
\newcommand\docshots@prereq[1]{%
  \iexec[\docshots@log,quiet]{perl -MFile::Copy -e "copy(shift,shift) or die q(cannot copy)"
    "#1" "\docshots@tmpdir/\jobname/#1"}%
  \message{docshots: File '#1' copied to
    '\docshots@tmpdir/\jobname/#1'^^J}%
}
%    \end{macrocode}
% \end{macro}

% Then, we register the keys accepted by the optional argument of the |docshot|
% environment. Each stores into the same internal macro that the environment
% reads while rendering:
%    \begin{macrocode}
\pgfkeys{
  /docshots/shot/.cd,
  snippet/.store in=\docshots@thissnippet,
  options/.store in=\docshots@opts,
  after/.code=\edef\docshots@after{\detokenize{#1}},
  prerequisite/.code=\docshots@prereq{#1},
}
%    \end{macrocode}

% Then, we define the reader of that optional argument. Before peeking for the
% |[|, we make the end-of-line active, exactly as |fancyvrb| does: an absent
% optional argument then leaves the raw end-of-line in place, which |fancyvrb|
% needs in order to find where the verbatim body begins. A plain |\@ifnextchar|
% would skip that end-of-line and mislead the verbatim scanner:
%    \begin{macrocode}
\def\docshots@shot{%
  \catcode`\^^M=\active%
  \@ifnextchar[%]
    {\catcode`\^^M=5 \docshots@grab}%
    {\catcode`\^^M=5 \docshots@begin}}
\def\docshots@grab[#1]{\pgfkeys{/docshots/shot/.cd,#1}\docshots@begin}
\def\docshots@begin{\VerbatimEnvironment\begin{VerbatimOut}
  {\docshots@tmpdir/\jobname/docshots-temp.tex}}
\makeatother
%    \end{macrocode}

% \begin{macro}{docshot}
% \changes{0.6.0}{2026/07/16}{The environment gains an optional argument carrying per-docshot settings; the commands docshotSnippet, docshotOptions, docshotAfter, and docshotPrerequisite are removed in its favour.}
% Then, we define the |docshot| environment. Its optional argument carries the
% per-docshot settings (|snippet|, |options|, |after|, and |prerequisite|),
% which we parse under normal catcodes, before the body is captured verbatim.
% The defaults are set locally, so that each docshot starts afresh and no
% setting leaks into the next:
%    \begin{macrocode}
\makeatletter
\newenvironment{docshot}
{\let\docshots@thissnippet\docshots@snippet%
 \def\docshots@opts{}%
 \docshots@shot}
{\end{VerbatimOut}%
%    \end{macrocode}
% If we are in |dtx| mode, leading percent characters must be removed. The
% substitution stays line-oriented and anchored with |\A|, since the whole-file
% form needed the caret and vertical-bar metacharacters that |cmd.exe| reads as
% an escape and a pipe, mangling the command on Windows:
% \changes{0.3.1}{2022/11/20}{A bug fixed, now handling of leading percentage symbols is done right.}
% \changes{0.5.1}{2026/07/16}{Leading percent stripping avoids the "^" and "|" metacharacters, which cmd.exe mangled on Windows.}
%    \begin{macrocode}
  \ifdefined\docshots@dtx%
    \iexec[null]{perl -i -pe "s/\\A\\x{25} ?//"
      \docshots@tmpdir/\jobname/docshots-temp.tex}%
  \fi%
%    \end{macrocode}
% We calculate MD5 hashsum of the file content:
%    \begin{macrocode}
  \def\hash{\docshots@mdfive{\docshots@tmpdir/\jobname/docshots-temp.tex}}%
%    \end{macrocode}
% If the PDF with the required name already exists, we ignore this step.
% Otherwise, we copy |docshots-temp.tex| into a new file and run |pdflatex|:
% \changes{0.1.0}{2022/10/26}{The output is saved to a hash-named file, for better uniqueness of temporary files.}
% \changes{0.4.0}{2022/11/29}{Now, \TeX output has a log message with the number of the line in the source file, which we render.}
%    \begin{macrocode}
  \IfFileExists{\docshots@tmpdir/\jobname/\hash.pdf}
    {\message{docshots: Won't render,
      the PDF '\docshots@tmpdir/\jobname/\hash.pdf' already exists^^J}}
    {\iexec[\docshots@log,quiet]{perl -MFile::Copy -e "copy(shift,shift) or die q(cannot copy)"
      "\docshots@tmpdir/\jobname/docshots-temp.tex"
      "\docshots@tmpdir/\jobname/\hash.tex"}%
    \message{docshots: rendering at line no. \the\inputlineno^^J}%
    \foreach \n in {1,...,\docshots@runs}{%
      \iexec[\docshots@log,
        stdout=\docshots@tmpdir\docshots@sep\jobname\docshots@sep\hash.stdout,
        exit=\docshots@tmpdir\docshots@sep\jobname\docshots@sep\hash.ret,
        quiet,trace]{\docshots@render}%
      \ifnum\n=1\else%
        \message{docshots: pdflatex run no.\n^^J}%
      \fi%
%    \end{macrocode}
% If a post-processing command was registered by the |after| key, we substitute
% its |$1|, |$2|, and |$3| placeholders and execute it. There is no shell script
% and no |chmod|, so the mechanism works on Windows too:
%    \begin{macrocode}
      \ifdefined\docshots@after%
        \begingroup%
          \docshots@aftercmd{\n}{\hash}{\hash.tex}%
          \iexec[\docshots@log,quiet]{cd "\docshots@tmpdir\docshots@sep\jobname" &&
            \docshots@aftersh}%
        \endgroup%
      \fi}}%
%    \end{macrocode}
% If a cropped version of the PDF with the required name already exists, we ignore this step.
% Otherwise, we ask |pdfcrop| to crop the PDF:
%    \begin{macrocode}
  \IfFileExists{\docshots@tmpdir/\jobname/\hash.crop.pdf}
    {\message{docshots: Won't pdfcrop,
      the PDF '\docshots@tmpdir/\jobname/\hash.crop.pdf'
      already exists^^J}}
    {\ifdefined\docshots@nocrop
      \iexec[\docshots@log,quiet]{perl -MFile::Copy -e "copy(shift,shift) or die q(cannot copy)"
        "\docshots@tmpdir/\jobname/\hash.pdf"
        "\docshots@tmpdir/\jobname/\hash.crop.pdf"}%
      \else%
      \iexec[\docshots@log,quiet]{"\docshots@pdfcrop"
        --gscmd "\docshots@gs"
        --margins 0
        "\docshots@tmpdir/\jobname/\hash.pdf"
        "\docshots@tmpdir/\jobname/\hash.crop.pdf"}%
      \fi}%
  \message{docshots: the PDF is ready from line no. \the\inputlineno^^J}%
%    \end{macrocode}
% Finally, we render the content. The placement was resolved by the optional
% argument, defaulting to the package-wide |snippet| setting. The snapshot is a
% framed image, and the source is a top-aligned minipage; we keep each in a
% macro of its own, so that either may precede the other:
%    \begin{macrocode}
  \begingroup%
  \par%
  \def\docshots@image{\tikz[baseline=(a.north)]
    \node (a) [draw=gray,inner sep=\docshots@margin,
      line width=.2pt]
    {\includegraphics[width=\docshots@left]
      {\docshots@tmpdir/\jobname/\hash.crop.pdf}};}%
  \def\docshots@code{\begin{minipage}[t]{\docshots@right}%
    \vspace{0pt}%
    \ifdefined\docshots@lstinputlisting%
      \ifdefined\docshots@opts%
        \expandafter\lstset\expandafter{\docshots@opts}%
      \fi%
      \lstinputlisting{\docshots@tmpdir/\jobname/\hash.tex}%
    \else\ifdefined\docshots@inputminted%
      \expandafter\inputminted\expandafter[\docshots@opts]
        {\docshots@inputminted}
        {\docshots@tmpdir/\jobname/\hash.tex}%
    \else%
      \fvset{numbers=left,numbersep=3pt}%
      \fvset{frame=leftline,framerule=.2pt,rulecolor=\color{gray}}%
      \fvset{samepage=true}%
      \fvset{commandchars=none}%
      \fvset{baselinestretch=1}%
      \ifdefined\docshots@small%
        \fvset{fontsize=\small}%
      \fi%
      \ifdefined\docshots@tiny%
        \fvset{fontsize=\scriptsize}%
      \fi%
      \ifdefined\docshots@opts%
        \expandafter\fvset\expandafter{\docshots@opts}%
      \fi%
      \edef\FancyVerbHFuzz{\number\maxdimen sp}%
      \VerbatimInput{\docshots@tmpdir/\jobname/\hash.tex}%
    \fi\fi%
    \vspace{0pt}%
  \end{minipage}}%
%    \end{macrocode}
% According to the |snippet| setting, the source stands to the left of the
% snapshot, to its right, or is omitted altogether:
%    \begin{macrocode}
  \ifx\docshots@thissnippet\docshots@snippetnone%
    \docshots@image%
  \else\ifx\docshots@thissnippet\docshots@snippetleft%
    \docshots@code\hspace{\docshots@hspace}\docshots@image%
  \else\ifx\docshots@thissnippet\docshots@snippetright%
    \docshots@image\hspace{\docshots@hspace}\docshots@code%
  \else%
    \PackageError{docshots}{Unknown snippet
      '\docshots@thissnippet', use left, right, or none}{}%
  \fi\fi\fi%
  \par%
  \endgroup%
}
\makeatother
%    \end{macrocode}
% \end{macro}

%    \begin{macrocode}
\endinput
%    \end{macrocode}

% \Finale

%\clearpage

%\PrintChanges
%\clearpage
%\PrintIndex
