latex-style-esdpx/xespdtab.cls
2020-03-14 15:04:02 +03:00

305 lines
14 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

% 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