What to do when tabular alignment just doesn't cut it?
I designed (perhaps not efficiently or with the "right" approach, yet using some helpful LaTeX3 answers from egreg) a way to enter data into an almost table-like list.
The main issue is that
- my "table" can break where the table's footer bar occurs as demonstrated in the example.
- Also, it can break just after the footer bar's information, just before the caption.
This results in a caption or footer and caption that is separated from the table by a page break. I know that I could just wrap things with minipages, but I need breakable text, because some of these parameter lists are very long.
Criteria
- Every item is page-breakable except the last two items, which must stay with the table's footer and caption.
- The descriptions should be in paragraph format under each item (as I have demonstrated in the example)
jkodescriptionlistand\jkoitemhave a flexible number of arguments (only the first two get aligned left).
What I would like is to define a minimum number lines (jkoitems) that should be kept with the table's footer bar. (For that matter, a break should also never occur immediately after the table's header bar.) If a page break is necessary right where the table's footer is or caption, a page break will occur, but it will take a few of the items with it onto the next page.
Note: I was able to keep the table's footer bar and data together by using \\* which corresponds to \vadjust{\nobreak\vskip<length>}
I am also open to suggestions as to how I could implement this entire thing better. I would think that the solution deals with glue. As cfr suggested, a longtable environment might work, but I do not know how to implement this layout with longtable without making the source code a total mess. UPDATE: I forgot that I had previously asked a question regarding tables and LaTeX3, which might come in handy here: https://tex.stackexchange.com/a/243627/13552^. I remember just giving up because of a time constraint and I was never able to implement the longtable version.
Code
I am open to suggestions
\documentclass{article}
\usepackage{fontspec}
\usepackage{lipsum}
\usepackage{caption}
\usepackage{xparse}
\usepackage{booktabs}
\usepackage{tikz}
\newcommand{\jkotabcap}[1]{\captionof{table}{#1}\bigskip}
\ExplSyntaxOn
\DeclareDocumentEnvironment{jkodescriptionlist}{O{}O{}}%
{%
\noindent\rule{\textwidth}{\heavyrulewidth}\\*
\noindent\textbf{\textcolor{red}{#1}}\\*
\noindent\rule[2mm]{\textwidth}{\lightrulewidth}\par
}%
{%
% Some glue should probably go here that prevents the bottom of the table from being alone on a page but I am not sure how to do this.
% Do I need \leavevmode\vadjust{\penalty 10000} or something similar?
{\nopagebreak\noindent\rule{\textwidth}{\heavyrulewidth}\\*
\tiny #2\par}
}%
\DeclareDocumentCommand{\jkoitem}{O{}m}{% Optional:comma list of values; mandatory:description
\noindent\dojkoitemargs:n{#1}\vadjust{\nobreak\vskip .1ex}
\null\hspace{2em}\par\parbox{\dimexpr\textwidth-4em\relax}{\footnotesize#2}\vskip 1.7ex plus 2ex % Description Format
}%
\clist_new:N\jkoitemargs
\cs_new_protected:Nn\dojkoitemargs:n{{%
\clist_set:Nn\jkoitemargs{#1}%
\textbf{\clist_item:Nn \jkoitemargs {1}},~\clist_item:Nn \jkoitemargs {2} \hfill
\int_step_inline:nnnn {3}{1}{\clist_count:N \jkoitemargs}
{%
\int_compare:nTF { ##1 = \clist_count:N \jkoitemargs }
{\clist_item:Nn \jkoitemargs {##1}}
{\clist_item:Nn \jkoitemargs {##1},~}
}
}}%
\ExplSyntaxOff
\begin{document}
% Syntax
%\jkoitem[Whatever fields are needed]
%{Description}
\section{Introduction}
\subsection{This Fun Document}
\lipsum[1-2]
Hello\\ % <-- Uncomment this line to push the entire bottom of the table to another page.
\begin{jkodescriptionlist}[HL7-Path, Name \hfill R/O, Rep\#][\textbf{R/0} = Required/Optional, \textbf{R} = Required,
\textbf{O} = Optional, \textbf{RO} = Required if known,
\textbf{REP\#} = Repitition, \textbf{Y} = entry can be
taken from the list, \textbf{N} = Individual Values,
\textbf{Number} = Maximum length of the list]
\jkoitem[MSH-6-2,homeCommunityID,R]
{OID of the affinity domain where the document will be stored.}
\jkoitem[MSH-19,languageCode,R]
{Specifies the human language of the document. Format according RFC-3066.}
\jkoitem[PID-3,patientInfo.socialSecurityNumber,R]
{Social security number of the patient. Important: The social security number will be
identified within the list of patient
identifiers (PID-3) by the OID of the social security association.}
\jkoitem[PID-3,patientInfo.sourcePatientID,R]
{Patient identifier of the local CIS/RIS/PACS…Important: The Patient Identifier
will be identified within the list of patient identifiers (PID-3) by the identifier type code PI.}
\jkoitem[PID-5-1,patientInfo.familyName,R]
{Family name of the patient.}
\jkoitem[PID-5-2,patientInfo.givenName,R]
{Given name of the patient.}
\jkoitem[PID-5-3,patientInfo.secondAndFurtherNames[0],O]
{Second and further names of the patient}
\end{jkodescriptionlist}
\jkotabcap{Fun Mapping Data.}
\label{Table:Fun Mapping Data}
\end{document}
Output
Semi-Successful Revamp TeX > LaTeX from wipet's Code
I am not completely satisfied because it is not as flexible with the \jkoitem arguments as the original. For example, my \jkoitem can support an arbitrary number of arguments (until they become unaesthetic). This code only supports 3 aesthetically pleasing arguments. Also, I am not exactly sure whether I understand what is going on, but I made it to page 112 of the TeXBook, and tried implementing some of the things I learned for breaking and paragraph shapes.
Code
\documentclass{article}
\usepackage{lipsum}
\newcount\jcodenum
\def\jcode[#1]#2[#3]#4\endjcode{\goodbreak\hbox{}\par
\hrule\medskip\hbox to\hsize{\bf #1}\medskip\hrule\medskip
{\jcodenum=0
\def\jkoitem[##1]##2{\advance\jcodenum by1 } % Dummy function just tallies up jkoitem's as they are parsed
\typeout{**** Value of Counter (before first call of body 4): \the\jcodenum}% Print count of jcodenum at this point to log
#4 % prints contents of jcode=nothing because jkoitem prints nothing, serves to increment \jcodenum (see log output)
\typeout{**** Value of Counter (after first call of body 4): \the\jcodenum}% Print count of jcodenum at this point to log
\interlinepenalty=10000% value of the penalty (node) added after each line of a paragraph.
\let\jkoitem=\jkoitemx% Reassign jkoitem to jkoitemx, passing all args properly
#4 %This #4 represents the jkoitems with the new definition? Commenting this out erases content
\typeout{**** Value of Counter (after redefinition and new call of body 4): \the\jcodenum}% Print count of jcodenum at this point to log
\medskip\hrule\nobreak\smallskip \tiny \noindent#3\bigskip\par}
}
\def\jkoitemx[#1,#2,#3]#4{\goodbreak\par \noindent{\bf#1}, \ignorespaces#2\hfill #3\par\nobreak
\hangindent=\parindent{\footnotesize #4\par}% This #4 represents the descriptions
\advance\jcodenum by-1% descrease count while it is increased
\typeout{**** Value of Counter (inside of jkoitemx): \the\jcodenum}% Print count of jcodenum at this point to log
\ifnum\jcodenum<2 \nobreak \fi
}
\begin{document}
\lipsum[1-2]
\jcode[HL7-Path, Name \hfill R/O, Rep\#]
[{\bf R/0}~=~Required/Optional, {\bf R}~=~Required,
{\bf O}~=~Optional, {\bf RO}~=~Required if known,
{\bf REP\#}~=~Repitition, {\bf Y}~=~entry can be taken from the list,
{\bf N}~=~Individual Values, {\bf Number}~=~Maximum length of the list]
\jkoitem[MSH-6-2,homeCommunityID,R]
{OID of the affinity domain where the document will be stored.}
\jkoitem[MSH-19,languageCode,R]
{Specifies the human language of the document. Format according RFC-3066.}
\jkoitem[PID-3,patientInfo.socialSecurityNumber,R]
{Social security number of the patient. Important: The social security
number will be
identified within the list of patient
identifiers (PID-3) by the OID of the social security association.}
\jkoitem[PID-3,patientInfo.sourcePatientID,R]
{Patient identifier of the local CIS/RIS/PACS…Important: The Patient
Identifier
will be identified within the list of patient identifiers (PID-3) by the
identifier type code PI.}
\jkoitem[PID-5-1,patientInfo.familyName,R]
{Family name of the patient.}
\jkoitem[PID-5-2,patientInfo.givenName,R]
{Given name of the patient.}
\jkoitem[PID-5-3,patientInfo.secondAndFurtherNames{[0]},O]
{Second and further names of the patient}
\jkoitem[PID-5-3,patientInfo.secondAndFurtherNames{[0]},O]
{Second and further names of the patient}
\jkoitem[PID-5-3,patientInfo.secondAndFurtherNames{[0]},O]
{Second and further names of the patient}
\jkoitem[PID-5-3,patientInfo.secondAndFurtherNames{[0]},O]
{Second and further names of the patient}
\jkoitem[PID-5-3,patientInfo.secondAndFurtherNames{[0]},O]
{Second and further names of the patient}
\endjcode
%\bye
\lipsum[1]
\end{document}
Related Log Entries:
**** Value of Counter (before first call of body 4): 0
**** Value of Counter (after first call of body 4): 11
**** Value of Counter (inside of jkoitemx): 10
**** Value of Counter (inside of jkoitemx): 9
**** Value of Counter (inside of jkoitemx): 8
**** Value of Counter (inside of jkoitemx): 7
**** Value of Counter (inside of jkoitemx): 6
**** Value of Counter (inside of jkoitemx): 5
**** Value of Counter (inside of jkoitemx): 4
**** Value of Counter (inside of jkoitemx): 3
**** Value of Counter (inside of jkoitemx): 2
**** Value of Counter (inside of jkoitemx): 1
**** Value of Counter (inside of jkoitemx): 0
**** Value of Counter (after redefinition and new call of body 4): 0
Output
A Revamped Approach using Longtable (response to cfr's comment)
Updated January 7, 2016
Issues:
- col1 not bold (because I am using
\clist_use:Nn \jkoitemargs { & }instead of\textbf{\clist_item:Nn \jkoitemargs {1}}) - col3 not right aligning correctly
- a page break can potentially occur between a row and its description (FIXED:
\\to\\*) - Tabular alignment simply does not look as good as the original.
Code
\documentclass{article}
\usepackage{fontspec}
\usepackage[margin=2cm]{geometry}
\usepackage{longtable}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentEnvironment{mytable}{ O{} }
{
\clist_set:Nn \jkotableargs { #1 }
\begin{longtable}{llrr}
\clist_use:Nn \jkoitemargs { & } \endhead
}
{
\end{longtable}
}
\clist_new:N\jkoitemargs
\clist_new:N\jkotableargs
\NewDocumentCommand{\myitem}{ O{} m }
{
\clist_set:Nn \jkoitemargs { #1 }
\clist_use:Nn \jkoitemargs { & }\\*
\multicolumn{ 4 } {@{}l@{}}
{
\hspace{\parindent}
\parbox{\dim_eval:n { \textwidth-\parindent } } {\footnotesize #2}
}
\\[\normalbaselineskip]
}
\ExplSyntaxOff
\begin{document}
\begin{mytable}[HL7-Path, Name, R/O, Rep\#]
\myitem[col1,col2,col3,col4]{description on new row}
\myitem[MSH-6-2,homeCommunityID,R/O,Rep\#]{OID of the affinity domain where the document will be stored.}
\end{mytable}
\end{document}


\jokitemxbut you added\goodbreakbefore\parat the starting point of this macro. This\goodbreaknegates all endeavour with\nobreak. Because\nobreak\goodbreakin a sequence acts like\goodbreak. Remove\goodbreak. – wipet Jan 10 '16 at 17:54\begin{env}\end{env}commands. As long as I can make it user-friendly from the document side, I am fine with TeX. I can't get that working. I am preparing another question about counters at the moment that may clear up some of my misunderstanding. – Jonathan Komar Jan 10 '16 at 18:04