latex-style-esdpx/xespdtab.cls

305 lines
14 KiB
OpenEdge ABL
Raw Normal View History

2020-03-14 11:58:37 +00:00
% 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