% Copyright 2006 Konstantin Korikov <lostclus@ua.fm>
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% 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.3 or later is part of all distributions of LaTeX
% version 2003/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
% 
% This Current Maintainer of this work is Konstantin Korikov.
%
% This work consists of all files listed in manifest.txt.
%

%
% This is automaticaly generated file, do not edit it.
%

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{xespdtab}[2020/03/20 v1.00 Tabular Documentation]

\RequirePackage{xkeyval}

\DeclareOption{russian}{\PassOptionsToPackage{\CurrentOption}{xespdlang}}
\DeclareOption{ukrainian}{\PassOptionsToPackage{\CurrentOption}{xespdlang}}
\DeclareOption{koi8-r}{\PassOptionsToPackage{\CurrentOption}{xespdlang}}
\DeclareOption{koi8-u}{\PassOptionsToPackage{\CurrentOption}{xespdlang}}
\DeclareOption{cp1251}{\PassOptionsToPackage{\CurrentOption}{xespdlang}}
\DeclareOption{iso8859-5}{\PassOptionsToPackage{\CurrentOption}{xespdlang}}
\DeclareOption{cp866}{\PassOptionsToPackage{\CurrentOption}{xespdlang}}
\DeclareOption{utf-8}{\PassOptionsToPackage{\CurrentOption}{xespdlang}}
\DeclareOption{utf8}{\PassOptionsToPackage{\CurrentOption}{xespdlang}}
\DeclareOption{twoside}{%
  \PassOptionsToClass{\CurrentOption}{article}%
  \PassOptionsToPackage{\CurrentOption}{xespdstamp}}
\DeclareOption{draft}{\PassOptionsToClass{\CurrentOption}{article}}
\DeclareOption{formI}{%
  \ClassError{xespdtext}{formI style is for graphical documentaion}{}}
\DeclareOption{zonelabels}{%
  \ClassError{xespdtext}{Zone labels is not allowed for tabular documentaion}{}}
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{xespdstamp}}

\newcommand{\XESPD@tabEmptyLineTop}{}
\newcommand{\XESPD@tabEmptyLineBottom}{}
\DeclareOption{emptylinetop}{\renewcommand{\XESPD@tabEmptyLineTop}{\XESPDtabStrut\tabularnewline}}
\DeclareOption{emptylinebottom}{\renewcommand{\XESPD@tabEmptyLineBottom}{\XESPDtabStrut\tabularnewline}}

\newcommand{\XESPD@tabfont}{10pt}
\DeclareOption{10pt}{\renewcommand{\XESPD@tabfont}{10pt}}
\DeclareOption{12pt}{\renewcommand{\XESPD@tabfont}{12pt}}
\DeclareOption{14pt}{\renewcommand{\XESPD@tabfont}{14pt}}

% расстояние между строками
\newlength{\XESPDtabLineSpace}
  \setlength{\XESPDtabLineSpace}{8mm}
