HTML/CGI Movie-making Package Table of Contents: 1. General 2. Overview 3. Installation and Use 4. Directives 5. Special pages 6. The BML macro language 7. In-text substitutions 8. Helpful tricks 9. Syntax recap 10. An example 11. Bugs and problems Section 1: General makemovie is intended as a tool to help authors create HTML/CGI pages and interactive "movies." The package contains a great deal of typesetting aids for bridge. The interaction mechanism, however, is not limited to bridge, and therefore might be useful in other applications. The software is freeware. No warrantee is express or implied. It was written by Jeff Goldsmith when he ought to have been doing constructive work in 1996. Please do not distribute this software without appropriate headers, but feel free to give it away to anyone. Please do not try to make money from it directly without asking me first. Feel free to produce movies that are commercially valuable. The software may be bundled with that, but the seller takes all appropriate responsibilty for the software in that case. If you ask for help about this software, I may or may not be able to help you. I am at If you praise it, I'm sure to be happy to hear that. Current version of the program is 1.0. Section 2: Overview The software (from now on referred to as "makemovie") consists of a main program, written in perl, called; a header file for your personal information, movie.h; and a set of data files containing movies. You only need to build the data files and tinker with movie.h The main user-servicable part of the system is the data files. One is likely to want to modify movie.h once. A data file (we'll use "movie.dat" interchangably for and synecdochically as a data file) consists of a preamble and a set of pages. Each page is, more or less, a single web page. makemovie creates the actual page dynamically, but all pages in movies are defined in movie.dat. As is nearly every other web page, it is defined in HTML. Normal HTML tags and constructs can be used within a page definition. Many shortcuts and aids are included to try to speed up the process of building these pages. movie.dat is divided into pages by way of the PAGE directive. Each occurrance of such a directive begins a new page and ends the previous one. The first PAGE directive ends the preamble, so a three-page movie will have the following sort of data file: # Begin Preamble # movie.dat # written by Cornelius Kerrigan Esq # Feb. 30, 1435 # Purpose: trivial partial example preamble stuff # Pages PAGE 1 page 1 stuff PAGE 2 page 2 stuff PAGE 3 page 3 stuff Each page may be split into a number of CASEs. These are parts of the page to be drawn if the previous answer matches a given string. For example, PAGE 3 stuff CASE 2NT bother CASE 3NT stuffnbother ENDCASE junk here, "stuff" will always be printed on page 3, but "bother" will only be printed if the answer of a previous question (see CHOICE) matches 2NT. If it matches 3NT, then "stuffnbother" will get printed. After the ENCASE, "junk" will get printed for either case. If neither case matches, only the stuff and junk get printed. Lines that begin with # are comments and are ignored. The contents of the preamble is "directives" and comments. Directives are all upper case words, beginning at the start of a line. Pages contain comments, directives, macros, and text. The text is mildly processed, but then sent to a normal HTML processor (CGI server) and often contains HTML tags. Some HTML can cause the server to be confused; the normal HTML header and trailer stuff is automatically placed on each page. With few exceptions, embedded HTML ought to be content and typesetting tags only, although hyperlinks are expected and are often helpful. Directives are in all upper case and begin at the beginning of a line. Many have a variant form, ending in *. So, "TITLE" is the standard form of the TITLE directive, and "TITLE*" is the variant form. Some have optional arguments. If they are included, they occur after the directive name and are enclosed in curly braces, {}, with arguments separated by commas. For example: HAND*{N,S} Some directives span many lines automatically; others are line-terminated. Continuation lines can be indicated by ending a line with a backslash (\). Macros are either defined in the preamble or are from the BML macro language, described later. BML (Bridge Macro Language) is intended for typesetting bridge. BML macros are of the form NAME(arg1,arg2,arg3,...) where "NAME" is the macro name and is in all upper case. Arguments are enclosed in parentheses and separated by commas. They need not occur at the beginning of a line and will extend across many lines of text if desired. Text is normally transmitted directly to the server, with one exception. Blank lines are considered to be paragraph separators and are replaced by the

