texlive[65860] Master/texmf-dist: algpseudocodex (17feb23)

commits+karl at tug.org commits+karl at tug.org
Fri Feb 17 22:50:24 CET 2023


Revision: 65860
          http://tug.org/svn/texlive?view=revision&revision=65860
Author:   karl
Date:     2023-02-17 22:50:23 +0100 (Fri, 17 Feb 2023)
Log Message:
-----------
algpseudocodex (17feb23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/algpseudocodex/README.md
    trunk/Master/texmf-dist/doc/latex/algpseudocodex/algpseudocodex.pdf
    trunk/Master/texmf-dist/doc/latex/algpseudocodex/algpseudocodex.tex
    trunk/Master/texmf-dist/tex/latex/algpseudocodex/algpseudocodex.sty

Modified: trunk/Master/texmf-dist/doc/latex/algpseudocodex/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/algpseudocodex/README.md	2023-02-17 21:50:05 UTC (rev 65859)
+++ trunk/Master/texmf-dist/doc/latex/algpseudocodex/README.md	2023-02-17 21:50:23 UTC (rev 65860)
@@ -1,4 +1,11 @@
 # algpseudocodex
+## Overview
 This package allows typesetting pseudocode in LaTeX. It is based on algpseudocode from the algorithmicx package and uses the same syntax, but adds several new features and improvements. Notable features include customizable indent guide lines and the ability to draw boxes around parts of the code for highlighting differences. This package also has better support for long code lines spanning several lines and improved comments.
 
-This material is subject to the LATEX Project Public License 1.3c.
+The package documentation can be found in the file algpseudocodex.tex.
+
+## Author and Contact
+The package is authored and maintained by Christian Matt. For bug reports and other issues please visit the official repository at <https://github.com/chrmatt/algpseudocodex>.
+
+## License
+This material is subject to the LaTeX Project Public License (LPPL), version 1.3c.

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

Modified: trunk/Master/texmf-dist/doc/latex/algpseudocodex/algpseudocodex.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/algpseudocodex/algpseudocodex.tex	2023-02-17 21:50:05 UTC (rev 65859)
+++ trunk/Master/texmf-dist/doc/latex/algpseudocodex/algpseudocodex.tex	2023-02-17 21:50:23 UTC (rev 65860)
@@ -1,19 +1,19 @@
-%% documentation.tex
-%% Copyright 2020-2022 Christian Matt
+%% algpseudocodex.tex
+%% Copyright 2020-2023 Christian Matt
 %
 % This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
+% conditions of the LaTeX Project Public License, either version 1.3c
 % of this license or (at your option) any later version.
 % The latest version of this license is in
 %   http://www.latex-project.org/lppl.txt
-% and version 1.3 or later is part of all distributions of LaTeX
-% version 2005/12/01 or later.
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008-05-04 or later.
 %
 % This work has the LPPL maintenance status `maintained'.
 % 
 % The Current Maintainer of this work is Christian Matt.
 %
-% This work consists of the files algpseudocodex.sty and documentation.tex.
+% This work consists of the files algpseudocodex.sty and algpseudocodex.tex.
 
 \documentclass[11pt,a4paper,USenglish]{article}
 \usepackage[T1]{fontenc}
@@ -29,7 +29,7 @@
 
 \title{\bf{Algpseudocodex Package Documentation}}
 \author{Christian Matt \\ \url{https://github.com/chrmatt/algpseudocodex}}
-\date{\today\\v1.0.2}
+\date{\today\\v1.1.0}
 
 \begin{document}
 
@@ -384,11 +384,18 @@
 \begin{minipage}[t]{0.45\textwidth}
 	\verb|noEnd=false|:
 	\begin{algorithmic}
+		% redefine if commands here to handle noEnd = false
 		\makeatletter
 		\setbool{algpx at noEnd}{false}%
-		\algtext{EndIf}{\algpx at endIndent\algpx at startCodeCommand\algorithmicend\ \algorithmicif%
-			\algpx at startIndent% \EndIf ends another indent. Start fake one here to handle that.
+		\let\If\undefined%
+		\let\EndIf\undefined%
+		\algdef{SE}[IF]{If}{EndIf}[1]{%
+			\algpx at startCodeCommand\algpx at startIndent\algorithmicif\ #1\ \algorithmicthen%
+		}{%
+			\algpx at startEndBlockCommand\algpx at endIndent\algorithmicend\ \algorithmicif%
 		}
+		\pretocmd{\If}{\algpx at endCodeCommand}{}{}%
+		\pretocmd{\EndIf}{\algpx at endCodeCommand[0]}{}{}%
 		\makeatother
 		\If{$x > 0$}
 			\State $x \gets x - 1$
@@ -681,6 +688,11 @@
 
 \section{Revision History}
 
+\subsection*{v1.1.0 (2023-02-17)}
+\begin{itemize}
+	\item Added support for indent guide lines spanning multiple pages.
+\end{itemize}
+
 \subsection*{v1.0.2 (2022-10-07)}
 \begin{itemize}
 	\item Fixed bug with incorrectly ended indent block for nested statements.

Modified: trunk/Master/texmf-dist/tex/latex/algpseudocodex/algpseudocodex.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/algpseudocodex/algpseudocodex.sty	2023-02-17 21:50:05 UTC (rev 65859)
+++ trunk/Master/texmf-dist/tex/latex/algpseudocodex/algpseudocodex.sty	2023-02-17 21:50:23 UTC (rev 65860)
@@ -1,19 +1,19 @@
 %% algpseudocodex.sty
-%% Copyright 2017, 2020-2022 Christian Matt
+%% Copyright 2017, 2020-2023 Christian Matt
 %
 % This work may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
+% conditions of the LaTeX Project Public License, either version 1.3c
 % of this license or (at your option) any later version.
 % The latest version of this license is in
 %   http://www.latex-project.org/lppl.txt
-% and version 1.3 or later is part of all distributions of LaTeX
-% version 2005/12/01 or later.
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008-05-04 or later.
 %
 % This work has the LPPL maintenance status `maintained'.
 % 
 % The Current Maintainer of this work is Christian Matt.
 %
-% This work consists of the files algpseudocodex.sty and documentation.tex.
+% This work consists of the files algpseudocodex.sty and algpseudocodex.tex.
 
 
 % Pseudocodex algorithmic style
@@ -20,7 +20,7 @@
 % Based on Szasz Janos' algpseudocode.sty
 
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{algpseudocodex}[2022-10-07 v1.0.2 pseudocode typesetting]
+\ProvidesPackage{algpseudocodex}[2023-02-17 v1.1.0 pseudocode typesetting]
 \RequirePackage{kvoptions}
 \RequirePackage{algorithmicx}
 \RequirePackage{etoolbox}
@@ -27,6 +27,7 @@
 \RequirePackage{fifo-stack}
 \RequirePackage{varwidth}
 \RequirePackage{tabto}
+\RequirePackage{totcount}
 \RequirePackage{tikz}
 \usetikzlibrary{calc,fit,tikzmark}
 
@@ -77,25 +78,37 @@
 \newlength{\algpx at codeBoxInnerSep}% distance between box and its content
 \newlength{\algpx at codeBoxSep}% distance between nested boxes
 \newlength{\algpx at codeBoxOuterSep}% additional space before and after box
+
+% the following lengths related to indent lines are set when opening an algorithmic environment to reflect to current font size
+\newlength{\algpx at indShiftX}% indent line shifted right by that amount from beginning of line
+\newlength{\algpx at indStartShiftY}% start of indent line shifted up by that amount from beginning of line
+\newlength{\algpx at indEndShiftY}% end of indent line shifted up by that amount from beginning of line (only if noEnd=false, otherwise no shift)
+\newlength{\algpx at indXLineLength}% length of horizonal line drawn at end when noEnd=true
 \newlength{\algpx at minIndDist}% minimum distance between start and end of indent line to draw line
 \newlength{\algpx at oldPos}
 \newlength{\algpx at newPos}
 \newlength{\algpx at tmpLen}% length to be used for various things
-\newlength{\algpx at tmpLenA}% another tmp length
 \newlength{\algpx at indStartY}
 \newlength{\algpx at indEndY}
 \newlength{\algpx at indStartX}% x coordinate of indent line
+\newlength{\algpx at extraShiftX}% current line is shifted by this amount right
+\newlength{\algpx at minTopPageHeight}% minimum for setting height of first line on page (used, e.g., to draw indent lines on page break)
+\newlength{\algpx at minBotPageDepth}% minimum for setting depth of last line on page (used, e.g., to draw indent lines on page break)
 
 \setlength{\algpx at codeBoxInnerSep}{2pt}
 \setlength{\algpx at codeBoxSep}{3pt}
 \setlength{\algpx at codeBoxOuterSep}{1pt}
+\settoheight{\algpx at minTopPageHeight}{\footnotesize9}% account for line numbers, which use \footnotesize
+\settodepth{\algpx at minBotPageDepth}{\footnotesize9}% account for line numbers, which use \footnotesize
 
 \newbool{algpx at firstLine}
-\newbool{algpx at setNorth}
+\newbool{algpx at setNorth}% whether codeBoxNorth should be set
 \newbool{algpx at executeEndVarwidth}
 \newbool{algpx at adjustHeight}
 \newbool{algpx at restorePrevdepth}
+\newbool{algpx at hasCheckedPageBreak}% whether checkPageBreak has been executed in current environment
 \newbool{algpx at indJustEnded}% true after end with noend
+\newbool{algpx at pageJustBroken}%
 
 \newcounter{algpx at codeBoxCount}% number of already created code boxes. Used to fill algpx at startNewCodeBoxQueue
 \newcounter{algpx at nestedCBoxCount}
@@ -104,12 +117,15 @@
 \newcounter{algpx at nestedBoxedStringCount}
 \newcounter{algpx at nestedBoxedStringMaxCount}
 \newcounter{algpx at indentCount}
-\newcounter{algpx at justUsedIndentCount}
+\newcounter{algpx at lastIndentEnded}
+\newcounter{algpx at pageCount}% counter of "pages" (columns in multi column format); incremented when page break is detected
+\newcounter{algpx at tmpCount}% temporary counter
 
 \FSCreate{algpx at startNewCodeBoxQueue}{0}% queue of code boxes to be created on next \State, \If etc. Only stores index of box (0 is value of top if empty; should not be relevant)
 \FSCreate{algpx at codeBoxStack}{0}
 \FSCreate{algpx at codeBoxStackTmp}{0}
 \FSCreate{algpx at indentStack}{0}
+\FSCreate{algpx at indentStackTmp}{0}
 
 \newsavebox{\algpx at boxedStringBox}
 
@@ -132,13 +148,14 @@
 % execute before printing end if etc.
 \newcommand{\algpx at startEndBlockCommand}{%
 	% add space for indentation because of how ALG at nested is computed
-	\algpx at startCodeCommandX{}{\hspace*{\algorithmicindent}}%
+	\algpx at startCodeCommandX[1]{}{\hspace*{\algorithmicindent}}%
 }
 
 % extended version of \algpx at startCodeCommand
-% first argument is printed before content
-% second argument is used to reserve space after contents (for end symbol of long comments)
-\newcommand{\algpx at startCodeCommandX}[2]{%
+% first argument 1 if executed in \algpx at startEndBlockCommand
+% second argument is printed before content
+% third argument is used to reserve space after contents (for end symbol of long comments)
+\newcommand{\algpx at startCodeCommandX}[3][0]{%
 	\setbool{algpx at indJustEnded}{false}%
 	\setcounter{algpx at startedBoxesCount}{0}%
 	\setcounter{algpx at endedBoxesCount}{0}%
@@ -145,19 +162,23 @@
 	\setcounter{algpx at nestedBoxedStringMaxCount}{0}%
 	\whileboolexpr{test{\ifnumcomp{0}{<}{\FSSize{algpx at startNewCodeBoxQueue}}}}{%
 		\FSPush{algpx at codeBoxStack}{\FSTop{algpx at startNewCodeBoxQueue}}%
-		\algpx at drawCodeBox{algpx at codeBoxStyle\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxNorth-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxWest-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxEast-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxSouth-\FSTop{algpx at startNewCodeBoxQueue}}%
+		\algpx at drawCodeBox{algpx at codeBoxStyle-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxNorth-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxWest-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxEast-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxSouth-\FSTop{algpx at startNewCodeBoxQueue}}%
 		\FSPop{algpx at startNewCodeBoxQueue}%
 		\setbool{algpx at setNorth}{true}%
 		\stepcounter{algpx at startedBoxesCount}%
 	}%
 	\algpx at setCodeBoxWest%
+	% check for page break only if indent line is open because page breaks are only used for this
+	\ifboolexpr{test{\ifnumcomp{0}{<}{\FSSize{algpx at indentStack}}}}{%
+		\algpx at checkPageBreak[#1]%
+	}{}%
 	\setbool{algpx at firstLine}{false}%
 	\setbool{algpx at executeEndVarwidth}{true}%
-	#1%
-	% create box from here to end of line, leaving space for #2
-	\settowidth{\algpx at tmpLen}{#1}%
-	\settowidth{\algpx at tmpLenA}{#2}%
-	\begin{varwidth}[t]{\dimexpr \linewidth - \algpx at tmpLen - \algpx at tmpLenA - \algorithmicindent * \numexpr \value{ALG at nested} - 1 \relax \relax}%
+	#2%
+	% create box from here to end of line, leaving space for #3
+	\settowidth{\algpx at extraShiftX}{#2}% remember that line actually starts further right than last box
+	\settowidth{\algpx at tmpLen}{#3}%
+	\begin{varwidth}[t]{\dimexpr \linewidth - \algpx at extraShiftX - \algpx at tmpLen - \algorithmicindent * \numexpr \value{ALG at nested} - 1 \relax \relax}%
 }
 
 % executed before \State, \If etc., i.e., at end of previous line
@@ -176,6 +197,11 @@
 		\setbool{algpx at setNorth}{false}%
 	}{}%
 	\algpx at setCodeBoxEast%
+	% remember position of ending line and possibly set north of page
+	% not necessary if no indent lines are open or just ended (because EndIf with noEnd cannot break page)
+	\ifboolexpr{test{\ifnumcomp{0}{<}{\FSSize{algpx at indentStack}}} and not bool{algpx at indJustEnded}}{%
+		\algpx at setLineEndPos%
+	}{}%
 	\ifbool{algpx at adjustHeight}{%
 		% todo: if highest or deepest element in current line is BoxedString, \ht0 or \dp0 should be adjusted for different sep values
 		\algpx at addBoxSpacing{\value{algpx at startedBoxesCount}}{\the\ht0}{\value{algpx at endedBoxesCount}}{\the\dp0}%
@@ -187,6 +213,66 @@
 	}{}%
 }
 
+% Checks whether current line starts on new page (or column) by comparing y position with previous line.
+% If so, draws indent lines neither starting nor ending on this page.
+% Optional argument is 1 if executed on end block with noEnd=false.
+%
+% Note: We do not rely on \iftikzmarkonpage because, e.g., in double-column format, lines can be on the same page,
+% but we want to consider them to be on different pages.
+\newcommand{\algpx at checkPageBreak}[1][0]{%
+	\ifbool{algpx at hasCheckedPageBreak}{% first line of code cannot be on new page
+		% extract y positions of previous line
+		\tikz[overlay,remember picture]{%
+			\pgfextracty{\algpx at oldPos}{\pgfpointanchor{algpx at currentStartYPos}{center}}%
+			\global\algpx at oldPos=\algpx at oldPos%
+		}%
+		% current pos is 0, so if last pos is less than that, we are on new page
+		\ifdimcomp{\algpx at oldPos}{<}{0ex}{%
+			% set south of previous page to y pos last saved in \algpx at setLineEndPos
+			\tikz[overlay,remember picture]{%
+				\tikzmark{algpx at pageSouth-\thealgpx at pageCount}{(algpx at currentEndYPos)}%
+			}%
+			\stepcounter{algpx at pageCount}%
+			\setbool{algpx at pageJustBroken}{true}%
+			% all currently open indent lines have started on earlier page.
+			% Draw full line from top to bottom for all of those not ending on this page either
+			\algpx at drawIndentLinesOnPageBreak[#1]%
+		}{%
+			\tikz[overlay,remember picture]{}% dummy to keep in sync
+			\tikz[overlay,remember picture]{}% dummy to keep in sync (inside drawIndentLinesOnPageBreak)
+		}%
+	}{}%
+	\@tikzmarkNow{algpx at currentStartYPos}% save y position of current line to compare next time
+	\setbool{algpx at hasCheckedPageBreak}{true}%
+}
+
+% Remember current position as south of page and set north of current page if page was just broken.
+\newcommand{\algpx at setLineEndPos}{%
+	% save y position of current line shifted down the depth of current line to later use for pageSouth coordinate in \algpx at checkPageBreak
+	% shift down at least by \algpx at minBotPageDepth
+	\ifdimcomp{\the\dp0}{<}{\algpx at minBotPageDepth}{%
+		\@tikzmarkNow[yshift=-\algpx at minBotPageDepth]{algpx at currentEndYPos}%
+	}{%
+		\@tikzmarkNow[yshift=-\the\dp0]{algpx at currentEndYPos}%
+	}%
+	% right after pagebreak, set north of current page
+	\ifbool{algpx at pageJustBroken}{%
+		% shift to beginning of line and also shift up by height of current line, but last least \algpx at minTopPageHeight
+		% also shift to left by \wd0 (width of last box, i.e., of line in varwidth) + \algpx at extraShiftX to get x position at beginning of line
+		\tikz[overlay,remember picture]{%
+			\ifdimcomp{\the\ht0}{<}{\algpx at minTopPageHeight}{%
+				\coordinate (algpx at pageNorth) at (-\wd0 - \algpx at extraShiftX,\algpx at minTopPageHeight);%
+			}{%
+				\coordinate (algpx at pageNorth) at (-\wd0 - \algpx at extraShiftX,\the\ht0);%
+			}%
+			\tikzmark{algpx at pageNorth-\thealgpx at pageCount}{(algpx at pageNorth)}%
+		}%
+		\setbool{algpx at pageJustBroken}{false}%
+	}{%
+		\tikz[overlay,remember picture]{}% dummy to keep in sync
+	}%
+}
+
 % set algpx at codeBoxNorthMax of current box and all ancestors; argument is amount to shift up from current baseline
 \newcommand{\algpx at setCodeBoxNorth}[1]{%
 	\setcounter{algpx at nestedCBoxCount}{0}%
@@ -358,7 +444,7 @@
 	%globally set tikz style (https://tex.stackexchange.com/a/47918)
 	\begingroup%
 		\globaldefs=1\relax%
-		\pgfqkeys{/tikz}{algpx at codeBoxStyle\thealgpx at codeBoxCount/.style={#1}}%
+		\pgfqkeys{/tikz}{algpx at codeBoxStyle-\thealgpx at codeBoxCount/.style={#1}}%
 	\endgroup%
 	\stepcounter{algpx at codeBoxCount}%
 	\ignorespaces%
@@ -448,41 +534,48 @@
 % start indented block
 \newcommand{\algpx at startIndent}{%
 	\ifbool{algpx at indLines}{%
-		\@tikzmarkNow{algpx at indentStart-\thealgpx at indentCount}%
+		% Define counter for the page on which this indent line ends.
+		% The use of totcount ensures the last value is preserved during compilations and thus can be used before setting it.
+		% expansion is needed because name contains variable, see
+		% https://tex.stackexchange.com/questions/517559/why-cant-the-name-of-a-totcounter-be-defined-with-a-variable
+		\expanded{\noexpand\newtotcounter{algpx at indentEndPage-\thealgpx at indentCount}}%
+		% set start coordinate here and draw indent line
+		% Note: Draw already here because endIndent could already be called on next page if end is at last line of page.
+		\tikz[overlay,remember picture]{%
+			\coordinate (startPos) at (\algpx at indShiftX,\algpx at indStartShiftY);
+			\algpx at drawIndentLine{\thealgpx at indentCount}{startPos}%
+		}%
 		\FSPush{algpx at indentStack}{\thealgpx at indentCount}%
 		\stepcounter{algpx at indentCount}%
 	}{}%
 }
 
-% end of indented block; optional argument 1 means that only interrupted by else, 2 means ended with until
+% end of indented block
+% optional argument 1 means that only interrupted by else, 2 means ended with until
 \newcommand{\algpx at endIndent}[1][0]{%
 	\ifbool{algpx at indLines}{%
-		\ifboolexpr{bool{algpx at noEnd} and test{\ifstrequal{#1}{0}}}{%
-			\setlength{\algpx at minIndDist}{1ex}% set mininum drawing distance to 1ex if ending without text
-		}{% otherwise, factor in additional line for end, else, or until
-			\setlength{\algpx at minIndDist}{\dimexpr \baselineskip + 1ex \relax}%
-		}%
-		\@tikzmarkNow{algpx at indentEnd-\FSTop{algpx at indentStack}}%
+		% remember on which page indent line ends (remembered through compiliations because we use totcount)
+		\setcounter{algpx at indentEndPage-\FSTop{algpx at indentStack}}{\value{algpx at pageCount}}%
 		\tikz[overlay,remember picture]{%
-			\pgfextractx{\algpx at indStartX}{\pgfpointanchor{algpx at indentStart-\FSTop{algpx at indentStack}}{center}}%
 			\ifboolexpr{bool{algpx at indJustEnded} and test{\ifstrequal{#1}{0}}}{%
-				% use same coordinates as for previous end
-				\pgfextracty{\algpx at indEndY}{\pgfpointanchor{algpx at indentEnd-\thealgpx at justUsedIndentCount}{center}}%
-				\draw[algpxIndentLine] ($(algpx at indentStart-\FSTop{algpx at indentStack})+(0.12em,-0.8ex)$) -- ($(\algpx at indStartX,\algpx at indEndY)+(0.12em,0ex)$) -- +(0.5em,0);%
+				% if another line has just ended, use same coordinates as for previous end
+				% to this end, remember index of previous end to use
+				\expanded{\noexpand\newtotcounter{algpx at indentEndCoordIndex-\FSTop{algpx at indentStack}}}%
+				\setcounter{algpx at indentEndCoordIndex-\FSTop{algpx at indentStack}}{\thealgpx at lastIndentEnded}%
 			}{%
-				% only draw if at least one line between start and end
-				\pgfextracty{\algpx at indStartY}{\pgfpointanchor{algpx at indentStart-\FSTop{algpx at indentStack}}{center}}%
-				\pgfextracty{\algpx at indEndY}{\pgfpointanchor{algpx at indentEnd-\FSTop{algpx at indentStack}}{center}}%
-				\ifdimcomp{\algpx at indStartY-\algpx at minIndDist}{>}{\algpx at indEndY}{%
-					\ifboolexpr{bool{algpx at noEnd} and test{\ifstrequal{#1}{0}}}{%
-						% x of end is at end of line, extract x of start and use that instead
-						\pgfextractx{\algpx at indStartX}{\pgfpointanchor{algpx at indentStart-\FSTop{algpx at indentStack}}{center}}%
-						% draw additional line to right if noend and line is not interrupted
-						\draw[algpxIndentLine] ($(algpx at indentStart-\FSTop{algpx at indentStack})+(0.12em,-0.8ex)$) -- ($(\algpx at indStartX,\algpx at indEndY)+(0.12em,0ex)$) -- +(0.5em,0);%
-					}{%
-						\draw[algpxIndentLine] ($(algpx at indentStart-\FSTop{algpx at indentStack})+(0.12em,-0.8ex)$) -- ($(algpx at indentEnd-\FSTop{algpx at indentStack})+(0.12em,2.0ex)$);%
-					}%
-				}{}%
+				% if not just ended, use current position (0,0) as end
+				\ifboolexpr{bool{algpx at noEnd} and test{\ifstrequal{#1}{0}}}{%
+					% Draw additional line to right if noend and line is not interrupted and move down by current line depth.
+					% Note: we are now at the end of the line, so the x position is too far right.
+					% We solve this in \algpx at drawIndentLine by going at most \algpx at indShiftX to the right.
+					% Adjusting here would require access to the start position and thus an additional compilation.
+					\coordinate (algpx at indentEndCoord) at (\algpx at indShiftX+\algpx at indXLineLength,-\the\dp0);%
+				}{%
+					% if using end or interrupted by else etc., use current position shifted by default values
+					\coordinate (algpx at indentEndCoord) at (\algpx at indShiftX,\algpx at indEndShiftY);%
+				}%
+				% remember end position using \tikzmark so it can be accessed by \algpx at startIndent before
+				\tikzmark{algpx at indentEnd-\FSTop{algpx at indentStack}}{(algpx at indentEndCoord)}%
 			}%
 		}%
 	}{}%
@@ -489,7 +582,9 @@
 	% set indJustEnded even if indLines are not drawn; also used for EndBox
 	\ifboolexpr{not bool{algpx at indJustEnded} and bool{algpx at noEnd} and test{\ifstrequal{#1}{0}}}{%
 		\setbool{algpx at indJustEnded}{true}%
-		\setcounter{algpx at justUsedIndentCount}{\FSTop{algpx at indentStack}}%
+		\ifbool{algpx at indLines}{%
+			\setcounter{algpx at lastIndentEnded}{\FSTop{algpx at indentStack}}%
+		}{}%
 	}{}%
 	\ifbool{algpx at indLines}{%
 		\FSPop{algpx at indentStack}%
@@ -499,7 +594,63 @@
 	}{}%
 }
 
+% Draw indent line with index #1 and start coordinate (#2).
+% To be called inside a TikZ picture.
+\newcommand{\algpx at drawIndentLine}[2]{%
+	\ifnumcomp{\totvalue{algpx at indentEndPage-#1}}{>}{\value{algpx at pageCount}}{%
+		% if indentation does not end on the same page, draw line to end of page with x position of start
+		\coordinate (algpx at indentEndCoord) at (#2 |- {pic cs:algpx at pageSouth-\thealgpx at pageCount});%
+	}{%
+		% otherwise, indentation ends on same page
+		\@ifundefined{c at algpx@indentEndCoordIndex-#1 at totc}{%
+			% if no indentEndCoordIndex is stored, just use stored end position
+			\coordinate (algpx at indentEndCoord) at (pic cs:algpx at indentEnd-#1);%
+		}{%
+			% if indentEndCoordIndex is defined, another line has just ended and we use the same y coordinates as for previous end
+			\coordinate (algpx at indentEndCoord) at (pic cs:algpx at indentEnd-\the\totvalue{algpx at indentEndCoordIndex-#1});%
+		}%
+	}{}%
+	% Only draw if there is minimum distance between start and end
+	\pgfextracty{\algpx at indStartY}{\pgfpointanchor{#2}{center}}%
+	\pgfextracty{\algpx at indEndY}{\pgfpointanchor{algpx at indentEndCoord}{center}}%
+	\ifdimcomp{\algpx at indStartY - \algpx at indEndY}{>}{\algpx at minIndDist}{%
+		% draw in straight lines from start position (#2) to end coordinate, but with x position at most start + \algpx at indXLineLength since end position is set at end of line in \algpx at endIndent
+		\draw[algpxIndentLine] let \p1=(#2), \p2=(algpx at indentEndCoord) in (#2) |- ({min(\x2, \x1 + \algpx at indXLineLength)}, \y2);%
+	}{}%
+}
 
+% For all open indent lines not ending on current page, draw from top to bottom of page
+% Optional argument is 1 if executed on end block with noEnd=false.
+\newcommand{\algpx at drawIndentLinesOnPageBreak}[1][0]{%
+	\tikz[overlay,remember picture]{%
+		% iterate over all open indent lines
+		\ifstrequal{#1}{0}{%
+			\setcounter{algpx at tmpCount}{0}% tmp counter to count interations
+		}{%
+			% if ending block here, the last indentation has already ended and line won't be drawn
+			% start counting at -1 to get correct indentation of later ending lines.
+			\setcounter{algpx at tmpCount}{-1}%
+		}%
+		\whileboolexpr{test{\ifnumcomp{0}{<}{\FSSize{algpx at indentStack}}}}{%
+			\FSPush{algpx at indentStackTmp}{\FSTop{algpx at indentStack}}% copy stack to tmp	
+			\stepcounter{algpx at tmpCount}%
+			% draw line to bottom of page
+			% set beginning of line to north of page (with x set to beginning of line, see \algpx at checkPageBreak)
+			% shifted by the number indentations
+			\coordinate (startPos) at ($(pic cs:algpx at pageNorth-\thealgpx at pageCount) - (\dimexpr \algorithmicindent * \value{algpx at tmpCount} - \algpx at indShiftX \relax, 0ex)$);%
+			\algpx at drawIndentLine{\FSTop{algpx at indentStack}}{startPos}%
+			% finally remove top element
+			\FSPop{algpx at indentStack}%
+		}%
+		% restore stack from tmp
+		\whileboolexpr{test{\ifnumcomp{0}{<}{\FSSize{algpx at indentStackTmp}}}}{%
+			\FSPush{algpx at indentStack}{\FSTop{algpx at indentStackTmp}}%
+			\FSPop{algpx at indentStackTmp}%
+		}%
+	}%
+}
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Keywords
 %
@@ -527,48 +678,48 @@
 % Loops, conditional statements, and functions
 %
 \algdef{SE}[WHILE]{While}{EndWhile}[1]{%
-	\algpx at startIndent\algpx at startCodeCommand\algorithmicwhile\ #1\ \algorithmicdo%
+	\algpx at startCodeCommand\algpx at startIndent\algorithmicwhile\ #1\ \algorithmicdo%
 }{%
-	\algpx at endIndent\algpx at startEndBlockCommand\algorithmicend\ \algorithmicwhile%
+	\algpx at startEndBlockCommand\algpx at endIndent\algorithmicend\ \algorithmicwhile%
 }
 \algdef{SE}[FOR]{For}{EndFor}[1]{%
-	\algpx at startIndent\algpx at startCodeCommand\algorithmicfor\ #1\ \algorithmicdo%
+	\algpx at startCodeCommand\algpx at startIndent\algorithmicfor\ #1\ \algorithmicdo%
 }{%
-	\algpx at endIndent\algpx at startEndBlockCommand\algorithmicend\ \algorithmicfor%
+	\algpx at startEndBlockCommand\algpx at endIndent\algorithmicend\ \algorithmicfor%
 }
 \algdef{S}[FOR]{ForAll}[1]{%
-	\algpx at startIndent\algpx at startCodeCommand\algorithmicforall\ #1\ \algorithmicdo%
+	\algpx at startCodeCommand\algpx at startIndent\algorithmicforall\ #1\ \algorithmicdo%
 }
 \algdef{SE}[LOOP]{Loop}{EndLoop}{%
-	\algpx at startIndent\algpx at startCodeCommand\algorithmicloop%
+	\algpx at startCodeCommand\algpx at startIndent\algorithmicloop%
 }{%
-	\algpx at endIndent\algpx at startEndBlockCommand\algorithmicend\ \algorithmicloop%
+	\algpx at startEndBlockCommand\algpx at endIndent\algorithmicend\ \algorithmicloop%
 }
 \algdef{SE}[REPEAT]{Repeat}{Until}{%
-	\algpx at startIndent\algpx at startCodeCommand\algorithmicrepeat%
+	\algpx at startCodeCommand\algpx at startIndent\algorithmicrepeat%
 }[1]{%
-	\algpx at endIndent[2]\algpx at startEndBlockCommand\algorithmicuntil\ #1%
+	\algpx at startEndBlockCommand\algpx at endIndent[2]\algorithmicuntil\ #1%
 }
 \algdef{SE}[IF]{If}{EndIf}[1]{%
-	\algpx at startIndent\algpx at startCodeCommand\algorithmicif\ #1\ \algorithmicthen%
+	\algpx at startCodeCommand\algpx at startIndent\algorithmicif\ #1\ \algorithmicthen%
 }{%
-	\algpx at endIndent\algpx at startEndBlockCommand\algorithmicend\ \algorithmicif%
+	\algpx at startEndBlockCommand\algpx at endIndent\algorithmicend\ \algorithmicif%
 }
 \algdef{C}[IF]{IF}{ElsIf}[1]{%
-	\algpx at endIndent[1]\algpx at startCodeCommand\algorithmicelse\ \algorithmicif\ #1\ \algorithmicthen%
+	\algpx at startCodeCommand\algpx at endIndent[1]\algorithmicelse\ \algorithmicif\ #1\ \algorithmicthen%
 }
 \algdef{Ce}[ELSE]{IF}{Else}{EndIf}{%
-	\algpx at endIndent[1]\algpx at startCodeCommand\algorithmicelse%
+	\algpx at startCodeCommand\algpx at endIndent[1]\algorithmicelse%
 }
 \algdef{SE}[PROCEDURE]{Procedure}{EndProcedure}[2]{%
-	\algpx at startIndent\algpx at startCodeCommand\algorithmicprocedure\ \textproc{#1}\ifstrempty{#2}{}{(#2)}%
+	\algpx at startCodeCommand\algpx at startIndent\algorithmicprocedure\ \textproc{#1}\ifstrempty{#2}{}{(#2)}%
 }{%
-	\algpx at endIndent\algpx at startEndBlockCommand\algorithmicend\ \algorithmicprocedure%
+	\algpx at startEndBlockCommand\algpx at endIndent\algorithmicend\ \algorithmicprocedure%
 }
 \algdef{SE}[FUNCTION]{Function}{EndFunction}[2]{%
-	\algpx at startIndent\algpx at startCodeCommand\algorithmicfunction\ \textproc{#1}\ifstrempty{#2}{}{(#2)}%
+	\algpx at startCodeCommand\algpx at startIndent\algorithmicfunction\ \textproc{#1}\ifstrempty{#2}{}{(#2)}%
 }{%
-	\algpx at endIndent\algpx at startEndBlockCommand\algorithmicend\ \algorithmicfunction%
+	\algpx at startEndBlockCommand\algpx at endIndent\algorithmicend\ \algorithmicfunction%
 }
 
 \ifbool{algpx at noEnd}{%
@@ -579,13 +730,13 @@
 	\algtext*{EndProcedure}%
 	\algtext*{EndFunction}%
 	%
-	% end indent line after (not before), to get correct y position for multiline text in last command
-	\apptocmd{\EndWhile}{\algpx at endIndent}{}{}%
-	\apptocmd{\EndFor}{\algpx at endIndent}{}{}%
-	\apptocmd{\EndLoop}{\algpx at endIndent}{}{}%
-	\apptocmd{\EndIf}{\algpx at endIndent}{}{}%
-	\apptocmd{\EndProcedure}{\algpx at endIndent}{}{}%
-	\apptocmd{\EndFunction}{\algpx at endIndent}{}{}%
+	% end indent line before end command
+	\pretocmd{\EndWhile}{\algpx at endIndent}{}{}%
+	\pretocmd{\EndFor}{\algpx at endIndent}{}{}%
+	\pretocmd{\EndLoop}{\algpx at endIndent}{}{}%
+	\pretocmd{\EndIf}{\algpx at endIndent}{}{}%
+	\pretocmd{\EndProcedure}{\algpx at endIndent}{}{}%
+	\pretocmd{\EndFunction}{\algpx at endIndent}{}{}%
 }{}%
 
 % execute \algpx at endCodeCommand before \State, \If etc.
@@ -633,7 +784,7 @@
 	\item[%
 		\whileboolexpr{test{\ifnumcomp{0}{<}{\FSSize{algpx at startNewCodeBoxQueue}}}}{%
 			\FSPush{algpx at codeBoxStack}{\FSTop{algpx at startNewCodeBoxQueue}}%
-			\algpx at drawCodeBox{algpx at codeBoxStyle\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxNorth-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxWest-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxEast-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxSouth-\FSTop{algpx at startNewCodeBoxQueue}}%
+			\algpx at drawCodeBox{algpx at codeBoxStyle-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxNorth-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxWest-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxEast-\FSTop{algpx at startNewCodeBoxQueue}}{algpx at codeBoxSouth-\FSTop{algpx at startNewCodeBoxQueue}}%
 			\FSPop{algpx at startNewCodeBoxQueue}%
 			\stepcounter{algpx at startedBoxesCount}%
 		}%
@@ -728,8 +879,17 @@
 	\setbool{algpx at executeEndVarwidth}{false}%
 	\setbool{algpx at adjustHeight}{false}%
 	\setbool{algpx at restorePrevdepth}{false}%
+	\setbool{algpx at hasCheckedPageBreak}{false}%
+	\setbool{algpx at pageJustBroken}{false}%
 	\setcounter{algpx at startedBoxesCount}{0}%
 	\setcounter{algpx at endedBoxesCount}{0}%
+	%
+	% Set lengths here to use correct font sizes
+	\setlength{\algpx at indShiftX}{0.12em}%
+	\setlength{\algpx at indStartShiftY}{-0.8ex}%
+	\setlength{\algpx at indEndShiftY}{2.0ex}%
+	\setlength{\algpx at indXLineLength}{0.5em}%
+	\setlength{\algpx at minIndDist}{0.7ex}%
 }
 
 \AtEndEnvironment{algorithmic}{%



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