305 lines
14 KiB
TeX
305 lines
14 KiB
TeX
% 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
|
||
|
||
|