stevecheckoway / everyhook

The everyhook package provides hooks to TeX's everyX set of token parameters.
0 stars 0 forks source link

LaTeX / everyhook-package/undesired halving of the amount of hashes and other problems #1

Open Ulrich-Diez opened 5 years ago

Ulrich-Diez commented 5 years ago

Dear Mr Checkoway,

some months ago at the TeX-LaTeX StackExchange forum a question was asked under the title "Macro only to be defined in math mode", https://tex.stackexchange.com/questions/477280/macro-only-to-be-defined-in-math-mode.

The questioner intended to use the everyhook-package for redefining macros that process arguments whenever \everymath gets carried out.

The question at the TeX-LaTeX StackExchange Forum caused me to look at the code of the everyhook package.

Seems there are some problems with your package everyhook 2014/11/26 v1.2 (SVN Rev: 12)\ Hooks for low level TeX everyX primitives.

Problem 1:

Quote from the documentation (everyhook.pdf):

17 \def\eh@definehook#1#2{%
18         \cslet{eh@every#1}#2%
19         \newtoks#2%
20         \cslet{eh@private#1}#2%
21         #2\csuse{eh@every#1}%
22         \csdef{eh@pre#1}{}%
23         \csdef{eh@post#1}{}%

This is slightly tricky to get right. Basically, we want to set the
\everyfoo primitive which we have saved as \eh@everyfoo like
   \eh@everyfoo={\eh@prefoo\the\expandafter\everyfoo\eh@postfoo}.
   The reason for the \expandafter is to make sure it is expanded
before the the token register \everyfoo is expanded. Thus if the
post hook is empty, then code in \everyfoo sees no additional
tokens, in case that is important.
   Unfortunately, some code wants to redefine \everyfoo itself
in order to prevent other code that uses \everyfoo from actually
setting anything. To deal with that, we use the private 
token list
   \eh@everyfoo{\eh@prefoo\the\expandafter\eh@privatefoo\eh@postfoo}

24         \csuse{eh@every#1}\expandafter{\csname eh@pre#1\expandafter\endcsname
25                \expandafter\the\csname eh@private#1\expandafter\endcsname
26                \csname eh@post#1\endcsname}%
27 }

A token \expandafter is promised for ensuring that the macro code>\eh@post<i⟨foo⟩ gets expanded before code>\the\eh@private<i⟨foo⟩.

The problem with the code in lines 24-27 is:

That code does not set the token register code>\eh@every<i⟨foo⟩ to

code>\eh@pre<i⟨foo⟩/i>\the\expandafter\eh@private<i⟨foo⟩/i>\eh@post<i⟨foo⟩

but it does set that register to:

code>\eh@pre<i⟨foo⟩/i>\the\eh@private<i⟨foo⟩/i>\eh@post<i⟨foo⟩

The promised \expandafter behind \the is missing.

You can easily test this with the following MWE:

\documentclass{article}
\usepackage{everyhook}
\makeatletter
\showthe\eh@everypar
\stop

Here \showthe\eh@everypar reveals:

\eh@prepar \the \eh@privatepar \eh@postpar .
l.4     \showthe\eh@everypar

As you can see: The promised \expandafter behind \the is missing.

In order to fulfill the promise/in order to have that \expandafter behind \the, two \expandafter need to be added to line 25:

17 \def\eh@definehook#1#2{%
18         \cslet{eh@every#1}#2%
19         \newtoks#2%
20         \cslet{eh@private#1}#2%
21         #2\csuse{eh@every#1}%
22         \csdef{eh@pre#1}{}%
23         \csdef{eh@post#1}{}%
[...]
24         \csuse{eh@every#1}\expandafter{\csname eh@pre#1\expandafter\endcsname
25                \expandafter\the\expandafter\expandafter\csname eh@private#1\expandafter\endcsname %<--------
26                \csname eh@post#1\endcsname}%
27 }

Additionally to fulfilling the promise I'd probably add yet another two \expandafter to make sure everything is expanded when it comes to carrying out the very first token that comes from code>\eh@pre<i⟨foo⟩:

17 \def\eh@definehook#1#2{%
18         \cslet{eh@every#1}#2%
19         \newtoks#2%
20         \cslet{eh@private#1}#2%
21         #2\csuse{eh@every#1}%
22         \csdef{eh@pre#1}{}%
23         \csdef{eh@post#1}{}%
[...]
24         \csuse{eh@every#1}\expandafter{\expandafter\expandafter\csname eh@pre#1\expandafter\endcsname %<--------
25                \expandafter\the\expandafter\expandafter\csname eh@private#1\expandafter\endcsname %<--------
26                \csname eh@post#1\endcsname}%
27 }

This way code>\eh@pre<i⟨foo⟩ gets expanded when code>\the\eh@private<i⟨foo⟩ is already expanded while code>\the\eh@private<i⟨foo⟩ gets expanded when code>\eh@post<i⟨foo⟩ is already expanded.

So this will set the token register code>\eh@every<i⟨foo⟩ to

code>\expandafter\eh@pre<i⟨foo⟩/i>\the\expandafter\eh@private<i⟨foo⟩/i>\eh@post<i⟨foo⟩

Problem 2:

Seems a pair of empty braces is not in the right place with \eh@checkhooknotempty:

Definition of \eh@checkhooknotempty as found in everyhook.sty v1.2, dated 2014/11/26:

41 \def\eh@checkhooknotempty#1#2#3{%
42         \eh@checkhook{#2}#3%
43         \ifcsempty{eh@#1#2}{\PackageError{everyhook}{The #1 hook for
44         \protect\every#2\space is empty}{I have seen too many
45         \protect#3{#2}s.}{}}%
46 }

\PackageError takes three arguments. In \eh@checkhooknotempty four arguments are passed to it. The last one of them is empty.
\ifcsempty takes three arguments. In \eh@checkhooknotempty only two arguments are passed to it.
Thus \ifcsempty's third argument will be taken from the token-stream/input-stream.
In case of the hook not being empty this may probably not matter as in this case the tokens which form that argument will be returned to the token-stream. "probably" because a pair of matching curly braces surrounding that argument will be removed after returning if previously present. This might make a difference.
In case of the hook being empty the tokens forming that argument will not be returned to the token-stream. The effect of the removal of these tokens is not predictable. In harmless cases this just leads to subsequent error-messages which are confusing.

Let's change the line-wrapping:

\def\eh@checkhooknotempty#1#2#3{%
  \eh@checkhook{#2}#3%
  \ifcsempty{% <- first argument of \ifcsempty
     eh@#1#2%
  }{% <- second argument of \ifcsempty
    \PackageError{% <- first argument of \PackageError
      everyhook%
    }{% <- second argument of \PackageError
       The #1 hook for \protect\every#2\space is empty%
    }{% <- third argument of \PackageError
      I have seen too many \protect#3{#2}s.%
    }{}% <- empty fourth argument of \PackageError ??????????
  }% <- where is the third argument of \ifcsempty???????
}%

I suggest something like:

\def\eh@checkhooknotempty#1#2#3{%
        \eh@checkhook{#2}#3%
        \ifcsempty{eh@#1#2}{\PackageError{everyhook}{The #1 hook for
        \protect\every#2\space is empty}{I have seen too many
        \protect#3{#2}s.}}{}%<- brace pair "moved"
}%

Problem 3:

You can use \PushPreHook / \PopPreHook for adding tokens to / for removing tokens from the definitions of macros code>\eh@pre<i⟨foo⟩ .

You can use \PushPostHook / \PopPostHook for adding tokens to / for removing tokens from the definitions of macros \eh@post⟨foo⟩.

The problem is:

Somebody may add macro-definitions to code>\eh@pre<i⟨foo⟩ / code>\eh@post<i⟨foo⟩.
If this is done, then every subsequent use of
\PushPreHook{⟨foo⟩}... or \PopPreHook{⟨foo⟩}...
respective
\PushPostHook{⟨foo⟩}... or \PopPostHook{⟨foo⟩}...
will reduce the amount of hashes / the parameter-characters # that belong to these definitions.

You can easily test with the following MWE:

\documentclass{article}
\usepackage{everyhook}
\makeatletter
\PushPreHook{par}{D\def\dummy################1{This is the argument ################1}}
\show\eh@prepar
\PushPreHook{par}{C}
\show\eh@prepar
\PushPreHook{par}{B}
\show\eh@prepar
\PushPreHook{par}{A}
\show\eh@prepar
\stop

I'd expect this to yield in the end:

> \eh@prepar=macro:
->A\eh@hookseparator B\eh@hookseparator C\eh@hookseparator D\def \dummy #######
#########################1{This is the argument ###############################
#1}\eh@hookseparator .

The hashes within \eh@prepar's definition should be doubled because at the time of expanding \eh@prepar, the amount of hashes will be reduced/halved.

Instead \show reveals that the amount of hashes gets halved with each use of \PushPreHook:

?
> \eh@prepar=macro:
->D\def \dummy ########1{This is the argument ########1}\eh@hookseparator .
l.5     \show\eh@prepar

?
> \eh@prepar=macro:
->C\eh@hookseparator D\def \dummy ####1{This is the argument ####1}\eh@hooksepa
rator .
l.7     \show\eh@prepar

?
> \eh@prepar=macro:
->B\eh@hookseparator C\eh@hookseparator D\def \dummy ##1{This is the argument #
#1}\eh@hookseparator .
l.9     \show\eh@prepar

?
! Illegal parameter number in definition of \eh@prepar.
<to be read again> 
                   1
l.11     \PushPreHook{par}{A}

?
! Illegal parameter number in definition of \eh@prepar.
<to be read again> 
                   1
l.11     \PushPreHook{par}{A}

?
> \eh@prepar=macro:
->A\eh@hookseparator B\eh@hookseparator C\eh@hookseparator D\def \dummy ##1{Thi
s is the argument ##1}\eh@hookseparator .
l.11     \show\eh@prepar

In the end you get error-messages because hashes are reduced so much that remaining hashes are taken for a means of denoting arguments of \eh@prepar which were not declared in \eh@prepar's parameter text.

The same situation with \PopPreHook, \PushPostHook and \PopPostHook.

In order to resolve this issue, it is helpful to keep in mind:

  1. Macro-definitions can have ⟨parameter text⟩ and must have ⟨balanced text⟩.
    ( ⟨definition⟩⟨def⟩⟨control sequence⟩⟨definition text⟩
    ⟨def⟩ → \def | \gdef | \edef | \xdef ⟨definition text⟩⟨parameter text⟩⟨left brace⟩⟨balanced text⟩⟨right brace⟩ )
  2. When placing hashes/parameter-characters into a⟨balanced text⟩ that belongs to the ⟨definition text⟩ of the ⟨definition⟩ of a macro, two consecutive hashes of that ⟨balanced text⟩ will be collapsed into one single hash at the time of having expanded the macro in question.
    (That's why you can use ##1 / ##2 etc for the parameters with macro-definitions nested inside the ⟨balanced text⟩ of macro-definitions.)
    In short: Macro expansion will reduce/halve the amount of consecutive hashes that come from the macro's definition's ⟨balanced text⟩.
  3. When during macro expansion (La)TeX gathers an argument for a macro whereby that argument itself contains hashes, (La)TeX leaves the amount of these hashes untouched.
  4. When (La)TeX encounters hashes while gathering the tokens of a ⟨balanced text⟩ that belongs to ⟨general text⟩, e.g., the ⟨balanced text⟩ of an assignment to a token-register, it will leave the amount of hashes contained in that ⟨balanced text⟩ untouched: \the⟨token register⟩ under normal circumstances will yield the same amount of hashes as were contained in that ⟨balanced text⟩.
    ( ⟨variable assignment⟩ → ... | ⟨token variable⟩⟨equals⟩⟨general text⟩
    ⟨token variable⟩⟨token parameter⟩ | ⟨toksdef token⟩ | \toks⟨8-bit number⟩
    ⟨general text⟩⟨filler⟩{⟨balanced text⟩⟨right brace⟩ )
  5. There are special circumstances when hashes will be doubled:

    • When writing a hash-token to screen or to external file, two hashes will be written:
      \message{This is my message: #} yields on the screen: This is my message: ##.
      Be aware that with \show and \message{\meaning\...} you don't get this hash-doubling. The reason is: At the time of writing to screen \show and \message actually don't deal with hash-tokens of category-code 6 (parameter) but with the "stringified" variants thereof, i.e., with hash-tokens of category code 12(other).
      The ε-TeX primitive \detokenize is like unexpanded-immediate-writing tokens to an external file (hereby hash-dobling takes place!) and reading back that external file under a category-code-régime where everything but space (which has category code 10(space)) has category code 12(other).
      The ε-TeX primitive \scantokens is like unexpanded-immediate-writing tokens to an external file (hereby hash-dobling takes place!) and reading back that external file under the current category-code-régime.
    • When \the delivers tokens of a ⟨token variable⟩, e.g., of a token-register or of a token-parameter like \everypar or \everyeof during an \edef/\xdef-expansion-context, hashes will be doubled.
      This hash-doubling is done for compensating the circumstance that hashes will be reduced after having expanded the macro in question.
    • When the ε-TeX-primitive \unexpanded delivers its ⟨balanced text⟩ during an \edef/\xdef-expansion-context, hashes will be doubled. This hash-doubling is done for compensating the circumstance that hashes will be reduced after having expanded the macro in question.
      1. \romannumeral0-expansion is a powerful tool for reducing the amount of \expandafter needed for triggering desired expansion-steps:

    \romannumeral triggers expansion until (La)TeX finds a number. In the not so interesting case of the number found being positive, (La)TeX will deliver its representation in lowercase roman numerals. In the more interesting case of the number found being not positive, (La)TeX will silently not deliver any token at all but swallow the tokens that form the number.

    Therefore \romannumeral can be (ab?)used for triggering a lot of expansion-work as long as in the end the first tokens from the expansion-result form a non-positive number.

    In order to get the sequence \relax6 5 4 3 2 1 0 from macros

    \def\top{\first0 }
    \def\first{\second1 }
    \def\second{\third2 }
    \def\third{\fourth3 }
    \def\fourth{\fifth4 }
    \def\fifth{\sixth5 }
    \def\sixth{6 }

    you could place (27-1) = 127\expandafter-tokens in front of the sequence \relax\top.

    If you change the definition of \sixth to \def\sixth{ 6 }, you can do:

    \expandafter\relax\romannumeral0\top

    You get:

    %\expandafter-expansion in progress
    \relax\romannumeral0\top

    %\expandafter-expansion in progress
    \relax
    %\romannumeral-expansion in progress
    0\top

    %\expandafter-expansion in progress
    \relax
    %\romannumeral-expansion in progress
    0\first0 

    %\expandafter-expansion in progress
    \relax
    %\romannumeral-expansion in progress
    0\second1 0 

    %\expandafter-expansion in progress
    \relax
    %\romannumeral-expansion in progress
    0\third2 1 0 

    %\expandafter-expansion in progress
    \relax
    %\romannumeral-expansion in progress
    0\fourth3 2 1 0 

    %\expandafter-expansion in progress
    \relax
    %\romannumeral-expansion in progress
    0\fifth4 3 2 1 0 

    %\expandafter-expansion in progress
    \relax
    %\romannumeral-expansion in progress
    0\sixth5 4 3 2 1 0 

    %\expandafter-expansion in progress
    \relax
    %\romannumeral-expansion in progress
    0 6 5 4 3 2 1 0 

    → now digit 0 trailed by a space which terminates the digit-sequence that is to be converted is found during searching the number that is to be converted due to \romannumeral.
    The terminating space is discarded. 0 is not a positive number. The tokens that form that number get swallowed silently while no tokens will be delivered:

    %\expandafter-expansion in progress
    \relax
    %\romannumeral-expansion done
    6 5 4 3 2 1 0 

    → as \romannumeral-expansion is done, \expandafter-expansion is done also:

    %\expandafter-expansion done
    \relax
    %\romannumeral-expansion done
    6 5 4 3 2 1 0

    \romannumeral0-expansion is very useful in combination with exchanging macro-arguments.

Armed with this knowledge, let's look at the definitions of the macros \PushPreHook, \PopPreHook, \PushPostHook and \PopPostHook:

Definition of \PushPreHook as found in everyhook.sty v1.2, dated 2014/11/26:

47 \newrobustcmd\PushPreHook[2]{%
48         \eh@checkhook{#1}\PushPreHook
49         \def\eh@tempi{#2}%
50         \letcs\eh@tempii{eh@pre#1}%
51         \expandafter\gdef\csname eh@pre#1\expandafter\expandafter
52                 \expandafter\endcsname\expandafter\expandafter
53                 \expandafter{\expandafter\eh@tempi\expandafter
54                              \eh@hookseparator\eh@tempii}%
55         \undef\eh@tempi
56         \undef\eh@tempii
57 }

I suggest something like this:

[...]
%%======================================================================
% Helper-macros for \PushPreHook, \PopPreHook, \PushPostHook and \PopPostHook:
%%======================================================================
\newcommand\eh@exchange[2]{#2#1}%
% As everyhook requires etoolbox you are urged to run with eTeX-extensions 
% being available.
%%----------------------------------------------------------------------
%% Check whether argument is empty:
%%......................................................................
%% \eh@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%% A variant requiring e-TeX extensions:
\newcommand\eh@CheckWhetherNull[1]{%
  \romannumeral0\if\relax\detokenize{#1}\relax
  \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {\@firstoftwo{\expandafter}{} \@firstoftwo}%
  {\@firstoftwo{\expandafter}{} \@secondoftwo}%
}%
%%
%% A variant not requiring e-TeX extensions:
%% ( The gist of this macro comes from Robert R. Schneck's 
%%   \ifempty-macro:
%%    <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%% )
%\newcommand\eh@CheckWhetherNull[1]{%
%  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
%  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
%  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
%  \@secondoftwo\string}\@firstoftwo\expandafter{} %
%  \@secondoftwo}{\@firstoftwo\expandafter{} \@firstoftwo}%
%}%
%%-----------------------------------------------------------------------------
%% Check whether argument contains no token \eh@hookseparator which is not
%% nested in braces:
%%.............................................................................
%% \eh@CheckWhetherNoEh@hookseparator{<Argument which is to be checked>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains no exclamation mark>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains exclamation mark>}%
%%
\@ifdefinable\eh@GobbleToEh@hookseparator{%
  \long\def\eh@GobbleToEh@hookseparator#1\eh@hookseparator{}%
}%
\newcommand\eh@CheckWhetherNoEh@hookseparator[1]{%
  \expandafter\eh@CheckWhetherNull
  \expandafter{\eh@GobbleToEh@hookseparator#1\eh@hookseparator}%
}%
%%----------------------------------------------------------------------
%% Use tokens as definition-text of macro without losing
%% # (hashes) during macro-expansion:
%%......................................................................
%% \eh@csxdefunexpanded{<tokens>}%
%%                     {<name of macro that is to expand to <tokens>; 
%%                       hashes doubled so that they can losslessly be reduced
%%                       during expansion of the macro>}
% With e-TeX-extensions:
\newcommand\eh@csxdefunexpanded[2]{%
  \csxdef{#2}{\unexpanded{#1}}%
}%
% Without e-TeX-extensions:
%\newtoks\eh@scratchtoks\global\eh@scratchtoks{}%
%\newcommand\eh@csxdefunexpanded[2]{%
%  \eh@scratchtoks{#1}%
%  \csxdef{#2}{\the\eh@scratchtoks}%
%  \eh@scratchtoks{}%
%}%
%%----------------------------------------------------------------------
% Checking the availability of e-TeX-extensions could be implemented as follows:
%%......................................................................
%\begingroup
%\edef\eh@tempi{\string\eTeXversion}%
%\edef\eh@tempii{\meaning\eTeXversion}%
%\expandafter\endgroup
%\ifx\eh@tempi\eh@tempii
%  % e-TeX extensions are available
%\else
%  % e-TeX extensions are not available
%\fi
[...]
%%======================================================================
%% \PushPreHook
%%======================================================================
\newrobustcmd\PushPreHook[2]{%
        \eh@checkhook{#1}\PushPreHook
        \expandafter\eh@csxdefunexpanded\expandafter{%
          \romannumeral0%
          \expandafter\expandafter
          \expandafter            \eh@exchange
          \expandafter\expandafter
          \expandafter            {%
          \csname eh@pre#1\endcsname}{ #2\eh@hookseparator}%
        }{eh@pre#1}%
}%

Definition of \PopPreHook as found in everyhook.sty v1.2, dated 2014/11/26:

58 \newrobustcmd\PopPreHook[1]{%
59         \eh@checkhooknotempty{pre}{#1}\PopPreHook
60         \expandafter\eh@popprehook\csname eh@pre#1\expandafter
61                 \expandafter\expandafter\endcsname
62                 \csname eh@pre#1\endcsname\eh@hookend
63 }
64 \def\eh@popprehook#1#2\eh@hookseparator#3\eh@hookend{\gdef#1{#3}}

Besides the hash-reduction-problem \eh@popprehook might—in case of the list of \eh@hookseparator-separated elements stored in code>\eh@pre<i⟨foo⟩ having only two elements—remove surrounding braces from the second/remaining element.

I suggest something like this which does not have the hash-reduction problem and which does without returning whatsoever delimited arguments so that brace removal with delimited arguments does does not matter:

\newrobustcmd\PopPreHook[1]{%
        \eh@checkhooknotempty{pre}{#1}\PopPreHook
        \ifcsdef{eh@pre#1}{%
          \expandafter\expandafter\expandafter\eh@CheckWhetherNoEh@hookseparator
           \expandafter\expandafter\expandafter{\csname eh@pre#1\endcsname}{}{%
            \expandafter\eh@csxdefunexpanded\expandafter{%
                \romannumeral0%
                \expandafter\expandafter\expandafter\eh@popprehook
                \csname eh@pre#1\endcsname
            }{eh@pre#1}%
          }%
        }{}%
}%
\@ifdefinable\eh@popprehook{%
  \long\def\eh@popprehook#1\eh@hookseparator{ }%<-this spece will terminate \romannumeral0-expansion.
}%

Definition of \PushPostHook as found in everyhook.sty v1.2, dated 2014/11/26:

65 \newrobustcmd\PushPostHook[2]{%
66         \eh@checkhook{#1}\PushPostHook
67         \letcs\eh@tempi{eh@post#1}%
68         \expandafter\gdef\csname eh@post#1\expandafter\endcsname
69                 \expandafter{\eh@tempi\eh@hookseparator#2}%
70         \undef\eh@tempi
71 }

I suggest something like this:

\newrobustcmd\PushPostHook[2]{%
        \eh@checkhook{#1}\PushPostHook
        \expandafter\expandafter\expandafter\eh@csxdefunexpanded
        \expandafter\expandafter\expandafter{%
           \csname eh@post#1\endcsname\eh@hookseparator#2%
        }{eh@post#1}%
}%

Definition of \PopPostHook as found in everyhook.sty v1.2, dated 2014/11/26:

72 \newrobustcmd\PopPostHook[1]{%
73         \eh@checkhooknotempty{post}{#1}\PopPostHook
74         \letcs\eh@tempi{eh@post#1}%
75         \expandafter\eh@popposthook\csname eh@post#1\expandafter
76                 \endcsname\expandafter{\expandafter}\eh@tempi
77                 \eh@hookend\eh@hookseparator\eh@sentinel\eh@hookend
78         \undef\eh@tempi
79 }
80 \def\eh@popposthook#1#2\eh@hookseparator#3\eh@hookseparator#4\eh@hookend{%
81         \def\eh@tempi{#4}%
82         \ifdefequal\eh@sentinel\eh@tempi%
83                 {\gdef#1{#2}\undef\eh@tempi}%
84              {\eh@popposthook#1{#2\eh@hookseparator#3}\eh@hookseparator#4\eh@hookend}%
85 }
86 \def\eh@sentinel{\eh@sentinel}

Besides the hash-reduction-problem the \eh@popposthook-loop might remove surrounding braces with all elements of the list of \eh@hookseparator-separated elements stored in code>\eh@post<i⟨name of hook⟩.

I suggest something like this:

\newrobustcmd\PopPostHook[1]{%
        \eh@checkhooknotempty{post}{#1}\PopPostHook
        \ifcsdef{eh@post#1}{%
          \expandafter\expandafter\expandafter\eh@CheckWhetherNoEh@hookseparator
          \expandafter\expandafter\expandafter{\csname eh@post#1\endcsname}{}{%
            \expandafter\eh@csxdefunexpanded\expandafter{%
                \romannumeral0%
                \expandafter\expandafter\expandafter\eh@PopPostHookLoop
                \expandafter\expandafter\expandafter{%
                \expandafter\expandafter\expandafter}%
                \expandafter\expandafter\expandafter{\csname eh@post#1\endcsname}%
            }{eh@post#1}%
          }%
        }{}%
}%
%%======================================================================
% Helper-macros for \PopPostHook:
%%======================================================================
%% Extract first item from list of arguments separated by \eh@hookseparator
%%
%% \romannumeral0%
%% \eh@ExtractFirstEh@hookseparatorArgLoop
%% {.<list of arguments separated by \eh@hookseparator>\eh@hookseparator\eh@SelDOm}%
%%
%% yields:
%% 
%% <first item of list of arguments separated by \eh@hookseparatorArg>
%%..............................................................................
\@ifdefinable\eh@GobbleDot{\def\eh@GobbleDot.{}}%
\@ifdefinable\eh@RemoveEh@hookseparator{\long\def\eh@RemoveEh@hookseparator#1\eh@hookseparator{#1}}%
\@ifdefinable\eh@RemoveFromEh@hookseparatorTillEh@SelDOm{%
  \long\def\eh@RemoveFromEh@hookseparatorTillEh@SelDOm#1\eh@hookseparator#2\eh@SelDOm{#1\eh@hookseparator}%
}%
\newcommand\eh@ExtractFirstEh@hookseparatorArgLoop[1]{%
  \expandafter\eh@CheckWhetherNull\expandafter{\eh@GobbleToEh@hookseparator#1}%
  {%
    \eh@exchange{ }{\expandafter\expandafter\expandafter}% 
    \expandafter\eh@GobbleDot\eh@RemoveEh@hookseparator#1%
  }%
  {%
    \expandafter\eh@ExtractFirstEh@hookseparatorArgLoop
    \expandafter{\eh@RemoveFromEh@hookseparatorTillEh@SelDOm#1}%
  }%
}%
%%------------------------------------------------------------------------------
%% Extract all items but the last item from list of arguments separated by
%% \eh@hookseparator
%%
%% \romannumeral0%
%% \eh@PopPostHookLoop{}%
%%                    {<list of arguments separated by \eh@hookseparator>}%
%%
%% yields:
%%
%% <list of arguments separated by \eh@hookseparatorArg with last element removed>.
%% 
%% The list must have at least one element. This must be checked by the macro 
%% which calls the loop.
%%..............................................................................
\newcommand\eh@PopPostHookLoop[2]{%
  %#1 = <collected list items>
  %#2 = <remaining list items>
  \expandafter\eh@CheckWhetherNoEh@hookseparator\expandafter{\eh@GobbleToEh@hookseparator#2}{%
    \expandafter\eh@exchange
    \expandafter{%
       \romannumeral0\eh@ExtractFirstEh@hookseparatorArgLoop{.#2\eh@hookseparator\eh@SelDOm}%
    }{ #1}%
  }{%
    \expandafter\eh@exchange\expandafter{\expandafter{\eh@GobbleToEh@hookseparator#2}}{%
      \expandafter\expandafter\expandafter\eh@PopPostHookLoop
      \expandafter\expandafter\expandafter{%
        \expandafter\eh@exchange
        \expandafter{%
          \romannumeral0\eh@ExtractFirstEh@hookseparatorArgLoop{.#2\eh@hookseparator\eh@SelDOm}%
        }{#1}\eh@hookseparator
      }%
    }%
  }%
}%
%%------------------------------------------------------------------------------

Problem 4:

With the package everyhook you are urged to run things under ε-TeX.

In section 5.1 "Mode-Independent Commands" of the ε-TeX manual, Version 2, February 1998 by The NTS Team — Peter Breitenlohner, Max-Planck-Institut füur Physik, München, on page 17 you find a paragraph about the additional possibilities for ⟨token parameter⟩.

This paragraph mentions another token-parameter \everyeof:

The additional possibilities for ⟨token parameter⟩ are:
\everyeof (tokens to insert when an \input file ends)

\everyeof is executed at the end of every \input file.
\everyeof is also executed at the end of every pseudo-file generated and input by \scantokens.
\everyeof is not executed at the end of pseudo-files generated and input by \detokenize.

You can nicely use \everyeof, e.g., for passing \noexpand to the end of a (pseudo) file for neutralizing within \edef/\xdef-contexts the end-of-file-pseudo-token which usually gets attached by (La)TeX and which, if not neutralized, triggers an error-message in case it is encountered while scanning/gathering the text of a ⟨definition⟩:

\long\def\exchange#1#2{#2#1}%
\long\def\definetest#1#2{%
  \expandafter\exchange\expandafter{%
    \expandafter\everyeof\expandafter{\the\everyeof}%
  }{%
    #2%
    \everyeof{\noexpand}%
    \edef\test{\scantokens{#1}}%
  }%
}%
\begingroup
\catcode`\%=12\relax
A\definetest{text text%}{\endgroup}%B
C

\show\test
\csname stop\endcsname
\bye

Perhaps everyhook's facilities can be made available for the \everyeof-token-parameter as well.


I've allowed myself to create a file UDInterimEveryhook.sty based on your everyhook package where all the changes I've suggested are included:

%% This is file `UDInterimEveryhook.sty'.
%%
%% This file is derived from Stephen Checkoway's file everyhook.sty
%% which forms the LaTeX 2e-package
%% everyhook 2014/11/26 v1.2 (SVN Rev: 12)\ Hooks for low level TeX every X primitives.
%% (<https://ctan.org/pkg/everyhook>)
%%
%% Author of this file: Ulrich Diez.
%% Copyright holder of this file: Ulrich Diez.
%% Copyright (C) 2019 Ulrich Diez.
%%
%% This file is neither for distribution nor for publishing.
%% This file is written by Ulrich Diez for Stephen Checkoway, the
%% author of everyhook.dtx.
%%
%% In order to solve some problems with Stephen Checkoway's
%% LaTeX 2e-package everyhook Ulrich Diez suggests some changes
%% to that package.
%%
%% This file is derived from Stephen Checkoway's package everyhook.
%% This file contains the suggested changes.
%%
%% The only purpose of this file is making it more easy for
%% Stephen Checkoway to test the changes suggested by Ulrich Diez.
%%
%% Permission is granted by Ulrich Diez to Stephen Checkoway
%% to use in the context of creating future releases of the
%% everyhook package those portions of code in this file that are
%% written by Ulrich Diez in whatever ways Stephen Checkoway likes to.
%%
%% Although everyhook 2014/11/26 v1.2 (SVN Rev: 12) was published
%% under the LPPL license, this permission is independent from
%% the licensing-models under which Stephen Checkoway intends to
%% publish future releases of the everyhook package.
%%
%% !!!! Usage/handling of this file and usage/handling of code
%% !!!! exhibited in this file is _not_ at the risk of Ulrich Diez.
%% !!!! Usage/handling of this file and usage/handling of code
%% !!!! exhibited in this file is at the risk of those who use/
%% !!!! handle these things and/or is at the risk of those on
%% !!!! whose behalf usage/handling takes place.
%% !!!!
%% !!!! Ulrich Diez does neither give whatsoever warranties nor
%% !!!! give whatsoever quarantees nor take on whatsoever 
%% !!!! liabilites for correctness, completeness, relevance,
%% !!!! accuracy, functuality, quality, anything else
%% !!!! in connection with whatever use or handling of this file
%% !!!! and in connection with whatever use or handling of the
%% !!!! code exhibited in this file. If something breaks, the
%% !!!! user/s usually may herself/himself/themselves cope with
%% !!!! the pieces.
%%
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%////////////////////////////////////////////////////////////////////////////////
% The interim-thingie for testing has another name:
%////////////////////////////////////////////////////////////////////////////////
%% Requires eTeX extensions.
\ProvidesPackage{UDInterimEveryhook}%
                [2019/09/07 v0.01beta Hooks for low level
                 TeX everyX primitives. Interim-work. 
                 Not to be published.]
%////////////////////////////////////////////////////////////////////////////////
\DeclareOption{excludeor}{%
\AtBeginDocument{%
\output\expandafter{%
\expandafter\eh@saveclearallhooks
\the\output
\eh@restoreallhooks
}%
}%
}
\ProcessOptions\relax
\RequirePackage{etoolbox}
\def\eh@definehook#1#2{%
\cslet{eh@every#1}#2%
\newtoks#2%
\cslet{eh@private#1}#2%
#2\csuse{eh@every#1}%
\csdef{eh@pre#1}{}%
\csdef{eh@post#1}{}%
%////////////////////////////////////////////////////////////////////////////////
% Two additional \exandafter added in the line below (-> Problem 1): 
%////////////////////////////////////////////////////////////////////////////////
\csuse{eh@every#1}\expandafter{\expandafter\expandafter\csname eh@pre#1\expandafter\endcsname
%////////////////////////////////////////////////////////////////////////////////
% Two previously missing \exandafter added in the line below (-> Problem 1): 
%////////////////////////////////////////////////////////////////////////////////
\expandafter\the\expandafter\expandafter\csname eh@private#1\expandafter\endcsname 
\csname eh@post#1\endcsname}%
}
\eh@definehook{par}\everypar
\eh@definehook{math}\frozen@everymath
\eh@definehook{display}\frozen@everydisplay
\eh@definehook{hbox}\everyhbox
\eh@definehook{vbox}\everyvbox
\eh@definehook{cr}\everycr
%//////////// Take into consideration the token-parameter \everyeof (<-Problem 4):
\eh@definehook{eof}\everyeof
\undef\eh@definehook
\def\eh@hookseparator{}
\def\eh@checkhook#1#2{%
\ifcsdef{eh@every#1}{}{\PackageError{everyhook}{Argument #1 to
\protect#2\space is invalid}{There is no hook for
\protect\every#1.}}%
}
%////////////////////////////////////////////////////////////////////////////////
%////////////////////////////////////////////////////////////////////////////////
%////////////////////////////////////////////////////////////////////////////////
\def\eh@checkhooknotempty#1#2#3{%
        \eh@checkhook{#2}#3%
        \ifcsempty{eh@#1#2}{\PackageError{everyhook}{The #1 hook for
        \protect\every#2\space is empty}{I have seen too many
        \protect#3{#2}s.}}{}%<-////////// braces moved (-> Problem 2)
}%
%================================================================================
% -> Problem 3
% \PushPreHook, \PopPreHook, \PushPostHook and \PopPostHook:
%================================================================================
% Helper-macros for \PushPreHook, \PopPreHook, \PushPostHook and \PopPostHook:
%--------------------------------------------------------------------------------
% Define a macro from an undelimited macro argument in a way where hashes (#)
% get doubled inside the macro-definition for compensating the circumstance
% that hashes inside the <balanced text> of macro definitions get halved during
% macro expansion
% -- \eh@csxdefunexpanded is called by:\ PushPreHook, \PopPreHook, \PushPostHook
%    and \PopPostHook:
%
%  \eh@csxdefunexpanded{<argument>}{<csname>}
%  -> defines globally a macro whose name is <csname> to expand to the tokens 
%     that form <argument>.
%
%  Syntax with <argument> before <csname> makes applying expansion-and
%  token-exchanging trickery with <argument> for first obtaining the <argument>
%  more easy.
%
\newcommand\eh@csxdefunexpanded[2]{\csxdef{#2}{\unexpanded{#1}}}%
%................................................................................
% Exchange two undelimited macro arguments and with each of these arguments
% remove the outermost  pair of matching surrounding curly braces if present
% -- \eh@exchange is called by: \PushPreHook and \PopPostHook:
%
\newcommand\eh@exchange[2]{#2#1}%
%................................................................................
% Check whether undelimited macro argument contains the token \eh@hookseparator
% -- \eh@CheckWhetherNoEh@hookseparator is called by: \PopPreHook and \PopPostHook:
%
%  \eh@CheckWhetherNoEh@hookseparator{<argument>}%
%                                    {<tokens to be delivered in case <argument>
%                                      does not contain a token \eh@hookseparator
%                                      which is not nested in braces.>}%
%                                     {<tokens to be delivered in case <argument>
%                                       does contain a token \eh@hookseparator
%                                       which is not nested in braces.>}%
%
\newcommand\eh@CheckWhetherNoEh@hookseparator[1]{%
  \expandafter\eh@CheckWhetherNull
  \expandafter{\eh@GobbleToEh@hookseparator#1\eh@hookseparator}%
}%
\@ifdefinable\eh@GobbleToEh@hookseparator{%
  \long\def\eh@GobbleToEh@hookseparator#1\eh@hookseparator{}%
}%
% Check whether <argument> is empty:
%  \eh@CheckWhetherNull{<argument>}%
%                      {<tokens to be delivered in case "emptiness"
%                        was gathered as <argument>}%
%                      {<tokens to be delivered in case at least
%                        one token was gathered as <argument>}%
\newcommand\eh@CheckWhetherNull[1]{%
  \romannumeral0\if\relax\detokenize{#1}\relax
  \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {\@firstoftwo{\expandafter}{} \@firstoftwo}%
  {\@firstoftwo{\expandafter}{} \@secondoftwo}%
}%
%--------------------------------------------------------------------------------
% \PushPreHook:
%--------------------------------------------------------------------------------
\newrobustcmd\PushPreHook[2]{%
\eh@checkhook{#1}\PushPreHook
\expandafter\eh@csxdefunexpanded\expandafter{%
  \romannumeral0%
  \expandafter\expandafter
  \expandafter            \eh@exchange
  \expandafter\expandafter
  \expandafter            {%
  \csname eh@pre#1\endcsname}{ #2\eh@hookseparator}%
}{eh@pre#1}%
}%
%--------------------------------------------------------------------------------
% \PushPostHook:
%--------------------------------------------------------------------------------
\newrobustcmd\PushPostHook[2]{%
\eh@checkhook{#1}\PushPostHook
\expandafter\expandafter\expandafter\eh@csxdefunexpanded
\expandafter\expandafter\expandafter{%
   \csname eh@post#1\endcsname\eh@hookseparator#2%
}{eh@post#1}%
}%
%--------------------------------------------------------------------------------
%% \PopPreHook
%--------------------------------------------------------------------------------
\newrobustcmd\PopPreHook[1]{%
\eh@checkhooknotempty{pre}{#1}\PopPreHook
\ifcsdef{eh@pre#1}{%
  \expandafter\expandafter\expandafter\eh@CheckWhetherNoEh@hookseparator
  \expandafter\expandafter\expandafter{\csname eh@pre#1\endcsname}{}{%
        \expandafter\eh@csxdefunexpanded
        \expandafter{%
        \romannumeral0%
        \expandafter\expandafter\expandafter\eh@popprehook
        \csname eh@pre#1\endcsname
        }{eh@pre#1}%
  }%
}{}%
}%
%................................................................................
% Helper-macros only for \PopPreHook:
%................................................................................
% \eh@popprehook<\eh@hookseparator-separated list>
%   removes the the first \eh@hookseparator-separated item and the first
%   \eh@hookseparator behind that item from the 
%   <\eh@hookseparato-separated list> and delivers a space-token for
%  terminating \romannumeral0-expansion; <\eh@hookseparator-separated list>
%  must contain a token \eh@hookseparator:
%
\@ifdefinable\eh@popprehook{\long\def\eh@popprehook#1\eh@hookseparator{ }}%
%--------------------------------------------------------------------------------
% \PopPostHook
%--------------------------------------------------------------------------------
\newrobustcmd\PopPostHook[1]{%
\eh@checkhooknotempty{post}{#1}\PopPostHook
\ifcsdef{eh@post#1}{%
  \expandafter\expandafter\expandafter\eh@CheckWhetherNoEh@hookseparator
  \expandafter\expandafter\expandafter{\csname eh@post#1\endcsname}{}{%
        \expandafter\eh@csxdefunexpanded\expandafter{%
        \romannumeral0%
        \expandafter\expandafter\expandafter\eh@PopPostHookLoop
        \expandafter\expandafter\expandafter{%
        \expandafter\expandafter\expandafter}%
        \expandafter\expandafter\expandafter{\csname eh@post#1\endcsname}%
        }{eh@post#1}%
  }%
}{}%
}%
%................................................................................
% Helper-macros only for \PopPostHook:
%................................................................................
%  Extract first item from list of arguments separated by \eh@hookseparator:
%
%  \romannumeral0%
%  \eh@ExtractFirstEh@hookseparatorArgLoop%
%  {.<list of arguments separated by \eh@hookseparator>\eh@hookseparator\eh@SelDOm}%
%
%  yields:
% 
%  <first item of list of arguments separated by \eh@hookseparatorArg>
%................................................................................
\@ifdefinable\eh@GobbleDot{\def\eh@GobbleDot.{}}%
\@ifdefinable\eh@RemoveEh@hookseparator{%
  \long\def\eh@RemoveEh@hookseparator#1\eh@hookseparator{#1}%
}%
\@ifdefinable\eh@RemoveFromEh@hookseparatorTillEh@SelDOm{%
  \long\def\eh@RemoveFromEh@hookseparatorTillEh@SelDOm%
                   #1\eh@hookseparator#2\eh@SelDOm{#1\eh@hookseparator}%
}%
\newcommand\eh@ExtractFirstEh@hookseparatorArgLoop[1]{%
  \expandafter\eh@CheckWhetherNull\expandafter{\eh@GobbleToEh@hookseparator#1}{%
    \eh@exchange{ }{\expandafter\expandafter\expandafter}% 
    \expandafter\eh@GobbleDot\eh@RemoveEh@hookseparator#1%
  }{%
    \expandafter\eh@ExtractFirstEh@hookseparatorArgLoop
    \expandafter{\eh@RemoveFromEh@hookseparatorTillEh@SelDOm#1}%
  }%
}%
%................................................................................
%  Extract all items but the last item from list of arguments separated by
%  \eh@hookseparator:
%
%  \romannumeral0%
%  \eh@PopPostHookLoop{}%
%                     {<list of arguments separated by \eh@hookseparator>}%
%
%  yields:
%
%  <list of arguments separated by \eh@hookseparatorArg with last element removed>.
% 
%  The list must have at least one element. This must be checked by the macro 
%  which calls the loop.
%................................................................................
\newcommand\eh@PopPostHookLoop[2]{%
  %#1 = <collected list items>
  %#2 = <remaining list items>
  \expandafter\eh@CheckWhetherNoEh@hookseparator
  \expandafter{%
  \eh@GobbleToEh@hookseparator#2}{%
    \expandafter\eh@exchange
    \expandafter{%
      \romannumeral0%
      \eh@ExtractFirstEh@hookseparatorArgLoop{.#2\eh@hookseparator\eh@SelDOm}%
    }{ #1}%
  }{%
    \expandafter\eh@exchange
    \expandafter{%
    \expandafter{%
    \eh@GobbleToEh@hookseparator#2}}{%
      \expandafter\expandafter\expandafter\eh@PopPostHookLoop
      \expandafter\expandafter\expandafter{%
        \expandafter\eh@exchange
        \expandafter{%
          \romannumeral0%
          \eh@ExtractFirstEh@hookseparatorArgLoop{.#2\eh@hookseparator\eh@SelDOm}%
        }{#1}\eh@hookseparator
      }%
    }%
  }%
}%
%--------------------------------------------------------------------------------
%  Remarks:
%
%  \PushPreHook, \PopPreHook, \PushPostHook and \PopPostHook and the underlying
%  macro mechanisms work without defining temporary macros.
%  
%  The only token not allowed in the second arguent of \PushPreHook, \PopPreHook,
%  \PushPostHook and \PopPostHook is the token \eh@hookseparator.
%
%  The internal tail recursive loop \eh@ExtractFirstEh@hookseparatorArgLoop
%  makes use of the token \eh@SelDOm in order to reduce the amount of
%  iterations needed for extracting the first item that is delimited by
%  \eh@hookseparator. Nonetheless you may use the token \eh@SelDOm.
%  If you do so the only effect will be: In case such an \eh@SelDOm is not in the very
%  first item of the \eh@hookseparator-list, the loop will need more iterations.
%
%////////////////////////////////////////////////////////////////////////////////
%////////////////////////////////////////////////////////////////////////////////
%////////////////////////////////////////////////////////////////////////////////
\def\eh@clearhook#1{%
\global\csdef{eh@#1}{}%
}
\newrobustcmd\ClearPreHook[1]{%
\eh@checkhook{#1}\ClearPreHook
\eh@clearhook{pre#1}%
}
\newrobustcmd\ClearPostHook[1]{%
\eh@checkhook{#1}\ClearPostHook
\eh@clearhook{post#1}%
}
\def\eh@savehook#1#2{%
\letcs#2{eh@#1}%
}
\def\eh@restorehook#1#2{%
\global\cslet{eh@#1}#2%
}
\newrobustcmd\SavePreHook[2]{%
\eh@checkhook{#1}\SavePreHook
\eh@savehook{pre#1}#2%
}
\newrobustcmd\SavePostHook[2]{%
\eh@checkhook{#1}\SavePostHook
\eh@savehook{post#1}#2%
}
\newrobustcmd\RestorePreHook[2]{%
\eh@checkhook{#1}\RestorePreHook
\eh@restorehook{pre#1}#2%
}
\newrobustcmd\RestorePostHook[2]{%
\eh@checkhook{#1}\RestorePostHook
\eh@restorehook{post#1}#2%
}
\def\eh@saveclearallhooks{%
\global\eh@savehook{prepar}\eh@or@prepar
\global\eh@savehook{postpar}\eh@or@postpar
\global\eh@savehook{premath}\eh@or@premath
\global\eh@savehook{postmath}\eh@or@postmath
\global\eh@savehook{predisplay}\eh@or@predisplay
\global\eh@savehook{postdisplay}\eh@or@postdisplay
\global\eh@savehook{prehbox}\eh@or@prehbox
\global\eh@savehook{posthbox}\eh@or@posthbox
\global\eh@savehook{prevbox}\eh@or@prevbox
\global\eh@savehook{postvbox}\eh@or@postvbox
\global\eh@savehook{precr}\eh@or@precr
\global\eh@savehook{postcr}\eh@or@postcr
%//////////// Take into consideration the token-parameter \everyeof (<-Problem 4):
\global\eh@savehook{preeof}\eh@or@preeof
\global\eh@savehook{posteof}\eh@or@posteof
%///////////////
\eh@clearhook{prepar}%
\eh@clearhook{postpar}%
\eh@clearhook{premath}%
\eh@clearhook{postmath}%
\eh@clearhook{predisplay}%
\eh@clearhook{postdisplay}%
\eh@clearhook{prehbox}%
\eh@clearhook{posthbox}%
\eh@clearhook{prevbox}%
\eh@clearhook{postvbox}%
\eh@clearhook{precr}%
\eh@clearhook{postcr}%
%//////////// Take into consideration the token-parameter \everyeof (<-Problem 4):
\eh@clearhook{preeof}%
\eh@clearhook{posteof}%
%///////////////
}
\def\eh@restoreallhooks{%
\eh@restorehook{prepar}\eh@or@prepar
\eh@restorehook{postpar}\eh@or@postpar
\eh@restorehook{premath}\eh@or@premath
\eh@restorehook{postmath}\eh@or@postmath
\eh@restorehook{predisplay}\eh@or@predisplay
\eh@restorehook{postdisplay}\eh@or@postdisplay
\eh@restorehook{prehbox}\eh@or@prehbox
\eh@restorehook{posthbox}\eh@or@posthbox
\eh@restorehook{prevbox}\eh@or@prevbox
\eh@restorehook{postvbox}\eh@or@postvbox
\eh@restorehook{precr}\eh@or@precr
\eh@restorehook{postcr}\eh@or@postcr
%//////////// Take into consideration the token-parameter \everyeof (<-Problem 4):
\eh@restorehook{preeof}\eh@or@preeof
\eh@restorehook{posteof}\eh@or@posteof
%///////////////    
}
\endinput
%%
%% End of file `UDInterimEveryhook.sty'.

This way you can easily test by "commenting out" \usepackage...-statements for alternately loading either everyhook.sty or UDInterimEveryhook.sty in order to see the difference in behavior between the two package variants.

I also have made a small test file:

%% Author of this file: Ulrich Diez.
%% Copyright holder of this file: Ulrich Diez.
%% Copyright (C) 2019 Ulrich Diez.
%% 
%% This file is written by Ulrich Diez for Stephen Checkoway, the
%% author of everyhook.dtx.
%%
%% In order to solve some problems with Stephen Checkoway's
%% LaTeX 2e-package everyhook Ulrich Diez suggests some changes
%% to that package.
%%
%% The only purpose of this file is making it more easy for
%% Stephen Checkoway to test the changes suggested by Ulrich Diez.
%%
%% Permission is granted by Ulrich Diez to Stephen Checkoway
%% to use in the context of creating future releases of the
%% everyhook package those portions of code in this file that are
%% written by Ulrich Diez in whatever ways Stephen Checkoway likes to.
%%
%% Although everyhook 2014/11/26 v1.2 (SVN Rev: 12) was published
%% under the LPPL license, this permission is independent from
%% the licensing-models under which Stephen Checkoway intends to
%% publish future releases of the everyhook package.
%%
%% !!!! Usage/handling of this file and usage/handling of code
%% !!!! exhibited in this file is _not_ at the risk of Ulrich Diez.
%% !!!! Usage/handling of this file and usage/handling of code
%% !!!! exhibited in this file is at the risk of those who use/
%% !!!! handle these things and/or is at the risk of those on
%% !!!! whose behalf usage/handling takes place.
%% !!!!
%% !!!! Ulrich Diez does neither give whatsoever warranties nor
%% !!!! give whatsoever quarantees nor take on whatsoever 
%% !!!! liabilites for correctness, completeness, relevance,
%% !!!! accuracy, functuality, quality, anything else
%% !!!! in connection with whatever use or handling of this file
%% !!!! and in connection with whatever use or handling of the
%% !!!! code exhibited in this file. If something breaks, the
%% !!!! user/s usually may herself/himself/themselves cope with
%% !!!! the pieces.
%%
\documentclass{article}
\usepackage{UDInterimEveryhook}[2019/09/07]
%\usepackage{everyhook}
\newcommand\ThisShallNotBeExpanded{Oh no!}%
\makeatletter
\message{^^JShowing \string\eh@everypar^^J====================^^J}
\showthe\eh@everypar
\message{^^JDoing Pre-Hook-Things^^J=====================^^J%
         ^^JPushing Pre-Hook^^J----------------^^J^^J}
\PushPreHook{par}{D\ThisShallNotBeExpanded\def\dummy################1{This is the argument ################1}}
\show\eh@prepar
\PushPreHook{par}{C\ThisShallNotBeExpanded}
\show\eh@prepar
\PushPreHook{par}{B\ThisShallNotBeExpanded}
\show\eh@prepar
\PushPreHook{par}{A\ThisShallNotBeExpanded}
\show\eh@prepar
\message{^^JPoping Pre-Hook^^J----------------^^J^^J}
\PopPreHook{par}
\show\eh@prepar
\PopPreHook{par}
\show\eh@prepar
\PopPreHook{par}
\show\eh@prepar
\PopPreHook{par}
\show\eh@prepar
\message{The next pop is expected to yield an error-message:^^J(Press return to proceed.)}%
\immediate\read-1to\scratchy
\PopPreHook{par}
\show\eh@prepar
\message{^^JDoing Post-Hook-Things^^J======================^^J%
         ^^JPushing Post-Hook^^J-----------------^^J^^J}
\PushPostHook{par}{A\ThisShallNotBeExpanded\def\dummy################1{This is the argument ################1}}
\show\eh@postpar
\PushPostHook{par}{B\ThisShallNotBeExpanded}
\show\eh@postpar
\PushPostHook{par}{C\ThisShallNotBeExpanded}
\show\eh@postpar
\PushPostHook{par}{D\ThisShallNotBeExpanded}
\show\eh@postpar
\message{^^JPoping Post-Hook^^J-----------------^^J^^J}
\PopPostHook{par}
\show\eh@postpar
\PopPostHook{par}
\show\eh@postpar
\PopPostHook{par}
\show\eh@postpar
\PopPostHook{par}
\show\eh@postpar
\message{The next pop is expected to yield an error-message:^^J(Press return to proceed.)}%
\immediate\read-1to\scratchy
\PopPostHook{par}
\show\eh@postpar
\stop

Sincerely

Ulrich Diez

stevecheckoway commented 5 years ago

Hi Ulrich,

I really appreciate the detailed write up.

I would like to incorporate your suggestions and release a new version. If you feel like making pull requests for each of the issues, that would be very helpful for me. If not, that's okay, I can make the changes myself, but it'll take a little more time. I definitely won't get to this until at least this coming weekend.

Ulrich-Diez commented 5 years ago

Dear Mr Checkoway,

I just added another suggestion to the issue. The suggestion of taking the token-parameter \everyeof into account also.

I don't think any of this is a matter of urgency. ;-)

I'd be glad if I could be of assistance with a pull request.

But there are some problems:

  1. I am not familiar with GitHub. I know a bit of Markdown as Markdown is also used in the TeX-LaTeX StackExchange-Forum. This would be my very first pull-request. For handing it in correctly I'd need to learn more about GitHub. (Not just handling the web-interface. Legal stuff also.) I would definitely not have done that at the coming weekend or at the next weekend. ;-)
  2. You seem to maintain the file everyhook.dtx by means of a private SVN repository. At least this is what I guess from the commands \RequirePackage{svn-prov} and \ProvidesPackageSVN{....
    Doing all changes to the .dtx-file that are necessary for creating a new version of the package would include adjusting both the version-number and the SVN-data that is to be provided to \ProvidesPackageSVN as well.
    I'd be unconfortable with interfering in your ways of maintaining your private SVN-repositories.
  3. I don't know which level of excessiveness in the matter of commenting and explaining the code within the implementation-section of the .dtx-file would be welcome to you. ;-)

    Therefore I added some attempts at explaining things to my first posting in this issue.

    I would like to leave it to you to decide which passages of explanation to take and which ones to improve/to omit.