HTML tag. Page-to-page interaction is done primarily by the CHOICE and NEXT directives. Within each page, except perhaps the last, one ought to include one of those two directives. CHOICE gives the user a choice of answers to a question and will send him to the next page. Using the page operator (see syntax or directives) one can use CHOICE to have the user end up on one of many different pages. NEXT will send the user to a single page of your choice. In its normal form, it will also allow him to check his scorecard on the way; in the variant form, he can't see the scorecard. The page operator can also be used in SAVE to override other page selections. Use this carefully. Section 3: Installation and Use You will need a copy of the perl interepreter, available free from various places. will need to be modified to point to your perl interpreter. The first line of makemovie looks like #!/usr/bin/perl Change that path to point to perl and all will be happy. The permission of will need to be executable to all. The other files (data files, gifs) will need to be readable by all. In UNIX, that means chmod a+x for, and chmod a+r for the rest. The system comes with a set of image files for bridge diagrams. They are the four suit symbols, plus a table marker. They are are all in gif format and are small images. They will need to be placed somewhere convenient to makemovie; the default location is a subdirectory called "gifs". The four suit symbols were created by Rod Roark. Thank you, Rod. If one chooses not to place the suit symbols in the default location, edit movie.h, which must appear in the same directory as, and indicate where the images are to reside. movie.h also contains information that is to appear on each of the pages generated by the movie. That information is the author's (you, not me) name, WWW home page, and email address. The package comes with a sample movie file that doesn't do anything particularly interesting. Try typing You ought to see some gibberish that starts with Content-type: text/html Welcome

A Silly Problem