\define@key{xespd}{linespace}{\setlength{\XESPDtabLineSpace}{#1}}

% пустое место внизу страницы, единицами измерения являются строки
\newcounter{footwhitespace}
  \setcounter{footwhitespace}{2}
\define@key{xespd}{footwhitespace}{\setcounter{footwhitespace}{#1}}
                                              
\ProcessOptions\relax

\newif\ifXESPD@tab@first@column@enum
\XESPD@tab@first@column@enumfalse

\LoadClass{article}
\RequirePackage{xespdlang}
\RequirePackage[formII]{xespdstamp}
\RequirePackage{xespdinfo}
\RequirePackage{calc}

% несколько служебных длин
\newlength{\XESPDtabBodyH} % высота тела таблицы
\newlength{\XESPDtabHeadH} % высота заголовка таблицы


% макрос-подпорка для строк таблицы
\newcommand{\XESPDtabStrut}{\parbox[c][\XESPDtabLineSpace][c]{0mm}{\rule{0mm}{0mm}}}

% на случай, если запись не влезет в одну строку и произойдет перенос на
% следующую, следует задать интерлиньяж равный \XESPDtabLineSpace. Возможно,
% логичнее задать такой интерлиньяж в xespdfont.
\renewcommand{\XESPDfontTabBody}{%
  \fontsize{\XESPD@tabfont}{\XESPDtabLineSpace}%
  \selectfont\XESPDfontShape}
\renewcommand{\XESPDfontTabHead}{%
  \fontsize{\XESPD@tabfont}{\XESPD@tabfont + 2pt}%
  \selectfont\XESPDfontShape}



% ------------------------------------------------------------------------
% Анализатор "командной строки":
% ------------------------------------------------------------------------
% макрос принимает строку аргументов, разделенных пробелами
% возвращает количество аргументов в макросе \narg и сами аргументы в макросах
% \argi \argii и т.д.
% Изначально он был написан для нужд xespdtab.cls, возможно он пригодится еще
% где-то - тогда стоит вынести его в отдельный файл 
\RequirePackage{xstring}
\RequirePackage{ifthen}

\newcommand{\XESPD@argparse}[1]{
  \newcommand{\@arglist}{#1 }% добавим в конец пробел для нужд парсера
  \newcounter{@iargc}
  % удалим ведущие пробелы, если есть
  \StrChar{\@arglist}{1}[\first@arg]
  \whiledo{\equal{\first@arg}{ }}{%
    \StrGobbleLeft{\@arglist}{1}[\@arglist]
    \StrChar{\@arglist}{1}[\first@arg]}
  \setcounter{@iargc}{0}
  \StrLen{\@arglist}[\@arglistwidth]
  \whiledo{\not\equal{\@arglistwidth}{0}}{%
    \addtocounter{@iargc}{1}%
    % откусим в \arg первое слово
    \StrBefore{\@arglist}{ }[\@arg]
    % сохраним в \argN откушенный кусок
    \expandafter\edef\csname arg\roman{@iargc}\endcsname{\@arg}
    % удалим отработанный кусок
    \StrLen{\@arg}[\@argwidth]
    \StrGobbleLeft{\@arglist}{\@argwidth}[\@arglist] % удалим использованный аргумент
    \StrGobbleLeft{\@arglist}{1}[\@arglist] % удалим пробел после аргумента
    \StrLen{\@arglist}[\@arglistwidth]
    \edef\narg{\arabic{@iargc}}}}

% завернем в более благозвучное название
\newcommand{\XESPDtabColumnsWidth}[1]{\XESPD@argparse{#1}}


% ------------------------------------------------------------------------
% макросы разлиновки листа
% ------------------------------------------------------------------------
\RequirePackage{calc}
\newcounter{narg@tmp}
\newcounter{XESPD@tmpcnt}
\let\XESPDlineCount=\XESPD@tmpdimc

% отрисовка тела таблицы
\newcommand{\XESPDtabDrawBody}[1][]{% принимает один необязательный параметр,
% чтобы рисовать другую таблицу для второго и последующих листов его надо
% установить в "1"
  \put(\XESPDltu{\XESPDframeX},\XESPDltu{\XESPDframeY}){%
    \begin{picture}(0,0)
      \if 1#1 % настройки для второго и последующего листов 
        \XESPD@tmpdima=\XESPD@style@sh@formIIb % высота рамки минус высота штампа.
        % Для второго и последующих листов сделаем пустое пространство на 2 строки
        % это требование ГОСТа. Так сделано для возможности руками дорисовывать
        % штамп вверх, когда для фиксации изменений не будет хватать граф.
        \setlength{\XESPD@tmpdima}{\XESPD@tmpdima + \value{footwhitespace}\XESPDtabLineSpace}
      \else
        \XESPD@tmpdima=\XESPD@style@sh@formII
      \fi
      % чтобы получить высоту тела таблицы, вычтем из высоты рамки
      % высоту шапки и скорректированную (если надо) высоту штампа
      \setlength{\XESPDtabBodyH}{\XESPDframeH - \XESPD@tmpdima - \XESPDtabHeadH}
      % посчитаем, сколько строк укладывается на лист
      \setlength{\XESPD@tmpdima}{\XESPDtabBodyH / \XESPDtabLineSpace}
      \XESPDlineCount=\XESPD@tmpdima % сохраним рассчитанное количество строк
      % скорректируем высоту таблицы с учетом того, что в нее укладывается не целое количество строк
      \setlength{\XESPDtabBodyH}{\XESPDtabLineSpace * \XESPDlineCount}
      % сохраним в "а" расстояние между нижним краем рамки и нижним краем таблицы
      \setlength{\XESPD@tmpdima}{\XESPDframeH - \XESPDtabHeadH - \XESPDtabBodyH}

      % рисуем вертикальные линии на высоте "а" от нижнего края рамки длинной в высоту таблицы
      \linethickness{\XESPDlineThick}
      \setcounter{narg@tmp}{0}
      \XESPD@tmpdimb=0mm
      \whiledo{\value{narg@tmp}<\narg}{
        \addtocounter{narg@tmp}{1}
        \setlength{\XESPD@tmpdimb}{\XESPD@tmpdimb + \csname arg\roman{narg@tmp}\endcsname}
        \put(\XESPDltu{\XESPD@tmpdimb},\XESPDltu{\XESPD@tmpdima}){\line(0,1){\XESPDltu{\XESPDtabBodyH}}}}
      
      % рисуем рассчитанное количество горизонтальных линий начиная снизу ("а")
      \linethickness{\XESPDlineThin}
      \multiput(0,\XESPDltu{\XESPD@tmpdima})(0,\XESPDltu{\XESPDtabLineSpace}){\XESPDlineCount}{%
        \line(1,0){\XESPDltu{\XESPDframeW}}}

      % нумерация строк
      \ifXESPD@tab@first@column@enum
        \setlength{\XESPD@tmpdimb}{\XESPDframeH - \XESPDtabHeadH}
        \setcounter{XESPD@tmpcnt}{0}
        \whiledo{\lengthtest{\XESPD@tmpdimb > \XESPD@tmpdima}}{%
          \addtolength{\XESPD@tmpdimb}{-\XESPDtabLineSpace}%
          \stepcounter{XESPD@tmpcnt}%
          \put(0,\XESPDltu{\XESPD@tmpdimb}){\parbox[b][\XESPDtabLineSpace][c]{\argi}
            {\XESPDfontTabBody\centering\XESPDtabStrut \arabic{XESPD@tmpcnt}}}}
      \fi

    \end{picture}}}


% отрисовка шапки таблицы
\newcommand{\XESPDtabDrawHead}{
% На первый взгляд, этот код логичнее объединить с кодом, рисующим
% вертикальные линии тепла таблицы, но в случае "многоэтажной" шапки
% придется рисовать отдельно
  \put(\XESPDltu{\XESPDframeX},\XESPDltu{\XESPDframeY}){%
    \begin{picture}(0,0)
      % вычислим расстояние от нижнего края рамки до нижнего края шапки таблицы
      \setlength{\XESPD@tmpdima}{\XESPDframeH - \XESPDtabHeadH} 
      % отчеркнем нижний край шапки
      \linethickness{\XESPDlineThick}
      \put(0,\XESPDltu{\XESPD@tmpdima}){\line(1,0){\XESPDltu{\XESPDframeW}}}
      % нарисуем вертикальные линии шапки
      \setcounter{narg@tmp}{0}
      \XESPD@tmpdimb=0mm
      \whiledo{\value{narg@tmp}<\narg}{
        \addtocounter{narg@tmp}{1}
        \setlength{\XESPD@tmpdimb}{\XESPD@tmpdimb + \csname arg\roman{narg@tmp}\endcsname}
        \put(\XESPDltu{\XESPD@tmpdimb},\XESPDltu{\XESPD@tmpdima}){\line(0,1){\XESPDltu{\XESPDtabHeadH}}}}
    \end{picture}}%
}


% ------------------------------------------------------------------------
% Комментарий слева от штампа для листов А3 и более
% ------------------------------------------------------------------------
%
\newlength{\XESPDtabCommentPaddingV}
\newlength{\XESPDtabCommentPaddingH}
\setlength{\XESPDtabCommentPaddingV}{5mm}
\setlength{\XESPDtabCommentPaddingH}{5mm}

\newcommand{\XESPDtabComment}[1]{\def\XESPDtheTabComment{#1}}

\newcommand{\XESPDtabDrawComment}{
  \@ifundefined{XESPDtheTabComment}{}{%
    % тут 185мм - длина штампа, 40мм - высота штампа
    \setlength{\XESPD@tmpdima}{\XESPDframeW -185mm -2\XESPDtabCommentPaddingH}
    \ifthenelse{\lengthtest{\XESPD@tmpdima > 10mm}}{% true
      \put(\XESPDltu{\XESPDframeX},\XESPDltu{\XESPDframeY}){%
        \begin{picture}(0,0)
          \put(\XESPDltu{\XESPDtabCommentPaddingH},\XESPDltu{\XESPDtabCommentPaddingV}){%
            \parbox[b][40mm -2\XESPDtabCommentPaddingV][c]{\XESPD@tmpdima}{%
            \setlength{\parindent}{15mm}%
            \XESPDtheTabComment}}
        \end{picture}}}%
      {\@ifundefined{XESPDtheTabComment}{}{%
        \ClassWarning{xespdtab}{%
          Not anough space to place comment message}}}}% false
}



% ------------------------------------------------------------------------
% Обертка для longtable
% ------------------------------------------------------------------------
% эти 2 макроса должны быть использованы
% в стилевом файле разрабатываемого документа
\newcommand{\XESPDtabLTPreamble}[2]{
  \XESPDputOnStyle{formII}{grid}{\XESPDtabDrawBody\XESPDtabDrawHead}
  \XESPDputOnStyle{formIIb}{grid}{\XESPDtabDrawBody[1]\XESPDtabDrawHead}
  \XESPDputOnStyle{formII}{comment}{\XESPDtabDrawComment}
  \begin{XESPDzeroPadding}
  \setlength{\tabcolsep}{0.5mm}
  \setlength{\LTpre}{0mm}
  \setlength{\LTpost}{0mm}
  \setlength{\LTleft}{0mm}
  \setlength{\LTright}{\fill}
  \begin{longtable}{#1}
  % изменим некоторые константы longtable для того, чтобы
  % таблица занимала всё свободное место
  \setlength{\XESPD@tmpdima}%
    {\XESPDframeH - \XESPD@style@sh@formIIb - \value{footwhitespace}\XESPDtabLineSpace}%
  \global\@colht\XESPD@tmpdima%
  \global\@colroom\XESPD@tmpdima%
  % заполним шапку таблицы
  #2
  % первые и последние строки листов сделаем пустыми для эстетичности 
  \XESPD@tabEmptyLineTop%
  \endhead
  \XESPD@tabEmptyLineBottom%
  \endfoot}
% закрывающий макрос
\newcommand{\XESPDtabLTAmble}
  {\end{longtable}
  \end{XESPDzeroPadding}
  \XESPDremoveFromStyle{formII}{grid}
  \XESPDremoveFromStyle{formIIb}{grid}}


% ----------------------------------------------------------------------
% макрос уменьшает содержимое под заданный размер в случае необходимости
% ----------------------------------------------------------------------
\newcommand{\XESPDsmartScaleBox}[2]{
  \settowidth{\XESPD@tmpdima}{#2}%
  \setlength{\XESPD@tmpdimb}{#1}%
  \ifthenelse{\lengthtest{\XESPD@tmpdima > \XESPD@tmpdimb}}%
    {\ifthenelse{\lengthtest{0.75\XESPD@tmpdima > \XESPD@tmpdimb}}%
      {\scalebox{0.45}[1]{\bfseries#2}}%
      {\scalebox{0.75}[1]{#2}}%
    }%
    {#2}%
}


\let\XESPD@tmpdimc=\XESPDlineCount


