7

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

  1. Every item is page-breakable except the last two items, which must stay with the table's footer and caption.
  2. The descriptions should be in paragraph format under each item (as I have demonstrated in the example)
  3. jkodescriptionlist and \jkoitem have 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

enter image description here


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

enter image description here


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}
  • If you use longtable, then you can specify a table footer for each page and/or a distinct footer for the final page, if desired. (The same for headers, with a distinct one for the first page, if wanted.) The package will then automatically insert page breaks in a way that allows space for the footer on each page and/or the footer on the last page. I imagine this would be easier than rolling your own, but perhaps the needspace package would help if you really need the latter. – cfr Jan 6 '16 at 23:23
  • @cfr The problem with using tables is that the syntax is so bad for writing descriptions in the last column (which I don't even have in a column as you can see in the output). Tables aren't really good for paragraph data. But maybe I should reconsider using it. Maybe I can even wrap the longtable by my environment. – Jonathan Komar Jan 7 '16 at 7:12
  • 1
    @macmadness86 You copied my macro \jokitemx but you added \goodbreak before \par at the starting point of this macro. This \goodbreak negates all endeavour with \nobreak. Because \nobreak\goodbreak in a sequence acts like \goodbreak. Remove \goodbreak. – wipet Jan 10 '16 at 17:54
  • @macmadness86 I don't understand why you takes useless effort with re-writing the idea to LaTeX3 language. TeX primitives work much more flexible. You need no more than to copy my macros to your LaTeX (if you are using LaTeX). – wipet Jan 10 '16 at 17:59
  • @wipet Well, I do not know if that is true due to my limited knowledge of TeX. I do know that my code allows for more than three arguments in the jkoenv and jkoitem. LaTeX3 loops them. Yours is hardcoded. (I mentioned this in the question) I am dealing with a situation where other people need to be able to understand the userlevel LaTeX \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
4
+150

You can start wit experimenting with the following code

\newcount\jcodenum

\def\jcode[#1]#2[#3]#4\endjcode{\par
    \hrule\medskip\hbox to\hsize{\bf #1}\medskip\hrule\medskip
    {\jcodenum=0
     \def\jkoitem[##1]##2{\advance\jcodenum by1 }#4
     \interlinepenalty=10000 \let\jkoitem=\jkoitemx #4
     \medskip\hrule\nobreak\medskip #3\par}
}
\def\jkoitemx[#1,#2,#3]#4{\par \noindent{\bf#1}, \ignorespaces#2\hfill #3\par\nobreak
    #4\par
    \advance\jcodenum by-1 \ifnum\jcodenum<2 \nobreak \fi
}

\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}
\endjcode

\bye

You can try this in plain TeX. To rewrite this for LaTeX is simple exercise. I'll do not this because I don't support LaTeX.

The paragraphs are not breakable between lines and the last two items plus footer are not breakable too because of the test \ifnum\jcodenum<2 \nobreak \fi.

  • It's ok to use TeX. In fact, I've been reading through the TeXBook. I think I might have outgrown LaTeX. Without truly understanding TeX, I do not think I can effectively code in LaTeX (unfortunately). – Jonathan Komar Jan 7 '16 at 12:53
  • I don't get why you used jkoitem and jkoitemx. Why not just use the if/then logic in jkoitem? Is this understanding correct: you define an unbreakable \jkoitem that assigns itself to \jkoitemx that becomes breakable if the count is < 2? – Jonathan Komar Jan 7 '16 at 14:29
  • The text with \jkoitem, \jkoitem, ... (i. e. #4) is processed twice. First with meaning of \jkoitem: print nothing, only increase \jcodenum. Now, the number of items is know. Second processing is with meaning of \jkoitemx: print all and decrease \jcodenum, append \nobreak if \jcodenum<2. – wipet Jan 7 '16 at 15:11
  • I get that #1 and #3 correspond to \jcode[HL7-Path, Name \hfill R/O, Rep\#] and everything in the next [], respectively, but what do #2 and #4 represent in jcode? Maybe you could look at my attempt at translating your code into LaTeX (bottom of my question). – Jonathan Komar Jan 7 '16 at 15:21
  • The #2 in \jcode is usually space between first and second [...] [...]. And #4 is whole text (all \jokitems) separated by \endjcode – wipet Jan 7 '16 at 17:00
1

SOLVED Explanation of wipet's answer

UPDATED January 11, 2016:

The following code demonstrates a solution that counts each item within the environment. It also demonstrates which types of environment's support this technique. It is not supported by the \newenvironment macro or the xparse \NewDocumentEnvironment macro, because the content is inaccessible like it is in TeX. The only way to do it in LaTeX is to use the environ package's \NewEnviron combined with the \BODY macro to insert the environment's contents.

The trick is to tally up the number of \additems and then redefine \additem to subtract from the sum of \additems stored in the counter. An if/then statement checks to see whether the environment reaches the last \additem (\ifnum\counter<2 \nobreak \fi). So, when there is one item (in other words, the counter hits 1), add a \nobreak (\penalty \@M/\penalty 10000) into the mix, which keeps the second to last item and the last item together on the next page. Ingenious! Thank you wipet!

\documentclass{article}
\usepackage{environ}
\usepackage{xparse}

\newcount\texcounter
\newcounter{latexNewEnvironcounter}
\newcounter{latexcounter}
\newcounter{latexthreecounter}

% TeX Syntax
\def\texenv#1\endtexenv{
  \def\additem[##1]##2{\advance\texcounter by1 }
  \typeout{**** Value texcounter (before first call of body): \the\texcounter} % Should be 0
  #1 % Typeset body of env
  \typeout{**** Value texcounter (after first call of body): \the\texcounter} % Should be 3
  \let\additem=\additemtex
  #1 % Retypeset body of env with new definition of \additem (\additemx)
  }

% environ Package NewEnviron
\NewEnviron{NewEnvironenv}{% environ package is the only way I know how to grab the body like in TeX
  \def\additem[##1]##2{\addtocounter{latexNewEnvironcounter}{1}}
  \typeout{**** Value latexNewEnvironcounter (before first call of body): \the\value{latexNewEnvironcounter}} % Should be 0
  \BODY % Typeset body of env
  \typeout{**** Value latexNewEnvironcounter (after first call of body): \the\value{latexNewEnvironcounter}} % Should be 3
  \let\additem=\additemlatexNewEnviron
  \BODY % Retypeset body of env with new definition of \additem (\additemx)
}{}

% LaTeX2e Syntax
\newenvironment{latexenv}{% Not supported because #1 cannot contain the body of the environment like in TeX
  \def\additem[##1]##2{\addtocounter{latexcounter}{1}}
  \typeout{****  Value latexcounter (before first call of body): \the\value{latexcounter}} % Should be 0
  %#1
  \typeout{**** Value latexcounter (after first call of body): \the\value{latexcounter}} % Should be 3
  \let\additem=\additemlatex
}{}

% LaTeX3 Syntax
\NewDocumentEnvironment{latexthreeenv}{}{% Not supported because #1 cannot contain the body of the environment like in TeX
  \def\additem[##1]##2{\addtocounter{latexthreecounter}{1}}
  \typeout{****  Value latexthreecounter (before first call of body): \the\value{latexthreecounter}} % Should be 0
  %#1
  \typeout{**** Value latexthreecounter (after first call of body): \the\value{latexthreecounter}} % Should be 3
  \let\additem=\additemlatexthree
}{}

% additem redefinition for TeX
\def\additemtex[#1,#2,#3]#4{\par \noindent{\bf#1}, \ignorespaces#2\hfill
    \def\comma{\def\comma{, }}\listargs #3,,\par\nobreak%Redefine comma to use space, see \listargs
    \hangindent=\parindent{\parbox{\dimexpr\textwidth-\parindent-1cm\relax}{\footnotesize #4}\par}% This #4 represents the descriptions
    \typeout{**** Value texcounter (inside additemx): \the\texcounter}% Print count
    \advance\texcounter by-1 % descrease count while it is increased
    \ifnum\texcounter<2 \nobreak \fi
}
\def\listargs#1,{\ifx,#1,\else\comma\ignorespaces#1\expandafter\listargs\fi}% Redefine args to user spaces


% additem redefinition for NewEnviron
\def\additemlatexNewEnviron[#1,#2,#3]#4{\par \noindent{\bf#1}, \ignorespaces#2\hfill
    \def\comma{\def\comma{, }}\listargs #3,,\par\nobreak%Redefine comma to use space, see \listargs
    \hangindent=\parindent{\parbox{\dimexpr\textwidth-\parindent-1cm\relax}{\footnotesize #4}\par}% This #4 represents the descriptions
    \typeout{**** Value latexNewEnvironcounter (inside additemlatexNewEnviron): \the\value{latexNewEnvironcounter}} % Print Count
    \addtocounter{latexNewEnvironcounter}{-1} % descrease count while it is increased
    \ifnum\latexNewEnvironcounter<2 \nobreak \fi
}

% additem redefinition for LaTeX2e
\def\additemlatex[#1,#2,#3]#4{\par \noindent{\bf#1}, \ignorespaces#2\hfill
    \def\comma{\def\comma{, }}\listargs #3,,\par\nobreak%Redefine comma to use space, see \listargs
    \hangindent=\parindent{\parbox{\dimexpr\textwidth-\parindent-1cm\relax}{\footnotesize #4}\par}% This #4 represents the descriptions
    \typeout{**** Value latexcounter (inside additemlatex): \the\value{latexcounter}} % Print Count
    \addtocounter{latexcounter}{-1} % descrease count while it is increased
    \ifnum\latexcounter <2 \nobreak \fi
}


% additem redefinition for LaTeX3
\def\additemlatexthree[#1,#2,#3]#4{\par \noindent{\bf#1}, \ignorespaces#2\hfill
    \def\comma{\def\comma{, }}\listargs #3,,\par\nobreak%Redefine comma to use space, see \listargs
    \hangindent=\parindent{\parbox{\dimexpr\textwidth-\parindent-1cm\relax}{\footnotesize #4}\par}% This #4 represents the descriptions
    \typeout{**** Value latexthreecounter (inside additemlatexthree): \the\value{latexthreecounter}} % Print Count
    \addtocounter{latexthreecounter}{-1} % descrease count while it is increased
    \ifnum\latexthreecounter<2 \nobreak \fi
}


\begin{document}

\section{Supported}
\subsection{\TeX}
\texenv
\additem[arg1,arg2,arg3]{A nice description. Value texcounter: \the\texcounter}
\additem[arg1,arg2,arg3]{A nice description. Value texcounter: \the\texcounter}
\additem[arg1,arg2,arg3]{A nice description. Value texcounter: \the\texcounter}
\endtexenv
\subsection{\texttt{environ} Package}
\begin{NewEnvironenv}
\additem[arg1,arg2,arg3]{A nice description. Value latexNewEnvironmentcounter: \the\value{latexNewEnvironcounter}}
\additem[arg1,arg2,arg3]{A nice description. Value latexNewEnvironmentcounter: \the\value{latexNewEnvironcounter}}
\additem[arg1,arg2,arg3]{A nice description. Value latexNewEnvironmentcounter: \the\value{latexNewEnvironcounter}}
\end{NewEnvironenv}

\section{Unsupported}

\subsection{\LaTeX\ 2e}
\begin{latexenv} % Does not work, see definition comment
\additem[arg1,arg2,arg3]{A nice description. Value latexcounter: \the\value{latexcounter}}
\additem[arg1,arg2,arg3]{A nice description. Value latexcounter: \the\value{latexcounter}}
\additem[arg1,arg2,arg3]{A nice description. Value latexcounter: \the\value{latexcounter}}
\end{latexenv}

\subsection{\LaTeX\ 3}
Workaround maybe possible, see egreg's hack: \\http://tex.stackexchange.com/a/172426/13552
\begin{latexthreeenv} % Does not work, see definition comment
\additem[arg1,arg2,arg3]{A nice description. Value latexthreecounter: \the\value{latexthreecounter}}
\additem[arg1,arg2,arg3]{A nice description. Value latexthreecounter: \the\value{latexthreecounter}}
\additem[arg1,arg2,arg3]{A nice description. Value latexthreecounter: \the\value{latexthreecounter}}
\end{latexthreeenv}

\end{document}

Output

[![enter image description here][1]][1]

Log

The point of this is to demonstrate which counters are working as expected. We expect: 0,3,3,2,1.

Plain TeX

**** Value texcounter (before first call of body): 0
**** Value texcounter (after first call of body): 3
**** Value texcounter (inside additemx): 3
**** Value texcounter (inside additemx): 2
**** Value texcounter (inside additemx): 1

Environ

**** Value latexNewEnvironcounter (before first call of body): 0
**** Value latexNewEnvironcounter (after first call of body): 3
**** Value latexNewEnvironcounter (inside additemlatexNewEnviron): 3
**** Value latexNewEnvironcounter (inside additemlatexNewEnviron): 2
**** Value latexNewEnvironcounter (inside additemlatexNewEnviron): 1

Standard LaTeX \newenvironment

**** Value latexcounter (before first call of body): 0
**** Value latexcounter (after first call of body): 0
**** Value latexcounter (inside additemlatex): 0
**** Value latexcounter (inside additemlatex): -1
**** Value latexcounter (inside additemlatex): -2

xparse's \NewDocumentEnvironment

**** Value latexthreecounter (before first call of body): 0
**** Value latexthreecounter (after first call of body): 0
**** Value latexthreecounter (inside additemlatexthree): 0
**** Value latexthreecounter (inside additemlatexthree): -1
**** Value latexthreecounter (inside additemlatexthree): -2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.