% \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{ffcode.dtx}
% \DoNotIndex{\endgroup,\begingroup,\let,\else,\fi,\newcommand,\newenvironment}

% \iffalse
%<*driver>
\ProvidesFile{ffcode.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{ffcode}
%<*package>
[2026-05-01 0.11.1 Fixed Font Code]
%</package>
%<*driver>
\documentclass{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage{paratype}
\usepackage{microtype}
\AddToHook{env/verbatim/begin}{\microtypesetup{protrusion=false}}
\usepackage{href-ul}
\usepackage{ffcode}
\usepackage{amsmath}
\usepackage{multicol}
\usepackage{xcolor}
\usepackage[dtx,runs=2]{docshots}
\PageIndex
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
	\DocInput{ffcode.dtx}
	\PrintChanges
	\PrintIndex
\end{document}
%</driver>
% \fi

% \title{|ffcode|: \LaTeX{} Package \\ for Fixed-Font Code Blocks\thanks{The sources are in GitHub at \href{https://github.com/yegor256/ffcode}{yegor256/ffcode}}}
% \author{Yegor Bugayenko \\ \texttt{yegor256@gmail.com}}
% \date{\filedate, \fileversion}
%
% \maketitle
%
% \section{Introduction}
%
% This package helps you write source code in your articles
% and make sure it looks nice. Install it from CTAN and then
% use like this (pay attention to |\ff| command
% and |ffcode| environment):
% \begin{docshot}
% \documentclass{article}
% \usepackage{ffcode}
% \pagestyle{empty}
% \begin{document}
% The function |fibo()| is recursive:
% \begin{ffcode}
% int fibo(int n) {
%   if (n < 2) {
%     return n; (*@ \label{ln:ret} @*)
%   }
%   return fibo(n-1)+fibo(n-2);
% }
% \end{ffcode}
% Line no.~\ref{ln:ret} returns \ff{n}
% and terminates it.
% \end{document}
% \end{docshot}

% \DescribeMacro{\ffinput}
% There is also an |\ffinput| command that reads the content from a file
% and places it into the document, formatted exactly the same way as
% it would be if the |ffcode| environment were used. It may be useful
% to use |ffsave| environment first, which acts exactly like the |ffcode|
% environment but doesn't print the content. It saves it to a file instead,
% which may later be used by the |\ffinput| command.

% \section{Package Options}

% \DescribeMacro{samepage}
% If you want to avoid page breaks inside |ffcode| blocks, use the |samepage|
% package option.

% \DescribeMacro{noframes}
% If you want to omit the light gray frames around |\ff|
% texts, use the package option |noframes|.

% \DescribeMacro{nobars}
% To omit the vertical gray bar at the left side of each snippet,
% use the |nobars| option of the package.

% \DescribeMacro{nonumbers}
% To omit the line numbers, use the |nonumbers| option of the package.

% \DescribeMacro{nocn}
% By default, the numbering is continuous: line numbers start at the
% first snippet and increment until the end of the document. If you
% want them to start from one at each snippet, use |nocn|
% (stands for ``no continuous numbering'')
% option of the package.

% \DescribeMacro{bold}
% You can make your |\ff| pieces look bolder than usual, which may be pretty convenient for some document classes
% (pay attention to the usage of the \href{https://ctan.org/pkg/lmodern}{lmodern} package, without it the bold won't work, as explained \href{https://tex.stackexchange.com/a/215489/1449}{here}):
% \docshotOptions{firstline=4,lastline=10}
% \begin{docshot}
% \documentclass{article}
% \usepackage[paperwidth=3in]{geometry}
% \pagestyle{empty}
% \usepackage{lmodern}
% \usepackage[bold,noframes]{ffcode}
% \begin{document}
% Sometimes it's necessary to make
% code pieces look bolder, like
% the |fibo()| function in this text.
% \end{document}
% \end{docshot}

% \DescribeMacro{sf}
% You can change the font family of |\ff| pieces to |\sffamily|:
% \docshotOptions{firstline=4,lastline=10}
% \begin{docshot}
% \documentclass{article}
% \usepackage[paperwidth=3in]{geometry}
% \pagestyle{empty}
% \usepackage[sf,bold,noframes]{ffcode}
% \begin{document}
% Sometimes you may want them to look
% not strictly fixed-width, but more
% elegant, like the \emph{|fibo()|}
% here.
% \end{document}
% \end{docshot}

% \section{Typesetting}

% By the way, the package correctly formats low-height texts, for example, just
% a dot: \ff{.}

% A pair of vertical lines decorates a TeX command inside the snippet.
% If you want to print a single vertical line, use this:
% ``\verb+|\char`\\vert|+''.

% The command |\ff| behaves differently in math mode --- it doesn't
% add gray frames:
% \docshotOptions{firstline=6,lastline=8}
% \begin{docshot}
% \documentclass{article}
% \usepackage{ffcode}
% \usepackage{mathtools}
% \pagestyle{empty}
% \begin{document}
% \begin{equation*}
% x = \int_{|home|}^N f(x).
% \end{equation*}
% \end{document}
% \end{docshot}

% \section{Line Highlighting}

% You can highlight some lines in your |ffcode| environment,
% or can use any other additional configuration parameters from
% |fancyvrb| and |fvextra| packages:
% \docshotOptions{firstline=6,lastline=13}
% \begin{docshot}
% \documentclass{article}
% \usepackage[paperwidth=3in]{geometry}
% \usepackage{ffcode}
% \pagestyle{empty}
% \begin{document}
% \begin{ffcode}[backgroundcolor=\color{gray!20}]
% while (true) {
%   (*@\textcolor{red}{print("Hi!")}@*)
%   print("Enter your name:")
%   scan(x)
%   print("Your name | " + x)
% }
% \end{ffcode}
% \end{document}
% \end{docshot}

% Using this second argument of |ffcode|,
% you can provide any other options from the |listings| package to the
% snippet.

% \StopEventually{}

% \section{Implementation}
% \changes{v0.1.0}{2021/06/10}{Initial version}

% First, we parse package options with the help of
% \href{https://ctan.org/pkg/pgfopts}{pgfopts} package:
% \changes{v0.2.0}{2021/06/13}{Package options \texttt{nonumbers} and \texttt{noframes} added.}
% \changes{v0.3.0}{2021/09/07}{Package option \texttt{nocn} added.}
% \changes{v0.4.0}{2022/01/09}{Package option \texttt{nobars} added.}
% \changes{v0.6.0}{2021/11/14}{We use \texttt{pgfopts} instead of \texttt{xkeyval}.}
% \changes{v0.6.0}{2021/11/14}{Package option \texttt{novert} added, to disable redefinition of vertical bar.}
% \changes{v0.7.0}{2021/11/28}{Package option \texttt{bold} added, to make all \texttt{\char`\\ff} pieces look bolder than usual.}
% \changes{v0.7.0}{2021/11/28}{Package option \texttt{sf} added, to make all \texttt{\char`\\ff} pieces be printed as \texttt{\char`\\sffamily}.}
% \changes{v0.9.2}{2024/02/04}{All lengths and sizes are in "em" instead of "pt".}
% \changes{v0.10.0}{2025/01/02}{Package option \texttt{samepage} added, to keep all \texttt{ffcode} blocks on the same page.}
% \changes{v0.11.1}{2026/05/01}{Reserve \texttt{xleftmargin} for line numbers so they sit inside the column instead of protruding into the page margin.}
%    \begin{macrocode}
\RequirePackage{pgfopts}
\pgfkeys{
  /ff/.cd,
  bold/.store in=\ff@bold,
  sf/.store in=\ff@sf,
  samepage/.store in=\ff@samepage,
  noframes/.store in=\ff@noframes,
  nonumbers/.store in=\ff@nonumbers,
  nobars/.store in=\ff@nobars,
  novert/.store in=\ff@novert,
  nocn/.store in=\ff@nocn,
}
\ProcessPgfPackageOptions{/ff}
%    \end{macrocode}

% Then, we include the \href{https://ctan.org/pkg/xcolor}{xcolor} package:
%    \begin{macrocode}
\RequirePackage{xcolor}
%    \end{macrocode}

% Then, we configure the \href{https://ctan.org/pkg/listings}{listings} package:
% \changes{v0.9.0}{2024/01/09}{The \texttt{minted} package is replaced by the \texttt{listings} package.}
%    \begin{macrocode}
\RequirePackage{listings}
\makeatletter
% See \href{https://tex.stackexchange.com/questions/706858}{the explanation}:
\lst@AddToHook{Init}{\setlength{\lineskip}{0pt}}
\makeatother
%    \end{macrocode}

% Then, we define a supplementary command \texttt{\char`\\ff@set}:
% \changes{v0.10.2}{2025/07/06}{We started to use \texttt{keepspaces} in order to guarantee correct visual render of multi-spaced content.}
%    \begin{macrocode}
\makeatletter
\newcommand\ff@set[1]{
  \lstset{breaklines}
  \lstset{escapeinside={(*@}{@*)}}
  \lstset{basicstyle={\ttfamily}}
  \lstset{columns=fullflexible}
  \lstset{keepspaces=true}
  \ifdefined\ff@nonumbers\else
    \lstset{numbers=left,numbersep=.8em,numberstyle={\tiny\sffamily\color{gray}},xleftmargin=2.5em}
  \fi
  \ifdefined\ff@nobars\else
    \lstset{frame=leftline,framerule=.05em,rulecolor={\color{gray}}}
  \fi
  \ifdefined\ff@nocn\else
    \lstset{firstnumber=last}
  \fi
  \lstset{#1}
}
\makeatother
%    \end{macrocode}

% \begin{macro}{ffcode}
% Then, we define the |ffcode| environment and its supplementary |ffcode*| counterpart:
%    \begin{macrocode}
\makeatletter
\lstnewenvironment{ffcode}[1][]
  {\ff@set{#1}\ifdefined\ff@samepage\noindent\minipage{\linewidth}\fi}
  {\ifdefined\ff@samepage\endminipage\fi}
\makeatother
%    \end{macrocode}
% \end{macro}

% \begin{macro}{ffinput}
% Then, we define the \texttt{\char`\\ffinput} command:
% \changes{v0.10.0}{2024/12/29}{The \texttt{\char`\\ffinput} command added.}
%    \begin{macrocode}
\makeatletter
\newcommand\ffinput[2][]{%
  \ff@set{#1}%
  \ifdefined\ff@samepage\noindent\minipage{\linewidth}\fi%
  \lstinputlisting[#1]{#2}%
  \ifdefined\ff@samepage\endminipage\fi%
}
\makeatother
%    \end{macrocode}
% \end{macro}

% \begin{macro}{ffsave}
% Then, we define the \texttt{ffsave} environment:
% \changes{v0.11.0}{2025/07/06}{The \texttt{ffsave} environment added.}
%    \begin{macrocode}
\RequirePackage{fancyvrb}
\newenvironment{ffsave}[1][ffsave.txt]
  {\VerbatimEnvironment\begin{VerbatimOut}{#1}}
  {\end{VerbatimOut}}
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\ff@print}
% Then, we define a supplementary macro |\ff@print|:
% \changes{v0.5.1}{2022/10/30}{Now, the command \texttt{ff} ignores italic and bold and always prints \texttt{\char`\\texttt} as it should be.}
%    \begin{macrocode}
\makeatletter
\newcommand\ff@print[1]{%
  \textnormal{%
    \ifdefined\ff@sf\sffamily\else\ttfamily\fi%
    \ifdefined\ff@bold\fontseries{b}\selectfont\fi%
    #1%
  }%
}
\makeatother
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\ff@rule}
% Then, we define supplementary command |\ff@rule|:
%    \begin{macrocode}
\makeatletter\newcommand\ff@rule
  {\vrule height 0.6em depth 0.1em width 0em}
\makeatother
%    \end{macrocode}
% \end{macro}

% \begin{macro}{tcolorbox}
% Then, we use \href{https://ctan.org/pkg/tcolorbox}{tcolorbox} to define |\ff@box|
% command for a gray box around verbatim text block:
%    \begin{macrocode}
\makeatletter
\ifdefined\ff@noframes\else
  \RequirePackage{tcolorbox}
  \newtcbox\ff@box{nobeforeafter,colframe=gray!80!white,
    colback=gray!5!white,boxrule=0.01em,arc=0.1em,
    boxsep=0.12em,left=0.05em,right=0.05em,top=0.02em,bottom=0.02em,
    tcbox raise base}
\fi
\makeatother
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\ff@x}
% Then, we define |\ff@x| internal command for printing a piece of fixed-width-font text:
%    \begin{macrocode}
\makeatletter
\NewDocumentCommand\ff@x{v}{\ff{#1}}
\makeatother
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\ff}
% \changes{v0.8.0}{2022/12/01}{The \texttt{\char`\\ff} command is now a normal command, not verbatim.}
% Then, we define |\ff| macro:
%    \begin{macrocode}
\makeatletter
\newcommand\ff[1]{%
  \ifdefined\ff@noframes%
    \ff@rule\ff@print{#1}%
  \else%
    \relax\ifmmode%
      \ff@rule\ff@print{#1}%
    \else%
      \ff@box{\ff@rule\ff@print{#1}}%
    \fi%
  \fi%
}
\makeatother
%    \end{macrocode}
% \end{macro}

% \begin{macro}{novert}
% Finally, we let vertical bars work similar to |\ff|, as suggested
% \href{https://tex.stackexchange.com/a/665105/1449}{here}
% and \href{https://tex.stackexchange.com/a/665303/1449}{here}
% (unless |novert| package option is used):
%    \begin{macrocode}
\makeatletter\ifdefined\ff@novert\else
  \catcode`\|\active
  \AtBeginDocument{\catcode`\|\active\protected\def|{\ff@x|}}
  \catcode`\| 12 %
\fi\makeatother
%    \end{macrocode}
% \end{macro}

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

% \Finale

%\clearpage
%
%\PrintChanges
%\clearpage
%\PrintIndex
