###
### lsa reference formatting style
###

BEGIN	{
	PASS="";		# only one pass thru document
	sortflag = 1;		# reference_placement bib is sortedone
	STYLE = "lsa";
	SKEY = "adt";
}



#######################################################
#
# Functions required by general awk script
#
#######################################################


##
## Set author and editor fields
##	for reference list
##	for citation
##	for possible sorting
##
func setauthor(b,a) {
	Afull[b,a] = FirstMiddleLast();
	Arfull[b,a] = LastFirstMiddle();
	Alast[b,a] = Last;
	Asort[b] = Asort[b] Arfull[b,a] " ";
}

func seteditor(b,a) {
	Efull[b,a] = FirstMiddleLast();;
	Erfull[b,a] = LastFirstMiddle();
	Elast[b,a] = Last;
	Esort[b] = Esort[b] Erfull[b,a] " ";
}




##
## citations
##	print a citation list
##	(Last year{, year}, Last year...)
##
func citations(lastpunc) {
	sep = "\n(";
	if(lastpunc == "\"" || lastpunc == "'") {
		sep = lastpunc " (";
		lastpunc = "\\ ";
	}
	ptext = 0;
	ctext = 0;
	for(i=1; i<=cites; i++) {
		cn = bibptr[i];
		b = uniqno[cn];
		if (pre_text[cn]) ctext = 1;
		if ((ctext == 1) || (ptext == 1) || new_author(i)) {
			printf sep;
			if (pre_text[cn]) {
				printf "%s", pre_text[cn];
				if((no_author[cn] == 0) || (no_date[cn] == 0))
					printf " ";
			}	
			if (no_author[cn] == 0) {
				if(authors[b])
					printlast(b);
				else if (editors[b])
					printlasted(b);
				else if (issuer[b])
					printf issuer[b];
				else
					printf title[b];
				punc = " ";
			}
			else punc = "";
		}
		else {
			punc = ", ";
		}
		if(no_date[cn] == 0) {
			if(year[b] ~ /^[0-9][0-9][0-9][0-9]$/)
				printf "%s%s", punc, year[b];
			else {
				if (date[b] != 0) printf "%s%s", punc, date[b];
			}
		}
		if (post_text[cn]) {
			if (is_punc(substr(post_text[cn],1,1)) == 0) print "";
			printf "%s", post_text[cn];
		}
		sep = ",\n";
		ptext = ctext;
		ctext = 0;
	}
	printf ")";
	printf lastpunc;
}

func is_punc(p)
{
	if(p == ",") return 1;
	if(p == ".") return 1;
	if(p == ";") return 1;
	return 0;
}

##
## new_author
##	returns 1 if current author is difference from
##	previous author in the citation list
##
func new_author(c) {
	if (c == 1) return 1;
	b1 = uniqno[bibptr[c-1]];
	b = uniqno[bibptr[c]];
	if(authors[b] == 0) return 1;
	if(authors[b1] != authors[b]) return 1;
	for(k = 1; k <= authors[b]; k++) {
		if (Alast[b1,k] != Alast[b,k]) return 1;
	}
	return 0;
}


##
## print author last name for citation
##	First
##	First and Second
##	First, Second,..., & Last
func printlast(c) {			
        a = authors[c]			
	if ( a == 1 ) printf "%s", Alast[c,1];
	else if ( a == 2 ) printf "%s & %s", Alast[c,1], Alast[c,2];
	else if (a > 5) printf "%s et al.", Alast[c,1];
	else {
		for ( j = 1; j < a; j++ ) printf Alast[c,j] ", ";
		printf "& %s", Alast[c,a];
	}
}

##

## print editor last name for citation
##	First
##	First and Second
##	First, Second,..., & Last
func printlasted(c) {			
        a = editors[c]			
	if ( a == 1 ) printf "%s", Elast[c,1];
	else if ( a == 2 ) printf "%s & %s", Elast[c,1], Elast[c,2];
	else if (a > 5) printf "%s et al.", Elast[c,1] ;
	else {
		for ( j = 1; j < a; j++ ) printf "%s, ", Elast[c,j];
		printf "& %s", Elast[c,a];
	}
}


##
## bibindex
##	set up indentation for bibliography;
##	return an index for accessing rest of citation
##	do misc stuff specific to this style
##
func bibindex(i) {
	printf ".sp .3\n.ti -.3i\n";
	if (sortflag)
		return sortorder[i];
	else return i;
}



