texlive[54454] trunk: latexindent (21mar20)

commits+karl at tug.org commits+karl at tug.org
Sat Mar 21 22:20:37 CET 2020


Revision: 54454
          http://tug.org/svn/texlive?view=revision&revision=54454
Author:   karl
Date:     2020-03-21 22:20:37 +0100 (Sat, 21 Mar 2020)
Log Message:
-----------
latexindent (21mar20)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/latexindent/latexindent.pl
    trunk/Master/bin/win32/latexindent.exe
    trunk/Master/texmf-dist/doc/support/latexindent/README
    trunk/Master/texmf-dist/doc/support/latexindent/latexindent.pdf
    trunk/Master/texmf-dist/doc/support/latexindent/latexindent.tex
    trunk/Master/texmf-dist/doc/support/latexindent/sec-conclusions-know-limitations.tex
    trunk/Master/texmf-dist/doc/support/latexindent/sec-default-user-local.tex
    trunk/Master/texmf-dist/doc/support/latexindent/sec-fine-tuning.tex
    trunk/Master/texmf-dist/doc/support/latexindent/sec-how-to-use.tex
    trunk/Master/texmf-dist/doc/support/latexindent/sec-introduction.tex
    trunk/Master/texmf-dist/doc/support/latexindent/sec-replacements.tex
    trunk/Master/texmf-dist/doc/support/latexindent/sec-the-m-switch.tex
    trunk/Master/texmf-dist/doc/support/latexindent/subsubsec-no-add-remaining-code-blocks.tex
    trunk/Master/texmf-dist/doc/support/latexindent/title.tex
    trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm
    trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm
    trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm
    trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm
    trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm
    trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm
    trunk/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml
    trunk/Master/texmf-dist/scripts/latexindent/latexindent.pl

Modified: trunk/Build/source/texk/texlive/linked_scripts/latexindent/latexindent.pl
===================================================================
(Binary files differ)

Modified: trunk/Master/bin/win32/latexindent.exe
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/support/latexindent/README
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/README	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/README	2020-03-21 21:20:37 UTC (rev 54454)
@@ -1,5 +1,5 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-    latexindent.pl, version 3.7.1, 2019-09-07
+    latexindent.pl, version 3.8, 2020-03-21
 
     PERL script to indent code within environments, and align delimited 
     environments in .tex files.

Modified: trunk/Master/texmf-dist/doc/support/latexindent/latexindent.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/support/latexindent/latexindent.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/latexindent.tex	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/latexindent.tex	2020-03-21 21:20:37 UTC (rev 54454)
@@ -1,8 +1,8 @@
 % arara: pdflatex: {shell: yes}
 % arara: bibtex
-% arara: pdflatex: {shell: yes}
-% arara: pdflatex: {shell: yes}
-% arara: pdflatex: {shell: yes}
+% arara: pdflatex: {shell: yes} if changed (toFile('latexindent.aux')) 
+% arara: pdflatex: {shell: yes} if changed (toFile('latexindent.aux')) 
+% arara: pdflatex: {shell: yes} if changed (toFile('latexindent.aux')) 
 \documentclass[10pt]{article}
 %   This program is free software: you can redistribute it and/or modify
 %   it under the terms of the GNU General Public License as published by
@@ -360,129 +360,135 @@
 	numbers=left,
 }
 
+\lstdefinestyle{lookForAlignDelims}{
+	style=yaml-LST,
+	firstnumber=148,linerange={148-164},
+	numbers=left,
+}
+
 \lstdefinestyle{indentAfterItems}{
 	style=yaml-LST,
-	firstnumber=187,linerange={187-191},
+	firstnumber=191,linerange={191-195},
 	numbers=left,
 }
 
 \lstdefinestyle{itemNames}{
 	style=yaml-LST,
-	firstnumber=197,linerange={197-199},
+	firstnumber=201,linerange={201-203},
 	numbers=left,
 }
 
 \lstdefinestyle{specialBeginEnd}{
 	style=yaml-LST,
-	firstnumber=203,linerange={203-216},
+	firstnumber=207,linerange={207-220},
 	numbers=left,
 }
 
 \lstdefinestyle{indentAfterHeadings}{
 	style=yaml-LST,
-	firstnumber=226,linerange={226-235},
+	firstnumber=230,linerange={230-239},
 	numbers=left,
 }
 
 \lstdefinestyle{noAdditionalIndentGlobalEnv}{
 	style=yaml-LST,
-	firstnumber=284,linerange={284-285},
+	firstnumber=288,linerange={288-289},
 	numbers=left,
 }
 
 \lstdefinestyle{noAdditionalIndentGlobal}{
 	style=yaml-LST,
-	firstnumber=284,linerange={284-296},
+	firstnumber=288,linerange={288-300},
 	numbers=left,
 }
 
 \lstdefinestyle{indentRulesGlobalEnv}{
 	style=yaml-LST,
-	firstnumber=300,linerange={300-301},
+	firstnumber=304,linerange={304-305},
 	numbers=left,
 }
 
 \lstdefinestyle{indentRulesGlobal}{
 	style=yaml-LST,
-	firstnumber=300,linerange={300-312},
+	firstnumber=304,linerange={304-316},
 	numbers=left,
 }
 
 \lstdefinestyle{commandCodeBlocks}{
 	style=yaml-LST,
-	firstnumber=315,linerange={315-329},
+	firstnumber=319,linerange={319-333},
 	numbers=left,
 }
 
 \lstdefinestyle{modifylinebreaks}{
 	style=yaml-LST,
-	firstnumber=441,linerange={441-443},
+	firstnumber=445,linerange={445-447},
 	numbers=left,
 }
 
 \lstdefinestyle{textWrapOptions}{
 	style=yaml-LST,
-	firstnumber=468,linerange={468-469},
+	firstnumber=472,linerange={472-473},
 	numbers=left,
 }
 
 \lstdefinestyle{textWrapOptionsAll}{
 	style=yaml-LST,
-	firstnumber=468,linerange={468-484},
+	firstnumber=472,linerange={472-488},
 	numbers=left,
 }
 
 \lstdefinestyle{removeParagraphLineBreaks}{
 	style=yaml-LST,
-	firstnumber=485,linerange={485-499},
+	firstnumber=489,linerange={489-503},
 	numbers=left,
 }
 
 \lstdefinestyle{paragraphsStopAt}{
 	style=yaml-LST,
-	firstnumber=500,linerange={500-509},
+	firstnumber=504,linerange={504-513},
 	numbers=left,
 }
 
 \lstdefinestyle{oneSentencePerLine}{
 	style=yaml-LST,
-	firstnumber=444,linerange={444-467},
+	firstnumber=448,linerange={448-471},
 	numbers=left,
 }
 
 \lstdefinestyle{sentencesFollow}{
 	style=yaml-LST,
-	firstnumber=449,linerange={449-457},
+	firstnumber=453,linerange={453-461},
 	numbers=left,
 }
 
 \lstdefinestyle{sentencesBeginWith}{
 	style=yaml-LST,
-	firstnumber=458,linerange={458-461},
+	firstnumber=462,linerange={462-465},
 	numbers=left,
 }
 
 \lstdefinestyle{sentencesEndWith}{
 	style=yaml-LST,
-	firstnumber=462,linerange={462-467},
+	firstnumber=466,linerange={466-471},
 	numbers=left,
 }
 
 \lstdefinestyle{modifylinebreaksEnv}{
 	style=yaml-LST,
-	firstnumber=510,linerange={510-519},
+	firstnumber=514,linerange={514-523},
 	numbers=left,
 }
 
 \lstdefinestyle{replacements}{
 	style=yaml-LST,
-	firstnumber=571,linerange={571-579},
+	firstnumber=575,linerange={575-583},
 	numbers=left,
 }
 
 \lstdefinestyle{fineTuning}{
 	style=yaml-LST,
-	firstnumber=582,linerange={582-603},
+	firstnumber=586,linerange={586-607},
 	numbers=left,
 }
 

Modified: trunk/Master/texmf-dist/doc/support/latexindent/sec-conclusions-know-limitations.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/sec-conclusions-know-limitations.tex	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/sec-conclusions-know-limitations.tex	2020-03-21 21:20:37 UTC (rev 54454)
@@ -28,7 +28,7 @@
  that this will improve the efficiency of the script.
 
  You can run \texttt{latexindent} on any file;%
- \announce*{2019-07-13}*{ability to call latexindent on any file} if you don't specify an extension, then the extensions that you
+ \announce{2019-07-13}*{ability to call latexindent on any file} if you don't specify an extension, then the extensions that you
  specify in \lstinline[breaklines=true]!fileExtensionPreference! (see \vref{lst:fileExtensionPreference}) will be consulted. If you
  find a case in which the script struggles, please feel free to report it at
  \cite{latexindent-home}, and in the meantime, consider using a \texttt{noIndentBlock} (see \cpageref{lst:noIndentBlockdemo}).

Modified: trunk/Master/texmf-dist/doc/support/latexindent/sec-default-user-local.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/sec-default-user-local.tex	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/sec-default-user-local.tex	2020-03-21 21:20:37 UTC (rev 54454)
@@ -18,15 +18,13 @@
 	\begin{commandshell}
 latexindent.pl myfile
 \end{commandshell}
-	\begin{wrapfigure}[8]{r}[0pt]{6cm}
-		\cmhlistingsfromfile[style=fileExtensionPreference]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{\texttt{fileExtensionPreference}}{lst:fileExtensionPreference}
-	\end{wrapfigure}
-
 	in which case the script will look for \texttt{myfile} with the extensions
 	specified in \texttt{fileExtensionPreference} in their numeric order. If no match is found, the
 	script will exit. As with all of the fields, you should change and/or add to this as
 	necessary.
 
+	\cmhlistingsfromfile[style=fileExtensionPreference]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{\texttt{fileExtensionPreference}}{lst:fileExtensionPreference}
+
 	Calling \texttt{latexindent.pl myfile} with the (default) settings specified in
 	\cref{lst:fileExtensionPreference} means that the script will first look for
 	\texttt{myfile.tex}, then \texttt{myfile.sty}, \texttt{myfile.cls}, and
@@ -128,14 +126,13 @@
 
 \yamltitle{noIndentBlock}*{fields}
 
-	\begin{wrapfigure}[8]{r}[0pt]{6cm}
-		\cmhlistingsfromfile[style=noIndentBlock]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{\texttt{noIndentBlock}}{lst:noIndentBlock}
-	\end{wrapfigure}
 	If you have a block of code that you don't want \texttt{latexindent.pl} to touch (even if
 	it is \emph{not} a verbatim-like environment) then you can wrap it in an
 	environment from \texttt{noIndentBlock}; you can use any name you like for this,
 	provided you populate it as demonstrate in \cref{lst:noIndentBlock}.
 
+	\cmhlistingsfromfile[style=noIndentBlock]*{../defaultSettings.yaml}[width=.4\linewidth,before=\centering,yaml-TCB]{\texttt{noIndentBlock}}{lst:noIndentBlock}
+
 	Of course, you don't want to have to specify these as null environments in your code, so
 	you use them with a comment symbol, \lstinline!%!, followed by as many spaces
 	(possibly none) as you like; see \cref{lst:noIndentBlockdemo} for example.
@@ -152,14 +149,6 @@
 
 \yamltitle{removeTrailingWhitespace}*{fields}\label{yaml:removeTrailingWhitespace}
 
-	\begin{wrapfigure}[10]{r}[0pt]{7cm}
-		\cmhlistingsfromfile[style=removeTrailingWhitespace]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{removeTrailingWhitespace}{lst:removeTrailingWhitespace}
-
-		\vspace{.1cm}
-		\begin{yaml}[numbers=none]{removeTrailingWhitespace (alt)}[width=.8\linewidth,before=\centering]{lst:removeTrailingWhitespace-alt}
-removeTrailingWhitespace: 1
-\end{yaml}
-	\end{wrapfigure}
 	Trailing white space can be removed both \emph{before} and
 	\emph{after} processing the document, as detailed in \cref{lst:removeTrailingWhitespace};
 	each of the fields can take the values \texttt{0} or
@@ -166,6 +155,16 @@
 	\texttt{1}. See \vref{lst:removeTWS-before,lst:env-mlb5-modAll,lst:env-mlb5-modAll-remove-WS} for before and after results. Thanks
 	to \cite{vosskuhle} for providing this feature.
 
+	\begin{minipage}{.4\textwidth}
+		\cmhlistingsfromfile[style=removeTrailingWhitespace]*{../defaultSettings.yaml}[before=\centering,yaml-TCB]{removeTrailingWhitespace}{lst:removeTrailingWhitespace}
+	\end{minipage}%
+	\hfill
+	\begin{minipage}{.5\textwidth}
+		\begin{yaml}[numbers=none]{removeTrailingWhitespace (alt)}[before=\centering]{lst:removeTrailingWhitespace-alt}
+removeTrailingWhitespace: 1
+\end{yaml}
+	\end{minipage}%
+
 	You can specify \texttt{removeTrailingWhitespace} simply as \texttt{0} or
 	\texttt{1}, if you wish; in this case,%
 	\announce{2017-06-28}{removeTrailingWhitespace} \texttt{latexindent.pl} will set both \texttt{beforeProcessing} and
@@ -172,9 +171,6 @@
 	\texttt{afterProcessing} to the value you specify; see \cref{lst:removeTrailingWhitespace-alt}.
 \yamltitle{fileContentsEnvironments}*{field}
 
-	\begin{wrapfigure}[6]{r}[0pt]{6cm}
-		\cmhlistingsfromfile[style=fileContentsEnvironments]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{\texttt{fileContentsEnvironments}}{lst:fileContentsEnvironments}
-	\end{wrapfigure}
 	Before \texttt{latexindent.pl} determines the difference between preamble (if any) and
 	the main document, it first searches for any of the environments specified in
 	\texttt{fileContentsEnvironments}, see \cref{lst:fileContentsEnvironments}. The behaviour of
@@ -181,6 +177,8 @@
 	\texttt{latexindent.pl} on these environments is determined by their location (preamble
 	or not), and the value \texttt{indentPreamble}, discussed next.
 
+	\cmhlistingsfromfile[style=fileContentsEnvironments]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{\texttt{fileContentsEnvironments}}{lst:fileContentsEnvironments}
+
 \yamltitle{indentPreamble}{0|1}
 
 	The preamble of a document can sometimes contain some trickier code for
@@ -191,9 +189,6 @@
 
 \yamltitle{lookForPreamble}*{fields}
 
-	\begin{wrapfigure}[8]{r}[0pt]{5cm}
-		\cmhlistingsfromfile[style=lookForPreamble]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{lookForPreamble}{lst:lookForPreamble}
-	\end{wrapfigure}
 	Not all files contain preamble; for example, \texttt{sty},
 	\texttt{cls} and \texttt{bib} files typically do
 	\emph{not}. Referencing \cref{lst:lookForPreamble}, if you set, for example,
@@ -200,6 +195,8 @@
 	\texttt{.tex} to \texttt{0}, then regardless of the setting of the
 	value of \texttt{indentPreamble}, preamble will not be assumed when operating upon
 	\texttt{.tex} files.
+
+	\cmhlistingsfromfile[style=lookForPreamble]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{lookForPreamble}{lst:lookForPreamble}
 \yamltitle{preambleCommandsBeforeEnvironments}{0|1}
 	Assuming that \texttt{latexindent.pl} is asked to operate upon the preamble of a
 	document, when this switch is set to \texttt{0} then environment code blocks
@@ -223,8 +220,13 @@
 	\emph{remove} all indentation by setting \texttt{defaultIndent: ""}.
 
 \yamltitle{lookForAlignDelims}*{fields}\label{yaml:lookforaligndelims}
-	\begin{wrapfigure}[12]{r}[0pt]{5cm}
-		\begin{yaml}[numbers=none]{\texttt{lookForAlignDelims} (basic)}[width=.8\linewidth,before=\centering]{lst:aligndelims:basic}
+	This contains a list of environments and/or commands that are operated upon in a special
+	way by \texttt{latexindent.pl} (see \cref{lst:aligndelims:basic}). In fact, the fields in \texttt{lookForAlignDelims} can
+	actually take two different forms: the \emph{basic} version is shown in
+	\cref{lst:aligndelims:basic} and the \emph{advanced} version in
+	\cref{lst:aligndelims:advanced}; we will discuss each in turn.
+
+	\begin{yaml}[numbers=none]{\texttt{lookForAlignDelims} (basic)}[width=.8\linewidth,before=\centering]{lst:aligndelims:basic}
 lookForAlignDelims:
    tabular: 1
    tabularx: 1
@@ -233,12 +235,6 @@
    matrix: 1
    ...
 	\end{yaml}
-	\end{wrapfigure}
-	This contains a list of environments and/or commands that are operated upon in a special
-	way by \texttt{latexindent.pl} (see \cref{lst:aligndelims:basic}). In fact, the fields in \texttt{lookForAlignDelims} can
-	actually take two different forms: the \emph{basic} version is shown in
-	\cref{lst:aligndelims:basic} and the \emph{advanced} version in
-	\cref{lst:aligndelims:advanced}; we will discuss each in turn.
 
 	The environments specified in this field will be operated on in a special way by
 	\texttt{latexindent.pl}. In particular, it will try and align each column by its
@@ -261,7 +257,7 @@
 	delimiter-aligned block, then the advanced form of \texttt{lookForAlignDelims} shown in
 	\cref{lst:aligndelims:advanced} is for you.
 
-	\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/tabular.yaml}[yaml-TCB]{\texttt{tabular.yaml}}{lst:aligndelims:advanced}
+	\cmhlistingsfromfile*[style=lookForAlignDelims]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{\texttt{lookForAlignDelims} (advanced)}{lst:aligndelims:advanced}
 
 	Note that you can use a mixture of the basic and advanced form: in
 	\cref{lst:aligndelims:advanced} \texttt{tabular} and \texttt{tabularx} are advanced
@@ -292,11 +288,25 @@
 		      $\geq$ 0) of
 		      spaces to be placed \emph{After} ampersands (default: 1);
 		\item \announce{2018-01-13}{justification of cells in ampersand alignment}\texttt{justification}: optionally specifies the justification of
