% \iffalse
%
%% File l3dosctrip.dtx
%
% Copyright (C) 2012,2014-2020 The LaTeX3 Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version.  The latest version
% of this license is in the file
%
%    https://www.latex-project.org/lppl.txt
%
% This file is part of the "l3kernel bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% -----------------------------------------------------------------------
%
% The development version of the bundle can be found at
%
%    https://github.com/latex3/latex3
%
% for those people who are interested.
%
%<*driver|program>
%</driver|program>
%<*driver>
% The same approach as used in \textsf{DocStrip}: if \cs{documentclass}
% is undefined then skip the driver, allowing the file to be used to extract
% \texttt{l3docstrip.tex} from \texttt{l3docstrip.dtx} directly. This works
% as the \cs{fi} is only seen if \LaTeX{} is not in use. The odd \cs{jobname}
% business allows the extraction to work with \LaTeX{} provided an appropriate
% \texttt{.ins} file is set up.
%<*gobble>
\ifx\jobname\relax\let\documentclass\undefined\fi
\ifx\documentclass\undefined
\else \csname fi\endcsname
%</gobble>
  \def\filename{docstrip.dtx}
  \documentclass[full,kernel]{l3doc}
  \ExplSyntaxOn
  \cs_set_eq:NN \__codedoc_replace_at_at:N \use_none:n
  \ExplSyntaxOff
  \begin{document}
    \DocInput{\jobname.dtx}
  \end{document}
%<*gobble>
\fi
%</gobble>
%</driver>
% \fi
%
% \title{^^A
%   The \pkg{l3docstrip} package\\ Code extraction and manipulation^^A
% }
%
% \author{^^A
%  The \LaTeX3 Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Released 2020-06-03}
%
% \maketitle
%
% \begin{documentation}
%
% \section{Extending \textsf{DocStrip}}
%
% The \pkg{l3docstrip} module adds \LaTeX3 extensions to the \textsf{DocStrip}
% program for extracting code from \texttt{.dtx}. As such, this documentation
% should be read along with that for \textsf{DocStrip}.
%
% \section{Internal functions and variables}
%
% An important consideration for \LaTeX3 development is separating out public
% and internal functions. Functions and variables which are private to one
% module should not be used or modified by any other module. As \TeX{} does
% not have any formal namespacing system, this requires a convention for
% indicating which functions in a code-level module are public and which are
% private.
%
% Using \pkg{l3docstrip} allows internal functions to be indicated using a
% \enquote{two part} system. Within the \texttt{.dtx} file, internal functions
% may be indicated using |@@| in place of the module name, for example
% \begin{verbatim}
%    \cs_new_protected:Npn \@@_some_function:nn #1#2
%      {
%        % Some code here
%      }
%    \tl_new:N \l_@@_internal_tl
% \end{verbatim}
%
% To extract the code using \pkg{l3docstrip}, the \enquote{guard} concept
% used by \textsf{DocStrip} is extended by introduction of the syntax
% \texttt{\%<@@=\meta{module}>}. The \meta{module} name then replaces
% the |@@| when the code is extracted, so that
% \begin{verbatim}
%   %<*package>
%   %<@@=foo>
%   \cs_new_protected:Npn \@@_some_function:nn #1#2
%      {
%        % Some code here
%      }
%   \tl_new:N \l_@@_internal_tl
%   %</package>
% \end{verbatim}
% is extracted as
% \begin{verbatim}
%   \cs_new_protected:Npn \__foo_some_function:nn #1#2
%      {
%        % Some code here
%      }
%   \tl_new:N \l__foo_internal_tl
% \end{verbatim}
% where the |__| indicates that the functions and variables are internal
% to the \texttt{foo} module.
%
% Use |@@@@| to obtain |@@| in the output (|@@@@@| to get |@@@|).  For
% longer pieces of code the replacement can be completely suppressed by
% giving an empty module name, namely using the syntax \texttt{\%<@@=>}.
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3docstrip} implementation}
%
%    \begin{macrocode}
%<*program>
%    \end{macrocode}
%
% We start by loading the existing \textsf{DocStrip} code using the \TeX{}
% input convention.
%    \begin{macrocode}
\input docstrip %
%    \end{macrocode}
%
% \begin{macro}{\checkOption}
%   The \cs{checkOption} macro is defined by \textsf{DocStrip} and is redefined
%   here to accommodate the new \texttt{\%<@} syntax.
%
%   When the macros that process a line have found that the line starts with
%   \enquote{\texttt{\%<}}, a guard line has been encountered. The first
%   character of a guard can be an asterisk (\texttt{*}), a slash (\texttt{/}),
%   a plus (\texttt{+}), a minus (\texttt{-}), a less-than sign (\texttt{<})
%   starting verbatim mode, a commercial at (\texttt{@}) or any other character
%   that can be found in an option name. This means that we have to peek at the
%   next token and decide what kind of guard we have. We reinsert |#1| as it
%   may be needed by \cs{doOption}.
%    \begin{macrocode}
\def\checkOption<#1{%
  \ifcase
    \ifx*#10\else \ifx/#11\else
    \ifx+#12\else \ifx-#13\else
    \ifx<#14\else \ifx @#15\else 6\fi\fi\fi\fi\fi\fi\relax
  \expandafter\starOption\or
  \expandafter\slashOption\or
  \expandafter\plusOption\or
  \expandafter\minusOption\or
  \expandafter\verbOption\or
  \expandafter\moduleOption\or
  \expandafter\doOption\fi
  #1%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\moduleOption}