#############################################
#
# Reference types
#
############################################


func book(b) {
	# authorlist.
			if(authors[b]) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# date.
			printf "%s", date[b] ;
			punc = ".\n";
	# title
			if(title[b]) {
				printf "%s%s", punc, title[b];
	# Vol #.
				if(volstr[b])
					printf ", %s", volstr[b];
				else if(volume[b])
					printf ", Vol. %s", volume[b];
			}
	# location: publisher.
			if (city[b]) {
				printf "%s%s", punc, city[b] ;
				punc = ": ";
			}
			printf "%s%s", punc, issuer[b] ;
}


func editedbook(b) {
	# authorlist.
			if(authors[b]) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# date.
			printf "%s", date[b] ;
				if(authors[b] <2)
					printf " (ed.)\n";
				else
					printf " (eds.)\n";
	# italic(title)
			if(title[b]) {
				printf title[b];
				punc = ".\n";
			}
	# (Vol #).
			if(volstr[b])
				printf ", %s", volstr[b];
			else if(volume[b])
				printf ", Vol. %s", volume[b];
	# location: publisher.
			if (city[b]) {
				printf "%s%s", punc, city[b] ;
				punc = ": ";
			}
			printf "%s%s", punc, issuer[b] ;
}


func thesis(b) {

	# authorlist.
			if(authors[b]) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# date.
			printf "%s.\n", date[b] ;
	# title.
			if(title[b]) {
				printf "%s.\n", title[b];
			}
	# city
			if(address[b]) {
				printf "%s: ", address[b];
			}
	# thesis, school.
			if(reftype[b] == "phdthesis")
				printf "%s dissertation", issuer[b];
			else if(reftype[b] == "mastersthesis")
				printf "%s master's thesis", issuer[b];
}

func review(b) {
	article(b);
}


func article(b) {

	# authorlist.
			if(authors[b]) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# date.
			printf "%s.\n", date[b] ;
	# title.
			if(title[b]) {
				printf title[b] ".\n";
			}
	# [reviewed title.]
			if(booktitle[b]) {
				printf "[Review of %s", booktitle[b];
				if(editors[b]) {
					printf " by ";
					editorlist(b);
				if (issuer[b]) {
					printf " %s", issuer[b];
				}
				}
				printf "].\n";
			}

	# italics journal,
			printf "%s", journal[b];
			punc = ", ";
	# volume:number.pages
			if (volstr[b]) {
				printf ", %s", volstr[b];
				if (numstr[b]) {
					printf ", %s", numstr[b];
				}
				else if (number[b]) {
					printf ", %s", number[b];
				}
				punc = ".";
			}
			else if (volume[b]) {
				printf " %s", volume[b];
				if (numstr[b]) {
					printf ", %s", numstr[b];
				}
				else if (number[b]) {
					printf ":%s",number[b];
				}
				punc = ".";
			}
			if ( pages[b] ) printf "%s%s", punc, pages[b];
}

func inproceedings(b) {

	# authorlist.
			if(authors[b]) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# date.
			printf "%s.\n", date[b] ;
	# title.
			if(title[b]) {
				printf title[b] ".\n";
			}

	# italics journal,
			printf "%s", journal[b];
			punc = ",\n";

	# ed. by editorlist,
			if(editors[b]) {
				printf ", ed. by "
				editorlist(b);
			}
			punc = ".\n";
	# pages.
			if(pages[b]) {
				printf ", %s", pages[b];
			}
	# location: publisher,
			if (city[b]) {
				printf "%s%s", punc, city[b] ;
				punc = ": ";
			}
			if (issuer[b])
				printf "%s%s", punc, issuer[b] ;
}

func proceedings(b) {
			punc = "";
	# authorlist.
			if(authors[b] >0) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# editor
			else if(editors[b]) {
				printedfull(b);
				if (editors[b] == 1) printf " (Ed.)"
				else if (editors[b] > 1) printf " (Eds.)"
				punc = ".\n";
			}

	# publisher
			else if(issuer[b]) {
				printf "%s%s", punc, issuer[b];
				punc = ".\n";
			}
	# date.
			printf "%s%s.\n", punc, date[b] ;
	# title
			if (title[b]) {
				printf "%s", title[b];
				punc = ".\n";
				if(substr(title[b],length(title[b]),1) == ".")
					punc = "\n";
			}
	# volume:number
			if (volstr[b]) {
				printf ", %s", volstr[b];
				if (numstr[b]) {
					printf ", %s", numstr[b];
				}
				else if (number[b]) {
					printf ", %s", number[b];
				}
				punc = ".";
			}
			else if (volume[b]) {
				printf " %s", volume[b];
				if (numstr[b]) {
					printf ", %s", numstr[b];
				}
				else if (number[b]) {
					printf ":%s",number[b];
				}
				punc = ".";
			}
	# location: publisher,
			if (city[b]) {
				printf "%s%s", punc, city[b] ;
				punc = ": ";
			}
			printf "%s%s", punc, issuer[b] ;
}


