home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume18
/
scene
/
part01
/
scene.l
< prev
Wrap
Text File
|
1991-04-26
|
6KB
|
280 lines
%{ / -*- Mode: Fundamental -*-
/*
* scene - a scene-file processor for TeX
*/
/*
* Copyright 1991, Garrett A. Wollman
*
* The recipient is licensed to compile, modify, and distribute this work
* provided that this comment remains intact and unmodified in any such
* versions, and the documentation (such as it is) is included.
* Modified version must clearly be marked as such.
*
* If this program is of any use to anybody, I would appreciate hearing
* about it. Please send E-mail to wollman@sadye.uvm.edu (in bangland,
* ...uunet!uvm-gen!griffin!wollman).
*/
/* These prototypes are fairly standard... although it should
* probably be "void *" as the first parm to qsort()
*/
extern void volatile exit(int);
extern void qsort(char *,int,int,int (*)(const void *,const void *));
int scene_no;
/*
* Look, I told you this was a quick hack, didn't I?
* The program doesn't even check if you overrun any
* of these fixed limits. Boo! Hiss! But I can't be
* bothered to do it right so long as it still works
* for me.
*/
struct character {
char name[255];
short scenes[512];
int num_scenes;
} chars[256];
struct scene {
char book[32];
int chars[64];
int num_chars;
int page;
char music[64];
char musicby[64];
} scenes[640];
/* some more prototypes */
static void add_char_to_scene(char *);
static void write_scene(void);
static void sort_scene_chars(void);
static int sort_int_by_char(const void *,const void *);
static int sort_char_by_name(const void *,const void *);
extern int strcmp(const char *,const char *);
extern char *strcpy(char *,const char *);
extern char *strcat(char *,const char *);
/* some more local data */
char curr_book[256];
int curr_page;
%}
%%
"\n" ;
"S"|"s" {
write_scene();
scene_no++;
}
("C"|"c")[^\n]+ {
add_char_to_scene(yytext + 1);
}
("B"|"b")[^\n]+ {
strcpy(curr_book,yytext + 1);
strcpy(scenes[scene_no - 1].book,yytext + 1);
}
"#"[0-9]+ {
sscanf(yytext,"#%d",&(scenes[scene_no - 1].page));
}
"#"[^0-9]+ {
fprintf(stderr,"Invalid page number, ignoring\n");
}
("M"|"m")[^\n]+ {
strcpy(scenes[scene_no - 1].music,yytext + 1);
}
("A"|"a")[^\n]+ {
strcpy(scenes[scene_no - 1].musicby,yytext + 1);
}
[CcBb#MmAa]"\n" {
fprintf(stderr,"Invalid null %c, ignoring\n",yytext[0]);
}
[Ee]"\n" {
write_scene();
return(0);
}
. {
fprintf(stderr,"What does %c mean?\n",yytext[0]);
}
%%
void add_char_to_scene(char *thechar) {
int i;
i = 0;
while(chars[i].num_scenes) {
if(!strcmp(chars[i].name,thechar))
break;
i++;
}
if(chars[i].num_scenes) {
chars[i].num_scenes++;
chars[i].scenes[chars[i].num_scenes-1] = scene_no;
} else {
strcpy(chars[i].name,thechar);
chars[i].scenes[0] = scene_no;
chars[i].num_scenes = 1;
}
scenes[scene_no-1].chars[scenes[scene_no-1].num_chars] = i;
scenes[scene_no-1].num_chars++;
}
void write_scene(void) {
static int first = 1;
int i;
if(first) {
first = 0;
return;
}
if(!scenes[scene_no-1].book[0]) {
strcpy(scenes[scene_no-1].book,curr_book);
}
printf("\\vskip 12pt\nScene {\\scenef %d}\n\n",scene_no);
printf("from {\\bookf %s}, p. %d\n\n",scenes[scene_no-1].book,
scenes[scene_no-1].page);
printf("Characters: ");
sort_scene_chars();
for(i=0; i<scenes[scene_no-1].num_chars; i++) {
printf("%s{\\charf %s}",
i?",\n":"",
chars[scenes[scene_no-1].chars[i]].name);
}
printf("%s.\n\n",i?"":"Narrator");
if(scenes[scene_no-1].music[0]) {
printf("Music: {\\musicf ``%s''}, %s",
scenes[scene_no-1].music,
scenes[scene_no-1].musicby);
}
printf("\n\n");
}
static void sort_scene_chars(void) {
int i;
qsort((char *)scenes[scene_no-1].chars,scenes[scene_no-1].num_chars,
sizeof scenes[scene_no-1].chars[0],
sort_int_by_char);
}
static int sort_int_by_char(const void *a,const void *b) {
int i = *(const int *)a,j = *(const int *)b;
return(strcmp(chars[i].name,chars[j].name));
}
static int sort_char_by_name(const void *a,const void *b) {
const char *n = ((const struct character *)a)->name;
const char *o = ((const struct character *)b)->name;
return(strcmp(n,o));
}
/*
* WARNING
* This function destroys the mapping from scens[i].chars[i] to
* an actual character. It MUST BE CALLED LAST (or at least after
* this mapping is no longer needed.
*/
static void anal_chars(void) {
int i,j,last,olast;
for(i=0; chars[i].num_scenes; i++); /* i is now number of characters */
qsort((char *)chars,i,sizeof chars[0],sort_char_by_name);
printf("\\vskip 0pt plus 1filll\n{\\bigfont Character Windows}\n\n");
for(i=0; chars[i].num_scenes; i++) {
printf("\\vskip 12pt\nCharacter %s appears in scenes: \n",chars[i].name);
last = 0; olast = 0;
/* look, this could be a lot smarter if I felt like working on it more.
If I ever get around to it, maybe. Maybe. */
for(j=0; j < chars[i].num_scenes; j++) {
if(last && (chars[i].scenes[j] == last + 1)) {
/*
* The last one we got was one less than this one, so keep on
* going.
*/
olast = last++;
} else if(last) {
/*
* The last one we got was something else, so output the
* last one, a comma, and then this one.
*/
if(olast) {
printf("--%d",last);
olast = 0;
}
printf(", %d",last=chars[i].scenes[j]);
} else {
/*
* The first scene: just print it.
*/
printf("%d",last=chars[i].scenes[j]); /* side effect */
}
}
if(last && olast) {
printf("--%d",last);
}
printf(".\n\n");
}
}
void main(int argc,char **argv) {
argc--; argv++;
if(argc) {
if(!freopen(*argv,"r",stdin)) {
fprintf(stderr,"scene: cannot open input file %s\n",*argv);
exit(1);
}
}
/* USER CUSTOMIZATION
* You may want to change some of these definitions, especially
* if your printer has good fonts of its own.
*/
printf("\\font\\scenef=cmbx10 scaled \\magstep2\n"
"\\font\\bookf=cmti10 scaled \\magstephalf\n"
"\\font\\charf=cmbx10 scaled \\magstep1\n"
"\\font\\musicf=cmsl10 scaled \\magstephalf\n"
"\\font\\bodyfont=cmr10 scaled \\magstephalf\n"
"\\font\\bigfont=cmr10 scaled \\magstep2\n"
"{\\bodyfont\n");
yylex();
anal_chars();
printf("}\\end\n");
exit(0);
}