latex3 / latex2e

The LaTeX2e kernel
https://www.latex-project.org/
LaTeX Project Public License v1.3c
1.94k stars 267 forks source link

Hooks: Double`\alignmark`s like doubling hashes? #1137

Open muzimuzhi opened 1 year ago

muzimuzhi commented 1 year ago

Brief outline of the enhancement

LaTeX2e generally cannot add new features without an extreme amount of care to accommodate backwards compatibility. Please do not be offended if your request is closed for being infeasible.

LuaTeX primitive \alignmark "duplicates the functionality of # inside alignment preambles". And like #, its number is halved when used in replacement text of some macro.

Currently hook management only doubles hashes (#s) in hook code, through \__hook_double_hashes:n. It would be better if \alighmarks can be doubled too, when running in LuaTeX.

See a real use case of adding \alignmark to generic hook in https://github.com/phst/lualatex-math/issues/26.

Minimal example showing the current behaviour

% !TeX program = lualatex
\RequirePackage{latexbug}
\documentclass{article}

% or any generic hooks
\AddToHook{package/a/before}
  {\halign{a#&b#\cr 1&2\cr 1&2\cr}} % works

\AddToHook{package/b/before}
  {\halign{a\alignmark&b\alignmark\cr 1&2\cr 1&2\cr}} % errors
% ! Illegal parameter number in definition of \__hook_toplevel package/b/before.

\AddToHook{package/c/before}
  {\halign{a\alignmark\alignmark&b\alignmark\alignmark\cr 1&2\cr 1&2\cr}} % works

\NewHook{test}
\AddToHook{test}
  {\halign{a\alignmark&b\alignmark\cr 1&2\cr 1&2\cr}} % works, but I don't know why

\begin{document}
\UseHook{test}
\end{document}

Adding the same code \halign{a\alignmark&b\alignmark\cr 1&2\cr 1&2\cr} to a non-generic hook works, and I don't know why.

PhelypeOleinik commented 1 year ago

It wouldn't be too hard to add this at the macro level, but it would be rather costly regarding build times. I'm wondering if it's worth pursuing a primitive to replace \__hook_double_hashes:n: it would naturally deal with this case too...

muzimuzhi commented 1 year ago

The following patch to \__hook_double_hashes_output:N for LuaTeX seems to pass the current test suites for hooks (by running l3build check -q -c config-lthooks,config-lthooks2, after adding luatex as checkengins variable in both config-lthooks.lua and config-lthooks2.lua), except that github-1078.lvt used \tex_resettimer:D and \tex_elapsedtime:D that are undefined in LuaTeX.

\sys_if_engine_luatex:T
  {
    \cs_gset:Npn \__hook_double_hashes_output:N #1
      {
        \if_meaning:w \q__hook_recursion_tail #1
          \__hook_double_hashes_stop:w
        \fi:
        \if:w ?
          \if_meaning:w \c__hook_hash_tl #1 ! \fi:
          \if_meaning:w \c__hook_hashes_tl #1 ! \fi:
              ?
        \else:
          \use_i:nnnn
        \fi:
        \use:n
          {
            \if_catcode:w ## \exp_not:N #1
              \exp_after:wN \use_ii:nnnn
            % <<< added
            \else:
              \if_meaning:w \tex_alignmark:D \tex_alignmark:D #1
                \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nnnn
              \fi:
            % >>>
            \fi:
            \use_none:n
              { \exp_not:n { #1 #1 } }
          }
        \exp_not:N #1
        \__hook_double_hashes:w
      }
  }
github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity.

josephwright commented 5 months ago

@muzimuzhi Fancy making a PR?

github-actions[bot] commented 3 months ago

This issue has been automatically marked as stale because it has not had recent activity.