func incollection(b) {

	# authorlist.
			if(authors[b]) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}	
	# date.
			printf "%s.\n", date[b] ;
	# title
			if(title[b]) {
				printf "%s.\n", title[b];
			}
	# booktitle,
			printf "%s", booktitle[b];
	# Vol #.
			if(volstr[b])
				printf ", %s", volstr[b];
			else if(volume[b])
				printf ", Vol. %s", volume[b];
	# ed. by editorlist,
			if(editors[b]) {
				printf ", ed. by "
				editorlist(b);
			}
			punc = ".\n";
	# pages.
			if(pages[b]) {
				printf ", %s", pages[b];
			}
	# location: publisher,
			if (city[b]) {
				printf "%s%s", punc, city[b] ;
				punc = ": ";
			}
			printf "%s%s", punc, issuer[b];
}



func techreport(b) {

	# authorlist.
			if(authors[b]) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# date.
			printf "%s.\n", date[b] ;
	# title.
			if(title[b])
				printf "%s.\n", title[b];
	# (report number).
			printf "(%s).\n", report[b];

	# location: publisher.
			if (city[b]) printf "%s: ", city[b] ;
			printf issuer[b];
}

func tm(b) {

	# authorlist.
			if(authors[b]) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# date.
			printf "%s.\n", date[b] ;
	# title.
			if(title[b])
				printf "%s.\n", title[b];
	# (tm number).
			if(rp)
				printf "(AT&T Bell Laboratories internal memorandum)";
			else
				printf "(%s)", tmno[b] 
}

func manual(b) {
			punc = "";
	# authorlist.
			if(authors[b] >0) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# editor.
			else if(editors[b]) {
				if(printedfull(b) != ".")
					printf ".";
				printf "\n";
			}

	# publisher
			else if(issuer[b]) {
				printf "%s%s", punc, issuer[b];
				punc = ".\n";
			}
	# date.
			printf "%s%s", punc, date[b] ;
				if (editors[b] == 1) printf " (ed.)\n";
				else if (editors[b] > 1) printf " (eds.)\n";
				else printf ".\n";
	# title
			if(title[b]) {
				printf "%s", title[b];
				punc = ".\n";
			}
	# location: publisher.
			if (city[b]) {
				printf "%s%s", punc, city[b] ;
				punc = ": ";
			}
			if(issuer[b]) {
				if(editors[b] || authors[b]);
					printf "%s%s", punc, issuer[b];
			}
}

func pamphlet(b)
{

			punc = "";
	# authorlist.
			if(authors[b] >0) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# publisher.
			else if(issuer[b]) {
				printf issuer[b];
				punc = ".\n";
			}
	# title.
			else if(title[b]) {
				printf title[b];
				punc = ".\n"
			}
	# date.
			if(date[b]) {
				printf "%s%s", punc, date[b] ;
				punc = ".\n";
			}
	# title
			if(editors[b] || authors[b] || issuer[b]) {
				if(title[b]) {
					printf "%s%s", punc, title[b];
					punc = ".\n"
				}
			}

	# Vol #.
			if(volstr[b])
				printf ", %s", volstr[b];
			else if(volume[b])
				printf ", Vol. %s", volume[b];
	# location: publisher.
			if (city[b]) {
				printf "%s%s", punc, city[b] ;
				punc = ": ";
			}
			if(issuer[b]) {
				if(editors[b] || authors[b]);
					printf "%s%s", punc, issuer[b];
			}

}

