From e3fc112b2ceec82657c11e788064ee66cdb0c9e3 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 6 Sep 2009 23:33:52 +0000 Subject: crossword update (6sep09) git-svn-id: svn://tug.org/texlive/trunk@15166 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/crossword/README | 73 + Master/texmf-dist/doc/latex/crossword/cwpuzzle.pdf | Bin 0 -> 185513 bytes .../source/latex/crossword/AcrossLite/README | 143 ++ .../source/latex/crossword/AcrossLite/nytconv.c | 202 +++ .../source/latex/crossword/AcrossLite/nytsconv.c | 209 +++ .../source/latex/crossword/AcrossLite/usaconv.c | 229 +++ Master/texmf-dist/source/latex/crossword/Makefile | 42 + .../texmf-dist/source/latex/crossword/cwpuzzle.dtx | 1774 ++++++++++++++++++++ .../texmf-dist/source/latex/crossword/cwpuzzle.ins | 43 + Master/texmf-dist/tex/latex/crossword/cwpuzzle.sty | 358 ++++ 10 files changed, 3073 insertions(+) create mode 100644 Master/texmf-dist/doc/latex/crossword/README create mode 100644 Master/texmf-dist/doc/latex/crossword/cwpuzzle.pdf create mode 100644 Master/texmf-dist/source/latex/crossword/AcrossLite/README create mode 100644 Master/texmf-dist/source/latex/crossword/AcrossLite/nytconv.c create mode 100644 Master/texmf-dist/source/latex/crossword/AcrossLite/nytsconv.c create mode 100644 Master/texmf-dist/source/latex/crossword/AcrossLite/usaconv.c create mode 100644 Master/texmf-dist/source/latex/crossword/Makefile create mode 100644 Master/texmf-dist/source/latex/crossword/cwpuzzle.dtx create mode 100644 Master/texmf-dist/source/latex/crossword/cwpuzzle.ins create mode 100644 Master/texmf-dist/tex/latex/crossword/cwpuzzle.sty (limited to 'Master/texmf-dist') diff --git a/Master/texmf-dist/doc/latex/crossword/README b/Master/texmf-dist/doc/latex/crossword/README new file mode 100644 index 00000000000..09c35992db2 --- /dev/null +++ b/Master/texmf-dist/doc/latex/crossword/README @@ -0,0 +1,73 @@ + + cwpuzzle.sty + - + a LaTeX package for typesetting crossword puzzles + + Gerd Neugebauer + + +Since I know only of one additional package for this purpose on CTAN +-- named crosswrd.sty -- I will compare it against this package to +show the advantages and disadvantages of both packages. + +I have developed cwpuzzle.sty because I needed to typeset a puzzle +which required more features than those provided by crosswrd. The +feature I was missing was the inclusion of rectangular regions in the +puzzles containing ads or other texts not directly related to the +characters to be filled in. + +I have generalized this requirement by allowing arbitrary rectangles +to be left free. Thus it is possible to typeset puzzles which have no +rectangular border (See the documentation for examples). + +Another idea was to have different types of puzzles generated from the +same source: + +- The classical puzzle contains numbers for the words and clues for + the words to be filled in. + +- The numbered puzzle contains numbers in each cell where identical + numbers represent identical letters. The goal is to find out which + number corresponds to which letter. + +- The fill-in type of puzzle consists of a grid and a list of words. + The goal is to place all words in the grid. + +crosswrd supports the first type of puzzle only. cwpuzzle supports all +of them. + +The input for both packages is completely different. crosswrd assumes +that a user uses this package to develop a puzzle. Thus it is tailored +towards a human user. It checks for consistency and requires +non-redundant input. (As a unpleasant side effect fragile macros used +in clues have to be protected) + +cwpuzzle needs some redundancy in the input for the sake of +flexibility. But it seems quite natural to specify the frame of the +puzzle and the clues separately. Especially for those types where no +clues are needed at all. + +cwpuzzle currently assumes that words are terminated by a black block +(or the border of the puzzle). crosswrd also supports also the variant +where words are terminated by a thicker border. This might also be +incorporated into a future release of cwpuzzle. + +In cwpuzzle it is also possible to specify whether the crossword +puzzle or it's solution should be produced (from the same +source). Thus it is possible to include the puzzle in one issue of a +journal and the solution into another, or to typeset the solution +several pages after the puzzle. + +cwpuzzle provides a larger number of options and hooks which can be +used to customize the result. E.g it is possible to modify the size of +the boxes or the fonts used as well as the appearance of graphical +elements like the black blocks. + + +cwpuzzle is located in the CTAN directory + + tex-archive/macros/latex/contrib/gene/crossword + +run tex on cwpuzzle.ins to produce the package and latex on +cwpuzzle.dtx to get the documentation (or the Makefile to do both). + diff --git a/Master/texmf-dist/doc/latex/crossword/cwpuzzle.pdf b/Master/texmf-dist/doc/latex/crossword/cwpuzzle.pdf new file mode 100644 index 00000000000..343c36975b5 Binary files /dev/null and b/Master/texmf-dist/doc/latex/crossword/cwpuzzle.pdf differ diff --git a/Master/texmf-dist/source/latex/crossword/AcrossLite/README b/Master/texmf-dist/source/latex/crossword/AcrossLite/README new file mode 100644 index 00000000000..8555f2a213a --- /dev/null +++ b/Master/texmf-dist/source/latex/crossword/AcrossLite/README @@ -0,0 +1,143 @@ +Here are three programs and a script for use with Gerd +Neugebauer's excellent cwpuzzle.sty package for typesetting +crossword puzzles in LaTeX. + +The purpose of the programs is to convert the popular +Across Lite(R) puzzle formats, both binary and text, to +LaTeX input suitable for use with Gerd's package. + +Build the programs like this: + +gcc -o nytconv nytconv.c +gcc -o nytsconv nytsconv.c +gcc -o usaconv usaconv.c + +1. nytconv + +This program converts Across Lite(R) binary puzzle files: + +nytconv puzzlefile.puz >puzzlefile.tex + +where of course 'puzzlefile' is the name of the binary +input file. The program is best suited to puzzles up to +size 15x15, which is the standard daily puzzle size for +the New York Times. NYT puzzles are distributed from their +web site in Across Lite binary format. The web site is +http://www.nytimes.com but registration (currently free) +is needed to access the contents of the site. + +2. nytsconv + +This program is very similar to the previous one except +it's for the larger Sunday puzzles, up to about 23x23. + +nytsconv puzzlefile.puz >puzzlefile.tex + +3. usaconv + +This program converts Across Lite(R) text files. Puzzles +such as the USA Today daily puzzle and the Times of London +daily puzzle are converted to LaTeX input via a two step +process. You should go to the Across Lite web site, +http://www.litsoft.com to pick up a USA Today conversion +program and a Times of London conversion program. You can +then pick up the puzzles (http://www.usatoday.com, or +http://www.the-times.co.uk), convert to Across Lite text form, +and then convert to LaTeX. + +usaconv puzzlefile.txt >puzzlefile.tex + +Well, you might say, what's the point? There are several. +I don't want to solve crosswords on screen; I want printed +copy to work with. So, why not just print from the Across +Lite program? Because (1) I'm a LaTeX fanatic, and more +importantly (2) I use an automated procedure to download +the NYT and USA puzzles every morning, format them, and +ready them for printing whenever I want a fresh puzzle! +The only work I have to do is to actually solve the +puzzle. (I don't have the skill needed to solve difficult +cryptics such as the Times of London puzzles so I don't +download them regularly.) + +Another important point is generating your own crosswords +with computerized tools. Tools such as Crossword Express +(http://www.puzzledepot.com/cwe) help you to produce +crosswords quickly and effectively. One of the output +format is Across Lite binary. This can then be converted +(with the nyt- or nyts- conversion program, depending on +puzzle size) and dropped into a LaTeX document. This is +nice for newsletters, educational material, etc. + +There is still another possibility using postscript tools +usually found on Unix systems. You might collect, say, +100 puzzles, convert them all to LaTeX input, and process +them. Then you can use tools such as psbook to make books +of puzzles to take along on boring business trips or +interesting vacation trips. + +For those of you with an interest, here is my automated +Perl script for downloading and formatting puzzles. It +requires the program 'wget' which can be found at +ftp://gnjilux.cc.fer.hr/pub/unix/util/wget/ +(This site is sometimes hard to reach. Keep trying. Or +contact me for alternatives.) + +Now, the script, which will require local site modification: +--------------- +#!/usr/bin/perl + +chdir("/usr/games/crossword"); +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); + +# NY Times + + $mpart = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)[$mon]; + if ($mday lt 10){$puzzle = $mpart."0".$mday.$year;} + else {$puzzle = $mpart.$mday.$year;} + system("/usr/bin/wget --http-user=myname --http-passwd=secret http://www.nytimes.com/partners/xword/$puzzle.puz"); + if ($wday ne 0) {system("./nytconv $puzzle.puz >$puzzle.tex");} + else {system("./nytsconv $puzzle.puz >$puzzle.tex");} + system("/usr/bin/latex $puzzle"); + if ($wday ne 0) {system("/usr/bin/dvips -x 1400 $puzzle");} + else {system("/usr/bin/dvips -x 1100 $puzzle");} + system("/usr/bin/psnup -l -2 -pletter $puzzle.ps $puzzle.wps"); + system("echo \"quit\" >>$puzzle.wps"); + system("/usr/bin/gs -q -sDEVICE=laserjet -r300 -dQUIET -dNOPAUSE -sOutputFile=$puzzle.lj $puzzle.wps "); + system("gzip -9 -f $puzzle.lj"); + system("/bin/rm *dvi *ps *log *aux *tex"); + +# USA Today + +if ($wday ne 6 && $wday ne 0) { # no weekend puzzles + $month = $mon + 1; + if ($month lt 10) {$directory = $year."0".$month;} + else {$directory = $year.$month;} + if ($mday lt 10){$puzzle = "ut".$directory."0".$mday;} + else {$puzzle = "ut".$directory.$mday;} + system("/usr/bin/wget http://www.usatoday.com/life/puzzles/$directory/$puzzle.puz"); + system("./usa-acl $puzzle.puz $puzzle.txt"); + system("./usaconv $puzzle.txt >$puzzle.tex"); + system("/usr/bin/latex $puzzle"); + system("/usr/bin/dvips -x 1400 $puzzle"); + system("/usr/bin/psnup -l -2 -pletter $puzzle.ps $puzzle.wps"); + system("echo \"quit\" >>$puzzle.wps"); + system("/usr/bin/gs -q -sDEVICE=laserjet -r300 -dQUIET -dNOPAUSE -sOutputFile=$puzzle.lj $puzzle.wps "); + system("gzip -9 -f $puzzle.lj"); + system("/bin/rm *dvi *ps *log *aux *tex *txt"); +} + +exit; +-------------- + +For any questions, bug reports, or especially improvements, please +contact me: + +bnewell@btigate.com +http://www.btigate.com/~bnewell + + +Bob Newell +Bismarck, North Dakota +28 November, 1996 + + diff --git a/Master/texmf-dist/source/latex/crossword/AcrossLite/nytconv.c b/Master/texmf-dist/source/latex/crossword/AcrossLite/nytconv.c new file mode 100644 index 00000000000..2956d29b345 --- /dev/null +++ b/Master/texmf-dist/source/latex/crossword/AcrossLite/nytconv.c @@ -0,0 +1,202 @@ + +#include +#include +#include +#include +#define ROWSIZE 256 + +FILE *infile; +int width, height, j, k, ccount, mcount, anum, dnum; +int apos, dpos; + +char inbuf[ROWSIZE]; + +/* Here is a lazy programmer's waste of space. */ +char aspace[ROWSIZE][ROWSIZE]; +char dspace[ROWSIZE][ROWSIZE]; + +char rowtext[10*ROWSIZE]; +char tmp[ROWSIZE]; + +char title[80]; +char author[80]; +char copyright[80]; +char matrix[ROWSIZE*ROWSIZE*10]; +char aclues[ROWSIZE*15*16]; +char dclues[ROWSIZE*15*16]; + +void fgetaline(char *, FILE *); + +void main(int argc, char *argv[]) +{ + +/* Open the puzzle file. */ + if (argc < 2) { + printf("Usage: Acl2TeX \n"); + exit(1); + } + infile = fopen(argv[1], "rb"); + if (infile == NULL) { + printf("Error opening %s.\n"); + exit(1); + } + +/* From here on we're assuming a non-corrupt puzzle file. + An enhancement later could be to check for this. */ + +/* Read in the puzzle size, skipping the stuff + we don't understand. */ + fread(inbuf, 46, 1, infile); + width = (int)(inbuf[44]); + height = (int)(inbuf[45]); + +/* Read in the solution, assuming(!) it is not scrambled. + This may be a bad idea but we do it anyhow. */ + fread(inbuf, 6, 1, infile); /* more basura */ + for (j=0; j=0 && dspace[j][k]=='-' + && dspace[j][k-1]=='.' + && dspace[j][k+1]=='-' ) + ){ + ccount++; + anum = ccount; + } + /* Analyze position for down-number */ + dnum = 0; + /* Top row non-black followed by non-black */ + if ( (j==0 && dspace[j][k]=='-' && dspace[j+1][k]=='-') || + /* Black above - nonblack - nonblack below */ + ( (j-1)>=0 && (j+1) +#include +#include +#include +#define ROWSIZE 256 + +FILE *infile; +int width, height, j, k, ccount, mcount, anum, dnum; +int apos, dpos; + +char inbuf[ROWSIZE]; + +/* Here is a lazy programmer's waste of space. */ +char aspace[ROWSIZE][ROWSIZE]; +char dspace[ROWSIZE][ROWSIZE]; + +char rowtext[10*ROWSIZE]; +char tmp[ROWSIZE]; + +char title[80]; +char author[80]; +char copyright[80]; +char matrix[ROWSIZE*ROWSIZE*10]; +char aclues[ROWSIZE*15*16]; +char dclues[ROWSIZE*15*16]; + +void fgetaline(char *, FILE *); + +void main(int argc, char *argv[]) +{ + +/* Open the puzzle file. */ + if (argc < 2) { + printf("Usage: Acl2TeX \n"); + exit(1); + } + infile = fopen(argv[1], "rb"); + if (infile == NULL) { + printf("Error opening %s.\n"); + exit(1); + } + +/* From here on we're assuming a non-corrupt puzzle file. + An enhancement later could be to check for this. */ + +/* Read in the puzzle size, skipping the stuff + we don't understand. */ + fread(inbuf, 46, 1, infile); + width = (int)(inbuf[44]); + height = (int)(inbuf[45]); + +/* Read in the solution, assuming(!) it is not scrambled. + This may be a bad idea but we do it anyhow. */ + fread(inbuf, 6, 1, infile); /* more basura */ + for (j=0; j=0 && dspace[j][k]=='-' + && dspace[j][k-1]=='.' + && dspace[j][k+1]=='-' ) + ){ + ccount++; + anum = ccount; + } + /* Analyze position for down-number */ + dnum = 0; + /* Top row non-black followed by non-black */ + if ( (j==0 && dspace[j][k]=='-' && dspace[j+1][k]=='-') || + /* Black above - nonblack - nonblack below */ + ( (j-1)>=0 && (j+1) +#include +#include +#include +#define ROWSIZE 256 + +FILE *infile; +int width, height, j, k, ccount, mcount, anum, dnum; +int apos, dpos; +int acount, dcount; + +char inbuf[ROWSIZE]; + +/* Here is a lazy programmer's waste of space. */ +char aspace[ROWSIZE][ROWSIZE]; +char dspace[ROWSIZE][ROWSIZE]; + +char rowtext[10*ROWSIZE]; +char tmp[ROWSIZE]; + +char title[80]; +char author[80]; +char copyright[80]; +char matrix[ROWSIZE*ROWSIZE*10]; +char actext[ROWSIZE][80]; +char dctext[ROWSIZE][80]; +char aclues[ROWSIZE*15*16]; +char dclues[ROWSIZE*15*16]; + +void fgetsa(char *, int, FILE *); + +void main(int argc, char *argv[]) +{ + +/* Open the puzzle file. */ + if (argc < 2) { + printf("Usage: usaconv \n"); + exit(1); + } + infile = fopen(argv[1], "r"); + if (infile == NULL) { + printf("Error opening %s.\n"); + exit(1); + } + +/* From here on we're assuming a non-corrupt puzzle file. + An enhancement later could be to check for this. */ + +/* start reading stuff in */ + fgetsa(inbuf, 80, infile); /**/ + fgetsa(inbuf, 80, infile); /**/ + fgetsa(title, 80, infile); + fgetsa(inbuf, 80, infile); /*<AUTHOR>*/ + fgetsa(author, 80, infile); + fgetsa(inbuf, 80, infile); /*<COPYRIGHT>*/ + fgetsa(copyright,80, infile); + fgetsa(inbuf, 80, infile); /*<SIZE>*/ + + fgetsa(inbuf, 80, infile); + height = width = 0 ; /* we calculate instead */ + + fgetsa(inbuf, 80, infile); /*<GRID>*/ + +/* Read in the first line of the solution/diagram and determine width */ + fgetsa(&aspace[height][0], 80, infile); + width = strlen(&aspace[height][0]); + height++; + while (1) { + fgetsa(&aspace[height][0], 80, infile); + if(strcmp(&aspace[height][0],"<ACROSS>")==0) goto didit; + height++; + } +didit: + /* Read and save across and down clues */ + + apos=dpos=0; + while(1) { + fgetsa(&actext[apos][0], 80, infile); + if(strcmp(&actext[apos][0],"<DOWN>")==0)goto dida; + apos++; + } +dida: + while(1) { + fgetsa(&dctext[dpos][0], 80, infile); + if(feof(infile)) goto didd; + dpos++; + } +didd: + apos=dpos=0; + +/* Now we are ready to produce the LaTeX stuff for the + puzzle diagram. Again we are assuming we have an unscrambled + solution. How can we know this? Put on TODO list. */ + +/* We write to standard out. Lazy but effective. */ + + printf("\\documentclass{article}\n"); + printf("\\usepackage{cwpuzzle}\n"); + printf("\\title{%s}\n", title); + printf("\\author{%s}\n", author); + printf("\\date{%s}\n", copyright); + printf("\\voffset -1in\n"); + printf("\\hoffset -1in\n"); + printf("\\begin{document}\n"); + + ccount = 0; + mcount = 0; + acount = dcount = 0; + + for (j=0; j<height; j++) { + strcpy(rowtext,"\0"); + for (k=0; k<width; k++) { + /* Analyze position for across-number */ + /* Left edge non-black followed by non-black */ + anum = 0; + if ( (k==0 && aspace[j][k]!='.' && aspace[j][k+1]!='.') || + /* Previous black - nonblack - nonblack */ + ( (k+1)<width && (k-1)>=0 && aspace[j][k]!='.' + && aspace[j][k-1]=='.' + && aspace[j][k+1]!='.' ) + ){ + ccount++; + anum = ccount; + } + /* Analyze position for down-number */ + dnum = 0; + /* Top row non-black followed by non-black */ + if ( (j==0 && aspace[j][k]!='.' && aspace[j+1][k]!='.') || + /* Black above - nonblack - nonblack below */ + ( (j-1)>=0 && (j+1)<height && aspace[j][k]!='.' + && aspace[j-1][k]=='.' + && aspace[j+1][k]!='.' ) + ){ + /* Don't double number the same space */ + if (anum == 0) ccount++; + dnum = ccount; + } + /* Now, if necessary, assign some clues and save them. */ + if (anum != 0) { + sprintf(&aclues[apos], "\\Clue{%d}{}{%s}\\\\\n", + anum, actext[acount]); + acount++; + apos = strlen(aclues); + } + if (dnum != 0) { + sprintf(&dclues[dpos], "\\Clue{%d}{}{%s}\\\\\n", + dnum, dctext[dcount]); + dcount++; + dpos = strlen(dclues); + } + /* Concat the current info to the current row. */ + strcat(rowtext, "|"); + if (aspace[j][k] == '.') strcat(rowtext, "*"); + else { + /* see if we need a grid number */ + if (dnum != 0) { + sprintf(tmp, "[%d]", dnum); + strcat(rowtext, tmp); + } + else if (anum != 0) { + sprintf(tmp, "[%d]", anum); + strcat(rowtext, tmp); + } + /* Put in solution letter */ +/* this is for real */ if (aspace[j][k]== '&') strncat(rowtext, "\\", 1); + strncat(rowtext, &aspace[j][k], 1); + } + } + /* End of the row. Put in marker and output it. */ + strcat(rowtext, "|."); + sprintf(&matrix[mcount], "%s\n", rowtext); + mcount = strlen(matrix); + } + /* That's it for the puzzle. */ + + /* Now output the clue section */ + printf("\\begin{PuzzleClues}{\\textbf{Across}}\\\\\n"); + for (j=0; j<strlen(aclues); j++){ + printf("%c",aclues[j]); + } + printf("\\end{PuzzleClues}\n"); + printf("\\begin{PuzzleClues}{\\textbf{Down}}\\\\\n"); + for (j=0; j<strlen(dclues); j++){ + printf("%c",dclues[j]); + } + printf("\\end{PuzzleClues}\n"); + + /* Now output the diagram */ + printf("\\newpage\n"); + printf("\\maketitle\n"); + printf("\\begin{Puzzle}{%d}{%d}\n", width, height); + printf("%s", matrix); + printf("\\end{Puzzle}\n"); + + + printf("\\end{document}\n"); + + exit(0); + +} + + void fgetsa(char *foo, int size, FILE *infile) { + int i, oe; + fgets(tmp, size, infile); + tmp[strlen(tmp)-1] = '\0'; + strcpy(foo, "\0"); + oe = 0; + for (i=0; i<strlen(tmp); i++) { + if (tmp[i]=='$' || tmp[i] == '_' || tmp[i] =='&' || tmp[i] == '#') strcat(foo, "\\"); + if (tmp[i] == '"') { + if (oe == 0) { + oe = 1; + strcat(foo, "``"); + } + else { + oe = 0; + strcat(foo, "''"); + } + } + else strncat(foo, &tmp[i], 1); + } + } + + + + + + diff --git a/Master/texmf-dist/source/latex/crossword/Makefile b/Master/texmf-dist/source/latex/crossword/Makefile new file mode 100644 index 00000000000..b1372e38a2a --- /dev/null +++ b/Master/texmf-dist/source/latex/crossword/Makefile @@ -0,0 +1,42 @@ +#****************************************************************************** +#* $Id: Makefile,v 1.5 2006/08/11 19:15:05 gene Exp $ +#****************************************************************************** +#* Author: Gerd Neugebauer +#*============================================================================= + +INSTALLDIR = /usr/local/lib/texmf/tex/latex/cwpuzzle + +FILES = cwpuzzle.dtx \ + cwpuzzle.ins \ + Makefile \ + README + +LATEX = latex +PDFLATEX = pdflatex +MAKEINDEX = makeindex +RM = rm -f +INSTALL = install +MKDIR = mkdir + +#*============================================================================= + +all: cwpuzzle.sty cwpuzzle.pdf + +cwpuzzle.sty sty: cwpuzzle.dtx cwpuzzle.ins + $(RM) cwpuzzle.cls cwpuzzle.sty + $(LATEX) cwpuzzle.ins + +cwpuzzle.dvi dvi: cwpuzzle.dtx cwpuzzle.sty + $(LATEX) cwpuzzle.dtx + $(LATEX) cwpuzzle.dtx + $(MAKEINDEX) -s gind.ist cwpuzzle + $(MAKEINDEX) -s gglo.ist -o cwpuzzle.gls cwpuzzle.glo + $(LATEX) cwpuzzle.dtx + +cwpuzzle.pdf pdf: cwpuzzle.dtx cwpuzzle.sty + $(PDFLATEX) cwpuzzle.dtx + $(PDFLATEX) cwpuzzle.dtx + $(MAKEINDEX) -s gind.ist cwpuzzle + $(MAKEINDEX) -s gglo.ist -o cwpuzzle.gls cwpuzzle.glo + $(PDFLATEX) cwpuzzle.dtx + diff --git a/Master/texmf-dist/source/latex/crossword/cwpuzzle.dtx b/Master/texmf-dist/source/latex/crossword/cwpuzzle.dtx new file mode 100644 index 00000000000..d97e650f3dc --- /dev/null +++ b/Master/texmf-dist/source/latex/crossword/cwpuzzle.dtx @@ -0,0 +1,1774 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% $Id: cwpuzzle.dtx,v 1.7 2009/09/06 15:16:53 gene Exp gene $ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\CWP@RCS$#1: #2 #3${#2} +\def\filename{cwpuzzle.dtx} +\xdef\fileversion{\CWP@RCS$Revision: 1.7 $} +\xdef\filedate{\CWP@RCS$Date: 2009/09/06 15:16:53 $} +\let\docversion=\fileversion +\let\docdate=\filedate +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%\iffalse +\typeout{% +%% Purpose: + Package: cwpuzzle \filedate\space\fileversion\space + for typesetting crossword puzzles. +}% +%% +%% Documentation: +%% The documentation can be generated from the original file +%% cwpuzzle.dtx with the doc style/package. LaTeX the file +%% cwpuzzle.dtx to get the full documentation in dvi format. +%% +%% +%% Author: Gerd Neugebauer +%% Im Lerchelsöhl 5 +%% 64521 Groß-Gerau +%% Mail: gene@gerd-neugebauer.de +%% +%% Copyright (C) 1995-2009 Gerd Neugebauer +%% +%% cwpuzzle.dtx is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY. No author or distributor accepts +%% responsibility to anyone for the consequences of using it or for +%% whether it serves any particular purpose or works at all, unless +%% he says so in writing. +%% +%% Everyone is granted permission to copy, modify and redistribute +%% cwpuzzle.dtx, provided this copyright notice is preserved and +%% any modifications are indicated. +%% +%% +%% This style is still under development and may be replaced with a +%% new version which provides an enhanced functionality. +%% +%<*driver> +\documentclass{ltxdoc} +\usepackage{color} +\usepackage{cwpuzzle} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\setcounter{IndexColumns}2 +\begin{document} + \DocInput{cwpuzzle.dtx} + \newpage + \PrintChanges +\end{document} +%</driver> +%\fi +% +% \title{A \LaTeX\ Package for Typesetting\\ Crossword +% Puzzles\thanks{This file documents \filename\ version +% \fileversion\ as of \filedate.}} +% \author{Gerd Neugebauer\\ +% Im Lerchels\"ohl 5\\ +% 64521 Gro\ss{}-Gerau (Germany)\\ +% Net: {\tt gene@gerd-neugebauer.de}} +% +% \date{{\footnotesize Documentation date: \docdate}} +% +% \maketitle +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \DoNotIndex{\ ,\",\',\.,\,,\[,\\,\],\^,\`,\~,\@,\@dottedtocline} +% \DoNotIndex{\@empty,\@namedef,\@nameuse,\advance,\begin,\begingroup} +% \DoNotIndex{\catcode,\csname,\def,\else,\end,\endcsname,\endgroup} +% \DoNotIndex{\fi,\filedate,\footnotesize,\framebox,\gdef,\global} +% \DoNotIndex{\hfill,\if,\ifx,\large,\let,\makebox,\mbox,\newcommand} +% \DoNotIndex{\newcount,\newdimen,\newenvironment,\newif,\noindent} +% \DoNotIndex{\normalsize,\null,\par,\put,\relax,\renewcommand,\rm,\rule} +% \DoNotIndex{\scriptsize,\sf,\small,\textsf,\textwidth} +% \DoNotIndex{\the,\unitlength,\uppercase,\xdef,\ProvidesPackage} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \changes{1.3}{1996/10/28}{First public release.} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \CheckSum{469} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% \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 \~} +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \MakeShortVerb{|} +% +% \begin{abstract} +% cpwuzzle.dtx provides a package to typeset crossword puzzles. +% The leading philosophy is that the puzzle and the solution are +% typeset from the same source. +% +% The package can be used to produce several types of puzzles like +% the classical crossword puzzle, a number puzzle, and fill-in +% puzzles. In addition to the block separated puzzles the thick +% line delimited puzzles are supported as well. +% \end{abstract} +% +% \tableofcontents +% \newpage +% +% \section{About Crossword Puzzles} +% +% Crossword puzzles are can be a an amusing but also a challenging +% hobby. Unfortunately at the time of this writing I am not aware +% of any good package to typeset crossword puzzles with \LaTeX. +% Thus I decided to make one which at least fits my needs. +% +% There are several types of crossword puzzles among. This +% package can only be used to typeset several of them. The basic +% assumption in this package is that puzzles are rectangular +% arrangements of boxes. Some of these boxes are black and others +% are prepared to take single letters. +% Each word in the grid is enclosed in black boxes or the outside. +% +% Optionally there may be rectangular regions left blank inside the +% puzzle. They can be used to place ads or other informative texts +% inside the puzzle. +% +% \subsection{Classical Crossword Puzzles}\label{sec:classical} +% +% \PuzzleUnsolved +% \begin{minipage}{.35\textwidth}% +% \begin{Puzzle}{5}{3}% +% |* |* |[1]E|X |* |. +% |[2]A|[3]S|T |* |[4]T|. +% |* |[5]P|A |R |T |. +% \end{Puzzle}% +% \end{minipage}% +% \begin{minipage}{.6\textwidth} +% \begin{PuzzleClues}{Across}% +% \Clue{1}{EX}{unit of measure}% +% \Clue{2}{AST}{\(\ast\)}% +% \Clue{5}{PART}{sectioning unit}% +% \end{PuzzleClues}% +% \begin{PuzzleClues}{Down}% +% \Clue{1}{ETA}{\(\eta\)}% +% \Clue{3}{SP}{unit of measure}% +% \Clue{4}{TT}{non-proportional font}% +% \end{PuzzleClues}% +% \end{minipage}\medskip +% +% The ``classical'' type of a crossword puzzle words are marked +% with numbers and each word is accompanied with a clue which +% should help (or confuse) the reader. Those clues are listed after +% the frame of the puzzle. +% +% \subsection{Number Crossword Puzzles}\label{sec:numbered} +% +% \begin{minipage}{.35\textwidth}% +% \begin{Puzzle}{5}{3}% +% |* |* |[6]E|[1]X|* |. +% |[5]A|[2]S|[7]T|* |[7]T|. +% |* |[4]P|[5]A|[3]R|[7]T|. +% \end{Puzzle}% +% \end{minipage}% +% \begin{minipage}{.6\textwidth} +% \PuzzleLetters{AEPRSTX}\medskip\par +% \PuzzleNumbers{XSRPAET}% +% \end{minipage}\medskip +% +% The ``number puzzle'' variant contains only numbers instead of +% letters. Different numbers denote different letters. There are no +% clues. The reader is assumed to find a complete list of letters +% by filling appropriate words into the grid. Sometimes a word is +% already entered into the grid to ease the start. +% +% \subsection{Fill-In Crossword Puzzles}\label{sec:fill-in} +% +% \begin{minipage}{.35\textwidth}% +% \begin{Puzzle}{5}{3}% +% |* |* |E |X |* |. +% |A |S |T |* |T |. +% |* |P |A |R |T |. +% \end{Puzzle}% +% \end{minipage}% +% \begin{minipage}{.6\textwidth} +% \begin{PuzzleWords}{2} +% \Word{EX}% +% \Word{SP}% +% \Word{TT}% +% \end{PuzzleWords}% +% \begin{PuzzleWords}{3} +% \Word{AST}% +% \Word{ETA}% +% \end{PuzzleWords}% +% \begin{PuzzleWords}{4} +% \Word{PART}% +% \end{PuzzleWords}% +% \end{minipage}\medskip +% +% The ``fill-in puzzle'' variant consists of a frame containing +% only black and white boxes. Additionally a list of words is given +% which have to be put into the frame until none is left and the +% frame is completed. +% +% \subsection{Line delimited Crossword Puzzles}\label{sec:line-delimited} +% +% The crossword puzzles we have seen before had the property that +% words are either delimited by the outer border or by a solid +% block. In addition line delimited puzzles are common. In this +% case a thicker line is drawn to indicate the end of a line.\medskip +% +% \noindent +% \begin{minipage}{.35\textwidth}% +% \begin{Puzzle}{5}{3}% +% |[1] c |[2] c |[3][l]e |[4] x |[5] p |. +% |[6] l | o |[][o]t |[7][l]m| u |. +% | o |[][fl]s|[8][l]a | l |[][o]t |. +% \end{Puzzle}% +% \end{minipage}% +% \begin{minipage}{.6\textwidth} +% \begin{PuzzleClues}{Across}% +% \Clue{1}{CC}{unit of measure}% +% \Clue{3}{EXP}{math function}% +% \Clue{6}{LOT}{list of tables}% +% \Clue{7}{MU}{$\mu$}% +% \Clue{8}{ALT}{key}% +% \end{PuzzleClues}% +% \begin{PuzzleClues}{Down}% +% \Clue{1}{CLO}{class option}% +% \Clue{2}{COS}{math function}% +% \Clue{3}{ETA}{\(\eta\)}% +% \Clue{4}{XML}{all in angle brackets}% +% \Clue{5}{PUT}{\LaTeX\ place picture element}% +% \end{PuzzleClues}% +% \end{minipage} +% +% In the example above we can see another feature. This feature is +% that two letters are circled. This can be used to indicate +% letters for a solution word of the crossword puzzle. +% +% +% +% \subsection{Solutions} +% +% \PuzzleSolution +% \begin{minipage}{.35\textwidth}% +% \begin{Puzzle}{5}{3}% +% |* |* |[1]E|X |* |. +% |[2]A|[3]S|T |* |[4]T|. +% |* |[5]P|A |R |T |. +% \end{Puzzle}% +% \end{minipage}% +% \begin{minipage}{.6\textwidth} +% \end{minipage}\medskip +% +% Often it is not only desirable to typeset the unsolved crossword +% puzzle but also the solution. This means that all the letters +% have to be filled in. This should be possible with the same +% source as the questions to avoid typos or redundancies leading to +% additional work. +% +% Several variants of solutions come to mind. Primarily the +% solution should show the letters and suppress any clues. One +% major distinction is also whether or not the numbers of the words +% should be shown in the solution as well.\medskip +% +% \noindent +% \PuzzleSolution[true]% +% \begin{minipage}{.35\textwidth}% +% \begin{Puzzle}{5}{3}% +% |* |* |[1]E|X |* |. +% |[2]A|[3]S|T |* |[4]T|. +% |* |[5]P|A |R |T |. +% \end{Puzzle}% +% \end{minipage}% +% \begin{minipage}{.6\textwidth} +% \end{minipage}% +% +% Finally there are the lists of letters in numbered puzzles. In +% the solution they will show the letters in them as well.\medskip +% +% \noindent +% \PuzzleSolution[false]% +% \begin{minipage}{.35\textwidth}% +% \begin{Puzzle}{5}{3}% +% |* |* |[6]E|[1]X|* |. +% |[5]A|[2]S|[7]T|* |[7]T|. +% |* |[4]P|[5]A|[3]R|[7]T|. +% \end{Puzzle}% +% \end{minipage}% +% \begin{minipage}{.6\textwidth} +% \PuzzleLetters{AEPRSTX}\medskip\par +% \PuzzleNumbers{XSRPAET}% +% \end{minipage} +% +% +% \section{Input of Crossword Puzzles} +% +% The basic idea behind this package is that a crossword puzzle is +% specified in a separate file. The actual appearance of the puzzle +% is controlled by several options. Thus it should be possible to +% produce the unsolved and the solved puzzle from the same +% source. Before we describe the various options we will have a +% look at the basic environments and macros used to specified a +% crossword puzzle. +% +% \DescribeEnv{Puzzle}% +% This package provides the environment |Puzzle| which typesets the +% frame of a crossword puzzle. This environment takes two +% arguments. These arguments are the number of columns and the +% number of the rows of the puzzle. This means that essentially +% only rectangular puzzles can be typeset. +% +% The example from section~\ref{sec:classical} has been entered as +% follows: +% \begin{verbatim} +% \begin{Puzzle}{5}{3}% +% |* |* |[1]E|X |* |. +% |[2]A|[3]S|T |* |[4]T|. +% |* |[5]P|A |R |T |. +% \end{Puzzle} +% \end{verbatim} +% In this example we can see that inside the |Puzzle| environment +% there is one special character. This is the bar \verb/|/. This +% bar is an active character in \TeX. Thus you can think of it +% like a macro. +% +% The \verb/|/ macro takes three arguments. The first two arguments +% are optional, i.e. enclosed in brackets if present. The first +% optional argument denotes the number for numbered boxes. The +% second optional argument specifies the formatting of the cell. +% +% The third argument is either empty |{}| or it consists of a +% single character. This argument describes the action to be +% performed. +% +% \begin{itemize} +% \item If this argument is a letter then it is simply shown +% in the solution and suppressed in the unsolved crossword puzzle. +% +% \item If this argument is an asterisk |*| then a black box is +% produced. +% +% \item If this argument is a dot |.| then this marks the end of +% the current row. The next box is typeset at the beginning of the +% following row. +% +% \item If this argument is empty |{}| then a white box is +% typeset. This box does not contain a letter, nor does it have a +% frame. This macro can be used to leave room for larger boxed with +% ads. Alternatively this can be used to disable certain boxes to +% make a non-rectangular crossword puzzle. +% \end{itemize} +% +% \begin{verbatim} +% \begin{Puzzle}{5}{5} +% |{} |{} |[1]S|. +% |{} |[2]M|I |[3]D|. +% |[4]T|I |M |E |S |. +% |{} |[5]N|E |G |. +% |{} |{} |Q |. +% \end{Puzzle} +% \end{verbatim} +% \PuzzleUnsolved +% \begin{minipage}{.35\textwidth}% +% \begin{Puzzle}{5}{5}% +% |{} |{} |[1]S|. +% |{} |[2]M|I |[3]D|. +% |[4]T|I |M |E |S |. +% |{} |[5]N|E |G |. +% |{} |{} |Q |. +% \end{Puzzle}% +% \end{minipage}% +% \begin{minipage}{.6\textwidth} +% \begin{PuzzleClues}{\textbf{Across: }}% +% \Clue{2}{MID}{\(\mid\)}% +% \Clue{4}{TIMES}{\(\times\)}% +% \Clue{5}{NEG}{\(\neg\)}% +% \end{PuzzleClues}% +% \begin{PuzzleClues}{\textbf{Down: }}% +% \Clue{1}{SIMEQ}{\(\simeq\)}% +% \Clue{2}{MIN}{log-like function}% +% \Clue{3}{DEG}{log-like function}% +% \end{PuzzleClues}% +% \end{minipage}% +% +% Note that white-space is ignored after the arguments but not +% between the bar and the arguments. +% \bigskip +% +% The formatting of the cell is controlled by the second optional +% argument of the \verb/|/ macro. This optional argument may +% contain a list of several characters. Each of these characters is +% interpreted from left to right. The following list describes the +% meaning of the built-in characters.\medskip +% +% \PuzzleUnsolved +% \newenvironment{CellLetter}[1]{\par\noindent +% \begin{minipage}{.25\textwidth} +% \let\PuzzlePre\relax +% \let\PuzzlePost\relax +% \begin{Puzzle}{1}{1}|[8][#1]X +% \end{Puzzle}\tt\quad +% \char`\|[8][#1]X +% \end{minipage}% +% \begin{minipage}{.7\textwidth} +% }{\end{minipage}\smallskip}% +% \begin{CellLetter}{f} +% The letter f produces a simple frame around the cell. This is +% the default if nothing is specified. +% \end{CellLetter}% +% \begin{CellLetter}{.} +% The character . produces no additional rendering it can be used +% to overwrite the default rendering which is to place a frame +% around the cell. +% \end{CellLetter}% +% \begin{CellLetter}{*} +% The character * produces a black box. This is the same effect +% which can be achieved by providing the character * to be filled +% into the cell for the solution. +% \end{CellLetter}% +% \begin{CellLetter}{O} +% The letter O produces an oval as drawn with the \LaTeX\ macro +% \verb/\oval/. +% \end{CellLetter}% +% \begin{CellLetter}{o} +% The letter o produces an oval inside a frame. T is is an +% abbreviation for the two letters fO. +% \end{CellLetter}% +% \begin{CellLetter}{t} +% The letter t produces a frame with a thicker line at the top. +% The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \end{CellLetter}% +% \begin{CellLetter}{T} +% The letter T produces a thicker line at the top of the cell. +% The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \end{CellLetter}% +% \begin{CellLetter}{b} +% The letter b produces a frame with a thicker line at the bottom. +% The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \end{CellLetter}% +% \begin{CellLetter}{B} +% The letter B produces a thicker line at the bottom of the cell. +% The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \end{CellLetter}% +% \begin{CellLetter}{l} +% The letter l produces a frame with a thicker line at the left +% side of the cell. The thickness of this line is controlled by +% the macro |\PuzzleThickline|. +% \end{CellLetter}% +% \begin{CellLetter}{L} +% The letter L produces a thicker line at the left side of the +% cell. The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \end{CellLetter}% +% \begin{CellLetter}{r} +% The letter r produces a frame with a thicker line at the right +% side of the cell. The thickness of this line is controlled by +% the macro |\PuzzleThickline|. +% \end{CellLetter}% +% \begin{CellLetter}{R} +% The letter R produces a thicker line at the right side of the +% cell. The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \end{CellLetter}% +% \begin{CellLetter}{/} +% The character / produces a line crossing the cell from lower +% left to upper right. +% \end{CellLetter}% +% \begin{CellLetter}{,} +% The character , produces a line crossing the cell from upper +% left to lower right. +% \end{CellLetter}% +% \begin{CellLetter}{S} +% The character S produces the solution, i.e. the content of the +% cell is typeset. No decorations are placed around. For this +% purpose it should be combined with some other formatting +% characters. +% \end{CellLetter}% +% +% Whenever you try to use an undefined specification for the cell +% frame a warning is printed and the letter is ignored. +% +% \DescribeMacro{\PuzzleDefineCell} +% You can define additional cell renderings of your own. For this +% purpose the macro |\PuzzleDefineCell| is provided. It takes two +% arguments. The first argument contains the key under which the +% rendering should be addressed in the optional second argument of +% the macro \verb/|/. The second argument contains the replacement +% text like in |\newcommand|. This replacement text can make use of +% two arguments. They are addressed with |#1| and |#2|. The first +% one contains the x coordinate of the cell to be rendered. The +% second one its y coordinate. +% +% The following example shows for instance the definition of a new +% cell type addressed by the key + which draws a thick frame around +% the cell. +% \begin{verbatim} +% \PuzzleDefineCell{+}{ +% \PuzzleThicklines +% \put(#1,#2){\framebox(1,1){}} +% } +% \end{verbatim} +% +% +% Finally we show how to define a cell type consisting of a colored +% box. The box itself is drawn with the help of the macro +% |\colorbox|. Thus it is necessary to load the package +% \texttt{color} which defines this macro. +% +% The two invocations show the combination with the f specifier. +% The specifier f is the default and used only if the user does not +% provide the optional argument. Thus we need to provide the f we +% we want to have it additionally.\medskip +% +% \noindent +% \begin{minipage}{.65\textwidth}\small +% \begin{verbatim} +% \definecolor{gray}{gray}{.9} +% \PuzzleDefineCell{c}{{% +% \put(#1,#2){\makebox(1,1){% +% \fboxsep=0pt +% \colorbox{gray}{\makebox(1,1){}}}} +% }} +% \begin{Puzzle}{2}{2} +% |[1][cf]X | {} |. +% |{} |[2][c]X |. +% \end{Puzzle} +% \end{verbatim} +% \end{minipage}\hfill +% \begin{minipage}{.30\textwidth} +% \definecolor{gray}{gray}{.9} +% \PuzzleDefineCell{c}{{% +% \fboxsep=0pt +% \put(#1,#2){\makebox(1,1){\colorbox{gray}{\makebox(1,1){}}}} +% }} +% \begin{Puzzle}{2}{2} +% |[1][cf]X | {} |. +% |{} |[2][c]X |. +% \end{Puzzle} +% \end{minipage} +% +% \DescribeMacro{\DefineColorCell} +% The macro |\DefineColorCell| simplifies this task by +% encapsulating the definition above. It has two arguments. The +% first one is the key character and the second one is th name of +% the color to use for the background.\medskip +% +% \noindent +% \begin{minipage}{.65\textwidth}\small +% \begin{verbatim} +% \definecolor{gray}{gray}{.9} +% \PuzzleDefineColorCell{g}{gray} +% \begin{Puzzle}{2}{2} +% |{} |[1][cf]X |. +% |[2][c]X |{} |. +% \end{Puzzle} +% \end{verbatim} +% \end{minipage}\hfill +% \begin{minipage}{.30\textwidth} +% \definecolor{gray}{gray}{.9} +% \PuzzleDefineColorCell{g}{gray} +% \begin{Puzzle}{2}{2} +% |{} |[1][cf]X |. +% |[2][c]X |{} |. +% \end{Puzzle} +% \end{minipage} +% +% \DescribeMacro{\Frame} +% The macro |\Frame| can be used to typeset ads or other text into +% larger boxes inside the frame of the crossword puzzle. For this +% purpose five arguments are required. The first two arguments are +% used to specify the lower left corner of the frame. The lower +% left corner has the coordinates 0,0 and the numbers increase +% upwards and to the right. +% +% The third argument is the width of the frame and the fourth +% argument is the height of the frame measured in number of boxes. +% Finally, the fifth argument contains the text to be typeset. Per +% default it is typeset in a mini-page of the appropriate width +% centered horizontally and vertically. +% +% \begin{verbatim} +% \begin{Puzzle}{8}{6} +% \Frame{2}{2}{4}{2}{\sf Crossword\\Puzzle} +% |[1]E|* |[2]N |U |L |[3]L |* |[4]V|. +% |[5]T|[6]R|I |A |N |G |[7]L|E |. +% |A |U |{} |{} |{} |{} |[8]C|C |. +% |* |L |{} |{} |{} |{} |E |* |. +% |[9]B|E |T |[10]A|* |[11]L|I |M |. +% |F |* |[12]L|A |B |E |L |* |. +% \end{Puzzle} +% \end{verbatim} +% +% \PuzzleUnsolved\noindent +% \begin{minipage}{.5\textwidth}\PuzzleUnitlength=18pt +% \begin{Puzzle}{8}{6}% +% \Frame{2}{2}{4}{2}{\sf Crossword\\Puzzle}% +% |[1]E|* |[2]N|U|L|[3]L|* |[4]V|. +% |[5]T|[6]R|I|A|N|G|[7]L|E|. +% |A|U|{}|{}|{}|{}|[8]C|C|. +% |* |L|{}|{}|{}|{}|E|* |. +% |[9]B|E|T|[10]A|* |[11]L|I|M|. +% |F|* |[12]L|A|B|E|L|* |. +% \end{Puzzle}% +% \end{minipage}% +% \begin{minipage}{.47\textwidth} +% \begin{PuzzleClues}{\textbf{Across: }}% +% \Clue{2}{NULL}{empty}% +% \Clue{5}{TRIANGLE}{\(\triangle\)}% +% \Clue{8}{CC}{carbon copy (letter.sty)}% +% \Clue{9}{BETA}{\(\beta\)}% +% \Clue{11}{LIM}{limes}% +% \Clue{12}{LABEL}{mark it}% +% \end{PuzzleClues}% +% \begin{PuzzleClues}{\textbf{Down: }}% +% \Clue{1}{ETA}{\(\eta\)}% +% \Clue{2}{NI}{\(\ni\)}% +% \Clue{3}{LG}{logarithm}% +% \Clue{4}{VEC}{\(\vec{}\)}% +% \Clue{6}{RULE}{black rectangle}% +% \Clue{7}{LCEIL}{\(\lceil\)}% +% \Clue{9}{BF}{bold face}% +% \Clue{10}{AA}{\AA}% +% \Clue{11}{LE}{\(\le\)}% +% \end{PuzzleClues}% +% \end{minipage}% +% +% +% \DescribeEnv{PuzzleClues} +% The clues in the classical crossword puzzle are typeset with the +% use of the environment |PuzzleClues|. This environment takes one +% argument which is typeset before the clues. The environment takes +% roughly the half of the text width and make a mini-page with this +% width. Thus two invocations of this environment are typeset side +% by side. +% +% Alternatively if the solution is typeset then the environment +% |PuzzleClues| has no effect. +% +% \begin{verbatim} +% \begin{PuzzleClues}{\textbf{Across}}% +% \Clue{1}{EX}{unit of measure}% +% \Clue{2}{AST}{\(\ast\)}% +% \Clue{5}{PART}{sectioning unit}% +% \end{PuzzleClues}% +% \begin{PuzzleClues}{\textbf{Down}}% +% \Clue{1}{ETA}{\(\eta\)}% +% \Clue{3}{SP}{unit of measure}% +% \Clue{4}{TT}{nonproportional font}% +% \end{PuzzleClues}% +% \end{verbatim} +% +% \DescribeMacro{Clue} +% The environment |PuzzleClues| defines one local macro. This macro +% is named |\Clue| and takes three arguments. The first argument is +% the number of the word. This should correspond to the number in +% the puzzle frame. The second argument is the word itself. +% Currently this not used at all. Finally the third argument is the +% clue for the word. +% +% If the unsolved puzzle is typeset then the first and the third +% argument are used. Otherwise all arguments are silently absorbed. +% +% \DescribeMacro{\PuzzleLetters} +% The macro |\PuzzleLetters| can be used to typeset the list of +% used letters in numbered crossword puzzles. It has one argument +% which are the used letters (preferably in alphabetical order. +% +% \DescribeMacro{\PuzzleNumbers} +% The macro |\PuzzleNumbers| can be used to generate a numbered +% list of boxes for the numbered crossword puzzles. The user is +% supposed to collect the found letters here. +% +% \DescribeEnv{PuzzleWords} +% The environment |PuzzleWords| can be sued to typeset the list of +% words for a fill-in puzzle. It takes one argument. This is the +% length of the words listed. For each length there should be an +% invocation of this environment. The words in this environment are +% supposed to be ordered alphabetically. +% +% \DescribeMacro{\Word} +% The macro |\Word| is defined inside the environment +% |PuzzleWords|. It takes one argument which is the word itself. +% +% \begin{verbatim} +% \begin{PuzzleWords}{2} +% \Word{EX}% +% \Word{SP}% +% \Word{TT}% +% \end{PuzzleWords}% +% \begin{PuzzleWords}{3} +% \Word{AST}% +% \Word{ETA}% +% \end{PuzzleWords}% +% \begin{PuzzleWords}{4} +% \Word{PART}% +% \end{PuzzleWords}% +% \end{verbatim} +% +% +% \section{Parameters and Options} +% +% The package cwpuzzle can be controlled by a rich set of macros. +% In addition some settings can be performed with style options. The +% following style options are recognized: +% \begin{description} +% \item [numbered] +% The solution numbering is turned on. +% \item [nocenter] +% The puzzle is not typeset in a centered paragraph of its own. +% \item [unboxed] +% The clues are not enclosed in mini-pages and centered on the +% page. +% \item [normalsize] +% The puzzle is set in normalsize. This is the default. +% \item [small] +% The puzzle is set in small. The size of the cell and the font +% size of the solution are adjusted accordingly. +% \item [large] +% The puzzle is set in large. The size of the cell and the font +% size of the solution are adjusted accordingly. +% \item [german] +% \item [ngerman] +% The build in texts are switched to german variants. The +% defaults are English. This options is also in effect when given +% to the document class. The style inherits it from there. +% \end{description} +% +% The style options can be passed to the style in the usual way: +% \begin{verbatim} +% \usepackage[nocenter,unboxed,small]{cwpuzzle} +% \end{verbatim} +% +% The fine tuning can be achieved with the help of several macros. +% Those macros are described below. +% +% \DescribeMacro{\PuzzleUnitlength} +% The length |\PuzzleUnitlength| determines the width and height of +% each single box in the frame of a crossword puzzle. The default +% value is |20pt|. +% +% \DescribeMacro{\PuzzleBlackBox} +% The macro |\PuzzleBlackBox| contains the commands to produce the +% black boxes. It has to produce at most of width and height of +% |\PuzzleUnitlength|. Per default it just produces a black +% rectangle of this size. +% +% The following list shows some variants which can be achieved by +% redefining the macro |\PuzzleBlackBox|.\medskip +% +% \noindent +% \unitlength=\PuzzleUnitlength +% \framebox(1,1){\rule{.75\PuzzleUnitlength}{.75\PuzzleUnitlength}} +% \hfill +% \begin{minipage}{.9\textwidth} +% \begin{verbatim} +% \renewcommand{\PuzzleBlackBox}{\rule{.75\PuzzleUnitlength}% +% {.75\PuzzleUnitlength}} +% \end{verbatim} +% \end{minipage} +% +% \noindent +% \framebox(1,1){\framebox(.75,.75){\framebox(.5,.5){}}} +% \hfill +% \begin{minipage}{.9\textwidth} +% \begin{verbatim} +% \renewcommand{\PuzzleBlackBox}{\framebox(.75,.75){% +% \framebox(.5,.5){}}} +% \end{verbatim} +% \end{minipage} +% +% Additional effects can be achieved by using shades of gray (with +% the |graphics| package). +% +% \DescribeMacro{\PuzzleFont} +% The macro |\PuzzleFont| contains the font changing +% command issued before the frame of the crossword puzzle. +% +% \DescribeMacro{\PuzzleNumberFont} +% The macro |\PuzzleNumberFont| contains the font changing +% command issued before a number in the frame of the crossword +% puzzle is typeset. +% +% \DescribeMacro{\PuzzleClueFont} +% The macro |\PuzzleClueFont| contains the font changing +% command issued before the clues are typeset. +% +% \DescribeMacro{\PuzzleWordsText} +% The macro |\PuzzleWordsText| contains the text which is typeset +% at the beginning of the environment |PuzzleWords|. It has one +% argument which contains the length of the words listed. +% +% \DescribeMacro{\PuzzleLettersText} +% The macro |\PuzzleLettersText| contains the text which is typeset +% at the beginning of the macro |\PuzzleLetters|. +% +% \DescribeMacro{\PuzzleSolution} +% The macro |\PuzzleSolution| arranges everything that the +% following puzzles are typeset in the ``solution'' mode, i.e. the +% letters are shown and the clues are suppressed. +% +% This macros has one optional argument which has to be |true| or +% |false|. This argument determines whether or not the numbers +% should also be shown in the solution. The default is |false| +% which means that the numbers are suppressed in the solution. +% +% \DescribeMacro{\PuzzleUnsolved} +% The macro |\PuzzleUnsolved| arranges everything that the +% following puzzles are typeset in the ``unsolved'' mode, i.e. the +% letters are suppressed and the clues are shown. +% +% \DescribeMacro{\PuzzlePutNumber} +% The macro |\PuzzlePutNumber| is a configuration macro which +% typesets the number in a cell. The first argument is the x +% coordinate. The second argument is the y coordinate. The third +% argument is the number to be typeset. The coordinates are integer +% numbers. The coordinate (0,0) is the lower left corner. +% +% \DescribeMacro{\PuzzleHook} +% The macro |\PuzzleHook| is called at the end of the |Puzzle| +% environment. It can be used to place additional graphical +% elements in the puzzle frame. +% +% The following example shows a crossword puzzle which we have seen +% before and the definition for the |\PuzzleHook|.\medskip +% +% \PuzzleUnsolved +% \begin{minipage}{.35\textwidth}% +% \newcommand\PuzzleHook{% +% \put(0,2){\line(1,-1){2}} +% \put(0,3){\line(1,1){2}} +% \put(5,2){\line(-1,-1){2}} +% \put(5,3){\line(-1,1){2}} +% } +% \begin{Puzzle}{5}{5}% +% |{} |{} |[1]S|. +% |{} |[2]M|I |[3]D|. +% |[4]T|I |M |E |S |. +% |{} |[5]N|E |G |. +% |{} |{} |Q |. +% \end{Puzzle}% +% \end{minipage}% +% \begin{minipage}{.6\textwidth} +% \begin{verbatim} +% \newcommand\PuzzleHook{ +% \put(0,2){\line(1,-1){2}} +% \put(0,3){\line(1,1){2}} +% \put(5,2){\line(-1,-1){2}} +% \put(5,3){\line(-1,1){2}} +% } +% \end{verbatim} +% \end{minipage} +% +% \DescribeMacro{\PuzzleLineThickness} +% The macro |\PuzzleLineThickness| contains the width of the line +% used to frame the cells. +% +% \DescribeMacro{\PuzzlePre} +% This macro contains the code to be inserted before a puzzle is +% typeset. It is initialized to begin a new paragraph and center the +% puzzle. +% +% \DescribeMacro{\PuzzlePost} +% This macro contains the code to be inserted after a puzzle is +% typeset. It is initialized to end the paragraph and center the +% puzzle. +% +% \DescribeMacro{\PuzzleCluePre} +% This macro contains the code to be inserted before the clues are +% typeset in normal mode. It is initialized to end the paragraph +% and center the puzzle. +% +% \DescribeMacro{\PuzzleCluePost} +% This macro contains the code to be inserted after the clues are +% typeset in normal mode. It is initialized to end the paragraph +% and center the puzzle. +% +% \DescribeMacro{\PuzzleContent} +% This macro contains the content of a cell during formatting this +% cell. This enables the cell formating macro to access it. +% +% +% \section{Further Plans} +% +% Maybe I will add a mode for further variants of crossword puzzles +% sometimes. +% +% Maybe I can add support for further languages if someone provides +% the appropriate texts. Contributions are welcome. +% +% +% \subsection{The Related Program} +% +% There is a related program written in Perl/Tk. This program can be +% used to manually construct crossword puzzles and save them in a +% format suitable for this package. +% Other features include the creation of a proper frame and filling +% with words. +% +% Right now I have not prepared a distribution of this program yet +% since this program requires dictionaries which I can not +% distribute legally. +% +% The examples in this documentation have been computed with the +% help of the |cwp| program. +% +% +% +% \StopEventually{} +% \newpage +% +% +% \section{The Implementation} +% +% The crossword puzzle is basically implemented with the \LaTeX{} +% picture environment. This gives us enough flexibility and +% provides an high enough abstraction such that we do not have to +% fiddle around with to many low level details. +% +% The natural unit in a crossword puzzle is a box which is empty +% or black. Thus the |unitlength| is set to the width (and height) +% of such a box. +% +% +% \subsection{Basic Definitions and Parameters} +% +% First we identify this package. +% +% \begin{macrocode} +\ProvidesPackage{cwpuzzle}[\filedate gene] +% \end{macrocode} +% +% The dimen register |\PuzzleUnitlength| stores the height and +% width of a box of the puzzle. The default is |20pt| which is +% also shown in this documentation. +% \begin{macrocode} +\newdimen\PuzzleUnitlength +\PuzzleUnitlength=20pt +% \end{macrocode} +% +% \begin{macro}{\PuzzleClueFont} +% +% The macro |\PuzzleClueFont| contains font changing +% commands issued before the clues are typeset. +% \begin{macrocode} +\newcommand\PuzzleClueFont{\footnotesize} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzleFont} +% +% The macro |\PuzzleFont| contains font changing +% commands issued before the puzzle is typeset. +% \begin{macrocode} +\newcommand\PuzzleFont{\rm\normalsize} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzleNumberFont} +% The macro |\PuzzleNumberFont| contains font changing +% commands issued before the numbers in a puzzle are typeset. +% \begin{macrocode} +\newcommand\PuzzleNumberFont{\sf\scriptsize} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzleHook} +% Puzzles are typeset with the \LaTeX{} picture environment. At the +% end of this environment the macro |\PuzzleHook| is +% called. The package produces an empty default. Users may want to +% use this place to typeset additional elements on top of the +% puzzle. +% +% The puzzle uses a |\unitlength| of |\PuzzleUnitlength|. Thus it +% is rather easy to address the boxes in the puzzle. +% +% \begin{macrocode} +\let\PuzzleHook=\relax +% \end{macrocode} +% \end{macro} +% +% \subsection{The Frame of the Crossword Puzzle} +% +% To describe the coordinates where the next box should be typeset +% we need two counters for the coordinates. These counters are now +% allocated (even though we could use temporary counters from +% \LaTeX). +% \begin{macrocode} +\newcount\Puzzle@X +\newcount\Puzzle@Y +% \end{macrocode} +% +% \begin{macrocode} +\begingroup +\catcode`\|=13 +\gdef\Puzzle@@solution{ + \let|=\Puzzle@Box@@solution + \let\Frame=\Puzzle@Frame@@solution +} +% \end{macrocode} +% +% \begin{macrocode} +\gdef\Puzzle@@normal{ + \let|=\Puzzle@Box@@normal + \let\Frame=\Puzzle@Frame@@normal +} +\endgroup +% \end{macrocode} +% +% \begin{environment}{Puzzle} +% The environment |Puzzle| typesets the frame of a crossword +% puzzle. It is implemented utilizing a |picture| environment. The +% unitlength is set to the |\PuzzleUnitlength|. Thus the navigation +% is fairly easy. The basic unit is width and height of a single +% box. +% +% The macros which are local to the environment are activated. Thus +% we avoid collisions with other packages where the same macro names +% might be used. +% +% Finally the counter which contain the x and the y coordinate have +% to be initialized. +% +% The last action in the |picture| environment is the expansion of +% the macro |\PuzzleHook|. This can be used to include additional +% material in the |picture| environment. Primarily I have use this +% to include the ads. But now there is the macro |\Frame| for this +% purpose. +% \begin{macrocode} +\newenvironment{Puzzle}[2]{\PuzzlePre + \catcode`\|=13 + \@nameuse{Puzzle@@\Puzzle@TYPE}% + \unitlength=\PuzzleUnitlength + \linethickness{\PuzzleLineThickness}% + \Puzzle@Y=#2 + \begin{picture}(#1,#2) + \Puzzle@Box@@normal. +}{% + \PuzzleHook + \end{picture}\PuzzlePost +} +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\PuzzleLineThickness} +% The macro |\PuzzleLineThickness| contains the width of the line +% used to frame the cells. +% \changes{1.5}{2006/08/11}{New} +% \begin{macrocode} +\newcommand\PuzzleLineThickness{.25pt} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzlePre} +% This macro contains the code to be inserted before a puzzle is +% typeset. It is initialized to begin a new paragraph and center the +% puzzle. +% \changes{1.5}{2006/08/11}{New} +% \begin{macrocode} +\newcommand\PuzzlePre{% + \par\noindent\mbox{}\hfill +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzlePost} +% This macro contains the code to be inserted after a puzzle is +% typeset. It is initialized to end the paragraph and center the +% puzzle. +% \changes{1.5}{2006/08/11}{New} +% \begin{macrocode} +\newcommand\PuzzlePost{% + \hfill\null\par\noindent +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Frame@@normal} +% The macro |Puzzle@Frame| is used to place additional +% rectangular regions into the puzzle frame. This frame can contain +% arbitrary text which is typeset in a centered environment. +% +% This macro takes five arguments. The first two arguments are the +% coordinates of the upper left corner of the frame. The +% coordinates are logical coordinates starting from the lower left +% corner of the puzzle. The next two arguments are the width and the +% height of the frame given in the number of boxes covered. Finally +% the fifth argument contains the text which should appear in this +% frame. +% \begin{macrocode} +\newcommand\Puzzle@Frame@@normal[5]{\put(#1,#2){\framebox(#3,#4){% + \begin{minipage}{#3\unitlength}\begin{center} #5 + \end{center}\end{minipage}}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Frame@@solution} +% For the solution the framed ads are simply ignored. +% \begin{macrocode} +\newcommand\Puzzle@Frame@@solution[5]{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzleBlackBox} +% The macro |\PuzzleBlackBox| is called to typeset the black boxes. +% It should produce a box of at most width and height of +% |\PuzzleUnitlength|. +% \begin{macrocode} +\newcommand\PuzzleBlackBox{\rule{\PuzzleUnitlength}{\PuzzleUnitlength}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Box@@normal} +% The macro |\Puzzle@Box@@normal| performs all tasks when a box +% should be typeset in ``normal'' mode. The arguments are evaluated +% and the appropriate type of box typeset or other actions performed. +% \changes{1.4}{1996/11/25}{Minor bug fix. Using +% \texttt{\char`\\ifx} +% instead of \texttt{\char`\\if}.} +% \changes{1.5}{2006/08/10}{Reimplemented to cope with two optional +% arguments.} +% \begin{macrocode} +\newcommand\Puzzle@Box@@normal[1][]{% + \def\Puzzle@tmp@{#1}% + \Puzzle@Box@@normal@ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Box@@normal@} +% The macro |\Puzzle@Box@@normal@| performs all tasks when a box +% should be typeset in ``normal'' mode. The arguments are evaluated +% and the appropriate type of box typeset or other actions performed. +% \changes{1.5}{2006/08/10}{Extracted from +% \texttt{\char`\\Puzzle@Box@@normal}.} +% \changes{1.7}{2009/06/09}{\texttt{\char`\\PuzzleContent} added to +% transport the letter to the formatting macro.} +% \begin{macrocode} +\newcommand\Puzzle@Box@@normal@[2][f]{% + \def\PuzzleContent{#2}% + \def\Puzzle@tmp{#2}% + \if\Puzzle@tmp. + \Puzzle@X=0 + \advance\Puzzle@Y-1 + \else + \ifx\Puzzle@tmp\@empty + \else + \if\Puzzle@tmp* + \Puzzle@Cell@Loop *#1{}% + \else + \Puzzle@Cell@Loop #1{}% + \fi + \fi + \ifx\@empty\Puzzle@tmp@\else + \PuzzlePutNumber{\Puzzle@X}{\Puzzle@Y}{\Puzzle@tmp@}% + \fi + \advance\Puzzle@X 1 + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzlePutNumber} +% The macro |\PuzzlePutNumber| is a configuration macro which +% typesets the number in a cell. The first argument is the x +% coordinate. The second argument is the y coordinate. The third +% argument is the number to be typeset. +% \changes{1.5}{2006/08/10}{New} +% \begin{macrocode} +\def\PuzzlePutNumber#1#2#3{% + \put(#1,#2){\makebox(1,.95)[tl]{\PuzzleNumberFont\,#3}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@Loop} +% The macro |\Puzzle@Cell@Loop| processes its arguments until an +% empty argument is found. For each argument it is tried to invoke +% the corresponding cell drawing macro. +% \changes{1.5}{2006/08/09}{New} +% \begin{macrocode} +\def\Puzzle@Cell@Loop#1{% + \def\Puzzle@tmp{#1}% + \ifx\Puzzle@tmp\@empty + \let\Puzzle@tmp\relax + \else + \expandafter\ifx\csname Puzzle@Cell@@#1\endcsname\relax + \typeout{cwpuzzle: Cell type #1 is undefined. I am ignoring it}% + \else + \csname Puzzle@Cell@@#1\endcsname{\Puzzle@X}{\Puzzle@Y}% + \fi + \let\Puzzle@tmp\Puzzle@Cell@Loop + \fi + \Puzzle@tmp +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Box@@solution} +% The macro |\Puzzle@Box@@solution| performs all tasks when a box +% should be typeset in ``solution'' mode. The arguments are evaluated +% and the appropriate type of box typeset or other actions performed. +% \changes{1.4}{1996/11/25}{Minor bug fix. Using \texttt{\char`\\ifx} instead of \texttt{\char`\\if}.} +% \changes{1.5}{2006/08/10}{Reimplemented to cope with two optional arguments.} +% \begin{macrocode} +\newcommand\Puzzle@Box@@solution[1][]{% + \def\Puzzle@tmp@{#1}% + \Puzzle@Box@@solution@ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Box@@solution@} +% The macro |\Puzzle@Box@@solution@| performs all tasks when a box +% should be typeset in ``solution'' mode. The arguments are evaluated +% and the appropriate type of box typeset or other actions performed. +% \changes{1.5}{2006/08/10}{Reimplemented to cope with two optional arguments.} +% \begin{macrocode} +\newcommand\Puzzle@Box@@solution@[2][f]{% + \def\Puzzle@tmp{#2}% + \if\Puzzle@tmp. + \Puzzle@X=0 + \advance\Puzzle@Y-1 + \else + \ifx\Puzzle@tmp\@empty + \else + \if\Puzzle@tmp* + \Puzzle@Cell@Loop *#1{}% + \else + \Puzzle@Cell@Loop #1{}% + \put(\Puzzle@X,\Puzzle@Y){\makebox(1,1){\uppercase{#2}}}% + \fi + \fi + \def\Puzzle@tmp{#1}% + \ifx\Puzzle@tmp\@empty\else + \ifPuzzle@SolutionNumbered + \PuzzlePutNumber{\Puzzle@X}{\Puzzle@Y}{\Puzzle@tmp@}% + \fi + \fi + \advance\Puzzle@X 1 + \fi +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Predefined Cell Types} +% In this section a series of frame types are defined. +% +% \begin{macro}{\PuzzleDefineCell} +% The macro |\PuzzleDefineCell| is a user command to define a new +% cell type. The first argument contains the key under which the +% cell type should be addressed. This key should be expandable and +% should result into a single letter. Special effects can be +% achieved with keys constituted of non letters or several +% characters. +% +% The second argument contains the code to be stored for the key +% given. +% \changes{1.5}{2006/08/08}{New} +% \begin{macrocode} +\newcommand\PuzzleDefineCell[2]{ + \global\@namedef{Puzzle@Cell@@#1}##1##2{#2}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\PuzzleDefineColorCell} +% +% \changes{1.5}{2006/08/11}{New} +% \begin{macrocode} +\newcommand\PuzzleDefineColorCell[2]{ + \global\@namedef{Puzzle@Cell@@#1}##1##2{% + \fboxsep=0pt + \put(##1,##2){\makebox(1,1){\colorbox{#2}{\makebox(1,1){}}}} + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzleThickine} +% The parameter |\PuzzleThickine| contains the expansion text to +% be inserted. whenever a thick line is required. This means that +% this macro arranges everything that a thick line is drawn. +% Usually it contains an invocation to |\linethickness|. It can +% be redefined to achieve other effects like even thicker lines +% or colored lines. Note that the macro is used inside a group in +% the predefined cell types. +% \begin{macrocode} +\def\PuzzleThickline{\linethickness{2pt}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@T} +% The letter T produces a thicker line at the top of the cell. +% The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \changes{1.5}{2006/08/08}{New} +% \begin{macrocode} +\PuzzleDefineCell{T}{{% + \advance#2 1 + \PuzzleThickline + \put(#1,#2){{\line(1,0){1}}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@t} +% The letter t produces a frame with a thicker line at the top. +% The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \changes{1.5}{2006/08/08}{New} +% \begin{macrocode} +\PuzzleDefineCell{t}{{% + \put(#1,#2){\framebox(1,1){}} + \advance#2 1 + \PuzzleThickline + \put(#1,#2){{\line(1,0){1}}} +}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\Puzzle@Cell@@B} +% The letter B produces a thicker line at the bottom of the cell. +% The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \changes{1.5}{2006/08/10}{New} +% \begin{macrocode} +\PuzzleDefineCell{B}{{% + \PuzzleThickline + \put(#1,#2){{\line(1,0){1}}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@b} +% The letter b produces a frame with a thicker line at the bottom. +% The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \changes{1.5}{2006/08/10}{New} +% \begin{macrocode} +\PuzzleDefineCell{b}{{% + \put(#1,#2){\framebox(1,1){}} + \PuzzleThickline + \put(#1,#2){{\line(1,0){1}}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@l} +% The letter l produces a frame with a thicker line at the left +% side of the cell. The thickness of this line is controlled by +% the macro |\PuzzleThickline|. +% \changes{1.5}{2006/08/10}{New} +% \begin{macrocode} +\PuzzleDefineCell{l}{{% + \put(#1,#2){\framebox(1,1){}} + \PuzzleThickline + \put(#1,#2){{\line(0,1){1}}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@L} +% The letter L produces a thicker line at the left side of the +% cell. The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \changes{1.5}{2006/08/10}{New} +% \begin{macrocode} +\PuzzleDefineCell{L}{{% + \PuzzleThickline + \put(#1,#2){{\line(0,1){1}}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@r} +% The letter r produces a frame with a thicker line at the right +% side of the cell. The thickness of this line is controlled by +% the macro |\PuzzleThickline|. +% \changes{1.5}{2006/08/10}{New} +% \begin{macrocode} +\PuzzleDefineCell{r}{{% + \put(#1,#2){\framebox(1,1){}} + \advance #1 1 + \PuzzleThickline + \put(#1,#2){{\line(0,1){1}}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@R} +% The letter R produces a thicker line at the right side of the +% cell. The thickness of this line is controlled by the macro +% |\PuzzleThickline|. +% \changes{1.5}{2006/08/10}{New} +% \begin{macrocode} +\PuzzleDefineCell{R}{{% + \advance #1 1 + \PuzzleThickline + \put(#1,#2){{\line(0,1){1}}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@f} +% The letter f produces a simple frame around the cell. This is +% the default if nothing is specified. +% \changes{1.5}{2006/08/08}{New} +% \begin{macrocode} +\PuzzleDefineCell{f}{{% + \put(#1,#2){\framebox(1,1){}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@S} +% The letter S produces the solution without any other formatting +% around it. +% \changes{1.7}{2009/06/09}{New} +% \begin{macrocode} +\PuzzleDefineCell{S}{{% + \put(#1,#2){\makebox(1,1){\expandafter\uppercase{\PuzzleContent}}} +}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\Puzzle@Cell@@.} +% The character . produces no additional rendering it can be used +% to overwrite the default rendering which is to place a frame +% around the cell. +% \changes{1.5}{2006/08/11}{New} +% \begin{macrocode} +\PuzzleDefineCell{.}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@O} +% The letter O produces an oval as drawn with the \LaTeX\ macro +% \verb/\oval/. +% \changes{1.5}{2006/08/11}{New} +% \begin{macrocode} +\PuzzleDefineCell{O}{{% + \put(\the#1.5,\the#2.5){\oval(1,1){}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@o} +% The letter o produces an oval inside a frame. T is is an +% abbreviation for the two letters fO. +% \changes{1.5}{2006/08/08}{New} +% \begin{macrocode} +\PuzzleDefineCell{o}{{% + \put(#1,#2){\framebox(1,1){}} + \put(\the#1.5,\the#2.5){\oval(1,1){}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@*} +% The letter * produces a solid black box. +% \changes{1.5}{2006/08/08}{New} +% \begin{macrocode} +\PuzzleDefineCell{*}{% + \put(#1,#2){\framebox(1,1){\PuzzleBlackBox}} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@/} +% The character / produces a line crossing the cell from lower +% left to upper right. +% \changes{1.5}{2006/08/08}{New} +% \begin{macrocode} +\PuzzleDefineCell{/}{{% + \put(#1,#2){{\line(1,1){1}}} +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Cell@@,} +% The character , produces a line crossing the cell from upper +% left to lower right. +% \changes{1.5}{2006/08/11}{New} +% \begin{macrocode} +\PuzzleDefineCell{,}{{% + \advance#2 1 + \put(#1,#2){{\line(1,-1){1}}} +}} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Clues} +% +% \begin{macro}{\Puzzle@Clue@@normal} +% The first and the third argument are shown as clue. This macro is +% used for unsolved puzzles. +% \begin{macrocode} +\newcommand\Puzzle@Clue@@normal[3]{\textsf{#1} #3 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Clue@@solution} +% In solutions clues are simply suppressed. Thus all three +% arguments are discarded. +% \begin{macrocode} +\newcommand\Puzzle@Clue@@solution[3]{} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{Puzzle@Clues@@normal} +% The environment |Puzzle@Clues@@normal| is mapped to |PuzzleClues| +% in ``normal'' mode. It typesets its contents in a mini-page of +% approximately half text width. +% \begin{macrocode} +\newenvironment{Puzzle@Clues@@normal}[1]{% + \let\Clue\Puzzle@Clue@@normal + \PuzzleCluePre + \PuzzleClueFont{#1}% +}{\PuzzleCluePost } +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\PuzzleCluePre} +% The macro |\PuzzleCluePre| contains the code which is inserted +% before the clues are typeset in normal mode. +% \begin{macrocode} +\newcommand\PuzzleCluePre{% + \null\hfill + \begin{minipage}[t]{.45\textwidth}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzleCluePost} +% The macro |\PuzzleCluePost| contains the code which is inserted +% after the clues are typeset in normal mode. +% \begin{macrocode} +\newcommand\PuzzleCluePost{ + \end{minipage}\hfill\null +} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{Puzzle@Clues@@solution} +% The environment |Puzzle@Clues@@solution| is mapped to |PuzzleClues| +% in ``solution'' mode. It just suppresses any output. +% \begin{macrocode} +\newenvironment{Puzzle@Clues@@solution}[1]{% + \let\Clue\Puzzle@Clue@@solution +}{} +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\PuzzleWordsText} +% The macro |\PuzzleWordsText| is the text typeset at the beginning +% of the environment |PuzzleWords|. It takes one argument which is +% the length of the words listed. +% \begin{macrocode} +\newcommand\PuzzleWordsText[1]{Words of length #1: } +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{Puzzle@Words@@normal} +% The environment |Puzzle@Words@@normal| will be mapped to the +% environment |PuzzleWords| in ``normal'' mode. It just arranges +% that words are typeset after the |\PuzzleWordsText| has shown the +% length of the words. Finally a new paragraph is started. +% \begin{macrocode} +\newenvironment{Puzzle@Words@@normal}[1]{% + \PuzzleWordsText{#1}% + \let\Word\relax +}{\par} +% \end{macrocode} +% \end{environment} +% +% \begin{environment}{Puzzle@Words@@solution} +% The environment |Puzzle@Words@@solution| will be mapped to the +% environment |PuzzleWords| in ``solution'' mode. It arranges +% things that the contents is silently ignored. +% \begin{macrocode} +\newenvironment{Puzzle@Words@@solution}[1]{% + \newcommand\Word[1]{}% +}{} +% \end{macrocode} +% \end{environment} +% +% \subsection{Numbers} +% +% \begin{macro}{\PuzzleNumbers} +% The macro |\PuzzleNumbers| will produce a list of boxes with +% numbers for letters. It is intended for numbered crossword puzzles. +% \begin{macrocode} +\newcommand\PuzzleNumbers[1]{\begingroup + \@nameuse{Puzzle@@\Puzzle@TYPE}% + \Puzzle@Y=0 + \Puzzle@X=1 + \unitlength=\PuzzleUnitlength + \Puzzle@Numbers#1.\endgroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@Numbers} +% The macro |\Puzzle@Numbers| loops through the arguments until it +% finds a dot. For each argument it produces a box, either with the +% numbers or with the letters or both, depending on the current +% settings. +% +% The loop is implemented via recursion. The box is typeset by the +% \verb/|/ macro which takes care of the current settings. For this +% purpose this character has to be made active temporarily. +% \begin{macrocode} +\begingroup +\catcode`\|=13 +\gdef\Puzzle@Numbers#1{% + \if#1. + \let\next\relax + \else + \begin{picture}(1,1) + \xdef\X{\the\Puzzle@X}% + \Puzzle@X=0 + |[\X]{#1}% + \end{picture}% + \let\next\Puzzle@Numbers + \advance\Puzzle@X 1 + \fi + \next +} +\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzleLettersText} +% The macro |\PuzzleLettersText| contains the text typeset at the +% beginning of the |\PuzzleLetters| environment. +% \begin{macrocode} +\newcommand\PuzzleLettersText{The following letters are used: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzleLetters} +% The macro |\PuzzleLetters| is intended to show the letters used +% in a numbered crossword puzzle. The argument is the (sorted) list +% of characters used. +% \begin{macrocode} +\newcommand\PuzzleLetters[1]{\PuzzleLettersText #1\par} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Puzzle@TYPE} +% The macro |\Puzzle@TYPE| contains the type of the puzzle. It is +% used find the appropriate initialization macro. +% \begin{macrocode} +\newcommand\Puzzle@TYPE{normal} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzleSolution} +% The macro |\PuzzleSolution| arranges everything that the +% following puzzles are typeset in the ``solution'' mode, i.e. the +% letters are shown and the clues are suppressed. +% +% This macros has one optional argument which has to be |true| or +% |false|. This argument determines whether or not the numbers +% should also be shown in the solution. The default is |false| +% which means that the numbers are suppressed in the solution. +% \begin{macrocode} +\newcommand\PuzzleSolution[1][false]{% + \@nameuse{Puzzle@SolutionNumbered#1}% + \let\PuzzleClues\Puzzle@Clues@@solution + \let\endPuzzleClues\endPuzzle@Clues@@solution + \let\PuzzleWords\Puzzle@Words@@solution + \let\endPuzzleWords\endPuzzle@Words@@solution + \def\Puzzle@TYPE{solution}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PuzzleUnsolved} +% The macro |\PuzzleUnsolved| arranges everything that the +% following puzzles are typeset in the ``unsolved'' mode, i.e. the +% letters are suppressed and the clues are shown. +% \begin{macrocode} +\newcommand\PuzzleUnsolved{% + \let\PuzzleClues\Puzzle@Clues@@normal + \let\endPuzzleClues\endPuzzle@Clues@@normal + \let\PuzzleWords\Puzzle@Words@@normal + \let\endPuzzleWords\endPuzzle@Words@@normal + \xdef\Puzzle@TYPE{normal}} +% \end{macrocode} +% \end{macro} +% +% The boolean |Puzzle@SolutionNumbered| determines whether or +% not the solution should contain numbers. Initially it is set to +% ``false''. +% +% \begin{macrocode} +\newif\ifPuzzle@SolutionNumbered +\Puzzle@SolutionNumberedfalse +% \end{macrocode} +% +% +% Finally we arrange that the default behavior is to typeset an +% unsolved crossword puzzle. +% +% \begin{macrocode} +\PuzzleUnsolved +% \end{macrocode} +% +% Now, that everything is in place we can arrange some package +% options. +% \changes{1.6}{2006/08/12}{Several style options defined} +% \begin{macrocode} +\DeclareOption{numbered}{\Puzzle@SolutionNumberedtrue} +\DeclareOption{nocenter}{\let\PuzzlePre=\relax + \let\PuzzlePost=\relax} +\DeclareOption{unboxed}{\let\PuzzleCluePre=\relax + \let\PuzzleCluePost=\relax} +\DeclareOption{normalsize}{\PuzzleUnitlength=20pt + \def\PuzzleFont{\rm\normalsize}} +\DeclareOption{small}{\PuzzleUnitlength=16pt + \def\PuzzleFont{\rm\small}} +\DeclareOption{large}{\PuzzleUnitlength=24pt + \def\PuzzleFont{\rm\large}} +\DeclareOption{german}{% + \renewcommand\PuzzleWordsText[1]{Worte der L\"ange #1: }% + \renewcommand\PuzzleLettersText{Benutzte Buchstaben: }% +} +\DeclareOption{ngerman}{% + \renewcommand\PuzzleWordsText[1]{Worte der L\"ange #1: }% + \renewcommand\PuzzleLettersText{Benutzte Buchstaben: }% +} +\ProcessOptions\relax +% \end{macrocode} +% +% That's all. +% +% \PrintChanges +% \newpage +% \PrintIndex +% +% \Finale +% +\endinput +% +% Local Variables: +% mode: latex +% TeX-master: t +% End: diff --git a/Master/texmf-dist/source/latex/crossword/cwpuzzle.ins b/Master/texmf-dist/source/latex/crossword/cwpuzzle.ins new file mode 100644 index 00000000000..3b838f78224 --- /dev/null +++ b/Master/texmf-dist/source/latex/crossword/cwpuzzle.ins @@ -0,0 +1,43 @@ +%%------------------------------------------------------------------ +%% Driver file to extract the dtx style and package file. +%% +%% Copyright (C) 1995-2009 Gerd Neugebauer +%% +%% Author: Gerd Neugebauer +%% Im Lerchelsöhl 5 +%% 64521 Groß-Gerau +%% Mail: gene@gerd-neugebauer.de +%% +%% cwpuzzle.ins is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY. No author or distributor accepts +%% responsibility to anyone for the consequences of using it or for +%% whether it serves any particular purpose or works at all, unless +%% he says so in writing. +%% +%% Everyone is granted permission to copy, modify and redistribute +%% cwpuzzle.ins, provided this copyright notice is preserved and +%% any modifications are indicated. +%% +%%------------------------------------------------------------------ +%% +%% Run this file through TeX or LaTeX to extract the files. +%% You need the docstrip package as distributed with LaTeX2e. +%% It is also availlable as seperate package from any CTAN site. +%% +%%------------------------------------------------------------------ +\def\batchfile{cwpuzzle.ins} +\input docstrip.tex +\keepsilent +\generateFile{cwpuzzle.sty}{t}{\from{cwpuzzle.dtx}{}} +\Msg{****************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* files into a directory searched by TeX:} +\Msg{*} +\Msg{* \space\space cwpuzzle.sty} +\Msg{*} +\Msg{* To produce the documentation run cwpuzzle.dtx through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing} +\Msg{****************************************************************} +\endinput diff --git a/Master/texmf-dist/tex/latex/crossword/cwpuzzle.sty b/Master/texmf-dist/tex/latex/crossword/cwpuzzle.sty new file mode 100644 index 00000000000..44a95c17af2 --- /dev/null +++ b/Master/texmf-dist/tex/latex/crossword/cwpuzzle.sty @@ -0,0 +1,358 @@ +%% +%% This is file `cwpuzzle.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% cwpuzzle.dtx +%% +%% IMPORTANT NOTICE: +%% +%% For the copyright see the source file. +%% +%% Any modified versions of this file must be renamed +%% with new filenames distinct from cwpuzzle.sty. +%% +%% For distribution of the original source see the terms +%% for copying and modification in the file cwpuzzle.dtx. +%% +%% This generated file may be distributed as long as the +%% original source files, as listed above, are part of the +%% same distribution. (The sources need not necessarily be +%% in the same archive or directory.) +%%^^A $Id: cwpuzzle.dtx,v 1.7 2009/09/06 15:16:53 gene Exp gene $ +\def\CWP@RCS$#1: #2 #3${#2} +\def\filename{cwpuzzle.dtx} +\xdef\fileversion{\CWP@RCS$Revision: 1.7 $} +\xdef\filedate{\CWP@RCS$Date: 2009/09/06 15:16:53 $} +\let\docversion=\fileversion +\let\docdate=\filedate +\typeout{% +%% Purpose: + Package: cwpuzzle \filedate\space\fileversion\space + for typesetting crossword puzzles. +}% +%% +%% Documentation: +%% The documentation can be generated from the original file +%% cwpuzzle.dtx with the doc style/package. LaTeX the file +%% cwpuzzle.dtx to get the full documentation in dvi format. +%% +%% +%% Author: Gerd Neugebauer +%% Im Lerchelsöhl 5 +%% 64521 Groß-Gerau +%% Mail: gene@gerd-neugebauer.de +%% +%% Copyright (C) 1995-2009 Gerd Neugebauer +%% +%% cwpuzzle.dtx is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY. No author or distributor accepts +%% responsibility to anyone for the consequences of using it or for +%% whether it serves any particular purpose or works at all, unless +%% he says so in writing. +%% +%% Everyone is granted permission to copy, modify and redistribute +%% cwpuzzle.dtx, provided this copyright notice is preserved and +%% any modifications are indicated. +%% +%% +%% This style is still under development and may be replaced with a +%% new version which provides an enhanced functionality. +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% \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 \~} +%% +\ProvidesPackage{cwpuzzle}[\filedate gene] +\newdimen\PuzzleUnitlength +\PuzzleUnitlength=20pt +\newcommand\PuzzleClueFont{\footnotesize} +\newcommand\PuzzleFont{\rm\normalsize} +\newcommand\PuzzleNumberFont{\sf\scriptsize} +\let\PuzzleHook=\relax +\newcount\Puzzle@X +\newcount\Puzzle@Y +\begingroup +\catcode`\|=13 +\gdef\Puzzle@@solution{ + \let|=\Puzzle@Box@@solution + \let\Frame=\Puzzle@Frame@@solution +} +\gdef\Puzzle@@normal{ + \let|=\Puzzle@Box@@normal + \let\Frame=\Puzzle@Frame@@normal +} +\endgroup +\newenvironment{Puzzle}[2]{\PuzzlePre + \catcode`\|=13 + \@nameuse{Puzzle@@\Puzzle@TYPE}% + \unitlength=\PuzzleUnitlength + \linethickness{\PuzzleLineThickness}% + \Puzzle@Y=#2 + \begin{picture}(#1,#2) + \Puzzle@Box@@normal. +}{% + \PuzzleHook + \end{picture}\PuzzlePost +} +\newcommand\PuzzleLineThickness{.25pt} +\newcommand\PuzzlePre{% + \par\noindent\mbox{}\hfill +} +\newcommand\PuzzlePost{% + \hfill\null\par\noindent +} +\newcommand\Puzzle@Frame@@normal[5]{\put(#1,#2){\framebox(#3,#4){% + \begin{minipage}{#3\unitlength}\begin{center} #5 + \end{center}\end{minipage}}}} +\newcommand\Puzzle@Frame@@solution[5]{} +\newcommand\PuzzleBlackBox{\rule{\PuzzleUnitlength}{\PuzzleUnitlength}} +\newcommand\Puzzle@Box@@normal[1][]{% + \def\Puzzle@tmp@{#1}% + \Puzzle@Box@@normal@ +} +\newcommand\Puzzle@Box@@normal@[2][f]{% + \def\PuzzleContent{#2}% + \def\Puzzle@tmp{#2}% + \if\Puzzle@tmp. + \Puzzle@X=0 + \advance\Puzzle@Y-1 + \else + \ifx\Puzzle@tmp\@empty + \else + \if\Puzzle@tmp* + \Puzzle@Cell@Loop *#1{}% + \else + \Puzzle@Cell@Loop #1{}% + \fi + \fi + \ifx\@empty\Puzzle@tmp@\else + \PuzzlePutNumber{\Puzzle@X}{\Puzzle@Y}{\Puzzle@tmp@}% + \fi + \advance\Puzzle@X 1 + \fi +} +\def\PuzzlePutNumber#1#2#3{% + \put(#1,#2){\makebox(1,.95)[tl]{\PuzzleNumberFont\,#3}}% +} +\def\Puzzle@Cell@Loop#1{% + \def\Puzzle@tmp{#1}% + \ifx\Puzzle@tmp\@empty + \let\Puzzle@tmp\relax + \else + \expandafter\ifx\csname Puzzle@Cell@@#1\endcsname\relax + \typeout{cwpuzzle: Cell type #1 is undefined. I am ignoring it}% + \else + \csname Puzzle@Cell@@#1\endcsname{\Puzzle@X}{\Puzzle@Y}% + \fi + \let\Puzzle@tmp\Puzzle@Cell@Loop + \fi + \Puzzle@tmp +} +\newcommand\Puzzle@Box@@solution[1][]{% + \def\Puzzle@tmp@{#1}% + \Puzzle@Box@@solution@ +} +\newcommand\Puzzle@Box@@solution@[2][f]{% + \def\Puzzle@tmp{#2}% + \if\Puzzle@tmp. + \Puzzle@X=0 + \advance\Puzzle@Y-1 + \else + \ifx\Puzzle@tmp\@empty + \else + \if\Puzzle@tmp* + \Puzzle@Cell@Loop *#1{}% + \else + \Puzzle@Cell@Loop #1{}% + \put(\Puzzle@X,\Puzzle@Y){\makebox(1,1){\uppercase{#2}}}% + \fi + \fi + \def\Puzzle@tmp{#1}% + \ifx\Puzzle@tmp\@empty\else + \ifPuzzle@SolutionNumbered + \PuzzlePutNumber{\Puzzle@X}{\Puzzle@Y}{\Puzzle@tmp@}% + \fi + \fi + \advance\Puzzle@X 1 + \fi +} +\newcommand\PuzzleDefineCell[2]{ + \global\@namedef{Puzzle@Cell@@#1}##1##2{#2}% +} +\newcommand\PuzzleDefineColorCell[2]{ + \global\@namedef{Puzzle@Cell@@#1}##1##2{% + \fboxsep=0pt + \put(##1,##2){\makebox(1,1){\colorbox{#2}{\makebox(1,1){}}}} + }% +} +\def\PuzzleThickline{\linethickness{2pt}} +\PuzzleDefineCell{T}{{% + \advance#2 1 + \PuzzleThickline + \put(#1,#2){{\line(1,0){1}}} +}} +\PuzzleDefineCell{t}{{% + \put(#1,#2){\framebox(1,1){}} + \advance#2 1 + \PuzzleThickline + \put(#1,#2){{\line(1,0){1}}} +}} +\PuzzleDefineCell{B}{{% + \PuzzleThickline + \put(#1,#2){{\line(1,0){1}}} +}} +\PuzzleDefineCell{b}{{% + \put(#1,#2){\framebox(1,1){}} + \PuzzleThickline + \put(#1,#2){{\line(1,0){1}}} +}} +\PuzzleDefineCell{l}{{% + \put(#1,#2){\framebox(1,1){}} + \PuzzleThickline + \put(#1,#2){{\line(0,1){1}}} +}} +\PuzzleDefineCell{L}{{% + \PuzzleThickline + \put(#1,#2){{\line(0,1){1}}} +}} +\PuzzleDefineCell{r}{{% + \put(#1,#2){\framebox(1,1){}} + \advance #1 1 + \PuzzleThickline + \put(#1,#2){{\line(0,1){1}}} +}} +\PuzzleDefineCell{R}{{% + \advance #1 1 + \PuzzleThickline + \put(#1,#2){{\line(0,1){1}}} +}} +\PuzzleDefineCell{f}{{% + \put(#1,#2){\framebox(1,1){}} +}} +\PuzzleDefineCell{S}{{% + \put(#1,#2){\makebox(1,1){\expandafter\uppercase{\PuzzleContent}}} +}} +\PuzzleDefineCell{.}{} +\PuzzleDefineCell{O}{{% + \put(\the#1.5,\the#2.5){\oval(1,1){}} +}} +\PuzzleDefineCell{o}{{% + \put(#1,#2){\framebox(1,1){}} + \put(\the#1.5,\the#2.5){\oval(1,1){}} +}} +\PuzzleDefineCell{*}{% + \put(#1,#2){\framebox(1,1){\PuzzleBlackBox}} +} +\PuzzleDefineCell{/}{{% + \put(#1,#2){{\line(1,1){1}}} +}} +\PuzzleDefineCell{,}{{% + \advance#2 1 + \put(#1,#2){{\line(1,-1){1}}} +}} +\newcommand\Puzzle@Clue@@normal[3]{\textsf{#1} #3 } +\newcommand\Puzzle@Clue@@solution[3]{} +\newenvironment{Puzzle@Clues@@normal}[1]{% + \let\Clue\Puzzle@Clue@@normal + \PuzzleCluePre + \PuzzleClueFont{#1}% +}{\PuzzleCluePost } +\newcommand\PuzzleCluePre{% + \null\hfill + \begin{minipage}[t]{.45\textwidth}% +} +\newcommand\PuzzleCluePost{ + \end{minipage}\hfill\null +} +\newenvironment{Puzzle@Clues@@solution}[1]{% + \let\Clue\Puzzle@Clue@@solution +}{} +\newcommand\PuzzleWordsText[1]{Words of length #1: } +\newenvironment{Puzzle@Words@@normal}[1]{% + \PuzzleWordsText{#1}% + \let\Word\relax +}{\par} +\newenvironment{Puzzle@Words@@solution}[1]{% + \newcommand\Word[1]{}% +}{} +\newcommand\PuzzleNumbers[1]{\begingroup + \@nameuse{Puzzle@@\Puzzle@TYPE}% + \Puzzle@Y=0 + \Puzzle@X=1 + \unitlength=\PuzzleUnitlength + \Puzzle@Numbers#1.\endgroup} +\begingroup +\catcode`\|=13 +\gdef\Puzzle@Numbers#1{% + \if#1. + \let\next\relax + \else + \begin{picture}(1,1) + \xdef\X{\the\Puzzle@X}% + \Puzzle@X=0 + |[\X]{#1}% + \end{picture}% + \let\next\Puzzle@Numbers + \advance\Puzzle@X 1 + \fi + \next +} +\endgroup +\newcommand\PuzzleLettersText{The following letters are used: } +\newcommand\PuzzleLetters[1]{\PuzzleLettersText #1\par} +\newcommand\Puzzle@TYPE{normal} +\newcommand\PuzzleSolution[1][false]{% + \@nameuse{Puzzle@SolutionNumbered#1}% + \let\PuzzleClues\Puzzle@Clues@@solution + \let\endPuzzleClues\endPuzzle@Clues@@solution + \let\PuzzleWords\Puzzle@Words@@solution + \let\endPuzzleWords\endPuzzle@Words@@solution + \def\Puzzle@TYPE{solution}% +} +\newcommand\PuzzleUnsolved{% + \let\PuzzleClues\Puzzle@Clues@@normal + \let\endPuzzleClues\endPuzzle@Clues@@normal + \let\PuzzleWords\Puzzle@Words@@normal + \let\endPuzzleWords\endPuzzle@Words@@normal + \xdef\Puzzle@TYPE{normal}} +\newif\ifPuzzle@SolutionNumbered +\Puzzle@SolutionNumberedfalse +\PuzzleUnsolved +\DeclareOption{numbered}{\Puzzle@SolutionNumberedtrue} +\DeclareOption{nocenter}{\let\PuzzlePre=\relax + \let\PuzzlePost=\relax} +\DeclareOption{unboxed}{\let\PuzzleCluePre=\relax + \let\PuzzleCluePost=\relax} +\DeclareOption{normalsize}{\PuzzleUnitlength=20pt + \def\PuzzleFont{\rm\normalsize}} +\DeclareOption{small}{\PuzzleUnitlength=16pt + \def\PuzzleFont{\rm\small}} +\DeclareOption{large}{\PuzzleUnitlength=24pt + \def\PuzzleFont{\rm\large}} +\DeclareOption{german}{% + \renewcommand\PuzzleWordsText[1]{Worte der L\"ange #1: }% + \renewcommand\PuzzleLettersText{Benutzte Buchstaben: }% +} +\DeclareOption{ngerman}{% + \renewcommand\PuzzleWordsText[1]{Worte der L\"ange #1: }% + \renewcommand\PuzzleLettersText{Benutzte Buchstaben: }% +} +\ProcessOptions\relax +\endinput +%% +%% End of file `cwpuzzle.sty'. -- cgit v1.2.3