From: orloff@surya4.cern.ch (Jean Orloff)
Newsgroups: comp.text.tex
Subject: Re: REAL HACKER'S QUIZZ: redefine \input
Date: 5 Nov 92 16:15:48 GMT
	<1992Oct30.014652.14128@infodev.cam.ac.uk>
	<ORLOFF.92Oct30190338@surya4.cern.ch>
Distribution: comp.text.tex
Organization: CERN, European Research Center for Particle Physics


Thank you to all people answering my (vague) questions. To summuarize:
- athough a rock-hard standard does not clearly exist for the rules to
  parse filenames, there seems to be a de-facto agreement around
  stopping filenames at spaces or unexpandable tokens like relax.
- There does not seem to be an easy way to change the catcodes of
  already tokenized lists otherwise than setting everything to
  12(special) by using \meaning.

Here follows the results of my quest, which just adds a few
functionalities to the good old \input.

Happy TeXing,
Jean
*************************************************************************
*	Jean Orloff		*	e-mail: ORLOFF@dxcern.cern.ch	*
*	TH-Division, CERN	*	phone:	(41-22) 767-3204	*
*	CH-1211 Geneva 23	*	fax:	(41-22) 782-3914	*
*************************************************************************
% INPUT REDEFINITION:
% -works both for TeX and LaTeX;
% -\GlobalInputList contains the list of these files (with unique entries!)
% -assumes \input-redefiners loaded before this one use
%  \@@input to save the primitive \input (if not, you should un-% the lines
%  containing \savedinputname)
% READ FILENAME MODE:
%-\readfilename can be used for other purposes, just redefine
%  \readfilenamehook to what you want to do after you read the filename
% -\lastfilename remembers the name of the filename just read
% -filenames are supposed to be ending by a space character or
%  unexpandable primitive (like \hbox, \relax,...), whichever shows up first
% -understands  (\~ or \\) to mean (~ or \) in the filename
\begingroup\catcode`\|=0 |catcode`|\=12 |catcode`|%=12 |catcode`~=12
|catcode`#=12
|xdef|backslashother{\}
|xdef|percentother{%}
|xdef|tildeother{~}
|xdef|sharpother{#}
|endgroup
%
\catcode`\@=11
\def\@mpty{}
% 
% <=> \iftrue if #1 contains #2, <=>\iffalse otherwise:
\def\ifmatchin#1#2{%
  \def\m@tchtmp##1#2##2\endm@tch{\def\tmp{##2}\let\m@tchtmp=\relax%
  \toks0={\let\next\relax\iftrue}%
  \toks2={\let\next\relax\iffalse}%
    \ifx\tmp\@mpty\@mpty\edef\next{\the\toks2}%
    \else\edef\next{\the\toks0}%
    \fi\next}%
  \m@tchtmp#1#2\endm@tch%
}
% works if #1 is a single character
\def\toother#1{\ifcat\relax#1\else\expandafter%
  \toother@ux\meaning#1\endtoother@ux\fi}
\def\toother@ux#1 #2#3\endtoother@ux{\def\tmp{#3}%
  \ifx\tmp\@mpty\def\tmp{#2}\let\next=\relax%
  \else\def\next{\toother@ux#2#3\endtoother@ux}\fi%
%  \message{\meaning\tmp}
\next}
%
% \readfilename defs:
%
\def\re@d{\expandafter\re@daux}% spares typing 10 \expandafter's...
\def\re@daux{\futurelet\nextchar\stopre@dtest}
\def\re@dnext{\xdef\lastfilename{\lastfilename\nextchar}\afterassignment\re@d\let\nextchar}
\def\stopre@d{\egroup\readfilenamehook}
\def\stopre@dtest{
%\message{(\meaning\nextchar)}
  \ifcat\nextchar\relax\let\nextread\stopre@d
  \else
    \ifcat\nextchar\space\def\nextread{\stopre@d\chardef\nextchar=`}
    \else\let\nextread=\re@dnext
      \toother\nextchar
      \edef\nextchar{\tmp}
    \fi
  \fi\nextread}
\def\readfilename{\vbox\bgroup% freeing me from all % at EOL
  \let\\=\backslashother \let\%=\percentother \let\~=\tildeother
\let\#=\sharpother
  \re@d}
%
% redefines \input using \readfilename
%
\xdef\GlobalInputList{\jobname}
\def\psnewinput{%
  \def\lastfilename{}%
  \def\readfilenamehook{% each entry in \GlobalInputList should be unique
    \edef\tmpa{{\GlobalInputList}}\edef\tmpb{{\lastfilename}}%
    \expandafter\expandafter\expandafter\ifmatchin\expandafter\tmpa\tmpb%
    \else\xdef\GlobalInputList{\GlobalInputList, \lastfilename}%
%      \immediate\write\psbj@inaux{\lastfilename,}%
    \fi%
    \ps@ldinput\lastfilename\relax%
    \let\readfilenamehook=\relax%
  }\readfilename
}
% ADAPT for macros redefining \input, 
%\let\@@input=\savedinputname
\expandafter\ifx\csname @@input\endcsname\relax    % then Plain
  \immediate\let\ps@ldinput=\input\def\input{\psnewinput}
\else
  \immediate\let\ps@ldinput=\@@input
  \def\@@input{\psnewinput}
% ADAPT for macros redefining \input, 
%  \let\savedinputname=\@@input
\fi%
\catcode`\@=12
\documentstyle[12pt]{article}
\begin{document}
\def\filename{a{b}c$&\#^_b\~\%\\\~c}%      \#,\%,\~ are defined for
easier definitions
%\tracingmacros=1
%\tracingcommands=1
a\input b c%                               no blanks added as in
original \input
\input\filename\hbox to 10cm{\hss HI THERE!\hss}
%                                          filename stops at
primitives, which are not gobbled
\input{a{b}c$&#^_b\~\%\\\~c}%              # can be used as such if
not in a definition
\message{\GlobalInputList}
\end{document}
\bye



--
*************************************************************************
*	Jean Orloff		*	e-mail: ORLOFF@dxcern.cern.ch	*
*	TH-Division, CERN	*	phone:	(41-22) 767-3204	*
*	CH-1211 Geneva 23	*	fax:	(41-22) 782-3914	*
*************************************************************************
Newsgroups: comp.text.tex