func default(b) {
			punc = "";
	# authorlist.
			if(authors[b]) {
				if(printfull(b) != ".")
					printf ".";
				printf "\n";
			}
	# publisher.
			else if(issuer[b]) {
				printf  issuer[b];
				punc = ".\n";
			}
	# title.
			else if(title[b]) {
				printf  title[b];
				punc = ".\n"
			}
	# date.
			if(date[b]) {
				printf "%s%s", punc, date[b] ;
				punc = ".\n";
			}
	# title
			if(editors[b] || authors[b] || issuer[b] ) {
				if(title[b]) {
					printf "%s%s", punc, title[b];
					punc = ".\n"
				}
			}
	# Vol #,
			if(volstr[b]) {
				printf ", %s", volstr[b];
				punc = ".\n";
			}
			else if(volume[b]) {
				printf ", Vol. %s", volume[b];
				punc = ".\n";
			}
	# pages.
			if (pages[b]) {
				printf ", %s", pages[b];
				punc = ".\n";
			}

	# location: publisher.
			if (city[b]) {
				printf "%s%s", punc, city[b] ;
				punc = ": ";
			}
			if(issuer[b]) {
				if(editors[b] || authors[b]);
					printf "%s%s", punc, issuer[b];
			}
}

#
# return index of previous item
#

func previous(q)
{
	if (sortflag)
		return sortorder[inverse[q]-1];
	else
		return q-1;
}



# Author, First
# Author, First, and Second Author
# Author, First, Second Author, and Remaining Authors

func printfull(b) {
	longdash = "\\(em\\(em\\(em";
	dash = 0;			
	prev = previous(b);
	if ( authors[b] == 1 ) {
		if(Arfull[b,1] == Arfull[prev,1]) {
			printf longdash;
			return "";
		}
		else printf Arfull[b,1] ;
		if(aetal[b]) {
			printf ", et al.";
			return ".";
		}
		return substr(Arfull[b,1],length(Arfull[b,1]));
	}
	else if ( authors[b] == 2 ) {
		if(Arfull[b,1] == Arfull[prev,1]) {
			printf longdash;
			dash = 1;
		}
		else printf Arfull[b,1];
		printf ", and "
		if(dash && (Afull[b,2] == Afull[prev,2]))
			printf longdash;
		else printf Afull[b,2];
	}	
	else {
		if(Arfull[b,1] == Arfull[prev,1]) {
			printf longdash;
			dash = 1;
		}
		else printf Arfull[b,1];
		printf "; ";
		for ( j = 2 ; j < authors[b]; j++ ) {
			if(dash && (Afull[b,j] == Afull[prev,j]))
				printf longdash;
			else {
				dash = 0;
				printf Afull[b,j];
			}
			printf  "; ";
		}
		printf "and "
		j = authors[b];
		if(dash && (Afull[b,j] == Afull[prev,j]))
			printf longdash;
		else printf Afull[b,j];
	}
	return "";
}

func printedfull(b) {
	longdash = "\\(em\\(em\\(em\\(em";
	dash = 0;
	prev = previous(b);			
 	if ( editors[b] == 0 ) ;
	else if ( editors[b] == 1 ) {
		if(Erfull[b,1] == Erfull[prev,1]) {
			printf longdash;
			return "";
		}
		else printf Erfull[b,1] ;
		if(aetal[b]) {
			printf ", et al.";
			return ".";
		}
		return substr(Erfull[b,1],length(Erfull[b,1]));
	}
	else if ( editors[b] == 2 ) {
		if(Erfull[b,1] == Erfull[prev,1]) {
			printf longdash;
			dash = 1;
		}
		else printf Erfull[b,1];
		printf ", and "
		if(dash && (Efull[b,2] == Efull[prev,2]))
			printf longdash;
		else printf Efull[b,2];
	}	
	else {
		if(Erfull[b,1] == Erfull[prev,1]) {
			printf longdash;
			dash = 1;
		}
		else printf Erfull[b,1];
		printf "; ";
		for ( j = 2 ; j < editors[b]; j++ ) {
			if(dash && (Efull[b,j] == Efull[prev,j]))
				printf longdash;
			else {
				dash = 0;
				printf Efull[b,j];
			}
			printf  "; ";
		}
		printf "and "
		j = editors[b];
		if(dash && (Efull[b,j] == Efull[prev,j]))
			printf longdash;
		else printf Efull[b,j];
	}
	return "";
}



func editorlist(b) {			
 	if ( editors[b] == 0 ) ;
	else if ( editors[b] == 1 ) printf "%s", Efull[b,1] ;
	else if ( editors[b] == 2 ) printf "%s & %s", Efull[b,1], Efull[b,2];
	else {
		printf  "%s et al.", Efull[b,1];
	}
}
