diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/rubik/rubikrotation.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/rubik/rubikrotation.dtx | 987 |
1 files changed, 987 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/rubik/rubikrotation.dtx b/Master/texmf-dist/source/latex/rubik/rubikrotation.dtx new file mode 100644 index 00000000000..8ffc824499a --- /dev/null +++ b/Master/texmf-dist/source/latex/rubik/rubikrotation.dtx @@ -0,0 +1,987 @@ +% \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 +%</readme> +% +%<*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} +%</driver> +% \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} +%</rubikrotation> +% \end{macrocode} +% +% +% +% +% \Finale +% +\endinput + + + + + |