\ProvidesPackage
  {lualineno} [2026-02-12 v0.1
  Line numbering in LuaTeX]

\directlua{require('lualineno')}
\AddToHook{build/page/reset}{\lualineno{unset}}

\AddToHook{package/multicol/after}{%
  \directlua{
      local replace = "\csstring\\\csstring\\directlua {
        local right_box = token.create('mult@rightbox').index
        local col_attr = luatexbase.attributes['lualineno_col']
        local i = right_box
        local last = tex.count['doublecol@number'] - 2
        local column = 0
        while i < last do
            i = i + 2
            column = column + 1
            tex.box[i][col_attr] = column
        end
        tex.box[right_box][col_attr] = column + 1}\csstring\\\csstring\\mc@align@columns"
      local find = "\csstring\\\csstring\\mc@align@columns"
      local patch, success = token.get_macro("page@sofar"):gsub(find, replace)
      if success > 0 then
          token.set_macro("page@sofar", patch)
      else
          texio.write_nl('log', "lualineno: failed to patch 
               \csstring\\\csstring\\page@sofar (multicol)")
      end}}
  
\AddToHook{package/balance/after}{%
  \expandafter\renewcommand\expandafter
  \@BAlancecol\expandafter{\@BAlancecol\directlua{
      local sec_col = token.create('@outputbox').index
      local first_col = token.create('@leftcolumn').index
      local col_attr = luatexbase.attributes['lualineno_col']
      tex.box[sec_col][col_attr] = 2
      tex.box[first_col][col_attr] = 1}}}
        
\AddToHook{package/flushend/after}{%
    \directlua{
      local replace = "\csstring\\\csstring\\set@outputbox@with@footnote@and@float 
        \csstring\\\csstring\\fi \csstring\\\csstring\\directlua {
          local sec_col = token.create('@outputbox').index
          local first_col = token.create('@leftcolumn').index
          local col_attr = luatexbase.attributes['lualineno_col']
          tex.box[sec_col][col_attr] = 2
          tex.box[first_col][col_attr] = 1}"
      local find = "\csstring\\\csstring\\set@outputbox@with@footnote@and@float 
        \csstring\\\csstring\\fi "
      local patch, success = token.get_macro("last@outputdblcol"):gsub(find, replace)
      if success > 0 then
          token.set_macro("last@outputdblcol", patch)
      else
          texio.write_nl('log', "lualineno: failed to patch 
            \csstring\\\csstring\\last@outputdblcol (flushend)")
      end}}

\AddToHook{package/ltxgrid/after}{%
\def\box@column#1{%
 \ltxgrid@info@sw{\class@info{\string\box@column\string#1}}{}%
 \raise\topskip
 \hb@xt@\columnwidth\bgroup
  \dimen@\ht#1\@ifdim{\dimen@>\@colht}{\dimen@\@colht}{}%
  \count@\vbadness\vbadness\@M
  \dimen@ii\vfuzz\vfuzz\maxdimen
  \ltxgrid@info@sw{\saythe\@colht\saythe\dimen@}{}%
  \vtop attr \directlua{tex.print(luatexbase.attributes['lualineno_col'])} 
        = \pagegrid@cur to\dimen@\bgroup
   \hrule\@height\z@
   \unvbox#1%
   \raggedcolumn@skip
  \egroup
  \vfuzz\dimen@ii
  \vbadness\count@
  \hss
 \egroup
}}

\AddToHook{package/breqn/after}{%
    \directlua{
      local replace = "\csstring\\\csstring\\directlua {
        local box = tex.getbox('EQ@numbox')
        if box then
          local n = node.copy_list(box)
          n.subtype = 7
          node.write(n)
        end}"
      local find = "\csstring\\\csstring\\copy \csstring\\\csstring\\EQ@numbox "
      local function patch_breqn(macro)
        local patch, success = token.get_macro(macro):gsub(find, replace)
        if success > 0 then
            token.set_macro(macro, patch)
        else
            texio.write_nl('log', "lualineno: failed to patch 
              \csstring\\\csstring\\" .. macro .. " (breqn)")
        end
      end
      patch_breqn("eq@typeset@RShifted")
      patch_breqn("eq@typeset@LShifted")
      patch_breqn("eq@typeset@rightnumber")
      patch_breqn("eq@typeset@leftnumber")
      }}


\endinput
