% \iffalse meta-comment
% !TEX program = pdfLaTeX
%
% DO NOT REMOVE THE MARK MANUALLY (used in l3build) -> %
%
%<*internal>
\iffalse
%</internal>
%<*internal>
\fi
\begingroup
  \def\nameofLaTeXe{LaTeX2e}
\expandafter\endgroup\ifx\fmtname\nameofLaTeXe\else
\csname fi\endcsname
%</internal>
%<*install>
\input docstrip
\keepsilent
\askforoverwritefalse
\preamble

    Copyright (C) 2024 by HUANG Yuxi <useclass@hyxi.dev>

    This work may be distributed and/or modified under the
    conditions of the LaTeX Project Public License, either
    version 1.3c of this license or (at your option) any later
    version. This version of this license is in
       https://www.latex-project.org/lppl/lppl-1-3c.txt
    and the latest version of this license is in
       https://www.latex-project.org/lppl.txt
    and version 1.3c or later is part of all distributions of LaTeX
    version 2008 or later.

    This work has the LPPL maintenance status "maintained".

    The Current Maintainer of this work is HUANG Yuxi.

\endpreamble
\postamble

    This work consists of the files \jobname.dtx
    and the derived files \jobname.sty and \jobname.ins.

\endpostamble

\generate
  {
%</install>
%<*internal>
    \usedir{source/latex/useclass}
    \file{\jobname.ins}{\from{\jobname.dtx}{install}}
%</internal>
%<*install>
    \usedir{tex/latex/useclass}
    \file{\jobname.sty}{\from{\jobname.dtx}{package}}
  }
\endbatchfile
%</install>
%<*internal>
\fi
%</internal>

%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesExplPackage{useclass}
%<package>  {2024-03-06}{1.0}{Use Classes as Packages} %
%<*driver>
\documentclass{article}
\usepackage{useclass}
\useclass*[full]{l3doc}
\usepackage{mdframed}

\providecommand{\name}{\jobname}
\providecommand{\pkgname}{\pkg{\name}}
\begin{document}
  \DocInput{\jobname.dtx}
  \PrintIndex