-		      each cell as either \emph{left} or \emph{right} (default: left).
+		      each cell as either \emph{left} or \emph{right} (default: left);
+		\item \announce*{2020-03-21}{align final double back slash}{alignFinalDoubleBackSlash} optionally specifies if the
+		      \emph{final} double back slash should be used for alignment (default: 0);
+		\item \announce*{2020-03-21}{don't measure feature}{dontMeasure} optionally specifies if
+		      user-specified cells, rows or the largest entries should \emph{not} be
+		      measured (default: 0);
+		\item \announce*{2020-03-21}{delimiter RegEx feature}{delimiterRegEx} optionally specifies the pattern
+		      matching to be used for the alignment delimeter (default: \lstinline3 '(?<!\\)(&)'3);
+		\item \announce*{2020-03-21}{delimiter justification}{delimiterJustification} optionally specifies the justification
+		      for the alignment delimeters (default: left); note that this feature is only useful if
+		      you have delimiters of different lengths in the same column, discussed in
+		      \cref{sec:delimiter-reg-ex}.
 	\end{itemize}
 
-	We will explore each of these features using the file \texttt{tabular2.tex} in
-	\cref{lst:tabular2} (which contains a \lstinline!\multicolumn! command), and the YAML files in \crefrange{lst:tabular2YAML}{lst:tabular8YAML}.
+	We will explore most of these features using the file \texttt{tabular2.tex} in
+	\cref{lst:tabular2} (which contains a \lstinline!\multicolumn! command), and the YAML files in \crefrange{lst:tabular2YAML}{lst:tabular8YAML}; we will explore
+	\texttt{alignFinalDoubleBackSlash} in \cref{lst:tabular4}; the \texttt{dontMeasure} feature
+	will be described in \cref{sec:dontMeasure}, and \texttt{delimiterRegEx} in
+	\cref{sec:delimiter-reg-ex}.
 
 	\cmhlistingsfromfile{demonstrations/tabular2.tex}{\texttt{tabular2.tex}}{lst:tabular2}
 	\begin{minipage}{.45\textwidth}
@@ -384,6 +394,34 @@
 		      correctly, because of the settings in \cref{lst:tabular2YAML}.
 	\end{itemize}
 
+	We explore%
+	\announce*{2020-03-21}{alignFinalDoubleBackSlash demonstration} the
+	\texttt{alignFinalDoubleBackSlash} feature by using the file in \cref{lst:tabular4}. Upon
+	running the following commands
+	\begin{commandshell}
+latexindent.pl tabular4.tex -o=+-default
+latexindent.pl tabular4.tex -o=+-FDBS -y="lookForAlignDelims:tabular:alignFinalDoubleBackSlash:1"
+\end{commandshell}
+	then we receive the respective outputs given in \cref{lst:tabular4-default} and
+	\cref{lst:tabular4-FDBS}.
+
+	\begin{cmhtcbraster}[raster columns=3,
+			raster left skip=-3.75cm,
+			raster right skip=-2cm,]
+		\cmhlistingsfromfile*{demonstrations/tabular4.tex}{\texttt{tabular4.tex}}{lst:tabular4}
+		\cmhlistingsfromfile*{demonstrations/tabular4-default.tex}{\texttt{tabular4-default.tex}}{lst:tabular4-default}
+		\cmhlistingsfromfile*{demonstrations/tabular4-FDBS.tex}{\texttt{tabular4-FDBS.tex}}{lst:tabular4-FDBS}
+	\end{cmhtcbraster}
+
+	We note that in:
+	\begin{itemize}
+		\item \cref{lst:tabular4-default}, by default, the \emph{first} set of double back
+		      slashes in the first row of the \texttt{tabular} environment have been used for
+		      alignment;
+		\item \cref{lst:tabular4-FDBS}, the \emph{final} set of double back slashes in the
+		      first row have been used, because we specified \texttt{alignFinalDoubleBackSlash} as 1.
+	\end{itemize}
+
 	As of Version 3.0, the alignment routine works on mandatory and optional arguments within
 	commands, and also within `special' code blocks (see \texttt{specialBeginEnd} on
 	\cpageref{yaml:specialBeginEnd}); for example, assuming that you have a command called
@@ -419,6 +457,207 @@
 	(see \vref{sec:noadd-indent-rules}), these comment-marked blocks are
 	considered \texttt{environments}.
 
+\subsection{lookForAlignDelims: the dontMeasure feature}\label{sec:dontMeasure}
+	The%
+	\announce*{2020-03-21}{don't measure feature} \texttt{lookForAlignDelims}
+	field can, optionally, receive the \texttt{dontMeasure} option which can be specified
+	in a few different ways. We will explore this feature in relation to the code given in
+	\cref{lst:tabular-DM}; the default output is shown in \cref{lst:tabular-DM-default}.
+
+	\begin{cmhtcbraster}
+		\cmhlistingsfromfile*{demonstrations/tabular-DM.tex}{\texttt{tabular-DM.tex}}{lst:tabular-DM}
+		\cmhlistingsfromfile*{demonstrations/tabular-DM-default.tex}{\texttt{tabular-DM.tex} default output}{lst:tabular-DM-default}
+	\end{cmhtcbraster}
+
+	The \texttt{dontMeasure} field can be specified as \texttt{largest}, and in
+	which case, the largest element will not be measured; with reference to the YAML file
+	given in \cref{lst:dontMeasure1}, we can run the command
+	\begin{commandshell} 
+latexindent.pl tabular-DM.tex -l=dontMeasure1.yaml
+\end{commandshell}
+	and receive the output given in \cref{lst:tabular-DM-mod1}.
+
+	\begin{cmhtcbraster}
+		\cmhlistingsfromfile*{demonstrations/tabular-DM-mod1.tex}{\texttt{tabular-DM.tex} using \cref{lst:dontMeasure1}}{lst:tabular-DM-mod1}
+		\cmhlistingsfromfile*{demonstrations/dontMeasure1.yaml}[yaml-TCB]{\texttt{dontMeasure1.yaml}}{lst:dontMeasure1}
+	\end{cmhtcbraster}
+
+	We note that the \emph{largest} column entries have not contributed to the
+	measuring routine.
+
+	The \texttt{dontMeasure} field can also be specified in the form demonstrated in
+	\cref{lst:dontMeasure2}. On running the following commands,
+	\begin{commandshell} 
+latexindent.pl tabular-DM.tex -l=dontMeasure2.yaml
+\end{commandshell}
+	we receive the output in \cref{lst:tabular-DM-mod2}.
+
+	\begin{cmhtcbraster}
+		\cmhlistingsfromfile*{demonstrations/tabular-DM-mod2.tex}{\texttt{tabular-DM.tex} using \cref{lst:dontMeasure2} or \cref{lst:dontMeasure3}}{lst:tabular-DM-mod2}
+		\cmhlistingsfromfile*{demonstrations/dontMeasure2.yaml}[yaml-TCB]{\texttt{dontMeasure2.yaml}}{lst:dontMeasure2}
+	\end{cmhtcbraster}
+
+	We note that in \cref{lst:dontMeasure2} we have specified entries not to be measured, one
+	entry per line.
+
+	The \texttt{dontMeasure} field can also be specified in the forms demonstrated in
+	\cref{lst:dontMeasure3} and \cref{lst:dontMeasure4}. Upon running the commands
+	\begin{commandshell} 
+latexindent.pl tabular-DM.tex -l=dontMeasure3.yaml
+latexindent.pl tabular-DM.tex -l=dontMeasure4.yaml
+\end{commandshell}
+	we receive the output given in \cref{lst:tabular-DM-mod3}
+	\begin{cmhtcbraster}[raster columns=3,
+			raster left skip=-3.5cm,
+			raster right skip=-2cm,
+			raster column skip=.03\linewidth]
+		\cmhlistingsfromfile*{demonstrations/tabular-DM-mod3.tex}{\texttt{tabular-DM.tex} using \cref{lst:dontMeasure3} or \cref{lst:dontMeasure3}}{lst:tabular-DM-mod3}
+		\cmhlistingsfromfile*{demonstrations/dontMeasure3.yaml}[yaml-TCB]{\texttt{dontMeasure3.yaml}}{lst:dontMeasure3}
+		\cmhlistingsfromfile*{demonstrations/dontMeasure4.yaml}[yaml-TCB]{\texttt{dontMeasure4.yaml}}{lst:dontMeasure4}
+	\end{cmhtcbraster}
+	We note that in:
+	\begin{itemize}
+		\item \cref{lst:dontMeasure3} we have specified entries not to be measured, each one has a
+		      \emph{string} in the \texttt{this}
+		      field, together with an optional specification of \texttt{applyTo} as
+		      \texttt{cell};
+		\item \cref{lst:dontMeasure4} we have specified entries not to be measured as a
+		      \emph{regular expression} using
+		      the \texttt{regex} field, together with an optional specification of
+		      \texttt{applyTo} as \texttt{cell} field, together with an optional
+		      specification of \texttt{applyTo} as \texttt{cell}.
+	\end{itemize}
+	In both cases, the default value of \texttt{applyTo} is \texttt{cell},
+	and does not need to be specified.
+
+	We may also specify the \texttt{applyTo} field as \texttt{row}, a
+	demonstration of which is given in \cref{lst:dontMeasure5}; upon running
+	\begin{commandshell} 
+latexindent.pl tabular-DM.tex -l=dontMeasure5.yaml
+\end{commandshell}
+	we receive the output in \cref{lst:tabular-DM-mod5}.
+	\begin{cmhtcbraster}
+		\cmhlistingsfromfile*{demonstrations/tabular-DM-mod5.tex}{\texttt{tabular-DM.tex} using \cref{lst:dontMeasure5}}{lst:tabular-DM-mod5}
+		\cmhlistingsfromfile*{demonstrations/dontMeasure5.yaml}[yaml-TCB]{\texttt{dontMeasure5.yaml}}{lst:dontMeasure5}
+	\end{cmhtcbraster}
+
+	Finally, the \texttt{applyTo} field can be specified as \texttt{row},
+	together with a \texttt{regex} expression. For example, for the settings given
+	in \cref{lst:dontMeasure6}, upon running
+	\begin{commandshell} 
+latexindent.pl tabular-DM.tex -l=dontMeasure6.yaml
+\end{commandshell}
+	we receive the output in \cref{lst:tabular-DM-mod6}.
+
+	\begin{cmhtcbraster}
+		\cmhlistingsfromfile*{demonstrations/tabular-DM-mod6.tex}{\texttt{tabular-DM.tex} using \cref{lst:dontMeasure6}}{lst:tabular-DM-mod6}
+		\cmhlistingsfromfile*{demonstrations/dontMeasure6.yaml}[yaml-TCB]{\texttt{dontMeasure6.yaml}}{lst:dontMeasure6}
+	\end{cmhtcbraster}
+
+\subsection{lookForAlignDelims: the delimiterRegEx and delimiterJustification feature}\label{sec:delimiter-reg-ex}
+	The delimiter alignment%
+	\announce*{2020-03-21}{delimiterRegEx feature} will, by
+	default, align code blocks at the ampersand character. The behaviour is controlled by the
+	\texttt{delimiterRegEx} field within \texttt{lookForAlignDelims}; the default value is
+	\lstinline3'(?<!\\)(&)'3, which can be read as: \emph{an ampersand, as long as it is not immediately preceeded by a backslash}.
+
+	\begin{warning}
+		Important: note the `capturing' parenthesis in the \lstinline!(&)! which are necessary; if you
+		intend to customise this field, then be sure to include them appropriately.
+	\end{warning}
+
+	We demonstrate how to customise this with respect to the code given in
+	\cref{lst:tabbing}; the default output from \lstinline!latexindent.pl! is given in
+	\cref{lst:tabbing-default}.
+
+	\begin{cmhtcbraster}
+		\cmhlistingsfromfile*{demonstrations/tabbing.tex}{\texttt{tabbing.tex}}{lst:tabbing}
+		\cmhlistingsfromfile*{demonstrations/tabbing-default.tex}{\texttt{tabbing.tex} default output}{lst:tabbing-default}
+	\end{cmhtcbraster}
+
+	Let's say that we wish to align the code at either the \lstinline!\=! or
+	\lstinline!\>!. We employ the settings given in \cref{lst:delimiterRegEx1} and run
+	the command
+	\begin{commandshell}
+latexindent.pl tabbing.tex -l=delimiterRegEx1.yaml
+\end{commandshell}
+	to receive the output given in \cref{lst:tabbing-mod1}.
+
+	\begin{cmhtcbraster}
+		\cmhlistingsfromfile*{demonstrations/tabbing-mod1.tex}{\texttt{tabbing.tex} using \cref{lst:delimiterRegEx1}}{lst:tabbing-mod1}
+		\cmhlistingsfromfile*{demonstrations/delimiterRegEx1.yaml}[yaml-TCB]{\texttt{delimiterRegEx1.yaml}}{lst:delimiterRegEx1}
+	\end{cmhtcbraster}
+	We note that:
+	\begin{itemize}
+		\item in \cref{lst:tabbing-mod1} the code has been aligned, as intended, at both the
+		      \lstinline!\=! and \lstinline!\>!;
+		\item in \cref{lst:delimiterRegEx1} we have heeded the warning and captured the expression using
+		      grouping parenthesis, specified a backslash using \lstinline!\\! and said that
+		      it must be followed by either \lstinline!=! or \lstinline!>!.
+	\end{itemize}
+	We can explore \texttt{delimiterRegEx} a little further using the settings in
+	\cref{lst:delimiterRegEx2} and run the command
+	\begin{commandshell}
+latexindent.pl tabbing.tex -l=delimiterRegEx2.yaml
+\end{commandshell}
+	to receive the output given in \cref{lst:tabbing-mod2}.
+
+	\begin{cmhtcbraster}
+		\cmhlistingsfromfile*{demonstrations/tabbing-mod2.tex}{\texttt{tabbing.tex} using \cref{lst:delimiterRegEx2}}{lst:tabbing-mod2}
+		\cmhlistingsfromfile*{demonstrations/delimiterRegEx2.yaml}[yaml-TCB]{\texttt{delimiterRegEx2.yaml}}{lst:delimiterRegEx2}
+	\end{cmhtcbraster}
+	We note that only the \lstinline!\>! have been aligned.
+
+	Of course, the other lookForAlignDelims options can be used alongside the
+	\texttt{delimiterRegEx}; regardless of the type of delimiter being used (ampersand or
+	anything else), the fields from \vref{lst:aligndelims:advanced} remain the same; for example,
+	using the settings in \cref{lst:delimiterRegEx3}, and running
+	\begin{commandshell}
+latexindent.pl tabbing.tex -l=delimiterRegEx3.yaml
+\end{commandshell}
+	to receive the output given in \cref{lst:tabbing-mod3}.
+
+	\begin{cmhtcbraster}
+		\cmhlistingsfromfile*{demonstrations/tabbing-mod3.tex}{\texttt{tabbing.tex} using \cref{lst:delimiterRegEx3}}{lst:tabbing-mod3}
+		\cmhlistingsfromfile*{demonstrations/delimiterRegEx3.yaml}[yaml-TCB]{\texttt{delimiterRegEx3.yaml}}{lst:delimiterRegEx3}
+	\end{cmhtcbraster}
+
+	It is possible that delimiters specified within \texttt{delimiterRegEx} can be of
+	different lengths. Consider the file in \cref{lst:tabbing1}, and associated YAML in
+	\cref{lst:delimiterRegEx4}. Note that the	      \cref{lst:delimiterRegEx4} specifies the
+	option for the delimiter to be either \lstinline!#! or \lstinline!\>!,
+	\emph{which are different lengths}. Upon running the command
+	\begin{commandshell}
+latexindent.pl tabbing1.tex -l=delimiterRegEx4.yaml -o=+-mod4
+\end{commandshell}
+	we receive the output in \cref{lst:tabbing1-mod4}.
+
+	\begin{cmhtcbraster}[raster columns=3,
+			raster left skip=-3.5cm,
+			raster right skip=-2cm,
+			raster column skip=.03\linewidth]
+		\cmhlistingsfromfile*{demonstrations/tabbing1.tex}{\texttt{tabbing1.tex}}{lst:tabbing1}
+		\cmhlistingsfromfile*{demonstrations/tabbing1-mod4.tex}{\texttt{tabbing1-mod4.tex}}{lst:tabbing1-mod4}
+		\cmhlistingsfromfile*{demonstrations/delimiterRegEx4.yaml}[yaml-TCB]{\texttt{delimiterRegEx4.yaml}}{lst:delimiterRegEx4}
+	\end{cmhtcbraster}
+
+	You can set the \emph{delimiter} justification as either \texttt{left} (default)
+	or \texttt{right}, which will only have effect when delimiters in the same
+	column have different lengths. Using the settings in \cref{lst:delimiterRegEx5} and running
+	the command
+	\begin{commandshell}
+latexindent.pl tabbing1.tex -l=delimiterRegEx5.yaml -o=+-mod5
+\end{commandshell}
+	gives the output in \cref{lst:tabbing1-mod5}.
+
+	\begin{cmhtcbraster}
+		\cmhlistingsfromfile*{demonstrations/tabbing1-mod5.tex}{\texttt{tabbing1-mod5.tex}}{lst:tabbing1-mod5}
+		\cmhlistingsfromfile*{demonstrations/delimiterRegEx5.yaml}[yaml-TCB]{\texttt{delimiterRegEx5.yaml}}{lst:delimiterRegEx5}
+	\end{cmhtcbraster}
+
+	Note that in \cref{lst:tabbing1-mod5} the second set of delimiters have been
+	\emph{right aligned} -- it is quite subtle!
+
 \yamltitle{indentAfterItems}*{fields}
 	The environment names specified in \texttt{indentAfterItems} tell \texttt{latexindent.pl}
 	to look for \lstinline!\item! commands; if these switches are set to
@@ -435,9 +674,6 @@
 	\end{cmhtcbraster}
 
 \yamltitle{itemNames}*{fields}
-	\begin{wrapfigure}[5]{r}[0pt]{5cm}
-		\cmhlistingsfromfile[style=itemNames]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{\texttt{itemNames}}{lst:itemNames}
-	\end{wrapfigure}
 	If you have your own \texttt{item} commands (perhaps you prefer to use
 	\texttt{myitem}, for example) then you can put populate them in
 	\texttt{itemNames}. For example, users of the \texttt{exam} document class
@@ -446,6 +682,8 @@
 	\vref{sec:indentconfig} for details of how to configure user settings, and
 	\vref{lst:mysettings} \\ in particular \label{page:examsettings}.)
 
+	\cmhlistingsfromfile[style=itemNames]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{\texttt{itemNames}}{lst:itemNames}
+
 \yamltitle{specialBeginEnd}*{fields}\label{yaml:specialBeginEnd}
 	The fields specified%
 	\announce{2017-08-21}*{specialBeginEnd} in
@@ -568,9 +806,6 @@
 	\end{cmhtcbraster}
 
 \yamltitle{indentAfterHeadings}*{fields}
-	\begin{wrapfigure}[17]{r}[0pt]{8cm}
-		\cmhlistingsfromfile[style=indentAfterHeadings]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{\texttt{indentAfterHeadings}}{lst:indentAfterHeadings}
-	\end{wrapfigure}
 	This field enables the user to specify indentation rules that take effect after heading
 	commands such as \lstinline!\part!, \lstinline!\chapter!,
 	\lstinline!\section!, \lstinline!\subsection*!, or indeed any user-specified command
@@ -577,12 +812,14 @@
 	written in this field.\footnote{There is a slight
 		difference in interface for this field when comparing Version 2.2 to Version 3.0; see \vref{app:differences} for details.}
 
+	\cmhlistingsfromfile[style=indentAfterHeadings]*{../defaultSettings.yaml}[width=.8\linewidth,before=\centering,yaml-TCB]{\texttt{indentAfterHeadings}}{lst:indentAfterHeadings}
+
 	The default settings do \emph{not} place indentation after a heading, but
-	you can easily switch them on by changing \\ \texttt{indentAfterThisHeading: 0} to \\
-	\texttt{indentAfterThisHeading: 1}. The \texttt{level} field tells \texttt{latexindent.pl}
-	the hierarchy of the heading structure in your document. You might, for example, like to
-	have both \texttt{section} and \texttt{subsection} set with
-	\texttt{level: 3} because you do not want the indentation to go too deep.
+	you can easily switch them on by changing \texttt{indentAfterThisHeading} from 0 to 1. The
+	\texttt{level} field tells \texttt{latexindent.pl} the hierarchy of the heading
+	structure in your document. You might, for example, like to have both
+	\texttt{section} and \texttt{subsection} set with \texttt{level: 3}
+	because you do not want the indentation to go too deep.
 
 	You can add any of your own custom heading commands to this field, specifying the
 	\texttt{level} as appropriate.  You can also specify your own indentation in
@@ -733,5 +970,5 @@
 	\end{table}
 
 	We will refer to these code blocks in what follows.%
-	\announce*{2019-07-13}{fine tuning of code blocks} Note that the fine tuning of the definition of the code blocks
+	\announce{2019-07-13}{fine tuning of code blocks} Note that the fine tuning of the definition of the code blocks
 	detailed in \cref{tab:code-blocks} is discussed in \vref{sec:finetuning}.

Modified: trunk/Master/texmf-dist/doc/support/latexindent/sec-fine-tuning.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/sec-fine-tuning.tex	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/sec-fine-tuning.tex	2020-03-21 21:20:37 UTC (rev 54454)
@@ -2,7 +2,7 @@
 \section{Fine tuning}\label{sec:finetuning}
  \texttt{latexindent.pl} operates by looking for the code blocks detailed in
  \vref{tab:code-blocks}.
- \announce*{2019-07-13}{details of fine tuning of code blocks} The fine tuning of the details of such code blocks
+ \announce{2019-07-13}{details of fine tuning of code blocks} The fine tuning of the details of such code blocks
  is controlled by the \texttt{fineTuning} field, detailed in \cref{lst:fineTuning}.
 
  This field is for those that would like to peek under the bonnet/hood and make some fine
@@ -14,7 +14,7 @@
  \end{warning}
 
  \begin{widepage}
-	 \cmhlistingsfromfile*[style=fineTuning]*{../defaultSettings.yaml}[width=0.95\linewidth,before=\centering,yaml-TCB]{\texttt{fineTuning}}{lst:fineTuning}
+	 \cmhlistingsfromfile[style=fineTuning]*{../defaultSettings.yaml}[width=0.95\linewidth,before=\centering,yaml-TCB]{\texttt{fineTuning}}{lst:fineTuning}
  \end{widepage}
 
  The fields given in \cref{lst:fineTuning} are all \emph{regular expressions}. This manual is
@@ -83,27 +83,63 @@
  \texttt{before} and \texttt{between} fields allow trailing comments, line
  breaks, and horizontal spaces between each character.
 
- As a demonstration, consider the file given in \cref{lst:finetuning1}, together with its
- default output using the command
- \begin{commandshell}
+ \begin{example}
+	 As a demonstration, consider the file given in \cref{lst:finetuning1}, together with its
+	 default output using the command
+	 \begin{commandshell}
 latexindent.pl finetuning1.tex 
 \end{commandshell}
- is given in \cref{lst:finetuning1-default}.
+	 is given in \cref{lst:finetuning1-default}.
 
- \begin{cmhtcbraster}[raster column skip=.01\linewidth]
-	 \cmhlistingsfromfile*{demonstrations/finetuning1.tex}{\texttt{finetuning1.tex}}{lst:finetuning1}
-	 \cmhlistingsfromfile*{demonstrations/finetuning1-default.tex}{\texttt{finetuning1.tex} default}{lst:finetuning1-default}
- \end{cmhtcbraster}
+	 \begin{cmhtcbraster}[raster column skip=.01\linewidth]
+		 \cmhlistingsfromfile{demonstrations/finetuning1.tex}{\texttt{finetuning1.tex}}{lst:finetuning1}
+		 \cmhlistingsfromfile{demonstrations/finetuning1-default.tex}{\texttt{finetuning1.tex} default}{lst:finetuning1-default}
+	 \end{cmhtcbraster}
 
- It's clear from \cref{lst:finetuning1-default} that the indentation scheme has not worked as
- expected. We can \emph{fine tune} the indentation scheme by employing the settings
- given in \cref{lst:fine-tuning1} and running the command
- \begin{commandshell}
+	 It's clear from \cref{lst:finetuning1-default} that the indentation scheme has not worked as
+	 expected. We can \emph{fine tune} the indentation scheme by employing the settings
+	 given in \cref{lst:fine-tuning1} and running the command
+	 \begin{commandshell}
 latexindent.pl finetuning1.tex -l=fine-tuning1.yaml
 \end{commandshell}
- and the associated (desired) output is given in \cref{lst:finetuning1-mod1}.
+	 and the associated (desired) output is given in \cref{lst:finetuning1-mod1}.
 
