% \iffalse meta-comment % % Copyright 2007-2008 by Will Robertson % % Distributable under the LaTeX Project Public License, % version 1.3c or higher (your choice). The latest version of % this license is at: http://www.latex-project.org/lppl.txt % % This work is "maintained" (as per LPPL maintenance status) % by Will Robertson. % % This work consists of the file inversepath.dtx % and the derived files inversepath.sty and inversepath.pdf. % % %<*internalbatchfile> \begingroup % %<*batchfile> \input docstrip.tex \keepsilent \preamble _______________________________________ Copyright (C) 2007-2008 Will Robertson License information appended. \endpreamble \postamble Copyright (C) 2007-2008 by Will Robertson Distributable under the LaTeX Project Public License, version 1.3c or higher (your choice). The latest version of this license is at: http://www.latex-project.org/lppl.txt This work is "maintained" (as per LPPL maintenance status) by Will Robertson. This work consists of the file \jobname.dtx and the derived files \jobname.sty and \jobname.pdf. \endpostamble \askforoverwritefalse \generate{\file{\jobname.sty}{\from{\jobname.dtx}{package}}} % %\endbatchfile %<*internalbatchfile> \generate{\file{\jobname.ins}{\from{\jobname.dtx}{batchfile}}} \nopreamble\nopostamble \generate{\file{README.txt}{\from{\jobname.dtx}{readme}}} \generate{\file{dtx-style.sty}{\from{\jobname.dtx}{dtx-style}}} \endgroup \immediate\write18{mv README.txt README} \immediate\write18{makeindex -s gind.ist -o \jobname.ind \jobname.idx} \immediate\write18{makeindex -s gglo.ist -o \jobname.gls \jobname.glo} % % %<*driver> \documentclass{ltxdoc} \EnableCrossrefs \CodelineIndex \RecordChanges %\OnlyDescription \usepackage{dtx-style} \begin{document} \DocInput{\jobname.dtx} \end{document} % % %<*readme> _______________________ The INVERSEPATH package v0.2 Calculate inverse relative paths in LaTeX. E.g., from "/one/two/three.tex" or "/one/two/" to "../../". Could be easily converted to Plain TeX if I wasn't lazy. ______________ Will Robertson 2007-2008 % % % \fi % % \GetFileInfo{\jobname.sty} % \CheckSum{0} % \makeatletter % % \title{Relative inverse path calculation} % \author{Will Robertson} % \date{\filedate \qquad \fileversion} % % \maketitle % % \noindent % \pkg{inversepath} is a simple package to calculate inverse relative paths. % For example, when writing to an auxiliary file in a subdirectory % (or a series of nested subdirectories), it can be useful to know % how to get back to the original file. % % If the absolute path of the original file is specified, this package % can also calculate the relative path of a file in parent or sibling % directories. % % \bigskip % {\centering\noindent % \cmd\inversepath\marg{path} --- prints the inverse of \meta{path}.\par} % {\centering\noindent % \cmd{\inversepath*}\marg{path} --- calculates the inverse of \meta{path}.\par} % % \bigskip % {\raggedleft\noindent % \cmd\absolutepath\marg{abs.\ path} --- specifies the absolute % path for calculating parent/sibling relative paths.\par} % % \noindent Regular usage: % \begin{example}{} % \inversepath*{one/two/three/four.tex}\par % \ip@inversepath\par % \ip@lastelement\par % \ip@directpath % \end{example} % % \noindent Expands to \meta{empty} if the relative path is the same directory: % \begin{example}{} % [\inversepath*{one.tex}]\par % \ip@inversepath\par % \ip@lastelement\par % [\ip@directpath] % \end{example} % % \noindent For `back-relative' paths, the absolute path needs to be specified: % \begin{example}{} % \absolutepath{/xyz/here/there/everywhere/} % % \inversepath*{../../one/two/three.tex}\par % \ip@inversepath\par % \ip@lastelement\par % \ip@directpath % \end{example} % % % \StopEventually{} % % \part{\pkg{\jobname} implementation} %\iffalse %<*package> %\fi % This is the package. % \begin{macrocode} \ProvidesPackage{inversepath} [2008/07/31 v0.2 Inverse relative paths] % \end{macrocode} % \begin{macro}{\inversepath} % \darg{Path to invert} % \begin{macrocode} \newcommand\inversepath{% \@ifstar{\inversepath@star}{\inversepath@nostar}} \newcommand\inversepath@star[1]{% % \end{macrocode} % \cmd\ip@jobpath\ is preserved to restore after truncation for % back-relative paths. % \begin{macrocode} \let\ip@origjobpath\ip@jobpath \let\ip@directpath\@empty \let\ip@inversepath\@empty \ip@strippath#1/\@nil/% \let\ip@jobpath\ip@origjobpath} \newcommand\inversepath@nostar[1]{% \inversepath@star{#1}% \let\ip@jobpath\ip@origjobpath} % \end{macrocode} % \changes{v0.2}{2008/07/31}{Starred form to not print the output. What was I thinking?} % \end{macro} % \begin{macro}{\absolutepath} % \darg{Absolute path used for calculating parent/sibling relative paths.} % \begin{macrocode} % macro to define the absolute path of where we are: \newcommand\absolutepath[1]{\def\ip@jobpath{#1}} % \end{macrocode} % \end{macro} % For \cs{ifx} comparisons for relative back-paths: % \begin{macrocode} \def\ip@literaldotdot{..} % \end{macrocode} % \begin{macro}{\ip@strippath} % This is the macro that does all the work. % It takes input like |a/b/c/...x/y/z/\@nil/| and % expands to \cmd\ip@inversepath, the inverse path of \cmd\ip@directpath\ % (|a/b/.../y/|). % \begin{macrocode} \def\ip@strippath#1/#2/{% \ifx\@nil#2\relax % \end{macrocode} % If input is |z/\@nil/| then we've reached the end: % \begin{macrocode} \def\ip@lastelement{#1}% \else % \end{macrocode} % If we're in the middle of the slash-separated list; % build up \cmd\ip@directpath: % \begin{macrocode} \edef\ip@directpath{\ip@directpath#1/} \def\@tempa{#1}% \ifx\@tempa\ip@literaldotdot \unless\ifdefined\ip@jobpath \PackageError{inversepath} {No absolute path specified} {You must declare the file path of the main file with \protect\absolutepath{} to be able to resolve back-relative paths}% \fi % \end{macrocode} % If the path is a back-relative path, things are more complex. % to get the inverse of |../|, we need the absolute file path. % this requires using \cmd\ip@strippath\ on \cmd\ip@jobpath\ itself, so save out % our current definitions of \cmd\ip@directpath/\cmd\ip@inversepath\ and % (re-)initialise them: % \begin{macrocode} \let\ip@olddirectpath\ip@directpath \let\ip@oldinversepath\ip@inversepath \let\ip@directpath\@empty \let\ip@inversepath\@empty % \end{macrocode} % \cmd\ip@strippath on \cmd\ip@jobpath\ gives us the topmost directory in % \cmd\ip@lastelement: % \begin{macrocode} \expandafter\ip@strippath\ip@jobpath\@nil/ \let\@tempa\ip@lastelement % \end{macrocode} % \cmd\ip@jobpath is now truncated so \cmd\iplastelement\ in the next % iteration is one folder up the hierarchy. % \begin{macrocode} \let\ip@jobpath\ip@directpath % \end{macrocode} % Now we restore everything to how it was: (this would be better % with grouping, but I don't want to use \cmd\global) % \begin{macrocode} \let\ip@directpath\ip@olddirectpath \let\ip@inversepath\ip@oldinversepath % \end{macrocode} % Build up the inverse path: % \begin{macrocode} \ifx\@tempa\@empty \PackageError{inversepath} {Absolute path too shallow to resolve such a deep relative path} {You're trying to go back more directories than you have!} \fi \edef\ip@inversepath{\@tempa/\ip@inversepath}% \else % \end{macrocode} % If the path is a simple relative path, % then build up the inverse path by prepending |../|: % \begin{macrocode} \edef\ip@inversepath{../\ip@inversepath}% \fi % \end{macrocode} % Iterate: % \begin{macrocode} \def\@tempa{\ip@strippath#2/}% \expandafter\@tempa \fi} % \end{macrocode} % \end{macro} % %\iffalse % %\fi % % %\iffalse %<*dtx-style> % \begin{macrocode} \ProvidesPackage{dtx-style} \errorcontextlines=999 \def\@dotsep{1000} \setcounter{tocdepth}{2} \setlength\columnseprule{0.4pt} \renewcommand\tableofcontents{\relax \begin{multicols}{2}[\section*{\contentsname}]\relax \@starttoc{toc}\relax \end{multicols}} \setcounter{IndexColumns}{2} \renewenvironment{theglossary} {\small\list{}{} \item\relax \glossary@prologue\GlossaryParms \let\item\@idxitem \ignorespaces \def\pfill{\hspace*{\fill}}} {\endlist} \usepackage[svgnames]{xcolor} \usepackage{amsmath,array,bm,booktabs,calc,enumitem,fancyvrb,graphicx,ifthen,longtable,refstyle,subfig,topcapt,varioref,\jobname,url} \usepackage[sc,osf]{mathpazo} \linespread{1.069} % A bit more space between lines \frenchspacing % Remove ugly extra space after punctuation \definecolor{niceblue}{rgb}{0.2,0.4,0.8} \newenvironment{example}[1] {\VerbatimEnvironment \def\Options{#1}% \begin{VerbatimOut}[gobble=2]{\examplefilename}} {\end{VerbatimOut}\relax \typesetexample} \fvset{formatcom=\color{niceblue}} \DefineShortVerb{\|} \def\theCodelineNo{\textcolor{niceblue}{\sffamily\tiny\arabic{CodelineNo}}} \let\examplesize\normalsize \let\auxwidth\relax \newlength\examplewidth\newlength\verbatimwidth \newlength\exoutdent \newlength\exverbgap \setlength\exverbgap{1em} \setlength\exoutdent{-0.15\textwidth} \newsavebox\verbatimbox \edef\examplefilename{\jobname.example} \newcommand\typesetexample{\relax \smallskip \noindent \begin{minipage}{\linewidth} \color{niceblue} \hrulefill\par \edef\@tempa{[gobble=0,fontsize=\noexpand\small,\Options]}% \begin{lrbox}{\verbatimbox}\relax \expandafter\BVerbatimInput\@tempa{\examplefilename}% \end{lrbox} \begin{list}{}{\setlength\itemindent{0pt} \setlength\leftmargin\exoutdent \setlength\rightmargin{0pt}}\item \ifx\auxwidth\relax \setlength\verbatimwidth{\wd\verbatimbox}% \else \setlength\verbatimwidth{\auxwidth}% \fi \begin{minipage}[c]{\textwidth-\exoutdent-\verbatimwidth-\exverbgap} \catcode`\%=14\centering\linespread{1.6}\input\examplefilename\relax \end{minipage}\hfill \begin{minipage}[c]{\verbatimwidth} \usebox\verbatimbox \end{minipage} \end{list} \par\noindent\hrulefill \end{minipage} \smallskip} \newcommand*\setverbwidth[1]{\def\auxwidth{#1}} \newcommand*\name[1]{{#1}} \newcommand*\pkg[1]{\textsf{#1}} \newcommand*\feat[1]{\texttt{#1}} \newcommand*\opt[1]{\texttt{#1}} \newcommand*\note[1]{\unskip\footnote{#1}} \let\latin\textit \def\eg{\latin{e.g.}} \def\Eg{\latin{E.g.}} \def\ie{\latin{i.e.}} \def\etc{\@ifnextchar.{\latin{etc}}{\latin{etc.}\@}} \def\STIX{\textsc{stix}} \def\MacOSX{Mac~OS~X} \def\ascii{\textsc{ascii}} \def\OMEGA{Omega} \def\CTAN{\textsc{ctan}} \newcounter{argument} \g@addto@macro\endmacro{\setcounter{argument}{0}} \newcommand*\darg[1]{% \stepcounter{argument}% {\ttfamily\char`\#\theargument~:~}#1\par\noindent\ignorespaces} \newcommand*\doarg[1]{% \stepcounter{argument}% {\ttfamily\makebox[0pt][r]{[}\char`\#\theargument]:~}#1\par\noindent\ignorespaces} \def\codeline{\par\hspace{2\parindent}} \newcommand\unichar[2]{\textsc{\MakeLowercase{u+#1: #2}}} \setlength\parindent{2em} % \end{macrocode} % %\fi % % \typeout{*************************************************************} % \typeout{*} % \typeout{* To finish the installation you have to move the following} % \typeout{* file into a directory searched by XeTeX:} % \typeout{*} % \typeout{* \space\space\space inversepath.sty} % \typeout{*} % \typeout{*************************************************************} % \endinput