Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

l3doc: base form conditional \<name>:<arg spec>TF is indexed unconditionally #1216

Open
muzimuzhi opened this issue May 21, 2023 · 2 comments
Labels

Comments

@muzimuzhi
Copy link
Contributor

Not all conditionals have a \<name>:<arg spec>TF base form, but currently the T and F form usages are always indexed as the TF base form.

For example \file_if_exist_input:nF has no T and TF forms, but \file_if_exist_input:nTF, an undefined function is the only form listed in the "Index" chapter of interface3.pdf.

Here's a possible patch that makes \__codedoc_key_get_base:nN aware of \DoNotIndex records (stored in \l__doc_donotindex_seq since doc v3). Then one can use \DoNotIndex{\file_if_exist_input:nTF} to make \file_if_exist_input:nF indexed as itself.

diff --git a/l3kernel/l3doc.dtx b/l3kernel/l3doc.dtx
index 039ee83..39ed45d 100644
--- a/l3kernel/l3doc.dtx
+++ b/l3kernel/l3doc.dtx
@@ -1173,15 +1173,15 @@ and all files in that bundle must be distributed together.
   {
     \str_case:nnTF {#1}
       {
-        { N } { N }
-        { c } { N }
-        { n } { n }
-        { o } { n }
-        { f } { n }
-        { e } { n }
-        { x } { n }
-        { V } { n }
-        { v } { n }
+        { N } { \token_to_str:N N }
+        { c } { \token_to_str:N N }
+        { n } { \token_to_str:N n }
+        { o } { \token_to_str:N n }
+        { f } { \token_to_str:N n }
+        { e } { \token_to_str:N n }
+        { x } { \token_to_str:N n }
+        { V } { \token_to_str:N n }
+        { v } { \token_to_str:N n }
       }
       { \@@_signature_base_form_aux:n }
       { \@@_signature_base_form_aux:w #1 }
@@ -1207,7 +1207,7 @@ and all files in that bundle must be distributed together.
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_split_function_do:nn, \@@_split_function_do:on}
+% \begin{macro}{\@@_split_function_do:nn}
 % \begin{macro}{\@@_get_function_name:n, \@@_get_function_signature:n}
 % \begin{macro}{\@@_split_function_auxi:w, \@@_split_function_auxii:w}
 %   Similar to internal functions defined in \pkg{l3basics}, but here we
@@ -1234,7 +1234,6 @@ and all files in that bundle must be distributed together.
       { ##1 {##2} }
   }
 \exp_args:No \@@_tmpa:w { \token_to_str:N : }
-\cs_generate_variant:Nn \@@_split_function_do:nn { o }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -1252,9 +1251,13 @@ and all files in that bundle must be distributed together.
   {
     \@@_if_almost_str:nTF {#1}
       {
-        \@@_key_get_base_TF:nN {#1} \l_@@_tmpa_tl
-        \__kernel_tl_set:Nx #2
-          { \@@_split_function_do:on \l_@@_tmpa_tl { \@@_base_form_aux:nnN } }
+        \__kernel_tl_set:Nx \l_@@_tmpa_tl
+          { \@@_split_function_do:nn {#1} { \@@_base_form_aux:nnN } }
+        \@@_key_get_base_TF:oN \l_@@_tmpa_tl \l_@@_tmpb_tl
+        \seq_if_in:NxTF \l__doc_donotindex_seq
+          { \exp_after:wN \use_none:n \l_@@_tmpb_tl } % or \tl_tail:N
+          { \tl_set_eq:NN #2 \l_@@_tmpa_tl }
+          { \tl_set_eq:NN #2 \l_@@_tmpb_tl }
       }
       { \tl_set:Nn #2 {#1} }
   }
@@ -1278,6 +1281,7 @@ and all files in that bundle must be distributed together.
       }
     \exp_not:N \prg_break_point:
   }
+\cs_generate_variant:Nn \@@_key_get_base_TF:nN { o }
 \cs_new:Npn \@@_base_form_aux:nnN #1#2#3
   {
     \exp_not:n {#1}

This slows down l3doc further more, since \seq_if_in:NnTF takes linear time. Storing \DoNotIndex records in a l3key module would reduce the time complexity I think.

A full example to test the patch

% !TeX TS-program = pdflatex -interaction=nonstopmode %.tex | makeindex -s gind.ist -o %.ind %.idx | pdflatex -interaction=nonstopmode %.tex | pdflatex -interaction=nonstopmode %.tex
\documentclass{l3doc}

\ExplSyntaxOn
\cs_generate_variant:Nn \__codedoc_key_get_base_TF:nN { o }

\cs_gset_protected:Npn \__codedoc_key_get_base:nN #1#2
  {
    \__codedoc_if_almost_str:nTF {#1}
      {
        \__kernel_tl_set:Nx \l__codedoc_tmpa_tl
          { \__codedoc_split_function_do:nn {#1} { \__codedoc_base_form_aux:nnN } }
        \exp_args:No
        \__codedoc_key_get_base_TF:nN \l__codedoc_tmpa_tl \l__codedoc_tmpb_tl
        \seq_if_in:NxTF \l__doc_donotindex_seq
          { \exp_after:wN \use_none:n \l__codedoc_tmpb_tl } % or \tl_tail:N
          { \tl_set_eq:NN #2 \l__codedoc_tmpa_tl }
          { \tl_set_eq:NN #2 \l__codedoc_tmpb_tl }
      }
      { \tl_set:Nn #2 {#1} }
  }

\cs_gset:Npn \__codedoc_signature_base_form_aux:n #1
  {
    \str_case:nnTF {#1}
      {
        { N } { \token_to_str:N N }
        { c } { \token_to_str:N N }
        { n } { \token_to_str:N n }
        { o } { \token_to_str:N n }
        { f } { \token_to_str:N n }
        { e } { \token_to_str:N n }
        { x } { \token_to_str:N n }
        { V } { \token_to_str:N n }
        { v } { \token_to_str:N n }
      }
      { \__codedoc_signature_base_form_aux:n }
      { \__codedoc_signature_base_form_aux:w #1 }
  }
\ExplSyntaxOff

\ExplSyntaxOn
\DoNotIndex{\file_if_exist_input:nTF, \mymod_no_TF_form:nTF}
\ExplSyntaxOff

\begin{document}
\begin{function}{\file_if_exist_input:n, \file_if_exist_input:nF}
  No \cs[no-index]{file_if_exist_input:nTF}.
\end{function}

\begin{function}[TF]{\mymod_has_TF_form:n, \mymod_has_TF_form:o}
  description
\end{function}

\begin{function}{\mymod_no_TF_form:nT, \mymod_no_TF_form:nF,
                 \mymod_no_TF_form:oT, \mymod_no_TF_form:oF}
  No \cs[no-index]{mymod_no_TF_form:oTF} nor \cs[no-index]{mymod_no_TF_form:nTF}.
\end{function}

\begin{macro}{\mymod_no_TF_form:nT, \mymod_no_TF_form:nF}
    \begin{macrocode}
\cs_new:Nn \mymod_no_TF_form:nT {}
\cs_new:Nn \mymod_no_TF_form:nF {}
%    \end{macrocode}
\end{macro}

\bigskip
Used in \cs[no-index]{cs}\Arg{csname}, base forms
\begin{itemize}
  \item \cs{file_if_exist_input:n}, \cs{file_if_exist_input:nF}
  \item \cs{mymod_has_TF_form:nT},  \cs{mymod_has_TF_form:nF}
  \item \cs{mymod_no_TF_form:nT},   \cs{mymod_no_TF_form:nF}
\end{itemize}
and variant forms
\begin{itemize}
  \item \cs{mymod_has_TF_form:oT},  \cs{mymod_has_TF_form:oF}
  \item \cs{mymod_no_TF_form:oT},   \cs{mymod_no_TF_form:oF}
\end{itemize}

\PrintIndex
\end{document}

  • Without patch
    image
  • With patch
    image
@josephwright
Copy link
Member

Could you put your patch in as a PR?

@muzimuzhi muzimuzhi changed the title l3doc: base form \<name>:<arg spec>TF conditional is indexed unconditionally l3doc: base form conditional \<name>:<arg spec>TF is indexed unconditionally Oct 16, 2023
@muzimuzhi
Copy link
Contributor Author

Related to #892 (actually almost identical, current issue just used a more general title)

I was thinking about adding some caching for quicker resolving, but didn't have a try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants