3

Suppose that I have a dimension (call it \shape) whose value is to change locally several times throughout a piece of code. Suppose also that I have defined a command (called \shifter in the code that follows) that effects these changes. Then, is it possible to use, at the beginning of the code, the final value that \shape will take on? For example:

\documentclass{article}
\usepackage{showframe}
\usepackage{etoolbox}

\setlength{\parindent}{0pt} % Cancel automatic indentation

\newdimen\shape % Let there be the dimension \shape \setlength{\shape}{0pt} % Let \shape start at 0pt \newdimen\shapecompare % Let there be the dimension \shapecompare

\newcommand{\shifter}[1]{% If \shape is less than the width of the input of \shifter, then make \shape equal to the width of the input. Otherwise, do nothing. \settowidth\shapecompare{#1}% \ifdimless{\shape}{\shapecompare}% {\setlength{\shape}{\shapecompare}}% {}% }%

\begin{document}

% At this moment (namely, the very beginning of the document), I would like to make use of whatever value \shape will end up at by the end of the code (namely, by the end, \shape = the width of the words ``Yes, sir, I will be there.'').

\hspace{\shape}Hello

\shifter{Hello}

\hspace{\shape}Hello

Hello

\shifter{Yes, sir, I will be there.}

\hspace{\shape}Hello

Yes, sir, I will be there.

\end{document}

Note: Stephen's answer (https://tex.stackexchange.com/a/55432/277990) to the question How to retrieve a value which is set later on in the document? seems like it could be relevant to my situation, but when I tried to replace its use of \setvalue and \getvalue into the corresponding terms in my situation, I couldn't get it to work --- and on top of that I'm not sure how the stuff about .aux works.

Noah J
  • 515
  • 1
    you need to write it to the aux and use it on the next run – David Carlisle Aug 24 '23 at 21:08
  • 2
    So, you will need to learn how aux works. Keep in mind that you should code the aux in a way that does not crash the following compile, if you delete the aux file. In other words, do not unconditionally try to read a value that you previously wrote to aux, but first test whether such a value exists. – rallg Aug 25 '23 at 00:18
  • maybe have a look at https://tex.stackexchange.com/questions/355978/how-to-remember-a-length-across-compilations – samcarter_is_at_topanswers.xyz Aug 26 '23 at 19:31

1 Answers1

4

You need to write the setting in the .aux file, which is read in the next LaTeX run. Here you need \global settings, because the .aux file is read in a group.

\documentclass{article}
\usepackage{ifthen}
\usepackage{showframe}

\newdimen\shape \global\shape=0pt \makeatletter \AtEndDocument{\immediate\write@auxout{\global\shape=\the\shape}} \makeatother

\newcommand{\shifter}[1]{% \settowidth{\dimen0}{#1}% \ifdim\shape<\dimen0 \global\shape=\dimen0 \fi }

\setlength{\parindent}{0pt}

\begin{document}

\hspace{\shape}Hello

\shifter{Tyrannosaurus}

\hspace{\shape}Hello

Tyrannosaurus % check the space

\end{document}

First run

enter image description here

Second run

enter image description here

egreg
  • 1,121,712
  • Is there a way to cordon off different parts of a document so that several different final values of \shape can be established locally? (I am designing a template for a certain style of mathematical proof, and I want the rightmost column of a given proof to have its width equal to a local value of \shape.) I tried \begingroup <proof> \endgroup, but I couldn't get that to work --- I presume because \global overwrites the value of \shape everywhere. (I'm sorry I didn't say as much before. I didn't realize that I would need this extra condition to hold.) – Noah J Aug 27 '23 at 14:48
  • 1
    @NoahJ Sorry, but the comment is too generic to be helpful. Please, open a new question with all the details. – egreg Aug 27 '23 at 14:54
  • New question: https://tex.stackexchange.com/q/694481/277990 – Noah J Aug 27 '23 at 18:36
  • \immediate would be safer I think, not sure a \write there is guaranteed to be shipped out – David Carlisle Aug 27 '23 at 20:52
  • @DavidCarlisle I take your word for it. – egreg Aug 27 '23 at 21:00