diff options
22 files changed, 1644 insertions, 558 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/latexindent/latexindent.pl b/Build/source/texk/texlive/linked_scripts/latexindent/latexindent.pl index 91e5f09ae8a..cd07805cbe8 100755 --- a/Build/source/texk/texlive/linked_scripts/latexindent/latexindent.pl +++ b/Build/source/texk/texlive/linked_scripts/latexindent/latexindent.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# latexindent.pl, version 3.7.1, 2019-09-07 +# latexindent.pl, version 3.8, 2020-03-21 # # 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 diff --git a/Master/bin/win32/latexindent.exe b/Master/bin/win32/latexindent.exe Binary files differindex 7f91dd58be5..23d0cb32bec 100755 --- a/Master/bin/win32/latexindent.exe +++ b/Master/bin/win32/latexindent.exe diff --git a/Master/texmf-dist/doc/support/latexindent/README b/Master/texmf-dist/doc/support/latexindent/README index 1c1451c2cdc..e0b469f3b3a 100644 --- a/Master/texmf-dist/doc/support/latexindent/README +++ b/Master/texmf-dist/doc/support/latexindent/README @@ -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. diff --git a/Master/texmf-dist/doc/support/latexindent/latexindent.pdf b/Master/texmf-dist/doc/support/latexindent/latexindent.pdf Binary files differindex 6597dba12d7..9eaf86fe5ff 100644 --- a/Master/texmf-dist/doc/support/latexindent/latexindent.pdf +++ b/Master/texmf-dist/doc/support/latexindent/latexindent.pdf diff --git a/Master/texmf-dist/doc/support/latexindent/latexindent.tex b/Master/texmf-dist/doc/support/latexindent/latexindent.tex index 775bd6a7d9d..5ecfce6268d 100644 --- a/Master/texmf-dist/doc/support/latexindent/latexindent.tex +++ b/Master/texmf-dist/doc/support/latexindent/latexindent.tex @@ -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, } diff --git a/Master/texmf-dist/doc/support/latexindent/sec-conclusions-know-limitations.tex b/Master/texmf-dist/doc/support/latexindent/sec-conclusions-know-limitations.tex index 1e865c9c843..ddd4e6c8ad0 100644 --- a/Master/texmf-dist/doc/support/latexindent/sec-conclusions-know-limitations.tex +++ b/Master/texmf-dist/doc/support/latexindent/sec-conclusions-know-limitations.tex @@ -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}). diff --git a/Master/texmf-dist/doc/support/latexindent/sec-default-user-local.tex b/Master/texmf-dist/doc/support/latexindent/sec-default-user-local.tex index 2a657fae8a6..e47115486b7 100644 --- a/Master/texmf-dist/doc/support/latexindent/sec-default-user-local.tex +++ b/Master/texmf-dist/doc/support/latexindent/sec-default-user-local.tex @@ -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 @@ copy myfile.bak4 to myfile.bak3 \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,35 +149,36 @@ copy myfile.bak4 to myfile.bak3 \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 \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 \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 \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,15 +189,14 @@ removeTrailingWhitespace: 1 \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, \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 @@ postfoothook=\end{mdframed}, \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 @@ lookForAlignDelims: 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 @@ lookForAlignDelims: 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 @@ lookForAlignDelims: $\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 @@ latexindent.pl tabular2.tex -l tabular2.yaml,tabular8.yaml 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 @@ latexindent.pl matrix1.tex (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 @@ latexindent.pl matrix1.tex \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 @@ latexindent.pl matrix1.tex \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,21 +806,20 @@ latexindent.pl special3.tex -l=special-verb1 \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 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 @@ mand arg text \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}. diff --git a/Master/texmf-dist/doc/support/latexindent/sec-fine-tuning.tex b/Master/texmf-dist/doc/support/latexindent/sec-fine-tuning.tex index 9a2cbbb5c81..f026a176231 100644 --- a/Master/texmf-dist/doc/support/latexindent/sec-fine-tuning.tex +++ b/Master/texmf-dist/doc/support/latexindent/sec-fine-tuning.tex @@ -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} diff --git a/Master/texmf-dist/doc/support/latexindent/sec-how-to-use.tex b/Master/texmf-dist/doc/support/latexindent/sec-how-to-use.tex index bdae2b428e4..4735cb34a57 100644 --- a/Master/texmf-dist/doc/support/latexindent/sec-how-to-use.tex +++ b/Master/texmf-dist/doc/support/latexindent/sec-how-to-use.tex @@ -286,7 +286,7 @@ latexindent.pl -c=/path/to/directory/ myfile.tex 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,12 +329,19 @@ latexindent.pl myfile \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 @@ -357,7 +364,7 @@ latexindent.pl -r myfile.tex 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 -rv myfile.tex 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 -rr myfile.tex 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 diff --git a/Master/texmf-dist/doc/support/latexindent/sec-introduction.tex b/Master/texmf-dist/doc/support/latexindent/sec-introduction.tex index c6fafd92696..a6a2627309f 100644 --- a/Master/texmf-dist/doc/support/latexindent/sec-introduction.tex +++ b/Master/texmf-dist/doc/support/latexindent/sec-introduction.tex @@ -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 @@ perl latexindent-module-installer.pl \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}. diff --git a/Master/texmf-dist/doc/support/latexindent/sec-replacements.tex b/Master/texmf-dist/doc/support/latexindent/sec-replacements.tex index 6bc7223d4d1..aa575f269fc 100644 --- a/Master/texmf-dist/doc/support/latexindent/sec-replacements.tex +++ b/Master/texmf-dist/doc/support/latexindent/sec-replacements.tex @@ -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 @@ latexindent.pl -r replace1.tex 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 @@ latexindent.pl -r replace1.tex -l=replace1.yaml 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 @@ latexindent.pl -r replace1.tex -l=replace1.yaml \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 @@ latexindent.pl -r colsep.tex -l=colsep.yaml \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 @@ latexindent.pl -r colsep.tex -l=colsep1.yaml \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 @@ latexindent.pl -r colsep.tex -l=multi-line.yaml \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 @@ latexindent.pl -r colsep.tex -l=multi-line1.yaml \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 @@ latexindent.pl -rr colsep.tex -l=multi-line1.yaml 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 @@ latexindent.pl -r displaymath.tex -l=displaymath1.yaml \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 @@ latexindent.pl -r -m displaymath.tex -l=displaymath1.yaml,equation.yaml 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 @@ latexindent.pl -r -m displaymath.tex -l=displaymath1.yaml,equation.yaml 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 @@ latexindent.pl -r phrase.tex -l=hspace.yaml 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 @@ latexindent.pl -r phrase.tex -l=hspace.yaml \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 @@ latexindent.pl -r references.tex -l=reference.yaml \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 @@ latexindent.pl -r references.tex -l=reference.yaml 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 @@ latexindent.pl -rr verb1.tex -l=verbatim1.yaml -o=+-rr-mod1 \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,16 +331,16 @@ latexindent.pl -rr verb1.tex -l=verbatim1.yaml -o=+-rr-mod1 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}. \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 @@ latexindent.pl -r amalg1.tex -l=amalg1-yaml,amalg2-yaml,amalg3-yaml \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} diff --git a/Master/texmf-dist/doc/support/latexindent/sec-the-m-switch.tex b/Master/texmf-dist/doc/support/latexindent/sec-the-m-switch.tex index c7cb62a41fd..7d8f72ed7c3 100644 --- a/Master/texmf-dist/doc/support/latexindent/sec-the-m-switch.tex +++ b/Master/texmf-dist/doc/support/latexindent/sec-the-m-switch.tex @@ -146,7 +146,7 @@ latexindent.pl -m textwrap4.tex -o textwrap4-mod2.tex -l textwrap2.yaml 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 @@ latexindent.pl -m textwrap4.tex -o=+-mod2B -l textwrap2B.yaml 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 @@ latexindent.pl url -m -l=manipulate-sentences.yaml 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 @@ latexindent.pl multiple-sentences5 -m -l=sentence-wrap1.yaml \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 @@ latexindent.pl -m textwrap7.tex -l=textwrap12.yaml -o=+-mod12 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 @@ latexindent.pl -m env-mlb.tex -l env-mlb2.yaml \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 @@ latexindent.pl -m env-mlb.1tex -l env-body4.yaml 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 @@ latexindent.pl -m env-mlb.tex -l env-mlb8.yaml \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 @@ latexindent.pl -m env-mlb.1tex -l env-end-f4.yaml 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 @@ latexindent.pl -m env-mlb7.tex -l env-mlb13.yaml,env-mlb14.yaml,UnpreserveBlankL \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 @@ latexindent.pl -m env-mlb7.tex -l env-mlb13.yaml,env-mlb14.yaml,UnpreserveBlankL \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 @@ latexindent.pl -m tabular3.tex -l DBS2.yaml \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 @@ latexindent.pl -m tabular3.tex -l DBS4.yaml \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 @@ latexindent.pl -m tabular3.tex -l DBS4.yaml \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 @@ latexindent.pl -m special4.tex -l DBS5.yaml 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 @@ latexindent.pl -m special4.tex -l DBS5.yaml 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,16 +1655,16 @@ latexindent.pl -m mycommand2.tex -l DBS7.yaml 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}[ 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 @@ latexindent.pl -m mycommand2.tex -l DBS7.yaml 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 @@ latexindent.pl -m pmatrix3.tex -l DBS3.yaml \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 @@ latexindent.pl -m pmatrix3.tex -l DBS3.yaml \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} diff --git a/Master/texmf-dist/doc/support/latexindent/subsubsec-no-add-remaining-code-blocks.tex b/Master/texmf-dist/doc/support/latexindent/subsubsec-no-add-remaining-code-blocks.tex index a91b4b0c98f..7068c5a873b 100644 --- a/Master/texmf-dist/doc/support/latexindent/subsubsec-no-add-remaining-code-blocks.tex +++ b/Master/texmf-dist/doc/support/latexindent/subsubsec-no-add-remaining-code-blocks.tex @@ -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}. diff --git a/Master/texmf-dist/doc/support/latexindent/title.tex b/Master/texmf-dist/doc/support/latexindent/title.tex index 4dde532e63c..b83f0c45e52 100644 --- a/Master/texmf-dist/doc/support/latexindent/title.tex +++ b/Master/texmf-dist/doc/support/latexindent/title.tex @@ -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! diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm index 8b8e387d095..95f2389e806 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/AlignmentAtAmpersand.pm @@ -20,15 +20,20 @@ use utf8; 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/; 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 @@ sub align_at_ampersand{ my $self = shift; return if(${$self}{bodyLineBreaks}==0); - # calculate the maximum number of ampersands in a row in the body my $maximumNumberOfAmpersands = 0; - foreach(split("\n",${$self}{body})){ - my $numberOfAmpersands = () = $_ =~ /(?<!\\)&/g; - $maximumNumberOfAmpersands = $numberOfAmpersands if($numberOfAmpersands>$maximumNumberOfAmpersands); - } - # create an array of zeros - my @maximumColumnWidth = (0) x ($maximumNumberOfAmpersands+1); - my @maximumColumnWidthMC = (0) x ($maximumNumberOfAmpersands+1); + # clear the global arrays + @formattedBody = (); + @cellStorage = (); + @minMultiColSpan = (); + @maxColumnWidth = (); + @maxDelimiterWidth = (); + + # maximum column widths + my @maximumColumnWidths; - # array for the new body - my @formattedBody; + my $rowCounter = -1; + my $columnCounter = -1; - # now loop back through the body, and store the maximum column size + $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})){ + $rowCounter++; + + # default is to measure this row, but it can be switched off by the dont_measure routine + ${$self}{measureRow} = 1; + + # call the dont_measure routine + $self->dont_measure(mode=>"row",row=>$_) if ${$self}{dontMeasure}; + # 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,318 +195,172 @@ sub align_at_ampersand{ $trailingComments = $1; } - # count the number of ampersands in the current row - my $numberOfAmpersands = () = $_ =~ /(?<!\\)&/g; - - # switch for multiColumGrouping - my $multiColumnGrouping = ($_ =~ m/\\multicolumn/ and ${$self}{multiColumnGrouping}); - my $alignRowsWithoutMaxDelims = ${$self}{alignRowsWithoutMaxDelims}; - - # by default, the stripped row is simply the current row - my $strippedRow = $_; - - # loop through the columns - my $columnCount = 0; - - # format switch off by default - my $formatRow = 0; - - # store the column sizes for measuring and comparison purposes - my @columnSizes = (); - - # we will store the columns in each row - my @columns; - - # 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; - - # if the line finishes with an &, then add an empty space, - # otherwise the column count is off - $_ .= ($_ =~ m/(?<!\\)&$/ ? " ":q()); - - # 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(/(?<!\\)&/,$_) : $_); - - # 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()); - - # 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(); - - # 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+)\}/)); - } + # some rows shouldn't be formatted + my $unformattedRow = $_; + + # 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}/; + + 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()); + + # 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)/,$_) : $_); + + $columnCounter = -1; + my $spanning = 0; + + 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(); + + # 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}); + + # importantly, move on to the next column! + next; + } - # store the maximum column width - $maximumColumnWidth[$columnCount] = $columnWidth if( defined $maximumColumnWidth[$columnCount] and ($columnWidth > $maximumColumnWidth[$columnCount]) ); - - # put the row back together, using " " if the column is empty - $strippedRow .= ($columnCount>0 ? "&" : q() ).($columnWidth > 0 ? $column: " "); - - # store the column width - $columnSizes[$columnCount] = $columnWidth; - - # 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++; + # otherwise increment the column counter, and proceed + $columnCounter++; + + # reset spanning (only applicable if multiColumnGrouping) + $spanning = 0; + + # 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()); + + # 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; + + # 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 ); - # 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; + # adjust the column counter + $columnCounter += $spanning - 1; + } } # store the information - push(@formattedBody,{ - row=>$strippedRow, - format=>$formatRow, - multiColumnGrouping=>$multiColumnGrouping, - columnSizes=>\@columnSizes, - columns=>\@columns, - endPiece=>($endPiece ? $endPiece :q() ), - trailingComment=>($trailingComments ? $trailingComments :q() )}); + push(@formattedBody,{row=>$_, + endPiece=>$endPiece, + trailingComment=>$trailingComments, + numberOfAmpersands=>$numberOfAmpersands, + unformattedRow=>$unformattedRow }); + } - # 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; - - # acount for multicolumn grouping, if the appropriate switch is set - if(${$self}{multiColumnGrouping}){ - foreach(@formattedBody){ - if(${$_}{format} and ${$_}{row} !~ m/^\h*$/){ - - # set a columnCount, which will vary depending on multiColumnGrouping settings or not - my $columnCount=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(); - - # check for multiColumnGrouping - if(${$_}{multiColumnGrouping} and $column =~ m/\\multicolumn\{(\d+)\}/ and $1>1){ - my $multiColSpan = $1; - - # 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; - - # groupingWidth contains the total width of column sizes grouped - # underneath the \multicolumn{} statement - my $groupingWidth = 0; - my $maxGroupingWidth = 0; - foreach (@formattedBody){ - $groupingWidth = 0; - - # 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; - } - } - - # update the maximum grouping width - $maxGroupingWidth = $groupingWidth if($groupingWidth > $maxGroupingWidth); - - # 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); - - # 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; - } - - # 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}); - - # store the maxGroupingWidth for use in the next loop - @{${$_}{maxGroupingWidth}}[$columnCount] = $maxGroupingWidth; - - # update the columnCount to account for the multiColSpan - $columnCount += $multiColSpan - 1; - } - - # increase the column count - $columnCount++; - } - } - } - } + # store the maximum number of ampersands + ${$self}{maximumNumberOfAmpersands} = $maximumNumberOfAmpersands; - # the maximum row width will be used in aligning (or not) the \\ - my $maximumRowWidth = 0; - - # now that the multicolumn widths have been accounted for, loop through the body - foreach(@formattedBody){ - if(${$_}{format} and ${$_}{row} !~ m/^\h*$/){ - - # set a columnCount, which will vary depending on multiColumnGrouping settings or not - my $columnCount=0; - my $tmpRow = q(); - - # 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(); - - # reset the column padding - my $padding = q(); - - # check for multiColumnGrouping - if(${$_}{multiColumnGrouping} and $column =~ m/\\multicolumn\{(\d+)\}/ and $1>1){ - my $multiColSpan = $1; - - # groupingWidth contains the total width of column sizes grouped - # underneath the \multicolumn{} statement - my $maxGroupingWidth = ${${$_}{maxGroupingWidth}}[$columnCount]; - - # 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; - } - } - - # 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; - } - - # calculate the padding - $padding = " " x ( $maxValueToUse >= $columnWidth ? $maxValueToUse - $columnWidth : 0 ); - - # 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(",",@maximumColumnWidth)); - $logger->trace("maximumColumnWidthMC: ",join(",",@maximumColumnWidthMC)); - } - - # 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); - } + # 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; - # 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++; - } + # multi column rearrangement and multicolumn padding + $self->multicolumn_padding if ${$self}{multiColumnGrouping}; - # remove the final & - $tmpRow =~ s/\h*&\h*$/ /; - my $finalSpacing = q(); - $finalSpacing = " " x (${$self}{spacesBeforeDoubleBackSlash}) if ${$self}{spacesBeforeDoubleBackSlash}>=1; - $tmpRow =~ s/\h*$/$finalSpacing/; + # multi column post check to ensure that multicolumn commands have received appropriate padding + $self->multicolumn_post_check if ${$self}{multiColumnGrouping}; - # replace the row with the formatted row - ${$_}{row} = $tmpRow; - - # update the maximum row width - my $gcs = Unicode::GCString->new($tmpRow); - ${$_}{rowWidth} = $gcs->columns(); - $maximumRowWidth = ${$_}{rowWidth} if(${$_}{rowWidth} > $maximumRowWidth); - } + # output to log file + if( $is_t_switch_active ){ + &pretty_print_cell_info($_) for ("entry","type","colSpan","width","measureThis","maximumColumnWidth","individualPadding","groupPadding","delimiter","delimiterLength"); } - # final loop through to get \\ aligned + # 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(${$_}{format} and ${$_}{row} !~ m/^\h*$/){ + if(${$_}{row} !~ m/^\h*$/){ # remove trailing horizontal space if ${$self}{alignDoubleBackSlash} is set to 0 ${$_}{row} =~ s/\h*$// if (!${$self}{alignDoubleBackSlash}); @@ -481,17 +373,22 @@ sub align_at_ampersand{ $padding = " " x (${$self}{spacesBeforeDoubleBackSlash}); } else { # aligned \\ - $padding = " " x ($maximumRowWidth - ${$_}{rowWidth}); + $padding = " " x max(0,(${$self}{maximumRowWidth} - ${$_}{rowWidth})); } } # format the row, and put the trailing \\ and trailing comments back into the row ${$_}{row} .= $padding.(${$_}{endPiece} ? ${$_}{endPiece} :q() ).(${$_}{trailingComment}? ${$_}{trailingComment} : q() ); - } - # to the log file - if($is_tt_switch_active){ - $logger->trace(${$_}{row}) for @formattedBody; + # 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()); + } + } # delete the original body @@ -503,6 +400,882 @@ sub align_at_ampersand{ # 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 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; + + ${$self}{maximumRowWidth} = 0; + + # objective (1): padding + # objective (1): padding + # objective (1): padding + + $logger->trace("*formatted rows for: ${$self}{name}") if($is_t_switch_active); + + my $rowCount = -1; + # row loop + foreach my $row (@cellStorage) { + $rowCount++; + + # clear the temporary row + my $tmpRow = q(); + + # column loop + foreach my $cell (@$row) { + if (${$cell}{type} eq "*" or ${$cell}{type} eq "-"){ + $tmpRow .= ${$cell}{entry}; + next; + } + + # 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}; + } + + # either way, finish with: <spacesBeforeAmpersand> & <spacesAfterAmpersand> + $tmpRow .= " " x ${$self}{spacesBeforeAmpersand}; + $tmpRow .= ${$cell}{delimiter}; + $tmpRow .= " " x ${$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}; + } + + # spacing before \\ + my $finalSpacing = q(); + $finalSpacing = " " x (${$self}{spacesBeforeDoubleBackSlash}) if ${$self}{spacesBeforeDoubleBackSlash}>=1; + $tmpRow =~ s/\h*$/$finalSpacing/; + + # if $tmpRow is made up of only horizontal space, then empty it + $tmpRow = q() if($tmpRow =~ m/^\h*$/); + + # 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; + } + } + } +} + +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; + + # array to store maximum column widths + my @maximumColumnWidths; + + # we count the maximum number of columns + my $maximumNumberOfColumns = 0; + + # 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); + + # row loop + my $rowCount = -1; + foreach my $row (@cellStorage) { + $rowCount++; + + # column loop + my $j = -1; + foreach my $cell (@$row) { + $j++; + + # 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} = "*"; + } + + # check if the cell shouldn't be measured + $self->dont_measure(mode=>"cell",row=>$rowCount,column=>$j) if ${$self}{dontMeasure}; + + # 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} ; + } + + # 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}; + + # otherwise, make the measurement + $maximumColumnWidths[$j] = (defined $maximumColumnWidths[$j] + ? + max($maximumColumnWidths[$j],${$cell}{width}) + : + ${$cell}{width}); + } + + # 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, + }); + } + + # now the gaps have been filled, store the maximumColumnWidth for future reference + ${$row}[$j]{maximumColumnWidth} = (defined $maximumColumnWidths[$j] ? $maximumColumnWidths[$j] : 0); + } + } +} + +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; + + # loop through minMultiColSpan and add empty entries as necessary + foreach(@minMultiColSpan){ + $_ = "." if !(defined $_); + } + + # 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; + } + } + } + + # now loop back through and ensure that each of the \multicolumn commands + # are measured correctly + # + # row loop + $rowCount = -1; + foreach my $row (@cellStorage) { + $rowCount++; + + # 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 + + $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); + } + + ${$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}); + } + } +} + +sub pretty_print_cell_info{ + + my $thingToPrint = (defined $_[0] ? $_[0] : "entry"); + + $logger->trace("*cell information: $thingToPrint"); + + $logger->trace("minimum multi col span: ",join(",",@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); + } + + 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"); + } + } sub double_back_slash_else{ diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm index 7f6694d0493..027597b9ef4 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Document.pm @@ -35,7 +35,7 @@ use LatexIndent::HorizontalWhiteSpace qw/remove_trailing_whitespace remove_leadi 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 diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm index 3029043f23f..addcdaf3f17 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/GetYamlSettings.pm @@ -42,6 +42,10 @@ our @alignAtAmpersandInformation = ( {name=>"lookForAlignDelims",yamlname=>"de {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{ diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm index 75ebe0b2ea2..763ca6e39e6 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/LogFile.pm @@ -103,7 +103,7 @@ ENDQUOTE ${$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 @@ ENDQUOTE $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 diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm index cc11997e36f..c8534681f0a 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Sentence.pm @@ -25,7 +25,6 @@ use LatexIndent::Environment qw/$environmentBasicRegExp/; 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 @@ sub one_sentence_per_line{ # 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/ diff --git a/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm b/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm index b21b3beb8ad..8ec1dc71ba4 100644 --- a/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm +++ b/Master/texmf-dist/scripts/latexindent/LatexIndent/Version.pm @@ -19,6 +19,6 @@ use warnings; 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 diff --git a/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml b/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml index e45d27d1955..2406809d62d 100755 --- a/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml +++ b/Master/texmf-dist/scripts/latexindent/defaultSettings.yaml @@ -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 @@ lookForAlignDelims: alignRowsWithoutMaxDelims: 1 spacesBeforeAmpersand: 1 spacesAfterAmpersand: 1 - justification: "left" + justification: left + alignFinalDoubleBackSlash: 0 + dontMeasure: 0 + delimiterRegEx: '(?<!\\)(&)' + delimiterJustification: left tabularx: delims: 1 longtable: 1 diff --git a/Master/texmf-dist/scripts/latexindent/latexindent.pl b/Master/texmf-dist/scripts/latexindent/latexindent.pl index 91e5f09ae8a..cd07805cbe8 100755 --- a/Master/texmf-dist/scripts/latexindent/latexindent.pl +++ b/Master/texmf-dist/scripts/latexindent/latexindent.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# latexindent.pl, version 3.7.1, 2019-09-07 +# latexindent.pl, version 3.8, 2020-03-21 # # 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 |