# What are the allowed characters in filenames?

What characters can be used in filenames for the main document and input files, both .tex and images etc.? I'm not asking about which are recommended to be used, but about a list of all possible characters a user could ever use in a filename. This is important to know in order to support those in filename related packages (e.g. currfile, svn-multi, ...).

I can see two use cases here:

• On the command line, e.g. using pdflatex <filename>.
Which might require single-quotes and/or \ to escape characters special to the command line shell, but then maybe again for TeX.
• Inside (La)TeX itself, e.g. \input{<filename>}.

For example: The use of % in (main document) filenames seems not possible with LaTeX using TeXLive 2011 under Linux. A pdflatex 'test%it.tex' results in a prompt and entering \relax there gives: ! I can't find file `test'.. So the % is also used as comment character in this case.

There seems to be more going on with filenames on the command line because I got the following warning:

# pdflatex 'test\$it*gdg!£\$^&%_*(){.tex'
warning: test\$it*gdg!£\$^&%_*(){.tex: Unrecognized variable construct `\$^'.
-
You may want to narrow down your main question to "which characters cannot be used in filenames, for .tex and image files, that are otherwise acceptable to the operating system?" I think there's little point in exploring characters that the operating system itself doesn't allow (e.g., /, \ , and ?) for valid names of files, right? –  Mico Apr 28 '12 at 12:02
@Mico: Thanks. That's a good point. The / and \ however can be part of the "filename" if you include the path, which we should. Also ? is valid for filenames under Linux, you just have to make sure it is masked and not taken as wildcard, e.g. 'test?it' or test\?it. –  Martin Scharrer Apr 28 '12 at 13:21

The filename syntax is one of the few explicitly system dependent parts of TeX-the-program.

In texlive (ie web2c tex) most characters are allowed (especially after the syntax was changed to allow " quoting names including spaces). Of course the characters are interpreted by TeX's macro expansion before being considered as possible filename characters, so % and friends need special handling.

This inputs test%it.tex on my texlive 2010 (using a cygwin bash shell in windows, but I imagine other command lines would be similar)

pdflatex "\begingroup\lccode44=37 \lowercase{\endgroup\input test,it}"

The warning about \$ that you mention comes from kpathsea, as described in its manual

3.3.2 Variable expansion ‘\$foo’ or ‘\${foo}’ in a path element is replaced by (1) the value of an environment variable ‘foo’ (if defined); (2) the value of ‘foo’ from ‘texmf.cnf’ (if defined); (3) the empty string. If the character after the ‘\$’ is alphanumeric or ‘_’, the variable name consists of all consecutive such characters. If the character after the ‘\$’ is a ‘{’, the variable name consists of everything up to the next ‘}’ (braces may not be nested around variable names). Otherwise, Kpathsea gives a warning and ignores the ‘\$’ and its following character.

you can test kpathsea's handling with tests sch as

\$ FOO=ZENV tex kps
This is TeX, Version 3.1415926 (Web2C 2010)
(./kps.tex (./a b c.tex
a b c found
) (./ZENV.tex
ZENV found
) )
No pages of output.
Transcript written on kps.log.

which shows that you can refer to environment variables from with tex, kps.tex is

\input "a b c.tex"

\catcode`\\$=12

\input "\$FOO.tex"

\bye

a b c.tex is

\immediate\write20{a b c found}

and ZENV.tex is

\immediate\write20{ZENV found}
-
Thanks. The kpathsea hint is very useful. Does this mean you can write \input{\$foo/myfile.tex} where foo is an environment variable or in texmf.cnf? –  Martin Scharrer Apr 28 '12 at 13:29
Yes, I updated my answer with an example –  David Carlisle Apr 28 '12 at 13:44

It gets interesting if you try characters beyond the first 128/256; e.g. XeTeX from TL2011 can not handle unicode characters (like "äöüß") in input filenames on Windows 7. But this is highly system dependent.

It's best to use only alphanum ASCII (i.e. [a-zA-Z0-9]) for filenames, as these will always work.

-