\end{document}
%</driver>
% \fi
%
% \title{The \pkgname.sty Package: Load Classes as Packages}
% \author
%   {
%     Huang Yuxi
%     \thanks{
%       \textit{Huang} is his surname.
%     }
%     <^^A
%     \href
%       {mailto:useclass@hyxi.dev}
%       {useclass@hyxi.dev}^^A
%     >
%   }
% \date{2024-03-06 \quad Version 1.0} 
%
%
% \maketitle
%
% \begin{mdframed}
%   \textsf{TL;DR} \; Use \cs{useclass} to load a class with the same usage as \cs{usepackage}:
%   \begin{verbatim}
% \usepackage{useclass}
% \useclass[full]{l3doc}
%   \end{verbatim}
% \end{mdframed}
%
% \tableofcontents
%
% \begin{documentation}
%
% \section{Introduction}
%
% \pkgname{} is a package that enables the usage of classes as packages. It was originally designed for the \cls{l3doc} class, which is employed for documenting \LaTeX{} code with numerous useful features. However, employing the \cls{l3doc} class as a package is not convenient when using the developing class as the style for the document. Therefore, this package provides a simple interface for utilizing classes as packages.
% The package \pkgname{} was initially released on 2024-03-05, under the LaTeX Project Public License Version 1.3c^^A
% \footnote{\url{https://www.latex-project.org/lppl/lppl-1-3c.txt}}
% or later, and is maintained at \url{https://github.com/huangyxi/useclass}.
% The latest documentation can be found at
% \url{https://github.com/huangyxi/useclass/releases/latest/download/useclass.pdf}.
%
%
% \section{Installation}
%
% The following are the methods for installing and updating the package.
% You can choose the method that is most suitable for you.
%
% Since this package is tangled from the \file{.dtx} file,
% the easiest way to install or update the package is to place or replace the \file{\name.sty} file in the same directory as your working document.
% You can find \file{\name.sty} at GitHub Release^^A
% \footnote{\url{https://github.com/huangyxi/useclass/releases/latest/download/useclass.sty}}.
%
% For a full installation of the package, you can use the \TeX repository manager, such as \TeX{} Live.
% This method will download the package from CTAN, and install all required files to \TeX{} Directory Structure (TDS).
% For command-line users, you can use the following command:
% \begin{verbatim}
% tlmgr [--usermode] install useclass
% tlmgr [--usermode] update useclass
% \end{verbatim}
%
% If you're a developer interested in contributing to the project's development,
% or just want to try the latest features before they are released,
% you can clone the repository from GitHub, and use either |l3build| or |make| to install the package.
%
% \section{Usage}
%
% \begin{function}{\useclass, \useclass*}
%   \begin{syntax}
%     \cs{useclass} \marg{class}
%     \cs{useclass} \oarg{options} \marg{class}
%     \cs{useclass*} \marg{class}
%     \cs{useclass*} \oarg{options} \marg{class}
%   \end{syntax}
%   Load class with options, where \meta{options} is the options for the class and \meta{class} is the class name without the extension.
%   When using the starred version \cs{useclass*}, the tokens, dimensions, and control sequences modified by the class will be saved before loading the class and restored after loading the class.
% Currently, the starred version is only applicable to the \cls{l3doc} class.
% \end{function}
%
% Example for a \file{dtx} file:
% \begin{mdframed}
%   \begin{verbatim}
% % \iffalse
% \documentclass{article}
% \usepackage{l3doc}
% \begin{document}
%   \DocInput{\jobname.dtx}
% \end{document}
% % \fi
% %
% % \section{Implementation}
% % \begin{variable}{\l_demo_tl}
% %    \begin{macrocode}
% \tl_new:N \l_demo_tl
% %    \end{macrocode}
% % \end{variable}
%   \end{verbatim}
% \end{mdframed}
%
% \end{documentation}
%
% \begin{implementation}
%
%
% \section{\pkgname{} Implementation}
%    \begin{macrocode}
%<@@=useclass>
%<*package>
%    \end{macrocode}
%
%
% \subsection{Variables}
%
% \begin{macro}{\c_@@_cs_name_tl}
% Prefix of control sequence names for saving and restoring.
%    \begin{macrocode}
\tl_const:Nn \c_@@_cs_name_tl {@@_s_cs_}
%    \end{macrocode}
% \end{macro}
%
% \begin{variable}{\g_@@_tl_seq, \g_@@_dim_seq, \g_@@_cs_name_seq}
% Sequnce of variables to save before, and restore after loading class.
%    \begin{macrocode}
\seq_new:N \g_@@_tl_seq
\seq_new:N \g_@@_dim_seq
\seq_new:N \g_@@_cs_name_seq
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_class_prop}
% Temporary property list of class configuration.
%    \begin{macrocode}
\prop_new:N \l_@@_class_prop
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_csname_seq}
% Temporary sequence of csnames of variables to save and restore.
%    \begin{macrocode}
\seq_new:N \l_@@_csname_seq
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_tmpa_tl, \l_@@_tmpb_tl, \l_@@_tmpa_dim, \@@_tempa_cs:w}
% Temporary variables used in the implementation.
%    \begin{macrocode}
\tl_new:N \l_@@_tmpa_tl
\tl_new:N \l_@@_tmpb_tl
\dim_new:N \l_@@_tmpa_dim
\cs_new_eq:NN \@@_tempa_cs:w ?
%    \end{macrocode}
% \end{variable}
%
%
% \subsection{Helpers}
%
% \begin{macro}{\@@_prop_get_prop:NnN, \@@_prop_get_seq:NnN}
% Since the values of \cs{c_@@_classes_prop} are token lists, we need to parse them to property.
%    \begin{macrocode}
% \cs_set_eq:NN \@@_prop_set_from_keyval:Nn \prop_set_from_keyval:Nn
% \cs_generate_variant:Nn \@@_prop_set_from_keyval:Nn { No }
\cs_new_protected:Npn \@@_prop_get_prop:NnN #1 #2 #3
  {
    \prop_get:NnN #1 {#2} \l_@@_tmpa_tl
    \exp_args:NNo \prop_set_from_keyval:Nn #3 \l_@@_tmpa_tl
  }
\cs_new_protected:Npn \@@_prop_get_seq:NnN #1 #2 #3
  {
    \prop_get:NnN #1 {#2} \l_@@_tmpa_tl
    \exp_args:NNo \seq_set_from_clist:Nn #3 \l_@@_tmpa_tl
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_cs_swap:NN}
% Define a helper function to swap two control sequences.
%    \begin{macrocode}
\cs_new:Npn \@@_cs_swap:NN #1 #2
  {
    \cs_set_eq:NN \@@_tempa_cs:w #1
    \cs_set_eq:NN #1 #2
    \cs_set_eq:NN #2 \@@_tempa_cs:w
  }
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Variables Save and Restore}
%
% \begin{macro}{\@@_save_tl:N, \@@_restore_tl:N}
% Save and restore the token lists of the class.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_save_tl:N #1
  {
    \@@_prop_get_seq:NnN #1 {tl} \l_@@_csname_seq
    \seq_map_inline:Nn \l_@@_csname_seq
      {
        \tl_set:Nx \l_@@_tmpa_tl {\tl_use:c {##1}}
        \seq_gput_right:No \g_@@_tl_seq {\l_@@_tmpa_tl}
      }
  }
\cs_new_protected:Npn \@@_restore_tl:N #1
  {
    \@@_prop_get_seq:NnN #1 {tl} \l_@@_csname_seq
    \seq_map_inline:Nn \l_@@_csname_seq
      {
        \seq_gpop_left:NN \g_@@_tl_seq \l_@@_tmpa_tl
        \tl_set:cn {##1} {\l_@@_tmpa_tl}
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_save_dim:N, \@@_restore_dim:n}
% Save and restore the dimensions of the class.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_save_dim:N #1
  {
    \@@_prop_get_seq:NnN #1 {dim} \l_@@_csname_seq
    \seq_map_inline:Nn \l_@@_csname_seq
      {
        \tl_set:Nx \l_@@_tmpa_tl {\dim_use:c {##1}}
        \seq_gput_right:No \g_@@_dim_seq {\l_@@_tmpa_tl}
      }
  }
\cs_new_protected:Npn \@@_restore_dim:N #1
  {
    \@@_prop_get_seq:NnN #1 {dim} \l_@@_csname_seq
    \seq_map_inline:Nn \l_@@_csname_seq
      {
        \seq_gpop_left:NN \g_@@_dim_seq \l_@@_tmpa_dim
        \dim_set:cn {##1} {\l_@@_tmpa_dim}
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_save_cs:N, \@@_restore_cs:N}
% Create a new control sequence with the transformed name,
% and save and restore the original control sequence with the new name.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_save_cs:N #1
  {
    \@@_prop_get_seq:NnN #1 {cs} \l_@@_csname_seq
    \seq_map_inline:Nn \l_@@_csname_seq
      {
        \tl_concat:NNN \l_@@_tmpa_tl \c_@@_cs_name_tl {##1}
        \cs_set_eq:cc \l_@@_tmpa_tl {##1}
        \seq_gput_right:No \g_@@_cs_name_seq {\l_@@_tmpa_tl}
      }
  }
\cs_new_protected:Npn \@@_restore_cs:N #1
  {
    \@@_prop_get_seq:NnN #1 {cs} \l_@@_csname_seq
    \seq_map_inline:Nn \l_@@_csname_seq
      {
        \seq_gpop_left:NN \g_@@_cs_name_seq \l_@@_tmpa_tl
        \cs_set_eq:cc {##1} \l_@@_tmpa_tl
      }
  }
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Dependences loading}
% \pkgname{} currently don't have any explicit dependences.
%
% \subsection{Patched Macros}
%
% \begin{macro}{\@@_LoadClass:n}
% Patched \cs{LoadClass} to do nothing.
%    \begin{macrocode}
\cs_new:Npn \@@_LoadClass:n #1 {}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Before Loading Class}
%
% \begin{macro}{\@@_save_before:N}
% Save variables before loading class.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_save_before:N #1
  {
    \@@_save_tl:N #1
    \@@_save_dim:N #1
    \@@_save_cs:N #1
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_use_before:}
% These are the general things to do before loading class.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_use_before:
  {
    \@@_cs_swap:NN \LoadClass \@@_LoadClass:n
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Loading Class}
%
% \begin{macro}{\@@_use_class:nn}
% Load class with options.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_use_class:nn #1 #2
  {
    \@fileswithoptions\@clsextension[#1]{#2}
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{After Loading Class}
%
% \begin{macro}{\@@_use_after:}
% These are the general things to do after loading class.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_use_after:
  {
    \@@_cs_swap:NN \LoadClass \@@_LoadClass:n
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_restore_after:N}
% Restore variables after loading class.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_restore_after:N #1
  {
    \@@_restore_cs:N #1
    \@@_restore_dim:N #1
    \@@_restore_tl:N #1
  }
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{User Interface}
% \begin{macro}{\useclass, \useclass*}
% Load patch class with options.
%    \begin{macrocode}
\NewDocumentCommand {\useclass} { s O{} m }
  {
    \bool_if:NTF #1
      {
        \@@_prop_get_prop:NnN \c_@@_classes_prop {#3} \l_@@_class_prop
        \@@_save_before:N \l_@@_class_prop
        \@@_use_before:
        \@@_use_class:nn {#2} {#3}
        \@@_use_after:
        \@@_restore_after:N \l_@@_class_prop
      }
      {
        \@@_use_before:
        \@@_use_class:nn {#2} {#3}
        \@@_use_after:
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Classes Configuration}
% \begin{variable}{\c_@@_classes_prop}
% Configuration for classes to restore after loading.
% The defined property is NOT nested, where values in the prop are token lists but not properties or sequences.
%    \begin{macrocode}
\prop_const_from_keyval:Nn \c_@@_classes_prop {
  l3doc = {
    tl = {
      partname,
    },
    dim = {
      textwidth,
      marginparwidth,
      oddsidemargin,
      evensidemargin,
      parindent,
      itemindent,
      parskip,
    },
    cs = {
      list,
      l@section,
      l@subsection,
    },
  },
}
%    \end{macrocode}
% \end{variable}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \end{implementation}
% \PrintIndex
