home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume18 / scene / part01 / scene.l < prev   
Text File  |  1991-04-26  |  6KB  |  280 lines

  1. %{ / -*- Mode: Fundamental -*-
  2.  
  3. /*
  4.  * scene - a scene-file processor for TeX
  5.  */
  6.  
  7. /*
  8.  * Copyright 1991, Garrett A. Wollman
  9.  *
  10.  * The recipient is licensed to compile, modify, and distribute this work
  11.  * provided that this comment remains intact and unmodified in any such
  12.  * versions, and the documentation (such as it is) is included.
  13.  * Modified version must clearly be marked as such.
  14.  *
  15.  * If this program is of any use to anybody, I would appreciate hearing
  16.  * about it.  Please send E-mail to wollman@sadye.uvm.edu (in bangland,
  17.  * ...uunet!uvm-gen!griffin!wollman).
  18.  */
  19.  
  20. /* These prototypes are fairly standard... although it should
  21.  * probably be "void *" as the first parm to qsort()
  22.  */
  23. extern void volatile exit(int);
  24. extern void qsort(char *,int,int,int (*)(const void *,const void *));
  25.  
  26. int scene_no;
  27.  
  28. /*
  29.  * Look, I told you this was a quick hack, didn't I?
  30.  * The program doesn't even check if you overrun any
  31.  * of these fixed limits.  Boo! Hiss!  But I can't be
  32.  * bothered to do it right so long as it still works
  33.  * for me.
  34.  */
  35.  
  36. struct character {
  37.     char name[255];
  38.     short scenes[512];
  39.     int num_scenes;
  40. } chars[256];
  41.  
  42. struct scene {
  43.     char book[32];
  44.     int chars[64];
  45.     int num_chars;
  46.     int page;
  47.     char music[64];
  48.     char musicby[64];
  49. } scenes[640];
  50.  
  51. /* some more prototypes */
  52. static void add_char_to_scene(char *);
  53. static void write_scene(void);
  54. static void sort_scene_chars(void);
  55. static int sort_int_by_char(const void *,const void *);
  56. static int sort_char_by_name(const void *,const void *);
  57.  
  58. extern int strcmp(const char *,const char *);
  59. extern char *strcpy(char *,const char *);
  60. extern char *strcat(char *,const char *);
  61.  
  62. /* some more local data */
  63. char curr_book[256];
  64. int curr_page;
  65.  
  66. %}
  67.  
  68. %%
  69.  
  70. "\n"        ;
  71.  
  72. "S"|"s"        {
  73.             write_scene();
  74.             scene_no++;
  75.         }
  76.  
  77. ("C"|"c")[^\n]+    {
  78.             add_char_to_scene(yytext + 1);
  79.         }
  80.  
  81. ("B"|"b")[^\n]+    {
  82.             strcpy(curr_book,yytext + 1);
  83.             strcpy(scenes[scene_no - 1].book,yytext + 1);
  84.         }
  85.  
  86. "#"[0-9]+    {
  87.             sscanf(yytext,"#%d",&(scenes[scene_no - 1].page));
  88.         }
  89.  
  90. "#"[^0-9]+    {
  91.             fprintf(stderr,"Invalid page number, ignoring\n");
  92.         }
  93.  
  94. ("M"|"m")[^\n]+    {
  95.             strcpy(scenes[scene_no - 1].music,yytext + 1);
  96.         }
  97.  
  98. ("A"|"a")[^\n]+ {
  99.             strcpy(scenes[scene_no - 1].musicby,yytext + 1);
  100.         }
  101.  
  102. [CcBb#MmAa]"\n"    {
  103.             fprintf(stderr,"Invalid null %c, ignoring\n",yytext[0]);
  104.         }
  105.  
  106. [Ee]"\n"    {
  107.             write_scene();
  108.             return(0);
  109.         }
  110.  
  111. .        {
  112.             fprintf(stderr,"What does %c mean?\n",yytext[0]);
  113.         }
  114.  
  115. %%
  116.  
  117. void add_char_to_scene(char *thechar) {
  118.     int i;
  119.  
  120.     i = 0;
  121.     while(chars[i].num_scenes) {
  122.         if(!strcmp(chars[i].name,thechar))
  123.             break;
  124.         i++;
  125.     }
  126.  
  127.     if(chars[i].num_scenes) {
  128.         chars[i].num_scenes++;
  129.         chars[i].scenes[chars[i].num_scenes-1] = scene_no;
  130.     } else {
  131.         strcpy(chars[i].name,thechar);
  132.         chars[i].scenes[0] = scene_no;
  133.         chars[i].num_scenes = 1;
  134.     }
  135.  
  136.     scenes[scene_no-1].chars[scenes[scene_no-1].num_chars] = i;
  137.     scenes[scene_no-1].num_chars++;
  138. }
  139.  
  140. void write_scene(void) {
  141.     static int first = 1;
  142.     int i;
  143.  
  144.     if(first) {
  145.         first = 0;
  146.         return;
  147.     }
  148.  
  149.     if(!scenes[scene_no-1].book[0]) {
  150.       strcpy(scenes[scene_no-1].book,curr_book);
  151.     }
  152.  
  153.     printf("\\vskip 12pt\nScene {\\scenef %d}\n\n",scene_no);
  154.     printf("from {\\bookf %s}, p. %d\n\n",scenes[scene_no-1].book,
  155.                         scenes[scene_no-1].page);
  156.     printf("Characters: ");
  157.     
  158.     sort_scene_chars();
  159.  
  160.     for(i=0; i<scenes[scene_no-1].num_chars; i++) {
  161.         printf("%s{\\charf %s}",
  162.                i?",\n":"",
  163.                chars[scenes[scene_no-1].chars[i]].name);
  164.     }
  165.     printf("%s.\n\n",i?"":"Narrator");
  166.  
  167.     if(scenes[scene_no-1].music[0]) {
  168.       printf("Music: {\\musicf ``%s''}, %s",
  169.          scenes[scene_no-1].music,
  170.          scenes[scene_no-1].musicby);
  171.     }
  172.  
  173.     printf("\n\n");
  174. }
  175.  
  176. static void sort_scene_chars(void) {
  177.   int i;
  178.  
  179.   qsort((char *)scenes[scene_no-1].chars,scenes[scene_no-1].num_chars,
  180.     sizeof scenes[scene_no-1].chars[0],
  181.     sort_int_by_char);
  182. }
  183.  
  184. static int sort_int_by_char(const void *a,const void *b) {
  185.   int i = *(const int *)a,j = *(const int *)b;
  186.  
  187.   return(strcmp(chars[i].name,chars[j].name));
  188. }
  189.  
  190. static int sort_char_by_name(const void *a,const void *b) {
  191.   const char *n = ((const struct character *)a)->name;
  192.   const char *o = ((const struct character *)b)->name;
  193.  
  194.   return(strcmp(n,o));
  195. }
  196.  
  197. /*
  198.  * WARNING
  199.  * This function destroys the mapping from scens[i].chars[i] to
  200.  * an actual character.  It MUST BE CALLED LAST (or at least after
  201.  * this mapping is no longer needed.
  202.  */
  203. static void anal_chars(void) {
  204.   int i,j,last,olast;
  205.  
  206.   for(i=0; chars[i].num_scenes; i++); /* i is now number of characters */
  207.  
  208.   qsort((char *)chars,i,sizeof chars[0],sort_char_by_name);
  209.  
  210.   printf("\\vskip 0pt plus 1filll\n{\\bigfont Character Windows}\n\n");
  211.  
  212.   for(i=0; chars[i].num_scenes; i++) {
  213.     printf("\\vskip 12pt\nCharacter %s appears in scenes: \n",chars[i].name);
  214.  
  215.     last = 0; olast = 0;
  216.  
  217.     /* look, this could be a lot smarter if I felt like working on it more.
  218.        If I ever get around to it, maybe.  Maybe. */
  219.  
  220.     for(j=0; j < chars[i].num_scenes; j++) {
  221.       if(last && (chars[i].scenes[j] == last + 1)) {
  222.     /*
  223.      * The last one we got was one less than this one, so keep on
  224.      * going.
  225.      */
  226.     olast = last++;
  227.       } else if(last) {
  228.     /*
  229.      * The last one we got was something else, so output the
  230.      * last one, a comma, and then this one.
  231.      */
  232.     if(olast) {
  233.       printf("--%d",last);
  234.       olast = 0;
  235.     }
  236.  
  237.     printf(", %d",last=chars[i].scenes[j]);
  238.       } else {
  239.     /*
  240.      * The first scene: just print it.
  241.      */
  242.     printf("%d",last=chars[i].scenes[j]); /* side effect */
  243.       }
  244.     }
  245.     if(last && olast) {
  246.       printf("--%d",last);
  247.     }
  248.     printf(".\n\n");
  249.   }
  250. }
  251.  
  252.  
  253. void main(int argc,char **argv) {
  254.   argc--; argv++;
  255.   if(argc) {
  256.     if(!freopen(*argv,"r",stdin)) {
  257.       fprintf(stderr,"scene: cannot open input file %s\n",*argv);
  258.       exit(1);
  259.     }
  260.   }
  261.  
  262.   /* USER CUSTOMIZATION
  263.    * You may want to change some of these definitions, especially
  264.    * if your printer has good fonts of its own.
  265.    */
  266.   printf("\\font\\scenef=cmbx10 scaled \\magstep2\n"
  267.      "\\font\\bookf=cmti10 scaled \\magstephalf\n"
  268.      "\\font\\charf=cmbx10 scaled \\magstep1\n"
  269.      "\\font\\musicf=cmsl10 scaled \\magstephalf\n"
  270.      "\\font\\bodyfont=cmr10 scaled \\magstephalf\n"
  271.      "\\font\\bigfont=cmr10 scaled \\magstep2\n"
  272.      "{\\bodyfont\n");
  273.  
  274.   yylex();
  275.   anal_chars();
  276.   printf("}\\end\n");
  277.   exit(0);
  278. }
  279.  
  280.