5

I want to test (not to print) if the actual line is the x line of a page.

With the help of the lineno package I able to know if the actual line is the x line of the document, testing what number is \thelinenumber. Also I can print the line of the page in margin or even in line itself with \thePagewiseLineNumber but unlike \thelinenumber, the control sequence \thePagewiseLineNumber cannot be used to test if the line number of page is greater, less or equal than x because seem that is not really a counter, so some like \ifnum\thePagewiseLineNumber > 1 A \else B \fi produce a "Missing number" error.

Let me explain better with this MWE:

\documentclass[a4paper,12pt]{article}
\usepackage{xcolor,lipsum}
\usepackage[pagewise]{lineno}
\pagewiselinenumbers
\renewcommand\linenumberfont{\color{gray!50}}

\def\testinglinenumber{\noindent
Line \thePagewiseLineNumber\ 
(\thelinenumber\ in global count) --- 
% \ifnum\thePagewiseLineNumber>1   % Do not work (Missing number error)
\ifnum\thelinenumber>0 
  I am NOT in first line \else 
  I am in first line \fi\par}

\begin{document}

\testinglinenumber  % OK  because is still in first page 
\testinglinenumber  % OK because is still in first page
{\color{gray!50} \lipsum[1-4] More text \par More text \par } % only dummy text 

% the page break goes here
\testinglinenumber  % Wrong test, but I cannot test 
                    % \ifnum\thePagewiseLineNumber > 1 ....

\testinglinenumber  % Result of test OK but purely coincidental     
\end{document}

I've been diving in the code of lineno.sty to try to fish the right pagewise line counter (or make it) but it was deep water to me.

Some ideas with or without lineno?

3

Yeah it's a little tricky to get this right. The command \thePageWiseNumber is an unexpandable command, which is why saying \ifnum\thePageWiseNumber fails. Usually the way to get output from unexpandable commands is that they store their output in a macro. Looking at the code for \thePageWiseNumber, it just calls a command called \getpagewiselinenumber on the current line number:

\def\thePagewiseLineNumber{\protect\getpagewiselinenumber{\the\c@linenumber}}

The macro \getpagewiselinenumber starts a group, stores its argument (a "document-wise" line number) into \c@linenumber, then calls the misleadingly named macro \testNumberedPage, which calculates the page-wise line number and stores the result back into \c@linenumber. Then it prints out the value of \c@linenumber and ends the group to restore the original value of \c@linenumber.

\def\getpagewiselinenumber#1{{% extra brace makes assignments local
    \c@linenumber #1\relax % store argument (a document-wise line number) in \c@linenumber
    \testNumberedPage % calculate page-wise line number, store result in \c@linenumber
    \thelinenumber % print \c@linenumber
}} % end the group to restore \c@linenumber

In my opinion, this is crappy code. Why is \c@linenumber used for storing 1) the actual current line number 2) the input value and 3) the output value? If you fail to restore \c@linenumber at the end, it corrupts the .aux file and tex hangs the next time you run it. Also, as you discovered, this design makes it impossible for the user of the package to do anything with the calculated value other than directly print it. It should store the output value into some well-named output macro and then let the user do what they want with it.

Anyways, now that we understand how the package works, it's easy enough to write our own function to test the current page.

% #1 -- a macro to store the pagewise line number into 
\def\storepagewiselineno#1{%
   \bgroup % This group is to keep the value of \c@linenumber local
   \testNumberedPage % store the page-wise line number into \c@linenumber
   \xdef#1{\the\c@linenumber}% globally store the page-wise line number in #1
   \egroup % restore the value of \c@linenumber
}

As an alternative, if you like to avoid making global definitions, you can use the following version, which uses a standard trick to "smuggle" the value of \c@linenumber out of the scope with a chain of \expandafters. (pgf defines a macro called \pgfmathsmuggle that lets you say \pgfmathsmuggle\somemacro\endgroup and does this automatically).

\def\storepagewiselineno#1{%
   \bgroup 
   \testNumberedPage 
   \expandafter\egroup % smuggle \c@linenumber out of the group with an \expandafter chain
   \expandafter\edef\expandafter#1\expandafter{\the\c@linenumber}% 
}

Here's the full code:

\documentclass[a4paper,12pt]{article}
\usepackage{xcolor,lipsum}
\usepackage[pagewise]{lineno}
\pagewiselinenumbers
\renewcommand\linenumberfont{\color{gray!50}}
\makeatletter
\def\storepagewiselineno#1{%
    \bgroup % This group is to keep the value of \c@linenumber local
    \testNumberedPage % store the page-wise line number into \c@linenumber
    \expandafter\egroup % smuggle \c@linenumber out of the scope
    \expandafter\edef\expandafter#1\expandafter{\the\c@linenumber}%
}
\makeatother


\def\testinglinenumber{\noindent
    Line \thePagewiseLineNumber\ (\thelinenumber\ in global count) ---
    \storepagewiselineno\temp
    \ifnum\temp>1\relax I am NOT in first line\else I am in first line\fi\par
}

\begin{document}
\testinglinenumber  
\testinglinenumber  
{\color{gray!50} \lipsum[1-4] More text \par More text \par }

\newpage

\testinglinenumber  
\testinglinenumber 
\end{document} 
| improve this answer | |
  • Nice answer. I half-understood the problem and played with \testNumberedPage and \c@linenumber (and all others` \c@...` counters) without hit the key. BTW, why you show two different versions of \storepagewiselineno? There are some reason to change it in the MWE or it is simply a matter of taste? – Fran Feb 1 '18 at 2:52
  • @Fran Oh sorry that was a mistake. I'll add an explanation for the second version. – Hood Chatham Feb 1 '18 at 2:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.