% \iffalse meta-comment %<=*COPYRIGHT> %% %% Copyright (c) 2010-2024 by Martin Scharrer %% ---------------------------------------------------------------------- %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3c %% of this license or (at your option) any later version. %% The latest version of this license is in %% %% http://www.latex-project.org/lppl.txt %% %% and version 1.3c or later is part of all distributions of LaTeX %% version 2008/05/04 or later. %% %% This work has the LPPL maintenance status `maintained'. %% %% The Current Maintainer of this work is Martin Scharrer. %% %% This work consists of the files currfile.dtx, currfile.ins %% and currfile.sty. %% %<=/COPYRIGHT> % \fi % % \iffalse %<*driver> \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesFile{currfile.dtx}[% %<=*DATE> 2024/03/14 %<=/DATE> %<=*VERSION> v1.0 %<=/VERSION> DTX file for currfile package] \documentclass{ydoc}[2011/03/19] \usepackage{currfile}[2011/09/18] \usepackage{ifpdf} \usepackage{booktabs} \usepackage{hyperref} \usepackage{flafter} \EnableCrossrefs \CodelineIndex \RecordChanges \let\IncludeImplementation\relax %\let\IncludeImplementation\empty %^^A Enable implementation \ifx\IncludeImplementation\relax \OnlyDescription \fi \let\cnt\env \begin{document} \DocInput{currfile.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % \CheckSum{1115} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % % \changes{v0.1}{2010/04/08}{Initial version} % \changes{v0.2}{2010/04/10}{Now work for all files, not only for \cs{input} and \cs{include} files. % Added package option 'fink' to define the same macros as the 'fink' package. % } % \changes{v0.3}{2011/01/03}{Update to use new version of filehook.} % \changes{v0.4}{2011/01/09}{Added if-macros and sanitized currfile macros.} % \changes{v0.5}{2011/09/18}{Added support for \cs{input@path} and files with multiple dots.} % \changes{v0.6}{2012/05/06}{Added support for absolute file paths.} % \changes{v0.7}{2012/05/15}{Added support for parent file paths.} % \changes{v0.7a}{2012/10/28}{Fixed issue with \pkg{enumitem} package which redefines \cs{value}.} % \changes{v0.7b}{2013/02/01}{Support for \cs{\subinput*} etc.\ from the \pkg{import} package which requires a different path search order.} % \changes{v0.7c}{2015/04/23}{Removed stack underflow warning if loaded by other package. Set default file name in this case to main file name.} % \changes{v0.7d}{2020/09/29}{Updated documentation for 2020/10/01 \LaTeX\ release.} % \changes{v0.8}{2022/10/10}{Fixed issue with filename with spaces.} % % % \GetFileInfo{currfile.dtx} % % \DoNotIndex{\newcommand,\newenvironment,\fi,\relax,\def,\gdef,\xdef} % \DoNotIndex{\RequirePackage,\space,\PackageError,\PackageWarning,\let} % \DoNotIndex{\ifx,\global,\long,\dindent,\else,\empty,\expandafter} % \DoNotIndex{\csname,\endcsname,\DeclareBoolOption,\DeclareStringOption} % \DoNotIndex{\SetupKeyvalOptions,\begingroup,\endgroup,\@gobble,\edef} % \DoNotIndex{\message,\jobname,\@namedef} % % \author{Martin Scharrer} % \email{martin.scharrer@web.de} % \repository{https://github.com/MartinScharrer/currfile} % \maketitle % % \begin{abstract} % This small package provides the file name and path information of the current input file as \LaTeX{} macros. % It properly supports file names with multiple dots and the \cs{input@path} feature used by some packages like \pkg{import}. % Optionally also the absolute location of current input file can be provided if a special compiler option is enabled. % \end{abstract} % % \tableofcontents % % \section{Direct filename support in \LaTeX\ 2020/10/01} % With the \LaTeX\ release 2020/10/01 the core now provides own filehooks and access to the current filename and path. % This package still uses the authors \pkg{filehook} package to collect the filenames but there the core implementation is now used internally. % Due to this users could see changes in the output in some special cases. % % For new documents users might want to use the new core macros \Macro\CurrentFile and \Macro\CurrentFilePath discribed in % \href{http://mirrors.ctan.org/macros/latex-dev/base/ltfilehook-doc.pdf}{\texttt{ltfilehook-doc}} % directly and use this package only if the advanced features -- like parent or absolute file names - are required. % Note that \Macro\CurrentFile is empty for the main document which filename can be accessed usually over \Macro\jobname. % % % \section{Important notice} % This package relies heavily on the package \pkg{filehook} by the same author and installs at-begin and at-end hooks for all files. % The provided macros for the file names \emph{will only work for files loaded \emph{after} the package}. % This means only for files which are getting opened afterwards and where not yet opened, as the at-begin hook is required to run. % The macros will therefore not work correctly in a package which loaded \pkg{currfile}, but for all further loaded packages. % % The options \opt{abspath} and \opt{realmainfile} may be used to improve the behavior in such cases. % % However, it is simply recommended to load \pkg{currfile} as early as possible. It can even be loaded before the class using % \Macro\RequirePackage{currfile}. % % \section{Usage} % % \DescribeMacro{\currfiledir} % \DescribeMacro{\currfilebase} % \DescribeMacro{\currfileext} % \DescribeMacro{\currfilename} % \DescribeMacro{\currfilepath} % The directory, base (name without extension), extension (without dot), name (=base+`|.|'+ext) and path (=dir+name) of the current file are provided by these macros. % This means that the macros returns the file information of the file they are used in. All macros are fully expanded, i.e.\ only hold % text and not further macros. They are also ``sanitized'' to ensure that all characters, especially special ones like `|_|', are taken verbatim. % However this special characters might not be displayed correctly in all fonts. A good font is text-type (\Macro\ttfamily, \Macro\texttt{\ldots}), % but other fonts can be used using the \pkg{url} package, e.g.: |\urlstyle{rm}\expandafter\nolinkurl\expandafter{\currfilename}|. % Note that the directory separator is always `|/|' even under MS Windows. % % Special care is taken to keep the file information of \Macro\included files till the final \Macro\clearpage command, so that page header and footer of the last page % will hold the correct data. % % Since v0.2 all files are are taken into account, i.e.\ files read using \Macro\input, \Macro\include, \Macro\InputIfFileExists, \Macro\usepackage, \Macro\RequirePackage and even % \Macro\LoadClass and similar macros. Before v0.2 only \Macro\input or \Macro\include and the main file were taken into account. % % This package uses the \pkg{filehook} package written by the same author. See there for possible incompatibilities with classes or other packages. % % If required more detailed information can be found in the implementation section \ifx\IncludeImplementation\relax(compile this manual with \Macro\AlsoImplementation)\else % \unskip~\ref{sec:impl}\fi. % % \begingroup % \let\DescribeCounter\DescribeKey % \let\keydescstyle\macrodescstyle % \DescribeCounter{currfiledepth} % This\marginpar{\raggedright New in v0.7 from 2012/05/15} \LaTeX\ counter provides the nesting depth of the current input file. % For the main file name it has a value of 0. % Inside a sub-file of the main file it has a value of 1, while in a sub-file to that file it has a value of 2, etc. % Like all \LaTeX\ counter it can be typeset using \Macro\arabic{currfiledepth} and its numeric value can be accessed % using \Macro\value{currfiledepth}. % \endgroup % % \DescribeMacro{\ifcurrfiledir}{}{}{} % \DescribeMacro{\ifcurrfilebase}{}{}{} % \DescribeMacro{\ifcurrfileext}{}{}{} % \DescribeMacro{\ifcurrfilename}{}{}{} % \DescribeMacro{\ifcurrfilepath}{}{}{} % This\marginpar{\raggedright New in v0.4 from 2011/01/09} if-macros allow the comparison of \meta{text} with the current file directory, base, extension, name and path, respectively. % The \meta{text} is fully expanded and sanitized for the comparison. Example: |\ifcurrfileext{cfg}{I'm in a config file}{No config file!}| % % \DescribeMacro{\ifcurrfile}{}{}{}{} % Compares the given \meta{currfile macro or text} with \meta{text}. Both are taken as file name parts and are fully expanded and sanitized before the comparison. % This general macro is a little slower then the specialised macros above but might be useful to compare different file names/paths where non of the two is the current file. % Note that the all comparisons are done insensitive to the catcodes of the texts, which is what users want. Different comparision macros (|\ifx|, \pkg{ifthenelse}) might not do this. % % \subsection{Package Options} % The package provides the following options: % % The string options \opt{mainext} and \opt{maindir} can be used to provide the extension (without the dot) and directory of the main file. % This is required if the above macros should be used for the main file itself and if this does has a file extension other than `|.tex|' (e.g.\ a |.dtx| file) % or is not located in the current directory. The \opt{mainext} is by default `|tex|' and the \opt{maindir} is the empty % string. See also the related \pkg{realmainfile} option. % % To provide support for the macros defined by the \pkg{fink} package (see section~\ref{sec:fink}) a boolean \opt{fink} option exists. % If the \pkg{fink} package is loaded before \pkg{currfile} this option is automatically enabled to provide % compatibility. The \opt{mainext} and \opt{maindir} options are then automatically set to the values of the identical % options of \pkg{fink}. Note that \pkg{fink} is now officially declared deprecated by its author in favour of % \pkg{currfile}. % % Using the boolean \opt{abspath} option\marginpar{\raggedright New in v0.6 from 2012/05/06} % the support for absolute directories and paths is enabled. This loads the % sub-package \pkg{currfile-abspath}. % This requires the compiler option `|-recorder|' to be used. % See \autoref{sec:abspath} for more details. % This option will also enabled the related option \opt{realmainfile} if it isn't explicitly used. % % If the boolean \opt{realmainfile} option\marginpar{\raggedright New in v0.6 from 2012/05/06} % is enabled the real main file path is determined using the sub-package \pkg{currfile-abspath}. % This option is very useful if the job-name is set to something else then the main file base name, e.g.\ using the % `|-jobname|' compiler option. Note that this option requires the correct file extension being set using \opt{mainext} % (without the dot). If the main file has the default extension `|.tex|' then no extra efford is required. For `|.dtx|' files % |mainext=dtx| must also be used, otherwise the correct file name can't be determined. % This option requires the compiler option `|-recorder|' to be used in order to work correctly. % See \autoref{sec:abspath} for more details. % % Using the boolean \opt{parent} option\marginpar{\raggedright New in v0.7 from 2012/05/15} % additional macros are set for the parent file of the current file. % See \autoref{sec:parent} for more details. % % \section{Absolute paths}\label{sec:abspath} % If\marginpar{\raggedright New in v0.6 from 2012/05/06} % required also the absolute path and directory of the current input file can be provided. % This feature is implemented by the sub-package \pkg{currfile-abspath} which is automatically loaded by the % \opt{abspath} option. % The absolute path information are read from the `|\jobname.fls|' file produced by the `|-recorder|' compiler option % (i.e.\ compile with `|pdflatex -recorder file.tex|'). % Without this compiler option a warning is produced and the related macros stay empty. % Note that TeX Live under Linux and Windows is able to read the currently produced `|.fls|' file while with MiKTeX % the file of the last run is still active. The means that the information is not available with MiKTeX in the very % first compiler run and every time the `|.fls|' file is deleted. Also, changes in the file structure are taking % two compiler runs in order to be noticed. With TeX Live the `|.fls|' file and its information is always current. % % % \subsection{Additional \pkg{currfile} macros for absolute dir and path} % Using the \opt{abspath} package option of \pkg{currfile} the following macros with absolute directories and paths are enabled. % % \DescribeMacro{\currfileabsdir} % \DescribeMacro{\currfileabspath} % Hold the absolute directory and path (directory plus filename) of the current input file, respectively. % Both macros will always be empty if the `|.fls|' file is not available. % % \DescribeMacro{\ifcurrfileabsdir}{}{}{} % \DescribeMacro{\ifcurrfileabspath}{}{}{} % These if-macros allow the comparison of \meta{text} with the current absolute file directory and path, respectively. % The \meta{text} is fully expanded and sanitized for the comparison. % % \subsection{Stand-alone usage of \pkg{currfile-abspath}} % The sub-package \pkg{currfile-abspath} can also be used on its own and provides the following lower-level macros: % % \DescribeMacro\getpwd % \DescribeMacro\thepwd % The parent working directory (PWD) is read by \Macro\getpwd from the `|.fls|' file and stored in \Macro\thepwd. % All characters of the directory will have catcode 12 (other) except spaces which still have catcode 10 (space). % If the PWD could not be determined, because there was not `|.fls|' file, then `\Macro\thepwd` will be empty. % Note that \Macro\getmainfile and \Macro\getabspath both also set \Macro\thepwd while reading the `|.fls|' file. % % \DescribeMacro\getmainfile % \DescribeMacro\themainfile % With \Macro\getmainfile the name of the main file is read from the `|.fls|' file and stored in \Macro\themainfile. % All characters of the file name will have catcode 12 (other) except spaces which still have catcode 10 (space). % If the main file name could not be determined, because there was not `|.fls|' file, then `\Macro\themainfile` will be empty. % % Here it is assumed that the first read file with the `|.tex|' extension is the main file. There is currently no user interface for this % sub-package to change this extension (to e.g.\ `|.dtx|'). However, this can be done using the \opt{mainext} option % of the main package \pkg{currfile}. % % \DescribeMacro\getabspath{} % \DescribeMacro\getabspath{} % \DescribeMacro\theabspath % \DescribeMacro\theabsdir % With \Macro\getabspath{} the absolute path of the given file is read from the `|.fls|' file and stored in \Macro\theabspath. % The directory component (path without file name) is stored in \Macro\theabsdir. % The directory always ends in a `|/|' (even under MS Windows), so that a file name can be appended directly. % All characters of both macros will have catcode 12 (other) except spaces which still have catcode 10 (space). % Note that \meta{file name} must include the full extension but can include a directory component (e.g.\ `|subdir/file.tex|'). % If a directory component is given it will not be part of \Macro\theabsdir. % For example \Macro\getabspath{'subdir/file.tex'} will return \Macro\theabspath as `|/absolute/path/subdir/file.tex|' % and \Macro\theabsdir as `|/absolute/path/|'. This differs from \Macro\currfileabsdir which will always includes all directory % elements, which is done by appending \Macro\currfiledir after \Macro\theabsdir. % % The given file must be directly accessible by \TeX, i.e.\ from the current directory or using the |TEXMF| tree, % otherwise it the absolute location can not be determined. If the file can't be found in the `|.fls|' file the macros % \Macro\theabspath and \Macro\theabsdir are empty. % % \section{Parent file macros}\label{sec:parent} % If\marginpar{\raggedright New in v0.7 from 2012/05/15} % the \opt{parent} package option is enabled the following macros are provided. % They are no direct |\if...| macros for these but the general \Macro\ifcurrfile macro can be used with them. % % \DescribeMacro{\parentfiledir} % \DescribeMacro{\parentfilebase} % \DescribeMacro{\parentfileext} % \DescribeMacro{\parentfilename} % \DescribeMacro{\parentfilepath} % These macros are analog to the |\currfile...| macros but for the parent file of the current file. % They are all empty for the main file which does not have a parent file. % % \DescribeMacro{\parentfileabsdir} % \DescribeMacro{\parentfileabspath} % These macros are provided if the \opt{abspath} option is used in addition to \opt{parent}. % They are also empty for the main file. % % % \section{Access all parent files}\label{sec:parents} % If\marginpar{\raggedright New in v0.7 from 2012/05/15} % the \opt{parents} package option is enabled the following macros are provided. % Note that this option does not enable the \opt{parent} option. % % \DescribeMacro{\currfilegetparents} % This macro locally defines file name macros for all parent files of the current input file: % The macros are named like the ones of the \opt{parent} option, but also include a trailing % roman number to indicate the parent file level, starting with `i` for the first parent file: % % \begin{DescribeMacrosTab}{llll} % \Macro{\parentfilediri} & \Macro{\parentfiledirii} & $\ldots$ \\ % \Macro{\parentfilebasei} & \Macro{\parentfilebaseii} & $\ldots$ \\ % \Macro{\parentfileexti} & \Macro{\parentfileextii} & $\ldots$ \\ % \Macro{\parentfilenamei} & \Macro{\parentfilenameii} & $\ldots$ \\ % \Macro{\parentfilepathi} & \Macro{\parentfilepathii} & $\ldots$ \\ % \Macro{\parentfileabsdiri} & \Macro{\parentfileabsdirii} & $\ldots$ \\ % \Macro{\parentfileabspathi} & \Macro{\parentfileabspathii} & $\ldots$ \\ % \end{DescribeMacrosTab} % Note that these macros are only defined in the current group and not globally like all other file name macros. % The number of the highest parent file is given by the \cnt{currfiledepth} counter. % % For example, if \Macro\currfilegetparents is used in a sub-sub-sub-file the \cnt{currfiledepth} counter is 3 % and \Macro\parentfilenameiii is the name of the main document file. % % \section{Usage inside file hooks} % This package uses the `EveryFile' hooks of the \pkg{filehook} package to update its macros. % Special care is taken to do this in a way so that the macros can be used safely inside other hook code, including other `EveryFile' hooks. % Please note that the `AtEndOfPackageFile' and `AtEndOfClassFile' hooks are executed after `AtEndOfEveryFile' % and therefore the |currfile| macros will hold the values of the parent file, not of that package or class file. % % \section{Compatibility with the \texttt{fink} package}\label{sec:fink} % The \pkg{fink} package (\emph{fi}le \emph{n}ame \emph{k}eeper) provides a similar functionality. It has inspired this package in several points (e.g.\ package % options). However, it does not exclude package and other preamble files and does not take care to change the filename \emph{after} the \Macro\clearpage of % \Macro\include. The author of \texttt{fink} is now discontinuing it in favour of this package. % Existing documents which use \pkg{fink} should either rename the related macros as shown by Table~\ref{tab:fink} or use the \pkg{fink} option of \pkg{currfile} which defines % the \pkg{fink} macros to use the \pkg{currfile} ones. % % Because both packages do basically the same thing, especially patch the same macros, there are incompatible and should not be loaded at the same time. % In consent with the \pkg{fink} package author this package will undo most of the \pkg{fink} code if it was already loaded or prevent it from being loaded afterwards. % % \begin{table} % \belowcaptionskip=\abovecaptionskip % \abovecaptionskip=0pt % \caption{Conversion from \texttt{fink} package to \texttt{currfile}.} % \label{tab:fink} % \centering % \begin{tabular}{lll} % \toprule % \texttt{fink} & \texttt{currfile} & Example Result \\ % \midrule % \cs{finkdir} & \cs{currfiledir} & \ttfamily\currfiledir \\ % \cs{finkbase} & \cs{currfilebase} & \ttfamily\currfilebase \\ % \cs{finkext} & \cs{currfileext} & \ttfamily\currfileext \\ % \cs{finkfile} & \cs{currfilename} & \ttfamily\currfilename \\ % \cs{finkpath} & \cs{currfilepath} & \ttfamily\currfilepath \\ % \bottomrule % \end{tabular} % \end{table} % % \StopEventually{} % % \section{Implementation}\label{sec:impl} % % \iffalse %<*currfile.sty> % \fi % % \subsection{Package \pkg{currfile}} % % \subsubsection{Package header} % % \begin{macrocode} \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{currfile}[% % % %<*DRIVER> 2099/01/01 develop % Provides the file path elements of the current input file] % \end{macrocode} % % \subsubsection{Options} % % \begin{macrocode} \RequirePackage{kvoptions} \SetupKeyvalOptions{family=currfile,prefix=currfile@} % \end{macrocode} % % Handle already loaded \pkg{currfile-abspath} package. % \begin{macrocode} \@ifpackageloaded{currfile-abspath}{% \let\currfile@mainext\relax }{}% % \end{macrocode} % % \begin{macrocode} \@ifpackageloaded{fink}{% \DeclareStringOption[\fnk@mainext]{mainext}% \DeclareStringOption[\fnk@maindir]{maindir}% \DeclareBoolOption[true]{fink}% \PackageWarning{currfile}{Deprecated package 'fink' detected. % The 'fink' option will default to 'true'.^^J% If set to 'false' no 'fink' macros will be changed but they will stop working correctly!}% }{% \DeclareStringOption[tex]{mainext}% \DeclareStringOption[\@currdir]{maindir}% \DeclareBoolOption[false]{fink}% }% \DeclareVoidOption{force}{\PassOptionsToPackage{force}{filehook}} \DeclareBoolOption[false]{parent} \DeclareBoolOption[false]{parents} \DeclareBoolOption[false]{realmainfile}% \let\ifcurrfile@realmainfile\relax \DeclareBoolOption[false]{abspath}% \RequirePackage{filehook}[2011/01/09] \ProcessKeyvalOptions*\relax \begingroup \xdef\currfile@mainext{\currfile@mainext}% \xdef\currfile@maindir{\currfile@maindir}% \def\@tempa{./}% \ifx\@tempa\currfile@maindir \global\let\currfile@maindir\@empty \fi \endgroup % \end{macrocode} % Check if \opt{realmainfile} option was used. If not it is determined % by the \opt{abspath} option. % \begin{macrocode} \expandafter\ifx\csname ifcurrfile@realmainfile\endcsname\relax \ifcurrfile@abspath \currfile@realmainfiletrue \else \currfile@realmainfilefalse \fi \fi % \end{macrocode} % % \begin{macrocode} \begingroup \@tempswafalse \ifcurrfile@abspath \@tempswatrue \else \ifcurrfile@realmainfile \@tempswatrue \fi\fi \if@tempswa \endgroup \@ifpackageloaded{currfile-abspath}{% \PackageWarning{currfile}{Sub-package 'currfile-abspath' already loaded beforehand. This might lead to wrong results when non-default options are used.}% }{}% \RequirePackage{currfile-abspath} \else \endgroup \fi % \end{macrocode} % % % \subsubsection{File Hooks} % The \pkg{filehook} package is used to execute the macros at the correct places. % However it must be loaded before the option processed because the |fink| compatibility % code in |filehook-fink| will modify the option list. % The internal interface, not the user-interface, is used to make sure that the file names are valid for all other hooks. % % \begin{macrocode} \filehook@prefixwarg\filehook@every@atbegin{% \currfile@push \currfile@set{#1}% } \filehook@appendwarg\filehook@every@atend{% \currfile@pop } % \end{macrocode} % % % \subsubsection{Set Current Values} % % \begin{macro}{\currfile@set} % Sets the file information which are parsed by \LaTeX's \Macro\filename@parse. % \changes{2011/09/18}{v0.5}{Now supports path elements from \cs{input@path}.} % \changes{2011/09/18}{v0.5}{Now supports multiple dots in the file name.} % \begin{macrocode} \def\currfile@set#1{% \begingroup \currfile@setparent \edef\@filef@und{#1}% \ifx\input@path\@undefined\else \currfile@checkpath \fi \@onelevel@sanitize\@filef@und \let\filename@simple\currfile@parseext \let\filename@base\@gobble \expandafter\filename@parse\expandafter{\@filef@und}% \global\let\currfiledir\filename@area \global\let\currfilebase\filename@base \global\let\currfileext\filename@ext \xdef\currfilename{\currfilebase\ifx\currfileext\@empty\else.\currfileext\fi}% \xdef\currfilepath{\currfiledir\currfilename}% \ifcurrfile@abspath \getabspath\currfilepath \global\let\currfileabspath\theabspath \xdef\currfileabsdir{\theabsdir\currfiledir}% \fi \global\advance\c@currfiledepth by\@ne \endgroup % \expandafter\gdef\expandafter\dindent\expandafter{\dindent\space}% % \message{^^JDEBUG: \dindent\empty Entering file '\currfilename' ^^J }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\currfile@parent} % Sets the current file data as parent file data. Must be called directly before % updating the current file data. % \begin{macrocode} \ifcurrfile@parent \ifcurrfile@abspath \def\currfile@setparent{% \global\let\parentfiledir\currfiledir \global\let\parentfilebase\currfilebase \global\let\parentfileext\currfileext \global\let\parentfilename\currfilename \global\let\parentfilepath\currfilepath \global\let\parentfileabspath\currfileabspath \global\let\parentfileabsdir\currfileabsdir } \else \def\currfile@setparent{% \global\let\parentfiledir\currfiledir \global\let\parentfilebase\currfilebase \global\let\parentfileext\currfileext \global\let\parentfilename\currfilename \global\let\parentfilepath\currfilepath } \fi \else \let\currfile@setparent\relax \fi % \end{macrocode} % \end{macro} % % % \begin{macro}{\currfile@openin}[2]{file handle}{file path} % Opens the given file for reading. % \begin{macrocode} \def\currfile@openin#1#2{% \openin#1="#2"\relax } % \end{macrocode} % \end{macro} % % % \begin{macro}{\currfile@checkpath} % This loop is placed in an own macro for efficiency reasons. % In the majority of cases it should not be needed and having it as % a macro avoids the need to skip over this code as part of a conditional clause % for every read file. % \changes{2011/09/18}{v0.5}{New macro as part of the \cs{input@path} support.} % \begin{macrocode} \def\currfile@checkpath{% \currfile@openin{\@inputcheck}{\@filef@und}% \ifeof\@inputcheck \currfile@check@inputpath \fi \closein\@inputcheck } % \end{macrocode} % \end{macro} % % % \begin{macro}{\currfile@check@inputpath} % Check all paths in the \cs{input@path} macro. % \begin{macrocode} \def\currfile@check@inputpath{% \expandafter\@tfor \expandafter\@tempb \expandafter:\expandafter=\input@path\do{% \currfile@openin{\@inputcheck}{\@tempb\@filef@und}% \ifeof\@inputcheck\else \edef\@filef@und{\@tempb\@filef@und}% \@break@tfor \fi }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\currfile@checkpath} % Special version for the \pkg{import} package. % \begin{macrocode} \AtEndOfPackageFile*{import}{% \def\currfile@checkpath{% \ifx\IfFileExists\@iffileonpath \currfile@check@inputpath \else \currfile@openin{\@inputcheck}{\@filef@und}% \ifeof\@inputcheck \currfile@check@inputpath \fi \fi \closein\@inputcheck }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\currfile@parseext} % Replacement for \Macro\filename@simple to allow multiple dots in a filename. % This needs |\let\filename@base\@gobble| before it is called. % \changes{2011/09/18}{v0.5}{New macro as part of the multi-dot support.} % \begin{macrocode} \begingroup \@makeother{.} \gdef\currfile@parseext#1.#2\\{% \ifx\\#2\\% \ifx\filename@base\@gobble \def\filename@base{#1}% \let\filename@ext\currfile@defaultext% \else \def\filename@ext{#1}% \fi \else \edef\filename@base{\filename@base.#1}% \def\@tempa{\currfile@parseext#2\\}% \expandafter\@tempa \fi } \endgroup % \end{macrocode} % \end{macro} % % \begin{macro}{\currfile@defaultext} % Holds the default extension `|tex|' with catcode \emph{other} like \Macro\jobname. % \changes{2011/09/18}{v0.5}{New macro as part of the multi-dot support.} % \begin{macrocode} \def\currfile@defaultext{tex} \@onelevel@sanitize\currfile@defaultext % \end{macrocode} % \end{macro} % % \subsubsection{File Stack} % The file information are pushed and popped on a stack to save and restore them when % entering and leaving a sub-file, respectively. This is quite similar to the way % \LaTeX\ saves file base names and extension as well as the `@' status (letter or other) for % package and class files. % % \begin{macro}{\currfile@push} % \begin{macrocode} \ifcurrfile@abspath \def\currfile@push{% \xdef\currfile@stack{% {\currfiledir}% {\currfilebase}% {\currfileext}% {\currfileabsdir}% \currfile@stack }% } \else \def\currfile@push{% \xdef\currfile@stack{% {\currfiledir}% {\currfilebase}% {\currfileext}% \currfile@stack }% } \fi % \end{macrocode} % \end{macro} % % \begin{macro}{\currfile@pop} % \begin{macrocode} \def\currfile@pop{% % \message{^^JDEBUG: \dindent\empty Leaving file '\currfilename' ^^J }% \ifcase0% \ifx\currfile@stack\empty 1\else \ifnum\c@currfiledepth<\@ne 1\fi\fi \relax \global\advance\c@currfiledepth by\m@ne \else \global\let\currfile@stack\currfile@stackinit \global\c@currfiledepth=\z@ \fi \expandafter\currfile@pop@\currfile@stack\relax \relax\relax\relax\relax\relax\relax\relax % \message{^^JDEBUG: \dindent\empty Restoring file '\currfilename' ^^J }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\currfile@pop@} % \begin{macrocode} \ifcurrfile@abspath \def\currfile@pop@#1#2#3#4{% \gdef\currfiledir{#1}% \gdef\currfilebase{#2}% \gdef\currfileext{#3}% \xdef\currfilename{\currfilebase\ifx\currfileext\empty\else.\currfileext\fi}% \xdef\currfilepath{\currfiledir\currfilename}% \gdef\currfileabsdir{#4}% \xdef\currfileabspath{\ifx\currfileabsdir\@empty\else\currfileabsdir\currfilename\fi}% \currfile@updatestack } \else \def\currfile@pop@#1#2#3{% \gdef\currfiledir{#1}% \gdef\currfilebase{#2}% \gdef\currfileext{#3}% \xdef\currfilename{\currfilebase\ifx\currfileext\empty\else.\currfileext\fi}% \xdef\currfilepath{\currfiledir\currfilename}% \currfile@updatestack } \fi % \end{macrocode} % \end{macro} % % \begin{macro}{\currfile@updatestack} % \begin{macrocode} \ifcurrfile@parent \ifcurrfile@abspath \def\currfile@updatestack#1#2#3#4#5\relax{% \gdef\parentfiledir{#1}% \gdef\parentfilebase{#2}% \gdef\parentfileext{#3}% \xdef\parentfilename{\parentfilebase\ifx\parentfileext\empty\else.\parentfileext\fi}% \xdef\parentfilepath{\parentfiledir\parentfilename}% \gdef\parentfileabsdir{#4}% \xdef\parentfileabspath{\ifx\parentfileabsdir\@empty\else\parentfileabsdir\parentfilename\fi}% \gdef\currfile@stack{{#1}{#2}{#3}{#4}#5}% } \else \def\currfile@updatestack#1#2#3#4\relax{% \gdef\parentfiledir{#1}% \gdef\parentfilebase{#2}% \gdef\parentfileext{#3}% \xdef\parentfilename{\parentfilebase\ifx\parentfileext\empty\else.\parentfileext\fi}% \xdef\parentfilepath{\parentfiledir\parentfilename}% \gdef\currfile@stack{{#1}{#2}{#3}#4}% } \fi \else \def\currfile@updatestack#1\relax{% \gdef\currfile@stack{#1}% } \fi % \end{macrocode} % \end{macro} % % \begin{macrocode} \ifcurrfile@parents % \end{macrocode} % % \begin{macro}{\currfilegetparents} % \begin{macrocode} \newcommand*\currfilegetparents{% \@tempcnta\@ne \expandafter\currfile@getparents\currfile@stack\relax \relax\relax\relax\relax\relax\relax\relax } \ifcurrfile@abspath \def\currfile@getparents#1#2#3#4{% \@namedef{parentfiledir\romannumeral\@tempcnta}{#1}% \@namedef{parentfilebase\romannumeral\@tempcnta}{#2}% \@namedef{parentfileext\romannumeral\@tempcnta}{#3}% \expandafter\edef\csname parentfilename\romannumeral\@tempcnta\endcsname{#2\ifx\empty#3\empty\else.#3\fi}% \expandafter\edef\csname parentfilepath\romannumeral\@tempcnta\endcsname{#1\csname parentfilename\romannumeral\@tempcnta\endcsname}% \@namedef{parentfileabsdir\romannumeral\@tempcnta}{#4}% \expandafter\edef\csname parentfileabspath\romannumeral\@tempcnta\endcsname{% \expandafter\ifx\csname parentfileabsdir\romannumeral\@tempcnta\endcsname\@empty\else \csname parentfileabsdir\romannumeral\@tempcnta\endcsname \csname parentfilename\romannumeral\@tempcnta\endcsname \fi }% \ifnum\@tempcnta<\c@currfiledepth \advance\@tempcnta\@ne \expandafter\currfile@getparents \fi } \else \def\currfile@getparents#1#2#3{% \@namedef{parentfiledir\romannumeral\@tempcnta}{#1}% \@namedef{parentfilebase\romannumeral\@tempcnta}{#2}% \@namedef{parentfileext\romannumeral\@tempcnta}{#3}% \expandafter\edef\csname parentfilename\romannumeral\@tempcnta\endcsname{#2\ifx\empty#3\empty\else.#3\fi}% \expandafter\edef\csname parentfilepath\romannumeral\@tempcnta\endcsname{#1\csname parentfilename\romannumeral\@tempcnta\endcsname}% \ifnum\@tempcnta<\c@currfiledepth \advance\@tempcnta\@ne \expandafter\currfile@getparents \fi } \fi % \end{macrocode} % \end{macro} % % \begin{macro}{\parentfile}[2]{file path part}{number} % Expands to the \Macro\parentfile macro. % \begin{macrocode} \newcommand\parentfile[2]{% \csname parentfile#1\romannumeral#2\endcsname } % \end{macrocode} % \end{macro} % % \begin{macrocode} \fi % \end{macrocode} % % \iffalse % \def\dindent{} % \fi % % \begin{macro}{\currfile@stack} % \begin{macro}{\currfile@stackinit} % Initialise the stack with empty values and set the main file values. % \begin{macrocode} \let\currfile@stack\@empty \let\currfiledir\@empty \let\currfilebase\@empty \let\currfileext\@empty \let\currfilename\@empty \let\currfilepath\@empty \let\currfileabspath\@empty \let\currfileabsdir\@empty \newcounter{currfiledepth} \global\c@currfiledepth\m@ne \ifcurrfile@realmainfile \getmainfile \ifx\themainfile\@empty \currfile@set{\currfile@maindir\jobname.\currfile@mainext} \else \currfile@set{\themainfile} \fi \else \currfile@set{\currfile@maindir\jobname.\currfile@mainext} \fi \currfile@push \let\currfile@stackinit\currfile@stack % \end{macrocode} % \end{macro} % \end{macro} % % Disable the change of the \opt{abspath} option at this point % in order to freeze the stack format. % \begin{macrocode} \let\currfile@abspathfalse\relax \let\currfile@abspathtrue\relax % \end{macrocode} % % \subsubsection{If Macros} % \begin{macro}{\ifcurrfilename} % \begin{macrocode} \newcommand*\ifcurrfilename{\begingroup\currfile@if\currfilename} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifcurrfilebase} % \begin{macrocode} \newcommand*\ifcurrfilebase{\begingroup\currfile@if\currfilebase} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifcurrfileext} % \begin{macrocode} \newcommand*\ifcurrfileext{\begingroup\currfile@if\currfileext} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifcurrfiledir} % \begin{macrocode} \newcommand*\ifcurrfiledir{\begingroup\currfile@if\currfiledir} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifcurrfilepath} % \begin{macrocode} \newcommand*\ifcurrfilepath{\begingroup\currfile@if\currfilepath} % \end{macrocode} % \end{macro} % % \begin{macrocode} \ifcurrfile@abspath % \end{macrocode} % % \begin{macro}{\ifcurrfileabspath} % \begin{macrocode} \newcommand*\ifcurrfileabspath{\begingroup\currfile@if\currfileabspath} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifcurrfileabsdir} % \begin{macrocode} \newcommand*\ifcurrfileabsdir{\begingroup\currfile@if\currfileabsdir} % \end{macrocode} % \end{macro} % % \begin{macrocode} \fi % \end{macrocode} % % \begin{macro}{\ifcurrfile}[1]{currfile macro or text} % Expands and sanitizes the first argument and then calls the internal if-macro % with the result. % \begin{macrocode} \newcommand*\ifcurrfile[1]{% \begingroup \edef\@tempb{#1}% \@onelevel@sanitize\@tempb \currfile@if\@tempb } % \end{macrocode} % \end{macro} % % \begin{macro}{\currfile@if}[2]{currfile macro to compare}{compare text} % Expands the text and sanitize it to ensure correct neutral catcodes. % Then it temp macro is compared to the given currfile macro. % \begin{macrocode} \def\currfile@if#1#2{% \edef\@tempa{#2}% \@onelevel@sanitize\@tempa \ifx\@tempa#1% \endgroup \expandafter\@firstoftwo \else \endgroup \expandafter\@secondoftwo \fi } % \end{macrocode} % \end{macro} % % % \subsubsection{Fink Macros} % % The \pkg{fink} option defines all \pkg{fink} package macros to use the ones provided % by this package. If the \pkg{fink} package was loaded beforehand the restoration % of these macros must be avoided at the end of this file % (\pkg{fink}s \Macro\InputIfFileExists was then used to load this package). % If the package was not loaded its version is set to a dummy value and its % options to this package options. If \pkg{fink} is attempted to be loaded later % it will trigger an package option clash if different option are used. % Otherwise it will be taken as already loaded and not loaded ``again''. % % \begin{macrocode} \ifcurrfile@fink \def\finkfile{\currfilename}% \def\finkdir{\currfiledir}% \def\finkpath{\currfilepath}% \def\finkbase{\currfilebase}% \def\finkext{\currfileext}% \@ifpackageloaded{fink}{% \def\fink@restore#1{}% }{% \@namedef{ver@fink.sty}{2011/01/09}% \expandafter\edef\csname opt@fink.sty\endcsname{% maindir=\currfile@maindir,mainext=\currfile@mainext }% }% \else \@ifpackageloaded{fink}{}{% \AtBeginOfPackageFile{fink}{% \PackageError{currfile}{The 'fink' package is now deprecated. % Load 'currfile' with the 'fink' option or see the upgrade guide in the manual}{}% }% }% \fi % \end{macrocode} % % \iffalse % % \fi % % \iffalse %<*currfile-abspath.sty> % \fi % \subsection{Sub-package \pkg{currfile-abspath}} % % \subsubsection{Package header} % % \begin{macrocode} \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{currfile-abspath}[% % % %<*DRIVER> 2099/01/01 develop % Provides absolute file paths, the parent working directory and the main file name] % \end{macrocode} % % % \subsubsection{Preliminary Code} % % Declare and init macros % \begin{macrocode} \newcommand*\thepwd{} \newcommand*\theabspath{} \newcommand*\theabsdir{} \newcommand*\themainfile{} % \end{macrocode} % Long, empty: % \begin{macrocode} \newif\ifcurrfile@abspath@windows % \end{macrocode} % % Ensure that the main file extension is defined and not empty. % \begin{macrocode} \providecommand\currfile@mainext{tex} \ifx\currfile@mainext\@empty \PackageError{currfile-abspath} {Empty main file extension is not supported}{}% \fi % \end{macrocode} % % \iffalse %\edef\themainfile{\jobname.\currfile@mainext} %\@onelevel@sanitize\themainfile % \fi % % % \begin{macro}{\currfile@abspath@noflswarning} % % \begin{macrocode} \def\currfile@abspath@noflswarning{% \PackageWarning{currfile-abspath} {The required recorder file (.fls) was not found.\MessageBreak Please compile with the '-recorder' option.\MessageBreak Note that MikTeX requires two compiler runs.\MessageBreak Occurred}% \global\let\currfile@abspath@noflswarning\relax \global\csname currfile@abspathfalse\endcsname }% % \end{macrocode} % \end{macro} % % % \subsubsection{Parent Working Directory (PWD)} % Opens the |\jobname.fls| file and checks for the `|PWD|' line (should be the very first one). % \begin{macro}{\getpwd} % \begin{macrocode} \newcommand\getpwd{% \begingroup \let\thepwd\@empty \IfFileExists{\jobname.fls}{% \openin\@inputcheck=\jobname.fls\relax \endlinechar\m@ne \loop \readline\@inputcheck to \line \@onelevel@sanitize\line \expandafter\currfile@checkpwd\line\relax\relax\relax\relax\relax \ifeof\@inputcheck\else \repeat \closein\@inputcheck } \currfile@abspath@noflswarning \edef\@tempa{% \def\noexpand\thepwd{\thepwd}% }% \expandafter \endgroup \@tempa } % \end{macrocode} % \end{macro} % % % \begin{macro}{\currfile@checkpwd} % Checks if the read line starts with `|PWD|' and stores the rest % of the line in \Macro\thepwd. The space after `|PWD|' is skipped by % \TeX\ when looking for |#4|. % \begin{macrocode} \def\currfile@checkpwd#1#2#3#4#5\relax{% \edef\@tempa{#1#2#3}% \edef\@tempb{PWD}% \@onelevel@sanitize\@tempb \ifx\@tempa\@tempb \edef\thepwd{#4#5/}% \def\@tempa{#4}% \def\@tempb{/}% \ifx\@tempa\@tempb \currfile@abspath@windowsfalse \else \currfile@abspath@windowstrue \fi \let\iterate\relax \fi } % \end{macrocode} % \end{macro} % % % \subsubsection{Absolute Path} % % \begin{macro}{\getabspath} % Opens the |\jobname.fls| file and checks for the first `|INPUT|' line % which lists the given filename. % \begin{macrocode} \newcommand\getabspath[1]{% \begingroup \edef\filename{#1}% \@onelevel@sanitize\filename% \let\theabspath\@empty \let\theabsdir\@empty \IfFileExists{\filename}{% \IfFileExists{\jobname.fls}{% \openin\@inputcheck=\jobname.fls\relax \endlinechar\m@ne \expandafter\currfile@abspath@defs\expandafter{\filename}% \readline\@inputcheck to \line \@onelevel@sanitize\line \expandafter\currfile@checkpwd\line\relax\relax\relax\relax\relax \loop \readline\@inputcheck to \line \@onelevel@sanitize\line \expandafter\currfile@abspath@getabspath\expandafter{\line}% \ifeof\@inputcheck\else \repeat \closein\@inputcheck }\currfile@abspath@noflswarning }{}% \edef\@tempa{% \def\noexpand\theabspath{\theabspath}% \def\noexpand\theabsdir{\theabsdir}% \def\noexpand\thepwd{\thepwd}% }% \expandafter \endgroup \@tempa } % \end{macrocode} % \end{macro} % % % \begin{macro}{\getmainfile} % Opens the |\jobname.fls| file and checks for the first `|INPUT|' line % which lists a file with the main file extension (usually `|.tex|'). % \begin{macrocode} \newcommand\getmainfile{% \begingroup \let\themainfile\@empty \IfFileExists{\jobname.fls}{% \openin\@inputcheck=\jobname.fls\relax \endlinechar\m@ne \readline\@inputcheck to \line \@onelevel@sanitize\line \expandafter\currfile@checkpwd\line\relax\relax\relax\relax\relax \loop \readline\@inputcheck to \line \@onelevel@sanitize\line \expandafter\currfile@abspath@getmainfile\expandafter{\line}% \ifeof\@inputcheck\else \repeat \closein\@inputcheck }% \currfile@abspath@noflswarning \edef\@tempa{% \def\noexpand\themainfile{\themainfile}% \def\noexpand\thepwd{\thepwd}% }% \expandafter \endgroup \@tempa } % \end{macrocode} % \end{macro} % % % \subsubsection{Line scanning macros for abspath and mainfile} % % % \begin{macro}{\currfile@abspath@testfname} % Test if directory is empty because the file is only listed by name, i.e. is in the PWD % or because the searched path was an absolute one and no further path elements are therefore listed % In the first case set \Macro\theabsdir to \Macro\thepwd, in the second case keep it empty. % \begin{macrocode} \def\currfile@abspath@testfname#1#2#3\relax{% \ifcurrfile@abspath@windows \def\@tempa{#2}% \def\@tempb{:}% \else \def\@tempa{#1}% \def\@tempb{/}% \fi \ifx\@tempa\@tempb\else \let\theabsdir\thepwd \fi } % \end{macrocode} % \end{macro} % % Change catcodes for `|INPUT|' to 12 (\emph{other}), because we need % them this way in the parameter lists of the following macros. % \begin{macrocode} \begingroup \catcode`I=12 \catcode`N=12 \catcode`P=12 \catcode`U=12 \catcode`T=12 % \end{macrocode} % % \begin{macro}{\currfile@abspath@defs} % Dynamically defines the macros needed to find the line with the requested file name. % \begin{macrocode} \gdef\currfile@abspath@defs#1{% \def\currfile@abspath@checkabspath ##1INPUT ##2#1\relax##3\relax##4\@nnil{% \ifx\@empty##4\@empty\else \def\theabsdir{##2}% \ifx\theabsdir\@empty \currfile@abspath@testfname#1\@empty\@empty\relax \fi \edef\theabspath{\theabsdir#1}% \let\iterate\relax \fi }% \def\currfile@abspath@getabspath##1{% \currfile@abspath@checkabspath##1\relax INPUT \@empty#1\relax{}\relax\@nnil }% } % \end{macrocode} % \end{macro} % % % \begin{macro}{\currfile@abspath@checkmainfile} % \begin{macro}{\currfile@abspath@getmainfile} % These two macros are defined with the main file extension given by % \Macro\currfile@mainext in their parameter texts. To insert the extension % with the correct catcode 12 two temporary auxiliary macros are utilized. % The |get| macro places the line content before the |check| macro with a suitable % fallback code so that the search text is always found and no \TeX\ error is raised. % The |check| macro tests if the fallback has occurred and stores the read path % if this was not the case. % \begin{macrocode} \def\@tempa#1{% \gdef\currfile@abspath@checkmainfile ##1INPUT ##2#1\relax##3\relax##4\@nnil{% \ifx\@empty##4\@empty\else \def\themainfile{##2#1}% \let\iterate\relax \fi }% \gdef\currfile@abspath@getmainfile##1{% \currfile@abspath@checkmainfile##1\relax INPUT \@empty#1\relax{}\relax\@nnil }% } \edef\@tempb{.\currfile@mainext} \@onelevel@sanitize\@tempb \expandafter\@tempa\expandafter{\@tempb} % \end{macrocode} % \end{macro} % \end{macro} % % Ends catcode changes: % \begin{macrocode} \endgroup % \end{macrocode} % % \iffalse % % \fi % % \iffalse % \fi % % \Finale \endinput