diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/crosswrd |
Initial commit
Diffstat (limited to 'macros/latex/contrib/crosswrd')
-rw-r--r-- | macros/latex/contrib/crosswrd/README | 81 | ||||
-rw-r--r-- | macros/latex/contrib/crosswrd/crosswrd.dtx | 1596 | ||||
-rw-r--r-- | macros/latex/contrib/crosswrd/crosswrd.ins | 35 | ||||
-rw-r--r-- | macros/latex/contrib/crosswrd/crosswrd.pdf | bin | 0 -> 239279 bytes |
4 files changed, 1712 insertions, 0 deletions
diff --git a/macros/latex/contrib/crosswrd/README b/macros/latex/contrib/crosswrd/README new file mode 100644 index 0000000000..e395d67cca --- /dev/null +++ b/macros/latex/contrib/crosswrd/README @@ -0,0 +1,81 @@ +Copyright 1989 Brian Hamilton Kelly +updated for LaTeX2e by Frank Mittelbach 96/12/06 +upgraded with many new features by Dirk Laurie 10/02/01 + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either version 1.3 +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.3 or later is part of all distributions of LaTeX +version 2005/12/01 or later. + +This work has the LPPL maintenance status `unmaintained'. + +This work consists of the files crosswrd.dtx, crosswrd.ins and README +and the derived files test0.tex, test1.tex, test2.tex, grid0.tex, +grid1.tex, grid2.tex and crosswrd.sty. + +Introduction +============ + +This distribution contains the crosswrd package by Brian Hamilton +Kelly updated to run with LaTeX2e the standard LaTeX distribution, +and extended in several ways, one of which Brian himself envisaged +but did not live to complete. Brian died on 15th September 2005. + +Frank Mittelbach's comments and instructions (slightly updated) +follow after the hline. + +I added support for several new features, including barred grids, +mixed barred/blocked grids, rectangular grids, automatic clue number +checking and more, and composed a hard cryptic in the Azed/Mephisto +style demonstrating those. + +For the next few months I am willing to support the package. + +Enjoy! + +Dirk Laurie 10/02/01 + +PS If you can solve the hard thematic puzzle, let me know. I'd like +to add the names of the first few solvers to this README. + dee pee ell at ess you en dot ay see dot zed ay + +------------------------------------------------------------------- + +I did change a bit of the coding to allow typesetting an unlimited +number of crosswords and also added two new commands + +\DOWNtext and \ACROSStext + +that contain the heading texts for the clues. Thus this will allow you +to use the macros in a language environment other than English. + +Installation +============ + +to unpack run + latex crosswrd.ins + +to install place crosswrd.sty into dir searched by LaTeX + +to produce documentation (after unpacking) run + latex crosswrd.dtx +until there is no "Rerun LaTeX" message + +to produce examples (after unpacking) run + latex test0 +or + latex test1 +or + latex test2 + + +enjoy + +frank + +ps i do not support that package it is offered as is. + +Frank Mittelbach 96/12/06 diff --git a/macros/latex/contrib/crosswrd/crosswrd.dtx b/macros/latex/contrib/crosswrd/crosswrd.dtx new file mode 100644 index 0000000000..741e54f8e8 --- /dev/null +++ b/macros/latex/contrib/crosswrd/crosswrd.dtx @@ -0,0 +1,1596 @@ +% \iffalse meta-comment +%% crosswrd.dtx +%% Copyright 1989 Brian Hamilton Kelly +%% updated for LaTeX2e by Frank Mittelbach 96/12/06 +%% Updated for LPPL 1.3c or later by Clea F. Rees (for Frank Mittelbach), 2008/10/06. +%% +%% Upgraded with many new features by Dirk Laurie 2010/02/01 +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% 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.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `unmaintained'. +% +% This work consists of the files crosswrd.dtx, crosswrd.ins and README +% and the derived files crosswrd.sty, test0.tex, test1.tex, grid0.tex and grid1.tex. +% \fi +% \iffalse +%<*dtx> + \ProvidesFile{crosswrd.dtx} +%</dtx> +%<+package>\NeedsTeXFormat{LaTeX2e}[1995/12/01] +%<+package>\RequirePackage{ifthen} +%<+package>\ProvidesPackage{crosswrd} +%<*dtx,package> +% \fi +% \ProvidesFile{crosswrd.dtx} + [2010/02/01 v3.0 Generating crosswords (BHK,DPL)] +% +% \iffalse +%</dtx,package> +%<*driver> +\documentclass{ltxdoc} +\usepackage{crosswrd} +\begin{document} +\GetFileInfo{crosswrd.dtx} +\DocInput{crosswrd.dtx} +\end{document} +%</driver> +% \fi +% +% \CheckSum{813} +% +% \let\ifBigTeX=\iftrue ^^A Change this in the obvious fashion if an +% ^^A enlarged (>75k maxmem) version of TeX is available +% \changes{v2.7}{89/10/16}{Conditional compilation for variant +% \protect\TeX's} +% +% \DoNotIndex{\@input,\@ixpt,\@listi,\@ne,\@setsize,\@starttoc,\@writefile} +% \DoNotIndex{\abovedisplayshortskip,\abovedisplayskip,\advance} +% \DoNotIndex{\afterassignment,\begin,\belowdisplayshortskip} +% \DoNotIndex{\belowdisplayskip,\bf,\bgroup,\centerline,\closeout,\csname} +% \DoNotIndex{\def,\edef,\egroup,\else,\end,\endcsname,\endgraf,\endlist} +% \DoNotIndex{\errhelp,\errmessage,\expandafter,\fi,\filedate,\fileversion} +% \DoNotIndex{\hbox,\hspace,\hss,\if,\iffalse,\ifnum,\ifx,\ignorespaces} +% \DoNotIndex{\immediate,\input,\item,\itemsep,\ixpt,\jobname,\labelsep} +% \DoNotIndex{\labelwidth,\leavevmode,\leftmargin,\let,\line,\list,\loop} +% \DoNotIndex{\lowercase,\m@ne,\makebox,\makelabel,\meaning,\newcount} +% \DoNotIndex{\next,\noexpand,\openout,\parsep,\put} +% \DoNotIndex{\relax,\repeat,\rm,\romannumeral,\rule,\sloppy,\space,\string} +% \DoNotIndex{\strut,\tensf,\the,\tiny,\topsep,\typein,\typeout,\unitlength} +% \DoNotIndex{\uppercase,\vtop,\z@} +% +% \changes{v2.1}{89/04/27}{Total revision of documentation part} +% \changes{v2.3}{89/05/17}{Used raw \protect\TeX\protect\space counters} +% \changes{v2.5}{89/09/01}{Final revisions for publication} +% \changes{v2.6}{89/10/13}{Consistent indentation of {\tt\protect\bslash +% def}s} +% \changes{v2.9}{07/12/19}{Variable dimensions and type sizes, does barred +% grids, does rectangular grids, tests label compatibility, complete +% rewrite of grid population code} +% \changes{v3.0}{10/02/01}{LPPL copyright notice included} +% +% \title{Some Macros to Draw Crosswords\thanks{This file is \fileversion, +% dated \filedate}} +% \author{B Hamilton Kelly\thanks{Especial thanks to my colleague Niel +% Kempson for many helpful suggestions, and to Frank Mittelbach of the +% Johannes Gutenberg University of Mainz, who saved me two pages of code!} +% \\ Extensions by Dirk Laurie} +% \maketitle +% \begin{abstract} +% The {\sf crossword} environment is intended to be used to typeset +% crossword puzzles for use in newsletters, etc. +% \end{abstract} +% +% \vspace*{3pt}\hrule +% +% +% \tableofcontents +% +% \addtocontents{toc}{\protect\begin{multicols}{2}} +% +% \listoffigures +% +% \ifBigTeX +% \else +% \addtocontents{lof}{\protect\begin{multicols}{2}} +% \fi +% +% \[ \vbox{\hrule width 4cm} \] +% +% \begin{multicols}{2}[\section{Introduction}] +% +% As a small diversion from the statistics of computer availability, lists +% of new software, and the like, Computer Centre Newsletters often include a +% crossword for the amusement of their readers.\footnote{That at RMCS has a +% bottle of wine as a prize!} +% +% The macros presented in this document provide a \LaTeX{} method of +% typesetting these, and also assist the composer to ensure that the +% ``grid'' all goes together correctly. That is to say, checks +% are made that crossing lights have the same letter where they cross, +% lights starting at the same square have the same clue number, +% and clue numbers are in sequence from 1 upwards when reading +% from top left to bottom right. + +% The grid generated can be the more +% usual form, with black squares separating the ``lights'' which receive the +% answers to the clues, or the {\sl Mephisto/Azed\/} type of grid, +% in which only thicker grid lines separate the lights, or even +% a mixture of these. The user need not specify which type of grid +% is to be used, since they are both described by the same simple rule: +% a bar is drawn between every pair of adjacent +% light squares that do not belong to the same light. +% +% A sample crossword appears as Figure~\ref{crossword:1}; I've left the +% grid blank for those who want some intellectual exercise: those who don't +% can cheat by reading the source listing at the end of this +% article! +% +% +% \DescribeEnv{crossword} +% The whole crossword, including the \verb+\clue+ commands ({\it q.v}.), +% is bracketed within the {\sf crossword} environment. The user may +% specify one optional and must specify two required parameters: +% \begin{description} +% \item[\meta{gridrows}] The number of rows +% in the rectangular grid. If supplied, it must be enclosed in +% square brackets. It may be omitted if the number of rows +% equals the number of columns. +% \item[\meta{gridcols}] The number of columns +% in the rectangular grid. +% \item[\meta{visible}] This controls whether the answers are to be +% ``filled in''; obviously of no use for publication, but useful whilst +% composing the crossword. If the parameter provided is the letter `{\tt +% Y}', then the answers will be typeset; if `{\tt N}' then the lights +% will be left blank. Any other value\footnote{The lower-case letters +% `{\tt y}' and `{\tt n}' are also recognized} provided for this +% parameter will cause \LaTeX{} to input a yes/no answer by interaction +% with the user. +% \end{description} +% +% \DescribeEnv{crossword*} +% An analogous environment is provided especially for typesetting a smaller +% version of a grid showing, for example, ``Last Month's Solution''. In +% this of course, the answers {\em always\/} appear, and the clues are not +% printed. Again it takes three parameters, the first optional: +% \begin{description} +% \item[\meta{gridrows, gridcols}] As before, these specify the number +% of squares in the two axes. +% \item[\meta{header\_text}] Some text which will be set (in {\bf bold}) +% above the completed grid. +% \end{description} +% \ifBigTeX +% \changes{v2.5a}{89/09/08}{Put the {\protect\sf crossword*} in-line} +% \changes{v2.7}{89/10/16}{Conditional compilation for variant +% \protect\TeX's} +% Here is an example of the {\sf crossword*} +% environment: +% {\centering +% \begin{crossword*}{15}{Last month's solution} +% \MakePercentComment \input{grid0} \MakePercentIgnore +% \end{crossword*}} +% \else +% Figure~\ref{crossword:2} shows an example of the {\sf crossword*} +% environment. +% \fi +% +% \DescribeMacro\clue +% Within the body of these environments appear a succession of \verb+\clue+ +% commands; each of these takes a total of seven (!) parameters: +% \begin{description} +% \item[\meta{clue\_number}] The number of the light on the grid, for +% example \verb+{17}+. See~\ref{clue-numbers} below for details of how +% more complex specifications may be given for multiple lights. +% \item[\meta{Across/Down}] This parameter {\em must\/} be either the +% letter `{\tt A}' or `{\tt D}', in upper-case. +% \item[\meta{col\_number}] The $x$-coordinate of the first square of the +% light. The left-most column of the grid is numbered 1. +% \item[\meta{row\_number}] The $y$-coordinate of the first square of the +% light. The top-most row is numbered 1. +% \item[\meta{answer}] The answer to the clue (or that part of it which +% appears in the light numbered \meta{clue\_number}). Traditionally +% in a completed grid, this is a +% string of upper-case letters, but spaces in between are silently ignored, +% lower case letters are equally OK, and some other characters such as +% question mark and fullstop are useful as placeholders in an +% uncompleted grid. No hyphens or apostrophes, though. +% \item[\meta{text}] The text of the clue itself. If you want to use any +% \LaTeX{} macros in this text, such as \verb+\dots+, each such macro must +% be preceded by \verb+\noexpand+. This includes such macros as \verb+\&+, +% to produce an explicit ampersand. +% \item[\meta{help}] Anything to appear after the text, in parentheses; +% this will most usually be used for giving the length of the answer, such +% as ``7'' or ``2,6,3-3''. Also used when the text of the clue is +% associated with another light when this parameter may say something like +% ``see 14d''. If this parameter is left \emph{absolutely empty}, +% not merely blank, i.e.\ \verb+{}+, the clue (if any) +% will not be printed at all. +% \end{description} +% +% \subsection{Customizing the layout} +% Some definitions made when entering the {\sf crossword} environment +% may be overridden by the user inside the environment. +% \begin{verbatim} +% \unitlength 6mm +% \def\Preamble{} +% \def\cluewidth{70mm} +% \let\numbersize\tiny +% \let\cluesize\ninept +% \def\barwidth{0.1} +% \end{verbatim} +% These refer respectively to size of grid cells, text to be set between +% the diagram and the clues, +% width of clue columns, typesize of numbers in grid, type size of +% clues, and width of bars in \verb+\unitlength+s. +% +% If you override +% \verb+\cluesize+ by a \LaTeX\ size command +% like \verb+\normalsize+, you will probably feel that there is too much +% vertical space between the clues. The only good solution is to +% write your own macro by adapting the definition of \verb+\ninept+ +% given below. +% + +% \subsection{How to Specify Clue Numbers}\label{clue-numbers} +% +% Sometimes the solution to one clue is split amongst a number of +% lights. To cover this eventuality, provide a \verb+\clue+ for {\em +% each\/} of the lights involved, with the solution to that light {\em +% alone\/} given as \meta{answer}. All except the \verb+\clue+ +% corresponding to the first light of the solution should have a null +% \meta{text}, and the \meta{help} parameter might be something like +% ``see 7d''. +% +% \changes{v2.4}{89/08/15}{Support for empty help field} +% If you wish to omit any further reference +% to the clue number (the usual practice when the current clue +% applies to consecutive lights, or in hard cryptics), +% leave the \meta{help} field totally empty. +% +% The \verb+\clue+ for the first light of the solution +% should provide the {\em entire\/} clue as its \meta{text}, and the +% \meta{help} might say something like ``7,3-3''. The \meta{clue\_number} +% field should consist of the number of that light, followed immediately +% by the text required to describe the other lights, separated from it by +% some non-digit character, for example, a space. +% +% +% \end{multicols} +% +% \begin{figure*}[tp] +% \begin{crossword}{15}{N} +% \MakePercentComment \input{grid1} \MakePercentIgnore +% \end{crossword} +% \caption{A Sample Crossword}\label{crossword:1} +% \end{figure*} +% +% For example, suppose the clue ``Bill's desired outcome?'', has the +% solution `ACT OF PARLIAMENT' which is to go into lights 9d and 13a. +% Then\footnote{note the {\tt\string\noexpand} before the {\tt\string\rm} +% for the {\tt\string\&}} +% \begin{verbatim} +% \clue{13}{A}{5}{1}{PARLIAMENT}{}{see 9d} +% \clue{9 {\noexpand\rm\&} 13a}{D}{1}{10}{ACT OF}% +% {Bill's desired outcome?}{3,2,10} +% \end{verbatim} +% will produce\begin{description} +% \item[13] (see 9d) +% \end{description} amongst the ACROSS clues, and\begin{description} +% \item[9 {\rm\&} 13a] Bill's desired outcome? (3,2,10) +% \end{description} amongst the DOWN % clues +% +% \ifBigTeX +% \else +% \begin{figure}[hbtp] +% \begin{crossword*}{15}{Last month's solution} +% \input{grid-0} +% \end{crossword*} +% \caption{An example of the {\sf crossword*} +% environment}\label{crossword:2} +% \end{figure} +% \fi +% + +% \StopEventually{\PrintIndex +% \PrintChanges +% \ifBigTeX +% \else +% \addtocontents{lof}{\protect\end{multicols}}% +% \fi +% \addtocontents{toc}{\protect\end{multicols}}} +% +% \section{Definition of the Macros} +% +% +% \begin{macro}{\ninept} +% \begin{macro}{\@listi} +% We define a new 9pt font size for setting clues. +% This command also defines suitable +% parameters for list environments set in this size of type. +% +% \begin{macrocode} +%<*package> +\def\ninept{\@setsize\ninept{11pt}\ixpt\@ixpt + \abovedisplayskip 8.5pt plus 3pt minus 4pt + \belowdisplayskip \abovedisplayskip + \abovedisplayshortskip \z@ plus2pt + \belowdisplayshortskip 4pt plus2pt minus 2pt + \def\@listi{\itemsep 0pt + \parsep \z@ plus 1pt + \topsep 4pt plus 2pt minus 2pt +}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Counters and Lengths} +% \begin{macro}{\ifnumberit} +% \begin{macro}{\numberittrue} +% \begin{macro}{\numberitfalse} +% +% The {\sf crossword} environment draws a grid (with black and white +% squares); each light into which a clue's answer is to be written has +% to be numbered, and this number will be typeset (using \verb+\tiny+) in +% the top-left corner of the first square of the light. +% +% This style option also provides the {\sf crossword*} environment, which +% is intended to be used to produce ``last month's solution'' in a smaller +% grid. There is insufficient room for clue numbers to appear on the grid +% in this mode, so \verb+\ifnumberit+ is used to indicate whether the +% numbers should be set. +% +% \begin{macrocode} +\newif\ifnumberit +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\gridr@ws} +% \begin{macro}{\gridc@ls} +% \changes{v2.3}{89/05/17}{Use a raw \protect\TeX\protect\space counter} +% \begin{macro}{\p@rsize} +% \begin{macro}{\p@csize} +% \changes{v2.3}{89/05/17}{Use a raw \protect\TeX\protect\space counter} +% \changes{v2.9}{07/12/05}{Define more counters to allow rectangular grids.} +% The counters \verb+\gridr@ws+, \verb+\gridc@ls+, are used to hold the +% width of the grid, as the number of squares in each direction. +% +% To prevent too much run-time arithmetic, the counters \verb+\p@rsize+, +% \verb+\p@csize+ are set to be one count higher than \verb+\gridc@ls+, +% \verb+\gridr@ws+. +% \begin{macrocode} +\newcount{\gridr@ws}\newcount{\gridc@ls} +\newcount{\p@rsize}\newcount{\p@csize} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\Down} +% \changes{v2.3}{89/05/17}{Use a raw \protect\TeX\protect\space counter} +% \begin{macro}{\Across} +% \changes{v2.3}{89/05/17}{Use a raw \protect\TeX\protect\space counter} +% As we move around the grid, determining whether squares are black or +% white, we utilize the counters \verb+\Across+ and \verb+\Down+ to keep track +% of our location. +% +% \begin{macrocode} +\newcount{\Down} +\newcount{\Across} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Reading and Writing the Clues} +% +% \begin{macro}{\tf@acr} +% \begin{macro}{\tf@dwn} +% \begin{macro}{\OpenClueFiles} +% \changes{v2.1}{89/04/27}{Now uses {\tt\protect\bslash @starttoc}} +% \changes{v2.1}{89/04/27}{and {\tt\protect\bslash @writefile}} +% Whilst we are determining the appearance of the grid, we copy the text of +% each of the clues to an auxiliary file, so that the latter may later be +% read back to generate the clues themselves after the grid has been +% printed. +% +% This macro opens a new file, with file extension \verb+.acr+, and puts +% into it the commands necessary to typeset the Across clues. It also +% opens a \verb+.dwn+ file, which is similarly filled with the Down clues. +% +% Next paragraph is no longer true. I changed the coding to allow more than +% 6 crosswords to be used in one document. Using the approach outlined below +% the system would run out of write channels pretty soon. (FMi) +% +% [ These files are created in the same manner as table-of-contents +% ({\tt.toc}) files, etc; thus \LaTeX{} will create file ``handles'' with +% names \verb+\tf@acr+ and \verb+\tf@dwn+. However, that would ordinarily +% attempt to {\em read\/} the given file first, and also might defer the +% actual opening; therefore, we start a new group in which we redefine +% \LaTeX's \verb+@input+ command and \TeX's \verb+\openout+ primitive. ] +% +% \changes{v2.8b}{96/12/06}{Use two global write channels (FMi)} +% \begin{macrocode} +\newwrite\tf@acr +\newwrite\tf@dwn +\def\OpenClueFiles{% + \immediate\openout \tf@acr \jobname.acr\relax + \immediate\openout \tf@dwn \jobname.dwn\relax +% \end{macrocode} +% Here's the preliminary material that gets inserted into the {\tt.acr} file. +% \changes{v2.8a}{96/07/22}{Removed string from \cs{@writefile} arg (FMi)} +% \changes{v2.8a}{96/07/22}{Make clue column texts accessible (FMi)} +% \begin{macrocode} + \@writefile{acr}{\begin{minipage}[t]{\cluewidth}}% + \@writefile{acr}{ \centerline{\textbf{\ACROSStext}}}% + \@writefile{acr}{ \sloppy}% + \@writefile{acr}{ \cluesize}% + \@writefile{acr}{ \begin{ClueList}}% +% \end{macrocode} +% Whilst something similar goes into the {\tt.dwn} file. +% \begin{macrocode} + \@writefile{dwn}{\begin{minipage}[t]{\cluewidth}}% + \@writefile{dwn}{ \centerline{\textbf{\DOWNtext}}}% + \@writefile{dwn}{ \sloppy}% + \@writefile{dwn}{ \cluesize}% + \@writefile{dwn}{ \begin{ClueList}}} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro} +% +% \begin{macro}{\ACROSStext} +% \changes{v2.8a}{96/07/22}{Make clue column texts accessible (FMi)} +% \begin{macro}{\DOWNtext} +% \changes{v2.8a}{96/07/22}{Make clue column texts accessible (FMi)} +% You may (e.g.\ if the crossword is not in English) prefer to change +% the column text headers. +% \begin{macrocode} +\newcommand\ACROSStext{ACROSS} +\newcommand\DOWNtext{DOWN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\CloseClueFiles} +% \changes{v2.1}{89/04/27}{Now uses {\tt\protect\bslash @writefile}} +% After the grid has been printed, we can close the ``clues'' files; these +% will later be read back in (by the \verb+\endcrossword+ command) to set +% the text of the clues below the grid. +% +% Before closing, we insert the material that completes the two {\sf +% ClueList} environments; firstly across\dots +% \changes{v2.8a}{96/07/22}{Removed string from \cs{@writefile} arg (FMi)} +% \begin{macrocode} +\def\CloseClueFiles{% + \@writefile{acr}{ \end{ClueList}}% + \@writefile{acr}{\end{minipage}}% +% \end{macrocode} +% Then for the down clues. +% \begin{macrocode} + \@writefile{dwn}{ \end{ClueList}}% + \@writefile{dwn}{\end{minipage}}% +% \end{macrocode} +% Now we can close those files, and make them ``invisible'' if someone +% tries to write to them. +% \begin{macrocode} + \immediate\closeout\tf@acr \let\tf@acr\relax + \immediate\closeout\tf@dwn \let\tf@dwn\relax + \endgraf +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Tabulating the Clues} +% The auxiliary files contain the texts of the clues, each given as an +% \verb+\item+ for the {\sf ClueList} environment. This is similar to a +% {\sf description} list, except that overlong labels run on into the text +% rather than sticking out to the left. +% +% \begin{macro}{\ClueList} +% \begin{macro}{\ClueListLabel} +% This sets up the {\sf ClueList} environment, and defines the appearance of +% the label. +% +% \begin{macrocode} +\def\ClueListlabel#1{\hspace\labelsep {\bf #1}\hss} +\def\ClueList{\list{}{\labelwidth\leftmargin + \advance \labelwidth by -\labelsep + \let\makelabel\ClueListlabel}} +\let\endClueList\endlist +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\PrintClues} +% The following macro reads in the two files (of Across and Down clues), +% and sets them alongside each other, separated by a vertical rule. Clues +% are set in the style of the {\sf ClueList} environment. +% +% \begin{macrocode} +\def\PrintClues{% + \centerline{% + \begin{tabular}{ c | c } + \@input{\jobname.acr} + & + \@input{\jobname.dwn} + \end{tabular} + }\endgraf +} +% \end{macrocode} +% \end{macro} +% +% \section{Creating the Grid} +% The remaining commands are concerned with creating (and, optionally, +% populating) the crossword grid. +% +% \begin{macro}{crossword} +% \begin{macro}{\c@ls} +% +% The {\sf crossword} environment takes three parameters: {\em viz}.~the +% number of rows (optional, may be omitted if the grid is square) and +% columns of the matrix, and the indication of whether the grid is to include +% the answers. (If the latter is not Y or N, \LaTeX\ will request it +% interactively.) The macro \verb+\c@ls+ is a communication mechanism. +% +% \begin{macrocode} +\newenvironment{crossword}[3][\c@ls]{% + \def\c@ls{#2} +% \end{macrocode} +% +% \changes{v2.4}{89/08/15}{Group within \string\crossword\space environment} +% \changes{v2.6}{89/10/13}{Removed {\tt\protect\bslash iffalse} hack} +% We start off with a \verb+\vtop+ box and a group to hold everything +% within the environment, so as to ensure that user-entered text remains +% with the crossword. +% \changes{v2.9}{07/12/04}{Changed to environment syntax, with +% optional argument for rectangular grids} +% +% \begin{macrocode} + \endgraf\leavevmode + \vtop\bgroup +% \end{macrocode} +% +% \begin{macro}{\Header} +% \begin{macro}{\cluewidth} +% \begin{macro}{\numbersize} +% \begin{macro}{\cluesize} +% \begin{macro}{\barwidth} +% The {\sf crossword} environment uses the full-size grid, and has the +% lights numbered. Furthermore it doesn't have any heading to output (see +% the {\sf crossword*} environment). +% Some other macros are given so that the user can customize the layout. +% +% \begin{macrocode} + \unitlength 6mm\numberittrue + \def\Header{}% + \def\Preamble{}% + \def\cluewidth{70mm} + \let\numbersize\tiny + \let\cluesize\ninept + \def\barwidth{0.1} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro} +% +% We now open the auxiliary files into which the clues are written, and +% determine (interactively if necessary) whether the answers are to be +% written into the grid. +% +% \begin{macrocode} + \OpenClueFiles + \TestAnswers{#3}% +% \end{macrocode} +% +% Finally, we generate the necessary macros to describe the grid. +% For each square, there are three macros. For example, corresponding +% to the square in row 4 from the top, column 2 from the +% left, the macros are: \smallskip \\ \hspace{1cm} +% \begin{tabular}{ll} +% \verb+\LetterRivCii+ & Letter in the square; \texttt{!} is used for a black square.\\ +% \verb+\NumberRivCii+ & Number in the square; 0 is used for a numberless square.\\ +% \verb+\BarRivCii+ & Code defining bars around the square, defined below. +% \end{tabular} \smallskip \\ +% +% \begin{macrocode} + \SetUpGrid{#1}{\c@ls}} +% \end{macrocode} +% +% When all the clues have been processed, we can invoke \verb+\FinishGrid+ +% to draw the grid. The \verb+\FinishGrid+ and \verb+\PrintClues+ commands +% draw the grid and tabulate the clues, respectively. By enclosing them in +% a vertical mode list, we ensure that they remain stuck together on one +% page! +% +% The {\sf crossword} environment defines \verb+\Header+ to be empty, but +% the user may give it an explicit definition within the environment; if so, +% we'll print it just above the grid itself. +% +% \begin{macrocode} +{\endgraf + \centerline{\Header}% + \hbox{\FinishGrid}% +% \end{macrocode} +% +% We can now finish off the auxiliary files and then read them back in to +% set the text of the clues below the grid. +% +% \changes{v2.4}{89/08/15}{Group within \string\crossword\space environment} +% \changes{v2.6}{89/10/13}{Removed {\tt\protect\bslash iffalse} hack} +% Finally, we complete the group and the \verb+\vtop+ box. +% +% \begin{macrocode} + \ifthenelse {\equal{\Preamble}{}} {} + {\centerline{\parbox{\textwidth}{\Preamble}}\medskip} + \CloseClueFiles + \hbox{\PrintClues}% + \egroup +} +% \end{macrocode} +% \end{macro}\end{macro} +% +% \begin{macro}{crossword*} +% \changes{v2.1}{89/04/27}{No longer opens {\tt.acr} and {\tt.dwn} files} +% \changes{v2.6}{89/10/13}{Removed {\tt\protect\bslash iffalse} hack} +% \changes{v2.9}{07/12/04}{Changed to environment syntax, with +% optional argument for rectangular grids} +% The {\sf crossword*} environment doesn't need a second parameter to +% control printing of answers, because it {\bf always} populates the grid +% with the answers. Instead, its second parameter provides the text to +% appear above the printed grid. Its actions are as for the {\sf +% crossword} environment except that\begin{itemize} +% \item It assumes that there is descriptive text above the grid +% and allows room for it. +% \item It {\bf always} outputs the answers, without numbers. +% \item It draws them in a smaller box. +% \item It doesn't output the clues (it doesn't even open any +% auxiliary files!) +% \end{itemize} +% +% \begin{macrocode} +\newenvironment{crossword*}[3][\c@ls]{% + \def\c@ls{#2} + \unitlength 4mm\numberitfalse + \def\barwidth{0.1} + \endgraf\leavevmode + \vtop\bgroup + \def\Header{{\bf\strut #3}}% + \def\answer{Y}% + \let\tf@dwn=\relax \let\tf@acr=\relax + \SetUpGrid{#1}{#2}} +{\endgraf + \centerline{\Header}% + \hbox{\FinishGrid}% + \egroup +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Macros for each square} +% \changes{v2.9}{07/12/19}{The part of the code dealing with grid details has +% been completely rewritten. (DPL)} +% \begin{macro}{\ind@x} +% \begin{macro}{\arr@yref} +% \begin{macro}{\value} +% \begin{macro}{\assign} +% \begin{macro}{\addto} +% Crosswords are inherently two-dimensional, and require matrices +% of related definitions. Since \TeX\ does not allow numbers in +% a name, each square has a unique text index using \texttt{R} and +% \texttt{C} followed by roman numerals. Each macro name consists +% of a prefix (the same for all squares) followed by the unique +% text index. The original version of this +% package had only one such macro for each square, with an empty prefix, +% but in this version we have three: \texttt{Letter}, \texttt{Number} +% and \texttt{Bar}. +% +% For readability of the code, the following macros provide bracket +% syntax, thereby avoiding the use of \verb+\csname+\ldots\verb+\endcsname+ +% elsewhere. +% For example, \verb+\value Bar[2,5]+ gives \verb+\BarRiiCv+. +% A new definition \texttt{NEW} is assigned by \verb+\assign Bar[2,5]=NEW;+. +% If the contents of \verb+\BarRiiCv+ is a number, you can add 31 +% to it using \verb"\addto Bar[2,5]+=31;". In both cases, the semicolon +% is essential. +% \begin{macrocode} +\def\ind@x#1#2{R\romannumeral #1C\romannumeral#2} +\def\arr@yref#1#2#3{\csname #1\ind@x{#2}{#3}\endcsname} +\def\value#1[#2,#3]{\arr@yref{#1}{#2}{#3}} +\def\assign#1[#2,#3]=#4;% +{\expandafter\edef\csname #1\ind@x{#2}{#3}\endcsname{#4}} +\newcount\accumulat@r +\def\addto#1[#2,#3]+=#4;% +{\accumulat@r=\value #1[#2,#3] \advance\accumulat@r by #4 + \assign #1[#2,#3]=\the\accumulat@r;} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro} + +% We do bars as follows: in addition to \verb+\RiCii+ etc which define the +% contents of a square, there is a bar code \verb+\BarRiCii+ etc with +% the following meaning: +% \begin{enumerate} +% \item[0:] no bar above or to the left of the square +% \item[1:] bar above the square +% \item[2:] bar to the left of the square +% \item[3:] bars above and to the left of the square +% \end{enumerate} +% At the start, all bar codes are set to 3; +% the bars between letters are erased as we go along. + +% \subsection{Macros used while processing the clues} + +% \begin{macro}{\lettercount} +% \begin{macro}{\Barcode} +% As we move along the letters of the answer, we count +% the number of letters processed in \verb+\lettercount+. +% The code for the bar to be erased (1 or 2) is put +% into \verb+Barcode+ before we start on each answer. +% \begin{macrocode} +\newcount\lettercount +\newcount\Barcode +% \end{macrocode} +% \end{macro} +% \end{macro} + +% \begin{macro}{\nextletter} +% \begin{macro}{\nextlet} +% To determine how much space is required for the light corresponding to +% an answer, we need to cycle through each of the characters of the answer +% individually; this macro is called with two parameters --- the first +% indicates the current setting direction (and thus accesses one of the +% counters \verb+\Across+ or \verb+\Down+), whilst the second consists of +% the characters forming the answer followed by the string \verb+\@nil+. +% When it is called, this ``second'' parameter is {\em not\/} enclosed in +% braces, so only the first token in it is accessed. The macro calls +% itself recursively to process the remaining characters until the +% \verb+\@nil+ has been met. +% +% \changes{v2.1}{89/04/27}{Can now process {\em first\/} letter of light} +% \begin{macrocode} +\def\nextletter#1#2{% +% \end{macrocode} +% +% If the next token is \verb+\@nil+, we've finished; the \verb+\let+ ensures +% that its parameter will be discarded (through the \LaTeX{} internal +% command \verb+\@gobble+) and the recursion will then unravel. +% +% \changes{v2.1}{89/04/27}{Use \protect\LaTeX's {\tt\protect\bslash @gobble} +% command} +% \begin{macrocode} + \ifx#2\@nil \let\nextlet=\@gobble +% \end{macrocode} +% +% Otherwise, we have another letter of the \meta{answer} in {\tt\#2}, so we +% save the letter and check that it does not conflict with an earlier letter +% in the same square. +% +% \begin{macrocode} + \else \immediate\edef\Before{\value Letter[\Down,\Across]} + \assign Letter[\Down,\Across]=#2; + \immediate\edef\After{\value Letter[\Down,\Across]} + \if \Before ! \else \if \Before \After + \else \errhelp{You mistyped an answer, or miscounted the coordinates.} + \errmessage{Letter "\After" conflicts with earlier "\Before" + in row \the\Down, column \the\Across} + \fi \fi +% If the letter is not the first letter of its answer, we erase a bar. + \ifnum \lettercount>0 \addto Bar[\Down,\Across]+=-\Barcode; \fi +% Advance another position in the current direction. + \@gobble{#2} \advance#1 by \@ne \global\advance \lettercount by \@ne +% \end{macrocode} +% +% After we've processed this letter, we want to call this routine +% recursively to process the remaining letters (if any)\dots +% +% \changes{v2.1}{89/04/27}{Change to handle subsequent letters of light} +% \begin{macrocode} + \let\nextlet=\nextletter + \fi +% \end{macrocode} +% +% This is where we either exit from the recursion (and \verb+\@gobble+ the +% {\tt\#1} parameter) or call the macro recursively to process the next +% character; the direction has to be passed on as the first parameter for +% \verb+\nextletter+ or \verb+\@gobble+. +% +% \begin{macrocode} + \nextlet{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% + + +% \subsection{The {\tt\protect\bslash clue} Command} +% +% \begin{macro}{\clue} +% +% Well, here it is at last. We start off by extracting the parts (if any) +% which form the \meta{clue\_number} parameter. We will therefore have +% the purely numeric first portion of the \meta{clue\_number} in +% \verb+\cluenumber+. +% +% \begin{macrocode} +\def\clue#1#2#3#4#5#6#7{% +% \end{macrocode} +% The $x$ and $y$ coordinate counters are set from the \meta{column} and +% \meta{row} parameters. +% +% \begin{macrocode} + \Across=#3 \Down=#4 +% \end{macrocode} +% The clue may be spread over more than one number, but the square +% takes only the first of these. +% \begin{macrocode} + \findnumber{#1} +% \end{macrocode} +% Save the clue number, checking that it was not previously defined +% to be something else. +% \begin{macrocode} + \immediate\edef\Before{\value Number[\Down,\Across]} + \assign Number[\Down,\Across]=\cluenumber; + \immediate\edef\After{\value Number[\Down,\Across]} + \ifnum \Before>0 \ifnum \After=\Before + \else \errhelp + {You probably made a mistake when typing in one of the clues.} + \errmessage{Number {\After} conflicts with earlier {\Before} + in row \the\Down, column \the\Across} + \fi \fi +% \end{macrocode} +% +% We now examine the second (\meta{Across/Down}) parameter of the +% \verb+\clue+ command to determine whether this is an Across or Down +% clue. The clue's \meta{text} and \meta{help} information is then +% written\footnote{The writes only take place if the output files exist, +% and the \meta{help} parameter is non-empty.} to the appropriate +% auxiliary file, and note taken of the direction in which the +% \meta{answer} should be set into the light of the grid. +% +% \changes{v2.4}{89/08/15}{Support for empty help field} +% +% Firstly we deal with writes to the {\tt.acr} file, if the +% \meta{Across/Down} parameter is the letter `{\tt A}'. In this case, the +% counter to be incremented is \verb+\Across+. +% \changes{v2.8a}{96/07/22}{Removed string from \cs{@writefile} arg (FMi)} +% \changes{v2.9}{07/12/19}{Change empty test to use \cs{ifthenelse}. +% Testing by \cs{if} is a bug. (DPL)} +% \begin{macrocode} + \ifx#2A + \global\Barcode=2 + \ifthenelse{\equal{\@empty}{#7}}{}{ + \ifx\tf@acr\relax\else + \@writefile{acr}{ \item[#1] #6 (#7)}% + \fi} + \let\Direction=\Across + \else +% \end{macrocode} +% If this parameter is the letter `{\tt D}', writes go to the {\tt.dwn} +% file, and the \verb+\Down+ counter is incremented. +% \begin{macrocode} + \ifx#2D + \global\Barcode=1 + \ifthenelse{\equal{\@empty}{#7}}{}{ + \ifx\tf@dwn\relax\else + \@writefile{dwn}{ \item[#1] #6 (#7)}% + \fi} + \let\Direction=\Down + \else +% \end{macrocode} +% +% If this \meta{Across/Down} parameter is not one of the two permitted +% characters, an error message is issued. +% +% \begin{macrocode} + \errhelp{The second parameter of the \string\clue\space + command must be `A' or `D'} + \errmessage{Illegal direction (#1) specification + for \string\clue.} + \fi + \fi +% \end{macrocode} +% +% Now we can call \verb+\nextletter+ which will cycle through all the +% letters of the \meta{answer} until meeting the token \verb+\@nil+. +% It will save the current letter and recursively call itself until no +% letters are left. +% Finally, we ensure that the newlines after \verb+\clue+ commands don't +% lead to unwanted spaces being typeset. +% \changes{v2.6}{89/10/13}{Minor revision of layout} +% \begin{macrocode} + \global\lettercount=0 + \nextletter{\Direction}#5\@nil + \ignorespaces +} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Finding the clue number to be set in the light} +% \begin{macro}{\findnumber} +% +% We mentioned earlier that clues with solutions which occupy more than +% one light require a special format for specifying their +% \meta{clue\_number}. If this form is required, the number of the current +% light is given first, with the remaining text (as it is required to be +% set) following, separated from the first number by some non-digit +% character. +% +% The macro \verb+\findnumber+ is called with the entire +% \meta{clue\_number} parameter passed to \verb+\clue+ and sets +% \verb+\cluenumber+ to expand to the first or only number found in that +% parameter (which should then appear in the first square of the light). +% +% \begin{macro}{\clueNumber} +% Of course, we require a counter in which to attempt to assemble that number: +% \begin{macrocode} +\newcount\clueNumber +% \end{macrocode} +% +% \begin{macro}{\special@gobble} +% This macro is used by \verb+\findnumber+ to discard the unwanted portion +% (if any) of a \meta{clue\_number}, including the special termination +% token. +% +% \begin{macrocode} +\def\special@gobble #1\@nil{} +% \end{macrocode} +% +% The following mechanism to separate the first (or only) number from the +% remainder was suggested by Frank Mittelbach of the University of Mainz, +% and replaced about two pages worth of code. +% \changes{v2.2}{89/05/17}{Much quicker clue number extraction} +% \begin{macrocode} +\def\findnumber#1{% +% \end{macrocode} +% We attempt to assign the \meta{clue\_number} parameter to the +% \verb+\clueNumber+ counter: only that portion consisting purely of digits +% will actually be assigned. The remainder, if any, including the special +% terminator sequence \verb+\@nil+ is then discarded by the +% \verb+\special@gobble+ command: +% +% \begin{macrocode} + \afterassignment \special@gobble \clueNumber=0#1 \@nil +% \end{macrocode} +% +% \changes{v2.6}{89/10/13}{Minor revision of layout} +% If the user did not provide a valid \meta{clue\_number} (i.e.\ something +% starting with a digit), then \verb+clueNumber+ will have zero assigned to +% it. This will cause a diagnostic message at the stage when it is checked +% that the clue numbers run consecutively in reading order from 1 upwards. +% +% This completes \verb+\findnumber+. +% +% \begin{macrocode} + \ifnum\clueNumber=0 + \errhelp{The first parameter of the \string\clue\space command + must commence with a digit} + \errmessage{Illegal clue number (#1) specified + for \string\clue.} + \fi +} +% \end{macrocode} +% \end{macro} ^^A \special@gobble +% \end{macro} ^^A \clueNumber +% \end{macro} ^^A \findnumber +% +% \begin{macro}{\cluenumber} +% This macro merely produces the number as saved in \verb+\clueNumber+. +% \begin{macrocode} +\def\cluenumber{\the\clueNumber} +% \end{macrocode} +% \end{macro} ^^A \cluenumber +% +% \subsection{Populating the Crossword Grid} +% \begin{macro}{\blackenrow} +% \changes{v2.2}{89/05/17}{Used {\tt\protect\bslash blackenrow} for inner loop} +% \changes{v2.8a}{96/07/22}{Fixed command to save val of \cs{iterate} +% not \cs{body} (FMi)} +% For each column in a row we create a black square by setting the +% letter in the square to \texttt{!}. We also initialize the \texttt{Number} +% and \texttt{Bar} macros. +% +% Before starting the inner loop, we need to save the definition of +% \verb+\body+ which was created for the outer loop. We cannot do this by +% creating a new block, since that would require that each square be defined +% globally, which might give rise to save stack overflow problems. +% +% Actually with \LaTeXe{} we have to save \verb=\iterate= as the internals +% of \verb=\loop= have been streamlined. With the old code only the first +% row was updated---this is the price for using an unpublished implementation +% feature. +% \begin{macrocode} +\def\blackenrow{\let\savediterate\iterate + \loop\relax\ifnum\Across>\z@ + \assign Bar[\Down,\Across]=3; + \assign Letter[\Down,\Across]=!; + \assign Number[\Down,\Across]=0; +% \end{macrocode} +% +% We then shift ourselves back to the next column to the left and iterate. +% If we've reached the end of this inner loop, we re-establish the +% definition of \verb+\body+. +% +% Again with 2e this has to be \verb=\iterate=. +% +% \begin{macrocode} + \advance\Across by \m@ne + \repeat + \let\iterate\savediterate +} +% \end{macrocode} +% +% \begin{macro}{\SetUpGrid} +% \changes{v2.9}{07/12/05}{Rectangular grids} +% +% This macro creates an empty grid of the appropriate size. +% +% \begin{macrocode} +\def\SetUpGrid#1#2{% +% \end{macrocode} +% +% We firstly make a note of the \meta{gridcols} parameter in the +% \verb+\gr@dcols+ counter, from which the width and height of the grid +% may be computed. We also set the \verb+\p@csize+ counter to be one +% greater than \verb+\gridc@ls+ to save our recomputing this quantity many +% times over. Ditto mutatis mutandis for \meta{gridrows}. +% +% \begin{macrocode} + \gridr@ws=#1\gridc@ls=#2 + \p@rsize=#1 \advance\p@rsize by \@ne + \p@csize=#2 \advance\p@csize by \@ne + \typeout{Grid has #1 rows and #2 columns.} +% \end{macrocode} +% +% Right, this is where we start to generate the grid itself. We start at +% the bottom edge, because \TeX\ loops are easiest if counting down to +% zero. Therefore, the \verb+\Down+ counter is set equal to the highest row +% number attainable. +% +% \begin{macrocode} + \Down=\gridr@ws +% \end{macrocode} +% +% We now start a loop, so the following code will be repeated for each row +% of the grid in turn. As with the rows, we process the columns from +% highest address to lowest, so the \verb+\Across+ counter is also set to the +% highest column attainable. +% +% \begin{macrocode} + \loop + \Across=\gridc@ls +% \end{macrocode} +% +% Provided we haven't decremented down to the 0th row, we start off the +% inner loop to process each column: this is done by invoking a separate +% macro --- the alternative to which would be to enclose the inner loop in +% a group, which would require the use of global definitions for each +% square. +% \changes{v2.2}{89/05/17}{Used {\tt\protect\bslash blackenrow} for inner loop} +% +% \begin{macrocode} + \ifnum\Down>\z@ + \blackenrow +% \end{macrocode} +% +% +% Afterwards we move ourselves up one row, and iterate for the next row. +% +% +% \begin{macrocode} + \advance\Down by \m@ne + \repeat +} +% \end{macrocode} +% \changes{v2.6}{89/10/13}{Minor revision of layout} +% And that's the end of \verb+\SetUpGrid+! +% \end{macro} ^^A \SetUpGrid +% \end{macro} ^^A \blackenrow +% +% \begin{macro}{\TestAnswers} +% This macro interacts with the user, if necessary, to get a yes or no +% indication of whether the answers shall be written into the grid. No +% check is made that the user has entered a valid response, but the use of +% \verb+\answer+ is such that any answer apart from a `{\tt y}' (in upper- +% or lower-case) is treated as if it were `{\tt n}'. +% +% \begin{macro}{\f@rst} +% To determine what parameter has been provided, or the response elicited, +% we will require a little macro to pass on the first token of a list +% terminated by a full stop. +% +% \begin{macrocode} +\def\f@rst#1#2.{#1} +% \end{macrocode} +% +% We commence by lower-casing the given parameter, setting the lower-cased +% version into the macro \verb+\answer+. +% \begin{macrocode} +\def\TestAnswers#1{\edef\next{\def\noexpand\answer{#1}}% + \lowercase\expandafter{\next}% +% \end{macrocode} +% We can then extract just the first character +% \begin{macrocode} + \edef\answer{\expandafter \f@rst \answer n.}% +% \end{macrocode} +% The we determine whether it's the letter `{\tt y}' or `{\tt n}'\dots +% \begin{macrocode} + \if\answer y \else \if\answer n \else +% \end{macrocode} +% If the \meta{visible} parameter isn't either of these, we ask the user +% to give us an answer! +% \begin{macrocode} + \typein[\answer]{Make answers visible? [Y/N]: }\fi + \fi +% \end{macrocode} +% OK, \verb+\answer+ now contains some response; let's upper-case it and +% extract just its first character +% \begin{macrocode} + \edef\next{\def\noexpand\answer{\answer}}% + \uppercase\expandafter{\next}% + \edef\answer{\expandafter \f@rst \answer n.}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Setting the Grid} +% +% \begin{macro}{\putletter} +% +% \changes{v2.8a}{96/07/22}{use \cs{sffamily} (FMi)} +% These macros put letters, numbers and bars at the current +% \verb+[\Down,\Across]+ position. Note that \verb+\putletter+ +% would be redefined to \verb+\relax+ if no actual letters are required. +% \begin{macrocode} +\def\putletter{{\put(\Across,-\Down){\makebox(1,1) + {\sffamily \value Letter[\Down,\Across]}}}} +% \end{macrocode} +% \begin{macro}{\putnumber} +% The \verb+\putnumber+ macro checks whether the clue number is 0 (which +% means an unnumbered square) and whether the clue numbers are in +% sequence. To this end, it makes use of global \verb+\oldnumber+ +% and \texttt{seqtest}. +% \begin{macrocode} +\newcount\oldnumber \oldnumber=0 +\newif\ifseqtest \seqtestfalse +\def\putnumber{\immediate\def\Number{\value Number[\Down,\Across]} + \ifnumberit \ifnum\Number>0 + \put(\Across,-\Down){% +% \end{macrocode} +% +% To insert the clue number, we generate it within a sub-picture, of size +% equal to one square. +% +% \begin{macrocode} + \begin{picture}(1,1)(0,0) +% \end{macrocode} +% +% We stick the number in the top-left corner of an (invisible) box which +% fills the central 81\% of the area. In the process, we check whether +% the clues are properly numbered in reading order. +% +% \begin{macrocode} + \put(0.05,0.05){\makebox(0.9,0.9)[tl]{\numbersize\Number}} + \end{picture}} + \ifnum \oldnumber>0 \advance\oldnumber by\m@ne + \ifnum \oldnumber=\Number {\seqtesttrue} \else + \ifseqtest + \errhelp{Clues should be numbered consecutively from top left + to bottom right.} + \errmessage{Found clue number \Number, but expected \the\oldnumber} +% \end{macrocode} +% If a clue number was mistyped, it will generate two out-of-sequence +% errors. We suppress the second of these. +% +% \begin{macrocode} + \seqtestfalse + \else\seqtesttrue\fi + \fi + \fi + \global \oldnumber=\Number +\fi \fi +} +% \end{macrocode} +% \begin{macro}{\putbars} +% If there are two adjacent light squares not belonging to the same light, +% we draw a bar between them. We use two counters for that: one for the +% previous square, so we can test for its blackness; one for the +% changing value of the barcode for the current square. +% \begin{macrocode} +\newcount \pr@vious +\newcount \c@de +\def\putbars{ \linethickness{\barwidth\unitlength} + \c@de=\value Bar[\Down,\Across] + \ifnum \c@de>1 \advance\c@de by -2 + \ifnum \Across>1 + \pr@vious=\Across \advance \pr@vious by -1 + \immediate\def\pr@vlet{\value Letter[\Down,\pr@vious]} + \if \pr@vlet ! \else \put(\Across,-\Down){\line(0,1){1}} + \fi \fi \fi + \ifnum \c@de>0 + \ifnum \Down>1 + \pr@vious=\Down \advance \pr@vious by -1 + \immediate\def\pr@vlet{\value Letter[\pr@vious,\Across]} + \if \pr@vlet ! \else \put(\Across,-\pr@vious){\line(1,0){1}} + \fi \fi \fi +} +% \end{macrocode} +% +% \end{macro}\end{macro}\end{macro} +% +% \begin{macro}{\FinishGrid} +% Now we can process all the stored macros which define the appearance of +% each square in the grid, and thus generate the printed version thereof, +% using \LaTeX's {\sf picture} environment. +% +% This command makes appropriate redefinitions of some macros which produced +% different effects during the filling of the grid. +% \changes{v2.2}{89/05/17}{Removed extraneous opening space after brace} +% \changes{v2.6}{89/10/13}{Minor revision of layout} +% \changes{v2.9}{07/12/05}{Rectangular grid, top right extra labels} +% \begin{macrocode} +\def\FinishGrid{% +% \end{macrocode} +% +% If the customer doesn't want the letters put into the grid, then we +% need only let \verb+\putletter+ do nothing. Since \verb+\FinishGrid+ +% is invoked inside the environment, the original definition will be +% restored on exit. +% +% \begin{macrocode} + \if\answer Y \else \let\putletter\relax \fi +% \end{macrocode} +% +% Now we come to the actual body of \verb+\FinishGrid+. +% +% \changes{v2.6}{89/10/13}{Minor revision of layout} +% \changes{v2.9}{07/12/05}{Rectangular grid} +% We start off at the bottom-most row of the grid\dots +% +% \begin{macrocode} + \Down=\gridr@ws +% \end{macrocode} +% +% The whole grid is created in a centered \verb+\hbox+ in a {\sf picture} +% environment. By offsetting the origin negatively, we can address each +% row by simply negating the $y$ coordinate; thus column $x$ in the highest +% row is $(x,-1)$. +% +% \begin{macrocode} + \centerline{% + \begin{picture}(\p@csize,\p@rsize)(1,-\p@rsize) +% \end{macrocode} +% +% We now cycle through each of the rows. The first thing we output is a +% horizontal rule of the full width of the grid, one such rule being +% generated for each row of the grid, providing the horizontal lines across +% vertical lights. +% +% \begin{macrocode} + \loop\ifnum\Down>\z@ + \put(1,-\Down){\line(1,0){\the\gridc@ls}} +% \end{macrocode} +% +% Now we are about to cycle across all the columns of the current row; +% again, it's convenient for us to work backwards to the left\dots +% +% \begin{macrocode} + \Across=\gridc@ls +% \end{macrocode} +% +% To do this we need an inner loop; this has to be inside a group so as to +% isolate the effects of its \verb+\repeat+ command. +% +% \begin{macrocode} + {\loop \ifnum\Across>\z@ +% \end{macrocode} +% +% A black square is represented by \texttt{!} instead of a letter. +% We need an \verb+\immediate+ definition to force the expansion +% so we can test using \verb+\if+. This test cannot be made inside +% \verb+\putletter+ because that macro may have been redefined +% when the lights are empty. +% \begin{macrocode} + \immediate\def\lett@r{\value Letter[\Down,\Across]} + \if \lett@r ! \put(\Across,-\Down){\rule{\unitlength}{\unitlength}} + \else \putletter \putnumber \putbars + \fi +% \end{macrocode} +% +% Now we advance to the next column and iterate. That's the end of the +% inner loop for each of the columns of the current row. +% +% \begin{macrocode} + \advance\Across by \m@ne + \repeat + }% +% \end{macrocode} +% +% Now we can decrement down to the next row and iterate through the +% rows. In the process, we encounter all the clue numbers in opposite +% order, therefore the last clue number found should be 1. +% +% \begin{macrocode} + \advance\Down by \m@ne + \repeat + \ifthenelse{\equal{\the\oldnumber}1}{} + {\ifnumberit\errhelp{Clues should be numbered consecutively + from top left to bottom right.} + \errmessage{First clue number is \the\oldnumber, not 1} \fi} +% \end{macrocode} +% +% We've so far drawn a horizontal line {\em under\/} each of the rows; the +% next \verb+\put+ draws a final line {\em above\/} the top-most row. +% +% \begin{macrocode} + \put(1,0){\line(1,0){\the\gridc@ls}} +% \end{macrocode} +% +% Similarly, a short loop can draw vertical rules at the left-hand edge of +% each of the columns, starting with a line on the left of an imaginary +% column to the right of the whole grid, which will therefore form a line to +% the right of the final column. +% +% \begin{macrocode} + \Across=\p@csize + \loop\ifnum\Across>\z@ + \put(\Across,0){\line(0,-1){\the\gridr@ws}} + \advance\Across by \m@ne + \repeat +% \end{macrocode} +% +% And that completes the picture. +% +% \begin{macrocode} + \end{picture}% + }% +} +%</package> +% \end{macrocode} +% \end{macro} +% +% +% +% \section{A hard crossword with blocks and bars} +% \begin{crossword}[11]{13}{N} +% \MakePercentComment \input{grid2} \MakePercentIgnore +% \end{crossword} + + +% \section{Sample input files} +% Finally, here's the input which produced the crossword in +% Figure~\ref{crossword:1} +% +% \begin{verbatim} +% \begin{crossword}{15}{N} +% \input{grid1} +% \end{crossword} +% \end{verbatim} +% +% +% +% \begin{macrocode} +%<*grid0> +\clue{1}{A}{3}{1}{PERAMBULATOR}{Stroller carrying the baby}{12} +\clue{8}{A}{1}{3}{IMPASSE}{Eastern note returned about predicament resulting + in deadlock}{7} +\clue{9}{A}{9}{3}{TERMINI}{Many ends brought back in one minute soak}{7} +\clue{11}{A}{1}{5}{TIEPOLO}{Venetian painter to draw Spanish gipsy dance?}{7} +\clue{12}{A}{9}{5}{ARAMAIC}{Semitic language of one in charge of following a + sheep}{7} +\clue{13}{A}{1}{7}{ENSUE}{Follow three directions and bend eastward}{5} +\clue{14}{A}{7}{7}{IMPLETION}{Filling feeble-minded person who lost his head + about one}{9} +\clue{16}{A}{1}{9}{SURPRISED}{Rip apart with duress taken unawares}{9} +\clue{19}{A}{11}{9}{DUNCE}{Stupid person from hill church}{5} +\clue{21}{A}{1}{11}{ERRATUM}{Published correction --- return walled-up + sailor}{7} +\clue{23}{A}{9}{11}{LIASSIC}{Lower Jurassic sea trip backwards [thus]}{7} +\clue{24}{A}{1}{13}{SABBATH}{Midnight meeting of witches at hospital on rest + day?}{7} +\clue{25}{A}{9}{13}{ISOTRON}{Sort ion with an accelerator?}{7} +\clue{26}{A}{2}{15}{STANDINGROOM}{Substitute husband relegated here at + crowded wedding}{8-4} +\clue{1}{D}{3}{1}{PEPPERS}{Showers band with lonely hearts?}{7} +\clue{2}{D}{5}{1}{RESTORE}{Concerning money saved --- reinstate to former + owner}{7} +\clue{3}{D}{7}{1}{MNEMONICS}{No-one in higher degree produces memory + joggers}{9} +\clue{4}{D}{9}{1}{ULTRA}{Enigmatic secret of WW\,I\kern-.1em I?}{5} +\clue{5}{D}{11}{1}{ACREAGE}{Current about time flows over measured area}{7} +\clue{6}{D}{13}{1}{ORIGAMI}{Maybe magic endlessly raised before one with + Japanese artistic skill}{7} +\clue{7}{D}{1}{2}{LISTLESSNESS}{Enroll fewer once before head suffering a + languid malaise}{12} +\clue{10}{D}{15}{3}{INCANDESCENT}{White-hot Peruvian reorganized objects + covering small coin}{12} +\clue{15}{D}{9}{7}{PEDALLING}{Penny led a rearranged fish engaging in cyclic + activity!}{9} +\clue{17}{D}{3}{9}{RAREBIT}{Welsh toast? An unusual drill!}{7} +\clue{18}{D}{5}{9}{RETRAIN}{Keep in mind, take in, and acquire new + skills}{7} +\clue{19}{D}{11}{9}{DIABOLO}{Twice a high ball thrown up round a two-headed + top}{7} +\clue{20}{D}{13}{9}{NOSTRUM}{No good man with spirit offers quack remedy}{7} +\clue{22}{D}{7}{11}{MAHDI}{I would shortly overact, sent up, and the + downfall of Gordon}{5} +%</grid0> +% \end{macrocode} +% +% +% +% \begin{macrocode} +%<*grid1> +\clue{8}{A}{1}{2}{SWAM}{Points a thousand tested for witchcraft.}{4} +\clue{9}{A}{6}{2}{OHO}{Gourmet's triumphant cry on finding middle-cut + Pacific salmon!}{3} +\clue{10}{A}{10}{2}{ICECAP}{One hundred stride backwards across a + Pole.}{3-3} +\clue{11}{A}{1}{4}{BOPEEP}{Fifties' jazz record about Eastern childs' + play.}{2-4} +\clue{12}{A}{8}{4}{SCHEDULE}{Timetable created by editor in synagogue + of Spain.}{8} +\clue{13}{A}{1}{6}{THALASSOGRAPHER}{The dialect a girl mixed up tangle + around symbolic diagram used by + maritime student!}{15} +\clue{15}{A}{1}{8}{HAIRPIN}{Wire fastening bent road narrowly.}{7} +\clue{17}{A}{9}{8}{UMBRAGE}{Hammerhead consumes German company + and casts a shade.}{7} +\clue{20}{A}{1}{10}{SCALENETRIANGLE}{Strange cel alien chops to make a + figure with odd sides.}{7,8} +\clue{23}{A}{1}{12}{AMOUNTED}{Sounds like a hoarse editor came to in + total!}{8} +\clue{25}{A}{10}{12}{ALLEGE}{Assert without proof everyone, for + example, English.}{6} +\clue{26}{A}{1}{14}{FLORAL}{Flourished examination of flowers.}{6} +\clue{27}{A}{8}{14}{NIL}{Floor covering discards fuming sulphuric acid + and returns to nothing.}{3} +\clue{28}{A}{12}{14}{TACE}{``Latin for a candle'' to be silent note + about aircraftman?}{4} +\clue{1}{D}{2}{1}{SWOOSH}{Water rush noise disturbs show so!}{6} +\clue{2}{D}{4}{1}{IMPELLER}{Mischievous child with cloth measure + hesitates to assemble rotor.}{8} +\clue{3}{D}{6}{1}{COMPASSIONATELY}{Mercifully inclined to pass round + ten? Nay, about short blower!}{15} +\clue{4}{D}{8}{1}{TORSION}{Sort ion? An isotron gives it a new + twist!}{7} +\clue{5}{D}{10}{1}{DITHYRAMBICALLY}{Wildly and boisterously rearrange + Billy May Third, roughly.}{15} +\clue{6}{D}{12}{1}{SENDUP}{Satirical book or film---give odds about + revision of ``Dune''?}{4-2} +\clue{7 {\noexpand\rm\&} 24}{D}{14}{1}{PALL}{Premier took in a Lord + Lieutenant and all played an + old game in London street.}{4-4} +\clue{14}{D}{14}{6}{ERG}{Work expended in power games?}{3} +\clue{16}{D}{2}{8}{ARC}{A church circle (or part of one).}{3} +\clue{18}{D}{12}{8}{RINGLETS}{Encircle hindrances under hair in long + curls.}{8} +\clue{19}{D}{8}{9}{STUDENT}{Boss over oto\-rhino\-laryng\-o\-logy + department undergraduate.}{7} +\clue{21}{D}{4}{10}{LOUVRE}{Old dovecote in Parisian museum.}{6} +\clue{22}{D}{14}{10}{LEGACY}{Like ornamental fabric, for example, + that's in bequest.}{6} +\clue{24}{D}{2}{12}{MALL}{}{See {\bf 7}} +%</grid1> +% \end{macrocode} +% +% +% +% \begin{macrocode} +%<*exa0> +\documentclass{article} +\usepackage{crosswrd} +\pagestyle{empty} +\setlength\topmargin{-1in} +\setlength\textheight{10.7in} + +\begin{document} + \begin{crossword}{15}{?} + \input{grid0} + \end{crossword} +\end{document} +%</exa0> +% \end{macrocode} +% +% +% \begin{macrocode} +%<*exa1> +\documentclass{article} +\usepackage{crosswrd} +\pagestyle{empty} +\setlength\topmargin{-1in} +\setlength\textheight{10.7in} +\begin{document} + \section*{A Sample Crossword} + \textit{(Chamber's Twentieth Century dictionary)} + \begin{crossword}{15}{N} + \input{grid1} + \end{crossword} + \begin{crossword*}{15}{Solution to grid 0} + \input{grid0} + \end{crossword*} +\end{document} +%</exa1> +% \end{macrocode} + +% +% \Finale +% \endinput + + +%<*exa2> +\documentclass[a4paper]{article} +\usepackage{a4wide,charter,crosswrd} +\topmargin -20mm +\textheight 240mm +\begin{document} + \thispagestyle{empty} + \begin{crossword}[11]{13}{N} + \input grid2 + \end{crossword} +\end{document} +%</exa2> +%<*grid2> + \unitlength 7mm + \let\numbersize\scriptsize + \centerline{\large{\textbf{T-shirt design} by Dirk Laurie}} + \def\Preamble{5 27, and that goes for 17 11 25 and 24A 10 too, +I'm sure, so the unclued lights should be entered in red. +The other lights are all +in the rather ancient edition of Chambers consulted by the composer.} +\clue{1}{A}{1}{1}{........}{Murderer's lip in an evil act}{8} +\clue{6}{A}{9}{1}{.....}{Places where vehicles without + resistance get bogged down?}{5} +\clue{10}{A}{2}{2}{..........}{}{} +\clue{12}{A}{1}{3}{....}{Perhaps 27 die here}{4} +\clue{14}{A}{5}{3}{.....}{Obstinate at first and after a smack}{5} +\clue{15}{A}{10}{3}{....}{Seduced girl, as rumoured}{4} +\clue{16}{A}{1}{5}{........}{Paid an unspecified amount in Johannesburg}{8} +\clue{17 \noexpand\& 11D \noexpand\& 25D}{A}{9}{5}{.....}{}{See preamble} +\clue{18}{A}{1}{6}{......}{Butt gives information in a peeve}{6,hyphenated} +\clue{20}{A}{8}{6}{......}{Big folk appearing in spots last month}{6} +\clue{24 \noexpand\& 10}{A}{1}{7}{.....}{}{See preamble} +\clue{26}{A}{6}{7}{........}{Wince after European has knocked back medicine, +leaving out some}{8} +\clue{30}{A}{1}{9}{....}{Recidivist is back, getting old in here}{4} +\clue{31}{A}{5}{9}{.....}{Unwilling to receive a small copper pot}{5} +\clue{32}{A}{10}{9}{....}{Primal wilderness beside a person from the East + ``is Paradise ---''}{4} +\clue{33}{A}{3}{10}{..........}{Denizen of Africa to suffer in the heat +when dose insects get in}{10} +\clue{34}{A}{1}{11}{.....}{Turn around at home and peek outside, like 18?}{5} +\clue{35}{A}{6}{11}{........}{Such as these two from the back going + ahead in copious lovemaking}{8} +\clue{1}{D}{1}{1}{......}{A disc full of French horn music}{6} +\clue{2}{D}{2}{1}{....}{Drams served up in Highland drizzle}{4} +\clue{3}{D}{4}{1}{......}{A gadfly with well-separated feet etc}{6,two words} +\clue{4}{D}{5}{1}{......}{Not many shooting up, in fact only one}{6} +\clue{5 \noexpand\& 27}{D}{7}{1}{.....}{}{See preamble,three words} +\clue{6}{D}{9}{1}{.....}{Tree that will, having had root extracted +at first, turn into mineral!}{5} +\clue{7}{D}{10}{1}{....}{Give me a response that I can hear: + it's no longer a crisis}{4} +\clue{8}{D}{12}{1}{......}{What unreformed head wears is right}{6} +\clue{9}{D}{13}{1}{.....}{Dirk's parrot, found in polar regions}{5} +\clue{11}{D}{11}{2}{........}{}{} +\clue{13}{D}{3}{3}{........}{Saying "Be with you shortly", lassie goes inside +house}{8} +\clue{19}{D}{2}{6}{......}{Invest ten rand judiciously}{6} +\clue{21}{D}{9}{6}{......}{Coin Dirk lost on the way up; Henry gets involved}{6} +\clue{22}{D}{10}{6}{......}{Peek!}{6} +\clue{23}{D}{13}{6}{......}{Neutral sounds and trite sayings arise all around Switzerland}{6} +\clue{24}{D}{1}{7}{.....}{Servants genteel at heart? One of them +is the butler at Blandings Castle!} +{5} +\clue{25}{D}{5}{7}{.....}{}{} +\clue{27}{D}{7}{7}{.....}{}{} +\clue{28}{D}{4}{8}{....}{Serving up only half a beer is a mistake}{4} +\clue{29}{D}{12}{8}{....}{Footplay before strong no-trump not allowed}{4} +%</grid2> +% + diff --git a/macros/latex/contrib/crosswrd/crosswrd.ins b/macros/latex/contrib/crosswrd/crosswrd.ins new file mode 100644 index 0000000000..49acbbf1bd --- /dev/null +++ b/macros/latex/contrib/crosswrd/crosswrd.ins @@ -0,0 +1,35 @@ + +\def\batchfile{crosswrd.ins} +\input docstrip.tex + +\preamble +Copyright C 1989 Brian Hamilton Kelly + +crossword macros for LaTeX +updated for LaTeX2e by Frank Mittelbach 96/12/06 +substantially extended by Dirk Laurie 08/01/18 + +for documentation run latex crosswrd.dtx + +distribution consist of + + crosswrd.dtx source + crosswrd.ins installation script + 00readme + +don't distribute this file without distributing the above +files as well + +\endpreamble + +\keepsilent + +\generate{ + \file{crosswrd.sty}{\from{crosswrd.dtx}{package}} + \file{test0.tex}{\from{crosswrd.dtx}{exa0}} + \file{test1.tex}{\from{crosswrd.dtx}{exa1}} + \file{test2.tex}{\from{crosswrd.dtx}{exa2}} + \file{grid0.tex}{\from{crosswrd.dtx}{grid0}} + \file{grid1.tex}{\from{crosswrd.dtx}{grid1}} + \file{grid2.tex}{\from{crosswrd.dtx}{grid2}} +} diff --git a/macros/latex/contrib/crosswrd/crosswrd.pdf b/macros/latex/contrib/crosswrd/crosswrd.pdf Binary files differnew file mode 100644 index 0000000000..30ddb0383f --- /dev/null +++ b/macros/latex/contrib/crosswrd/crosswrd.pdf |