# データフレーム・行列を LaTeX の表にする
print.latex <- function(
			x, 			# matrix or data frame;  "latex" class
			file="", 		# output file (default to screen)
			append=FALSE, 		# rewrite or append output file
			ctable=TRUE, 		# use ctable.sty or not
			caption="", 		# caption
			cap="", 		# short caption (ctable only)
			label="", 		# label
			htbp="htbp", 		# layout			ex. htpb="ht" or "p" etc.
			align=NULL, 		# algnment of column		ex. align="rlcrlcrlc"
			format=NULL,		# format of column		ex. format="f5 2i s" == "%.5f %i %i %s"
			tnote=NULL, 		# tnote (ctable only)		ex. tnote=c("xxx...", "yyy...",...)
			line.feed=NULL, 	# \\[nn] (not for ctable)	ex. line.feed="-1.5mm" etc. 
			na2blank=TRUE		# display blank for NA values
		)
{
	nc <- ncol(x)									# オブジェクトの列数
	nr <- nrow(x)									# オブジェクトの行数
	has.rowname <- !is.null(rownames(x))						# 行名がある
	if (is.null(colnames(x))) {							# 列名がないときは，
		colnames(x) <- paste("Col", 1:nc, sep="-")				# "Col-##" の形式で名前を付ける
	}
	if (is.null(align)) {								# align の指定がないときは，
		align <- paste(rep("c", nc+has.rowname), collapse="")			# センター揃え "c…" にする
	}
	if (is.null(format)) {								# format の指定がないときは，
		format <- rep("%s", nc)							# "%s" で書く
	}
	else {										# format の指定があるときは，
		format <- unlist(strsplit(format, "[ ,]"))				# 文字ベクトルに分解
		format <- unlist(sapply(format, function(str) {				# Rf3 のような形式（R 繰り返し）に対応
			rep <- sub("[a-z]+[0-9]*", "", str)
			if (rep == "") {
				rep <- "1"
			}
			rep <- as.integer(rep)
			fmt <- sub("^[0-9]*", "", str)
			return(rep(fmt, rep))
		}))
		if (nc+has.rowname > length(format)) stop("too few formats")		# 行名がないときは列数に等しいこと，行名があれば列数プラス1
		else if (nc+has.rowname < length(format)) stop("too many formats")
		format <- sapply(1:(nc+has.rowname), function(i) {			# 正式な format に変換する
			fmt <- format[i]
			ch <- substring(fmt, 1, 1)
			if (ch == "f") {
				format[i] <- paste("%.", substring(fmt, 2), "f", sep="")
			}
			else {
				format[i] <- paste("%", ch, sep="")
			}
		})
	}
	cat("%\n", file=file, append=append, sep="")					# ヘッダー
	if (ctable) {									# ctable 形式で出力する場合
		cat(	"\\ctable[\n",
			"\tcap = {", cap, "},\n",
			"\tcaption = {", caption, "},\n",
			"\tlabel = ", label, ",\n",
			"\tpos = htbp\n",
			"]\n",
			"{", align, "}\n",
			file=file, append=append, sep="")
		if (is.null(tnote)) {
			cat("{}\n", file=file, append=append, sep="")
		}
		else {
			cat("{\n", file=file, append=append, sep="")
			sapply(1:length(tnote),
				function(i)
				cat("\\tnote[", letters[i], "]{", tnote[i], "}\n", file=file, append=append, sep=""))
			cat("}\n", file=file, append=append, sep="")
		}
		cat("{ \\FL\n", file=file, append=append, sep="")
		head <- sprintf("\t %s %s \\ML\n", if (has.rowname) "&" else "", paste(colnames(x), collapse=" & "))
		cat(head, file=file, append=TRUE)
		for (i in 1:nr) {
			temp <- sapply(1:nc, function(j) sprintf(format[j+has.rowname], x[i, j]))
			if (has.rowname) {
				body <- sprintf("\t %s & %s", sprintf(format[1], rownames(x)[i]), paste(temp, collapse=" & "))
			}
			else {
				body <- sprintf("\t %s", paste(temp, collapse=" & "))
			}
			if (na2blank) {							# na2blank == TRUE なら，
				body <- gsub("(^NA | NA | NA$)", " ", body)		# NA を出力しない（空白を出力する）
			}
			if (i == nr) {
				body <- sprintf("%s \\LL\n", body)
			}
			else {
				body <- sprintf("%s \\NN\n", body)
			}
			cat(body, file=file, append=TRUE)
		}
		cat("}\n", file=file, append=TRUE, sep="")
	}
	else {										# table 形式で出力する場合
		cat(	"\\begin{table}[", htbp, "]\n",
			"\t\\caption{", caption, "}\n",
			"\t\\label{", label, "}\n",
			"\t\\centering\n",
			"\t\t\\begin{tabular}{", align, "} \\hline\n",
			file=file, append=append, sep="")
		head <- sprintf("\t\t\t\t %s %s \\\\ \\hline\n", if (has.rowname) "&" else "", paste(colnames(x), collapse=" & "))
		cat(head, file=file, append=TRUE)
		for (i in 1:nr) {
			temp <- sapply(1:nc, function(j) sprintf(format[j+has.rowname], x[i, j]))
			if (has.rowname) {
				body <- sprintf("\t\t\t %s & %s",  sprintf(format[1], rownames(x)[i]),  paste(temp, collapse=" & "))
			}
			else {
				body <- sprintf("\t\t\t %s", paste(temp, collapse=" & "))
			}
			if (na2blank) {							# na2blank == TRUE なら，
				body <- gsub("(^NA | NA | NA$)", " ", body)		# NA を出力しない（空白を出力する）
			}
			if (i == nr) {
				body <- sprintf("%s \\\\ \\hline\n", body)
			}
			else if (is.null(line.feed)) {
				body <- sprintf("%s \\\\\n", body)
			}
			else {
				body <- sprintf("%s \\\\[%s]\n", body, line.feed)
			}
			cat(body, file=file, append=TRUE)
		}
		cat("\t\t\\end{tabular}\n", "\\end{table}\n", file=file, append=TRUE, sep="")
	}
	cat("%\n", file=file, append=TRUE, sep="")					# フッター
}