To make a WWW movie, all this stuff must be placed in the directory in which you are allowed to execute CGI programs. That's often called cgi-bin. Ask thy system administrator or webmaster where that is if you don't already know. On some systems, CGI programs must have an extension .cgi If so, rename to makemovie.cgi Try opening cgi-bin/makemovie.cgi (or whatever) with your browser. You ought to see something that looks horribly messy, but starts with "A Silly Problem" in medium-big letters. To make more than one movie, you will need to make multiple copies of with different names. The only line that is likely to be needed to be changed is $datafile = "movie.dat"; Substitute your movie file for movie.dat. I apologize for the clunky nature of this installation, but makemovie can execute perl scripts and you don't want random users to be able to execute perl scripts on your machine. Advanced: while creating your data file, you will likely want to test your movie. You can do this by using a browser, or by running it standalone. To do the latter, just run To set page numbers and such, set the environment variable QUERY_STRING (in csh, type setenv QUERY_STRING "whatyouwantitotbe" What that string ought to be we shall come back to in the tricks section. To view the pages without using a CGI server, do >foo.html then open foo.html with your browser. You will see a line of nonsense at the beginning, but the rest of the page ought to be what you expect. One other installation option to consider: early in the main program is a line $secure = 0; If the 0 is changed to a 1, PERL blocks will not be allowed. If you don't use PERL blocks (for example, if you don't know perl) please change that to 1. Section 4: Directives understands the following directives: BID2, BID4, BIDDING, BOARD, BOARDS, BODY, CASE, CHOICE, DATE, DEBUG, DEFINE, ELSE, EMAIL, ENDCASE, ENDPERL, ENDUSE, HAND, HANDRECORDS, HOMEPAGE, IMP, LAYOUT, MAP, NAME, NEXT, OPPONENTS, PAGE, PERL, SAVE, SCORE, TEXTVERSION, TITLE, TOP, and USE. Some of these can only be used in the preamble: BOARDS, BODY, DATE, DEBUG, DEFINE, EMAIL, HOMEPAGE, IMP, LAYOUT, NAME, OPPONENTS, and TOP. Some can be used only in the pages: BID2, BID4, BIDDING, CASE, CHOICE, ELSE, ENDCASE, ENDUSE, HAND, HANDRECORDS, MAP, NEXT, PAGE, SAVE, SCORE, TITLE, TEXTVERSION, and USE. Some can be used in either: BOARD, PERL, and ENDPERL. Most directives take arguments. Arguments are normally delimited by spaces, tabs, or newlines. To include a space in an argument, enclose the argument in double quotes ("). Some directives have a variant form (*) and some take optional arguments (included in curly braces). Arguments to directives normally ought not include parentheses. If parentheses are meant in a textual sense, they must be escaped, \( and \). An alphabetical list of directives and explanations thereof follows. Directives: BID2 Scope: pages Usage: BID2 North South bid bid bid bid Pass BID2 draws a two-player bidding sequence. Its first two arguments are the players; these are never defaulted. The remaining arguments are bids. The directive is ended upon a "Pass" call, or upon the END token. Calls of the form will be assumed to be bridge calls and are typeset appropriately. An example: BIDDING North South "1NT FOOTNOTE(1)" 2C 2D 3NT Pass Note the footnote annotation. A description could be included here, too, say "1NT \(15-17\)". BID4 BIDDING Scope: pages Usage: BIDDING West North East South 1NT Pass 2C Dbl 2D Pass 3NT "All Pass" BID4 and BIDDING are synonymous. They are identical to BID2, except that bidding sequences are terminated by either "All Pass" (note the double quotes to make the two words one call) or END. BOARD Scope: any Usage in preamble: BOARD name AKQJ AKQ AKQ AKQ 1098 765 J1098 765 J109 8765 J109 876 432 432 432 5432 Usage in pages: BOARD name Optional arguments: N,S,E,W Variant form: yes, in pages BOARD defines a hand diagram to be used later. In the preamble, the layout must be included. The upper hand is North's and the rest are as expected. "name" defines the board for later use. In the pages, the board can be included by name (BOARD name). The optional arguments are the hand to be displayed; any unlisted hands are not shown (yet). I suggest using sequential integers as board names and telling the program which boards those are with the BOARDS directive. If you do that, you can get a hand records page generated automatically. The variant form (BOARD*) requires four "optional" arguments. It allows you to rotate the hands around, so the arguments are in order, which hand to put in the North position, the West position, the East position, and the South position. The stored board has North on top, so BOARD*{W,S,N,E} will rotate the board by 90 degrees clockwise. BOARDS Scope: preamble Usage: BOARDS n BOARDS 1st last BOARDS tells the program how many or which boards you intend to use. Only the scorecard and hand records pay attention to these numbers, so if you don't use those features, it is not needed. The first form of BOARDS specifies that you will use boards 1 through n. The second specifies a range of boards.:w BODY Scope: preamble Usage: BODY text makemovie creates an HTML header for each page for you; if you want some tweaks to all the pages' tags, you can use this to do it. This is helpful for doing backgrounds, for example. Such changes work on all pages, not just one, but this is probably a good thing in a sense, since you are forced to keep a common look. Advanced users are welcome to complain. CASE Scope: pages Usage: CASE string The CHOICE directive sets an internal variable to a string specified in the CHOICE directive. Within a page, one can have different text drawn depending on the value that variable by using CASE. CASE defines a block of text, ended by either an ENDCASE directive, another CASE directive, or a new PAGE. If the value of the CHOICE chosen by the user matches the string in a CASE block, then that text is used; otherwise it is ignored. CHOICE Scope: pages Usage: CHOICE page string text string text string text ... CHOICE sets up a set of buttons. During the running of the movie, the user is expected to pick one of the buttons, then hit a button marked "Onward." The movie will continue onto the page specified as the first argument to the CHOICE directive. Each (string text) pair is associated with a button. "string" is returned to the program and matches the argument in CASE directives, allowing the program to draw text determined by the user's choices. "text" is the text drawn for each button. For example: CHOICE "Page 3" \ Pass Pass \ S CARD(S) \ H CARD(H) \ D CARD(D) \ C CARD(C) The buttons are normally placed in a horizontal row. If you'd prefer them to be placed vertically, add the HTML directive
after each text item. The last one has a
tag included automatically. The first button is always checked initially and is the default action. Note that CHOICE directives are line-delimited, so they need to use continuation lines if they don't fit on one line. For very complicated choices, CHOICE can direct different answers to different pages using the page operator. Prefix a string with the page followed by two colons to redirect to a specified page, to wit: CHOICE "Page 3" \ Pass Pass \ S CARD(S) \ H CARD(H) \ D CARD(D) \ 3B::C CARD(C) If the user picks the last choice, he gets sent to page 3B instead of page "Page 3". Quotes may be needed if pages' names have spaces in them. CHOICE can take an optional argument, which is the string printed in the submission button. The default is "Onward". For example, CHOICE{"Hit me"} ... will put "Hit me" in the main button. DATE Scope: preamble Usage: DATE whenever you like it Each page in the movie is annotated with a date. That date is the last modified time of the movie file unless you include a DATE directive, in which case, it's what you choose it to be. It doesn't even have to be a date. DEBUG Scope: preamble Usage: DEBUG DEBUG tries to find errors in the movie file. Never leave this in when letting users use your movie. DEFINE Scope: preamble Usage: DEFINE string replacement DEFINE does simple macro substitution. The macros can have arguments. Whereever the string string appears in your text, it'll be replaced with the replacement string. Quoting either argument will allow spaces in the strings. Macro arguments are matched to the symbols $1, $2, ... in the replacement string, so DEFINE LABEL


LABEL(The Blackwood Convention) will produce

The Blackwood Convention

ELSE Scope: pages Usage: ELSE ELSE is part of a conditional block. See USE for more details. EMAIL Scope: preamble Usage: EMAIL stuff and such This overrides your email address as set in movie.h ENDCASE Scope: pages Usage: ENDCASE ENDCASE terminates a CASE block. This is most helpful if you have text that is to apply to all cases on a page. ENDPERL Scope: any Usage: ENDPERL ENDPERL terminates a PERL block. See PERL. ENDUSE Scope: pages Usage: ENDUSE ENDUSE terminates a USE block. See USE. HAND Scope: pages Usage: HAND AKQ AKQ AKQ AKQJ 10987 654 1098 765 1098 7654 1098 765 J32 J432 J32 432 In its basic form, HAND takes sixteen arguments and converts them into a double-dummy hand diagram. HAND takes up to four optional arguments. They are a list of the four hands intended in the diagram. Omitted hands are left blank. So, HAND{N,S} is a standard single-dummy diagram and takes 8 arguments. HAND{S,N} is the same, only expects the South hand first in the data file. If both the East and West hands are given, then they are expected to be on the same lines as above. The variant form (HAND*) requires all four hands being in the file, but only displays those given as its optional arguments. With no arguments, HAND* is identical to HAND. This is convenient in that if one is giving a problem with some hands concealed, one can just enter the hand once, then copy it with various arguments to HAND*, showing what one wants shown. The order of the arguments to HAND* is not used. Voids are indicated by anything you want other than empty space. HANDRECORDS Scope: pages Usage: HANDRECORDS If used on a page before the NEXT command, the page will have a button that leads to a hand records page. Now, it assumes that your boards are named as sequential integers over the range specified by BOARDS. It requires that all the boards are defined in the preamble. It assumes that all boards begin on a page named "Board i" where "i" is the appropriate integer. This may change or it may not. HOMEPAGE Scope: preamble Usage: HOMEPAGE url This overrides the home page setting in your movie.h file. IMP Scope: preamble Usage: IMP Scores are interpreted as being IMPs rather than matchpoints (the default) if IMP is issued. The scorecard is a bit different, too. LAYOUT Scope: preamble Usage: LAYOUT text Whatever you put here is written at the top of every page you build. If you'd like a common header; font size, shape or color; or whathaveyou, this is how to do it. MAP Scope: pages Usage: MAP imagefile page answer x1 y1 x2 y2 answer x3 y3 x4 y4 ... MAP installs a client-side clickable image map. It can be used instead of CHOICE or NEXT to travel to different pages. Imagefile is an image file you have (a path name will work). The image will be drawn as expected into the page. If no "answer" quintuples are given, the entire image is considered one area and clicks will send the user to Page page. If one or more answer quintubles is given, then if the click occurs within the rectangular boundary specified by the x1...y2 data, then the Answer will be set for use in CASE statements. The geometric data is x1 = left, y1 = top x2 = right, y2 = bottom (0,0) is the upper left corner of the image. The page operator works in answer tags. NAME Scope: preamble Usage: NAME you This overrides the name settign in your movie.h file. NEXT Scope: pages Usage: NEXT page Sends the user on to the next page with the "Onward" button, but gives him a chance to check his scorecard. Usually, a page will end in either a NEXT or a CHOICE directive. If neither is present, there's nowhere to go, so it'd better be the end of the movie :) The variant form (NEXT*) does not allow access to the scorecard. NEXT can take an optional argument, which is the string printed in the submission button, the one that will send the user on to the next hand. The default is "Next Hand". OPPONENTS Scope: preamble Usage: OPPONENTS opp opp opp opp ... Set opponents for scorecard. If you don't use this, your scorecard won't have any opponents listed, otherwise, it will use them for the appropriate boards. The first opponent listed will be for board 1, then board 2, etc., unless you specify a range of boards with BOARDS, in which case, they'll start with the first board listed there. PAGE Scope: pages Usage: PAGE string PAGE delimits pages in the movie file. The string is matched by pages in the CHOICE and NEXT directives. Names are case sensitive (as are most strings). Some page names are special. "Welcome", "Scorecard", "Hand Records", "Error", and "Sorry" have default meanings. If you want hand records, name your pages "Board 1", "Board 2", etc. The only pages that matter are those that start a board; they will get links from the hand record page. PERL Scope: any Usage: PERL Until the next ENDPERL directive, text will be assumed to be perl code and will get executed by the interpreter when the page is run. Dangerous directive. This is a major security careful with it. SAVE Scope: pages Usage: SAVE string SAVE saves some state from hand to hand. Use it sparingly, but you might need it to save the contract (if you are lazy and want to save pages) or that an appeal has been filed or such. See USE for how to use SAVEd state info. If you SAVE a string with the page operator (::), the next page will be forced to that page, regardless of anything else. For example, SAVE "Page 3::" will send the user to Page 3 regardless of other requests. It gets used up each time, so you'll have to SAVE again to keep him there. SCORE Scope: pages Usage: SCORE board contract declarer result score mps Example: SCORE 1 3Hx W +3 +730 24+ SCORE will both typeset the scores for you in the text and will assign them to the scorecard. TEXTVERSION Scope: pages, particularly Welcome Usage: TEXTVERSION TEXTVERSION will create a "No Graphics" button that draws everything in text thereafter. Normally, one uses it only on the first page. TITLE Scope: pages Usage: TITLE words and such TITLE both sets the title of the page and draws a header line with the text therein. The variant form (TITLE*) does not draw the header, but does set the title. TOP Scope: preamble Usage: TOP number TOP sets the top on the board for matchpoints. Defaults to 12. USE Scope: pages Usage: USE string USE is really "IF string was saved, then do this stuff, then remove string from saved stuff." Use blocks cannot be nested. Some helpful hints: you can SAVE something multiple times, but once used, it's used up completely. It's an easy way to keep a note around, for example, that an appeal is pending, or whatever. If you want the player to have one shot at something, put a SAVE in the welcome page. Section 5: Special Pages Some pages have special names. The default initial page is "Welcome" although you can specify any page you like to start the movie by using a URL of the form makemovie.cgi?Page=whatever Scorecard is a page that displays the scorecard. Hand Records is a page with hand records and links to other pages. Error is a page generated when the program can't figure out what's going on. I hope there won't be too many of those. Sorry is the conventional page used to indicate that a branch of the movie is not yet complete. Section 6: The BML macro language Most bridge typesetting is done with the HAND, BIDDING, and BOARD directives, but some needs to be done in normal text. To typeset in normal text, you need to use BML. BML macros look like NAME(arg1,arg2,...). All names are in all capitals. The macros currently supported are: SUIT, CARD, FOOTNOTE, HHAND, BIDDING, BID4, VHAND, HAND, TWOHANDS, and PANELIST. You will likely need only HHAND, CARD, and FOOTNOTE, but maybe VHAND. SUIT Usage: SUIT(dummy,declarer) SUIT draws a two-player card combination. The two arguments are the cards. Suit symbols are typeset normally. Example: SUIT(SAQ,Sxx) CARD Usage: CARD(string) CARD tells makemovie that the string is to be typeset as bridge text, that is to do suit symbol substitution on the string. It tries to be clever about what is in string; experiment. FOOTNOTE Usage: FOOTNOTE(string) FOOTNOTE draws a little supercripted string in the text, usually for annotation. HHAND Usage: HHAND(spades,hearts,diamonds,clubs) HHAND draws a hand in the text. BIDDING Usage: BIDDING(player1,player2,call,call,call,...) BIDDING draws two-player bidding diagrams. It is much like the BID2 directive. You probably don't need it. BID4 Usage: BID4(player1,player2,player3,player4,call,call,call,...) BID4 draws four-player bidding diagrams. It is much like the BIDDING directive. You probably don't need it. VHAND Usage: VHAND(spades,hearts,diamonds,clubs) VHAND draws a single hand in four lines. HAND Usage: HAND(North,West,East,South) HAND draws a hand diagram. You probably don't need this one; it's been superceded by the HAND directive. Example: HAND(VHAND(AKQ,AKQ,AKQ,AKQJ), VHAND(J109,J109,J109,10987), VHAND(876,876,876,6543), VHAND(5432,5432,5432,2)) TWOHANDS Usage: TWOHANDS(string1,string2,north1,west1,east1,south1, north2,west2,east2,south2) TWOHANDS draws two hand diagrams across the page. You probably don't need it, but it is used in hand diagrams. PANELIST Usage: PANELIST(string) PANELIST is useful for doing headers to lists. It draws the string in large and small caps (first letter is large) and inserts the name as a definition title in HTML. Use it in a
context. Section 7: In-text substitutions Currently, text only has one subsitution: blank lines are paragraph separators. Section 8: Helpful tricks The CHOICE directive need not use different CASE pointers for different answers. For example, if only a spade lead matters, you can use CHOICE "Page 7" \ S CARD(S) \ Other CARD(H) \ Other CARD(D) \ Other CARD(C) and process all the other cases together. When writing movies, it is quite helpful to use a browser. Have it show the location (URL) to tell you what's going on. The URL contains all the information about saved state; in particular, the page is listed there. When typesetting one page (or just a few) it's often easiest not to use a browser, but to redirect output to a file and use the browser just to look at the static file. You'll see a line marked "Content type..." at the top; ignore that. In any case, if you want to test a specific page, set your environment variable QUERY_STRING. The easiest way to do that is to have the browser show you your location, then grab everything after the question mark with the mouse. Then (if you are using c shell---there's an equivalent in other shells) do setenv QUERY_STRING "grabbed text" For simple movies that have a lot of the same text/graphics, you might only need one page. CHOICE/NEXT/etc. can point back to the same page they are on. Section 9: Syntax recap Directives: Directives are all caps, starting at the beginning of the line. The variant form has an asterisk (*) at the end of the word. Optional arguments are enclosed in curly braces ({}), delimited by commas. Continuation lines: All directives other than HAND, BOARD, BID2, BID4, and BIDDING are end-of line delimited. Continuation lines are indicated by ending the line with a backslash (\). Arguments with spaces: In general, arguments may be quoted using double quotes (") to preserve spaces. Macros: Macro arguments in replacement strings are $1, $2, etc. Macros (both user-defined and BML) require argument lists in parentheses, comma-separated. Parentheses: Parentheses in macro arguments confuse the program. These must be escaped: \( and \) will not get interpreted as macro parentheses. Page Operator: The page operator (::) will allow a CHOICE selection to point to a different page from others in the same CHOICE. It can also be used in SAVE to force moving to another page. Special Characters: Never SAVE, use as a PAGE or a CHOICE case, a string with any of the following characters: ?, :, ;, &, ., or = . Order of Hands: In general, hands are typeset N, W, E, S, or from top to bottom, left to right across the page. Argument lists expect them in that order. Section 10: An example See the file example.dat for a two-board example mini-movie, with lots of explanations in the file. Section 11: Bugs and problems I'm sure there are plenty. This space left intentionally blank due to laziness, impatience, and hubris. (Thank you, Larry Wall.) Things I know need work: - BML syntax is a little icky - movie.dat is hardcoded, but security is an issue - needs global layout directives in preamble - SCORE is ugly - Needs better error detection - DEBUG needs lots of work - needs a way to produce all possible pages at once - parentheses are handled poorly