4

I have a code that runs through and automated process in order to produce a latex layout.

In this process I need to recognize in which flowframe a specific point of text is. For example I need to know if the end of the second paragraph is on the flowframe 1 or 2.

To achieve this I'm using the command \thethis frame which returns the value contained in the counter \c@thisframe that should correspond to the current frame.

This works fine until the line i'm querying is the first line of a flowframe. In this case the ID returned is from the previous frame.

Here is a simple example of the issue

\documentclass[a4paper]{article}
\usepackage{flowfram}

\twocolumn

\begin{document}
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa \textbf{The current frame id is: \thethisframe} aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa \textbf{And now the frame id is: \thethisframe}

aaa \textbf{Here the frame id is: \thethisframe}

\end{document}

Which produces the following result.

Code sample result

Is there a way that I can always identify the correct frame of any specific position? Or how can I fix the code so this error doesn't happen?

2
  • The problem's caused by TeX's asynchronous output routine. It's the same issue as trying to do \thepage in a paragraph that spans a page break. Jan 16, 2017 at 14:34
  • Is there any workaround to this?
    – Fernando
    Jan 16, 2017 at 14:49

1 Answer 1

2

The problem is caused by TeX's asynchronous output routine. The count register isn't updated until the paragraph break occurs. The same problem occurs with the page count as illustrated here:

\documentclass[a4paper]{article}

\usepackage{geometry}
\usepackage{lipsum}

\begin{document}
\lipsum[1-6]

\lipsum*[7] Page: \thepage.

\end{document}

The standard way of getting around this is to use \label / \pageref like this:

\documentclass[a4paper]{article}

\usepackage{geometry}
\usepackage{lipsum}

\begin{document}
\lipsum[1-6]

\lipsum*[7] Page: \label{here}\pageref{here}.

\end{document}

Unfortunately this only works for counters that are incremented using \refstepcounter. The count register \c@thisframe isn't increment but is instead set to the next available frame that's valid for the given page. However, flowfram provides a command to label the current frame:

\newcommand*{\labelflowidn}[1]{%
  {%
    \def\@currentlabel{\thethisframe}%
    \label{#1}%
  }%
}

Unfortunately, unlike \c@page, \c@thisframe doesn't stabilise until after the \protected@write to the .aux file occurs.

One way to get around this is to patch \@setcol like this:

\makeatletter
\let\@org@setcol\@setcol

\def\dodeferredstuff{}

\renewcommand{\@setcol}[1]{\@org@setcol{#1}\dodeferredstuff}

\newcommand{\deferredlabelflowidn}[1]{%
  \def\dodeferredstuff{\labelflowidn{#1}\let\dodeferredstuff\relax}%
}
\makeatother

And use \deferredlabelflowidx instead. Adjusted MWE:

\documentclass[a4paper]{article}

\usepackage{flowfram}

\makeatletter
\let\@org@setcol\@setcol

\def\dodeferredstuff{}

\renewcommand{\@setcol}[1]{\@org@setcol{#1}\dodeferredstuff}

\newcommand{\deferredlabelflowidn}[1]{%
  \def\dodeferredstuff{\labelflowidn{#1}\let\dodeferredstuff\relax}%
}
\makeatother

\twocolumn

\begin{document}
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa \textbf{The current frame id is:
\thethisframe} aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa \textbf{And
now the frame id is: \thethisframe} Label/ref: 
\labelflowidn{here}\ref{here}.
Deferred: \deferredlabelflowidn{defhere}\ref{defhere}.

aaa \textbf{Here the frame id is: \thethisframe}


\end{document}

Label/ref: 1. Deferred: 2.

Unfortunately, this only works when used in the last paragraph of the frame. A better approach is to do the deferred command at the start of the next paragraph using \everypar:

\def\dodeferredstuff{}

\newcommand{\deferredlabelflowidn}[1]{%
  \def\dodeferredstuff{\labelflowidn{#1}\let\dodeferredstuff\relax}%
}

\everypar{\dodeferredstuff}

To guard against section commands that reset \everypar:

\def\dodeferredstuff{}

\newcommand{\deferredlabelflowidn}[1]{%
  \def\dodeferredstuff{\labelflowidn{#1}\let\dodeferredstuff\relax}%
  \everypar{\dodeferredstuff}%
}

Here's the amended MWE:

\documentclass[a4paper]{article}

\usepackage{flowfram}

\def\dodeferredstuff{}

\newcommand{\deferredlabelflowidn}[1]{%
  \def\dodeferredstuff{\labelflowidn{#1}\let\dodeferredstuff\relax}%
  \everypar{\dodeferredstuff}%
}

\twocolumn

\begin{document}
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
Deferred: \deferredlabelflowidn{sample}\ref{sample}.

aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa 
aaa aaa aaa aaa aaa aaa aaa aaa \textbf{The current frame id is:
\thethisframe} aaa aaa aaa aaa aaa aaa aaa aaa aaa aaa \textbf{And
now the frame id is: \thethisframe} Label/ref: 
\labelflowidn{here}\ref{here}.
Deferred: \deferredlabelflowidn{defhere}\ref{defhere}.

aaa \textbf{Here the frame id is: \thethisframe}


\end{document}

image of result

3
  • The only issue with the last solution is that it won't work if the line that we want to reference is the last line of the document. In that case the reference will not be defined.
    – Fernando
    Jan 16, 2017 at 17:19
  • As this is an automated process I might as well use your \@setcol solution concurrently with the \everypar solution. Do you see any problems with that approach?
    – Fernando
    Jan 16, 2017 at 17:27
  • @Fernando I'm not sure if there'll be a conflict. It's occurred to me that it might be better to append to \dodeferredstuff and reset \dodeferredstuff after it's used (rather than including the reset in the command definition). It could have a problem with a new instance of \deferredlabelflowidn overriding a previous one before it's been processed. Jan 16, 2017 at 17:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .