In this answer I will assume a Lua supporting engine (LuaTeX, HarfTeX, etc.)
MiKTeX is very eager to install packages, so you have to fool it:
If the file you are looking for already exists in your current directory, MiKTeX is happy and does not install the package if you ask it for the file.
So that's the plan:
Place a dummy file in the current working directory. Then ask MiKTeX, though the kpathsea emulation, for all known files matching the name. Of course the first one will be the local dummy file, but if another one is found, the package was installed.
Then delete the dummy file in the end.
\documentclass{article}
\newluafunction\filereallyexistsfuncid
\directlua{
local truetok, falsetok = token.create'@firstoftwo', token.create'@secondoftwo'
lua.get_functions_table()[\the\filereallyexistsfuncid] = function()
local filename = token.scan_string()
local f = io.open(filename) % First test if the file exists in the current folder
if f then
f:close()
return token.put_next(truetok) % In this case we are done, the file exists
end
f = io.open(filename, "w") f:close() % Otherwise create it to stop MiKTeX from installing anything
local _, f2 = kpse.lookup(filename,{all=true}) % Now we will always find the local file first and MiKTeX is happy. If the file existed before, it will be found too.
os.remove(filename) % The local file did it's job, delete it
token.put_next(f2 and truetok or falsetok) % And write the answer to TeX
end
}
\newcommand\filereallyexists{\luafunction\filereallyexistsfuncid}
\begin{document}
\filereallyexists{hyperbar.sty}{AWESOME!}{How can you be so cruel?}
\end{document}
A remark about the more special Lua language constructs here:
kpse.lookup
returns, if all=true
, one return value for every found file. So if only one file is found, only one value is returned. If two are found, two values, .... The line
local _, f2 = kpse.lookup(...)
stores the first two return values in the variables _
and f2
. (In Lua _
is a regular variable but by convention _
is used if a value is to be ignored) The actual values stored there are the full absolute filenames of the found files. But what happens if only one file is found? Then there are no "first two return values", only one filename is returned. In cases like this, Lua sets the remaining variables to the special value nil
.
In our code the only important question is: Is f2
a string or nil
? In Lua, every string (including the empty string ""
) is considered true but nil
is considered false
.
So we can act as if f2
was a boolean. Which brings us to the last line:
token.put_next(f2 and truetok or falsetok)
The a and b or c
is the Lua equivalent to the tertiary conditional operator a ? b : c
from C: If a
(in our case f2
) is true
, we get b
(truetok
) otherwise c
(falsetok
). This works as long as b
is never false
(or nil
) as a consequence of the short-circuiting of Lua's and
and or
:
We have a and b or c
which is seen as (a and b) or c
. If a
is considered true
, then a and b
if and only if b
. So Lua just evaluates a and b
to b
without casting this to a boolean value. We assumed b
to be true, so (a and b) or c === b or c
is always true
and c
doesn't even have to be evaluated, so Lua just returns b
, again without casting to booleans.
So Lua's and
and or
always return the first argument which determines their truth value. (What happens for a false
value a
is left as an exercise to the reader ;-) )
hyperbar
package using\pdffilemoddate{hyperbar.sty}
. Apparently Windows is excessive ;-) Apparently any file operation triggers the package manager...kpsewhich <package-file>
will immediately trigger auto-install if for the package to which<package-file>
belongs. It stands to reason that any TeX-operation on the file will trigger the auto-install. So Lua or some shell escape (but don't usekpsewhich
) seem like the only options out. ...