%   In the case where the line starts |%<@|: the defined syntax requires that
%   this continues to |%<@@=|. At the moment, we assume that the syntax is
%   correct and |#1| here is the module name for substitution into any
%   internal functions in the extracted material.
%    \begin{macrocode}
\def\moduleOption @@=#1>#2\endLine{%
  \maybeMsg{<@@=#1>}%
  \prepareActiveModule{#1}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\prepareActiveModule}
% \begin{macro}{\replaceModuleInLine}
%   Here, we set up to do the search-and-replace when doing the extraction.
%   The argument (|#1|) is the replacement text to use, or if empty an
%   indicator that no replacement should be done. The search material is
%   one of |__@@|, |_@@| or |@@|, done in order such that all three end
%   up the same in the output. The string |@@@@| is hidden from these
%   replacements by temporarily turning it into a pair of letters with
%   different category codes, not produced by \pkg{docstrip}; this allows to
%   get |@@| in the output. The replacement function is initialised as a
%   do-nothing for the case where |%<@@=| is never seen.
%    \begin{macrocode}
\begingroup
  \catcode`\_ = 12 %
  \long\gdef\prepareActiveModule#1{%
    \ifx\relax#1\relax
       \let\replaceModuleInLine\empty
    \else
      \edef\replaceModuleInLine{%
        \noexpand\replaceAllIn\noexpand\inLine{@@@@}{\string aa}%
        \noexpand\replaceAllIn\noexpand\inLine{__@@}{__#1}%
        \noexpand\replaceAllIn\noexpand\inLine{_@@}{__#1}%
        \noexpand\replaceAllIn\noexpand\inLine{@@}{__#1}%
        \noexpand\replaceAllIn\noexpand\inLine{\string aa}{@@}%
      }%
    \fi
  }
\endgroup
\let\replaceModuleInLine\empty
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\replaceAllIn}
% \begin{macro}{\replaceAllInAuxI}
% \begin{macro}{\replaceAllInAuxII}
% \begin{macro}{\replaceAllInAuxIII}
%   The code here is a simple search-and-replace routine for a macro |#1|,
%   replacing |#2| by |#3|. As set up here, there is an assumption that nothing
%   is going to be expandable, which is reasonable as \pkg{l3docstrip} deals
%   with \enquote{string} material.
%    \begin{macrocode}
\long\def\replaceAllIn#1#2#3{%
  \long\def\tempa##1##2#2{%
    ##2\qMark\replaceAllInAuxIII#3##1%
  }%
  \edef#1{\expandafter\replaceAllInAuxI#1\qMark#2\qStop}%
}
\def\replaceAllInAuxI{%
  \expandafter\replaceAllInAuxII\tempa\replaceAllInAuxI\empty
}
\long\def\replaceAllInAuxII#1\qMark#2{#1}
\long\def\replaceAllInAuxIII#1\qStop{}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\normalLine}
%   The \cs{normalLine} macro is present in \textsf{DocStrip} but is modified
%   here to include the search-and-replace macro \cs{replaceModuleInLine}. The
%   macro \cs{normalLine} writes its argument (which has to be delimited with
%   |\endLine|) on all active output files, i.e.~those with off-counters equal
%   to zero. The counter \cs{codeLinesPassed} is incremented by~$1$ for
%   statistics (the guards for this used in \textsf{DocStrip} are retained).
%    \begin{macrocode}
\def\normalLine#1\endLine{%
%<*stats>
  \advance\codeLinesPassed\@ne
%</stats>
  \maybeMsg{.}%
  \def\inLine{#1}%
  \replaceModuleInLine
  \let\do\putline@do
  \activefiles
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\doOption}
%   As \textsf{DocStrip} processes each line, a line starting with |%<| triggers (via \cs{checkOption} above) a look-ahead to establish the type of guard encountered.
%   Of the branching possibilities, if we ignore the deprecated |+| and |-| and choose to do no replacement for the special verbatim mode, the only branch that we need to alter is that for a single-line guard such as\\ |    %<stats> ...stats-only code to include...|.
%   The original definition of \cs{doOption} did not use \cs{inLine} but I believe we're safe to do so.
%    \begin{macrocode}
\def\doOption#1>#2\endLine{%
  \maybeMsg{<#1 . >}%
  \Evaluate{#1}%
  \def\do##1##2##3{%
    \if1\Expr{##2}%
      \def\inLine{#2}%
      \replaceModuleInLine
      \StreamPut##1{\inLine}%
    \fi
  }%
  \activefiles
}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</program>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
