% \iffalse meta-comment % rubikrotation.dtx % % Authors: RWD Nickalls (dick@nickalls.org) % and Apostolos Syropoulos (asyropoulos@yahoo.com) % Copyright 2014 RWD Nickalls + A Syropoulos % % 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 licence is in % % http://www.latex-project.org/lppl.txt % %<*readme> % % The rubikrotation package provides a collection of LaTeX commands and macros % for the typesetting of Rubik cube configurations and rotation % sequences using the TikZ graphic language. % % Please report errors or suggestions for improvement to % % Dick Nickalls or Apostolos Syropoulos % % This package requires the basic TikZ package to be loaded already % % %<*driver> \listfiles \documentclass{ltxdoc} \IfFileExists{rubikrotation.sty}{\usepackage{rubikrotation}}{% \GenericWarning{rubikrotation.dtx}{Package file rubikrotation.sty not found. Documentation will be messed up!^^J (Generate rubikrotation.sty by (La)TeXing rubikrotation.ins, and then^^J process rubikrotation.dtx again)^^J}\stop }% \usepackage{ifpdf} \usepackage{url} %% for references \usepackage{graphicx} %% for the two pdf figs %%\OnlyDescription \EnableCrossrefs \CodelineIndex \CodelineNumbered \RecordChanges \setcounter{StandardModuleDepth}{1} \begin{document} \DocInput{rubikrotation.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % % % \CheckSum{302} % %%% \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 \~} % % % % \title{The \textsf{rubikrotation} package} % % \author{ % RWD Nickalls (dick@nickalls.org) \\ % A Syropoulos (asyropoulos@yahoo.com) % } % \date{This file describes version \RRfileversion, last revised \RRfiledate} % \maketitle % % \begin{abstract} % The \rubikrotation\ package is an extension for the % \textsf{rubikcube} package. It provides the \cmd{\RubikRotation} command which % processes on-the-fly a sequence of Rubik rotation moves (using the Perl script % \texttt{rubikrotation.pl}) and returns the new Rubik cube state. It implements % some basic checking of the Rubik state, and also offers a command for displaying % any errors (\cmd{\ShowRubikErrors}). % This package requires access to the \TeX\ \texttt{write18} facility by using the % \texttt{--shell-escape} commandline switch. % The \textsf{rubikrotation} package has been road-tested on a Microsoft % platform (with MikTeX and Strawberry Perl), on a Linux platform ({\TeX}Live and Mandriva), % and on OpenIndiana (a Solaris platform). % \end{abstract} % % % \bigskip % % \tableofcontents % % \section{Introduction} % % The \rubikrotation\ package is a dynamic extension to the \textsc{rubikcube} package. % It consists of a style option (\texttt{rubikrotation.sty}) and a % Perl script (\texttt{rubikrotation.pl}). % % The primary role of the \rubikrotation\ package is to implement on-the-fly Rubik % rotation sequences using the \cmd{\RubikRotation} command. Consequently, this % package requires the use of the \texttt{--shell-escape} switch to allow % commandline control of the Perl script, which is really the `engine' of this package. % The \textsf{rubikrotation} package has been road-tested on a Microsoft % platform (with MikTeX and Strawberry Perl\,\footnote{`Strawberry Perl' % (\texttt{http://strawberryperl.com}) is a free Perl % environment for MS Windows, designed to be as close as possible to the Perl % environment of Unix/Linux systems.}) % and on a Linux platform ({\TeX}Live and Mandriva). % % The following commands are made available by \texttt{rubikrotation.sty}. % \begin{quote} % \begin{verbatim} % \RubikRotation{} % \SaveRubikState % \CheckRubikState % \ShowRubikErrors %\end{verbatim} % \end{quote} % Note that if the Perl script is not located in the local working directory, then % some care is needed regarding placing it where your system can both find it and % also run it. In this case, the setting up of a simple one or two-line configuration % file may be useful or even necessary, depending on your system % (see section on `installation' below). % % % \section{Requirements} % % The \rubikrotation\ package requires the TikZ and the \textsc{rubikcube} packages. % % % \section{Installation} % % \subsection{Generating the files} % % Place the file \texttt{rubikrotation.zip} into a temporary directory, and unzip it. % This will generate the following files: % \begin{verbatim} % rubikrotation.ins % rubikrotation.dtx % rubikrotation.sty % rubikrotation.pl % rubikrotation.PDF % example-rot1.tex % example-rot1.PDF % example-rot2.tex % example-rot2.PDF %\end{verbatim} % The style option \texttt{rubikrotation.sty} is generated by running (pdf)\LaTeX\ on % the file \texttt{rubikrotation.ins} as follows: %\begin{verbatim} % pdflatex rubikrotation.ins %\end{verbatim} % The documentation file (\texttt{rubikrotation.pdf}) was generated using the following % steps: % \begin{verbatim} % pdflatex --shell-escape rubikrotation.dtx % pdflatex --shell-escape rubikrotation.dtx % makeindex -s gind.ist rubikrotation % makeindex -s gglo.ist -o rubikrotation.gls rubikrotation.glo % pdflatex --shell-escape rubikrotation.dtx %\end{verbatim} % % % \subsection{Placing the files} % \label{sec:placingfiles} % % Place the files either in the local working directory, or where your system % will find them. For a Linux system with a standard \TeX\ Directory Structure (TDS), then: % %\medskip %{\noindent}*.sty $\rightarrow$ % \texttt{/usr/local/texlive/texmf-local/tex/latex/local/rubikrotation/} %{\newline}*.cfg $\rightarrow$ % \texttt{/usr/local/texlive/texmf-local/tex/latex/local/rubikrotation/} %{\newline}*.pdf $\rightarrow$ \texttt{/usr/local/texlive/texmf-local/doc/rubikrotation/} %{\newline}*.pl $\rightarrow$ \texttt{/usr/local/bin/} % % \medskip % {\noindent}Finally, (depending on your system) update the \TeX\ file database using the % \texttt{texhash} command. % % \subsection{Configuration file} % \label{sec:configfile} % % A plane text configuration file with the name \texttt{rubikrotation.cfg} (if one exists) % will be read by the system. Such a file allows the user to % adjust (a)~the filename of the Perl script (\texttt{rubikrotation.pl}) % and (b)~the commandline code used by \texttt{rubikrotation.sty} for calling the % Perl script. This sort of fine-tuning is sometimes convenient, and even necessary % (depending on your system), for locating and running the Perl script. % For example, on some systems it maybe preferable to use a different \textsc{path}, % file name and/or a different commandline code to call the script. % % % \DescribeMacro{\rubikperlname} % \DescribeMacro{\rubikperlcmd} % The configuration file is essentially a convenient software vehicle for feeding some % additional \LaTeX\ code to the style option, and hence allow the contents of some % commands to be adjusted and/or fine-tuned. % For the \rubikrotation\ package there are two particular commands we may wish to adjust. % The first is that defining the filename of the Perl script, namely % \cmd{\rubikperlname}. The second is that defining the commandline call, % namely \cmd{\rubikperlcmd}. % The default definitions for these (detailed in Section~\ref{sec:usefulcommands}) % are as follows: %\begin{verbatim} % \newcommand{\rubikperlname}{rubikrotation.pl} % \newcommand{\rubikperlcmd}{perl \rubikperlname} %\end{verbatim} % % % For example, we might wish to test out a slightly modified Perl script, say % with the name \texttt{rubikrotationV3.pl}. In this case we simply create, % in the local working directory, a plane text configuration file % (called \texttt{rubikrotation.cfg}) which includes the following line: %\begin{verbatim} %\renewcommand{\rubikperlname}{rubikrotationV3.pl} %\end{verbatim} % % Alternatively, say, if the Perl script is being installed on a Linux platform, then % it would be standard to install it in the directory \texttt{/usr/local/bin}. % A convenient approach in this case, therefore, would be to indicate this new \textsc{path} % by including the following line in the configuration file: %\begin{verbatim} %\renewcommand{\rubikperlname}{/usr/local/bin/rubikrotation.pl} %\end{verbatim} % and, since this would then be an essentially permanent feature, we would then % place the configuration file with the style option in the % \texttt{texmf-local/...} directory as described in section~\ref{sec:placingfiles} % (placing files). Note that in this case, we have \textit{not} made the Perl script % `executable', since the default commandline code is effectively % \texttt{perl \rubikperlname}, and this works just as it is. % % However, if the Perl script \textit{is} made `executable', then % a different commandline code will have to be used instead. % For example, suppose the Perl script is made executable and renamed to just % \texttt{rubikrotation} (ie with no filename extension), then we now have to % omit the `perl' from the default commandline. Consequently, we now need to make % two command changes, which we implement by including the following % two lines in the configuration file: %\begin{verbatim} %\renewcommand{\rubikperlname}{/usr/local/bin/rubikrotation} %\renewcommand{\rubikperlcmd}{\rubikperlname} %\end{verbatim} % % % \section{Usage} % % Load the packages \texttt{rubikcube.sty} % and \texttt{rubikrotation.sty} in the \TeX\ file \textit{after} loading % the TikZ package, as follows: % \begin{verbatim} % \usepackage{tikz} % \usepackage{rubikcube,rubikrotation} %\end{verbatim} % and run (pdf)\LaTeX\ using the \texttt{--shell-escape} commandline switch % (see following section). % % % \subsection{Enabling the \TeX\ `shell' facility} % % In order to enable the \TeX\ `write18' facility (so it can run the Perl script) % we will need to invoke (pdf)\LaTeX\ using the \texttt{--shell-escape} switch; say, as follows. % \begin{verbatim} % pdflatex --shell-escape filename.tex %\end{verbatim} % In practice, it is probably most convenient to run this via a % bash/batch file---something like the following, both of which % automatically show the graphic output: % \begin{verbatim} % pdflatex --shell-escape filename.tex % xpdf filename.pdf %\end{verbatim} % or % \begin{verbatim} % latex --shell-escape filename.tex % dvips filename.dvi % gv filename.ps %\end{verbatim} % % % \subsection{Test files} % % Two example tex files (which demonstrate the use of the package commands) are % included in the package, namely: % \begin{verbatim} % example-rot1.tex (shows 5 worked examples) % example-rot2.tex (is a `test' file for experimenting with different commands) %\end{verbatim} % These need to be run using \texttt{--shell-escape} switch; for example: % \begin{verbatim} % pdflatex --shell-escape example-rot1.tex %\end{verbatim} % If the files give unexpected results, check-out the log file to see if the system % has had any difficulties finding files etc. % % % % \section{Commands} % % The \textit{only} commands which \textit{must} be used inside a TikZ picture % environment are the \cmd{\Draw...} commands (these are all provided by % the \textsc{rubikcube} package), although most commands can be placed % inside a TikZ environment if necessary. However, using commands outside the environment % generally offers maximum flexibility, since the effects of commands used inside % a TikZ picture environment are `local' to that picture environment, and are not % therefore accessable outside the environment. % % The only command which must \textit{not} % be inside a TikZ environment is the \cmd{\ShowRubikErrors} command % (see the notes on this command below). % % % \subsection{\cmd{\RubikRotation} command} % % \DescribeMacro{\RubikRotation} % The \cmd{\RubikRotation}\marg{comma separated sequence} command processes % a comma separated sequence of rotations, and returns the final state. % For example, if we wanted to see the effect of the rotations % \textbf{R, R, L, U, D} on a solved Rubik cube, we could use the % following commands. % \begin{verbatim} % \begin{tikzpicture}[scale=0.7] % \RubikCubeSolved % \RubikRotation{R2,L,U,D} % \DrawRubikCubeRU % \end{tikzpicture} %\end{verbatim} % The \cmd{\RubikRotation} command results in \LaTeX\ first writing % the current Rubik state to a text file (\texttt{rubikstate.dat}), % and then calling the Perl program \texttt{rubikrotation.pl}. The Perl % program then reads the current rubik state from the (\texttt{rubikstate.dat}) % file, performs all the rotations, and then writes the new rubik state % (and any error messages) to the file \texttt{rubikstateNEW.dat}, % which is then input on-the-fly by the \LaTeX\ file and used to generate % some graphic image of the cube. % % Note that the \cmd{\RubikRotation} command can be either inside % or before the Tikz picture environment. In fact only the `\cmd{\Draw...}' % commands (from the \textsc{rubikcube} package) actually need to be inside % a TikZ picture environment. Consequently this makes for great flexibility. % % \subsubsection{Arguments prefixed with a *} % % If any of the comma separated arguments (strings) is prefixed with a * it is % not processed as a rotation. This feature therefore allows a string argument % to be used as a label, which can be very useful. % For example, we can use the * feature to label the following % sequence as generating the so-called % `sixspot' configuration (described by Reid): % \begin{verbatim} % \RubikRotation{*sixspot,U,Dp,R,Lp,F,Bp,U,Dp} %\end{verbatim} % Alternatively, and probably more conveniently, we could simply use % the name `sixspot' to define a new command, as follows (which therefore allows % one to store lots of different rotation sequences by name alone): % \begin{verbatim} % \newcommand{\sixspot}{U,Dp,R,Lp,F,Bp,U,Dp} %\end{verbatim} % With this `newcommand' we are now able to generate the graphic (sixspot cube) % much more easily using the following code: % % \medskip % % \begin{minipage}{6cm} % \begin{verbatim} % \begin{tikzpicture}[scale=0.7] % \RubikCubeSolved % \RubikRotation{\sixspot} % \DrawRubikCubeRU % \end{tikzpicture} %\end{verbatim} % \end{minipage} % \begin{minipage}{3.4cm} % \centering % \ifpdf % \includegraphics[height=3cm]{Rubikrot_doc_figA.pdf} % \else % \fi % \end{minipage} % % % \medskip % % In practice, it is quite useful to go one step further and include % the \texttt{*} label feature as well in the newcommand, as follows: % \begin{verbatim} % \newcommand{\sixspot}{*sixspot,U,Dp,R,Lp,F,Bp,U,Dp} %\end{verbatim} % since this has the great advantage of making the particular % rotation sequence identified by the label-name visible in the log file. % For example, the following command, which uses the rotations \textbf{x2} % and \textbf{y} to initially rotate the `solved' cube before applying % the `sixspot' sequence of rotations, % \begin{verbatim} % \RubikRotation{x2,y,\sixspot} %\end{verbatim} % will then be represented in the log file as % \begin{verbatim} % ...command=rotation,x2,y,*sixspot,U,Dp,R,Lp,F,Bp,U,Dp % ...arguments passed to `rotation' sub = x2 y *sixspot U Dp R Lp F Bp U Dp (n= 11) % ...rotation x OK (= rrR + rrSr + rrLp) % ...rotation x OK (= rrR + rrSr + rrLp) % ...rotation y OK (= rrU + rrSu + rrDp) % ...*sixspot is a label OK % ...rotation U OK % ...rotation Dp OK % ...rotation R OK % ...rotation Lp OK % ...rotation F OK % ...rotation Bp OK % ...rotation U OK % ...rotation Dp OK %\end{verbatim} % In this way, several named rotation sequences can be easily distinguished % in the log file from adjacent rotation commands. % % % \subsubsection{Random rotations} % % The \cmd{\RubikRotation} command can also be used to scramble the % cube using a random sequence of rotations. If the first argument % is the lowercase word `random' \textsc{and} the second argument % is an integer $n$, ($1\leq n \leq 200$), then a random sequence % of $n$ rotations will be performed; otherwise a default value % of 50 is used (for example, if the second argument is not an integer). % If $n > 200$ then the value $n=200$ will be used. % % For example, the following commands will scramble a solved cube using a % sequence of 120 random rotations, and display the state in the form of % a semi-flat cube. % % \medskip % % \begin{minipage}{5.5cm} %\begin{verbatim} % \RubikCubeSolved% % \RubikRotation{random,120}% % \begin{tikzpicture}[scale=0.5] % \DrawRubikCubeFlat % \end{tikzpicture} %\end{verbatim} % \end{minipage} % \begin{minipage}{3.4cm} % \centering % \ifpdf % \includegraphics[height=4cm]{Rubikrot_doc_figB.pdf} % \else % \fi % \end{minipage} % % Note that in this particular example (above), only % the \cmd{\Draw..} command is inside the TikZ picture environment---a useful % method when more than one figure is being drawn. Note also, that when such % commands are outside a TikZ picture environment, they should have a % trailing \% to stop additional white space being included. % % \medskip % % The procedure is that all the possible rotations are first allocated % a different number (integer) and collected into an array. Then a % sequence of $n$ randomised numbers is generated and mapped to the array % to generate the associated sequence of random rotations. % The sequence used is detailed in the \texttt{.log} file. % % % \subsection{\cmd{\SaveRubikState}} % % \DescribeMacro{\SaveRubikState} % The command \cmd{\SaveRubikState}\marg{filename} saves the state (configuration) % of the Rubik cube to the file \marg{filename} in the standard \cmd{\RubikFace...} % format. Consequently such a file can then be input at a later stage so it can be % drawn or processed in the usual way (inside the TikZ picture environment). % % For example, the following commands would save the so-called `sixspot' configuration % (generated by the rotations \textbf{U, Dp, R, Lp, F, Bp, U, Dp}) % to the file \verb!sixspot.tex!. %\begin{verbatim} % \RubikCubeSolved% % \RubikRotation{*sixspot,U,Dp,R,Lp,F,Bp,U,Dp}% % \SaveRubikState{sixspot.tex}% %\end{verbatim} % The form of the file \verb!sixspot.tex! will then be as follows---the % filename (commented out) is automatically written to the top of the % file for convenience. %\begin{verbatim} % % filename: sixspot.tex % \RubikFaceUp{O}{O}{O}{O}{W}{O}{O}{O}{O}% % \RubikFaceDown{R}{R}{R}{R}{Y}{R}{R}{R}{R}% % \RubikFaceLeft{Y}{Y}{Y}{Y}{B}{Y}{Y}{Y}{Y}% % \RubikFaceRight{W}{W}{W}{W}{G}{W}{W}{W}{W}% % \RubikFaceFront{G}{G}{G}{G}{O}{G}{G}{G}{G}% % \RubikFaceBack{B}{B}{B}{B}{R}{B}{B}{B}{B}% %\end{verbatim} % We can therefore access and draw this configuration later, when required, % simply by inputting the file as follows: %\begin{verbatim} %\begin{tikzpicture} % \input{sixspot.tex} % \DrawRubikCubeFlat %\end{tikzpicture} %\end{verbatim} % % % \subsection{\cmd{\CheckRubikState} command} % % \DescribeMacro{\CheckRubikState} % Since it is easy to inadvertently define an invalid Rubik cube % (eg enter an invalid number of, say, yellow cubies), this command % checks the current colour state of all the cubies % of a 3x3x3 Rubik cube, and shows the number of cubies of each colour. % An ERROR: code is issued if the number of cubies having a given colour exceeds 6. % The results are written to the the \texttt{.log} file, and displayed under % the graphic if the \cmd{\ShowRubikErrors} command is used. % % One can check the current Rubik state (for errors) by issuing the command %\begin{verbatim} % \CheckRubikState% %\end{verbatim} % Note that such a check is implemented automatically with each \cmd{\RubikRotation} command. % % % % % \subsection{\cmd{\ShowRubikErrors} command} % % \DescribeMacro{\ShowRubikErrors} % % Any errors which arise can be made visible using the % command \cmd{\ShowRubikErrors}. % This command places a copy of the `error' file (\texttt{rubikstateERRORS.dat}) % underneath the image so you can see any errors if there are any---all this % detail can also be found in the \texttt{.log} file. % % Consequently, this command must be placed \textit{after} a TikZ picture % environment---it cannot be used inside a TikZ environment. In fact this command % is probably best placed at the end of the document (if there are several such % environments), where it will reveal all rotation errors generated while % processing the document. % % % \section{Files generated} % % % Whenever the \cmd{\RubikRotation} or \cmd{\CheckRubikState} commands are used, % three small temporary plain text files for holding data are generated as % follows (they are refreshed with each \LaTeX\ run, and are not actively deleted). % \begin{itemize} % \item \LaTeX\ writes Rubik state data to the file \texttt{rubikstate.dat}. % % \item Perl reads the file \texttt{rubikstate.dat} and then writes % the new rubik state to the file \texttt{rubikstateNEW.dat}. % % \item Perl also writes error data to the file \texttt{rubikstateERRORS.dat}. % A copy of this file is displayed under the image when the command % \cmd{\ShowRubikErrors} is used after (outside) the TikZ picture environment. % % \end{itemize} % % % \section{General overview} % % When \LaTeX\ loads the \rubikrotation\ package the following steps are implemented. % \begin{itemize} % % % \item[1.] A check is made to see if \texttt{fancyvrb.sty} is loaded: if not % then this package is loaded if it is available (this package is required % for inputting the file \texttt{rubikstateERRORS.dat}). % % \item[2.] A check is made to see if a configuration file (\texttt{rubikrotation.cfg}) % exists: if so then this file is input. % % \item[3.] The text file \texttt{rubikstateNEW.dat} is overwritten (if it exists): % otherwise the file is created (this prevents an `old' file being used by \LaTeX). % % \item[4.] The plain text file \texttt{rubikstateERRORS.dat} is created. % This file collects error messages generated by the Perl script. % % \end{itemize} % % % When a \cmd{\RubikRotation} command is processed it first writes the current % colour configuration of each face (the `rubik state') to the temporary file % \texttt{rubikstate.dat} (to be read by the Perl script \texttt{rubikrotation.pl}). % The \cmd{\RubikRotation} command also appends the keyword ` % \texttt{checkrubik}' as well as a copy of the string of Rubik rotations. % It then calls the Perl script \texttt{rubikrotation.pl}. % % For example, if we use the command \cmd{\RubikCubeSolved} % followed by the command \verb!\RubikRotation{U,D,L,R}! then the associated % \texttt{rubikstate.dat} file would be as follows: % \begin{verbatim} % % filename: rubikstate.dat % up,W,W,W,W,W,W,W,W,W % down,Y,Y,Y,Y,Y,Y,Y,Y,Y % left,B,B,B,B,B,B,B,B,B % right,G,G,G,G,G,G,G,G,G % front,O,O,O,O,O,O,O,O,O % back,R,R,R,R,R,R,R,R,R % checkstate % rotation,U,D,L,R %\end{verbatim} % Alternatively, if the \cmd{\RubikRotation} command was % \verb!\RubikRotation{random, 45}! then the last line written to the file % would be the string `\texttt{rotation,random,45}' % A \cmd{\CheckRubikState} command triggers the same sequence of events except % no `rotation' line is written. % % The action of the Perl program is controlled by the keywords (first argument of % each line) associated with each line of the file \texttt{rubikstate.dat}. % When control passes to Perl, the Perl program starts by loading the % rubikstate (prompted by the keywords up, down, % left, right, front, back). Next the program performs % some basic checks (prompted by the key word `checkstate'), and then it processes % the sequence of Rubik rotations (prompted by the keyword `rotation'). % If, instead, the second argument of the `rotation' string is the keyword `random', and % provided this is followed by a valid integer, say $n$, then the Perl program performs % a sequence of $n$ random rotations. % Finally, the Perl program writes the final `rubikstate' to the text file % \texttt{rubikstateNEW.dat}. All error messages are written to the % text file \texttt{rubikstateERRORS.dat} and also to the \LaTeX\ log file. % % Control then reverts to \LaTeX\ which then inputs the file % \texttt{rubikstateNEW.dat}. If there are more \cmd{\RubikRotation} commands % then this cycle repeats accordingly. Eventually a `\texttt{Draw...}' command % of some form is reached and the final rubikstate is drawn in a TikZ picture % environment. % % If the TikZ picture environment is followed by a \cmd{\ShowRubikErrors} command, % then a `verbatim' copy of the \texttt{rubikstateERRORS.dat} file is displayed % immediately under the graphic. Once the graphic is error-free, then the % \cmd{\ShowRubikErrors} can be removed or commented out. % % % % ^^A ================================================== % \StopEventually{\PrintIndex} % % % % \section{The code (\texttt{rubikrotation.sty})} % % \subsection{Package heading} % % \begin{macrocode} %<*rubikrotation> \def\RRfileversion{2.0}% \def\RRfiledate{2014/01/20}% \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{rubikrotation}[\RRfiledate\space (v\RRfileversion)] % \end{macrocode} % % % {\noindent}The package requires rubikcube.sty. Do not automatically % load rubikcube.sty since this makes it difficult to errorcheck new % versions (for the moment at least). % \begin{macrocode} \@ifpackageloaded{rubikcube}{}{% \typeout{---rubikrotation requires the rubikcube package.}% }% % \end{macrocode} % % % % {\noindent}The \rubikrotation\ package requires access to the fancyvrb package % for the \cmd{\VerbatimInput\{\}} command which we use for inputting and displaying % the error file. % \begin{macrocode} \@ifpackageloaded{fancyvrb}{}{% \typeout{---rubikrotation requires the fancyvrb package% for VerbatimInput{} command.}% \RequirePackage{fancyvrb}} % \end{macrocode} % \medskip % % %\subsection{Some useful commands} % \label{sec:usefulcommands} % \begin{macro}{\rubikrotation} % First we create a suitable logo % \begin{macrocode} \newcommand{\rubikrotation}{\textsf{rubikrotation}} % \end{macrocode} % \end{macro} % % % % \begin{macro}{\@comment} % \begin{macro}{\@commentone} % We require access to the percent character so we can write comments % in files, including the log file. % We first define percentchar for the write statement % (From Abrahams PW, Berry K and Hargreaves KA (1990), ``TeX for the Impatient'', p~292; % available from: CTAN.../info/impatient/) % \begin{macrocode} {\catcode`\%=12 \global\def\rubikpercentchar{%}}% \newcommand{\@comment}{\rubikpercentchar\rubikpercentchar\space}% \newcommand{\@commentone}{\rubikpercentchar}% % \end{macrocode} % \end{macro} % \end{macro} % % % \begin{macro}{\@print} %% We need a simple print command for writing comments to a file. % \begin{macrocode} \newcommand{\@print}[1]{\immediate\write\outfile{#1}} % \end{macrocode} % \end{macro} % % % % \begin{macro}{\rubikperlname} % This holds the name of the Perl-5 script . It is used later to check % whether the Perl script exists or not. A plain text configuration file % \verb!rubikrotation.cfg! can be used to change the default name of the % Perl script using a renewcommand. % \begin{macrocode} \newcommand{\rubikperlname}{rubikrotation.pl} % \end{macrocode} % \end{macro} % % % \begin{macro}{\rubikperlcmd} % This holds the commandline code for calling the the Perl script. % A plain text configuration file \verb!rubikrotation.cfg! can be used to % change the default commandline code using a renewcommand. % \begin{macrocode} \newcommand{\rubikperlcmd}{perl \rubikperlname} % \end{macrocode} % \end{macro} % % %\subsection{Configuration file} % If a config file exists (rubikrotation.cfg) then input it here, % ie \textit{after} defining the \cmd{\rubikperlname} and \cmd{\rubikperlcmd} % commands and \textit{before} creating the \texttt{rubikstateERRORS.dat} file. % \begin{macrocode} \typeout{---checking for config file (rubikrotation.cfg)...} \IfFileExists{rubikrotation.cfg}{% \input{rubikrotation.cfg}% }{\typeout{---no config file available}% }% % \end{macrocode} % % % \subsection{Clean file rubikstateNEW.dat} % % {\noindent}We need to clean any existing (old) rubikstateNEW.dat file, % since if the TeX shell switch is accidentally not used then Perl will % not be CALLed and hence this file will not be renewed % (ie an `old' image may be used). % \begin{macrocode} \typeout{---cleaning file rubikstateNEW.dat}% \newwrite\outfile% \immediate\openout\outfile=rubikstateNEW.dat% \@print{\@comment rubikstateNEW.dat (by TeX)}% \immediate\closeout\outfile% % \end{macrocode} % % % \subsection{rubikstateERRORS.dat} % % {\noindent}The \rubikrotation\ package requires the Perl program. % We first open the file \texttt{rubikstateERRORS.dat} which is used % by the Perl program (\texttt{rubikrotation.pl}) for writing its error % messages to. This file is accessed and displayed by the command % \cmd{\ShowRubikErrors}. % % \textsc{important note}: this file is created fresh each time LaTeX is run % and hence the Perl program only appends data to it during the \LaTeX\ run, % so this file just grows until either it is destroyed or recreated---a useful % feature to keep since the file accumulates all error messages as the % .tex file is processed. % We can't make the Perl program create the file since the Perl program is only % CALLed if we use a \cmd{\RubikRotation} or \cmd{\CheckRubikState} % command (which we may not!)---so it has to be created (opened) here. % % The following code first opens the file, and then checks to see if % the Perl program (\cmd{\rubikperlname}) exists; % if the Perl prog does exist then all is OK, % otherwise we write an error message to the file. % \begin{macrocode} \typeout{---creating file rubikstateERRORS.dat}% \newwrite\outfile% \immediate\openout\outfile=rubikstateERRORS.dat% \@print{\@comment rubikstateERRORS.dat}% \typeout{---checking for Perl script \rubikperlname...} \IfFileExists{\rubikperlname}{% \typeout{---\rubikperlname\space exists OK}% }{\typeout{** ERROR: cannot find Perl program \rubikperlname}% \@print{\@comment ** ERROR: cannot find Perl program \rubikperlname}}% \immediate\closeout\outfile% % \end{macrocode} % % % \subsection{Setting up a newwrite and file-access for new files} % % Having set up all the primary files, we now need to set up a newwrite for % all subsequent files openings (eg for rubikstate.dat and saving % to arbitrary filenames by the \cmd{\SaveRubikState} command). Otherwise, we % can easily exceed the LaTeX limit of 15. From here-on \TeX\ will use openout7 % when opening and writing to files. We will implement new openings using % the command \verb!\@openstatefile! (see below). % \begin{macrocode} \typeout{---setting up newwrite for rubikrotation to use...}% \newwrite\outfile% % \end{macrocode} % % % \begin{macro}{\@openstatefile} % \begin{macro}{\@closestatefile} % We also need commands for easy file opening and and closing % for new instances of the file \texttt{rubikstate.dat} etc. % Note that for this we are therefore using the same outfile number as set up % by the \verb!\newwrite...! above. % \begin{macrocode} \newcommand{\@openstatefile}{\immediate\openout\outfile=rubikstate.dat} \newcommand{\@closestatefile}{\immediate\closeout\outfile} % \end{macrocode} % \end{macro} % \end{macro} % % % \subsection{Saving the Rubik state} % % \begin{macro}{\@printrubikstate} % This command writes the Rubik configuration (state) to % the file \texttt{rubikstate.dat}, and is used by the \cmd{\RubikRotation} command. % The file \texttt{rubikstate.dat} is read by the Perl program, and represents % the state on which the new \cmd{\RubikRotation} command acts. % Note that we append the key-word \texttt{checkstate} to the end of the file % in order to trigger the Perl program to implement its \texttt{checkstate} subroutine. % \begin{macrocode} \newcommand{\@printrubikstate}{% \@print{up,\Ult,\Umt,\Urt,\Ulm,\Umm,\Urm,\Ulb,\Umb,\Urb}% \@print{down,\Dlt,\Dmt,\Drt,\Dlm,\Dmm,\Drm,\Dlb,\Dmb,\Drb}% \@print{left,\Llt,\Lmt,\Lrt,\Llm,\Lmm,\Lrm,\Llb,\Lmb,\Lrb}% \@print{right,\Rlt,\Rmt,\Rrt,\Rlm,\Rmm,\Rrm,\Rlb,\Rmb,\Rrb}% \@print{front,\Flt,\Fmt,\Frt,\Flm,\Fmm,\Frm,\Flb,\Fmb,\Frb}% \@print{back,\Blt,\Bmt,\Brt,\Blm,\Bmm,\Brm,\Blb,\Bmb,\Brb}% \@print{checkstate}% } % \end{macrocode} % \end{macro} % % % \subsection{RubikRotation command} % % \begin{macro}{\RubikRotation} % The \cmd{\RubikRotation}\marg{comma separated sequence} % command (a)~writes the current Rubik state to the file % \texttt{rubikstate.dat}, and then (b)~CALLs the Perl program. % It also writes comments to the data file and also to the log file. % \begin{macrocode} \newcommand{\RubikRotation}[1]{\IfFileExists{\rubikperlname}{% \typeout{---NEW rotation command------------------}% \typeout{---command = RubikRotation{#1}}% \typeout{---Perl script \rubikperlname\space exists OK}% \typeout{---writing current Rubik state to file rubikstate.dat}% \@openstatefile% open data file \@print{\@comment filename: rubikstate.dat}% \@printrubikstate% \@print{rotation,#1}% \@closestatefile% close data file \typeout{---running Perl script}% \immediate\write18{\rubikperlcmd}% \typeout{---inputting NEW datafile (from Perl)}% \input{rubikstateNEW.dat}% \typeout{-----------------------------------------}% }{\typeout{** ERROR: \rubikperlname\space does not exist}% }} % \end{macrocode} % \end{macro} % % % \subsection{ShowRubikErrors command} % % \begin{macro}{\ShowRubikErrors} % This command inputs the file \texttt{rubikstateERRORS.dat}. % \begin{macrocode} \newcommand{\ShowRubikErrors}{% \typeout{---ShowRubikErrors: inputting file rubikstateERRORS.dat}% \VerbatimInput{rubikstateERRORS.dat}} % \end{macrocode} % \end{macro} % % % \subsection{CheckRubikState command} % % \begin{macro}{\CheckRubikState} % This command triggers the Perl program to implement % some simple error checking of the Rubik configuration (state). % This command (a)~writes the current Rubik state to the file % \texttt{rubikstate.dat}, and then (b)~CALLs the Perl program. % It also writes comments to the data file and also to the log file.. % \begin{macrocode} \newcommand{\CheckRubikState}{\IfFileExists{\rubikperlname}{% \typeout{---NEW check command------------------}% \typeout{---command = CheckRubikState}% \typeout{---Perl script \rubikperlname\space exists OK}% \typeout{---writing current Rubik state to file rubikstate.dat}% \@openstatefile% opens data file \@print{\@comment filename: rubikstate.dat}% \@printrubikstate% \@closestatefile% close data file \typeout{---running Perl script}% \immediate\write18{\rubikperlcmd}% \typeout{---inputting NEW datafile (from Perl)}% \input{rubikstateNEW.dat}% \typeout{-----------------------------------------}% }{\typeout{** ERROR: \rubikperlname\space does not exist}% }} % \end{macrocode} % \end{macro} % % % % \subsection{SaveRubikState macro} % % \begin{macro}{\SaveRubikState} % The command \cmd{\SaveRubikState}\marg{filename} saves the Rubik state % to a file. Note that in order to actually write a LaTeX % command to a file without a trailing space one must use the % \cmd{\string} command (see the book ``TeX by Topic'', p~238). % Note that this macro uses the two internal commands \cmd{\Rubik@comment} % and \cmd{\Rubik@print}. \#1 is the output filename. % We use several \cmd{\typeout} commands to write to the log file. % \begin{macrocode} \newcommand{\SaveRubikState}[1]{% \typeout{---NEW save command------------------}% \typeout{---command = SaveRubikState{#1}}% \typeout{---saving Rubik state data to file #1}% \immediate\openout\outfile=#1% \@print{\@comment filename: #1\@commentone}% \@print{\string\RubikFaceUp% {\Ult}{\Umt}{\Urt}{\Ulm}{\Umm}{\Urm}{\Ulb}{\Umb}{\Urb}\@commentone}% \@print{\string\RubikFaceDown% {\Dlt}{\Dmt}{\Drt}{\Dlm}{\Dmm}{\Drm}{\Dlb}{\Dmb}{\Drb}\@commentone}% \@print{\string\RubikFaceLeft% {\Llt}{\Lmt}{\Lrt}{\Llm}{\Lmm}{\Lrm}{\Llb}{\Lmb}{\Lrb}\@commentone}% \@print{\string\RubikFaceRight% {\Rlt}{\Rmt}{\Rrt}{\Rlm}{\Rmm}{\Rrm}{\Rlb}{\Rmb}{\Rrb}\@commentone}% \@print{\string\RubikFaceFront% {\Flt}{\Fmt}{\Frt}{\Flm}{\Fmm}{\Frm}{\Flb}{\Fmb}{\Frb}\@commentone}% \@print{\string\RubikFaceBack% {\Blt}{\Bmt}{\Brt}{\Blm}{\Bmm}{\Brm}{\Blb}{\Bmb}{\Brb}\@commentone}% \immediate\closeout\outfile% \typeout{-----------------------------------------}% }% % \end{macrocode} % \end{macro} % % % -------------------------- % End of this package % -------------------------- % \begin{macrocode} % % \end{macrocode} % % % % % \Finale % \endinput