% \iffalse meta-comment %% Copyright (c) 2010-2011 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. %% %% $Id$ % \fi % % \iffalse %<*driver> \ProvidesFile{currfile.dtx}[2011/09/18 v0.5 DTX file for currfile package] \documentclass{ydoc}[2011/03/19] \usepackage{currfile}[2011/09/18] \usepackage{ifpdf} \usepackage{booktabs} \usepackage{hyperref} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{currfile.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % \CheckSum{344} % % \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.} % % \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-online.de} % \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 name with multiple dots and the \cs{input@path} feature used by some packages like \pkg{import}. % \end{abstract} % % \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}|. % % 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. % % More detailed information can be found in the implementation section \ref{sec:impl} if required. % % \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 two options \opt{mainext} and \opt{maindir} which can be used to provide the extension 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. To provide support for the macros defined by the \pkg{fink} package (see section~\ref{sec:fink}) a \pkg{fink} option exists. % % \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 header} % % \begin{macrocode} \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{currfile}[2011/01/09 v0.4 Current input file name and path] % \begin{macrocode} % % \subsection{Options} % % \begin{macrocode} \RequirePackage{kvoptions} \SetupKeyvalOptions{family=currfile,prefix=currfile@} \@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}} \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} % % % \subsection{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} % % % \subsection{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 \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}% \endgroup % \expandafter\gdef\expandafter\dindent\expandafter{\dindent\space}% % \message{^^JDEBUG: \dindent\empty Entering file '\currfilename' ^^J }% } % \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{% \openin\@inputcheck\@filef@und\relax \ifeof\@inputcheck \expandafter\@tfor \expandafter\@tempb \expandafter:\expandafter=\input@path\do{% \openin\@inputcheck\@tempb\@filef@und\relax \ifeof\@inputcheck\else \edef\@filef@und{\@tempb\@filef@und}% \@break@tfor \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} % % \subsection{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} \def\currfile@push{% \xdef\currfile@stack{% {\currfiledir}% {\currfilebase}% {\currfileext}% \currfile@stack }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\currfile@pop} % \begin{macrocode} \def\currfile@pop{% % \message{^^JDEBUG: \dindent\empty Leaving file '\currfilename' ^^J }% \ifx\currfile@stack\empty \PackageWarning{currfile}{File stack underflow!}% \global\let\currfile@stack\currfile@stackinit \fi \expandafter\currfile@pop@\currfile@stack\relax \relax\relax\relax % \message{^^JDEBUG: \dindent\empty Restoring file '\currfilename' ^^J }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\currfile@pop@} % \begin{macrocode} \def\currfile@pop@#1#2#3#4\relax{% \gdef\currfiledir{#1}% \gdef\currfilebase{#2}% \gdef\currfileext{#3}% \xdef\currfilename{\currfilebase\ifx\currfileext\empty\else.\currfileext\fi}% \xdef\currfilepath{\currfiledir\currfilename}% \gdef\currfile@stack{#4}% % \expandafter\expandafter\expandafter\gdef % \expandafter\expandafter\expandafter\dindent % \expandafter\expandafter\expandafter{\expandafter\@gobble\dindent}% } % \end{macrocode} % \end{macro} % % \iffalse % \def\dindent{} % \fi % % \begin{macro}{\currfile@stack} % \begin{macro}{\currfile@stackinit} % Place \Macro\jobname values on stack and use this as init value. % \begin{macrocode} \def\currfile@stack{} \currfile@set{\currfile@maindir\jobname.\currfile@mainext} \currfile@push \let\currfile@stackinit\currfile@stack % \end{macrocode} % \end{macro} % \end{macro} % % % \subsection{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{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} % % % \subsection{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 % % \Finale \endinput