1

I created a small package to help me typeset various tidbits in papers for a specific domain of theoretical computer science that I sometimes work in. So far, it has been working well, but I decided that I wanted to introduce auto-growing brackets since I can sometimes end up with a whole bunch of nested brackets being displayed. To do this, I introduced use of the 'perfectcut' package. Or tried to.

For full reference, you can find the pre-perfectcut implementation here, and the attempt at a new implementation here. The only substantive difference between the two is changing the definitions of cpfunc, cpsend and cprecv, and introducing the new cpsystems@functorparens and cpsystems@msgbraces commands to back said new definitions.

The problem is, with just these changes (and, best as I can tell, the modification to cpfunc was the only one that actually caused these problems), is that now when I try to re-compile my .dtx file (using the command pdflatex cpsystems.dtx), I get a whole bunch of "Misplaced \cr" and "Misplaced alignment tab &" errors. E.g., the very first ones look like:

! Misplaced \cr.
\reserved@c ->\ifnum 0=`{}\fi \cr

l.310 ...func{p}{h(R) \cpfunc{p}{h(F)p(P)}}}~c(W)}

? ! Misplaced alignment tab character &. <recently read> &

l.310 ...func{p}{h(R) \cpfunc{p}{h(F)p(P)}}}~c(W)}

In the full-blown file, these such errors start at line 310, with more being reported at lines 315, 370 and 375 (though the latter two are actually a repeat of the earlier two, for documentation reasons). Going by discussions of these errors that I could turn up, such as this TeXOverflow question, or this Overleaf help page, I surmise that the errors are probably not occurring there, but likely on the line above. Either way, though, I can't work out what the issue really is.

The lines in question are using a package command, which in turn uses an array environment, to present something. On the previous line, I have included a line break. I have checked, and am fairly certain I have specified the correct number of & characters on those lines to get everything to fit together, and I didn't see any errors previously.

I have done my best to create an example that reproduces the errors, which is below, though it is still awfully long (I wasn't sure what else I could remove without mucking something up):

% \iffalse meta-comment
% !TEX program  = pdfLaTeX
%
% \fi
% \iffalse
%<*readme>
%%cpsystems LaTeX package
%</readme>
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{cpsystems.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{cpsystems}
%<*package>
[2020/07/16 v0.14 Package to aid in typesetting cP systems 
    rulesets, following Nicolescu's standard style]
%</package>
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{cpsystems}[2020/07/16 v0.14]
\usepackage{fancyvrb}
\usepackage[hidelinks]{hyperref}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
%\OnlyDescription %Leave this commented out unless you have read the Doc documentation and know what you're doing
\begin{document}
  \DocInput{cpsystems-autogrow-bracks-mwe.dtx}
  \PrintIndex
  \PrintChanges
\end{document}
%</driver>
% \fi
%
%   \begin{cpruleset}
%       \cprule{s_1}{\cpfunc{v}{v(R)Y}}{1}{s_2}{\cpfunc{s}{r(R)~u(Y)~
%       \cpfunc{p}{h(R)p()}}~c(\lambda)}
%       
%       \cprule{s_2}{\cpfunc{s}{r(R)~u() \\ & \cpfunc{p}{h(F)p(P)} \\ & c(C)}}
%       {+}{s_3}{\cpfunc{z}{\cpfunc{p}{h(R) \cpfunc{p}{h(F)p(P)}}}~c(W)}
%       
%       \cprule{s_2}{}{+}{s_2}{\cpfunc{s}{r(R)~u(Z) \\
%       & & & & \cpfunc{p}{h(T) \cpfunc{p}{h(F) p(P)}}
%       \\ & & & & c(CW)}}
%       
%       \cprule{s_2}{s(\_)}{+}{s_2}{}
%       
%       \cprule{s_3}{}{1}{s_4}{p'(P) \quad c'(1D)}
%   \end{cpruleset}
% \StopEventually{\PrintIndex}
% \iffalse
%<*package>
% \fi
%
% \iffalse
%
% \fi
% 
% \subsection{Preamble}
%
%    \begin{macrocode}
%

\RequirePackage{array} \RequirePackage{framed} \RequirePackage{changepage} \RequirePackage{amsmath} \RequirePackage{trimspaces} \RequirePackage{newfloat} \RequirePackage{perfectcut}

\newcounter{cpsystems@RuleNum} % % \begin{macrocode} \newenvironment{cpruleset} {\begin{framed}\begin{adjustwidth}{-1.0em}{-1.0em} \renewcommand{\arraystretch}{1.0}[\begin{array}{lllllr}} {\end{array}]\end{adjustwidth}\end{framed}} % \end{macrocode} % % % \begin{macro}{\cprule} % \begin{macrocode} \newcommand{\cprule}[5]{ \refstepcounter{cpsystems@RuleNum} \cpsystems@basecprule{#1}{#2}{#3}{#4}{#5}{(\arabic{cpsystems@RuleNum})} } % \end{macrocode} % \end{macro} % % \begin{macro}{\cpfunc} % Command for declaring a cP~systems functor. % The first argument is the symbol for the functor itself, and the second argument is the objects contained inside the functor. % \begin{macrocode} \newcommand{\cpfunc}[2]{ \trim@spaces@noexp{#1\cpsystems@functorparens{#2}} } % \end{macrocode} % \end{macro} % % \begin{macro}{\cpsystems@basecprule} % For writing out rules inside a |cpruleset| environment. % Required arguments are, in order, beginning state name; LHS of rule; the label to be applied to the arrow; the ending state name; the RHS of the rule. % \begin{macrocode} \newcommand{\cpsystems@basecprule}[6]{ \trim@spaces@noexp{#1 & #2 & \rightarrow_{#3} & #4 & #5 & #6\} } % \end{macrocode} % \end{macro} % % \begin{macro}{\cpsystems@functorparens} % To ensure that brackets resize themselves automatically in functors. % \begin{macrocode} \newcommand{\cpsystems@functorparens}[1]{ \perfectunary{IncreaseHeight}(){#1} } % \end{macrocode} % \end{macro} % % \iffalse %</package> % \fi % % \Finale %

In case versions matter, I am using MikTex to run this, and it seems to be reporting its version as 20.6.29. AmsMath is version 2.17e. The 'tools' package doesn't have a listed version in the MikTex console but is dated with 'Tue Feb 4 10:11:41 2020'.

Can you see what the problem is? I imagine it is probably some trivial issue of a misplaced character or something, but I have been unable to figure this out. (I'm also open to suggestions on other aspects of the package if someone is keen enough :) )

EDIT: I began to wonder if the perfectcut package actually had anything to do with this problem, and I'm not sure that it does in actuality. To test this, I removed the \RequirePackage{perfectcut} line and modified the definition of cpsystems@cpfunctorparens to simply (#1). I still get the exact same error. Leaving perfectcut in, but changing the cpruleset block to just:

\begin{cpruleset}
    \cpfunc{a}{\cpfunc{b}{\cpfunc{c}{d}}}
\end{cpruleset}

gives me exactly the expected behaviour. That said, I did also try to exclude the requirepackage line for perfectcut, but continue using perfectunary to define cpfunc, and didn't seem to experience any errors with it, so I'm not 100% sure I was doing everything correctly. Does anybody have any suggestions on what I should do to test this further to determine the problem precisely?

Jarak
  • 391

1 Answers1

1

I came back to this today, and I seem to have found the problem. It was, in fact, two-fold. Firstly, I wasn't using the perfectunary environment correctly. For some daft reason, I wasn't using including all necessary curly braces. I.e. the definition was

\newcommand{\cpsystems@functorparens}[1]{
    \perfectunary{IncreaseHeight}(){#1}
}

but should have been

\newcommand{\cpsystems@functorparens}[1]{
    \perfectunary{IncreaseHeight}{(}{)}{#1}
}

Secondly, it appears that the perfectcut macros (or, at least, perfectunary) don't play nicely with linebreaks inside itself. In a couple of places in the documentation inside the .dtx file for the package, I had linebreaks inside cpfunc macros. The use of perfectunary seems to break these and cause the errors I was seeing. I tried changing them from \\ to \linebreak based on what I read here and here, which helped, but not totally. The errors stopped complaining about misplaced \crs but swapped to complaining about misplaced &s. Removing the &s got rid of the errors, but now there doesn't seem to be any sort of line breaking at all going on inside either cpfunc or cprule macros. Currently, that is a lower priority for me than auto-growing brackets, so it is a trade-off I have made for now. Hopefully, I will stumble across a way to get that back.

You can find the results of all this at the GitHub repo under release v0.15 if you are interested.

Jarak
  • 391