%% This is file `stocksize.sty',
%%
%% Copyright (C) 2024–25 by João M. Lourenço <joao.lourenco@fct.unl.pt>
%%
%% This file 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. The latest version of this
%% license is in:
%%
%%    http://www.latex-project.org/lppl.txt
%%
%% and version 1.3c or later is part of all distributions of LaTeX
%% version 2006/05/20 or later.
%%
\def\fileversion{1.0.4}
\def\filedate   {2025/11/05}
\edef\filename  {\@currname}

\ProvidesPackage{stocksize}[%
  \filedate\  v\fileversion (João M. Lourenço) User defined PDF paper (stock) size.]

% Load geometry if it was was not loaded by the user
\AddToHook{begindocument/before}{
  \@ifpackageloaded{geometry}{}{
    \RequirePackage[reset]{geometry}
  }
}

% Change the physical paper (stock) size
% Works with pdfLaTeX, XeLaTeX and LuaLaTeX
% ------------------------------------------------------------
% \@ss@setpdfpagesize{<height>}{<width>}
% Low-level helper: syncs engine/LaTeX dimensions with the requested
% physical stock size.
% Sets (if defined): \pdfpageheight/\pdfpagewidth, \pageheight/\pagewidth,
% and LaTeX's \paperheight/\paperwidth plus \stockheight/\stockwidth.
% Args:
%   #1  height dimension (e.g., 297mm)
%   #2  width  dimension (e.g., 210mm)
% Notes: called after computing full stock size from geometry.
% ------------------------------------------------------------
\newcommand*{\@ss@setpdfpagesize}[2]{%
  \@ifundefined{pdfpageheight}{}{\pdfpageheight=#1}%
  \@ifundefined{pdfpagewidth}{}{\pdfpagewidth=#2}%
  \@ifundefined{pageheight}{}{\pageheight=#1}%
  \@ifundefined{pagewidth}{}{\pagewidth=#2}%
  \paperheight=#1\stockheight=#1%
  \paperwidth=#2\stockwidth=#2%
}

% ------------------------------------------------------------
% Internal stack depth for nested stock-size changes (LIFO).
% Each \pdfsavegeometry increases it; \pdfrestoregeometry decreases it.
% ------------------------------------------------------------
\newcounter{@ss@cnt}
% ------------------------------------------------------------
% \pdfsavegeometry{<geometry key=val list>}
% Push a new stock/page size while preserving current state.
% Steps:
%   1) Save current full stock size (width/height) and margins.
%   2) Increment internal stack counter and save a geometry profile.
%   3) Optionally preserve previous margins via key `keepmargins` (default true).
%   4) Apply \newgeometry{<...>} with the user-supplied keys.
%   5) Recompute and set the new physical stock size.
% Argument:
%   <geometry key=val list> — passed to \newgeometry, e.g.:
%     paper=letter, keepmargins
%     paper=210mm:297mm, margin=2cm
% Usage:
%   \pdfsavegeometry{paper=a4paper, keepmargins}
%   ... content ...
%   \pdfrestoregeometry
% ------------------------------------------------------------
\newcommand*{\pdfsavegeometry}[1]{%
  \expandafter\edef\csname @sspw@\arabic{@ss@cnt}\endcsname%
                {\the\dimexpr\Gm@lmargin+\Gm@width+\Gm@rmargin\relax}%
  \expandafter\edef\csname @ssph@\arabic{@ss@cnt}\endcsname%
                {\the\dimexpr\Gm@tmargin+\Gm@height+\Gm@bmargin\relax}%
  \stepcounter{@ss@cnt}%
  \savegeometry{@ss@cnt@\arabic{@ss@cnt}}%
  \newdimen\@tempdimd%
  \@tempdima=\Gm@lmargin\@tempdimb=\Gm@rmargin%
  \@tempdimc=\Gm@tmargin\@tempdimd=\Gm@bmargin%
  \define@key{Gm}{keepmargins}[true]{\setkeys{Gm}{lmargin=\the\@tempdima,
          rmargin=\the\@tempdimb, tmargin=\the\@tempdimc, bmargin=\the\@tempdimd
  }}%
  \restoregeometry%
  \newgeometry{#1}%
  \edef\@sspw{\the\dimexpr\Gm@lmargin+\Gm@width+\Gm@rmargin\relax}%
  \edef\@ssph{\the\dimexpr\Gm@tmargin+\Gm@height+\Gm@bmargin\relax}%
  \@ss@setpdfpagesize{\@ssph}{\@sspw}%
}

% ------------------------------------------------------------
% \pdfrestoregeometry
% Pop (restore) the previous geometry/stock size from the stack.
% Loads the saved geometry profile for the current depth, decrements
% the counter, and reapplies the previously saved stock size.
% Arguments: none
% ------------------------------------------------------------
\newcommand*{\pdfrestoregeometry}{%
  \loadgeometry{@ss@cnt@\arabic{@ss@cnt}}%
  \addtocounter{@ss@cnt}{-1}%
  \@ss@setpdfpagesize{\csname @ssph@\arabic{@ss@cnt}\endcsname}%
                     {\csname @sspw@\arabic{@ss@cnt}\endcsname}%
}

\newcommand*{\newstocksize}{\pdfsavegeometry}
\newcommand*{\restorestocksize}{\pdfrestoregeometry}

