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

Expandable \input (possibly with file lookup and hooks) #514

Open
PhelypeOleinik opened this issue Mar 3, 2021 · 13 comments · May be fixed by #1679
Open

Expandable \input (possibly with file lookup and hooks) #514

PhelypeOleinik opened this issue Mar 3, 2021 · 13 comments · May be fixed by #1679

Comments

@PhelypeOleinik
Copy link
Member

PhelypeOleinik commented Mar 3, 2021

Brief outline of the enhancement

LaTeX's \input has always been troublesome when used inside tables due to problems with TeX's scanning ahead for \omit and \noalign for being non-expandable. Some borderline cases, like #473 or this tex.sx question, which previously worked due to how \input was implemented, now also showed up.

Currently \input does:

  1. \@ifnextchar\bgroup to differentiate the \input{<file>} and \input <file> syntaxes;
  2. Checks if the <file> exists, and if it doesn't raise an error asking for another name;
  3. If the file exists, sets \CurrentFile;
  4. \@addtofilelist{<file>};
  5. \UseHook{file/before} and \UseHook{file/before/<file>};
  6. \@@input <file> ;
  7. \UseHook{file/after/<file>} and \UseHook{file/after};
  8. Resets \CurrentFile.

From the steps above, 3, 4, and 8 cannot be done expandably at all, that is, setting \CurrentFile and \@addtofilelist. The latter is unlikely to be useful in cases where an expandable \input is useful (most commonly tables), which only leaves us without \CurrentFile in an expandable context.

Step 1 can be done expandably with xparse, now integrated in the kernel, step 2 can be done with \file_full_name:n (with file lookup in \l_file_search_path_seq and \input@path, as standard \input do), and rely on TeX to handle the missing file error, and the hooks are already expandable by design, so the implementation of a functionally-equivalent expandable \input wouldn't need too much beyond what we already have.

What is needed is a good interface. Here are a few options:

  1. A brand-new command to be used in these places. Clean an easy, but requires document changes
  2. Some clever detection of table cells with \currentgrouptype. Clever, but prone to false-positives and doesn't cover other expandable contexts
  3. A new key-value argument to \input to signal when expandability is required. For example \input[expandable]{<file>}. Clean, clear in intention, and easily extensible if needed, but incompatible with the legacy \input <file> syntax for files whose name start with [ (is this a thing?)
  4. A starred version of \input that selects the expandable version. Also clean (maybe not so clear in intention), not so wordy as option 3, but also not easily extensible. Also incompatible with legacy syntax for files starting with * (even weirder than [, so I think it's okay).

Preferences toward one of the options? Other options?

@blefloch
Copy link
Member

blefloch commented Mar 3, 2021 via email

@josephwright
Copy link
Member

Step 1 can be done expandably with xparse, now integrated in the kernel

I'm not sure how you mean. Without an assignment, all we can do is grab an argument up-to left brace and see if that's empty. That's explicitly not in ltcmd. The 'expandable optional' stuff relies on grabbing an argument, and can't tell the difference between \foo{a} and \foo a (let alone \foo a\relax).

@josephwright
Copy link
Member

I notice another option: tell users to use the already currently working \input filename syntax since when there are no braces the primitive is used, if I understand correctly. I have no opinion on what's best.

Not currently true as \input as a LaTeX2e command is not expandable: one has to use \@@input.

@davidcarlisle
Copy link
Member

davidcarlisle commented Mar 3, 2021

\@ifnextchar\bgroup to differentiate the \input{<file>} and \input <file> syntaxes;

one option you didn't mention is (on platforms where you have added the primitive \input{..} just provide a no @ version of \@@input and let the engine handle the braces.

@PhelypeOleinik
Copy link
Member Author

I notice another option: tell users to use the already currently working \input filename

The primitive is used, but it's not expandable because of \@ifnextchar, which solves the problems in the linked issues (which is good!) but still doesn't allow lookup nor hooks.

@PhelypeOleinik
Copy link
Member Author

one option you didn't mention is (on platforms where you have added the primitive \input{..} just provide a no @ version of \@@input and let the engine handle the braces.

But LaTeX \input does a lot more than that, so this is only better than \@@input <file> because it allows spaces

@PhelypeOleinik
Copy link
Member Author

I'm not sure how you mean. Without an assignment, all we can do is grab an argument up-to left brace and see if that's empty. That's explicitly not in ltcmd. The 'expandable optional' stuff relies on grabbing an argument, and can't tell the difference between \foo{a} and \foo a (let alone \foo a\relax).

Sorry, I mixed stuff up. Yeah, not in ltcmd: it would need a dedicated parser. But I forgot about single-character file names :(

@u-fischer
Copy link
Member

While the hook code itself is expandable, this doesn't need to be the case for code in the hook. For example the structuredlog package adds non expandable code to file/before and file/after. Imho it would be better if at least the generic file hooks weren't used in such an expandable input command.

Regarding the syntax I have a slight preference for \input[expandable]{<file>}, as it would keep the option open for other variants (e.g. nohooks).

@blefloch
Copy link
Member

blefloch commented Mar 3, 2021 via email

@davidcarlisle
Copy link
Member

@PhelypeOleinik yes but as Ulrike comments it may be best not to do any of the additional things as you can't easily control what is in the hooks. If you just had \let\expandableinput\@@input then with new engines you'd be able to use \input{tablebody} in an expandable way and that may be enough.

@blefloch maybe I just misunderstood the context you are assuming but I didn't understand "3 Now we are allowed non-expandable things. " for the table use, you can't do anything non expandable before the content of the file is seen?

@PhelypeOleinik
Copy link
Member Author

@davidcarlisle Yeah, maybe generic file/before and file/after could be left out. The advantage of the key-val syntax is that you can do \input[with-hooks] or whatever if you need hooks or otherwise. The downside of \let\expandableinput\@@input is that it doesn't do file lookup where usual \input would, so the expl3 wrapper would be good to have, at least. Then \input[no-search] can be easily done.

What Bruno means with item 3 is that the expandable branch of \input would only be taken if \input[expandable] were used. If there is no [, then just do things the usual way

@stale
Copy link

stale bot commented Jun 2, 2021

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

@stale stale bot added the stale label Jun 2, 2021
@stale stale bot removed the stale label Oct 19, 2021
@stale
Copy link

stale bot commented Jan 3, 2022

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

@josephwright josephwright linked a pull request Feb 26, 2025 that will close this issue
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Pool (unscheduled issues)
Development

Successfully merging a pull request may close this issue.

5 participants