- \begin{cmhtcbraster}[raster column skip=.01\linewidth]
-	 \cmhlistingsfromfile*{demonstrations/finetuning1-mod1.tex}{\texttt{finetuning1.tex} using \cref{lst:fine-tuning1}}{lst:finetuning1-mod1}
-	 \cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/fine-tuning1.yaml}[yaml-TCB]{\texttt{finetuning1.yaml}}{lst:fine-tuning1}
- \end{cmhtcbraster}
+	 \begin{cmhtcbraster}[raster column skip=.01\linewidth]
+		 \cmhlistingsfromfile{demonstrations/finetuning1-mod1.tex}{\texttt{finetuning1.tex} using \cref{lst:fine-tuning1}}{lst:finetuning1-mod1}
+		 \cmhlistingsfromfile[style=yaml-LST]*{demonstrations/fine-tuning1.yaml}[yaml-TCB]{\texttt{finetuning1.yaml}}{lst:fine-tuning1}
+	 \end{cmhtcbraster}
+ \end{example}
+
+ \begin{example}
+	 Let's have another demonstration; consider the file given in \cref{lst:finetuning2}, together with its
+	 default output using the command
+	 \begin{commandshell}
+latexindent.pl finetuning2.tex 
+\end{commandshell}
+	 is given in \cref{lst:finetuning2-default}.
+
+	 \begin{cmhtcbraster}[raster column skip=.01\linewidth,
+			 raster left skip=-3.75cm,
+			 raster right skip=0cm,]
+		 \cmhlistingsfromfile*{demonstrations/finetuning2.tex}{\texttt{finetuning2.tex}}{lst:finetuning2}
+		 \cmhlistingsfromfile*{demonstrations/finetuning2-default.tex}{\texttt{finetuning2.tex} default}{lst:finetuning2-default}
+	 \end{cmhtcbraster}
+
+	 It's clear from \cref{lst:finetuning2-default} that the indentation scheme has not worked as
+	 expected. We can \emph{fine tune} the indentation scheme by employing the settings
+	 given in \cref{lst:fine-tuning2} and running the command
+	 \begin{commandshell}
+latexindent.pl finetuning2.tex -l=fine-tuning2.yaml
+\end{commandshell}
+	 and the associated (desired) output is given in \cref{lst:finetuning2-mod1}.
+
+	 \begin{cmhtcbraster}[raster column skip=.01\linewidth,
+			 raster left skip=-3.75cm,
+			 raster right skip=0cm,]
+		 \cmhlistingsfromfile*{demonstrations/finetuning2-mod1.tex}{\texttt{finetuning2.tex} using \cref{lst:fine-tuning2}}{lst:finetuning2-mod1}
+		 \cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/fine-tuning2.yaml}[yaml-TCB]{\texttt{finetuning2.yaml}}{lst:fine-tuning2}
+	 \end{cmhtcbraster}
+
+	 In particular, note that the settings in \cref{lst:fine-tuning2} specify that \texttt{NamedGroupingBracesBrackets}
+	 and \texttt{UnNamedGroupingBracesBrackets} can follow \texttt{"} and that we allow \lstinline!---! between arguments.
+ \end{example}

Modified: trunk/Master/texmf-dist/doc/support/latexindent/sec-how-to-use.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/sec-how-to-use.tex	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/sec-how-to-use.tex	2020-03-21 21:20:37 UTC (rev 54454)
@@ -286,7 +286,7 @@
 
 	If you wish to have backup files and \texttt{indent.log} written to a directory other
 	than the current working directory, then you can send these `cruft' files to another
-	directory. % this switch was made as a result of http://tex.stackexchange.com/questions/142652/output-latexindent-auxiliary-files-to-a-different-directory
+	directory. Note the use of a trailing forward slash. % this switch was made as a result of http://tex.stackexchange.com/questions/142652/output-latexindent-auxiliary-files-to-a-different-directory
 
 \flagbox{-g, --logfile=<name of log file>}
 	\begin{commandshell}
@@ -329,13 +329,20 @@
 \flagbox{STDIN}
 	\begin{commandshell}
 cat myfile.tex | latexindent.pl
+cat myfile.tex | latexindent.pl -
 \end{commandshell}
 	\texttt{latexindent.pl} will%
 	\announce{2018-01-13}{STDIN allowed} allow input from STDIN, which means that you can pipe output from
 	other commands directly into the script. For example assuming that you have content in
 	\texttt{myfile.tex}, then the above command will output the results of operating upon
-	\texttt{myfile.tex}
+	\texttt{myfile.tex}. 
 
+    If you wish to use this feature with your own local settings, via the \texttt{-l} switch, 
+    then you should finish your call to \texttt{latexindent.pl} with a \texttt{-} sign:
+	\begin{commandshell}
+cat myfile.tex | latexindent.pl -l=mysettings.yaml -
+\end{commandshell}
+
 	Similarly, if you%
 	\announce{2018-01-13}*{no options/filename updated} simply type
 	\texttt{latexindent.pl} at the command line, then it will expect (STDIN) input from the
@@ -357,7 +364,7 @@
 latexindent.pl -replacement myfile.tex
 \end{commandshell}
 	You can%
-	\announce*{2019-07-13}{replacement mode switch} call
+	\announce{2019-07-13}{replacement mode switch} call
 	\texttt{latexindent.pl} with the \texttt{-r} switch to instruct it to perform
 	replacements/substitutions on your file; full details and examples are given in
 	\vref{sec:replacements}.
@@ -368,7 +375,7 @@
 latexindent.pl -replacementrespectverb myfile.tex
 \end{commandshell}
 	You can%
-	\announce*{2019-07-13}{replacement mode switch, respecting verbatim} instruct
+	\announce{2019-07-13}{replacement mode switch, respecting verbatim} instruct
 	\texttt{latexindent.pl} to perform replacements/substitutions by using the
 	\texttt{-rv} switch, but will \emph{respect verbatim code blocks}; full details and
 	examples are given in \vref{sec:replacements}.
@@ -379,7 +386,7 @@
 latexindent.pl -onlyreplacement myfile.tex
 \end{commandshell}
 	You can%
-	\announce*{2019-07-13}{replacement (only) mode switch} instruct
+	\announce{2019-07-13}{replacement (only) mode switch} instruct
 	\texttt{latexindent.pl} to skip all of its other indentation operations and
 	\emph{only} perform replacements/substitutions by using the
 	\texttt{-rr} switch; full details and examples are given in

Modified: trunk/Master/texmf-dist/doc/support/latexindent/sec-introduction.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/sec-introduction.tex	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/sec-introduction.tex	2020-03-21 21:20:37 UTC (rev 54454)
@@ -87,7 +87,7 @@
 	\end{minipage}%
 
 	\begin{minipage}{.55\textwidth}
-		\cmhlistingsfromfile*[style=replacements]*{../defaultSettings.yaml}[replace-TCB,width=.85\linewidth,before=\centering]{\texttt{replacements}}{lst:replacements-demo}
+		\cmhlistingsfromfile[style=replacements]*{../defaultSettings.yaml}[replace-TCB,width=.85\linewidth,before=\centering]{\texttt{replacements}}{lst:replacements-demo}
 	\end{minipage}%
 	\hfill
 	\begin{minipage}{.4\textwidth}
@@ -128,3 +128,9 @@
 \end{commandshell}
 	You might also like to see \href{https://stackoverflow.com/questions/19590042/error-cant-locate-file-homedir-pm-in-inc}{https://stackoverflow.com/questions/19590042/error-cant-locate-file-homedir-pm-in-inc}, for example, as well as
 	\vref{sec:requiredmodules}.
+
+\subsection{A word about regular expressions}
+	As you read this documentation, you may encounter the term \emph{regular expressions}. I've
+	tried to write this documentation in such a way so as to allow you to engage with them or
+	not, as you prefer. This documentation is not designed to be a guide to regular
+	expressions, and if you'd like to read about them, I recommend \cite{masteringregexp}.

Modified: trunk/Master/texmf-dist/doc/support/latexindent/sec-replacements.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/sec-replacements.tex	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/sec-replacements.tex	2020-03-21 21:20:37 UTC (rev 54454)
@@ -6,9 +6,8 @@
  }
 
  You can instruct \texttt{latexindent.pl} to perform replacements/substitutions on your
- \announce*{2019-07-13}{replacement mode switches}
- file by using any of the \texttt{-r}, \texttt{-rv} or
- \texttt{-rr} switches:
+ \announce{2019-07-13}{replacement mode switches} file by using any of the \texttt{-r},
+ \texttt{-rv} or \texttt{-rr} switches:
  \begin{itemize}
 	 \item the \texttt{-r} switch will perform indentation and replacements, not
 	       respecting verbatim code blocks;
@@ -42,7 +41,7 @@
  \texttt{-rr} switches are active; when discussing YAML settings related to the
  replacement-mode switches, we will use the style given in \cref{lst:replacements}.
 
- \cmhlistingsfromfile*[style=replacements]*{../defaultSettings.yaml}[width=0.95\linewidth,before=\centering,replace-TCB]{\texttt{replacements}}{lst:replacements}
+ \cmhlistingsfromfile[style=replacements]*{../defaultSettings.yaml}[width=0.95\linewidth,before=\centering,replace-TCB]{\texttt{replacements}}{lst:replacements}
 
  The first entry within the \texttt{replacements} field is \texttt{amalgamate}, and
  is \emph{optional}; by default it is set to 1, so that replacements will be
@@ -65,8 +64,8 @@
 	gives the output given in \cref{lst:replace1-r1}.
 
 	\begin{cmhtcbraster}[raster column skip=.01\linewidth]
-		\cmhlistingsfromfile*{demonstrations/replace1.tex}{\texttt{replace1.tex}}{lst:replace1}
-		\cmhlistingsfromfile*{demonstrations/replace1-r1.tex}{\texttt{replace1.tex} default}{lst:replace1-r1}
+		\cmhlistingsfromfile{demonstrations/replace1.tex}{\texttt{replace1.tex}}{lst:replace1}
+		\cmhlistingsfromfile{demonstrations/replace1-r1.tex}{\texttt{replace1.tex} default}{lst:replace1-r1}
 	\end{cmhtcbraster}
 
 	If we don't wish to perform this replacement, then we can tweak the default settings of
@@ -78,8 +77,8 @@
 	which gives the output in \cref{lst:replace1-mod1}.
 
 	\begin{cmhtcbraster}[raster column skip=.01\linewidth]
-		\cmhlistingsfromfile*{demonstrations/replace1-mod1.tex}{\texttt{replace1.tex} using \cref{lst:replace1-yaml}}{lst:replace1-mod1}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/replace1.yaml}[replace-TCB]{\texttt{replace1.yaml}}{lst:replace1-yaml}
+		\cmhlistingsfromfile{demonstrations/replace1-mod1.tex}{\texttt{replace1.tex} using \cref{lst:replace1-yaml}}{lst:replace1-mod1}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/replace1.yaml}[replace-TCB]{\texttt{replace1.yaml}}{lst:replace1-yaml}
 	\end{cmhtcbraster}
 
 	Note that in \cref{lst:replace1-yaml} we have specified \texttt{amalgamate} as 0 so
@@ -108,7 +107,7 @@
 	\begin{example}
 		We begin with code given in \cref{lst:colsep}
 
-		\cmhlistingsfromfile*{demonstrations/colsep.tex}{\texttt{colsep.tex}}{lst:colsep}
+		\cmhlistingsfromfile{demonstrations/colsep.tex}{\texttt{colsep.tex}}{lst:colsep}
 
 		Let's assume that our goal is to remove both of the \texttt{arraycolsep} statements; we can achieve this in
 		a few different ways.
@@ -119,8 +118,8 @@
 \end{commandshell}
 		then we achieve the output in \cref{lst:colsep-mod0}.
 		\begin{cmhtcbraster}[raster column skip=.01\linewidth]
-			\cmhlistingsfromfile*{demonstrations/colsep-mod0.tex}{\texttt{colsep.tex} using \cref{lst:colsep}}{lst:colsep-mod0}
-			\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/colsep.yaml}[replace-TCB]{\texttt{colsep.yaml}}{lst:colsep-yaml}
+			\cmhlistingsfromfile{demonstrations/colsep-mod0.tex}{\texttt{colsep.tex} using \cref{lst:colsep}}{lst:colsep-mod0}
+			\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/colsep.yaml}[replace-TCB]{\texttt{colsep.yaml}}{lst:colsep-yaml}
 		\end{cmhtcbraster}
 		Note that in \cref{lst:colsep-yaml}, we have specified \emph{two} separate fields, each with their own `\emph{this}' field;
 		furthermore, for both of the separate fields, we have not specified `\texttt{that}', so the \texttt{that} field
@@ -135,8 +134,8 @@
 		\begin{cmhtcbraster}[raster column skip=.01\linewidth,
 				raster force size=false,
 				raster column 1/.style={add to width=-.1\textwidth}]
-			\cmhlistingsfromfile*{demonstrations/colsep-mod1.tex}{\texttt{colsep.tex} using \cref{lst:colsep1}}{lst:colsep-mod1}
-			\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/colsep1.yaml}[replace-TCB,width=0.6\textwidth]{\texttt{colsep1.yaml}}{lst:colsep1}
+			\cmhlistingsfromfile{demonstrations/colsep-mod1.tex}{\texttt{colsep.tex} using \cref{lst:colsep1}}{lst:colsep-mod1}
+			\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/colsep1.yaml}[replace-TCB,width=0.6\textwidth]{\texttt{colsep1.yaml}}{lst:colsep1}
 		\end{cmhtcbraster}
 
 		The code given in \cref{lst:colsep1} is an example of a \emph{regular expression}, which we may abbreviate to \emph{regex}
@@ -168,8 +167,8 @@
 \end{commandshell}
 		then we achieve the output in \cref{lst:colsep-mod2}.
 		\begin{cmhtcbraster}[raster column skip=.01\linewidth]
-			\cmhlistingsfromfile*{demonstrations/colsep-mod2.tex}{\texttt{colsep.tex} using \cref{lst:multi-line}}{lst:colsep-mod2}
-			\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/multi-line.yaml}[replace-TCB]{\texttt{multi-line.yaml}}{lst:multi-line}
+			\cmhlistingsfromfile{demonstrations/colsep-mod2.tex}{\texttt{colsep.tex} using \cref{lst:multi-line}}{lst:colsep-mod2}
+			\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/multi-line.yaml}[replace-TCB]{\texttt{multi-line.yaml}}{lst:multi-line}
 		\end{cmhtcbraster}
 		With reference to \cref{lst:multi-line}, we have specified a \emph{multi-line} version of \texttt{this} by employing the \emph{literal}
 		YAML style \lstinline!|-!. See, for example, \href{https://stackoverflow.com/questions/3790454/in-yaml-how-do-i-break-a-string-over-multiple-lines}{https://stackoverflow.com/questions/3790454/in-yaml-how-do-i-break-a-string-over-multiple-lines}
@@ -185,8 +184,8 @@
 \end{commandshell}
 		then we achieve the output in \cref{lst:colsep-mod3}.
 		\begin{cmhtcbraster}[raster column skip=.01\linewidth]
-			\cmhlistingsfromfile*{demonstrations/colsep-mod3.tex}{\texttt{colsep.tex} using \cref{lst:multi-line1}}{lst:colsep-mod3}
-			\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/multi-line1.yaml}[replace-TCB]{\texttt{multi-line1.yaml}}{lst:multi-line1}
+			\cmhlistingsfromfile{demonstrations/colsep-mod3.tex}{\texttt{colsep.tex} using \cref{lst:multi-line1}}{lst:colsep-mod3}
+			\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/multi-line1.yaml}[replace-TCB]{\texttt{multi-line1.yaml}}{lst:multi-line1}
 		\end{cmhtcbraster}
 		We note that, because we have specified \texttt{when: after}, that \texttt{latexindent.pl} has not found the string specified
 		in \cref{lst:multi-line1} within the file in \vref{lst:colsep}. As it has looked for the string within \cref{lst:multi-line1} \emph{after} the indentation has been performed. After
@@ -206,7 +205,7 @@
 		the code in \cref{lst:displaymath}, let's assume that our goal is to replace each occurrence of \lstinline!$$...$$!
 		with \lstinline!\begin{equation*}...\end{equation*}!. This example is partly motivated by \href{https://tex.stackexchange.com/questions/242150/good-looking-latex-code}{tex stackexchange question 242150}.
 
-		\cmhlistingsfromfile*{demonstrations/displaymath.tex}{\texttt{displaymath.tex}}{lst:displaymath}
+		\cmhlistingsfromfile{demonstrations/displaymath.tex}{\texttt{displaymath.tex}}{lst:displaymath}
 
 		We use the settings in \cref{lst:displaymath1} and run the command
 		\begin{commandshell}
@@ -216,8 +215,8 @@
 
 		\begin{cmhtcbraster}[raster left skip=-3.75cm,
 				raster right skip=-2cm,]
-			\cmhlistingsfromfile*{demonstrations/displaymath-mod1.tex}{\texttt{displaymath.tex} using \cref{lst:displaymath1}}{lst:displaymath-mod1}
-			\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/displaymath1.yaml}[replace-TCB]{\texttt{displaymath1.yaml}}{lst:displaymath1}
+			\cmhlistingsfromfile{demonstrations/displaymath-mod1.tex}{\texttt{displaymath.tex} using \cref{lst:displaymath1}}{lst:displaymath-mod1}
+			\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/displaymath1.yaml}[replace-TCB]{\texttt{displaymath1.yaml}}{lst:displaymath1}
 		\end{cmhtcbraster}
 
 		A few notes about \cref{lst:displaymath1}:
@@ -243,8 +242,8 @@
 				raster force size=false,
 				raster column 1/.style={add to width=-.1\textwidth},
 				raster column skip=.06\linewidth]
-			\cmhlistingsfromfile*{demonstrations/displaymath-mod2.tex}{\texttt{displaymath.tex} using \cref{lst:displaymath1,lst:equation}}{lst:displaymath-mod2}
-			\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/equation.yaml}[MLB-TCB,width=0.55\textwidth]{\texttt{equation.yaml}}{lst:equation}
+			\cmhlistingsfromfile{demonstrations/displaymath-mod2.tex}{\texttt{displaymath.tex} using \cref{lst:displaymath1,lst:equation}}{lst:displaymath-mod2}
+			\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/equation.yaml}[MLB-TCB,width=0.55\textwidth]{\texttt{equation.yaml}}{lst:equation}
 		\end{cmhtcbraster}
 	\end{example}
 
@@ -252,7 +251,7 @@
 		This example is motivated by \href{https://tex.stackexchange.com/questions/490086/bring-several-lines-together-to-fill-blank-spaces-in-texmaker}{tex stackexchange question 490086}.
 		We begin with the code in \cref{lst:phrase}.
 
-		\cmhlistingsfromfile*{demonstrations/phrase.tex}{\texttt{phrase.tex}}{lst:phrase}
+		\cmhlistingsfromfile{demonstrations/phrase.tex}{\texttt{phrase.tex}}{lst:phrase}
 
 		Our goal is to make the spacing uniform between the phrases. To achieve this, we employ the settings in \cref{lst:hspace},
 		and run the command
@@ -262,8 +261,8 @@
 		which gives the output in \cref{lst:phrase-mod1}.
 
 		\begin{cmhtcbraster}
-			\cmhlistingsfromfile*{demonstrations/phrase-mod1.tex}{\texttt{phrase.tex} using \cref{lst:hspace}}{lst:phrase-mod1}
-			\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/hspace.yaml}[replace-TCB]{\texttt{hspace.yaml}}{lst:hspace}
+			\cmhlistingsfromfile{demonstrations/phrase-mod1.tex}{\texttt{phrase.tex} using \cref{lst:hspace}}{lst:phrase-mod1}
+			\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/hspace.yaml}[replace-TCB]{\texttt{hspace.yaml}}{lst:hspace}
 		\end{cmhtcbraster}
 
 		The \lstinline!\h+! setting in \cref{lst:hspace} say to replace \emph{at least one horizontal space} with a single space.
@@ -272,7 +271,7 @@
 	\begin{example}
 		We begin with the code in \cref{lst:references}.
 
-		\cmhlistingsfromfile*{demonstrations/references.tex}{\texttt{references.tex}}{lst:references}
+		\cmhlistingsfromfile{demonstrations/references.tex}{\texttt{references.tex}}{lst:references}
 
 		Our goal is to change each reference so that both the text and the reference are contained within one hyperlink. We
 		achieve this by employing \cref{lst:reference} and running the command
@@ -281,9 +280,9 @@
 \end{commandshell}
 		which gives the output in \cref{lst:references-mod1}.
 
-		\cmhlistingsfromfile*{demonstrations/references-mod1.tex}{\texttt{references.tex} using \cref{lst:reference}}{lst:references-mod1}
+		\cmhlistingsfromfile{demonstrations/references-mod1.tex}{\texttt{references.tex} using \cref{lst:reference}}{lst:references-mod1}
 
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/reference.yaml}[replace-TCB]{\texttt{reference.yaml}}{lst:reference}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/reference.yaml}[replace-TCB]{\texttt{reference.yaml}}{lst:reference}
 
 		Referencing \cref{lst:reference}, the \lstinline!|! means \emph{or}, we have used \emph{capture groups}, together with an example
 		of an \emph{optional} pattern, \lstinline!(?:eq)?!.
@@ -294,8 +293,8 @@
 		an example that contains a verbatim code block, \cref{lst:verb1}; we will use the settings in \cref{lst:verbatim1-yaml}.
 
 		\begin{cmhtcbraster}
-			\cmhlistingsfromfile*{demonstrations/verb1.tex}{\texttt{verb1.tex}}{lst:verb1}
-			\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/verbatim1.yaml}[replace-TCB]{\texttt{verbatim1.yaml}}{lst:verbatim1-yaml}
+			\cmhlistingsfromfile{demonstrations/verb1.tex}{\texttt{verb1.tex}}{lst:verb1}
+			\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/verbatim1.yaml}[replace-TCB]{\texttt{verbatim1.yaml}}{lst:verbatim1-yaml}
 		\end{cmhtcbraster}
 
 		Upon running the following commands,
@@ -309,9 +308,9 @@
 		\begin{cmhtcbraster}[raster columns=3,
 				raster left skip=-3.75cm,
 				raster right skip=-2cm,]
-			\cmhlistingsfromfile*{demonstrations/verb1-mod1.tex}{\texttt{verb1-mod1.tex}}{lst:verb1-mod1}
-			\cmhlistingsfromfile*{demonstrations/verb1-rv-mod1.tex}{\texttt{verb1-rv-mod1.tex}}{lst:verb1-rv-mod1}
-			\cmhlistingsfromfile*{demonstrations/verb1-rr-mod1.tex}{\texttt{verb1-rr-mod1.tex}}{lst:verb1-rr-mod1}
+			\cmhlistingsfromfile{demonstrations/verb1-mod1.tex}{\texttt{verb1-mod1.tex}}{lst:verb1-mod1}
+			\cmhlistingsfromfile{demonstrations/verb1-rv-mod1.tex}{\texttt{verb1-rv-mod1.tex}}{lst:verb1-rv-mod1}
+			\cmhlistingsfromfile{demonstrations/verb1-rr-mod1.tex}{\texttt{verb1-rr-mod1.tex}}{lst:verb1-rr-mod1}
 		\end{cmhtcbraster}
 	\end{example}
 
@@ -332,7 +331,7 @@
 		Let's explore the \texttt{amalgamate} field from \vref{lst:replacements} in the context of the file specified
 		in \cref{lst:amalg1}.
 
-		\cmhlistingsfromfile*{demonstrations/amalg1.tex}{\texttt{amalg1.tex}}{lst:amalg1}
+		\cmhlistingsfromfile{demonstrations/amalg1.tex}{\texttt{amalg1.tex}}{lst:amalg1}
 
 		Let's consider the YAML files given in \crefrange{lst:amalg1-yaml}{lst:amalg3-yaml}.
 
@@ -339,9 +338,9 @@
 		\begin{cmhtcbraster}[raster columns=3,
 				raster left skip=-3.75cm,
 				raster right skip=-2cm,]
-			\cmhlistingsfromfile*[style=yaml-LST]{demonstrations/amalg1-yaml.yaml}[replace-TCB]{\texttt{amalg1-yaml.yaml}}{lst:amalg1-yaml}
-			\cmhlistingsfromfile*[style=yaml-LST]{demonstrations/amalg2-yaml.yaml}[replace-TCB]{\texttt{amalg2-yaml.yaml}}{lst:amalg2-yaml}
-			\cmhlistingsfromfile*[style=yaml-LST]{demonstrations/amalg3-yaml.yaml}[replace-TCB]{\texttt{amalg3-yaml.yaml}}{lst:amalg3-yaml}
+			\cmhlistingsfromfile[style=yaml-LST]{demonstrations/amalg1-yaml.yaml}[replace-TCB]{\texttt{amalg1-yaml.yaml}}{lst:amalg1-yaml}
+			\cmhlistingsfromfile[style=yaml-LST]{demonstrations/amalg2-yaml.yaml}[replace-TCB]{\texttt{amalg2-yaml.yaml}}{lst:amalg2-yaml}
+			\cmhlistingsfromfile[style=yaml-LST]{demonstrations/amalg3-yaml.yaml}[replace-TCB]{\texttt{amalg3-yaml.yaml}}{lst:amalg3-yaml}
 		\end{cmhtcbraster}
 
 		Upon running the following commands,
@@ -355,9 +354,9 @@
 		\begin{cmhtcbraster}[raster columns=3,
 				raster left skip=-3.75cm,
 				raster right skip=-2cm,]
-			\cmhlistingsfromfile*{demonstrations/amalg1-mod1.tex}{\texttt{amalg1.tex} using \cref{lst:amalg1-yaml}}{lst:amalg1-mod1}
-			\cmhlistingsfromfile*{demonstrations/amalg1-mod12.tex}{\texttt{amalg1.tex} using \cref{lst:amalg1-yaml,lst:amalg2-yaml}}{lst:amalg1-mod12}
-			\cmhlistingsfromfile*{demonstrations/amalg1-mod123.tex}{\texttt{amalg1.tex} using \cref{lst:amalg1-yaml,lst:amalg2-yaml,lst:amalg3-yaml}}{lst:amalg1-mod123}
+			\cmhlistingsfromfile{demonstrations/amalg1-mod1.tex}{\texttt{amalg1.tex} using \cref{lst:amalg1-yaml}}{lst:amalg1-mod1}
+			\cmhlistingsfromfile{demonstrations/amalg1-mod12.tex}{\texttt{amalg1.tex} using \cref{lst:amalg1-yaml,lst:amalg2-yaml}}{lst:amalg1-mod12}
+			\cmhlistingsfromfile{demonstrations/amalg1-mod123.tex}{\texttt{amalg1.tex} using \cref{lst:amalg1-yaml,lst:amalg2-yaml,lst:amalg3-yaml}}{lst:amalg1-mod123}
 		\end{cmhtcbraster}
 		We note that:
 		\begin{enumerate}

Modified: trunk/Master/texmf-dist/doc/support/latexindent/sec-the-m-switch.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/sec-the-m-switch.tex	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/sec-the-m-switch.tex	2020-03-21 21:20:37 UTC (rev 54454)
@@ -146,7 +146,7 @@
 
 	There are options to specify the \texttt{huge} option for the
 	\texttt{Text::Wrap} module \cite{textwrap}
-	\announce*{2019-09-07}{huge option for text wrap module}. This can be helpful if you would like to forbid the
+	\announce{2019-09-07}{huge option for text wrap module}. This can be helpful if you would like to forbid the
 	\texttt{Text::Wrap} routine from breaking words. For example, using the settings
 	in \cref{lst:textwrap2A-yaml,lst:textwrap2B-yaml} and running the commands
 	\begin{commandshell}
@@ -158,11 +158,11 @@
 	this; see \cite{textwrap} for more details.
 
 	\begin{cmhtcbraster}[raster column skip=.1\linewidth]
-		\cmhlistingsfromfile*{demonstrations/textwrap4-mod2A.tex}{\texttt{textwrap4-mod2A.tex}}{lst:textwrap4-mod2A}
-		\cmhlistingsfromfile*{demonstrations/textwrap2A.yaml}[MLB-TCB]{\texttt{textwrap2A.yaml}}{lst:textwrap2A-yaml}
+		\cmhlistingsfromfile{demonstrations/textwrap4-mod2A.tex}{\texttt{textwrap4-mod2A.tex}}{lst:textwrap4-mod2A}
+		\cmhlistingsfromfile{demonstrations/textwrap2A.yaml}[MLB-TCB]{\texttt{textwrap2A.yaml}}{lst:textwrap2A-yaml}
 
-		\cmhlistingsfromfile*{demonstrations/textwrap4-mod2B.tex}{\texttt{textwrap4-mod2B.tex}}{lst:textwrap4-mod2B}
-		\cmhlistingsfromfile*{demonstrations/textwrap2B.yaml}[MLB-TCB]{\texttt{textwrap2B.yaml}}{lst:textwrap2B-yaml}
+		\cmhlistingsfromfile{demonstrations/textwrap4-mod2B.tex}{\texttt{textwrap4-mod2B.tex}}{lst:textwrap4-mod2B}
+		\cmhlistingsfromfile{demonstrations/textwrap2B.yaml}[MLB-TCB]{\texttt{textwrap2B.yaml}}{lst:textwrap2B-yaml}
 	\end{cmhtcbraster}
 
 \subsubsection{text wrapping on a per-code-block basis}
@@ -576,7 +576,7 @@
 	you can switch it off by setting it to \texttt{0}, and you can
 	experiment with the \texttt{other}
 	field.%
-	\announce*{2019-07-13}{fine tuning the betterFullStop} You can also seek
+	\announce{2019-07-13}{fine tuning the betterFullStop} You can also seek
 	to customise the \texttt{betterFullStop} routine by using the
 	\emph{fine tuning}, detailed in \vref{lst:fineTuning}.
 
@@ -669,6 +669,11 @@
 	\vref{lst:textwrap9-yaml}, for example, you would replace/append
 	\texttt{environments} with, for example, \texttt{sentence: 50}.
 
+	If you specify \texttt{textWrapSentences} as 1, but do \emph{not}
+	specify a value for \texttt{columns} then the text wrapping will
+	\emph{not} operate on sentences, and you will see a warning in
+	\texttt{indent.log}.
+
 	The indentation of sentences requires that sentences are stored as code blocks. This
 	means that you may need to tweak \vref{lst:sentencesEndWith}. Let's explore this in
 	relation to \cref{lst:multiple-sentences6}.
@@ -969,7 +974,7 @@
 		      there is not already a line break before or after the \emph{<part of thing>},
 		      followed by a blank line;
 		\item[4] \emph{add blank line mode}%
-		      \announce*{2019-07-13}{blank line poly-switch}; a blank line will
+		      \announce{2019-07-13}{blank line poly-switch}; a blank line will
 		      be added before or after the \emph{<part of thing>} under consideration, even if the
 		      \emph{<part of thing>} is already on its own line.
 	\end{itemize}
@@ -1099,22 +1104,22 @@
 	\emph{blank line} has been added after adding the line break.
 
 	Let's now change%
-	\announce*{2019-07-13}{demonstration of new blank line poly-switch} each of
+	\announce{2019-07-13}{demonstration of new blank line poly-switch} each of
 	the \texttt{1} values in \cref{lst:env-mlb5,lst:env-mlb6} so that they are
 	$4$ and save them into \texttt{env-beg4.yaml} and
 	\texttt{env-body4.yaml} respectively (see \cref{lst:env-beg4,lst:env-body4}).
 
 	\begin{minipage}{.45\textwidth}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/env-beg4.yaml}[MLB-TCB]{\texttt{env-beg4.yaml}}{lst:env-beg4}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/env-beg4.yaml}[MLB-TCB]{\texttt{env-beg4.yaml}}{lst:env-beg4}
 	\end{minipage}
 	\hfill
 	\begin{minipage}{.45\textwidth}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/env-body4.yaml}[MLB-TCB]{\texttt{env-body4.yaml}}{lst:env-body4}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/env-body4.yaml}[MLB-TCB]{\texttt{env-body4.yaml}}{lst:env-body4}
 	\end{minipage}
 
 	We will demonstrate this poly-switch value using the code in \cref{lst:env-mlb1-text}.
 
-	\cmhlistingsfromfile*{demonstrations/env-mlb1.tex}{\texttt{env-mlb1.tex}}{lst:env-mlb1-text}
+	\cmhlistingsfromfile{demonstrations/env-mlb1.tex}{\texttt{env-mlb1.tex}}{lst:env-mlb1-text}
 
 	Upon running the commands
 	\begin{commandshell}
@@ -1125,8 +1130,8 @@
 	then we receive the respective outputs in \cref{lst:env-mlb1-beg4,lst:env-mlb1-body4}.
 
 	\begin{cmhtcbraster}[raster column skip=.1\linewidth]
-		\cmhlistingsfromfile*{demonstrations/env-mlb1-beg4.tex}{\texttt{env-mlb1.tex} using \cref{lst:env-beg4}}{lst:env-mlb1-beg4}
-		\cmhlistingsfromfile*{demonstrations/env-mlb1-body4.tex}{\texttt{env-mlb1.tex} using \cref{lst:env-body4}}{lst:env-mlb1-body4}
+		\cmhlistingsfromfile{demonstrations/env-mlb1-beg4.tex}{\texttt{env-mlb1.tex} using \cref{lst:env-beg4}}{lst:env-mlb1-beg4}
+		\cmhlistingsfromfile{demonstrations/env-mlb1-body4.tex}{\texttt{env-mlb1.tex} using \cref{lst:env-body4}}{lst:env-mlb1-body4}
 	\end{cmhtcbraster}
 
 	We note in particular that, by design, for this value of the poly-switches:
@@ -1237,17 +1242,17 @@
 	\emph{blank line} has been added after the line break.
 
 	Let's now change%
-	\announce*{2019-07-13}{demonstration of new blank line poly-switch} each
+	\announce{2019-07-13}{demonstration of new blank line poly-switch} each
 	of the \texttt{1} values in \cref{lst:env-mlb11,lst:env-mlb12} so that they
 	are $4$ and save them into \texttt{env-end4.yaml} and
 	\texttt{env-end-f4.yaml} respectively (see \cref{lst:env-end4,lst:env-end-f4}).
 
 	\begin{minipage}{.45\textwidth}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/env-end4.yaml}[MLB-TCB]{\texttt{env-end4.yaml}}{lst:env-end4}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/env-end4.yaml}[MLB-TCB]{\texttt{env-end4.yaml}}{lst:env-end4}
 	\end{minipage}
 	\hfill
 	\begin{minipage}{.5\textwidth}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/env-end-f4.yaml}[MLB-TCB]{\texttt{env-end-f4.yaml}}{lst:env-end-f4}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/env-end-f4.yaml}[MLB-TCB]{\texttt{env-end-f4.yaml}}{lst:env-end-f4}
 	\end{minipage}
 
 	We will demonstrate this poly-switch value using the code from
@@ -1262,8 +1267,8 @@
 	then we receive the respective outputs in \cref{lst:env-mlb1-end4,lst:env-mlb1-end-f4}.
 
 	\begin{cmhtcbraster}[raster column skip=.1\linewidth]
-		\cmhlistingsfromfile*{demonstrations/env-mlb1-end4.tex}{\texttt{env-mlb1.tex} using \cref{lst:env-end4}}{lst:env-mlb1-end4}
-		\cmhlistingsfromfile*{demonstrations/env-mlb1-end-f4.tex}{\texttt{env-mlb1.tex} using \cref{lst:env-end-f4}}{lst:env-mlb1-end-f4}
+		\cmhlistingsfromfile{demonstrations/env-mlb1-end4.tex}{\texttt{env-mlb1.tex} using \cref{lst:env-end4}}{lst:env-mlb1-end4}
+		\cmhlistingsfromfile{demonstrations/env-mlb1-end-f4.tex}{\texttt{env-mlb1.tex} using \cref{lst:env-end-f4}}{lst:env-mlb1-end-f4}
 	\end{cmhtcbraster}
 
 	We note in particular that, by design, for this value of the poly-switches:
@@ -1504,7 +1509,7 @@
 
 \subsection{Poly-switches for double back slash}\label{subsec:dbs}
 	With reference to \texttt{lookForAlignDelims} (see \vref{lst:aligndelims:basic})%
-	\announce*{2019-07-13}{poly-switch for double back slash} you can
+	\announce{2019-07-13}{poly-switch for double back slash} you can
 	specify poly-switches to dictate the line-break behaviour of double back slashes in
 	environments (\vref{lst:tabularafter:basic}), commands (\vref{lst:matrixafter}), or
 	special code blocks (\vref{lst:specialafter}). Note that for these poly-switches to
@@ -1512,7 +1517,7 @@
 	\texttt{lookForAlignDelims} (\vref{lst:aligndelims:basic}); we will demonstrate this in what follows.
 
 	Consider the code given in \cref{lst:dbs-demo}.
-	\begin{cmhlistings}*[style=tcblatex,escapeinside={(*@}{@*)}]{\texttt{tabular3.tex}}{lst:dbs-demo}
+	\begin{cmhlistings}[style=tcblatex,escapeinside={(*@}{@*)}]{\texttt{tabular3.tex}}{lst:dbs-demo}
 \begin{tabular}{cc}
  1 & 2 (*@$\ElseStartsOnOwnLine$@*)\\(*@$\ElseFinishesWithLineBreak$@*) 3 & 4 (*@$\ElseStartsOnOwnLine$@*)\\(*@$\ElseFinishesWithLineBreak$@*)
 \end{tabular}
@@ -1541,13 +1546,13 @@
 	\cref{lst:tabular3-DBS2}.
 
 	\begin{cmhtcbraster}[raster column skip=.01\linewidth]
-		\cmhlistingsfromfile*{demonstrations/tabular3-mod1.tex}{\texttt{tabular3.tex} using \cref{lst:DBS1}}{lst:tabular3-DBS1}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/DBS1.yaml}[MLB-TCB]{\texttt{DBS1.yaml}}{lst:DBS1}
+		\cmhlistingsfromfile{demonstrations/tabular3-mod1.tex}{\texttt{tabular3.tex} using \cref{lst:DBS1}}{lst:tabular3-DBS1}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/DBS1.yaml}[MLB-TCB]{\texttt{DBS1.yaml}}{lst:DBS1}
 	\end{cmhtcbraster}
 
 	\begin{cmhtcbraster}[raster column skip=.01\linewidth]
-		\cmhlistingsfromfile*{demonstrations/tabular3-mod2.tex}{\texttt{tabular3.tex} using \cref{lst:DBS2}}{lst:tabular3-DBS2}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/DBS2.yaml}[MLB-TCB]{\texttt{DBS2.yaml}}{lst:DBS2}
+		\cmhlistingsfromfile{demonstrations/tabular3-mod2.tex}{\texttt{tabular3.tex} using \cref{lst:DBS2}}{lst:tabular3-DBS2}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/DBS2.yaml}[MLB-TCB]{\texttt{DBS2.yaml}}{lst:DBS2}
 	\end{cmhtcbraster}
 
 	We note that
@@ -1576,13 +1581,13 @@
 	\cref{lst:tabular3-DBS4}.
 
 	\begin{cmhtcbraster}[raster column skip=.01\linewidth]
-		\cmhlistingsfromfile*{demonstrations/tabular3-mod3.tex}{\texttt{tabular3.tex} using \cref{lst:DBS3}}{lst:tabular3-DBS3}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/DBS3.yaml}[MLB-TCB]{\texttt{DBS3.yaml}}{lst:DBS3}
+		\cmhlistingsfromfile{demonstrations/tabular3-mod3.tex}{\texttt{tabular3.tex} using \cref{lst:DBS3}}{lst:tabular3-DBS3}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/DBS3.yaml}[MLB-TCB]{\texttt{DBS3.yaml}}{lst:DBS3}
 	\end{cmhtcbraster}
 
 	\begin{cmhtcbraster}[raster column skip=.01\linewidth]
-		\cmhlistingsfromfile*{demonstrations/tabular3-mod4.tex}{\texttt{tabular3.tex} using \cref{lst:DBS4}}{lst:tabular3-DBS4}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/DBS4.yaml}[MLB-TCB]{\texttt{DBS4.yaml}}{lst:DBS4}
+		\cmhlistingsfromfile{demonstrations/tabular3-mod4.tex}{\texttt{tabular3.tex} using \cref{lst:DBS4}}{lst:tabular3-DBS4}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/DBS4.yaml}[MLB-TCB]{\texttt{DBS4.yaml}}{lst:DBS4}
 	\end{cmhtcbraster}
 
 	We note that
@@ -1605,7 +1610,7 @@
 	\texttt{specialBeginEnd} code blocks (\vref{lst:specialBeginEnd}); we begin with
 	the code within \cref{lst:special4}.
 
-	\cmhlistingsfromfile*{demonstrations/special4.tex}{\texttt{special4.tex}}{lst:special4}
+	\cmhlistingsfromfile{demonstrations/special4.tex}{\texttt{special4.tex}}{lst:special4}
 
 	Upon using the YAML settings in \cref{lst:DBS5}, and running the command
 	\begin{commandshell}
@@ -1617,8 +1622,8 @@
 			raster force size=false,
 			raster column 1/.style={add to width=-.1\textwidth},
 			raster column skip=.06\linewidth]
-		\cmhlistingsfromfile*{demonstrations/special4-mod5.tex}{\texttt{special4.tex} using \cref{lst:DBS5}}{lst:special4-DBS5}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/DBS5.yaml}[MLB-TCB,width=0.6\textwidth]{\texttt{DBS5.yaml}}{lst:DBS5}
+		\cmhlistingsfromfile{demonstrations/special4-mod5.tex}{\texttt{special4.tex} using \cref{lst:DBS5}}{lst:special4-DBS5}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/DBS5.yaml}[MLB-TCB,width=0.6\textwidth]{\texttt{DBS5.yaml}}{lst:DBS5}
 	\end{cmhtcbraster}
 
 	There are a few things to note:
@@ -1637,7 +1642,7 @@
 	poly-switches for optional and mandatory arguments. We begin with the code in
 	\cref{lst:mycommand2}.
 
-	\cmhlistingsfromfile*{demonstrations/mycommand2.tex}{\texttt{mycommand2.tex}}{lst:mycommand2}
+	\cmhlistingsfromfile{demonstrations/mycommand2.tex}{\texttt{mycommand2.tex}}{lst:mycommand2}
 
 	Upon using the YAML settings in \cref{lst:DBS6,lst:DBS7}, and running the command
 	\begin{commandshell}
@@ -1650,8 +1655,8 @@
 			raster force size=false,
 			raster column 1/.style={add to width=-.1\textwidth},
 			raster column skip=.03\linewidth]
-		\cmhlistingsfromfile*{demonstrations/mycommand2-mod6.tex}{\texttt{mycommand2.tex} using \cref{lst:DBS6}}{lst:mycommand2-DBS6}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/DBS6.yaml}[MLB-TCB,width=0.6\textwidth]{\texttt{DBS6.yaml}}{lst:DBS6}
+		\cmhlistingsfromfile{demonstrations/mycommand2-mod6.tex}{\texttt{mycommand2.tex} using \cref{lst:DBS6}}{lst:mycommand2-DBS6}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/DBS6.yaml}[MLB-TCB,width=0.6\textwidth]{\texttt{DBS6.yaml}}{lst:DBS6}
 	\end{cmhtcbraster}
 
 	\begin{cmhtcbraster}[
@@ -1658,8 +1663,8 @@
 			raster force size=false,
 			raster column 1/.style={add to width=-.1\textwidth},
 			raster column skip=.03\linewidth]
-		\cmhlistingsfromfile*{demonstrations/mycommand2-mod7.tex}{\texttt{mycommand2.tex} using \cref{lst:DBS7}}{lst:mycommand2-DBS7}
-		\cmhlistingsfromfile*[style=yaml-LST]*{demonstrations/DBS7.yaml}[MLB-TCB,width=0.6\textwidth]{\texttt{DBS7.yaml}}{lst:DBS7}
+		\cmhlistingsfromfile{demonstrations/mycommand2-mod7.tex}{\texttt{mycommand2.tex} using \cref{lst:DBS7}}{lst:mycommand2-DBS7}
+		\cmhlistingsfromfile[style=yaml-LST]*{demonstrations/DBS7.yaml}[MLB-TCB,width=0.6\textwidth]{\texttt{DBS7.yaml}}{lst:DBS7}
 	\end{cmhtcbraster}
 
 \subsubsection{Double back slash optional square brackets}
@@ -1669,7 +1674,7 @@
 
 	For example, beginning with the code in \cref{lst:pmatrix3}
 
-	\cmhlistingsfromfile*{demonstrations/pmatrix3.tex}{\texttt{pmatrix3.tex}}{lst:pmatrix3}
+	\cmhlistingsfromfile{demonstrations/pmatrix3.tex}{\texttt{pmatrix3.tex}}{lst:pmatrix3}
 
 	and running the following command, using \cref{lst:DBS3},
 	\begin{commandshell}
@@ -1677,7 +1682,7 @@
 \end{commandshell}
 	then we receive the output given in \cref{lst:pmatrix3-DBS3}.
 
-	\cmhlistingsfromfile*{demonstrations/pmatrix3-mod3.tex}{\texttt{pmatrix3.tex} using \cref{lst:DBS3}}{lst:pmatrix3-DBS3}
+	\cmhlistingsfromfile{demonstrations/pmatrix3-mod3.tex}{\texttt{pmatrix3.tex} using \cref{lst:DBS3}}{lst:pmatrix3-DBS3}
 
 	You can customise the pattern for the double back slash by exploring the
 	\emph{fine tuning} field detailed in \vref{lst:fineTuning}.
@@ -1698,70 +1703,70 @@
 
 	\clearpage
 	\begin{longtable}{llll}
-		\caption{Poly-switch mappings for all code-block types}\label{tab:poly-switch-mapping}                                                                                                                                                          \\
+		\caption{Poly-switch mappings for all code-block types}\label{tab:poly-switch-mapping}                                                                                                                                                         \\
 		\toprule
-		Code block                                              & Sample                                                                  & \multicolumn{2}{c}{Poly-switch mapping}                                                                     \\
+		Code block                                             & Sample                                                                  & \multicolumn{2}{c}{Poly-switch mapping}                                                                     \\
 		\midrule
-		environment                                             & \verb!before words!$\BeginStartsOnOwnLine$                       & $\BeginStartsOnOwnLine$                 & BeginStartsOnOwnLine                                              \\
-		                                                        & \verb!\begin{myenv}!$\BodyStartsOnOwnLine$                        & $\BodyStartsOnOwnLine$                  & BodyStartsOnOwnLine                                               \\
-		                                                        & \verb!body of myenv!$\EndStartsOnOwnLine$                         & $\EndStartsOnOwnLine$                   & EndStartsOnOwnLine                                                \\
-		                                                        & \verb!\end{myenv}!$\EndFinishesWithLineBreak$                   & $\EndFinishesWithLineBreak$             & EndFinishesWithLineBreak                                          \\
-		                                                        & \verb!after words!                                              &                                         &                                                                   \\
+		environment                                            & \verb!before words!$\BeginStartsOnOwnLine$                      & $\BeginStartsOnOwnLine$                 & BeginStartsOnOwnLine                                              \\
+		                                                       & \verb!\begin{myenv}!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & BodyStartsOnOwnLine                                               \\
+		                                                       & \verb!body of myenv!$\EndStartsOnOwnLine$                        & $\EndStartsOnOwnLine$                   & EndStartsOnOwnLine                                                \\
+		                                                       & \verb!\end{myenv}!$\EndFinishesWithLineBreak$                  & $\EndFinishesWithLineBreak$             & EndFinishesWithLineBreak                                          \\
+		                                                       & \verb!after words!                                             &                                         &                                                                   \\
 		\cmidrule{2-4}
-		ifelsefi                                                & \verb!before words!$\BeginStartsOnOwnLine$                       & $\BeginStartsOnOwnLine$                 & IfStartsOnOwnLine                                                 \\
-		                                                        & \verb!\if...!$\BodyStartsOnOwnLine$                        & $\BodyStartsOnOwnLine$                  & BodyStartsOnOwnLine                                               \\
-		                                                        & \verb!body of if/or statement!$\OrStartsOnOwnLine$                          & $\OrStartsOnOwnLine$                    & OrStartsOnOwnLine                                                 %
-		\announce{2018-04-27}{new ifElseFi code block poly-switches}                                                                                                                                                                                    \\
-		                                                        & \verb!\or!$\OrFinishesWithLineBreak$                    & $\OrFinishesWithLineBreak$              & OrFinishesWithLineBreak                                           \\
-		                                                        & \verb!body of if/or statement!$\ElseStartsOnOwnLine$                       & $\ElseStartsOnOwnLine$                  & ElseStartsOnOwnLine                                               \\
-		                                                        & \verb!\else!$\ElseFinishesWithLineBreak$                 & $\ElseFinishesWithLineBreak$            & ElseFinishesWithLineBreak                                         \\
-		                                                        & \verb!body of else statement!$\EndStartsOnOwnLine$                        & $\EndStartsOnOwnLine$                   & FiStartsOnOwnLine                                                 \\
-		                                                        & \verb!\fi!$\EndFinishesWithLineBreak$                  & $\EndFinishesWithLineBreak$             & FiFinishesWithLineBreak                                           \\
-		                                                        & \verb!after words!                                             &                                         &                                                                   \\
+		ifelsefi                                               & \verb!before words!$\BeginStartsOnOwnLine$                      & $\BeginStartsOnOwnLine$                 & IfStartsOnOwnLine                                                 \\
+		                                                       & \verb!\if...!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & BodyStartsOnOwnLine                                               \\
+		                                                       & \verb!body of if/or statement!$\OrStartsOnOwnLine$                         & $\OrStartsOnOwnLine$                    & OrStartsOnOwnLine                                                 %
+		\announce{2018-04-27}{new ifElseFi code block poly-switches}                                                                                                                                                                                   \\
+		                                                       & \verb!\or!$\OrFinishesWithLineBreak$                   & $\OrFinishesWithLineBreak$              & OrFinishesWithLineBreak                                           \\
+		                                                       & \verb!body of if/or statement!$\ElseStartsOnOwnLine$                       & $\ElseStartsOnOwnLine$                  & ElseStartsOnOwnLine                                               \\
+		                                                       & \verb!\else!$\ElseFinishesWithLineBreak$                 & $\ElseFinishesWithLineBreak$            & ElseFinishesWithLineBreak                                         \\
+		                                                       & \verb!body of else statement!$\EndStartsOnOwnLine$                        & $\EndStartsOnOwnLine$                   & FiStartsOnOwnLine                                                 \\
+		                                                       & \verb!\fi!$\EndFinishesWithLineBreak$                  & $\EndFinishesWithLineBreak$             & FiFinishesWithLineBreak                                           \\
+		                                                       & \verb!after words!                                             &                                         &                                                                   \\
 		\cmidrule{2-4}
-		optionalArguments                                       & \verb!...!$\BeginStartsOnOwnLine$                      & $\BeginStartsOnOwnLine$                 & LSqBStartsOnOwnLine\footnote{LSqB stands for Left Square Bracket} \\
-		                                                        & \verb![!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & OptArgBodyStartsOnOwnLine                                         \\
-		\announce*{2019-07-13}{new comma-related poly-switches} & \verb!value before comma!$\ElseStartsOnOwnLine$,                      & $\ElseStartsOnOwnLine$                  & CommaStartsOnOwnLine                                              \\
-		                                                        & $\ElseFinishesWithLineBreak$                                            & $\ElseFinishesWithLineBreak$            & CommaFinishesWithLineBreak                                        \\
-		                                                        & \verb!end of body of opt arg!$\EndStartsOnOwnLine$                        & $\EndStartsOnOwnLine$                   & RSqBStartsOnOwnLine                                               \\
-		                                                        & \verb!]!$\EndFinishesWithLineBreak$                  & $\EndFinishesWithLineBreak$             & RSqBFinishesWithLineBreak                                         \\
-		                                                        & \verb!...!                                             &                                         &                                                                   \\
+		optionalArguments                                      & \verb!...!$\BeginStartsOnOwnLine$                      & $\BeginStartsOnOwnLine$                 & LSqBStartsOnOwnLine\footnote{LSqB stands for Left Square Bracket} \\
+		                                                       & \verb![!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & OptArgBodyStartsOnOwnLine                                         \\
+		\announce{2019-07-13}{new comma-related poly-switches} & \verb!value before comma!$\ElseStartsOnOwnLine$,                      & $\ElseStartsOnOwnLine$                  & CommaStartsOnOwnLine                                              \\
+		                                                       & $\ElseFinishesWithLineBreak$                                            & $\ElseFinishesWithLineBreak$            & CommaFinishesWithLineBreak                                        \\
+		                                                       & \verb!end of body of opt arg!$\EndStartsOnOwnLine$                        & $\EndStartsOnOwnLine$                   & RSqBStartsOnOwnLine                                               \\
+		                                                       & \verb!]!$\EndFinishesWithLineBreak$                  & $\EndFinishesWithLineBreak$             & RSqBFinishesWithLineBreak                                         \\
+		                                                       & \verb!...!                                             &                                         &                                                                   \\
 		\cmidrule{2-4}
-		mandatoryArguments                                      & \verb!...!$\BeginStartsOnOwnLine$                      & $\BeginStartsOnOwnLine$                 & LCuBStartsOnOwnLine\footnote{LCuB stands for Left Curly Brace}    \\
-		                                                        & \verb!{!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & MandArgBodyStartsOnOwnLine                                        \\
-		\announce*{2019-07-13}{new comma-related poly-switches} & \verb!value before comma!$\ElseStartsOnOwnLine$,                      & $\ElseStartsOnOwnLine$                  & CommaStartsOnOwnLine                                              \\
-		                                                        & $\ElseFinishesWithLineBreak$                                            & $\ElseFinishesWithLineBreak$            & CommaFinishesWithLineBreak                                        \\
-		                                                        & \verb!end of body of mand arg!$\EndStartsOnOwnLine$                        & $\EndStartsOnOwnLine$                   & RCuBStartsOnOwnLine                                               \\
-		                                                        & \verb!}!$\EndFinishesWithLineBreak$                  & $\EndFinishesWithLineBreak$             & RCuBFinishesWithLineBreak                                         \\
-		                                                        & \verb!...!                                             &                                         &                                                                   \\
+		mandatoryArguments                                     & \verb!...!$\BeginStartsOnOwnLine$                      & $\BeginStartsOnOwnLine$                 & LCuBStartsOnOwnLine\footnote{LCuB stands for Left Curly Brace}    \\
+		                                                       & \verb!{!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & MandArgBodyStartsOnOwnLine                                        \\
+		\announce{2019-07-13}{new comma-related poly-switches} & \verb!value before comma!$\ElseStartsOnOwnLine$,                      & $\ElseStartsOnOwnLine$                  & CommaStartsOnOwnLine                                              \\
+		                                                       & $\ElseFinishesWithLineBreak$                                            & $\ElseFinishesWithLineBreak$            & CommaFinishesWithLineBreak                                        \\
+		                                                       & \verb!end of body of mand arg!$\EndStartsOnOwnLine$                        & $\EndStartsOnOwnLine$                   & RCuBStartsOnOwnLine                                               \\
+		                                                       & \verb!}!$\EndFinishesWithLineBreak$                  & $\EndFinishesWithLineBreak$             & RCuBFinishesWithLineBreak                                         \\
+		                                                       & \verb!...!                                             &                                         &                                                                   \\
 		\cmidrule{2-4}
-		commands                                                & \verb!before words!$\BeginStartsOnOwnLine$                      & $\BeginStartsOnOwnLine$                 & CommandStartsOnOwnLine                                            \\
-		                                                        & \verb!\mycommand!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & CommandNameFinishesWithLineBreak                                  \\
-		                                                        & $\langle$\itshape{arguments}$\rangle$                                   &                                         &                                                                   \\
+		commands                                               & \verb!before words!$\BeginStartsOnOwnLine$                      & $\BeginStartsOnOwnLine$                 & CommandStartsOnOwnLine                                            \\
+		                                                       & \verb!\mycommand!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & CommandNameFinishesWithLineBreak                                  \\
+		                                                       & $\langle$\itshape{arguments}$\rangle$                                   &                                         &                                                                   \\
 		\cmidrule{2-4}
-		namedGroupingBraces Brackets                            & before words$\BeginStartsOnOwnLine$                                     & $\BeginStartsOnOwnLine$                 & NameStartsOnOwnLine                                               \\
-		                                                        & myname$\BodyStartsOnOwnLine$                                            & $\BodyStartsOnOwnLine$                  & NameFinishesWithLineBreak                                         \\
-		                                                        & $\langle$\itshape{braces/brackets}$\rangle$                             &                                         &                                                                   \\
+		namedGroupingBraces Brackets                           & before words$\BeginStartsOnOwnLine$                                     & $\BeginStartsOnOwnLine$                 & NameStartsOnOwnLine                                               \\
+		                                                       & myname$\BodyStartsOnOwnLine$                                            & $\BodyStartsOnOwnLine$                  & NameFinishesWithLineBreak                                         \\
+		                                                       & $\langle$\itshape{braces/brackets}$\rangle$                             &                                         &                                                                   \\
 		\cmidrule{2-4}
-		keyEqualsValuesBraces\newline Brackets                  & before words$\BeginStartsOnOwnLine$                                     & $\BeginStartsOnOwnLine$                 & KeyStartsOnOwnLine                                                \\
-		                                                        & key$\EqualsStartsOnOwnLine$=$\BodyStartsOnOwnLine$                      & $\EqualsStartsOnOwnLine$                & EqualsStartsOnOwnLine                                             \\
-		                                                        & $\langle$\itshape{braces/brackets}$\rangle$                             & $\BodyStartsOnOwnLine$                  & EqualsFinishesWithLineBreak                                       \\
+		keyEqualsValuesBraces\newline Brackets                 & before words$\BeginStartsOnOwnLine$                                     & $\BeginStartsOnOwnLine$                 & KeyStartsOnOwnLine                                                \\
+		                                                       & key$\EqualsStartsOnOwnLine$=$\BodyStartsOnOwnLine$                      & $\EqualsStartsOnOwnLine$                & EqualsStartsOnOwnLine                                             \\
+		                                                       & $\langle$\itshape{braces/brackets}$\rangle$                             & $\BodyStartsOnOwnLine$                  & EqualsFinishesWithLineBreak                                       \\
 		\cmidrule{2-4}
-		items                                                   & before words$\BeginStartsOnOwnLine$                                     & $\BeginStartsOnOwnLine$                 & ItemStartsOnOwnLine                                               \\
-		                                                        & \verb!\item!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & ItemFinishesWithLineBreak                                         \\
-		                                                        & \verb!...!                                             &                                         &                                                                   \\
+		items                                                  & before words$\BeginStartsOnOwnLine$                                     & $\BeginStartsOnOwnLine$                 & ItemStartsOnOwnLine                                               \\
+		                                                       & \verb!\item!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & ItemFinishesWithLineBreak                                         \\
+		                                                       & \verb!...!                                             &                                         &                                                                   \\
 		\cmidrule{2-4}
-		specialBeginEnd                                         & before words$\BeginStartsOnOwnLine$                                     & $\BeginStartsOnOwnLine$                 & SpecialBeginStartsOnOwnLine                                       \\
-		                                                        & \verb!\[!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & SpecialBodyStartsOnOwnLine                                        \\
-		                                                        & \verb!body of special/middle!$\ElseStartsOnOwnLine$                       & $\ElseStartsOnOwnLine$                  & SpecialMiddleStartsOnOwnLine                                      %
-		\announce{2018-04-27}{new special code block poly-switches}                                                                                                                                                                                     \\
-		                                                        & \verb!\middle!$\ElseFinishesWithLineBreak$                 & $\ElseFinishesWithLineBreak$            & SpecialMiddleFinishesWithLineBreak                                \\
-		                                                        & body of special/middle $\EndStartsOnOwnLine$                            & $\EndStartsOnOwnLine$                   & SpecialEndStartsOnOwnLine                                         \\
-		                                                        & \verb!\]!$\EndFinishesWithLineBreak$                  & $\EndFinishesWithLineBreak$             & SpecialEndFinishesWithLineBreak                                   \\
-		                                                        & after words                                                             &                                         &                                                                   \\
+		specialBeginEnd                                        & before words$\BeginStartsOnOwnLine$                                     & $\BeginStartsOnOwnLine$                 & SpecialBeginStartsOnOwnLine                                       \\
+		                                                       & \verb!\[!$\BodyStartsOnOwnLine$                       & $\BodyStartsOnOwnLine$                  & SpecialBodyStartsOnOwnLine                                        \\
+		                                                       & \verb!body of special/middle!$\ElseStartsOnOwnLine$                       & $\ElseStartsOnOwnLine$                  & SpecialMiddleStartsOnOwnLine                                      %
+		\announce{2018-04-27}{new special code block poly-switches}                                                                                                                                                                                    \\
+		                                                       & \verb!\middle!$\ElseFinishesWithLineBreak$                 & $\ElseFinishesWithLineBreak$            & SpecialMiddleFinishesWithLineBreak                                \\
+		                                                       & body of special/middle $\EndStartsOnOwnLine$                            & $\EndStartsOnOwnLine$                   & SpecialEndStartsOnOwnLine                                         \\
+		                                                       & \verb!\]!$\EndFinishesWithLineBreak$                  & $\EndFinishesWithLineBreak$             & SpecialEndFinishesWithLineBreak                                   \\
+		                                                       & after words                                                             &                                         &                                                                   \\
 		\cmidrule{2-4}
-		verbatim                                                & before words$\BeginStartsOnOwnLine$\verb!\begin{verbatim}!          & $\BeginStartsOnOwnLine$                 & VerbatimBeginStartsOnOwnLine                                      \\
-		\announce{2019-05-05}{verbatim poly-switches}           & body of verbatim \verb!\end{verbatim}!$\EndFinishesWithLineBreak$ & $\EndFinishesWithLineBreak$             & VerbatimEndFinishesWithLineBreak                                  \\
-		                                                        & after words                                                             &                                         &                                                                   \\
+		verbatim                                               & before words$\BeginStartsOnOwnLine$\verb!\begin{verbatim}!          & $\BeginStartsOnOwnLine$                 & VerbatimBeginStartsOnOwnLine                                      \\
+		\announce{2019-05-05}{verbatim poly-switches}          & body of verbatim \verb!\end{verbatim}!$\EndFinishesWithLineBreak$ & $\EndFinishesWithLineBreak$             & VerbatimEndFinishesWithLineBreak                                  \\
+		                                                       & after words                                                             &                                         &                                                                   \\
 		\bottomrule
 	\end{longtable}

Modified: trunk/Master/texmf-dist/doc/support/latexindent/subsubsec-no-add-remaining-code-blocks.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/subsubsec-no-add-remaining-code-blocks.tex	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/subsubsec-no-add-remaining-code-blocks.tex	2020-03-21 21:20:37 UTC (rev 54454)
@@ -17,7 +17,7 @@
 		\end{itemize}
 		See the \texttt{keyEqualsValuesBracesBrackets: follow} and \texttt{keyEqualsValuesBracesBrackets: name} fields of the fine tuning
 		section in \vref{lst:fineTuning}%
-		\announce*{2019-07-13}{fine tuning: keyEqualsValuesBracesBrackets}
+		\announce{2019-07-13}{fine tuning: keyEqualsValuesBracesBrackets}
 
 		An example is shown in \cref{lst:pgfkeysbefore}, with the default output given in
 		\cref{lst:pgfkeys1:default}.
@@ -53,7 +53,7 @@
 		\end{itemize}
 		See the \texttt{NamedGroupingBracesBrackets: follow} and \texttt{NamedGroupingBracesBrackets: name} fields of the fine tuning
 		section in \vref{lst:fineTuning}%
-		\announce*{2019-07-13}{fine tuning: namedGroupingBracesBrackets}
+		\announce{2019-07-13}{fine tuning: namedGroupingBracesBrackets}
 
 		A simple example is given in \cref{lst:child1}, with default output in
 		\cref{lst:child1:default}.
@@ -89,7 +89,7 @@
 			      allowed throughout).
 		\end{itemize}
 		See the \texttt{UnNamedGroupingBracesBrackets: follow} field of the fine tuning section in \vref{lst:fineTuning}%
-		\announce*{2019-07-13}{fine tuning: namedGroupingBracesBrackets}
+		\announce{2019-07-13}{fine tuning: namedGroupingBracesBrackets}
 
 		An example is shown in \cref{lst:psforeach1} with default output give in
 		\cref{lst:psforeach:default}.

Modified: trunk/Master/texmf-dist/doc/support/latexindent/title.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/latexindent/title.tex	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/doc/support/latexindent/title.tex	2020-03-21 21:20:37 UTC (rev 54454)
@@ -8,7 +8,7 @@
 			sharp corners,
 			enhanced,
 			overlay={\node[anchor=north east,outer sep=2pt] at ([xshift=3cm,yshift=4mm]frame.north east) {\includegraphics[width=3cm]{logo}}; }]
-		\centering\ttfamily\bfseries latexindent.pl\\[1cm] Version 3.7.1
+		\centering\ttfamily\bfseries latexindent.pl\\[1cm] Version 3.8
 	\end{tcolorbox}
 }
 \author{Chris Hughes \thanks{and contributors!

Modified: trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm
===================================================================
--- trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm	2020-03-21 21:20:37 UTC (rev 54454)
@@ -20,7 +20,7 @@
 use Unicode::GCString;
 use Data::Dumper;
 use Exporter qw/import/;
-use List::Util qw(max);
+use List::Util qw/max min sum/;
 use LatexIndent::TrailingComments qw/$trailingCommentRegExp/;
 use LatexIndent::Switches qw/$is_t_switch_active $is_tt_switch_active/;
 use LatexIndent::GetYamlSettings qw/%masterSettings/;
@@ -27,8 +27,13 @@
 use LatexIndent::Tokens qw/%tokens/;
 use LatexIndent::LogFile qw/$logger/;
 our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321
-our @EXPORT_OK = qw/align_at_ampersand find_aligned_block double_back_slash_else/;
+our @EXPORT_OK = qw/align_at_ampersand find_aligned_block double_back_slash_else main_formatting individual_padding multicolumn_padding multicolumn_pre_check multicolumn_post_check dont_measure/;
 our $alignmentBlockCounter;
+our @cellStorage;   # two-dimensional storage array containing the cell information
+our @formattedBody; # array for the new body
+our @minMultiColSpan;
+our @maxColumnWidth;
+our @maxDelimiterWidth;
 
 sub find_aligned_block{
     my $self = shift;
@@ -127,27 +132,60 @@
     my $self = shift;
     return if(${$self}{bodyLineBreaks}==0);
 
-    # calculate the maximum number of ampersands in a row in the body
     my $maximumNumberOfAmpersands = 0;
+
+    # clear the global arrays
+    @formattedBody = ();
+    @cellStorage = ();
+    @minMultiColSpan = ();
+    @maxColumnWidth = ();
+    @maxDelimiterWidth = ();
+
+    # maximum column widths
+    my @maximumColumnWidths;
+
+    my $rowCounter = -1;
+    my $columnCounter = -1;
+
+    $logger->trace("*dontMeasure routine, row mode") if(${$self}{dontMeasure} and $is_t_switch_active);
+
+    # initial loop for column storage and measuring
+    # initial loop for column storage and measuring
+    # initial loop for column storage and measuring
     foreach(split("\n",${$self}{body})){
-        my $numberOfAmpersands = () = $_ =~ /(?<!\\)&/g;
-        $maximumNumberOfAmpersands = $numberOfAmpersands if($numberOfAmpersands>$maximumNumberOfAmpersands);
-    }
+        $rowCounter++;
 
-    # create an array of zeros
-    my @maximumColumnWidth = (0) x ($maximumNumberOfAmpersands+1); 
-    my @maximumColumnWidthMC = (0) x ($maximumNumberOfAmpersands+1); 
+        # default is to measure this row, but it can be switched off by the dont_measure routine
+        ${$self}{measureRow} = 1;
 
-    # array for the new body
-    my @formattedBody;
+        # call the dont_measure routine
+        $self->dont_measure(mode=>"row",row=>$_) if ${$self}{dontMeasure};
 
-    # now loop back through the body, and store the maximum column size
-    foreach(split("\n",${$self}{body})){
         # remove \\ and anything following it
-        my $endPiece;
+        my $endPiece = q();
         if($_ =~ m/(\\\\.*)/){
-            $_ =~ s/(\\\\.*)//;
-            $endPiece = $1;
+            if(${$self}{alignFinalDoubleBackSlash} ){
+                # for example, if we want:
+                #
+                #  Name & \shortstack{Hi \\ Lo} \\      <!--- Note this row!
+                #  Foo  & Bar                   \\
+                #
+                # in the first row, note that the first \\
+                # needs to be ignored, and we align by 
+                # the final double back slash                           
+                
+                $_ =~ s/(\\\\
+                          (?:                      
+                              (?!                 
+                                  (?:\\\\)           
+                              ).            # any character, but not \\
+                          )*?$              # non-greedy
+                        )//sx;
+                $endPiece = $1;
+            } else {
+                $_ =~ s/(\\\\.*)//;
+                $endPiece = $1;
+            }
         }
 
         # remove any trailing comments
@@ -157,352 +195,1087 @@
             $trailingComments = $1; 
         }
 
-        # count the number of ampersands in the current row
-        my $numberOfAmpersands = () = $_ =~ /(?<!\\)&/g;
+        # some rows shouldn't be formatted
+        my $unformattedRow = $_;
 
-        # switch for multiColumGrouping
-        my $multiColumnGrouping = ($_ =~ m/\\multicolumn/ and ${$self}{multiColumnGrouping});
-        my $alignRowsWithoutMaxDelims = ${$self}{alignRowsWithoutMaxDelims};
+        # delimiters regex, default is:
+        #
+        #   (?<!\\)&
+        #
+        # which is set in GetYamlSettings.pm, but can be set 
+        # by the user using, for example
+        #
+        #   lookForAlignDelims:
+        #       tabular:
+        #           delimiter: '\<'
+        #
+        my $delimiterRegEx = qr/${$self}{delimiterRegEx}/;
 
-        # by default, the stripped row is simply the current row
-        my $strippedRow = $_;
+        my $numberOfAmpersands = () = $_ =~ /$delimiterRegEx/g;
+        $maximumNumberOfAmpersands = $numberOfAmpersands if($numberOfAmpersands>$maximumNumberOfAmpersands);
+        
+        # remove space at the beginning of a row, surrounding &, and at the end of the row
+        $_ =~ s/(?<!\\)\h*($delimiterRegEx)\h*/$1/g;
+        $_ =~ s/^\h*//g;
+        $_ =~ s/\h*$//g;
+        
+        # if the line finishes with an &, then add an empty space,
+        # otherwise the column count is off
+        $_ .= ($_ =~ m/$delimiterRegEx$/ ? " ":q());
 
-        # loop through the columns
-        my $columnCount = 0;
+        # store the columns, which are either split by & 
+        # or otherwise simply the current line, if for example, the current line simply
+        # contains \multicolumn{8}... \\  (see test-cases/texexchange/366841-zarko.tex, for example)
+        my @columns = ($_ =~ m/$delimiterRegEx/ ? split(/($delimiterRegEx)/,$_) : $_);
 
-        # format switch off by default
-        my $formatRow = 0;
+        $columnCounter = -1;
+        my $spanning = 0;
 
-        # store the column sizes for measuring and comparison purposes
-        my @columnSizes = ();
+        foreach my $column (@columns){
+            # if a column contains only the delimiter, then we need to 
+            #       - measure it
+            #       - add it and its length to the previous cell
+            #       - remove it from the columns array
+            #
+            if($column =~ m/$delimiterRegEx/) {
+                # update the delimiter to be used, and its associated length 
+                # for the *previous* cell
+                my $spanningOffSet = ($spanning > 0 ?  $spanning - 1 : 0);
+                ${$cellStorage[$rowCounter][$columnCounter - $spanningOffSet]}{delimiter} = $1;
+                ${$cellStorage[$rowCounter][$columnCounter - $spanningOffSet]}{delimiterLength} = Unicode::GCString->new($1)->columns();
 
-        # we will store the columns in each row
-        my @columns;
+                # keep track of maximum delimiter width
+                $maxDelimiterWidth[$columnCounter - $spanningOffSet] = 
+                                                (defined $maxDelimiterWidth[$columnCounter - $spanningOffSet]
+                                                        ? 
+                                                max($maxDelimiterWidth[$columnCounter-$spanningOffSet],
+                                                    ${$cellStorage[$rowCounter][$columnCounter-$spanningOffSet]}{delimiterLength})
+                                                        :
+                                                ${$cellStorage[$rowCounter][$columnCounter - $spanningOffSet]}{delimiterLength});
 
-        # need to have at least one ampersand, or contain a \multicolumn command
-        if( ($_ =~ m/(?<!\\)&/ and ( ($numberOfAmpersands == $maximumNumberOfAmpersands)||$multiColumnGrouping||$alignRowsWithoutMaxDelims ) )
-                                                or
-                            ($multiColumnGrouping and $alignRowsWithoutMaxDelims) ){
-            # remove space at the beginning of a row, surrounding &, and at the end of the row
-            $_ =~ s/(?<!\\)\h*(?<!\\)&\h*/&/g;
-            $_ =~ s/^\h*//g;
-            $_ =~ s/\h*$//g;
+                # importantly, move on to the next column!
+                next;
+            }
 
-            # if the line finishes with an &, then add an empty space,
-            # otherwise the column count is off
-            $_ .= ($_ =~ m/(?<!\\)&$/ ? " ":q());
+            # otherwise increment the column counter, and proceed
+            $columnCounter++;
 
-            # store the columns, which are either split by & 
-            # or otherwise simply the current line, if for example, the current line simply
-            # contains \multicolumn{8}... \\  (see test-cases/texexchange/366841-zarko.tex, for example)
-            @columns = ($_ =~ m/(?<!\\)&/ ? split(/(?<!\\)&/,$_) : $_);
+            # reset spanning (only applicable if multiColumnGrouping)
+            $spanning = 0;
 
-            # empty the white-space-stripped row
-            $strippedRow = '';
-            foreach my $column (@columns){
-                # if a column has finished with a \ then we need to add a trailing space, 
-                # otherwise the \ can be put next to &. See test-cases/texexchange/112343-gonzalo for example
-                $column .= ($column =~ m/\\$/ ? " ": q());
+            # if a column has finished with a \ then we need to add a trailing space, 
+            # otherwise the \ can be put next to &. See test-cases/texexchange/112343-gonzalo for example
+            $column .= ($column =~ m/\\$/ ? " ": q());
 
-                # store the column size
-                # reference: http://www.perl.com/pub/2012/05/perlunicook-unicode-column-width-for-printing.html
-                my $gcs  = Unicode::GCString->new($column);
-                my $columnWidth = $gcs->columns();
+            # basic cell storage
+            $cellStorage[$rowCounter][$columnCounter] 
+                    = ({width=>Unicode::GCString->new($column)->columns(),
+                        entry=>$column,
+                        type=>($numberOfAmpersands>0 ? "X" : "*"),
+                        groupPadding=>0,
+                        colSpan=>".",
+                        delimiter=>"",
+                        delimiterLength=>0,
+                        measureThis=> ($numberOfAmpersands>0 ?  ${$self}{measureRow} : 0) });
+                    
+            # store the maximum column width 
+            $maxColumnWidth[$columnCounter] = (defined $maxColumnWidth[$columnCounter] 
+                                                        ? 
+                                                max($maxColumnWidth[$columnCounter],${$cellStorage[$rowCounter][$columnCounter]}{width})
+                                                        :
+                                                ${$cellStorage[$rowCounter][$columnCounter]}{width} ) if ${$cellStorage[$rowCounter][$columnCounter]}{type} eq "X";
+            
+            # \multicolumn cell
+            if(${$self}{multiColumnGrouping} and $column =~ m/\\multicolumn\{(\d+)\}/ and $1>1){
+                $spanning = $1;
 
-                # multicolumn cells need a bit of special care
-                if($multiColumnGrouping and $column =~ m/\\multicolumn\{(\d+)\}/ and $1>1){
-                    $maximumColumnWidthMC[$columnCount] = $columnWidth if( defined $maximumColumnWidthMC[$columnCount] and ($columnWidth > $maximumColumnWidthMC[$columnCount]) );
-                    $columnWidth = 1 if($multiColumnGrouping and ($column =~ m/\\multicolumn\{(\d+)\}/));
+                # adjust the type
+                ${$cellStorage[$rowCounter][$columnCounter]}{type} = "$spanning";
+
+                # some \multicol cells can have their spanning information removed from type
+                # so we store it in colSpan as well
+                ${$cellStorage[$rowCounter][$columnCounter]}{colSpan} = $spanning;
+
+                # and don't measure it
+                ${$cellStorage[$rowCounter][$columnCounter]}{measureThis} = 0;
+
+                # create 'gap' columns
+                for(my $j=$columnCounter+1; $j<=$columnCounter+($spanning-1);$j++){
+                    $cellStorage[$rowCounter][$j] = ({type=>"-",
+                                                      entry=>'',
+                                                      width=>0,
+                                                      individualPadding=>0,
+                                                      groupPadding=>0,
+                                                      colSpan=>".",
+                                                      delimiter=>"",
+                                                      delimiterLength=>0,
+                                                      measureThis=>0});
                 }
+                
+                # store the minimum spanning value
+                $minMultiColSpan[$columnCounter] = (defined $minMultiColSpan[$columnCounter] ? min($minMultiColSpan[$columnCounter],$spanning) : $spanning );
 
-                # store the maximum column width
-                $maximumColumnWidth[$columnCount] = $columnWidth if( defined $maximumColumnWidth[$columnCount] and ($columnWidth > $maximumColumnWidth[$columnCount]) );
+                # adjust the column counter
+                $columnCounter += $spanning - 1;
+            } 
+        }
 
-                # put the row back together, using " " if the column is empty
-                $strippedRow .= ($columnCount>0 ? "&" : q() ).($columnWidth > 0 ? $column: " ");
+        # store the information
+        push(@formattedBody,{row=>$_,
+                             endPiece=>$endPiece,
+                             trailingComment=>$trailingComments,
+                             numberOfAmpersands=>$numberOfAmpersands,
+                             unformattedRow=>$unformattedRow });
+                 
+    }
 
-                # store the column width
-                $columnSizes[$columnCount] = $columnWidth; 
+    # store the maximum number of ampersands
+    ${$self}{maximumNumberOfAmpersands} = $maximumNumberOfAmpersands;
 
-                # move on to the next column
-                if($multiColumnGrouping and ($column =~ m/\\multicolumn\{(\d+)\}/)){
-                    # columns that are within the multiCol statement receive a width of -1
-                    for my $i (($columnCount+1)..($columnCount+$1)){
-                        $columnSizes[$i] = -1; 
-                    }
-                    # update the columnCount to account for the multiColSpan
-                    $columnCount += $1; 
-                } else {
-                    $columnCount++;
-                }
+    # blocks with nested multicolumns need some pre checking
+    $self->multicolumn_pre_check if ${$self}{multiColumnGrouping};
+    
+    # maximum column width loop, and individual padding
+    $self->individual_padding;
+
+    # multi column rearrangement and multicolumn padding
+    $self->multicolumn_padding if ${$self}{multiColumnGrouping};
+
+    # multi column post check to ensure that multicolumn commands have received appropriate padding
+    $self->multicolumn_post_check if ${$self}{multiColumnGrouping};
+
+    # output to log file
+    if( $is_t_switch_active ){
+      &pretty_print_cell_info($_) for ("entry","type","colSpan","width","measureThis","maximumColumnWidth","individualPadding","groupPadding","delimiter","delimiterLength");
+    }
+
+    # main formatting loop
+    $self->main_formatting;
+
+    # final \\ loop
+    # final \\ loop
+    # final \\ loop
+    foreach (@formattedBody){
+        # reset the padding
+        my $padding = q();
+
+        # possibly adjust the padding
+        if(${$_}{row} !~ m/^\h*$/){
+            # remove trailing horizontal space if ${$self}{alignDoubleBackSlash} is set to 0
+            ${$_}{row} =~ s/\h*$// if (!${$self}{alignDoubleBackSlash});
+            
+            # format spacing infront of \\
+            if(defined ${$self}{spacesBeforeDoubleBackSlash} and ${$self}{spacesBeforeDoubleBackSlash}<0 and !${$self}{alignDoubleBackSlash}){
+                # zero spaces (possibly resulting in un-aligned \\)
+                $padding = q();
+            } elsif(defined ${$self}{spacesBeforeDoubleBackSlash} and ${$self}{spacesBeforeDoubleBackSlash}>=0 and !${$self}{alignDoubleBackSlash}){
+                # specified number of spaces (possibly resulting in un-aligned \\)
+                $padding = " " x (${$self}{spacesBeforeDoubleBackSlash});
+            } else {
+                # aligned \\
+                $padding = " " x max(0,(${$self}{maximumRowWidth} - ${$_}{rowWidth}));
             }
+        }
 
-            # toggle the formatting switch
-            $formatRow = 1;
-        } elsif($endPiece and ${$self}{alignDoubleBackSlash}){
-            # otherwise a row could contain no ampersands, but would still desire
-            # the \\ to be aligned, see test-cases/alignment/multicol-no-ampersands.tex
-            @columns = $_;
-            $formatRow = 1;
+        # format the row, and put the trailing \\ and trailing comments back into the row
+        ${$_}{row} .= $padding.(${$_}{endPiece} ? ${$_}{endPiece} :q() ).(${$_}{trailingComment}? ${$_}{trailingComment} : q() );
+
+        # some rows shouldn't be formatted, and may only have trailing comments;
+        # see test-cases/alignment/table4.tex for example
+        if(  (${$_}{numberOfAmpersands} == 0 and !${$_}{endPiece})  
+                            or 
+             (${$_}{numberOfAmpersands} < ${$self}{maximumNumberOfAmpersands} and !${$self}{alignRowsWithoutMaxDelims} and !${$_}{endPiece})      
+        ){
+            ${$_}{row} = (${$_}{unformattedRow}?${$_}{unformattedRow}:q()).(${$_}{trailingComment}?${$_}{trailingComment}:q());
         }
 
-        # store the information
-        push(@formattedBody,{
-                            row=>$strippedRow,
-                            format=>$formatRow,
-                            multiColumnGrouping=>$multiColumnGrouping,
-                            columnSizes=>\@columnSizes,
-                            columns=>\@columns,
-                            endPiece=>($endPiece ? $endPiece :q() ),
-                            trailingComment=>($trailingComments ? $trailingComments :q() )});
     }
 
-    # output some of the info so far to the log file
-    $logger->trace("*Alignment at ampersand routine for ${$self}{name} (see lookForAlignDelims)") if $is_t_switch_active;
-    $logger->trace("Maximum column sizes of horizontally stripped formatted block (${$self}{name}): @maximumColumnWidth") if $is_t_switch_active;
-    $logger->trace("align at ampersand: ${$self}{lookForAlignDelims}") if $is_t_switch_active;
-    $logger->trace("align at \\\\: ${$self}{alignDoubleBackSlash}") if $is_t_switch_active;
-    $logger->trace("spaces before \\\\: ${$self}{spacesBeforeDoubleBackSlash}") if $is_t_switch_active;
-    $logger->trace("multi column grouping: ${$self}{multiColumnGrouping}") if $is_t_switch_active;
-    $logger->trace("align rows without maximum delimeters: ${$self}{alignRowsWithoutMaxDelims}") if $is_t_switch_active;
-    $logger->trace("spaces before ampersand: ${$self}{spacesBeforeAmpersand}") if $is_t_switch_active;
-    $logger->trace("spaces after ampersand: ${$self}{spacesAfterAmpersand}") if $is_t_switch_active;
-    $logger->trace("justification: ${$self}{justification}") if $is_t_switch_active;
+    # delete the original body
+    ${$self}{body} = q();
 
-    # acount for multicolumn grouping, if the appropriate switch is set
-    if(${$self}{multiColumnGrouping}){
-        foreach(@formattedBody){
-            if(${$_}{format} and ${$_}{row} !~ m/^\h*$/){
+    # update the body
+    ${$self}{body} .= ${$_}{row}."\n" for @formattedBody;
 
-                # set a columnCount, which will vary depending on multiColumnGrouping settings or not
-                my $columnCount=0;
+    # if the \end{} statement didn't originally have a line break before it, we need to remove the final 
+    # line break added by the above
+    ${$self}{body} =~ s/\h*\R$//s if !${$self}{linebreaksAtEnd}{body};
+  }
 
-                # loop through the columns
-                foreach my $column (@{${$_}{columns}}){
-                    # calculate the width of the current column 
-                    my $gcs  = Unicode::GCString->new($column);
-                    my $columnWidth = $gcs->columns();
+sub main_formatting {
+    # PURPOSE:
+    #   (1) perform the *padding* operations
+    #       by adding 
+    #
+    #           <spacesBeforeAmpersand>
+    #           &
+    #           <spacesEndAmpersand>
+    #
+    #       to the cell entries, accounting for
+    #       the justification being LEFT or RIGHT
+    #
+    #   (2) measure the row width and store
+    #       the maximum row width for use with 
+    #       the (possible) alignment of the \\
+    #
+    my $self = shift;
 
-                    # check for multiColumnGrouping
-                    if(${$_}{multiColumnGrouping} and $column =~ m/\\multicolumn\{(\d+)\}/ and $1>1){
-                        my $multiColSpan = $1;
+    ${$self}{maximumRowWidth} = 0;
 
-                        # for example, \multicolumn{3}{c}{<stuff>} spans 3 columns, so 
-                        # the maximum column needs to account for this (subtract 1 because of 0 index in perl arrays)
-                        my $columnMax = $columnCount+$multiColSpan-1;
+    # objective (1): padding
+    # objective (1): padding
+    # objective (1): padding
+    
+    $logger->trace("*formatted rows for: ${$self}{name}") if($is_t_switch_active);
 
-                        # groupingWidth contains the total width of column sizes grouped 
-                        # underneath the \multicolumn{} statement
-                        my $groupingWidth = 0;
-                        my $maxGroupingWidth = 0;
-                        foreach (@formattedBody){
-                           $groupingWidth = 0;
+    my $rowCount = -1;
+    # row loop
+    foreach my $row (@cellStorage) {
+      $rowCount++;
 
-                            # loop through the columns covered by the multicolumn statement
-                            foreach my $j ($columnCount..$columnMax){
-                                if(  defined @{${$_}{columnSizes}}[$j] 
-                                             and 
-                                     @{${$_}{columnSizes}}[$j] >= 0
-                                             and
-                                         ${$_}{format} 
-                                          ){
-                                    $groupingWidth += (defined $maximumColumnWidth[$j] ? $maximumColumnWidth[$j] : 0); 
-                                } else {
-                                    $groupingWidth = 0;
-                                }
-                            }
+      # clear the temporary row
+      my $tmpRow = q();
 
-                            # update the maximum grouping width
-                            $maxGroupingWidth = $groupingWidth if($groupingWidth > $maxGroupingWidth);
+      # column loop
+      foreach my $cell (@$row) {
+          if (${$cell}{type} eq "*" or ${$cell}{type} eq "-"){
+            $tmpRow .= ${$cell}{entry};
+            next;
+          }
 
-                            # the cells that receive multicolumn grouping need extra padding; in particular
-                            # if the justification is *left*:
-                            #       the *last* cell of the multicol group receives the padding
-                            # if the justification is *right*:
-                            #       the *first* cell of the multicol group receives the padding
-                            #
-                            # this motivates the introduction of $columnOffset, which is 
-                            #       0 if justification is left
-                            #       $multiColSpan if justification is right
-                            my $columnOffset = (${$self}{justification} eq "left") ? $columnMax : $columnCount;
-                            if(defined @{${$_}{columnSizes}}[$columnMax] and ($columnWidth > ($groupingWidth+(${$self}{spacesBeforeAmpersand}+1+${$self}{spacesAfterAmpersand})*($multiColSpan-1)) ) and @{${$_}{columnSizes}}[$columnMax] >= 0){
-                                my $multiColPadding = $columnWidth-$groupingWidth-(${$self}{spacesBeforeAmpersand}+1+${$self}{spacesAfterAmpersand})*($multiColSpan-1);
+          # the placement of the padding is dependent on the value of justification
+          if(${$self}{justification} eq "left"){
+            # LEFT: 
+            # LEFT: 
+            # LEFT: 
+            #   <cell entry> <individual padding> <group padding> ...
+            $tmpRow .= ${$cell}{entry};
+            $tmpRow .= " " x ${$cell}{individualPadding};
+            $tmpRow .= " " x ${$cell}{groupPadding};
+          } else {
+            # RIGHT: 
+            # RIGHT: 
+            # RIGHT: 
+            #   <group padding> <individual padding> <cell entry> ...
+            $tmpRow .= " " x ${$cell}{groupPadding};
+            $tmpRow .= " " x ${$cell}{individualPadding};
+            $tmpRow .= ${$cell}{entry};
+          }
 
-                                # it's possible that multiColPadding might already be assigned; in which case, 
-                                # we need to check that the current value of $multiColPadding is greater than the existing one
-                                if(defined @{${$_}{multiColPadding}}[$columnOffset]){
-                                    @{${$_}{multiColPadding}}[$columnOffset] = max($multiColPadding,@{${$_}{multiColPadding}}[$columnOffset]);
-                                } else {
-                                    @{${$_}{multiColPadding}}[$columnOffset] = $multiColPadding;
-                                }
+          # either way, finish with:  <spacesBeforeAmpersand> & <spacesAfterAmpersand>
+          $tmpRow .= " " x ${$self}{spacesBeforeAmpersand};
+          $tmpRow .= ${$cell}{delimiter};
+          $tmpRow .= " " x ${$self}{spacesAfterAmpersand};
+      }
 
-                                # also need to account for maximum column width *including* other multicolumn statements
-                                if($maximumColumnWidthMC[$columnCount]>$columnWidth and $column !~ m/\\multicolumn\{(\d+)\}/){
-                                    @{${$_}{multiColPadding}}[$columnOffset] += ($maximumColumnWidthMC[$columnCount]-$columnWidth); 
-                                }
-                            }
-                        }
-                        # update it to account for the ampersands and the spacing either side of ampersands
-                        $maxGroupingWidth += ($multiColSpan-1)*(${$self}{spacesBeforeAmpersand}+1+${$self}{spacesAfterAmpersand});
+      # if alignRowsWithoutMaxDelims = 0
+      # and there are *less than* the maximum number of ampersands, then 
+      # we undo all of the work above!
+      if( !${$self}{alignRowsWithoutMaxDelims} 
+              and 
+           ${$formattedBody[$rowCount]}{numberOfAmpersands} < ${$self}{maximumNumberOfAmpersands} ){
+            $tmpRow = ${$formattedBody[$rowCount]}{unformattedRow};
+      }
 
-                        # store the maxGroupingWidth for use in the next loop
-                        @{${$_}{maxGroupingWidth}}[$columnCount] = $maxGroupingWidth; 
+      # spacing before \\
+      my $finalSpacing = q();
+      $finalSpacing = " " x (${$self}{spacesBeforeDoubleBackSlash}) if ${$self}{spacesBeforeDoubleBackSlash}>=1;
+      $tmpRow =~ s/\h*$/$finalSpacing/;
 
-                        # update the columnCount to account for the multiColSpan
-                        $columnCount += $multiColSpan - 1;
-                    } 
+      # if $tmpRow is made up of only horizontal space, then empty it
+      $tmpRow = q() if($tmpRow =~ m/^\h*$/);
 
-                    # increase the column count
-                    $columnCount++;
-                }
-            } 
+      # to the log file
+      $logger->trace($tmpRow) if($is_t_switch_active);
+
+      # store this formatted row
+      ${$formattedBody[$rowCount]}{row} = $tmpRow;
+
+      # objective (2): calculate row width and update maximumRowWidth
+      # objective (2): calculate row width and update maximumRowWidth
+      # objective (2): calculate row width and update maximumRowWidth
+      my $rowWidth  = Unicode::GCString->new($tmpRow)->columns();
+      ${$formattedBody[$rowCount]}{rowWidth} = $rowWidth;
+      
+      # update the maximum row width
+      if( $rowWidth > ${$self}{maximumRowWidth}
+          and !(${$formattedBody[$rowCount]}{numberOfAmpersands} == 0 and !${$formattedBody[$rowCount]}{endPiece}) ){
+          ${$self}{maximumRowWidth} = $rowWidth;
+      }
+    }
+}
+
+sub dont_measure{
+
+    my $self = shift;
+    my %input = @_;
+
+    if( $input{mode} eq "cell" 
+        and ref(\${$self}{dontMeasure}) eq "SCALAR" 
+        and ${$self}{dontMeasure} eq "largest" 
+        and ${$cellStorage[$input{row}][$input{column}]}{width} == $maxColumnWidth[$input{column}]){
+        # dontMeasure stored as largest, for example
+        #
+        # lookForAlignDelims:
+        #    tabular: 
+        #       dontMeasure: largest
+        $logger->trace("CELL FOUND with maximum column width, $maxColumnWidth[$input{column}], and will not be measured (largest mode)") if($is_t_switch_active);
+        $logger->trace("column: ", $input{column}," width: ",${$cellStorage[$input{row}][$input{column}]}{width}) if($is_t_switch_active);
+        $logger->trace("entry: ", ${$cellStorage[$input{row}][$input{column}]}{entry}) if($is_t_switch_active);
+        $logger->trace("--------------------------") if($is_t_switch_active);
+        ${$cellStorage[$input{row}][$input{column}]}{measureThis} = 0;
+        ${$cellStorage[$input{row}][$input{column}]}{type} = "X";
+    } elsif($input{mode} eq "cell" and (ref(${$self}{dontMeasure}) eq "ARRAY")){
+      
+        # loop through the entries in dontMeasure
+        foreach(@{${$self}{dontMeasure}}){
+            if(ref(\$_) eq "SCALAR" and ${$cellStorage[$input{row}][$input{column}]}{entry} eq $_){
+                # dontMeasure stored as *strings*, for example:
+                #
+                #   lookForAlignDelims:
+                #      tabular: 
+                #         dontMeasure:
+                #           - \multicolumn{1}{c}{Expiry}
+                #           - Tenor 
+                #           - \multicolumn{1}{c}{$\Delta_{\text{call},10}$} 
+                
+                $logger->trace("CELL FOUND (this): $_ and will not be measured") if($is_t_switch_active);
+                ${$cellStorage[$input{row}][$input{column}]}{measureThis} = 0;
+                ${$cellStorage[$input{row}][$input{column}]}{type} = "X";
+            } elsif (ref($_) eq "HASH" and  ${$_}{this} and ${$cellStorage[$input{row}][$input{column}]}{entry} eq ${$_}{this}){
+                # for example:
+                #
+                #   lookForAlignDelims:
+                #      tabular: 
+                #         dontMeasure:
+                #           -
+                #               this: \multicolumn{1}{c}{Expiry}
+                #               applyTo: cell
+                #
+                # OR (note that applyTo is optional):
+                #
+                #   lookForAlignDelims:
+                #      tabular: 
+                #         dontMeasure:
+                #           -
+                #               this: \multicolumn{1}{c}{Expiry}
+                next if(defined ${$_}{applyTo} and !${$_}{applyTo} eq "cell" );
+                $logger->trace("CELL FOUND (this): ${$_}{this} and will not be measured") if($is_t_switch_active);
+                ${$cellStorage[$input{row}][$input{column}]}{measureThis} = 0;
+                ${$cellStorage[$input{row}][$input{column}]}{type} = "X";
+            } elsif (ref($_) eq "HASH" and  ${$_}{regex} ){
+                # for example:
+                #
+                #   lookForAlignDelims:
+                #      tabular: 
+                #         dontMeasure:
+                #           -
+                #               regex: \multicolumn{1}{c}{Expiry}
+                #               applyTo: cell
+                #
+                # OR (note that applyTo is optional):
+                #
+                #   lookForAlignDelims:
+                #      tabular: 
+                #         dontMeasure:
+                #           -
+                #               regex: \multicolumn{1}{c}{Expiry}
+                next if(defined ${$_}{applyTo} and !${$_}{applyTo} eq "cell" );
+                my $regex = qr/${$_}{regex}/;
+                next unless ${$cellStorage[$input{row}][$input{column}]}{entry} =~ m/${$_}{regex}/;
+                $logger->trace("CELL FOUND (regex): ${$_}{regex} and will not be measured") if($is_t_switch_active);
+                ${$cellStorage[$input{row}][$input{column}]}{measureThis} = 0;
+                ${$cellStorage[$input{row}][$input{column}]}{type} = "X";
+            }
         }
+    } elsif($input{mode} eq "row" and (ref(${$self}{dontMeasure}) eq "ARRAY")){
+        foreach(@{${$self}{dontMeasure}}){
+            # move on, unless we have specified applyTo as row:
+            #
+            #    lookForAlignDelims:
+            #       tabular: 
+            #          dontMeasure:
+            #            -
+            #                this: \multicolumn{1}{c}{Expiry}
+            #                applyTo: row
+            #
+            # note: *default value* of applyTo is cell
+            next unless (ref($_) eq "HASH" and  defined ${$_}{applyTo} and ${$_}{applyTo} eq "row");
+            if(${$_}{this} and $input{row} eq ${$_}{this}){
+                $logger->trace("ROW FOUND (this): ${$_}{this}") if($is_t_switch_active);
+                $logger->trace("and will not be measured") if($is_t_switch_active);
+                ${$self}{measureRow} = 0;
+            } elsif(${$_}{regex} and $input{row} =~  ${$_}{regex}){
+                $logger->trace("ROW FOUND (regex): ${$_}{regex}") if($is_t_switch_active);
+                $logger->trace("and will not be measured") if($is_t_switch_active);
+                ${$self}{measureRow} = 0;
+            }
+        }
     }
+}
 
-    # the maximum row width will be used in aligning (or not) the \\
-    my $maximumRowWidth = 0;
+sub individual_padding{
+  # PURPOSE
+  #     (1) the *primary* purpose of this routine is to 
+  #         measure the *individual padding* of 
+  #         each cell.
+  #
+  #         for example, for 
+  #
+  #            111 & 2  & 33333 \\
+  #            4   & 55 & 66\\ 
+  #
+  #         then the individual padding will be
+  #         
+  #            0    1   0
+  #            2    0   3
+  #
+  #         this is calculated by looping 
+  #         through the rows & columns
+  #         and finding the maximum column widths
+  #
+  #     (2) the *secondary* purpose of this routine is to 
+  #         fill in any gaps in the @cellStorage array 
+  #         for any entries that don't yet exist;
+  #
+  #         for example, 
+  #               111 & 2  & 33333 \\
+  #               4   & 55 & 66\\
+  #               77  & 8   <------ GAP HERE
+  #
+  #         there is a gap in @cellStorage in the final row,
+  #         which is completed by the second loop in the below
+  
+  my $self = shift;
 
-    # now that the multicolumn widths have been accounted for, loop through the body
-    foreach(@formattedBody){
-        if(${$_}{format} and ${$_}{row} !~ m/^\h*$/){
+  # array to store maximum column widths
+  my @maximumColumnWidths;
 
-            # set a columnCount, which will vary depending on multiColumnGrouping settings or not
-            my $columnCount=0;
-            my $tmpRow = q();
+  # we count the maximum number of columns
+  my $maximumNumberOfColumns = 0;
 
-            # loop through the columns
-            foreach my $column (@{${$_}{columns}}){
-                # calculate the width of the current column 
-                my $gcs  = Unicode::GCString->new($column);
-                my $columnWidth = $gcs->columns();
+  # maximum column width loop
+  # maximum column width loop
+  # maximum column width loop
+  
+  $logger->trace("*dontMeasure routine, cell mode") if(${$self}{dontMeasure} and $is_t_switch_active);
 
-                # reset the column padding
-                my $padding = q();
+  # row loop
+  my $rowCount = -1;
+  foreach my $row (@cellStorage) {
+    $rowCount++;
 
-                # check for multiColumnGrouping
-                if(${$_}{multiColumnGrouping} and $column =~ m/\\multicolumn\{(\d+)\}/ and $1>1){
-                    my $multiColSpan = $1;
+    # column loop
+    my $j = -1;
+    foreach my $cell (@$row) {
+        $j++;
 
-                    # groupingWidth contains the total width of column sizes grouped 
-                    # underneath the \multicolumn{} statement
-                    my $maxGroupingWidth = ${${$_}{maxGroupingWidth}}[$columnCount];
+        # if alignRowsWithoutMaxDelims = 0
+        # and there are *less than* the maximum number of ampersands, then 
+        # don't measure this column
+        if( !${$self}{alignRowsWithoutMaxDelims} 
+                and 
+             ${$formattedBody[$rowCount]}{numberOfAmpersands} < ${$self}{maximumNumberOfAmpersands} ){
+             ${$cell}{measureThis} = 0;
+             ${$cell}{type} = "*";
+        }
 
-                    # it's possible to have situations such as
-                    #
-	                # \multicolumn{3}{l}{one} & \multicolumn{3}{l}{two} & \\ 
-	                # \multicolumn{6}{l}{one}                           & \\
-                    #
-                    # in which case we need to loop through the @maximumColumnWidthMC
-                    my $groupingWidthMC = 0;
-                    my $multicolsEncountered =0;
-                    for ($columnCount..($columnCount + ($multiColSpan-1))){
-                        if(defined $maximumColumnWidthMC[$_]){
-                            $groupingWidthMC += $maximumColumnWidthMC[$_];
-                            $multicolsEncountered++ if $maximumColumnWidthMC[$_]>0;
-                        }
-                    }
+        # check if the cell shouldn't be measured
+        $self->dont_measure(mode=>"cell",row=>$rowCount,column=>$j) if ${$self}{dontMeasure};
 
-                    # need to account for (spacesBeforeAmpersands) + length of ampersands (which is 1) + (spacesAfterAmpersands)
-                    $groupingWidthMC += ($multicolsEncountered-1)*(${$self}{spacesBeforeAmpersand}+1+${$self}{spacesAfterAmpersand});
-                    
-                    # set the padding; we need
-                    #       maximum( $maxGroupingWidth, $maximumColumnWidthMC[$columnCount] )
-                    my $maxValueToUse = 0;
-                    if(defined $maximumColumnWidthMC[$columnCount]){
-                        $maxValueToUse = max($maxGroupingWidth,$maximumColumnWidthMC[$columnCount],$groupingWidthMC);
-                    } else {
-                        $maxValueToUse = $maxGroupingWidth;
-                    }
+        # it's possible to have delimiters of different lengths, for example
+        #
+        #       \begin{tabbing}
+        #       	1   # 22  \> 333   # 4444     \\
+        #       	xxx # aaa #  yyyyy # zzzzzzzz \\
+        #       	.   #     #  &     #          \\
+        #
+        #       	          ^^
+        #       	          ||
+        #       \end{tabbing}
+        #
+        # note that this has a delimiter of \> (length 2) and # (length 1)
+        #
+        # furthermore, it's possible to specify the delimiter justification as "left" or "right"
+        if(${$cell}{delimiterLength}>0 and ${$cell}{delimiterLength} < $maxDelimiterWidth[$j]){
+           if(${$self}{delimiterJustification} eq "left"){
+               ${$cell}{delimiter} .= " " x ($maxDelimiterWidth[$j] - ${$cell}{delimiterLength});
+           } elsif(${$self}{delimiterJustification} eq "right") {
+               ${$cell}{delimiter} = " " x ($maxDelimiterWidth[$j] - ${$cell}{delimiterLength}).${$cell}{delimiter} ;
+           }
 
-                    # calculate the padding
-                    $padding = " " x ( $maxValueToUse  >= $columnWidth ? $maxValueToUse  - $columnWidth : 0 );
+           # update the delimiterLength
+           ${$cell}{delimiterLength} = $maxDelimiterWidth[$j];
+        }
+        
+        # there are some cells that shouldn't be accounted for in measuring, 
+        # for example {ccc}
+        next if !${$cell}{measureThis};
 
-                    # to the log file
-                    if($is_tt_switch_active){    
-                        $logger->trace("*---------column-------------");
-                        $logger->trace($column);
-                        $logger->trace("multiColSpan: $multiColSpan");
-                        $logger->trace("groupingWidthMC: $groupingWidthMC");
-                        $logger->trace("padding length: ",$maxValueToUse  - $columnWidth);
-                        $logger->trace("multicolsEncountered: $multicolsEncountered");
-                        $logger->trace("maxValueToUse: $maxValueToUse");
-                        $logger->trace("maximumColumnWidth: ",join(",", at maximumColumnWidth));
-                        $logger->trace("maximumColumnWidthMC: ",join(",", at maximumColumnWidthMC));
-                    }
+        # otherwise, make the measurement
+        $maximumColumnWidths[$j] = (defined $maximumColumnWidths[$j] 
+                                        ? 
+                                    max($maximumColumnWidths[$j],${$cell}{width})
+                                        :
+                                    ${$cell}{width});
+    }
 
-                    # update the columnCount to account for the multiColSpan
-                    $columnCount += $multiColSpan - 1;
-                } else {
-                    # compare the *current* column width with the *maximum* column width
-                    $padding = " " x (defined $maximumColumnWidth[$columnCount] and $maximumColumnWidth[$columnCount] >= $columnWidth ? $maximumColumnWidth[$columnCount] - $columnWidth : 0);
-                }
+    # update the maximum number of columns
+    $maximumNumberOfColumns = $j if ( $j > $maximumNumberOfColumns );
+  }
+  
+  # individual padding and gap filling loop
+  # individual padding and gap filling loop
+  # individual padding and gap filling loop
+  
+  # row loop
+  foreach my $row (@cellStorage) {
+    # column loop
+    foreach (my $j=0; $j <= $maximumNumberOfColumns; $j++){
+        if( defined ${$row}[$j]){
+            # individual padding
+            my $maximum = (defined $maximumColumnWidths[$j] ? $maximumColumnWidths[$j]: 0);
+            my $cellWidth = ${$row}[$j]{width}; 
+            ${$row}[$j]{individualPadding} += ($maximum > $cellWidth ? $maximum - $cellWidth : 0);
+        } else { 
+            # gap filling
+            ${$row}[$j] = ({type=>"-",
+                            entry=>'',
+                            width=>0,
+                            individualPadding=>0,
+                            groupPadding=>0,
+                            measureThis=>0,
+                            colSpan=>".",
+                            delimiter=>"", 
+                            delimiterLength=>0,
+              });
+        }
 
-                # either way, the row is formed of "COLUMN + PADDING"
-                if(${$self}{justification} eq "left"){
-                    $tmpRow .= $column.$padding.(defined @{${$_}{multiColPadding}}[$columnCount] ? " " x @{${$_}{multiColPadding}}[$columnCount]: q()).(" " x ${$self}{spacesBeforeAmpersand})."&".(" " x ${$self}{spacesAfterAmpersand});
-                } else {
-                    $tmpRow .= $padding.(defined @{${$_}{multiColPadding}}[$columnCount] ? " " x @{${$_}{multiColPadding}}[$columnCount]: q()).$column.(" " x ${$self}{spacesBeforeAmpersand})."&".(" " x ${$self}{spacesAfterAmpersand});
-                }
-                $columnCount++;
-            }
+        # now the gaps have been filled, store the maximumColumnWidth for future reference
+        ${$row}[$j]{maximumColumnWidth} = (defined $maximumColumnWidths[$j] ? $maximumColumnWidths[$j] : 0);
+    }
+  }
+}
 
-            # remove the final &
-            $tmpRow =~ s/\h*&\h*$/ /;
-            my $finalSpacing = q();
-            $finalSpacing = " " x (${$self}{spacesBeforeDoubleBackSlash}) if ${$self}{spacesBeforeDoubleBackSlash}>=1;
-            $tmpRow =~ s/\h*$/$finalSpacing/;
+sub multicolumn_pre_check {
+  # PURPOSE:
+  #     ensure that multiple multicolumn commands are 
+  #     handled appropriately
+  #
+  #     example 1
+  #
+  #           \multicolumn{2}{c}{thing} &       \\
+  #           111 & 2                   & 33333 \\
+  #           4   & 55                  & 66    \\ 
+  #           \multicolumn{2}{c}{a}     &       \\
+  #
+  #              ^^^^^^^^
+  #              ||||||||
+  #              
+  #     the second multicolumn command should not be measured, but 
+  #     *should* receive individual padding
+    my $self = shift;
 
-            # replace the row with the formatted row
-            ${$_}{row} = $tmpRow;
+    # loop through minMultiColSpan and add empty entries as necessary
+    foreach(@minMultiColSpan){
+        $_ = "." if !(defined $_);
+    }
 
-            # update the maximum row width
-            my $gcs  = Unicode::GCString->new($tmpRow);
-            ${$_}{rowWidth} = $gcs->columns();
-            $maximumRowWidth = ${$_}{rowWidth} if(${$_}{rowWidth} >  $maximumRowWidth);
-        } 
+    # ensure that only the *MINIMUM* multicolumn commands are designated 
+    # to be measured; for example:
+    #
+    #     \multicolumn{2}{c|}{Ótimo humano}      & Abuso da pontuação & Recompensas densas \\
+    #     \multicolumn{3}{c||}{Exploração Fácil}                      & second             \\
+    #     Assault     & Asterix                  & Beam Rider         & Alien              \\
+    #
+    # the \multicolumn{2}{c|}{Ótimo humano} *is* the minimum multicolumn command
+    # for the first column, and the \multicolumn{3}{c||}{Exploração Fácil} *is not*
+    # to be measured
+    
+    # row loop
+    my $rowCount = -1;
+    foreach my $row (@cellStorage) {
+      $rowCount++;
+
+      # column loop
+      my $j = -1;
+      foreach my $cell (@$row) {
+        $j++;
+        if( ${$cell}{type} =~ m/(\d)/ and ($1 >$minMultiColSpan[$j])){
+          ${$cell}{type} = "X";
+          ${$cell}{measureThis} = 0;
+        }
+      }
     }
 
-    # final loop through to get \\ aligned
-    foreach (@formattedBody){
-        # reset the padding
-        my $padding = q();
+    # now loop back through and ensure that each of the \multicolumn commands
+    # are measured correctly
+    #
+    # row loop
+    $rowCount = -1;
+    foreach my $row (@cellStorage) {
+      $rowCount++;
 
-        # possibly adjust the padding
-        if(${$_}{format} and ${$_}{row} !~ m/^\h*$/){
-            # remove trailing horizontal space if ${$self}{alignDoubleBackSlash} is set to 0
-            ${$_}{row} =~ s/\h*$// if (!${$self}{alignDoubleBackSlash});
+      # column loop
+      my $j = -1;
+      foreach my $cell (@$row) {
+        $j++;
+        
+        # multicolumn entry
+        if(${$cell}{type} =~ m/(\d)/) {
+
+           my $multiColumnSpan = $1;
+
+           # *inner* row loop
+           my $innerRowCount = -1;
+           foreach my $innerRow (@cellStorage) {
+             $innerRowCount++;
+
+             # we only want to measure the *other* rows
+             next if($innerRowCount == $rowCount);
+             
+             # column loop
+             my $innerJ = -1;
+             foreach my $innerCell (@$innerRow) {
+               $innerJ++;
+
+               if(  $innerJ == $j and ${$innerCell}{type} =~ m/(\d)/ and $1 >= $multiColumnSpan){
+                 if(${$cell}{width} < ${$innerCell}{width}){
+                     ${$cell}{type} = "X";
+                     ${$cell}{measureThis} = 0;
+                     ${$cell}{individualPadding} = (${$innerCell}{width} - ${$cell}{width} );
+                 } else {
+                     ${$innerCell}{type} = "X";
+                     ${$innerCell}{measureThis} = 0;
+                     ${$innerCell}{individualPadding} = (${$cell}{width} - ${$innerCell}{width});
+                 }
+               }
+             }
+           }
+        }
+       }
+      }
+}
+
+sub multicolumn_padding{
+    # PURPOSE:
+    #   assign multi column padding, for example:
+    #
+    #       \multicolumn{2}{c}{thing}&\\
+    #       111 &2&33333 \\
+    #       4& 55&66\\ 
+    #
+    #  needs to be transformed into
+    #
+    #       \multicolumn{2}{c}{thing} &       \\
+    #       111 & 2                   & 33333 \\
+    #       4   & 55                  & 66    \\ 
+    #
+    #                ^^^^^^^^^^^^^^^
+    #                |||||||||||||||
+    #
+    #  and we need to compute the multi column padding,
+    #  illustrated by the up arrows in the above
+    #
+    #  Approach:
+    #   (1) measure the "grouping widths" under/above each of the 
+    #       \multicolumn entries; these are stored within
+    #
+    #               groupingWidth 
+    #
+    #       for the relevant column entries; in the 
+    #       above example, they would be stored in the 
+    #
+    #           2
+    #           55
+    #
+    #       entries when justification is LEFT, and in the 
+    #
+    #           111
+    #           4
+    #
+    #       entries when justification is RIGHT. We also calculate
+    #       maximum grouping width and store it within $maxGroupingWidth
+    #
+    #   (2) loop back through and update
+    #
+    #           groupPadding
+    #
+    #       for each of the relevant column entries; in the 
+    #       above example, they would be stored in the 
+    #
+    #           2
+    #           55
+    #
+    #       entries when justification is LEFT, and in the 
+    #
+    #           111
+    #           4
+    #
+    #   (3) finally, account for the \multicolumn command itself;
+    #       ensuring that we account for it being wider or narrower 
+    #       than its spanning columns
+    my $self = shift;
+
+    # row loop
+    my $rowCount = -1;
+    foreach my $row (@cellStorage) {
+      $rowCount++;
+
+      # column loop
+      my $j = -1;
+      foreach my $cell (@$row) {
+          $j++;
+          
+          # multicolumn entry
+          next unless (${$cell}{type} =~ m/(\d)/);
+
+          my $multiColumnSpan = $1;
+
+          my $maxGroupingWidth = 0;
+          
+          # depending on the 
+          #
+          #    justification
+          #
+          # setting (left or right), we store the 
+          #
+          #    groupingWidth 
+          #
+          # and groupPadding accordingly
+          my $justificationOffset = (${$self}{justification} eq "left" ? $j+$multiColumnSpan-1 : $j);
+
+          # phase (1)
+          # phase (1)
+          # phase (1)
+          
+          # *inner* row loop
+          my $innerRowCount = -1;
+          foreach my $innerRow (@cellStorage) {
+            $innerRowCount++;
+
+            # we only want to measure the *other* rows
+            next if($innerRowCount == $rowCount);
+
+            # we will store the width of columns spanned by the multicolumn command
+            my $groupingWidth = 0;
+
+            # *inner* column loop
+            for (my $innerJ = 0; $innerJ < $multiColumnSpan; $innerJ++) {
+
+               # some entries should not be measured in the grouping width, 
+               # for example
+               #
+               #       \multicolumn{2}{c}{thing} &       \\
+               #       111 & 2                   & 33333 \\
+               #       4   & 55                  & 66    \\ 
+               #       \multicolumn{2}{c}{a}     &       \\
+               #
+               #          ^^^^^^^^
+               #          ||||||||
+               #          
+               # the second \multicolumn entry shouldn't be measured, and it will 
+               # have had 
+               #     
+               #         measureThis 
+               #
+               # switched off during multicolumn_pre_check
+               
+               next if !${$cellStorage[$innerRowCount][$j+$innerJ]}{measureThis};
+
+               $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{width};
+               $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{individualPadding};
+               $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{delimiterLength} if ($innerJ < $multiColumnSpan - 1);
+            }
+
+            # adjust for 
+            #           <spacesBeforeAmpersand>
+            #           &
+            #           <spacesEndAmpersand>
+            # note:
+            #    we need to multiply this by the appropriate multicolumn 
+            #    spanning; in the above example:
+            #
+            #       \multicolumn{2}{c}{thing} &       \\
+            #       111 & 2                   & 33333 \\
+            #       4   & 55                  & 66    \\ 
+            #
+            #   we multiply by (2-1) = 1 because there is *1* ampersand
+            #   underneath the multicolumn command
+            #
+            # note:
+            #   the & will have been accounted for in the above section using delimiterLength
             
-            # format spacing infront of \\
-            if(defined ${$self}{spacesBeforeDoubleBackSlash} and ${$self}{spacesBeforeDoubleBackSlash}<0 and !${$self}{alignDoubleBackSlash}){
-                # zero spaces (possibly resulting in un-aligned \\)
-                $padding = q();
-            } elsif(defined ${$self}{spacesBeforeDoubleBackSlash} and ${$self}{spacesBeforeDoubleBackSlash}>=0 and !${$self}{alignDoubleBackSlash}){
-                # specified number of spaces (possibly resulting in un-aligned \\)
-                $padding = " " x (${$self}{spacesBeforeDoubleBackSlash});
-            } else {
-                # aligned \\
-                $padding = " " x ($maximumRowWidth - ${$_}{rowWidth});
+            $groupingWidth += ($multiColumnSpan-1)
+                                     *
+                              (${$self}{spacesBeforeAmpersand} + ${$self}{spacesAfterAmpersand});
+
+            # store the grouping width for the next phase
+            ${$cellStorage[$innerRowCount][$justificationOffset]}{groupingWidth} = $groupingWidth;
+
+            # update the maximum grouping width
+            $maxGroupingWidth = max($maxGroupingWidth, $groupingWidth);
+
+          }
+
+          # phase (2)
+          # phase (2)
+          # phase (2)
+          
+          # now that the maxGroupingWidth has been established, loop back 
+          # through and update groupingWidth for the appropriate cells
+          
+          # *inner* row loop
+          $innerRowCount = -1;
+          foreach my $innerRow (@cellStorage) {
+            $innerRowCount++;
+
+            # we only want to make adjustment on the *other* rows
+            next if($innerRowCount == $rowCount);
+
+            # it's possible that we have multicolumn commands that were *not* measured,
+            # and are *narrower* than the maxGroupingWidth, for example:
+            #
+            #        \multicolumn{3}{l}{aaaa}         &         \\    <------ this entry won't have been measured! 
+            #        $S_N$ & $=$ & $\SI{1000}{\kV\A}$ & $U_0$ & \\
+            #        \multicolumn{3}{l}{bbbbbbb}      &         \\
+            #
+            if(  ${$cellStorage[$innerRowCount][$j]}{colSpan} ne "."
+                    and ${$cellStorage[$innerRowCount][$j]}{colSpan} == $multiColumnSpan
+                    and !${$cellStorage[$innerRowCount][$j]}{measureThis} 
+                    and $maxGroupingWidth > ${$cellStorage[$innerRowCount][$j]}{width}
+                    and ${$cellStorage[$innerRowCount][$j]}{width} >= ${$cell}{width}) {
+                ${$cellStorage[$innerRowCount][$j]}{individualPadding} = 0;
+                ${$cellStorage[$innerRowCount][$j]}{groupPadding} = ($maxGroupingWidth - ${$cellStorage[$innerRowCount][$j]}{width});
             }
+
+            my $groupingWidth = ${$cellStorage[$innerRowCount][$justificationOffset]}{groupingWidth};
+
+            # phase (3)
+            # phase (3)
+            # phase (3)
+            
+            # there are two possible cases:
+            #
+            # (1) the \multicolumn statement is *WIDER* than its grouped columns, e.g.:
+            #
+            #       \multicolumn{2}{c}{thing} &       \\
+            #       111 & 2                   & 33333 \\ 
+            #       4   & 55                  & 66    \\ 
+            #                ^^^^^^^^^^^^^^^
+            #                |||||||||||||||
+            #
+            #     in this situation, we need to adjust each of the group paddings for the cells
+            #     marked with an up arrow
+            #
+            # (2) the \multicolumn statement is *NARROWER* than its grouped columns, e.g.:
+            #
+            #                                 ||
+            #                                 **
+            #       \multicolumn{2}{c}{thing}    &       \\
+            #       111 & bbbbbbbbbbbbbbbbbbbbbb & 33333 \\
+            #       4   & 55                     & 66    \\ 
+            #
+            #     in this situation, we need to adjust the groupPadding of the multicolumn
+            #     entry, which happens ***once the row loop has finished***
+            #
+            if(${$cell}{width} > $maxGroupingWidth ){
+                 ${$cellStorage[$innerRowCount][$justificationOffset]}{groupPadding} = (${$cell}{width} - $maxGroupingWidth );
+            }  
+          }
+
+          # case (2) from above when \multicolumn statement is *NARROWER* than its grouped columns
+          if(${$cell}{width} < $maxGroupingWidth ){
+             ${$cell}{groupPadding} += ($maxGroupingWidth - ${$cell}{width});
+             ${$cell}{individualPadding} = 0;
+          }
+      }
+
+    }
+
+}
+
+sub multicolumn_post_check {
+  # PURPOSE:
+  #     ensure that multiple multicolumn commands are 
+  #     handled appropriately
+  #
+  #     example 1
+  #
+  #           \multicolumn{2}{c}{thing} & aaa     & bbb  \\
+  #           111 & 2                   & 33333   &      \\
+  #           4   & 55                  & 66      &      \\ 
+  #           \multicolumn{3}{c}{a}               &      \\
+  #
+  #                                 ^^^^^^^^
+  #                                 ||||||||
+  #              
+  #     the second multicolumn command needs to have its group padding
+  #     accounted for.
+  #
+  #     *Note* this will not have been done previously, as
+  #     this second multicolumn command will have had its type changed to 
+  #     X, because it spans 3 columns, and there is a cell within its 
+  #     column that spans *less than 3 columns*
+  my $self = shift;
+
+  # row loop
+  my $rowCount = -1;
+  foreach my $row (@cellStorage) {
+    $rowCount++;
+
+    # column loop
+    my $j = -1;
+    foreach my $cell (@$row) {
+      $j++;
+      
+      # we only need to account for X-type columns, with an integer colSpan
+      next unless (${$cell}{type} eq "X" and ${$cell}{colSpan} =~ m/(\d+)/);
+
+      # multicolumn entry
+      my $multiColumnSpan = $1;
+      
+      # we store the maximum grouping width
+      my $maxGroupingWidth = 0;
+
+      # *inner* row loop
+      my $innerRowCount = -1;
+      foreach my $innerRow (@cellStorage) {
+        $innerRowCount++;
+
+        # we only want to measure the *other* rows
+        next if($innerRowCount == $rowCount);
+        
+        # we will store the width of columns spanned by the multicolumn command
+        my $groupingWidth = 0;
+        
+        # we need to keep track of the number of ampersands encountered; 
+        #
+        # for example:
+        #
+        #       \multicolumn{2}{c}{thing} & aaa     & bbb  \\
+        #       111 & 2                   & 33333   &      \\
+        #       4   & 55                  & 66      &      \\ 
+        #       \multicolumn{3}{c}{a}               &      \\   <!----- focus on the multicolumn entry in this row
+        #
+        # focusing on the final multicolumn entry (spanning 3 columns), 
+        # when we loop back through the rows, we will encounter:
+        #
+        #   row 1: one ampersand
+        #
+        #       \multicolumn{2}{c}{thing} & aaa    ...
+        #
+        #   row 2: two ampersands
+        #
+        #       111 & 2                   & 33333  ...
+        #
+        #   row 3: two ampersands
+        #
+        #       4   & 55                  & 66     ...
+        #
+        # note: we start the counter at -1, because the count of ampersands
+        #       is always one behind the cell count; for example, looking 
+        #       at row 3 in the above, in the above, in cell 1 (entry: 4)
+        #       we have 0 ampersands, in cell 2 (entry: 55) we now have 1 ampersands, etc
+        my $ampersandsEncountered = -1;
+
+        # column loop
+        my @dumRow = @$innerRow;
+        foreach (my $innerJ = 0; $innerJ <= $#dumRow; $innerJ++){
+
+          # exit the loop if we've reached the multiColumn spanning width
+          last if($innerJ >= ($multiColumnSpan));
+
+          # don't include '*' or '-' cell types in the calculations
+          my $type = ${$cellStorage[$innerRowCount][$j+$innerJ]}{type};
+          next if($type eq "*" or $type eq "-");
+
+          # update the grouping width
+          $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{width};
+          $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{individualPadding};
+
+          # update the number of & encountered
+          $ampersandsEncountered++;
+          $groupingWidth += ${$cellStorage[$innerRowCount][$j+$innerJ]}{delimiterLength} if ($ampersandsEncountered>0);
+
+          # and adjust the column count, if necessary; in the above example
+          #
+          #       \multicolumn{2}{c}{thing} & aaa     & bbb  \\
+          #       111 & 2                   & 33333   &      \\
+          #       4   & 55                  & 66      &      \\ 
+          #       \multicolumn{3}{c}{a}               &      \\   <!----- focus on the multicolumn entry in this row
+          #
+          # the *first entry* \multicolumn{2}{c}{thing} spans 2 columns, so 
+          # we need to move the column count along accordingly
+          
+          if(${$cellStorage[$innerRowCount][$j+$innerJ]}{colSpan} =~ m/(\d+)/){
+            $innerJ += $1-1;
+          }
+          
         }
+        
+        # adjust for 
+        #           <spacesBeforeAmpersand>
+        #           &
+        #           <spacesEndAmpersand>
+        # note:
+        #    we need to multiply this by the appropriate 
+        #    number of *ampersandsEncountered*
+        #
+        #       \multicolumn{2}{c}{thing} &       \\
+        #       111 & 2                   & 33333 \\
+        #       4   & 55                  & 66    \\ 
+        
+        $groupingWidth += $ampersandsEncountered
+                                 *
+                          (${$self}{spacesBeforeAmpersand} + ${$self}{spacesAfterAmpersand});
+                          
+        # update the maximum grouping width
+        $maxGroupingWidth = max($maxGroupingWidth, $groupingWidth);
+      }
 
-        # format the row, and put the trailing \\ and trailing comments back into the row
-        ${$_}{row} .= $padding.(${$_}{endPiece} ? ${$_}{endPiece} :q() ).(${$_}{trailingComment}? ${$_}{trailingComment} : q() );
+      ${$cell}{individualPadding} = 0;
+
+      # there are cases where the 
+      #
+      #     maxGroupingWidth 
+      #
+      # is *less than* the cell width, for example:
+      #
+      #    \multicolumn{4}{|c|}{\textbf{Search Results}} \\  <!------ the width of this multicolumn entry 
+	  #    1  & D7  & R                       &          \\           is larger than maxGroupingWidth
+	  #    2  & D2  & R                       &          \\
+	  #    \multicolumn{3}{|c|}{\textbf{Avg}} &          \\
+      #
+      ${$cell}{groupPadding} = max(0,$maxGroupingWidth - ${$cell}{width});
+     }
     }
+}
 
-    # to the log file
-    if($is_tt_switch_active){    
-        $logger->trace(${$_}{row}) for @formattedBody;
+sub pretty_print_cell_info{
+  
+  my $thingToPrint = (defined $_[0] ? $_[0] : "entry");
+
+  $logger->trace("*cell information: $thingToPrint");
+
+  $logger->trace("minimum multi col span: ",join(",", at minMultiColSpan)) if(@minMultiColSpan);
+
+  foreach my $row (@cellStorage) {
+    my $tmpLogFileLine = q();
+    foreach my $cell (@$row) {
+        $tmpLogFileLine .= ${$cell}{$thingToPrint}."\t";
     }
+    $logger->trace(' ', $tmpLogFileLine) if($is_t_switch_active);
+  }
 
-    # delete the original body
-    ${$self}{body} = q();
+  if($thingToPrint eq "type"){
+    $logger->trace("*key to types:");
+    $logger->trace("\tX\tbasic cell, will be measured and aligned");
+    $logger->trace("\t*\t will not be measured, and no ampersand");
+    $logger->trace("\t-\t phantom/blank cell for gaps");
+    $logger->trace("\t[0-9]\tmulticolumn cell, spanning multiple columns");
+  }
 
-    # update the body
-    ${$self}{body} .= ${$_}{row}."\n" for @formattedBody;
-
-    # if the \end{} statement didn't originally have a line break before it, we need to remove the final 
-    # line break added by the above
-    ${$self}{body} =~ s/\h*\R$//s if !${$self}{linebreaksAtEnd}{body};
 }
 
 sub double_back_slash_else{

Modified: trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm
===================================================================
--- trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm	2020-03-21 21:20:37 UTC (rev 54454)
@@ -35,7 +35,7 @@
 use LatexIndent::Indent qw/indent wrap_up_statement determine_total_indentation indent_begin indent_body indent_end_statement final_indentation_check  get_surrounding_indentation indent_children_recursively check_for_blank_lines_at_beginning put_blank_lines_back_in_at_beginning add_surrounding_indentation_to_begin_statement post_indentation_check/;
 use LatexIndent::Tokens qw/token_check %tokens/;
 use LatexIndent::HiddenChildren qw/find_surrounding_indentation_for_children update_family_tree get_family_tree check_for_hidden_children/;
-use LatexIndent::AlignmentAtAmpersand qw/align_at_ampersand find_aligned_block double_back_slash_else/;
+use LatexIndent::AlignmentAtAmpersand qw/align_at_ampersand find_aligned_block double_back_slash_else main_formatting individual_padding multicolumn_padding multicolumn_pre_check  multicolumn_post_check dont_measure/;
 use LatexIndent::DoubleBackSlash qw/dodge_double_backslash un_dodge_double_backslash/;
 
 # code blocks

Modified: trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm
===================================================================
--- trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm	2020-03-21 21:20:37 UTC (rev 54454)
@@ -42,6 +42,10 @@
                                        {name=>"spacesBeforeAmpersand",default=>1},
                                        {name=>"spacesAfterAmpersand",default=>1},
                                        {name=>"justification",default=>"left"},
+                                       {name=>"alignFinalDoubleBackSlash",default=>0},
+                                       {name=>"dontMeasure",default=>0},
+                                       {name=>"delimiterRegEx",default=>"(?<!\\\\)(&)"},
+                                       {name=>"delimiterJustification",default=>"left"},
                                         );
     
 sub yaml_read_settings{

Modified: trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm
===================================================================
--- trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm	2020-03-21 21:20:37 UTC (rev 54454)
@@ -103,7 +103,7 @@
     ${$self}{cruftDirectory} = $switches{cruftDirectory}||(dirname ${$self}{fileName});
     die "Could not find directory ${$self}{cruftDirectory}\nExiting, no indentation done." if(!(-d ${$self}{cruftDirectory}));
 
-    my $logfileName = ($switches{cruftDirectory} ? ${$self}{cruftDirectory} : '').($switches{logFileName}||"indent.log");
+    my $logfileName = ($switches{cruftDirectory} ? ${$self}{cruftDirectory}."/" : '').($switches{logFileName}||"indent.log");
     
     # layout of the logfile information, for example
     #
@@ -168,8 +168,10 @@
         $logger->info("Filename: ${$self}{fileName}");
     } else {
         $logger->info("Reading input from STDIN");
-        my $buttonText = ($FindBin::Script eq 'latexindent.exe') ? 'CTRL+Z followed by ENTER':'CTRL+D';
-        print STDERR "Please enter text to be indented: (press $buttonText when finished)\n";
+        if (-t STDIN) {
+            my $buttonText = ($FindBin::Script eq 'latexindent.exe') ? 'CTRL+Z followed by ENTER':'CTRL+D';
+            print STDERR "Please enter text to be indented: (press $buttonText when finished)\n";
+        }
     }
 
     # log the switches from the user

Modified: trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm
===================================================================
--- trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm	2020-03-21 21:20:37 UTC (rev 54454)
@@ -25,7 +25,6 @@
 use LatexIndent::IfElseFi qw/$ifElseFiBasicRegExp/;
 use LatexIndent::Heading qw/$allHeadingsRegexp/;
 use LatexIndent::Special qw/$specialBeginAndBracesBracketsBasicRegExp/;
-use Data::Dumper;
 use Exporter qw/import/;
 our @ISA = "LatexIndent::Document"; # class inheritance, Programming Perl, pg 321
 our @EXPORT_OK = qw/one_sentence_per_line/;
@@ -253,7 +252,15 @@
 
                        # text wrapping
                        $sentenceObj->yaml_get_columns;
-                       $sentenceObj->text_wrap;
+                       if(${$sentenceObj}{columns}<=0){
+                           $logger->warn("*Sentence text wrap warning:");
+                           $logger->info("You have specified oneSentencePerLine:textWrapSentences, but columns is set to 0");
+                           $logger->info("You might wish to specify, for example: modifyLineBreaks: textWrapOptions: columns: 80");
+                           $logger->info("The value of oneSentencePerLine:textWrapSentences will now be set to 0, so you won't see this message again");
+                           ${$masterSettings{modifyLineBreaks}{oneSentencePerLine}}{textWrapSentences} = 0;
+                       } else {
+                           $sentenceObj->text_wrap;
+                       }
 
                        # indentation of sentences
                        if(${$sentenceObj}{body} =~ m/

Modified: trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm
===================================================================
--- trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm	2020-03-21 21:20:37 UTC (rev 54454)
@@ -19,6 +19,6 @@
 use Exporter qw/import/;
 our @EXPORT_OK = qw/$versionNumber $versionDate/;
 
-our $versionNumber = '3.7.1';
-our $versionDate = '2019-09-07';
+our $versionNumber = '3.8';
+our $versionDate = '2020-03-21';
 1

Modified: trunk/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml
===================================================================
--- trunk/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml	2020-03-21 21:20:07 UTC (rev 54453)
+++ trunk/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml	2020-03-21 21:20:37 UTC (rev 54454)
@@ -1,4 +1,4 @@
-# defaultSettings.yaml for latexindent.pl, version 3.7.1, 2019-09-07
+# defaultSettings.yaml for latexindent.pl, version 3.8, 2020-03-21
 #                      a script that aims to
 #                      beautify .tex, .sty, .cls files
 #
@@ -154,7 +154,11 @@
       alignRowsWithoutMaxDelims: 1
       spacesBeforeAmpersand: 1
       spacesAfterAmpersand: 1
-      justification: "left"
+      justification: left
+      alignFinalDoubleBackSlash: 0
+      dontMeasure: 0
+      delimiterRegEx: '(?<!\\)(&)'
+      delimiterJustification: left
    tabularx:
       delims: 1
    longtable: 1

Modified: trunk/Master/texmf-dist/scripts/latexindent/latexindent.pl
===================================================================
(Binary files differ)



More information about the tex-live-commits mailing list.