[r-cran-xtable] 04/06: Imported Upstream version 1.8-2

Jonathon Love jon at thon.cc
Fri Apr 22 01:07:53 UTC 2016


This is an automated email from the git hooks/post-receive script.

jonathon-guest pushed a commit to branch master
in repository r-cran-xtable.

commit 9b92152fbe79c3f1cc02eba62f700482f890fca2
Author: Jonathon Love <jon at thon.cc>
Date:   Fri Apr 22 10:37:46 2016 +1000

    Imported Upstream version 1.8-2
---
 DESCRIPTION                          |   15 +-
 MD5                                  |   68 +-
 NAMESPACE                            |   38 +-
 NEWS                                 |   69 +-
 R/autoformat.R                       |   53 ++
 R/lagImpactMat.R                     |   44 ++
 R/print.xtable.R                     | 1147 ++++++++++++++++------------------
 R/sanitize.R                         |   97 +++
 R/table.attributes.R                 |  151 ++---
 R/toLatex.R                          |   10 +-
 R/xtable.R                           |  290 +++++++--
 R/xtableFtable.R                     |  197 ++++++
 R/xtableList.R                       |  275 ++++++++
 R/xtableMatharray.R                  |   36 ++
 build/vignette.rds                   |  Bin 251 -> 344 bytes
 data/tli.txt.gz                      |  Bin 585 -> 560 bytes
 inst/doc/OtherPackagesGallery.R      |  153 +++++
 inst/doc/OtherPackagesGallery.Rnw    |  322 ++++++++++
 inst/doc/OtherPackagesGallery.pdf    |  Bin 0 -> 145176 bytes
 inst/doc/listOfTablesGallery.R       |  144 +++++
 inst/doc/listOfTablesGallery.Rnw     |  267 ++++++++
 inst/doc/listOfTablesGallery.pdf     |  Bin 0 -> 146245 bytes
 inst/doc/margintable.R               |   31 +-
 inst/doc/margintable.Rnw             |   13 +-
 inst/doc/margintable.pdf             |  Bin 90568 -> 51841 bytes
 inst/doc/xtableGallery.R             |  944 +++++++++++-----------------
 inst/doc/xtableGallery.Rnw           |  731 ++++++++++++++++++++++
 inst/doc/xtableGallery.pdf           |  Bin 239535 -> 242003 bytes
 inst/doc/xtableGallery.snw           |  585 -----------------
 man/autoformat.Rd                    |   75 +++
 man/print.xtable.Rd                  |  103 +--
 man/print.xtableMatharray.Rd         |   96 +++
 man/sanitize.Rd                      |  105 ++++
 man/string.Rd                        |    5 +-
 man/table.attributes.Rd              |    7 +-
 man/tli.Rd                           |    3 +-
 man/xtable-internal.Rd               |   13 +
 man/xtable.Rd                        |   80 ++-
 man/xtableFtable.Rd                  |  347 ++++++++++
 man/xtableList.Rd                    |  331 ++++++++++
 man/xtableMatharray.Rd               |  105 ++++
 tests/test.matharray.R               |   37 ++
 tests/test.xalign.xdigits.xdisplay.R |   49 ++
 tests/test.xtable.xtableFtable.R     |   24 +
 vignettes/OtherPackagesGallery.Rnw   |  322 ++++++++++
 vignettes/listOfTablesGallery.Rnw    |  267 ++++++++
 vignettes/margintable.Rnw            |   13 +-
 vignettes/xtableGallery.Rnw          |  731 ++++++++++++++++++++++
 vignettes/xtableGallery.snw          |  585 -----------------
 49 files changed, 6333 insertions(+), 2645 deletions(-)

diff --git a/DESCRIPTION b/DESCRIPTION
index cdbb082..5a6a16b 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,14 +1,17 @@
 Package: xtable
-Version: 1.7-4
-Date: 2014/08/17
-Title: Export tables to LaTeX or HTML
+Version: 1.8-2
+Date: 2016-01-08
+Title: Export Tables to LaTeX or HTML
 Author: David B. Dahl <dahl at stat.byu.edu>
 Maintainer: David Scott <d.scott at auckland.ac.nz>
-Description: Coerce data to LaTeX and HTML tables
+Imports: stats, utils
+Suggests: knitr, lsmeans, spdep, splm, sphet, plm, zoo, survival
+VignetteBuilder: knitr
+Description: Coerce data to LaTeX and HTML tables.
 URL: http://xtable.r-forge.r-project.org/
 Depends: R (>= 2.10.0)
 License: GPL (>= 2)
 Repository: CRAN
-Packaged: 2014-09-11 22:38:16 UTC; dsco036
 NeedsCompilation: no
-Date/Publication: 2014-09-12 14:30:04
+Packaged: 2016-02-02 02:58:02 UTC; dsco036
+Date/Publication: 2016-02-05 19:22:18
diff --git a/MD5 b/MD5
index 859a8dd..40b1140 100644
--- a/MD5
+++ b/MD5
@@ -1,26 +1,50 @@
-2cb6fb8b229794a1f0b3f1942eda6442 *DESCRIPTION
-3b1d8bb64a284192c3090723f3973fe8 *NAMESPACE
-3cd1c6c94ca3385008051885faa0fae2 *NEWS
-2925af763dc97f52e15cec58c3a37865 *R/print.xtable.R
-224ad31199a69cbacb40593bc53670da *R/table.attributes.R
-a05e7179a5e51b4c0492dd92abd99cb5 *R/toLatex.R
-063aca83ae13f85e93b597e932423cac *R/xtable.R
-e461015597c171b358138351ac872a08 *build/vignette.rds
-b9a39bb9d8c88fbe0d3540a6ce1b11d3 *data/tli.txt.gz
-731fb95353666b59838b344a131a0c82 *inst/doc/margintable.R
-97de7ed6dfb487dc4888355c2355b137 *inst/doc/margintable.Rnw
-8f7529ffff1d2042e9d49727643d2bf4 *inst/doc/margintable.pdf
-88743ea9b7c8694fffd72bc5eb88892b *inst/doc/xtableGallery.R
-51086d16b8daed4035b9ee812f65471a *inst/doc/xtableGallery.pdf
-844a22a4adf2b2eddfd81757ed45b552 *inst/doc/xtableGallery.snw
-00c711d7e99853aab72f0c14bfb2c527 *man/print.xtable.Rd
-be0c2da0f5526de7a7bbaf045476255b *man/string.Rd
-3558d3ec1913057bed0f7e50cb5f10ff *man/table.attributes.Rd
-3c6841334d41dd4be535503ed29abd27 *man/tli.Rd
+6dd81c7b433108d593171196fa8198b5 *DESCRIPTION
+90596b1e5b9b8f180ef0f99094d463fd *NAMESPACE
+c8ac98db5287387914d25ec3761959b8 *NEWS
+5ae08bf6f1c93b19a9fd9dba478450d7 *R/autoformat.R
+8ea58528b95e7ae3b826b5da5d972939 *R/lagImpactMat.R
+6fba031394db12f413b056314417680f *R/print.xtable.R
+47e1421a7d31a9a104c4433cd84d79a1 *R/sanitize.R
+2c060a689e4abe5b527b03e744791dc3 *R/table.attributes.R
+61deeb5bc6a7f0da8fc14d68d073c842 *R/toLatex.R
+0f5e33b5c5923e5ec38341242ce17576 *R/xtable.R
+211fbb67f689c2f16fc940ebeb95eb4d *R/xtableFtable.R
+e398e3ea57af57d33e057deca8141d62 *R/xtableList.R
+bbe9b0d7afd6aa21f2cb29a068e9f982 *R/xtableMatharray.R
+e3af5932f38b00f75e5f840bc62f6105 *build/vignette.rds
+b6afe130c865e401927375d8a19c5660 *data/tli.txt.gz
+a1509f50be32cd1aefa57707436ae2d6 *inst/doc/OtherPackagesGallery.R
+05407db57a7b728e96023fefc6db75d3 *inst/doc/OtherPackagesGallery.Rnw
+4bb9328606ef54a87a6dfe36fc3cbce9 *inst/doc/OtherPackagesGallery.pdf
+5d242f8873cd471bbf8ba444735bed94 *inst/doc/listOfTablesGallery.R
+92fedeef7ae8001c9cd892e682705672 *inst/doc/listOfTablesGallery.Rnw
+325526dc0361086e76c486486e0b15a8 *inst/doc/listOfTablesGallery.pdf
+fbeb6f2011a3d0e76f0c6c435c82b458 *inst/doc/margintable.R
+99af34d2c77bb0a6d3c94d77353f282b *inst/doc/margintable.Rnw
+bd0ce99b8e3bb502972639dd08d35a5f *inst/doc/margintable.pdf
+3a277e10475eac250b616f435f76c845 *inst/doc/xtableGallery.R
+0fff2eac7404f621bb3c9ccfcea20217 *inst/doc/xtableGallery.Rnw
+b64bd89a854919b9c841468e570f5ab3 *inst/doc/xtableGallery.pdf
+f95d0f62ce805138f60e665c73eae98a *man/autoformat.Rd
+75c7e1dae94ded3203639a9c268f5b46 *man/print.xtable.Rd
+6f4e0d83245dbb2a052c8c5231a070af *man/print.xtableMatharray.Rd
+de7e9b4e1ba7d73979616e15d59aa785 *man/sanitize.Rd
+319908d8bdaa827ab3e702d75308a11f *man/string.Rd
+ce99416fe09c89d115650041321e3c4c *man/table.attributes.Rd
+09508527a5fa06fc0f845e3eeaaa2f0f *man/tli.Rd
 495dd6344cfa0335bb8018c094e081b3 *man/toLatex.Rd
-f643d895edf3b6d2bdba5111486b0f53 *man/xtable.Rd
+76c824e2e45a7ac6ca0313fba4a9edf4 *man/xtable-internal.Rd
+92ccae8e1bd7f7f18db93a0493bfb0b4 *man/xtable.Rd
+9dde9c9b6c3f56fe473e71f99bb75d23 *man/xtableFtable.Rd
+8cb43e1ae8c9ca119c264b933aa7a013 *man/xtableList.Rd
+2559d1cefd528d457e31d76eff8c32f1 *man/xtableMatharray.Rd
 596b4f4f3c425330eb54998231aca58b *tests/test.margintable.R
+41dd49eb66f7f3b27738424de6a27ac3 *tests/test.matharray.R
+820837020ab324ad88b4b9bf7fe2b451 *tests/test.xalign.xdigits.xdisplay.R
 12b35182cb70b6f47d262213b7e1b342 *tests/test.xtable.R
 3089b65c174191d5245050a760a86746 *tests/test.xtable.data.frame.R
-97de7ed6dfb487dc4888355c2355b137 *vignettes/margintable.Rnw
-844a22a4adf2b2eddfd81757ed45b552 *vignettes/xtableGallery.snw
+b084b5d2c7f7094464c2b64fc20cdf03 *tests/test.xtable.xtableFtable.R
+05407db57a7b728e96023fefc6db75d3 *vignettes/OtherPackagesGallery.Rnw
+92fedeef7ae8001c9cd892e682705672 *vignettes/listOfTablesGallery.Rnw
+99af34d2c77bb0a6d3c94d77353f282b *vignettes/margintable.Rnw
+0fff2eac7404f621bb3c9ccfcea20217 *vignettes/xtableGallery.Rnw
diff --git a/NAMESPACE b/NAMESPACE
index 52dbdd6..f5c4c69 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -1,15 +1,21 @@
-# NAMESPACE work by Robert Gentleman <rgentlem at fhcrc.org>
-# in e-mail on July 30, 2007.
-#
-# Extended by C Roosen, 30/01/2012
-
-importFrom("utils", toLatex)
-
+importFrom("utils", "toLatex")
+importFrom("stats", "anova", "as.ts", "cycle", "end", "frequency",
+           "na.omit", "pchisq", "start", "time")
+importFrom("utils", "packageDescription")
 export("caption<-", "caption", "label", "label<-",
-   "align<-", "align", "digits<-", "digits", "display<-",
-   "display", "xtable", "print.xtable", "toLatex.xtable")
+       "align<-", "align", "digits<-", "digits", "display<-",
+       "display", "xtable",
+       "xtableMatharray","xtableList", "xtableLSMeans",
+       "print.xtable", "print.xtableMatharray", "print.xtableList",
+       "xtableFtable", "print.xtableFtable",
+       "toLatex.xtable",
+       "autoformat", "xalign", "xdigits", "xdisplay",
+       "sanitize", "sanitize.numbers", "sanitize.final", "as.is", "as.math")
 
 S3method("print", "xtable")
+S3method("print", "xtableMatharray")
+S3method("print", "xtableList")
+S3method("print", "xtableFtable")
 S3method("toLatex", "xtable")
 
 S3method("caption<-", "xtable")
@@ -40,3 +46,17 @@ S3method("xtable", "summary.prcomp")
 S3method("xtable", "coxph")
 S3method("xtable", "ts")
 S3method("xtable", "zoo")
+S3method("xtable", "sarlm")
+S3method("xtable", "summary.sarlm")
+S3method("xtable", "gmsar")
+S3method("xtable", "summary.gmsar")
+S3method("xtable", "stsls")
+S3method("xtable", "summary.stsls")
+S3method("xtable", "sarlm.pred")
+S3method("xtable", "lagImpact")
+S3method("xtable", "splm")
+S3method("xtable", "summary.splm")
+S3method("xtable", "sphet")
+S3method("xtable", "summary.sphet")
+S3method("xtable", "spautolm")
+S3method("xtable", "summary.spautolm")
diff --git a/NEWS b/NEWS
index 30250af..9c2291e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,29 +1,63 @@
+1.8-2 (NOT YET SUBMITTED TO CRAN)
+  * Added function print.xtableMatharray to enable easy creation of
+    LaTeX code to enable an array to be included in a document.
+  * Added example to the gallery using sanitizing headings and row
+    names to produce large bold headings and italic row names.
+  * Added code from Martin Gubri, martin.gubri at framasoft.org, to produce
+    tables from the spatial econometrics packages, spdep, splm, and
+    sphet.
+  * Extracted sanitize functions from print.xtable as stand-alone
+    functions, and exported them. Added helper functions as.is and
+    as.math for assistance with sanitization (supplied by Stefan
+    Edwards <sme at iysik.com> in Feature Request #5303).
+  * Added option to produce math style exponents when sanitizing
+    numbers, as suggested by Don Armstrong <don at donarmstrong.com>, who
+    also provided code
+  * Fixed bug #6907. Warning was created when the data frame as no
+    rows for type is 'html'. Added a test to create the matrix
+    requested specially in that case. Original code was
+    BTD2 <- matrix(align.tmp[(2-pos):(ncol(x)+1)],
+                   nrow = nrow(x), ncol = ncol(x)+pos, byrow = TRUE)
+    which created a matrix with no rows, but gave a warning when
+    there were no rows in the data frame being processed.
+  * Fixed bug #6260. Accepted the change suggested by Claudius
+    Loehnert, which was to replace { and } by \begingroup and
+    \endgroup respectively as the delimiters when size was to changed
+    in a table.
+  * Added functions xtableList and print.xtableList to produce
+    composite tables consisting of a number of subtables.
+  * Added xtableFtable and print.xtableFtable to format flat tables
+    produced by ftable. Included examples in the xtable gallery.
+  * Produced new vignettes: 'The xtableList Gallery' to illustrate
+    xtableList and print.xtableList; and 'The Other Packages Gallery'
+    to illustrate methods for classes of objects from other packages.
 
-1.7-4 (NOT YET RELEASED)
+1.8-0 (2015-11-02)
+  * autoformat, xalign, xdigits, xdisplay from Arni Magnusson, added
+    along with help file. Feature request #5686.
+  * New argument 'auto' in xtable(), to call xalign, xdigits, and
+    xdisplay at the time when xtable is created.
+  * Updated xtableGallery vignette, now with TOC and revised examples.
+
+1.7-4 (2014-09-11)
   * Changed tags in HTML to be all lower case, to be compatible with
-    HTML5, part of feature request(#5879)
+    HTML5, part of feature request. (#5879)
   * Fixed booktabs bug (#2309), more of an enhancement really. Updated
     xtableGallery.snw to illustrate the change.
-  * Moved vignettes from inst/doc to vignettes as now required by CRAN
-  * Changed email address of David Dahl to dahl at stat.byu.edu in 9 places
 
 1.7-3 (2014-03-06)
-  * Released to CRAN
-
-1.7-2 (2013-08-28, Not Released to CRAN)
-  * Fixed HTML gsub bug (#2795)
   * Dealt with format.args bug (#4770). No code changes, but the
     documentation of print.xtable was changed to warn of the problem
-    and to give a workaround as an example
+    and to give a workaround as an example.
 
 1.7-1 (2013-02-24)
-  * Fixed logicals bug (Req #1911)
+  * Fixed logicals bug. (Req #1911)
   * Changed implementation of centering of tables. Instead of
     inserting a centered environment, now a \centering command is
     inserted. (Req #2104)
   * Allow for margin tables as possible with document class
-    tufte-handout. An example of usage is found in the vignette
-	produced by margintable.Rnw which is in inst/doc. (Req #2168)
+    tufte-handout. An example of usage is found in the vignette.
+    produced by margintable.Rnw which is in inst/doc. (Req #2168)
   * Added "timestamp" argument to print.xtable().  Set it to NULL
     if no timestamp is desired. (Req #2246)
   * Added "comment" argument to print.xtable().  Set it to FALSE
@@ -32,7 +66,7 @@
     is placed in a "parbox" of the specified width. (Req #2247)
   * Remove the check on whether the "floating.environment" is in a
     list of known floating environments. Users want to use floating
-    environments from multiple options LaTeX packages (Req #2488,
+    environments from multiple options LaTeX packages. (Req #2488,
     #2578)
 
 1.7-0 (2012-02-10)
@@ -49,7 +83,7 @@
     "print.xtable".
   * Added "booktabs" argument to use the "\toprule", "\midrule", and
     "\bottomrule" tags from the Latex "booktabs" package rather than
-	using "\hline" for all horizontal lines.
+    using "\hline" for all horizontal lines.
   * Added "scalebox" argument to include a "\scalebox" clause around
     the tabular environment with the specified value used as the
     scaling factor.
@@ -59,8 +93,8 @@
     replacement function.
   * Changed the "print.xtable()" arguments to use "getOption()"
     to check the options for a default value.  This was suggested
-	since "print.xtable()" has a lot of arguments that the user
-	will typically leave unchanged between tables.
+    since "print.xtable()" has a lot of arguments that the user
+    will typically leave unchanged between tables.
   * Added an "is.null()" check on the "table.placement" argument.
   * Added examples using the new arguments to the vignette.
 
@@ -79,7 +113,8 @@
   * Use options()$OutDec for decimal mark.
 
 1.5-5 (2009-03-24)
-  * Added html.table.attributes to set the attributed of the <TABLE> tag for HTML tables.
+  * Added html.table.attributes to set the attributed of the <TABLE> tag for
+    HTML tables.
   * Accommodated logicals by converting to characters.
   * Add an extra space at end of each line for LaTeX tables.
   * Fixed typographical error in documentation.
diff --git a/R/autoformat.R b/R/autoformat.R
new file mode 100644
index 0000000..940ecdb
--- /dev/null
+++ b/R/autoformat.R
@@ -0,0 +1,53 @@
+autoformat <- function(xtab, zap = getOption("digits")) {
+  align(xtab) <- xalign(xtab)
+  digits(xtab) <- xdigits(xtab, zap = zap)
+  display(xtab) <- xdisplay(xtab)
+  return(xtab)
+}
+
+xalign <- function(x, pad = TRUE) {
+  lr <- function(v) if(is.numeric(v)) "r" else "l"
+
+  is.2d <- length(dim(x)) == 2
+  alignment <- if(is.2d) sapply(as.data.frame(x), lr) else lr(x)
+  output <- if(is.2d && pad) c("l", alignment) else alignment
+
+  return(output)
+}
+
+xdigits <- function(x, pad = TRUE, zap = getOption("digits")) {
+  dig <- function(v) {
+    if(is.numeric(v)) {
+      v <- na.omit(v)
+      v <- zapsmall(abs(v - floor(v)), zap)
+      dec <- if(any(v > 0)) max(nchar(v) - 2L) else 0L
+    } else {
+      dec <- 0L
+    }
+    return(dec)
+  }
+
+  is.2d <- length(dim(x)) == 2
+  decimals <- if(is.2d) sapply(as.data.frame(x), dig) else dig(x)
+  output <- if(is.2d && pad) c(0L, decimals) else decimals
+
+  return(output)
+}
+
+xdisplay <- function(x, pad = TRUE) {
+  type <- function(v) {
+    if(is.numeric(v)) {
+      tp <- if(xdigits(v) == 0) "d" else "f"
+    } else {
+      tp <- "s"
+    }
+    return(tp)
+  }
+
+  is.2d <- length(dim(x)) == 2
+  disp <- if(is.2d) sapply(as.data.frame(x), type) else type(x)
+  output <- if(is.2d && pad) c("s", disp) else disp
+
+  return(output)
+}
+
diff --git a/R/lagImpactMat.R b/R/lagImpactMat.R
new file mode 100644
index 0000000..1ec881b
--- /dev/null
+++ b/R/lagImpactMat.R
@@ -0,0 +1,44 @@
+### This function is a copy of spdep:::lagImpactMat
+### It has been copied because lagImpactMat is not exported by spdep
+### There is no help available for lagImpactMat in spdep,
+### so I have not provided any help, and I am unable to trace the author
+###
+lagImpactMat <- function (x, reportQ = NULL) 
+{
+  if (is.null(x$res)) {
+    direct <- x$direct
+    indirect <- x$indirect
+    total <- x$total
+  } else {
+    direct <- x$res$direct
+    indirect <- x$res$indirect
+    total <- x$res$total
+  }
+  mat <- cbind(direct, indirect, total)
+  colnames(mat) <- c("Direct", "Indirect", "Total")
+  rownames(mat) <- attr(x, "bnames")
+  if (!is.null(reportQ) && reportQ) {
+    if (is.null(x$res)) {
+      Qobj <- attr(x, "Qres")
+    } else {
+      Qobj <- attr(x$res, "Qres")
+    }
+    if (is.null(Qobj)) {
+      warning("No impact components to report")
+    } else {
+      if (length(attr(x, "bnames")) == 1L) {
+        Qobj$direct <- matrix(Qobj$direct, ncol = 1)
+        Qobj$indirect <- matrix(Qobj$indirect, ncol = 1)
+        Qobj$total <- matrix(Qobj$total, ncol = 1)
+      }
+      colnames(Qobj$direct) <- attr(x, "bnames")
+      colnames(Qobj$indirect) <- attr(x, "bnames")
+      colnames(Qobj$total) <- attr(x, "bnames")
+      rownames(Qobj$direct) <- paste0("Q", 1:nrow(Qobj$direct))
+      rownames(Qobj$indirect) <- paste0("Q", 1:nrow(Qobj$indirect))
+      rownames(Qobj$total) <- paste0("Q", 1:nrow(Qobj$total))
+      attr(mat, "Qobj") <- Qobj
+    }
+  }
+  mat
+}
diff --git a/R/print.xtable.R b/R/print.xtable.R
index 67f48d5..ce9c7bc 100644
--- a/R/print.xtable.R
+++ b/R/print.xtable.R
@@ -45,6 +45,7 @@ print.xtable <- function(x,
   sanitize.colnames.function = getOption("xtable.sanitize.colnames.function",
                                          sanitize.text.function),
   math.style.negative = getOption("xtable.math.style.negative", FALSE),
+  math.style.exponents = getOption("xtable.math.style.exponents", FALSE),
   html.table.attributes = getOption("xtable.html.table.attributes", "border=1"),
   print.results = getOption("xtable.print.results", TRUE),
   format.args = getOption("xtable.format.args", NULL),
@@ -57,648 +58,592 @@ print.xtable <- function(x,
   timestamp = getOption("xtable.timestamp", date()),
   ...)
 {
-    ## If caption is length 2, treat the second value as the "short caption"
-    caption <- attr(x,"caption",exact = TRUE)
-    short.caption <- NULL
-    if (!is.null(caption) && length(caption) > 1){
-        short.caption <- caption[2]
-	caption <- caption[1]
-    }
-
-    ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28 hline.after
-    ## By default it print an \hline before and after the columns names
-    ## independently they are printed or not and at the end of the table
-    ## Old code that set hline.after should include c(-1, 0, nrow(x)) in the
-    ## hline.after vector
-    ## If you do not want any \hline inside the data, set hline.after to NULL
-    ## PHEADER instead the string '\\hline\n' is used in the code
-    ## Now hline.after counts how many time a position appear
-    ## I left an automatic PHEADER in the longtable is this correct?
-
-    ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28 include.rownames,
-    ## include.colnames
-    pos <- 0
-    if (include.rownames) pos <- 1
-
-    ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
-    ## hline.after checks
-    if (any(hline.after < -1) | any(hline.after > nrow(x))) {
-        stop("'hline.after' must be inside [-1, nrow(x)]")
-    }
-
-    ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
-    ## add.to.row checks
-    if (!is.null(add.to.row)) {
-        if (is.list(add.to.row) && length(add.to.row) == 2) {
-            if (is.null(names(add.to.row))) {
-                names(add.to.row) <- c('pos', 'command')
-            } else if (any(sort(names(add.to.row))!= c('command', 'pos'))) {
-                stop("the names of the elements of 'add.to.row' must be 'pos' and 'command'")
-            }
-            if (is.list(add.to.row$pos) && is.vector(add.to.row$command,
-                                                     mode = 'character')) {
-                if ((npos <- length(add.to.row$pos)) !=
-                    length(add.to.row$command)) {
-                    stop("the length of 'add.to.row$pos' must be equal to the length of 'add.to.row$command'")
-                }
-                if (any(unlist(add.to.row$pos) < -1) |
-                    any(unlist(add.to.row$pos) > nrow(x))) {
-                    stop("the values in add.to.row$pos must be inside the interval [-1, nrow(x)]")
-                }
-            } else {
-                stop("the first argument ('pos') of 'add.to.row' must be a list, the second argument ('command') must be a vector of mode character")
-            }
-        } else {
-            stop("'add.to.row' argument must be a list of length 2")
+  ## If caption is length 2, treat the second value as the "short caption"
+  caption <- attr(x,"caption",exact = TRUE)
+  short.caption <- NULL
+  if (!is.null(caption) && length(caption) > 1){
+    short.caption <- caption[2]
+    caption <- caption[1]
+  }
+
+  ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28 hline.after
+  ## By default it print an \hline before and after the columns names
+  ## independently they are printed or not and at the end of the table
+  ## Old code that set hline.after should include c(-1, 0, nrow(x)) in the
+  ## hline.after vector
+  ## If you do not want any \hline inside the data, set hline.after to NULL
+  ## PHEADER instead the string '\\hline\n' is used in the code
+  ## Now hline.after counts how many time a position appear
+  ## I left an automatic PHEADER in the longtable is this correct?
+  
+  ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28 include.rownames,
+  ## include.colnames
+  pos <- 0
+  if (include.rownames) pos <- 1
+  
+  ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
+  ## hline.after checks
+  if (any(hline.after < -1) | any(hline.after > nrow(x))) {
+    stop("'hline.after' must be inside [-1, nrow(x)]")
+  }
+  
+  ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
+  ## add.to.row checks
+  if (!is.null(add.to.row)) {
+    if (is.list(add.to.row) && length(add.to.row) == 2) {
+      if (is.null(names(add.to.row))) {
+        names(add.to.row) <- c('pos', 'command')
+      } else if (any(sort(names(add.to.row))!= c('command', 'pos'))) {
+        stop("the names of the elements of 'add.to.row' must be 'pos' and 'command'")
+      }
+      if (is.list(add.to.row$pos) && is.vector(add.to.row$command,
+                                               mode = 'character')) {
+        if ((npos <- length(add.to.row$pos)) !=
+            length(add.to.row$command)) {
+          stop("the length of 'add.to.row$pos' must be equal to the length of 'add.to.row$command'")
+        }
+        if (any(unlist(add.to.row$pos) < -1) |
+            any(unlist(add.to.row$pos) > nrow(x))) {
+          stop("the values in add.to.row$pos must be inside the interval [-1, nrow(x)]")
         }
+      } else {
+        stop("the first argument ('pos') of 'add.to.row' must be a list, the second argument ('command') must be a vector of mode character")
+      }
     } else {
-        add.to.row <- list(pos = list(),
-                           command = vector(length = 0, mode = "character"))
-        npos <- 0
+      stop("'add.to.row' argument must be a list of length 2")
     }
-
-    ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28 add.to.row
-    ## Add further commands at the end of rows
-    if (type == "latex") {
-        ## Original code before changes in version 1.6-1
-        ## PHEADER <- "\\hline\n"
-
-        ## booktabs code from Matthieu Stigler <matthieu.stigler at gmail.com>,
-        ## 1 Feb 2012
-        if(!booktabs){
-            PHEADER <- "\\hline\n"
-        } else {
-            ## This code replaced to fix bug #2309, David Scott, 8 Jan 2014
-            ## PHEADER <- ifelse(-1%in%hline.after, "\\toprule\n", "")
-            ## if(0%in%hline.after) {
-            ##     PHEADER <- c(PHEADER, "\\midrule\n")
-            ## }
-            ## if(nrow(x)%in%hline.after) {
-            ##     PHEADER <- c(PHEADER, "\\bottomrule\n")
-            ## }
-            if (is.null(hline.after)){
-                PHEADER <- ""
-            } else {
-                hline.after <- sort(hline.after)
-                PHEADER <- rep("\\midrule\n", length(hline.after))
-                if (hline.after[1] == -1) {
-                    PHEADER[1] <- "\\toprule\n"
-                }
-                if (hline.after[length(hline.after)] == nrow(x)) {
-                    PHEADER[length(hline.after)] <- "\\bottomrule\n"
-                }
-            }
-        }
+  } else {
+    add.to.row <- list(pos = list(),
+                       command = vector(length = 0, mode = "character"))
+    npos <- 0
+  }
+  
+  ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28 add.to.row
+  ## Add further commands at the end of rows
+  if (type == "latex") {
+    ## Original code before changes in version 1.6-1
+    ## PHEADER <- "\\hline\n"
+    
+    ## booktabs code from Matthieu Stigler <matthieu.stigler at gmail.com>,
+    ## 1 Feb 2012
+    if(!booktabs){
+      PHEADER <- "\\hline\n"
     } else {
+      ## This code replaced to fix bug #2309, David Scott, 8 Jan 2014
+      ## PHEADER <- ifelse(-1%in%hline.after, "\\toprule\n", "")
+      ## if(0%in%hline.after) {
+      ##     PHEADER <- c(PHEADER, "\\midrule\n")
+      ## }
+      ## if(nrow(x)%in%hline.after) {
+      ##     PHEADER <- c(PHEADER, "\\bottomrule\n")
+      ## }
+      if (is.null(hline.after)){
         PHEADER <- ""
-    }
-
-        lastcol <- rep(" ", nrow(x)+2)
-    if (!is.null(hline.after)) {
-        ## booktabs change - Matthieu Stigler: fill the hline arguments
-        ## separately, 1 Feb 2012
-        ##
-        ## Code before booktabs change was:
-        ##    add.to.row$pos[[npos+1]] <- hline.after
-
-        if (!booktabs){
-            add.to.row$pos[[npos+1]] <- hline.after
-	    } else {
-            for(i in 1:length(hline.after)) {
-                add.to.row$pos[[npos+i]] <- hline.after[i]
-            }
+      } else {
+        hline.after <- sort(hline.after)
+        PHEADER <- rep("\\midrule\n", length(hline.after))
+        if (hline.after[1] == -1) {
+          PHEADER[1] <- "\\toprule\n"
         }
-        add.to.row$command <- c(add.to.row$command, PHEADER)
-    }
-
-    if ( length(add.to.row$command) > 0 ) {
-        for (i in 1:length(add.to.row$command)) {
-            addpos <- add.to.row$pos[[i]]
-            freq <- table(addpos)
-            addpos <- unique(addpos)
-            for (j in 1:length(addpos)) {
-                lastcol[addpos[j]+2] <- paste(lastcol[addpos[j]+2],
-                                              paste(rep(add.to.row$command[i],
-                                                        freq[j]),
-                                                sep = "", collapse = ""),
-                                              sep = " ")
-            }
+        if (hline.after[length(hline.after)] == nrow(x)) {
+          PHEADER[length(hline.after)] <- "\\bottomrule\n"
         }
+      }
     }
-
-    if (length(type)>1) stop("\"type\" must have length 1")
-    type <- tolower(type)
-    if (!all(!is.na(match(type, c("latex","html"))))) {
-        stop("\"type\" must be in {\"latex\", \"html\"}")
-    }
-    ## Disabling the check on known floating environments as many users
-    ## want to use additional environments.
-    #    if (!all(!is.na(match(floating.environment,
-    #                          c("table","table*","sidewaystable",
-    #                            "margintable"))))) {
-    #        stop("\"type\" must be in {\"table\", \"table*\", \"sidewaystable\", \"margintable\"}")
-    #    }
-    if (("margintable" %in% floating.environment)
-        & (!is.null(table.placement))) {
-        warning("margintable does not allow for table placement; setting table.placement to NULL")
-        table.placement <- NULL
+  } else {
+    PHEADER <- ""
+  }
+  
+  lastcol <- rep(" ", nrow(x)+2)
+  if (!is.null(hline.after)) {
+    ## booktabs change - Matthieu Stigler: fill the hline arguments
+    ## separately, 1 Feb 2012
+    ##
+    ## Code before booktabs change was:
+    ##    add.to.row$pos[[npos+1]] <- hline.after
+    
+    if (!booktabs){
+      add.to.row$pos[[npos+1]] <- hline.after
+    } else {
+      for(i in 1:length(hline.after)) {
+        add.to.row$pos[[npos+i]] <- hline.after[i]
+      }
     }
-    if (!is.null(table.placement) &&
-        !all(!is.na(match(unlist(strsplit(table.placement,  split = "")),
-                          c("H","h","t","b","p","!"))))) {
-        stop("\"table.placement\" must contain only elements of {\"h\",\"t\",\"b\",\"p\",\"!\"}")
+    add.to.row$command <- c(add.to.row$command, PHEADER)
+  }
+  
+  if ( length(add.to.row$command) > 0 ) {
+    for (i in 1:length(add.to.row$command)) {
+      addpos <- add.to.row$pos[[i]]
+      freq <- table(addpos)
+      addpos <- unique(addpos)
+      for (j in 1:length(addpos)) {
+        lastcol[addpos[j]+2] <- paste(lastcol[addpos[j]+2],
+                                      paste(rep(add.to.row$command[i],
+                                                freq[j]),
+                                            sep = "", collapse = ""),
+                                      sep = " ")
+      }
     }
-    if (!all(!is.na(match(caption.placement, c("bottom","top"))))) {
-        stop("\"caption.placement\" must be either {\"bottom\",\"top\"}")
+  }
+  
+  if (length(type)>1) stop("\"type\" must have length 1")
+  type <- tolower(type)
+  if (!all(!is.na(match(type, c("latex","html"))))) {
+    stop("\"type\" must be in {\"latex\", \"html\"}")
+  }
+  ## Disabling the check on known floating environments as many users
+  ## want to use additional environments.
+  ##    if (!all(!is.na(match(floating.environment,
+  ##                          c("table","table*","sidewaystable",
+  ##                            "margintable"))))) {
+  ##        stop("\"type\" must be in {\"table\", \"table*\", \"sidewaystable\", \"margintable\"}")
+  ##    }
+  if (("margintable" %in% floating.environment)
+      & (!is.null(table.placement))) {
+    warning("margintable does not allow for table placement; setting table.placement to NULL")
+    table.placement <- NULL
+  }
+  if (!is.null(table.placement) &&
+      !all(!is.na(match(unlist(strsplit(table.placement,  split = "")),
+                        c("H","h","t","b","p","!"))))) {
+    stop("\"table.placement\" must contain only elements of {\"h\",\"t\",\"b\",\"p\",\"!\"}")
+  }
+  if (!all(!is.na(match(caption.placement, c("bottom","top"))))) {
+    stop("\"caption.placement\" must be either {\"bottom\",\"top\"}")
+  }
+  
+  if (type == "latex") {
+    BCOMMENT <- "% "
+    ECOMMENT <- "\n"
+    ## See e-mail from "John S. Walker <jsw9c at uic.edu>" dated 5-19-2003
+    ## regarding "texfloat"
+    ## See e-mail form "Fernando Henrique Ferraz P. da Rosa"
+    ## <academic at feferraz.net>" dated 10-28-2005 regarding "longtable"
+    if ( tabular.environment == "longtable" & floating == TRUE ) {
+      warning("Attempt to use \"longtable\" with floating = TRUE. Changing to FALSE.")
+      floating <- FALSE
     }
-
-    if (type == "latex") {
-        BCOMMENT <- "% "
-        ECOMMENT <- "\n"
-        ## See e-mail from "John S. Walker <jsw9c at uic.edu>" dated 5-19-2003
-        ## regarding "texfloat"
-        ## See e-mail form "Fernando Henrique Ferraz P. da Rosa"
-        ## <academic at feferraz.net>" dated 10-28-2005 regarding "longtable"
-        if ( tabular.environment == "longtable" & floating == TRUE ) {
-            warning("Attempt to use \"longtable\" with floating = TRUE. Changing to FALSE.")
-            floating <- FALSE
-        }
-        if ( floating == TRUE ) {
-            ## See e-mail from "Pfaff, Bernhard <Bernhard.Pfaff at drkw.com>"
-            ## dated 7-09-2003 regarding "suggestion for an amendment of
-            ## the source"
-            ## See e-mail from "Mitchell, David"
-            ## <David.Mitchell at dotars.gov.au>" dated 2003-07-09 regarding
-            ## "Additions to R xtable package"
-            ## See e-mail from "Garbade, Sven"
-            ## <Sven.Garbade at med.uni-heidelberg.de> dated 2006-05-22
-            ## regarding the floating environment.
-            BTABLE <- paste("\\begin{", floating.environment, "}",
-                            ifelse(!is.null(table.placement),
-                                   paste("[", table.placement, "]", sep = ""),
-                                   ""), "\n", sep = "")
-            if ( is.null(latex.environments) ||
-                (length(latex.environments) == 0) ) {
-                BENVIRONMENT <- ""
-                EENVIRONMENT <- ""
-            } else {
-                BENVIRONMENT <- ""
-                EENVIRONMENT <- ""
-                if ("center" %in% latex.environments){
-                    BENVIRONMENT <- paste(BENVIRONMENT, "\\centering\n",
-                                          sep = "")
-                }
-                for (i in 1:length(latex.environments)) {
-                    if (latex.environments[i] == "") next
-                    if (latex.environments[i] != "center"){
-                        BENVIRONMENT <- paste(BENVIRONMENT,
-                                              "\\begin{", latex.environments[i],
-                                              "}\n", sep = "")
-                        EENVIRONMENT <- paste("\\end{", latex.environments[i],
-                                              "}\n", EENVIRONMENT, sep = "")
-                    }
-                }
-            }
-            ETABLE <- paste("\\end{", floating.environment, "}\n", sep = "")
-        } else {
-            BTABLE <- ""
-            ETABLE <- ""
-            BENVIRONMENT <- ""
-            EENVIRONMENT <- ""
-        }
-
-        tmp.index.start <- 1
-        if ( ! include.rownames ) {
-            while ( attr(x, "align", exact = TRUE)[tmp.index.start] == '|' )
-                tmp.index.start <- tmp.index.start + 1
-            tmp.index.start <- tmp.index.start + 1
-        }
-        ## Added "width" argument for use with "tabular*" or
-        ## "tabularx" environments - CR, 7/2/12
-        if (is.null(width)){
-            WIDTH <-""
-        } else if (is.element(tabular.environment,
-                              c("tabular", "longtable"))){
-            warning("Ignoring 'width' argument.  The 'tabular' and 'longtable' environments do not support a width specification.  Use another environment such as 'tabular*' or 'tabularx' to specify the width.")
-            WIDTH <- ""
-        } else {
-            WIDTH <- paste("{", width, "}", sep = "")
-        }
-
-        BTABULAR <-
-            paste("\\begin{", tabular.environment, "}",
-                  WIDTH, "{",
-                  paste(c(attr(x, "align",
-                               exact = TRUE)[
-                               tmp.index.start:length(attr(x, "align",
-                                                           exact = TRUE))],
-                          "}\n"),
-                        sep = "", collapse = ""),
-                  sep = "")
-
-        ## fix 10-26-09 (robert.castelo at upf.edu) the following
-        ## 'if' condition is added here to support
-        ## a caption on the top of a longtable
-        if (tabular.environment == "longtable" && caption.placement == "top") {
-            if (is.null(short.caption)){
-                BCAPTION <- "\\caption{"
-            } else {
-                BCAPTION <- paste("\\caption[", short.caption, "]{", sep = "")
-            }
-            ECAPTION <- "} \\\\ \n"
-            if ((!is.null(caption)) && (type == "latex")) {
-                BTABULAR <- paste(BTABULAR,  BCAPTION, caption, ECAPTION,
-                                  sep = "")
-            }
-        }
-        ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
-        ## add.to.row position -1
-        BTABULAR <- paste(BTABULAR, lastcol[1], sep = "")
-        ## the \hline at the end, if present, is set in full matrix
-        ETABULAR <- paste("\\end{", tabular.environment, "}\n", sep = "")
-
-        ## Add scalebox - CR, 7/2/12
-        if (!is.null(scalebox)){
-            BTABULAR <- paste("\\scalebox{", scalebox, "}{\n", BTABULAR,
-                              sep = "")
-            ETABULAR <- paste(ETABULAR, "}\n", sep = "")
-        }
-
-        ## BSIZE contributed by Benno <puetz at mpipsykl.mpg.de> in e-mail
-        ## dated Wednesday, December 01, 2004
-        if (is.null(size) || !is.character(size)) {
-            BSIZE <- ""
-            ESIZE <- ""
-        } else {
-            if(length(grep("^\\\\", size)) == 0){
-                size <- paste("\\", size, sep = "")
-            }
-            BSIZE <- paste("{", size, "\n", sep = "")
-            ESIZE <- "}\n"
-        }
-        BLABEL <- "\\label{"
-        ELABEL <- "}\n"
-        ## Added caption width (jeff.laake at nooa.gov)
-	    if(!is.null(caption.width)){
-	        BCAPTION <- paste("\\parbox{",caption.width,"}{",sep="")
-	        ECAPTION <- "}"
-	    } else {
-	        BCAPTION <- NULL
-	        ECAPTION <- NULL
-	    }
-	    if (is.null(short.caption)){
-		   BCAPTION <- paste(BCAPTION,"\\caption{",sep="")
-	    } else {
-		   BCAPTION <- paste(BCAPTION,"\\caption[", short.caption, "]{", sep="")
-	    }
-        ECAPTION <- paste(ECAPTION,"} \n",sep="")
-        BROW <- ""
-        EROW <- " \\\\ \n"
-        BTH <- ""
-        ETH <- ""
-        STH <- " & "
-        BTD1 <- " & "
-        BTD2 <- ""
-        BTD3 <- ""
-        ETD  <- ""
-        ## Based on contribution from Jonathan Swinton
-        ## <jonathan at swintons.net> in e-mail dated Wednesday, January 17, 2007
-        sanitize <- function(str) {
-            result <- str
-            result <- gsub("\\\\", "SANITIZE.BACKSLASH", result)
-            result <- gsub("$", "\\$", result, fixed = TRUE)
-            result <- gsub(">", "$>$", result, fixed = TRUE)
-            result <- gsub("<", "$<$", result, fixed = TRUE)
-            result <- gsub("|", "$|$", result, fixed = TRUE)
-            result <- gsub("{", "\\{", result, fixed = TRUE)
-            result <- gsub("}", "\\}", result, fixed = TRUE)
-            result <- gsub("%", "\\%", result, fixed = TRUE)
-            result <- gsub("&", "\\&", result, fixed = TRUE)
-            result <- gsub("_", "\\_", result, fixed = TRUE)
-            result <- gsub("#", "\\#", result, fixed = TRUE)
-            result <- gsub("^", "\\verb|^|", result, fixed = TRUE)
-            result <- gsub("~", "\\~{}", result, fixed = TRUE)
-            result <- gsub("SANITIZE.BACKSLASH", "$\\backslash$",
-                           result, fixed = TRUE)
-            return(result)
-        }
-        sanitize.numbers <- function(x) {
-            result <- x
-            if ( math.style.negative ) {
-                ## Jake Bowers <jwbowers at illinois.edu> in e-mail
-                ## from 2008-08-20 suggested disabling this feature to avoid
-                ## problems with LaTeX's dcolumn package.
-                ## by Florian Wickelmaier <florian.wickelmaier at uni-tuebingen.de>
-                ## in e-mail from 2008-10-03 requested the ability to use the
-                ## old behavior.
-                for(i in 1:length(x)) {
-                    result[i] <- gsub("-", "$-$", result[i], fixed = TRUE)
-                }
-            }
-            return(result)
-        }
-        sanitize.final <- function(result) {
-            return(result)
-        }
-    } else {
-        BCOMMENT <- "<!-- "
-        ECOMMENT <- " -->\n"
-        BTABLE <- paste("<table ", html.table.attributes, ">\n", sep = "")
-        ETABLE <- "</table>\n"
+    if ( floating == TRUE ) {
+      ## See e-mail from "Pfaff, Bernhard <Bernhard.Pfaff at drkw.com>"
+      ## dated 7-09-2003 regarding "suggestion for an amendment of
+      ## the source"
+      ## See e-mail from "Mitchell, David"
+      ## <David.Mitchell at dotars.gov.au>" dated 2003-07-09 regarding
+      ## "Additions to R xtable package"
+      ## See e-mail from "Garbade, Sven"
+      ## <Sven.Garbade at med.uni-heidelberg.de> dated 2006-05-22
+      ## regarding the floating environment.
+      BTABLE <- paste("\\begin{", floating.environment, "}",
+                      ifelse(!is.null(table.placement),
+                             paste("[", table.placement, "]", sep = ""),
+                             ""), "\n", sep = "")
+      if ( is.null(latex.environments) ||
+           (length(latex.environments) == 0) ) {
         BENVIRONMENT <- ""
         EENVIRONMENT <- ""
-        BTABULAR <- ""
-        ETABULAR <- ""
-        BSIZE <- ""
-        ESIZE <- ""
-        BLABEL <- "<a name="
-        ELABEL <- "></a>\n"
-        BCAPTION <- paste("<caption align=\"", caption.placement, "\"> ",
-                          sep = "")
-        ECAPTION <- " </caption>\n"
-        BROW <- "<tr>"
-        EROW <- " </tr>\n"
-        BTH <- " <th> "
-        ETH <- " </th> "
-        STH <- " </th> <th> "
-        BTD1 <- " <td align=\""
-        align.tmp <- attr(x, "align", exact = TRUE)
-        align.tmp <- align.tmp[align.tmp!="|"]
-        BTD2 <- matrix(align.tmp[(2-pos):(ncol(x)+1)],
-                       nrow = nrow(x), ncol = ncol(x)+pos, byrow = TRUE)
-        ## Based on contribution from Jonathan Swinton <jonathan at swintons.net>
-        ## in e-mail dated Wednesday, January 17, 2007
-        BTD2[regexpr("^p", BTD2)>0] <- "left"
-        BTD2[BTD2 == "r"] <- "right"
-        BTD2[BTD2 == "l"] <- "left"
-        BTD2[BTD2 == "c"] <- "center"
-        BTD3 <- "\"> "
-        ETD  <- " </td>"
-        sanitize <- function(str) {
-            result <- str
-            ## Changed as suggested in bug report #2795
-            ## That is replacement of "&" is "&"
-            ## instead of previous "&amp" etc
-            ## result <- gsub("&", "&amp ", result, fixed = TRUE)
-            ## result <- gsub(">", "&gt ", result, fixed = TRUE)
-            ## result <- gsub("<", "&lt ", result, fixed = TRUE)
-            result <- gsub("&", "&", result, fixed = TRUE)
-            result <- gsub(">", ">", result, fixed = TRUE)
-            result <- gsub("<", "<", result, fixed = TRUE)
-            ## Kurt Hornik <Kurt.Hornik at wu-wien.ac.at> on 2006/10/05
-            ## recommended not escaping underscores.
-            ## result <- gsub("_", "\\_", result, fixed=TRUE)
-            return(result)
-        }
-        sanitize.numbers <- function(x) {
-            return(x)
+      } else {
+        BENVIRONMENT <- ""
+        EENVIRONMENT <- ""
+        if ("center" %in% latex.environments){
+          BENVIRONMENT <- paste(BENVIRONMENT, "\\centering\n",
+                                sep = "")
         }
-        sanitize.final <- function(result) {
-            ## Suggested by Uwe Ligges <ligges at statistik.uni-dortmund.de>
-            ## in e-mail dated 2005-07-30.
-            result$text <- gsub("  *", " ",  result$text, fixed = TRUE)
-            result$text <- gsub(' align="left"',  "", result$text,
-                                fixed = TRUE)
-            return(result)
+        for (i in 1:length(latex.environments)) {
+          if (latex.environments[i] == "") next
+          if (latex.environments[i] != "center"){
+            BENVIRONMENT <- paste(BENVIRONMENT,
+                                  "\\begin{", latex.environments[i],
+                                  "}\n", sep = "")
+            EENVIRONMENT <- paste("\\end{", latex.environments[i],
+                                  "}\n", EENVIRONMENT, sep = "")
+          }
         }
+      }
+      ETABLE <- paste("\\end{", floating.environment, "}\n", sep = "")
+    } else {
+      BTABLE <- ""
+      ETABLE <- ""
+      BENVIRONMENT <- ""
+      EENVIRONMENT <- ""
     }
-
-    result <- string("", file = file, append = append)
-    info <- R.Version()
-    ## modified Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
-    ## to set automatically the package version
-	if (comment){
-        result <- result + BCOMMENT + type + " table generated in " +
-              info$language + " " + info$major + "." + info$minor +
-              " by xtable " +  packageDescription('xtable')$Version +
-              " package" + ECOMMENT
-        if (!is.null(timestamp)){
-            result <- result + BCOMMENT + timestamp + ECOMMENT
-        }
+    
+    tmp.index.start <- 1
+    if ( ! include.rownames ) {
+      while ( attr(x, "align", exact = TRUE)[tmp.index.start] == '|' )
+        tmp.index.start <- tmp.index.start + 1
+      tmp.index.start <- tmp.index.start + 1
     }
-    ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28 only.contents
-    if (!only.contents) {
-        result <- result + BTABLE
-        result <- result + BENVIRONMENT
-        if ( floating == TRUE ) {
-            if ((!is.null(caption)) &&
-                (type == "html" ||caption.placement == "top")) {
-                result <- result + BCAPTION + caption + ECAPTION
-            }
-            if (!is.null(attr(x, "label", exact = TRUE)) &&
-                (type == "latex" && caption.placement == "top")) {
-                result <- result + BLABEL +
-                          attr(x, "label", exact = TRUE) + ELABEL
-            }
-        }
-        result <- result + BSIZE
-        result <- result + BTABULAR
+    ## Added "width" argument for use with "tabular*" or
+    ## "tabularx" environments - CR, 7/2/12
+    if (is.null(width)){
+      WIDTH <-""
+    } else if (is.element(tabular.environment,
+                          c("tabular", "longtable"))){
+      warning("Ignoring 'width' argument.  The 'tabular' and 'longtable' environments do not support a width specification.  Use another environment such as 'tabular*' or 'tabularx' to specify the width.")
+      WIDTH <- ""
+    } else {
+      WIDTH <- paste("{", width, "}", sep = "")
+    }
+    
+    BTABULAR <-
+      paste("\\begin{", tabular.environment, "}",
+            WIDTH, "{",
+            paste(c(attr(x, "align",
+                         exact = TRUE)[
+              tmp.index.start:length(attr(x, "align",
+                                          exact = TRUE))],
+              "}\n"),
+              sep = "", collapse = ""),
+            sep = "")
+    
+    ## fix 10-26-09 (robert.castelo at upf.edu) the following
+    ## 'if' condition is added here to support
+    ## a caption on the top of a longtable
+    if (tabular.environment == "longtable" && caption.placement == "top") {
+      if (is.null(short.caption)){
+        BCAPTION <- "\\caption{"
+      } else {
+        BCAPTION <- paste("\\caption[", short.caption, "]{", sep = "")
+      }
+      ECAPTION <- "} \\\\ \n"
+      if ((!is.null(caption)) && (type == "latex")) {
+        BTABULAR <- paste(BTABULAR,  BCAPTION, caption, ECAPTION,
+                          sep = "")
+      }
     }
     ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
-    ## include.colnames, include.rownames
-    if (include.colnames) {
-        result <- result + BROW + BTH
-        if (include.rownames) {
-            result <- result + STH
-	}
-        ## David G. Whiting in e-mail 2007-10-09
-        if (is.null(sanitize.colnames.function)) {
-            CNAMES <- sanitize(names(x))
-	} else {
-            CNAMES <- sanitize.colnames.function(names(x))
-	}
-        if (rotate.colnames) {
-            ##added by Markus Loecher, 2009-11-16
-            CNAMES <- paste("\\begin{sideways}", CNAMES, "\\end{sideways}")
-	}
-        result <- result + paste(CNAMES, collapse = STH)
-
-        result <- result + ETH + EROW
+    ## add.to.row position -1
+    BTABULAR <- paste(BTABULAR, lastcol[1], sep = "")
+    ## the \hline at the end, if present, is set in full matrix
+    ETABULAR <- paste("\\end{", tabular.environment, "}\n", sep = "")
+    
+    ## Add scalebox - CR, 7/2/12
+    if (!is.null(scalebox)){
+      BTABULAR <- paste("\\scalebox{", scalebox, "}{\n", BTABULAR,
+                        sep = "")
+      ETABULAR <- paste(ETABULAR, "}\n", sep = "")
     }
-
-    cols <- matrix("", nrow = nrow(x), ncol = ncol(x)+pos)
+    
+    ## BSIZE contributed by Benno <puetz at mpipsykl.mpg.de> in e-mail
+    ## dated Wednesday, December 01, 2004
+    if (is.null(size) || !is.character(size)) {
+      BSIZE <- ""
+      ESIZE <- ""
+    } else {
+      if(length(grep("^\\\\", size)) == 0){
+        size <- paste("\\", size, sep = "")
+      }
+      ## Change suggested by Claudius Loehnert reported in Bug #6260
+      ## BSIZE <- paste("{", size, "\n", sep = "")
+      ## ESIZE <- "{\n"
+      BSIZE <- paste("\\begingroup", size, "\n", sep = "")
+      ESIZE <- "\\endgroup\n"
+    }
+    BLABEL <- "\\label{"
+    ELABEL <- "}\n"
+    ## Added caption width (jeff.laake at nooa.gov)
+    if(!is.null(caption.width)){
+      BCAPTION <- paste("\\parbox{",caption.width,"}{",sep="")
+      ECAPTION <- "}"
+    } else {
+      BCAPTION <- NULL
+      ECAPTION <- NULL
+    }
+    if (is.null(short.caption)){
+      BCAPTION <- paste(BCAPTION,"\\caption{",sep="")
+    } else {
+      BCAPTION <- paste(BCAPTION,"\\caption[", short.caption, "]{", sep="")
+    }
+    ECAPTION <- paste(ECAPTION,"} \n",sep="")
+    BROW <- ""
+    EROW <- " \\\\ \n"
+    BTH <- ""
+    ETH <- ""
+    STH <- " & "
+    BTD1 <- " & "
+    BTD2 <- ""
+    BTD3 <- ""
+    ETD  <- ""
+    } else {
+      BCOMMENT <- "<!-- "
+      ECOMMENT <- " -->\n"
+      BTABLE <- paste("<table ", html.table.attributes, ">\n", sep = "")
+      ETABLE <- "</table>\n"
+      BENVIRONMENT <- ""
+      EENVIRONMENT <- ""
+      BTABULAR <- ""
+      ETABULAR <- ""
+      BSIZE <- ""
+      ESIZE <- ""
+      BLABEL <- "<a name="
+      ELABEL <- "></a>\n"
+      BCAPTION <- paste("<caption align=\"", caption.placement, "\"> ",
+                        sep = "")
+      ECAPTION <- " </caption>\n"
+      BROW <- "<tr>"
+      EROW <- " </tr>\n"
+      BTH <- " <th> "
+      ETH <- " </th> "
+      STH <- " </th> <th> "
+      BTD1 <- " <td align=\""
+      align.tmp <- attr(x, "align", exact = TRUE)
+      align.tmp <- align.tmp[align.tmp!="|"]
+      if (nrow(x) == 0) {
+        BTD2 <- matrix(nrow = 0, ncol = ncol(x)+pos)
+      } else {
+        BTD2 <- matrix(align.tmp[(2-pos):(ncol(x)+1)],
+                       nrow = nrow(x), ncol = ncol(x)+pos, byrow = TRUE)
+      }
+      ## Based on contribution from Jonathan Swinton <jonathan at swintons.net>
+      ## in e-mail dated Wednesday, January 17, 2007
+      BTD2[regexpr("^p", BTD2)>0] <- "left"
+      BTD2[BTD2 == "r"] <- "right"
+      BTD2[BTD2 == "l"] <- "left"
+      BTD2[BTD2 == "c"] <- "center"
+      BTD3 <- "\"> "
+      ETD  <- " </td>"
+    }
+  
+  result <- string("", file = file, append = append)
+  info <- R.Version()
+  ## modified Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
+  ## to set automatically the package version
+  if (comment){
+    result <- result + BCOMMENT + type + " table generated in " +
+      info$language + " " + info$major + "." + info$minor +
+      " by xtable " +  packageDescription('xtable')$Version +
+                                                  " package" + ECOMMENT
+    if (!is.null(timestamp)){
+      result <- result + BCOMMENT + timestamp + ECOMMENT
+    }
+  }
+  ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28 only.contents
+  if (!only.contents) {
+    result <- result + BTABLE
+    result <- result + BENVIRONMENT
+    if ( floating == TRUE ) {
+      if ((!is.null(caption)) &&
+          (type == "html" ||caption.placement == "top")) {
+        result <- result + BCAPTION + caption + ECAPTION
+      }
+      if (!is.null(attr(x, "label", exact = TRUE)) &&
+          (type == "latex" && caption.placement == "top")) {
+        result <- result + BLABEL +
+          attr(x, "label", exact = TRUE) + ELABEL
+      }
+    }
+    result <- result + BSIZE
+    result <- result + BTABULAR
+  }
+  ## Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
+  ## include.colnames, include.rownames
+  if (include.colnames) {
+    result <- result + BROW + BTH
     if (include.rownames) {
-        ## David G. Whiting in e-mail 2007-10-09
-        if (is.null(sanitize.rownames.function)) {
-            RNAMES <- sanitize(row.names(x))
-        } else {
-            RNAMES <- sanitize.rownames.function(row.names(x))
-        }
-        if (rotate.rownames) {
-            ##added by Markus Loecher, 2009-11-16
-            RNAMES <- paste("\\begin{sideways}", RNAMES, "\\end{sideways}")
-	}
-	cols[, 1] <- RNAMES
+      result <- result + STH
     }
-
-## Begin vectorizing the formatting code by Ian Fellows [ian at fellstat.com]
-## 06 Dec 2011
-##
-##  disp <- function(y) {
-##    if (is.factor(y)) {
-##      y <- levels(y)[y]
-##    }
-##    if (is.list(y)) {
-##      y <- unlist(y)
-##    }
-##    return(y)
-##  }
-    varying.digits <- is.matrix( attr( x, "digits", exact = TRUE ) )
-    ## Code for letting "digits" be a matrix was provided by
-    ## Arne Henningsen <ahenningsen at agric-econ.uni-kiel.de>
-    ## in e-mail dated 2005-06-04.
-    ##if( !varying.digits ) {
-    ## modified Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
-    ##  attr(x,"digits") <- matrix( attr( x, "digits",exact=TRUE ),
-    ## nrow = nrow(x), ncol = ncol(x)+1, byrow = TRUE )
-    ##}
-    for(i in 1:ncol(x)) {
- 	xcol <- x[, i]
-	if(is.factor(xcol))
-            xcol <- as.character(xcol)
-	if(is.list(xcol))
-            xcol <- sapply(xcol, unlist)
-        ina <- is.na(xcol)
-        is.numeric.column <- is.numeric(xcol)
-
-	if(is.character(xcol)) {
-            cols[, i+pos] <- xcol
-	} else {
-            if (is.null(format.args)){
-                format.args <- list()
-            }
-            if (is.null(format.args$decimal.mark)){
-                format.args$decimal.mark <- options()$OutDec
-            }
-            if(!varying.digits){
-		curFormatArgs <-
-                    c(list(
-                      x = xcol,
-                      format =
-                      ifelse(attr(x, "digits", exact = TRUE )[i+1] < 0, "E",
-                                   attr(x, "display", exact = TRUE )[i+1]),
-                      digits = abs(attr(x, "digits", exact = TRUE )[i+1])),
-                      format.args)
-                cols[, i+pos] <- do.call("formatC", curFormatArgs)
-            }else{
-		for( j in 1:nrow( cols ) ) {
-                    curFormatArgs <-
-                        c(list(
-                          x = xcol[j],
-                          format =
-                          ifelse(attr(x, "digits", exact = TRUE )[j, i+1] < 0,
-                                 "E", attr(x, "display", exact = TRUE )[i+1]),
-                          digits =
-                          abs(attr(x, "digits", exact = TRUE )[j, i+1])),
-                          format.args)
-                    cols[j, i+pos] <- do.call("formatC", curFormatArgs)
-		}
-            }
-	}
-	## End Ian Fellows changes
-
-        if ( any(ina) ) cols[ina, i+pos] <- NA.string
-        ## Based on contribution from Jonathan Swinton <jonathan at swintons.net>
-        ## in e-mail dated Wednesday, January 17, 2007
-        if ( is.numeric.column ) {
-            cols[, i+pos] <- sanitize.numbers(cols[, i+pos])
-        } else {
-            if (is.null(sanitize.text.function)) {
-                cols[, i+pos] <- sanitize(cols[, i+pos])
-            } else {
-                cols[, i+pos] <- sanitize.text.function(cols[, i+pos])
-            }
-        }
+    ## David G. Whiting in e-mail 2007-10-09
+    if (is.null(sanitize.colnames.function)) {
+      CNAMES <- sanitize(names(x), type = type)
+    } else {
+      CNAMES <- sanitize.colnames.function(names(x))
     }
-
-    multiplier <- 5
-    full <- matrix("", nrow = nrow(x), ncol = multiplier*(ncol(x)+pos)+2)
-    full[, 1] <- BROW
-    full[, multiplier*(0:(ncol(x)+pos-1))+2] <- BTD1
-    full[, multiplier*(0:(ncol(x)+pos-1))+3] <- BTD2
-    full[, multiplier*(0:(ncol(x)+pos-1))+4] <- BTD3
-    full[, multiplier*(0:(ncol(x)+pos-1))+5] <- cols
-    full[, multiplier*(0:(ncol(x)+pos-1))+6] <- ETD
-
-    full[, multiplier*(ncol(x)+pos)+2] <- paste(EROW, lastcol[-(1:2)],
-                                                sep = " ")
-
-    if (type == "latex") full[, 2] <- ""
-    result <- result + lastcol[2] + paste(t(full), collapse = "")
-    if (!only.contents) {
-        if (tabular.environment == "longtable") {
-            ## booktabs change added the if() - 1 Feb 2012
-            if(!booktabs) {
-                result <- result + PHEADER
-            }
-
-            ## fix 10-27-09 Liviu Andronic (landronimirc at gmail.com) the
-            ## following 'if' condition is inserted in order to avoid
-            ## that bottom caption interferes with a top caption of a longtable
-            if(caption.placement == "bottom"){
-                if ((!is.null(caption)) && (type == "latex")) {
-                    result <- result + BCAPTION + caption + ECAPTION
-                }
-            }
-            if (!is.null(attr(x, "label", exact = TRUE))) {
-                result <- result + BLABEL + attr(x, "label", exact = TRUE) +
-                    ELABEL
-            }
-            ETABULAR <- "\\end{longtable}\n"
+    if (rotate.colnames) {
+      ##added by Markus Loecher, 2009-11-16
+      CNAMES <- paste("\\begin{sideways}", CNAMES, "\\end{sideways}")
+    }
+    result <- result + paste(CNAMES, collapse = STH)
+    
+    result <- result + ETH + EROW
+  }
+  
+  cols <- matrix("", nrow = nrow(x), ncol = ncol(x)+pos)
+  if (include.rownames) {
+    ## David G. Whiting in e-mail 2007-10-09
+    if (is.null(sanitize.rownames.function)) {
+      RNAMES <- sanitize(row.names(x), type = type)
+    } else {
+      RNAMES <- sanitize.rownames.function(row.names(x))
+    }
+    if (rotate.rownames) {
+      ##added by Markus Loecher, 2009-11-16
+      RNAMES <- paste("\\begin{sideways}", RNAMES, "\\end{sideways}")
+    }
+    cols[, 1] <- RNAMES
+  }
+
+  ## Begin vectorizing the formatting code by Ian Fellows [ian at fellstat.com]
+  ## 06 Dec 2011
+  ##
+  ##  disp <- function(y) {
+  ##    if (is.factor(y)) {
+  ##      y <- levels(y)[y]
+  ##    }
+  ##    if (is.list(y)) {
+  ##      y <- unlist(y)
+  ##    }
+  ##    return(y)
+  ##  }
+  varying.digits <- is.matrix( attr( x, "digits", exact = TRUE ) )
+  ## Code for letting "digits" be a matrix was provided by
+  ## Arne Henningsen <ahenningsen at agric-econ.uni-kiel.de>
+  ## in e-mail dated 2005-06-04.
+  ##if( !varying.digits ) {
+  ## modified Claudio Agostinelli <claudio at unive.it> dated 2006-07-28
+  ##  attr(x,"digits") <- matrix( attr( x, "digits",exact=TRUE ),
+  ## nrow = nrow(x), ncol = ncol(x)+1, byrow = TRUE )
+  ##}
+  for(i in 1:ncol(x)) {
+    xcol <- x[, i]
+    if(is.factor(xcol))
+      xcol <- as.character(xcol)
+    if(is.list(xcol))
+      xcol <- sapply(xcol, unlist)
+    ina <- is.na(xcol)
+    is.numeric.column <- is.numeric(xcol)
+    
+    if(is.character(xcol)) {
+      cols[, i+pos] <- xcol
+    } else {
+      if (is.null(format.args)){
+        format.args <- list()
+      }
+      if (is.null(format.args$decimal.mark)){
+        format.args$decimal.mark <- options()$OutDec
+      }
+      if(!varying.digits){
+        curFormatArgs <-
+          c(list(
+            x = xcol,
+            format =
+              ifelse(attr(x, "digits", exact = TRUE )[i+1] < 0, "E",
+                     attr(x, "display", exact = TRUE )[i+1]),
+            digits = abs(attr(x, "digits", exact = TRUE )[i+1])),
+            format.args)
+        cols[, i+pos] <- do.call("formatC", curFormatArgs)
+      }else{
+        for( j in 1:nrow( cols ) ) {
+          curFormatArgs <-
+            c(list(
+              x = xcol[j],
+              format =
+                ifelse(attr(x, "digits", exact = TRUE )[j, i+1] < 0,
+                       "E", attr(x, "display", exact = TRUE )[i+1]),
+              digits =
+                abs(attr(x, "digits", exact = TRUE )[j, i+1])),
+              format.args)
+          cols[j, i+pos] <- do.call("formatC", curFormatArgs)
         }
-        result <- result + ETABULAR
-        result <- result + ESIZE
-        if ( floating == TRUE ) {
-            if ((!is.null(caption)) &&
-                (type == "latex" && caption.placement == "bottom")) {
-                result <- result + BCAPTION + caption + ECAPTION
-            }
-            if (!is.null(attr(x, "label", exact = TRUE)) &&
-                caption.placement == "bottom") {
-                result <- result + BLABEL + attr(x, "label", exact = TRUE) +
-                    ELABEL
-            }
+      }
+    }
+    ## End Ian Fellows changes
+
+    if ( any(ina) ) cols[ina, i+pos] <- NA.string
+    ## Based on contribution from Jonathan Swinton <jonathan at swintons.net>
+    ## in e-mail dated Wednesday, January 17, 2007
+    if ( is.numeric.column ) {
+      cols[, i+pos] <-
+        sanitize.numbers(cols[, i+pos], type = type,
+                         math.style.negative = math.style.negative,
+                         math.style.exponents = math.style.exponents)
+    } else {
+      if (is.null(sanitize.text.function)) {
+        cols[, i+pos] <- sanitize(cols[, i+pos], type = type)
+      } else {
+        cols[, i+pos] <- sanitize.text.function(cols[, i+pos])
+      }
+    }
+  }
+  
+  multiplier <- 5
+  full <- matrix("", nrow = nrow(x), ncol = multiplier*(ncol(x)+pos)+2)
+  full[, 1] <- BROW
+  full[, multiplier*(0:(ncol(x)+pos-1))+2] <- BTD1
+  full[, multiplier*(0:(ncol(x)+pos-1))+3] <- BTD2
+  full[, multiplier*(0:(ncol(x)+pos-1))+4] <- BTD3
+  full[, multiplier*(0:(ncol(x)+pos-1))+5] <- cols
+  full[, multiplier*(0:(ncol(x)+pos-1))+6] <- ETD
+  
+  full[, multiplier*(ncol(x)+pos)+2] <- paste(EROW, lastcol[-(1:2)],
+                                              sep = " ")
+  
+  if (type == "latex") full[, 2] <- ""
+  result <- result + lastcol[2] + paste(t(full), collapse = "")
+  if (!only.contents) {
+    if (tabular.environment == "longtable") {
+      ## booktabs change added the if() - 1 Feb 2012
+      if(!booktabs) {
+        result <- result + PHEADER
+      }
+
+      ## fix 10-27-09 Liviu Andronic (landronimirc at gmail.com) the
+      ## following 'if' condition is inserted in order to avoid
+      ## that bottom caption interferes with a top caption of a longtable
+      if(caption.placement == "bottom"){
+        if ((!is.null(caption)) && (type == "latex")) {
+          result <- result + BCAPTION + caption + ECAPTION
         }
-        result <- result + EENVIRONMENT
-        result <- result + ETABLE
+      }
+      if (!is.null(attr(x, "label", exact = TRUE))) {
+        result <- result + BLABEL + attr(x, "label", exact = TRUE) +
+          ELABEL
+      }
+      ETABULAR <- "\\end{longtable}\n"
     }
-    result <- sanitize.final(result)
-
-    if (print.results){
-	print(result)
+    result <- result + ETABULAR
+    result <- result + ESIZE
+    if ( floating == TRUE ) {
+      if ((!is.null(caption)) &&
+          (type == "latex" && caption.placement == "bottom")) {
+        result <- result + BCAPTION + caption + ECAPTION
+      }
+      if (!is.null(attr(x, "label", exact = TRUE)) &&
+          caption.placement == "bottom") {
+        result <- result + BLABEL + attr(x, "label", exact = TRUE) +
+          ELABEL
+      }
     }
-
-    return(invisible(result$text))
+    result <- result + EENVIRONMENT
+    result <- result + ETABLE
+  }
+  result <- sanitize.final(result, type = type)
+  
+  if (print.results){
+    print(result)
+  }
+  
+  return(invisible(result$text))
 }
 
 "+.string" <- function(x, y) {
-    x$text <- paste(x$text, as.string(y)$text, sep = "")
-    return(x)
+  x$text <- paste(x$text, as.string(y)$text, sep = "")
+  return(x)
 }
 
 print.string <- function(x, ...) {
-    cat(x$text, file = x$file, append = x$append)
-    return(invisible())
+  cat(x$text, file = x$file, append = x$append)
+  return(invisible())
 }
 
 string <- function(text, file = "", append = FALSE) {
-    x <- list(text = text, file = file, append = append)
-    class(x) <- "string"
-    return(x)
+  x <- list(text = text, file = file, append = append)
+  class(x) <- "string"
+  return(x)
 }
 
 as.string <- function(x, file = "", append = FALSE) {
-    if (is.null(attr(x, "class", exact = TRUE)))
-        switch(data.class(x),
-               character = return(string(x, file, append)),
-               numeric = return(string(as.character(x), file, append)),
-               stop("Cannot coerce argument to a string"))
-    if (class(x) == "string")
-        return(x)
-    stop("Cannot coerce argument to a string")
+  if (is.null(attr(x, "class", exact = TRUE)))
+    switch(data.class(x),
+           character = return(string(x, file, append)),
+           numeric = return(string(as.character(x), file, append)),
+           stop("Cannot coerce argument to a string"))
+  if (class(x) == "string")
+    return(x)
+  stop("Cannot coerce argument to a string")
 }
 
 is.string <- function(x) {
-    return(class(x) == "string")
+  return(class(x) == "string")
 }
 
diff --git a/R/sanitize.R b/R/sanitize.R
new file mode 100644
index 0000000..77404b7
--- /dev/null
+++ b/R/sanitize.R
@@ -0,0 +1,97 @@
+sanitize <- function(str, type = "latex") {
+  if(type == "latex"){
+    result <- str
+    result <- gsub("\\\\", "SANITIZE.BACKSLASH", result)
+    result <- gsub("$", "\\$", result, fixed = TRUE)
+    result <- gsub(">", "$>$", result, fixed = TRUE)
+    result <- gsub("<", "$<$", result, fixed = TRUE)
+    result <- gsub("|", "$|$", result, fixed = TRUE)
+    result <- gsub("{", "\\{", result, fixed = TRUE)
+    result <- gsub("}", "\\}", result, fixed = TRUE)
+    result <- gsub("%", "\\%", result, fixed = TRUE)
+    result <- gsub("&", "\\&", result, fixed = TRUE)
+    result <- gsub("_", "\\_", result, fixed = TRUE)
+    result <- gsub("#", "\\#", result, fixed = TRUE)
+    result <- gsub("^", "\\verb|^|", result, fixed = TRUE)
+    result <- gsub("~", "\\~{}", result, fixed = TRUE)
+    result <- gsub("SANITIZE.BACKSLASH", "$\\backslash$", result, fixed = TRUE)
+    return(result)
+  } else {
+    result <- str
+    result <- gsub("&", "&", result, fixed = TRUE)
+    result <- gsub(">", ">", result, fixed = TRUE)
+    result <- gsub("<", "<", result, fixed = TRUE)
+    return(result)
+  }
+}
+
+
+sanitize.numbers <- function(str, type,
+                             math.style.negative = FALSE,
+                             math.style.exponents = FALSE){
+  if (type == "latex"){
+    result <- str
+    if ( math.style.negative ) {
+      for(i in 1:length(str)) {
+        result[i] <- gsub("-", "$-$", result[i], fixed = TRUE)
+      }
+    }
+    if ( math.style.exponents ) {
+      if (is.logical(math.style.exponents) && ! math.style.exponents ) {
+      } else if (is.logical(math.style.exponents) && math.style.exponents ||
+                 math.style.exponents == "$$"
+                 ) {
+        for(i in 1:length(str)) {
+          result[i] <-
+            gsub("^\\$?(-?)\\$?([0-9.]+)[eE]\\$?(-?)\\+?\\$?0*(\\d+)$",
+                 "$\\1\\2 \\\\times 10^{\\3\\4}$", result[i])
+        }
+      } else if (math.style.exponents == "ensuremath") {
+        for(i in 1:length(str)) {
+          result[i] <-
+            gsub("^\\$?(-?)\\$?([0-9.]+)[eE]\\$?(-?)\\+?\\$?0*(\\d+)$",
+                 "\\\\ensuremath{\\1\\2 \\\\times 10^{\\3\\4}}",
+                 result[i])
+        }
+      } else if (math.style.exponents == "UTF8" ||
+                 math.style.exponents == "UTF-8") {
+        for(i in 1:length(str)) {
+          ## this code turns 1e5 into a UTF-8 representation of 1\times10^5
+          if (all(grepl("^\\$?(-?)\\$?([0-9.]+)[eE]\\$?(-?)\\+?\\$?0*(\\d+)$",
+                        result[i]))) {
+            temp <- strsplit(result[i],"eE",result[i])
+            result[i] <-
+              paste0(temp[1],
+                     "\u00d710",
+                     chartr("-1234567890",
+                            "\u207b\u00b9\u00b2\u00b3\u2074\u2075\u20746\u20747\u20748\u20749\u2070",
+                            temp[2]))
+          }
+        }
+      }
+    }
+    return(result)
+  } else {
+    return(str)
+  }
+}
+
+
+sanitize.final <- function(str, type){
+  if (type == "latex"){
+    return(str)
+  } else {
+    str$text <- gsub("  *", " ",  str$text, fixed = TRUE)
+    str$text <- gsub(' align="left"',  "", str$text,
+                     fixed = TRUE)
+    return(str)
+  }
+}
+
+### Some trivial helper functions
+### Suggested by Stefan Edwards, sme at iysik.com
+### Helper function for disabling sanitizing
+as.is <- function(str) {str}
+
+### Helper function for embedding names in a math environment
+as.math <- function(str, ...) { paste0('$',str,'$', ...) }
diff --git a/R/table.attributes.R b/R/table.attributes.R
index 718e41f..9932cef 100644
--- a/R/table.attributes.R
+++ b/R/table.attributes.R
@@ -20,56 +20,57 @@
 ### Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 ### MA 02111-1307, USA
 
-"caption<-" <- function(x,value) UseMethod("caption<-")
-"caption<-.xtable" <- function(x,value) {
-  if (length(value)>2)
+"caption<-" <- function(x, value) UseMethod("caption<-")
+"caption<-.xtable" <- function(x, value) {
+  if (length(value) > 2)
     stop("\"caption\" must have length 1 or 2")
-  attr(x,"caption") <- value
+  attr(x, "caption") <- value
   return(x)
 }
 
-caption <- function(x,...) UseMethod("caption")
-caption.xtable <- function(x,...) {
-  return(attr(x,"caption",exact=TRUE))
+caption <- function(x, ...) UseMethod("caption")
+caption.xtable <- function(x, ...) {
+  return(attr(x, "caption", exact = TRUE))
 }
 
-"label<-" <- function(x,value) UseMethod("label<-")
-"label<-.xtable" <- function(x,value) {
-  if (length(value)>1)
+"label<-" <- function(x, value) UseMethod("label<-")
+"label<-.xtable" <- function(x, value) {
+  if (length(value) > 1)
     stop("\"label\" must have length 1")
-  attr(x,"label") <- value
+  attr(x, "label") <- value
   return(x)
 }
 
-label <- function(x,...) UseMethod("label")
-label.xtable <- function(x,...) {
-  return(attr(x,"label",exact=TRUE))
+label <- function(x, ...) UseMethod("label")
+label.xtable <- function(x, ...) {
+  return(attr(x, "label", exact = TRUE))
 }
 
-"align<-" <- function(x,value) UseMethod("align<-")
+"align<-" <- function(x, value) UseMethod("align<-")
 
-# Based on contribution from Jonathan Swinton <jonathan at swintons.net> in e-mail dated Wednesday, January 17, 2007
+### Based on contribution from Jonathan Swinton <jonathan at swintons.net>
+### in e-mail dated Wednesday, January 17, 2007
 .alignStringToVector <- function(aString) {
-  # poor mans parsing - separating string of form "l{2in}llr|p{1in}c|{1in}"
-  # into "l{2in}" "l"      "l"      "r"      "|"      "p{1in}" "c"      "|{1in}"
+  ## poor mans parsing - separating string of form "l{2in}llr|p{1in}c|{1in}"
+  ## into "l{2in}" "l"  "l"  "r" "|" "p{1in}" "c" "|{1in}"
   aString.Align <- character(0);
   aString.Width <- character(0);
   wString <- aString
-  while( nchar(wString)>0) {
-    aString.Align <- c(aString.Align,substr(wString,1,1))
-    # is it followed by a brace?
+  while( nchar(wString) > 0) {
+    aString.Align <- c(aString.Align, substr(wString, 1, 1))
+    ## is it followed by a brace?
     thisWidth <- ""
-    if ( nchar(wString)>1 & substr(wString,2,2)=="{") {
-      beforeNextBrace <- regexpr("[^\\]\\}",wString)
+    if ( nchar(wString) > 1 & substr(wString, 2, 2) == "{") {
+      beforeNextBrace <- regexpr("[^\\]\\}", wString)
       if (beforeNextBrace <0 ) {
         stop("No closing } in align string")
       }
-      thisWidth <- substr(wString,2,beforeNextBrace+1)
-      wString <- substr(wString,beforeNextBrace+2,nchar(wString))
+      thisWidth <- substr(wString, 2, beforeNextBrace + 1)
+      wString <- substr(wString, beforeNextBrace + 2, nchar(wString))
     } else {
-      wString <- substr(wString,2,nchar(wString))
+      wString <- substr(wString, 2, nchar(wString))
     }
-    aString.Width <- c(aString.Width,thisWidth)
+    aString.Width <- c(aString.Width, thisWidth)
   }
 
   alignAllowed <- c("l","r","p","c","|","X")
@@ -77,78 +78,84 @@ label.xtable <- function(x,...) {
   if (any( !(aString.Align %in% alignAllowed))) {
     warning("Nonstandard alignments in align string")
   }
-  res <- paste(aString.Align,aString.Width,sep="")
+  res <- paste(aString.Align, aString.Width, sep = "")
   res
 }
-#.alignStringToVector ("l{2in}llr|p{1in}c|{1in}")
-#.alignStringToVector ("l{2in}llr|p{1in}c|")
-#.alignStringToVector ("{2in}llr|p{1in}c|") # latex syntax error, but gives wrong alignment
-#.alignStringToVector("llllp{3cm}")
-
-"align<-.xtable" <- function(x,value) {
-# Based on contribution from Benno <puetz at mpipsykl.mpg.de> in e-mail dated Wednesday, December 01, 2004
-# Based on contribution from Jonathan Swinton <jonathan at swintons.net> in e-mail dated Wednesday, January 17, 2007
-  # cat("%",value,"\n")
-  if ( (!is.null(value)) && ( is.character(value) ) && ( length(value) == 1 ) && ( nchar(value) > 1 ) ) {
+###.alignStringToVector ("l{2in}llr|p{1in}c|{1in}")
+###.alignStringToVector ("l{2in}llr|p{1in}c|")
+### latex syntax error, but gives wrong alignment
+###.alignStringToVector ("{2in}llr|p{1in}c|")
+###.alignStringToVector("llllp{3cm}")
+
+"align<-.xtable" <- function(x, value) {
+### Based on contribution from Benno <puetz at mpipsykl.mpg.de>
+### in e-mail dated Wednesday, December 01, 2004
+### Based on contribution from Jonathan Swinton <jonathan at swintons.net>
+### in e-mail dated Wednesday, January 17, 2007
+  ## cat("%", value, "\n")
+  if ( (!is.null(value)) && ( is.character(value) ) &&
+       ( length(value) == 1 ) && ( nchar(value) > 1 ) ) {
         value <- .alignStringToVector(value)
-  } # That should have checked we had only lrcp|
-    # but what if the "if statement" is false?
-    # For simplicity, deleting check present in version 1.4-2 and earlier.
-  c.value <- if (any(!is.na(match(value,"|")))) {
-                value[-which(value=='|')]
+  }
+  ## That should have checked we had only lrcp|
+  ## but what if the "if statement" is false?
+  ## For simplicity, deleting check present in version 1.4-2 and earlier.
+  c.value <- if (any(!is.na(match(value, "|")))) {
+               value[-which(value == '|')]
              } else {
-                value
+               value
              }
-  if (length(c.value)!=ncol(x)+1)
-      stop(paste("\"align\" must have length equal to",ncol(x)+1,"( ncol(x) + 1 )"))
-
-  attr(x,"align") <- value
+  if (length(c.value) != ncol(x) + 1)
+    stop(paste("\"align\" must have length equal to",
+               ncol(x) + 1, "( ncol(x) + 1 )"))
+  attr(x, "align") <- value
   return(x)
 }
 
-align <- function(x,...) UseMethod("align")
-align.xtable <- function(x,...) {
-  return(attr(x,"align",exact=TRUE))
+align <- function(x, ...) UseMethod("align")
+align.xtable <- function(x, ...) {
+  return(attr(x, "align", exact = TRUE))
 }
 
-"digits<-" <- function(x,value) UseMethod("digits<-")
-"digits<-.xtable" <- function(x,value) {
+"digits<-" <- function(x, value) UseMethod("digits<-")
+"digits<-.xtable" <- function(x, value) {
   if( is.matrix( value ) ) {
-    if( ncol( value ) != ncol(x)+1 || nrow( value ) != nrow(x) ) {
+    if( ncol( value ) != ncol(x) + 1 || nrow( value ) != nrow(x) ) {
       stop( "if argument 'digits' is a matrix, it must have columns equal",
-        " to ", ncol(x)+1, " ( ncol(x) + 1 ) and rows equal to ", nrow(x),
-        " ( nrow( x )" )
+           " to ", ncol(x) + 1, " ( ncol(x) + 1 ) and rows equal to ", nrow(x),
+           " ( nrow( x )" )
     }
   } else {
-    if( length(value)==1 ) { value <- rep(value, ncol(x)+1) }
-    if( length( value ) >1 & length( value ) != ncol(x)+1 ) {
+    if( length(value) == 1 ) { value <- rep(value, ncol(x) + 1) }
+    if( length( value ) > 1 & length( value ) != ncol(x) + 1 ) {
       stop( "if argument 'digits' is a vector of length more than one, it must have length equal",
-        " to ", ncol(x)+1, " ( ncol(x) + 1 )" )
+           " to ", ncol(x) + 1, " ( ncol(x) + 1 )" )
     }
   }
   if (!is.numeric(value))
     stop("\"digits\" must be numeric")
-  attr(x,"digits") <- value
+  attr(x, "digits") <- value
   return(x)
 }
 
-digits <- function(x,...) UseMethod("digits")
-digits.xtable <- function(x,...) {
-  return(attr(x,"digits",exact=TRUE))
+digits <- function(x, ...) UseMethod("digits")
+digits.xtable <- function(x, ...) {
+  return(attr(x, "digits", exact = TRUE))
 }
 
-"display<-" <- function(x,value) UseMethod("display<-")
-"display<-.xtable" <- function(x,value) {
-  if (length(value)!=ncol(x)+1)
-    stop(paste("\"display\" must have length equal to",ncol(x)+1,"( ncol(x) + 1 )"))
-  if (!all(!is.na(match(value,c("d","f","e","E","g","G","fg","s")))))
+"display<-" <- function(x, value) UseMethod("display<-")
+"display<-.xtable" <- function(x, value) {
+  if (length(value) != ncol(x) + 1)
+    stop(paste("\"display\" must have length equal to",
+               ncol(x) + 1, "( ncol(x) + 1 )"))
+  if (!all(!is.na(match(value, c("d","f","e","E","g","G","fg","s")))))
     stop("\"display\" must be in {\"d\",\"f\",\"e\",\"E\",\"g\",\"G\", \"fg\", \"s\"}")
-  attr(x,"display") <- value
+  attr(x, "display") <- value
   return(x)
 }
 
-display <- function(x,...) UseMethod("display")
-display.xtable <- function(x,...) {
-  return(attr(x,"display",exact=TRUE))
+display <- function(x, ...) UseMethod("display")
+display.xtable <- function(x, ...) {
+  return(attr(x, "display", exact = TRUE))
 }
 
diff --git a/R/toLatex.R b/R/toLatex.R
index b0a2e16..86fada2 100644
--- a/R/toLatex.R
+++ b/R/toLatex.R
@@ -4,7 +4,7 @@
 ###
 ### Copyright 2000-2013 David B. Dahl <dahl at stat.byu.edu>
 ###
-### Maintained by Charles Roosen <croosen at mango-solutions.com>
+### Maintained by David Scott <d.scott at auckland.ac.nz>
 ###
 ### This file is part of the `xtable' library for R and related languages.
 ### It is made available under the terms of the GNU General Public
@@ -22,12 +22,12 @@
 ### Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 ### MA 02111-1307, USA
 
-## The generic for toLatex() is declared in the base package "utils"
+### The generic for toLatex() is declared in the base package "utils"
 
 toLatex.xtable <- function(object, ...){
-  # Initially just capturing the output of print.xtable().  At some
-  # point this could be refactored to have print.xtable() call
-  # toLatex() instead. - CR, 30/01/2012
+  ## Initially just capturing the output of print.xtable().  At some
+  ## point this could be refactored to have print.xtable() call
+  ## toLatex() instead. - CR, 30/01/2012
   dotArgs <- list(...)
   dotArgs$x <- object
   dotArgs$type <- "latex"
diff --git a/R/xtable.R b/R/xtable.R
index 2afc43c..4f1973d 100644
--- a/R/xtable.R
+++ b/R/xtable.R
@@ -21,15 +21,16 @@
 ### MA 02111-1307, USA
 
 xtable <- function(x, caption = NULL, label = NULL, align = NULL,
-                   digits = NULL, display = NULL, ...) {
+                   digits = NULL, display = NULL, auto = FALSE, ...) {
   UseMethod("xtable")
 }
 
 
-## data.frame and matrix objects
+### data.frame and matrix objects
 
 xtable.data.frame <- function(x, caption = NULL, label = NULL, align = NULL,
-                              digits = NULL, display = NULL, ...) {
+                              digits = NULL, display = NULL, auto = FALSE,
+                              ...) {
   logicals <- unlist(lapply(x, is.logical))
   ##x[, logicals] <- lapply(x[, logicals], as.character)
   ## Patch for logicals bug, no 1911
@@ -41,6 +42,9 @@ xtable.data.frame <- function(x, caption = NULL, label = NULL, align = NULL,
   class(x) <- c("xtable","data.frame")
   caption(x) <- caption
   label(x) <- label
+  if(auto && is.null(align))   align   <- xalign(x)
+  if(auto && is.null(digits))  digits  <- xdigits(x)
+  if(auto && is.null(display)) display <- xdisplay(x)
   align(x) <- switch(1+is.null(align), align,
                      c("r",c("r","l")[(characters|factors)+1]))
   digits(x) <- switch(1+is.null(digits), digits, c(0,rep(2,ncol(x))))
@@ -56,38 +60,39 @@ xtable.data.frame <- function(x, caption = NULL, label = NULL, align = NULL,
 }
 
 xtable.matrix <- function(x, caption = NULL, label = NULL, align = NULL,
-                          digits = NULL, display = NULL, ...) {
+                          digits = NULL, display = NULL, auto = FALSE, ...) {
   return(xtable.data.frame(data.frame(x, check.names = FALSE),
                            caption = caption, label = label, align = align,
-                           digits = digits, display = display))
+                           digits = digits, display = display, auto = auto,
+                           ...))
 }
 
 
+
 ### table objects (of 1 or 2 dimensions) by Guido Gay, 9 Feb 2007
 ### Fixed to pass R checks by DBD, 9 May 2007
 xtable.table <- function(x, caption = NULL, label = NULL, align = NULL,
-                       digits = NULL, display = NULL, ...) {
+                       digits = NULL, display = NULL, auto = FALSE, ...) {
   if (length(dim(x)) == 1) {
     return(xtable.matrix(matrix(x,
                                 dimnames = list(rownames(x),
                                                 names(dimnames(x)))),
-                         caption = caption, label = label,
-                         align = align, digits = digits, display = display))
+                         caption = caption, label = label, align = align,
+                         digits = digits, display = display, auto = auto, ...))
   } else if (length(dim(x))==2) {
     return(xtable.matrix(matrix(x, ncol = dim(x)[2], nrow = dim(x)[1],
                                 dimnames = list(rownames(x), colnames(x))),
-                         caption = caption, label = label,
-                         align = align, digits = digits, display = display))
+                         caption = caption, label = label, align = align,
+                         digits = digits, display = display, auto = auto, ...))
   } else {
     stop("xtable.table is not implemented for tables of > 2 dimensions")
   }
 }
 
 
-## anova objects
-
+### anova objects
 xtable.anova <- function(x, caption = NULL, label = NULL, align = NULL,
-                         digits = NULL, display = NULL, ...) {
+                         digits = NULL, display = NULL, auto = FALSE, ...) {
   suggested.digits <- c(0,rep(2, ncol(x)))
   suggested.digits[grep("Pr\\(>", names(x))+1] <- 4
   suggested.digits[grep("P\\(>", names(x))+1] <- 4
@@ -96,6 +101,9 @@ xtable.anova <- function(x, caption = NULL, label = NULL, align = NULL,
   class(x) <- c("xtable","data.frame")
   caption(x) <- caption
   label(x) <- label
+  if(auto && is.null(align))   align   <- xalign(x)
+  if(auto && is.null(digits))  digits  <- xdigits(x)
+  if(auto && is.null(display)) display <- xdisplay(x)
   align(x) <- switch(1+is.null(align), align, c("l",rep("r", ncol(x))))
   digits(x) <- switch(1+is.null(digits), digits, suggested.digits)
   display(x) <- switch(1+is.null(display), display, c("s",rep("f", ncol(x))))
@@ -103,63 +111,69 @@ xtable.anova <- function(x, caption = NULL, label = NULL, align = NULL,
 }
 
 
-## aov objects
-
+### aov objects
 xtable.aov <- function(x, caption = NULL, label = NULL, align = NULL,
-                       digits = NULL, display = NULL, ...) {
+                       digits = NULL, display = NULL, auto = FALSE, ...) {
   return(xtable.anova(anova(x, ...), caption = caption, label = label,
-                      align = align, digits = digits, display = display))
+                      align = align, digits = digits, display = display,
+                      auto = auto, ...))
 }
 
 xtable.summary.aov <- function(x, caption = NULL, label = NULL, align = NULL,
-                               digits = NULL, display = NULL, ...) {
-  return(xtable.anova(x[[1]], caption = caption, label = label,
-                      align = align, digits = digits, display = display))
+                               digits = NULL, display = NULL, auto = FALSE,
+                               ...) {
+  return(xtable.anova(x[[1]], caption = caption, label = label, align = align,
+                      digits = digits, display = display, auto = auto, ...))
 }
 
 xtable.summary.aovlist <- function(x, caption = NULL, label = NULL,
-                                   align = NULL,
-                                   digits = NULL, display = NULL, ...) {
+                                   align = NULL, digits = NULL, display = NULL,
+                                   auto = FALSE, ...) {
     for (i in 1:length(x)) {
         if (i == 1) {
             result <- xtable.summary.aov(x[[i]], caption = caption,
                                          label = label,
                                          align = align, digits = digits,
-                                         display = display)
+                                         display = display, auto = auto, ...)
         } else {
             result <- rbind(result,
                             xtable.anova(x[[i]][[1]], caption = caption,
                                          label = label, align = align,
-                                         digits = digits, display = display))
+                                         digits = digits, display = display,
+                                         auto = auto, ...))
         }
     }
     return(result)
 }
 
 xtable.aovlist <- function(x, caption = NULL, label = NULL, align = NULL,
-                           digits = NULL, display = NULL, ...) {
+                           digits = NULL, display = NULL, auto = FALSE, ...) {
   return(xtable.summary.aovlist(summary(x), caption = caption, label = label,
                                 align = align, digits = digits,
-                                display = display))
+                                display = display, auto = auto, ...))
 }
 
 
 
-## lm objects
-
+### lm objects
 xtable.lm <- function(x, caption = NULL, label = NULL, align = NULL,
-                      digits = NULL, display = NULL, ...) {
+                      digits = NULL, display = NULL, auto = FALSE, ...) {
   return(xtable.summary.lm(summary(x), caption = caption, label = label,
-                           align = align, digits = digits, display = display))
+                           align = align, digits = digits, display = display,
+                           auto = auto, ...))
 }
 
 xtable.summary.lm <- function(x, caption = NULL, label = NULL, align = NULL,
-                              digits = NULL, display = NULL, ...) {
+                              digits = NULL, display = NULL, auto = FALSE,
+                              ...) {
   x <- data.frame(x$coef, check.names = FALSE)
 
   class(x) <- c("xtable","data.frame")
   caption(x) <- caption
   label(x) <- label
+  if(auto && is.null(align))   align   <- xalign(x)
+  if(auto && is.null(digits))  digits  <- xdigits(x)
+  if(auto && is.null(display)) display <- xdisplay(x)
   align(x) <- switch(1+is.null(align), align, c("r","r","r","r","r"))
   digits(x) <- switch(1+is.null(digits), digits, c(0,4,4,2,4))
   display(x) <- switch(1+is.null(display), display, c("s","f","f","f","f"))
@@ -167,31 +181,35 @@ xtable.summary.lm <- function(x, caption = NULL, label = NULL, align = NULL,
 }
 
 
-## glm objects
-
+### glm objects
 xtable.glm <- function(x, caption = NULL, label = NULL, align = NULL,
-                       digits = NULL, display = NULL, ...) {
+                       digits = NULL, display = NULL, auto = FALSE, ...) {
   return(xtable.summary.glm(summary(x), caption = caption,
                             label = label, align = align,
-                            digits = digits, display = display))
+                            digits = digits, display = display,
+                            auto = auto, ...))
 }
 
 xtable.summary.glm <- function(x, caption = NULL, label = NULL, align = NULL,
-                               digits = NULL, display = NULL, ...) {
-  return(xtable.summary.lm(x, caption = caption, label = label,
-                           align = align, digits = digits, display = display))
+                               digits = NULL, display = NULL, auto = FALSE,
+                               ...) {
+  return(xtable.summary.lm(x, caption = caption, label = label, align = align,
+                           digits = digits, display = display,
+                           auto = auto, ...))
 }
 
 
-## prcomp objects
-
+### prcomp objects
 xtable.prcomp <- function(x, caption = NULL, label = NULL, align = NULL,
-                          digits = NULL, display = NULL, ...) {
+                          digits = NULL, display = NULL, auto = FALSE, ...) {
   x <- data.frame(x$rotation, check.names = FALSE)
 
   class(x) <- c("xtable","data.frame")
   caption(x) <- caption
   label(x) <- label
+  if(auto && is.null(align))   align   <- xalign(x)
+  if(auto && is.null(digits))  digits  <- xdigits(x)
+  if(auto && is.null(display)) display <- xdisplay(x)
   align(x) <- switch(1+is.null(align), align, c("r",rep("r", ncol(x))))
   digits(x) <- switch(1+is.null(digits), digits, c(0,rep(4, ncol(x))))
   display(x) <- switch(1+is.null(display), display, c("s",rep("f", ncol(x))))
@@ -199,12 +217,16 @@ xtable.prcomp <- function(x, caption = NULL, label = NULL, align = NULL,
 }
 
 xtable.summary.prcomp <- function(x, caption = NULL, label = NULL, align = NULL,
-                                  digits = NULL, display = NULL, ...) {
+                                  digits = NULL, display = NULL, auto = FALSE,
+                                  ...) {
   x <- data.frame(x$importance, check.names = FALSE)
 
   class(x) <- c("xtable","data.frame")
   caption(x) <- caption
   label(x) <- label
+  if(auto && is.null(align))   align   <- xalign(x)
+  if(auto && is.null(digits))  digits  <- xdigits(x)
+  if(auto && is.null(display)) display <- xdisplay(x)
   align(x) <- switch(1+is.null(align), align, c("r",rep("r", ncol(x))))
   digits(x) <- switch(1+is.null(digits), digits, c(0,rep(4, ncol(x))))
   display(x) <- switch(1+is.null(display), display, c("s",rep("f", ncol(x))))
@@ -212,12 +234,12 @@ xtable.summary.prcomp <- function(x, caption = NULL, label = NULL, align = NULL,
 }
 
 
-# Slightly modified version of xtable.coxph contributed on r-help by
-#   Date: Wed, 2 Oct 2002 17:47:56 -0500 (CDT)
-#   From: Jun Yan <jyan at stat.wisc.edu>
-#   Subject: Re: [R] xtable for Cox model output
+### Slightly modified version of xtable.coxph contributed on r-help by
+###   Date: Wed, 2 Oct 2002 17:47:56 -0500 (CDT)
+###   From: Jun Yan <jyan at stat.wisc.edu>
+###   Subject: Re: [R] xtable for Cox model output
 xtable.coxph <- function (x, caption = NULL, label = NULL, align = NULL,
-                          digits = NULL, display = NULL, ...)
+                          digits = NULL, display = NULL, auto = FALSE, ...)
 {
   cox <- x
   beta <- cox$coef
@@ -226,24 +248,23 @@ xtable.coxph <- function (x, caption = NULL, label = NULL, align = NULL,
     tmp <- cbind(beta, exp(beta), se, beta/se, 1 - pchisq((beta/se)^2, 1))
     dimnames(tmp) <- list(names(beta),
       c("coef", "exp(coef)", "se(coef)", "z", "p"))
-  }
-  else {
+  } else {
     tmp <- cbind( beta, exp(beta), se, beta/se,
       signif(1 - pchisq((beta/se)^2, 1), digits - 1))
     dimnames(tmp) <- list(names(beta),
       c("coef", "exp(coef)", "robust se", "z", "p"))
   }
   return(xtable(tmp, caption = caption, label = label, align = align,
-                digits = digits, display = display))
+                digits = digits, display = display, auto = auto, ...))
 }
 
-# Additional method: xtable.ts
-# Contributed by David Mitchell (davidm at netspeed.com.au)
-# Date: July 2003
+### Additional method: xtable.ts
+### Contributed by David Mitchell (davidm at netspeed.com.au)
+### Date: July 2003
 xtable.ts <- function(x, caption = NULL, label = NULL, align = NULL,
-                      digits = NULL, display = NULL, ...) {
+                      digits = NULL, display = NULL, auto = FALSE, ...) {
   if (inherits(x, "ts") && !is.null(ncol(x))) {
-    # COLNAMES <- paste(colnames(x));
+    ## COLNAMES <- paste(colnames(x));
     tp.1 <- trunc(time(x))
     tp.2 <- trunc(cycle(x))
     day.abb <- c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
@@ -256,8 +277,7 @@ xtable.ts <- function(x, caption = NULL, label = NULL, align = NULL,
                        "Arg8", "Arg9", "Arg10", "Arg11",
                        paste(tp.1, month.abb[tp.2], sep = " "))
     tmp <- data.frame(x, row.names = ROWNAMES);
-  }
-  else if (inherits(x, "ts") && is.null(ncol(x))) {
+  } else if (inherits(x, "ts") && is.null(ncol(x))) {
     COLNAMES <- switch(frequency(x),
                        "Value",
                        "Arg2", "Arg3",              # Dummy arguments
@@ -274,11 +294,159 @@ xtable.ts <- function(x, caption = NULL, label = NULL, align = NULL,
     names(tmp) <- COLNAMES
   }
   return(xtable(tmp, caption = caption, label = label, align = align,
-                digits = digits, display = display))
+                digits = digits, display = display, auto = auto, ...))
+}
+
+### Suggested by Ajay Narottam Shah <ajayshah at mayin.org> in e-mail 2006/07/22
+xtable.zoo <- function(x, caption = NULL, label = NULL, align = NULL,
+                       digits = NULL, display = NULL, auto = FALSE, ...) {
+  return(xtable(as.ts(x), caption = caption, label = label,
+                align = align, digits = digits,
+                display = display, auto = auto, ...))
+}
+
+### Date: Fri, 29 May 2015 11:41:04 +0200
+### From: Martin G. <martin.gubri at framasoft.org>
+### Subject: [xtable] Code for spdep, splm and sphet objects outputs
+### package spdep
+### sarlm objects
+xtable.sarlm <- function(x, caption = NULL, label = NULL, align = NULL,
+                         digits = NULL, display = NULL, auto = FALSE, ...) {
+  return(xtable.summary.sarlm(summary(x), caption = caption, label = label,
+                              align = align, digits = digits,
+                              display = display, auto = auto, ...))
+}
+
+xtable.summary.sarlm <- function(x, caption = NULL, label = NULL, align = NULL,
+                                digits = NULL, display = NULL, auto = FALSE,
+                                ...) {
+  x <- data.frame(x$Coef, check.names = FALSE)
+
+  class(x) <- c("xtable","data.frame")
+  caption(x) <- caption
+  label(x) <- label
+  if(auto && is.null(align))   align   <- xalign(x)
+  if(auto && is.null(digits))  digits  <- xdigits(x)
+  if(auto && is.null(display)) display <- xdisplay(x)
+  align(x) <- switch(1+is.null(align), align, c("r","r","r","r","r"))
+  digits(x) <- switch(1+is.null(digits), digits, c(0,4,4,2,4))
+  display(x) <- switch(1+is.null(display), display, c("s","f","f","f","f"))
+  return(x)
+}
+
+### spautolm objects: added by David Scott, 6/1/2016, after suggestion by
+### Guido Schulz
+### Date: Wed, 29 Apr 2015 10:45:16 +0200
+### Guido Schulz <schulzgu at student.hu-berlin.de>
+xtable.spautolm <- function(x, caption = NULL, label = NULL, align = NULL,
+                            digits = NULL, display = NULL, auto = FALSE, ...) {
+    return(xtable.summary.sarlm(summary(x), caption = caption, label = label,
+                              align = align, digits = digits,
+                              display = display, auto = auto, ...))
 }
 
-# Suggested by Ajay Narottam Shah <ajayshah at mayin.org> in e-mail 2006/07/22
-xtable.zoo <- function(x, ...) {
-  return(xtable(as.ts(x), ...))
+xtable.summary.spautolm <- function(x, caption = NULL, label = NULL,
+                                    align = NULL, digits = NULL,
+                                    display = NULL, auto = FALSE, ...) {
+    return(xtable.summary.sarlm(summary(x), caption = caption, label = label,
+                              align = align, digits = digits,
+                              display = display, auto = auto, ...))
+}
+
+
+### gmsar objects
+xtable.gmsar <- function(x, caption = NULL, label = NULL, align = NULL,
+                         digits = NULL, display = NULL, auto = FALSE, ...) {
+    return(xtable.summary.sarlm(summary(x), caption = caption, label = label,
+                              align = align, digits = digits,
+                              display = display, auto = auto, ...))
 }
 
+xtable.summary.gmsar <- function(x, caption = NULL, label = NULL, align = NULL,
+                                 digits = NULL, display = NULL,
+                                 auto = FALSE, ...) {
+  return(xtable.summary.sarlm(x, caption = caption, label = label,
+                              align = align, digits = digits,
+                              display = display, auto = auto, ...))
+}
+
+### stsls objects
+xtable.stsls <- function(x, caption = NULL, label = NULL, align = NULL,
+                         digits = NULL, display = NULL, auto = FALSE, ...) {
+  return(xtable.summary.sarlm(summary(x), caption = caption, label = label,
+                              align = align, digits = digits,
+                              display = display, auto = auto, ...))
+}
+
+xtable.summary.stsls <- function(x, caption = NULL, label = NULL, align = NULL,
+                                 digits = NULL, display = NULL,
+                                 auto = FALSE, ...) {
+  return(xtable.summary.sarlm(x, caption = caption, label = label,
+                              align = align, digits = digits,
+                              display = display, auto = auto, ...))
+}
+
+### pred.sarlm objects
+xtable.sarlm.pred <- function(x, caption = NULL, label = NULL, align = NULL,
+                              digits = NULL, display = NULL,
+                              auto = FALSE, ...) {
+  return(xtable(as.data.frame(x), caption = caption, label = label,
+                align = align, digits = digits,
+                display = display, auto = auto, ...))
+}
+
+
+### This method removed because of the need to copy code to pass CRAN checks
+### lagImpactMat is neither exported nor documented in spdep
+
+###lagImpact objects
+xtable.lagImpact <- function(x, caption = NULL, label = NULL, align = NULL,
+                             digits = NULL, display = NULL,
+                             auto = FALSE, ...) {
+  xtable(lagImpactMat(x), caption = caption, label = label,
+         align = align, digits = digits,
+         display = display, auto = auto, ...)
+}
+
+### package splm
+### splm objects
+xtable.splm <- function(x, caption = NULL, label = NULL, align = NULL,
+                        digits = NULL, display = NULL, auto = FALSE, ...) {
+  return(xtable.summary.splm(summary(x), caption = caption, label = label,
+                             align = align, digits = digits,
+                             display = display, auto = auto, ...))
+}
+
+xtable.summary.splm <- function(x, caption = NULL, label = NULL, align = NULL,
+                                digits = NULL, display = NULL, auto = FALSE,
+                                ...) {
+  x <- data.frame(x$CoefTable, check.names = FALSE)
+
+  class(x) <- c("xtable","data.frame")
+  caption(x) <- caption
+  label(x) <- label
+  if(auto && is.null(align))   align   <- xalign(x)
+  if(auto && is.null(digits))  digits  <- xdigits(x)
+  if(auto && is.null(display)) display <- xdisplay(x)
+  align(x) <- switch(1+is.null(align), align, c("r","r","r","r","r"))
+  digits(x) <- switch(1+is.null(digits), digits, c(0,4,4,2,4))
+  display(x) <- switch(1+is.null(display), display, c("s","f","f","f","f"))
+  return(x)
+}
+
+### package sphet
+### sphet objects
+xtable.sphet <- function(x, caption = NULL, label = NULL, align = NULL,
+                         digits = NULL, display = NULL, auto = FALSE, ...) {
+  return(xtable.summary.splm(summary(x), caption = caption, label = label,
+                             align = align, digits = digits,
+                             display = display, auto = auto, ...))
+}
+
+xtable.summary.sphet <- function(x, caption = NULL, label = NULL, align = NULL,
+                                 digits = NULL, display = NULL,
+                                 auto = FALSE, ...) {
+  return(xtable.summary.splm(x, caption = caption, label = label,
+                             align = align, digits = digits,
+                             display = display, auto = auto, ...))
+}
diff --git a/R/xtableFtable.R b/R/xtableFtable.R
new file mode 100644
index 0000000..72964d8
--- /dev/null
+++ b/R/xtableFtable.R
@@ -0,0 +1,197 @@
+### ftable objects, requested by Charles Roosen
+### Feature request #2248, 2/9/2012
+xtableFtable <- function(x, caption = NULL, label = NULL, align = NULL,
+                         digits = 0, display = NULL,
+                         quote = FALSE,
+                         method = c("non.compact", "row.compact",
+                                    "col.compact", "compact"),
+                         lsep = " $\\vert$ ", ...) {
+  method <- match.arg(method)
+  saveMethod <- method
+  xDim <- dim(x)
+  nRowVars <- length(attr(x, "row.vars"))
+  nColVars <- length(attr(x, "col.vars"))
+  if (nRowVars == 0){
+    if (method =="col.compact"){
+      method <- "non.compact"
+    } else if (method == "compact"){
+      method <- "row.compact"
+    }
+  }
+  if (nColVars == 0){
+    if (method =="row.compact"){
+      method <- "non.compact"
+    } else if (method == "compact"){
+      method <- "col.compact"
+    }
+  }
+  if (method == "non.compact"){
+    nCharCols <- nRowVars + 2
+    nCharRows <- nColVars + 1
+  }
+  if (method == "row.compact"){
+    nCharCols <- nRowVars + 2
+    nCharRows <- nColVars
+  }
+  if (method == "col.compact"){
+    nCharCols <- nRowVars + 1
+    nCharRows <- nColVars + 1
+  }
+  if (method == "compact"){
+    nCharCols <- nRowVars + 1
+    nCharRows <- nColVars
+  }
+
+  if(is.null(align)) {
+    align <- c(rep("l", nCharCols - 1), "l |", rep("r", xDim[2]))
+  }
+  if(is.null(display)) {
+    display <- c(rep("s", nCharCols), rep("d", xDim[2]))
+  }
+
+  attr(x, "ftableCaption") <- caption
+  attr(x, "ftableLabel") <- label
+  attr(x, "ftableAlign") <- align
+  attr(x, "ftableDigits") <- digits
+  attr(x, "quote") <- quote
+  attr(x, "ftableDisplay") <- display
+  attr(x, "method") <- method
+  attr(x, "lsep") <- lsep
+  attr(x, "nChars") <- c(nCharRows, nCharCols)
+  class(x) <- c("xtableFtable", "ftable")
+  return(x)
+}
+
+print.xtableFtable <- function(x,
+  type = getOption("xtable.type", "latex"),
+  file = getOption("xtable.file", ""),
+  append = getOption("xtable.append", FALSE),
+  floating = getOption("xtable.floating", TRUE),
+  floating.environment = getOption("xtable.floating.environment", "table"),
+  table.placement = getOption("xtable.table.placement", "ht"),
+  caption.placement = getOption("xtable.caption.placement", "bottom"),
+  caption.width = getOption("xtable.caption.width", NULL),
+  latex.environments = getOption("xtable.latex.environments", c("center")),
+  tabular.environment = getOption("xtable.tabular.environment", "tabular"),
+  size = getOption("xtable.size", NULL),
+  hline.after = getOption("xtable.hline.after", NULL),
+  NA.string = getOption("xtable.NA.string", ""),
+  only.contents = getOption("xtable.only.contents", FALSE),
+  add.to.row = getOption("xtable.add.to.row", NULL),
+  sanitize.text.function = getOption("xtable.sanitize.text.function", as.is),
+  sanitize.rownames.function = getOption("xtable.sanitize.rownames.function",
+                                         sanitize.text.function),
+  sanitize.colnames.function = getOption("xtable.sanitize.colnames.function",
+                                         sanitize.text.function),
+  math.style.negative = getOption("xtable.math.style.negative", FALSE),
+  math.style.exponents = getOption("xtable.math.style.exponents", FALSE),
+  html.table.attributes = getOption("xtable.html.table.attributes", "border=1"),
+  print.results = getOption("xtable.print.results", TRUE),
+  format.args = getOption("xtable.format.args", NULL),
+  rotate.rownames = getOption("xtable.rotate.rownames", FALSE),
+  rotate.colnames = getOption("xtable.rotate.colnames", FALSE),
+  booktabs = getOption("xtable.booktabs", FALSE),
+  scalebox = getOption("xtable.scalebox", NULL),
+  width = getOption("xtable.width", NULL),
+  comment = getOption("xtable.comment", TRUE),
+  timestamp = getOption("xtable.timestamp", date()),
+  ...) {
+  if (type == "latex"){
+    ## extract the information in the attributes
+    caption <- attr(x, "ftableCaption")
+    label <- attr(x, "ftableLabel")
+    align <- attr(x, "ftableAlign")
+    digits <- attr(x, "ftableDigits")
+    quote <- attr(x, "quote")
+    digits <- attr(x, "ftabelDigits")
+    method <- attr(x, "method")
+    lsep <- attr(x, "lsep")
+    nCharRows <- attr(x, "nChars")[1]
+    nCharCols <- attr(x, "nChars")[2]
+    nRowVars <- length(attr(x, "row.vars"))
+    nColVars <- length(attr(x, "col.vars"))
+    
+    ## change class so format method will find format.ftable
+    ## even though format.ftable is not exported from 'stats'
+    class(x) <- "ftable"
+    fmtFtbl <- format(x, quote = quote, digits = digits,
+                      method = method, lsep = lsep)
+    attr(fmtFtbl, "caption") <- caption
+    attr(fmtFtbl, "label") <- label
+
+    ## sanitization is possible for row names and/or column names
+    ## row names
+    if (is.null(sanitize.rownames.function)) {
+      fmtFtbl[nCharRows, 1:nRowVars] <-
+        sanitize(fmtFtbl[nCharRows, 1:nRowVars], type = type)
+    } else {
+      fmtFtbl[nCharRows, 1:nRowVars] <-
+        sanitize.rownames.function(fmtFtbl[nCharRows, 1:nRowVars])
+    }
+    ## column names
+    if (is.null(sanitize.colnames.function)) {
+      fmtFtbl[1:nColVars, nCharCols - 1] <-
+        sanitize(fmtFtbl[1:nColVars, nCharCols - 1],
+                 type = type)
+    } else {
+      fmtFtbl[1:nColVars, nCharCols - 1] <-
+        sanitize.colnames.function(fmtFtbl[1:nColVars, nCharCols - 1])
+    }
+    ## rotations are possible
+    if (rotate.rownames){
+      fmtFtbl[1:dim(fmtFtbl)[1], 1:(nCharCols - 1)] <-
+        paste0("\\begin{sideways} ",
+               fmtFtbl[1:dim(fmtFtbl)[1], 1:(nCharCols - 1)],
+               "\\end{sideways}")
+    }
+    if (rotate.colnames){
+      if (rotate.rownames){
+        fmtFtbl[1:(nCharRows), (nCharCols):dim(fmtFtbl)[2]] <-
+          paste0("\\begin{sideways} ",
+                 fmtFtbl[1:(nCharRows), (nCharCols):dim(fmtFtbl)[2]],
+                 "\\end{sideways}")
+      } else {
+        fmtFtbl[1:(nCharRows), 1:dim(fmtFtbl)[2]] <-
+          paste0("\\begin{sideways} ",
+                 fmtFtbl[1:(nCharRows), 1:dim(fmtFtbl)[2]],
+                 "\\end{sideways}")
+      }
+    }
+
+
+    ## booktabs is incompatible with vertical lines in tables
+    if (booktabs) align <- gsub("|","", align, fixed = TRUE)
+    attr(fmtFtbl, "align") <- align
+    attr(fmtFtbl, "digits") <- digits
+    attr(fmtFtbl, "quote") <- quote
+    attr(fmtFtbl, "display") <- display
+
+    ## labels should be left aligned
+    for (i in 1:nCharRows){
+      fmtFtbl[i, nCharCols:dim(fmtFtbl)[2]] <-
+        paste0("\\multicolumn{1}{l}{ ",
+               fmtFtbl[i, nCharCols:dim(fmtFtbl)[2]], "}")
+    }
+
+
+    if(is.null(hline.after)) {
+      hline.after <- c(-1, nCharRows, dim(fmtFtbl)[1])
+    }
+    print.xtable(fmtFtbl, hline.after = hline.after,
+                 include.rownames = FALSE, include.colnames = FALSE,
+                 booktabs = booktabs,
+                 sanitize.text.function = as.is)
+  } else {
+    stop("print.xtableFtable not yet implemented for this type")
+  }
+}
+
+## format.xtableFtable <- function(x, quote = TRUE, digits = getOption("digits"),
+##                                 method = c("non.compact", "row.compact",
+##                                            "col.compact", "compact"),
+##                                 lsep = " | ", ...){
+##   class(x) <- "ftable"
+  
+##   format(x, quote = quote, digits = digits,
+##          method = method, lsep = lsep, ...)
+## }
diff --git a/R/xtableList.R b/R/xtableList.R
new file mode 100644
index 0000000..f4476a3
--- /dev/null
+++ b/R/xtableList.R
@@ -0,0 +1,275 @@
+### Function to create lists of tables
+xtableList <- function(x, caption = NULL, label = NULL, align = NULL,
+                       digits = NULL, display = NULL, ...) {
+  if (is.null(digits)){
+    digitsList <- vector("list", length(x))
+  } else {
+    if (!is.list(digits)){
+      digitsList <- vector("list", length(x))
+      for (i in 1:length(x)) digitsList[[i]] <- digits
+    }
+  }
+  if (is.null(display)){
+    displayList <- vector("list", length(x))
+  } else {
+    if (!is.list(display)){
+      displayList <- vector("list", length(x))
+      for (i in 1:length(x)) displayList[[i]] <- display
+    }
+  }
+  xList <- vector("list", length(x))
+  for (i in 1:length(x)){
+    xList[[i]] <- xtable(x[[i]], caption = caption, label = label,
+                         align = align, digits = digitsList[[i]],
+                         display = displayList[[i]], ...)
+    attr(xList[[i]], 'subheading') <- attr(x, 'subheadings')[[i]]
+  }
+  attr(xList, "message") <- attr(x, "message")
+  attr(xList, "caption") <- caption
+  attr(xList, "label") <- label
+  class(xList) <- c("xtableList")
+  return(xList)
+}
+
+print.xtableList <- function(x,
+  type = getOption("xtable.type", "latex"),
+  file = getOption("xtable.file", ""),
+  append = getOption("xtable.append", FALSE),
+  floating = getOption("xtable.floating", TRUE),
+  floating.environment = getOption("xtable.floating.environment", "table"),
+  table.placement = getOption("xtable.table.placement", "ht"),
+  caption.placement = getOption("xtable.caption.placement", "bottom"),
+  caption.width = getOption("xtable.caption.width", NULL),
+  latex.environments = getOption("xtable.latex.environments", c("center")),
+  tabular.environment = getOption("xtable.tabular.environment", "tabular"),
+  size = getOption("xtable.size", NULL),
+  hline.after = NULL,
+  NA.string = getOption("xtable.NA.string", ""),
+  include.rownames = getOption("xtable.include.rownames", TRUE),
+  colnames.format = "single",
+  only.contents = getOption("xtable.only.contents", FALSE),
+  add.to.row = NULL,
+  sanitize.text.function = getOption("xtable.sanitize.text.function", NULL),
+  sanitize.rownames.function = getOption("xtable.sanitize.rownames.function",
+                                         sanitize.text.function),
+  sanitize.colnames.function = getOption("xtable.sanitize.colnames.function",
+                                         sanitize.text.function),
+  sanitize.subheadings.function =
+    getOption("xtable.sanitize.subheadings.function",
+              sanitize.text.function),
+  sanitize.message.function =
+    getOption("xtable.sanitize.message.function",
+              sanitize.text.function),
+  math.style.negative = getOption("xtable.math.style.negative", FALSE),
+  math.style.exponents = getOption("xtable.math.style.exponents", FALSE),
+  html.table.attributes = getOption("xtable.html.table.attributes", "border=1"),
+  print.results = getOption("xtable.print.results", TRUE),
+  format.args = getOption("xtable.format.args", NULL),
+  rotate.rownames = getOption("xtable.rotate.rownames", FALSE),
+  rotate.colnames = getOption("xtable.rotate.colnames", FALSE),
+  booktabs = getOption("xtable.booktabs", FALSE),
+  scalebox = getOption("xtable.scalebox", NULL),
+  width = getOption("xtable.width", NULL),
+  comment = getOption("xtable.comment", TRUE),
+  timestamp = getOption("xtable.timestamp", date()),
+  ...)
+{
+  ## Get number of rows for each table in list of tables
+  nCols <- dim(x[[1]])[2]
+  rowNums <- sapply(x, dim)[1,]
+  combinedRowNums <- cumsum(rowNums)
+  combined <- do.call(rbind, x)
+  if (type == "latex"){
+    ## Special treatment if using booktabs
+    if (booktabs){
+      tRule <- "\\toprule"
+      mRule <- "\\midrule"
+      bRule <- "\\bottomrule"
+    } else {
+      tRule <- "\\hline"
+      mRule <- "\\hline"
+      bRule <- "\\hline"
+    }
+    ## Sanitize subheadings if required
+    if (!is.null(sanitize.subheadings.function)) {
+      for (i in 1:length(x)){
+        attr(x[[i]], 'subheading') <-
+          sanitize.subheadings.function(attr(x[[i]], 'subheading'))
+      }
+    }
+    ## Sanitize message if required
+    if (!is.null(sanitize.message.function)) {
+      xMessage <- attr(x, 'message')
+      xMessage <- sapply(xMessage, sanitize.message.function)
+      attr(x, 'message') <- xMessage
+    }
+    if (colnames.format == "single"){
+
+      add.to.row <- list(pos = NULL, command = NULL)
+      add.to.row$pos <- as.list(c(0, combinedRowNums[-length(x)],
+                                  dim(combined)[1]))
+      command <- sapply(x, attr, "subheading")
+
+      for (i in 1:length(x)){
+        if( !is.null(command[[i]]) ){
+          add.to.row$command[i] <-
+            paste0(mRule,"\n\\multicolumn{", nCols, "}{l}{",
+                   command[[i]],
+                   "}\\\\\n")
+        } else {
+          add.to.row$command[i] <- paste0(mRule, "\n")
+        }
+      }
+      ## Changed at request of Russ Lenth
+      ## add.to.row$command[1:length(x)] <-
+      ##   paste0(mRule,"\n\\multicolumn{", nCols, "}{l}{", command, "}\\\\\n")
+      
+      if ( (booktabs) & length(attr(x, "message") > 0) ){
+        attr(x, "message")[1] <-
+          paste0("\\rule{0em}{2.5ex}", attr(x, "message")[1])
+      }
+      add.to.row$command[length(x) + 1] <-
+        paste0("\n\\multicolumn{", nCols, "}{l}{",
+               attr(x, "message"), "}\\\\\n",
+               collapse = "")
+      add.to.row$command[length(x) + 1] <-
+        paste0(bRule, add.to.row$command[length(x) + 1])
+
+      class(combined) <- c("xtableList", "data.frame")
+      hline.after <- c(-1)
+      include.colnames <- TRUE
+    }
+
+    ## Create headings for columns if multiple headings are needed
+    if (colnames.format == "multiple"){
+      if (is.null(sanitize.colnames.function)) {
+        colHead <- names(x[[1]])
+      } else {
+        colHead <- sanitize.colnames.function(names(x[[1]]))
+      }
+      if (rotate.colnames) {
+        colHead <- paste("\\begin{sideways}", colHead, "\\end{sideways}")
+      }
+      colHead <- paste0(colHead, collapse = " & ")
+      if (include.rownames) {
+        colHead <- paste0(" & ", colHead)
+      }
+      colHead <- paste0(tRule, "\n", colHead, " \\\\", mRule, "\n")
+      add.to.row <- list(pos = NULL, command = NULL)
+      add.to.row$pos <- as.list(c(0, c(combinedRowNums[1:length(x)])))
+      command <- sapply(x, attr, "subheading")
+
+
+      add.to.row$command[1] <-
+        if( !is.null(command[[1]]) ){
+          add.to.row$command[1] <-
+            paste0("\n\\multicolumn{", nCols, "}{l}{",
+                   command[[1]],
+                   "}\\\\ \n", colHead, "\n")
+        } else {
+          add.to.row$command[1] <- colHead
+        }
+
+      for (i in 2:length(x)) {
+        add.to.row$command[i] <-
+          if( !is.null(command[[i]]) ) {
+            paste0(bRule,
+                   "\\\\ \n\\multicolumn{", nCols, "}{l}{",
+                   command[[i]], "}",
+                   "\\\\ \n",
+                   colHead)
+          } else {
+            add.to.row$command[i] <- paste0("\n", colHead)
+          }
+      }
+      
+      ## Changed at request of Russ Lenth
+      ## add.to.row$command[1] <-
+      ##   paste0("\n\\multicolumn{", nCols, "}{l}{", command[1],
+      ##          "}", " \\\\ \n",
+      ##          colHead)
+      ## add.to.row$command[2:length(x)] <-
+      ##   paste0(bRule,
+      ##          "\\\\ \n\\multicolumn{", nCols, "}{l}{",
+      ##          command[2:length(x)], "}",
+      ##          "\\\\ \n",
+      ##          colHead)
+      if ( (booktabs) & length(attr(x, "message") > 0) ){
+        attr(x, "message")[1] <-
+          paste0("\\rule{0em}{2.5ex}", attr(x, "message")[1])
+      }
+      add.to.row$command[length(x) + 1] <-
+        paste0("\n\\multicolumn{", nCols, "}{l}{",
+               attr(x, "message"), "}\\\\\n",
+               collapse = "")
+      add.to.row$command[length(x) + 1] <-
+        paste0(bRule, add.to.row$command[length(x) + 1])
+
+      class(combined) <- c("xtableList", "data.frame")
+      hline.after <- NULL
+
+      include.colnames <- FALSE
+    }
+
+    print.xtable(combined,
+                 type = type,
+                 floating = floating,
+                 floating.environment = floating.environment,
+                 table.placement = table.placement,
+                 caption.placement = caption.placement,
+                 caption.width = caption.width,
+                 latex.environments = latex.environments,
+                 tabular.environment = tabular.environment,
+                 size = size,
+                 hline.after = hline.after,
+                 NA.string = NA.string,
+                 include.rownames = include.rownames,
+                 include.colnames = include.colnames,
+                 only.contents = only.contents,
+                 add.to.row = add.to.row,
+                 sanitize.text.function = sanitize.text.function,
+                 sanitize.rownames.function = sanitize.rownames.function,
+                 sanitize.colnames.function = sanitize.colnames.function,
+                 math.style.negative = math.style.negative,
+                 math.style.exponents = math.style.exponents,
+                 html.table.attributes = html.table.attributes,
+                 print.results = print.results,
+                 format.args = format.args,
+                 rotate.rownames = rotate.rownames,
+                 rotate.colnames = rotate.colnames,
+                 booktabs = booktabs,
+                 scalebox = scalebox,
+                 width = width,
+                 comment = comment,
+                 timestamp = timestamp,
+                 ...)
+  } else {
+    stop("print.xtableList not yet implemented for this type")
+  }
+}
+
+
+### Uses xtableList
+xtableLSMeans <- function(x, caption = NULL, label = NULL,
+                          align = NULL, digits = NULL,
+                          display = NULL, auto = FALSE,
+                          ...){
+  if (attr(x, "estName") == "lsmean"){
+    xList <- split(x, f = x[, 2])
+    for (i in 1:length(xList)){
+      xList[[i]] <- as.data.frame(xList[[i]][, -2])
+    }
+    attr(xList, "subheadings") <-
+      paste0(dimnames(x)[[2]][2], " = ", levels(x[[2]]))
+    attr(xList, "message") <- c("", attr(x, "mesg"))
+    xList <- xtableList(xList, caption = caption, label = label,
+                        align = align, digits = digits,
+                        display = display, auto = auto, ...)
+  } else {
+    xList <- x
+    xList <- xtable.data.frame(xList, caption = caption, label = label,
+                               align = align, digits = digits,
+                               display = display, auto = auto, ...)
+  }
+  return(xList)
+}
diff --git a/R/xtableMatharray.R b/R/xtableMatharray.R
new file mode 100644
index 0000000..c782f59
--- /dev/null
+++ b/R/xtableMatharray.R
@@ -0,0 +1,36 @@
+### xtableMatharray object
+### To deal with numeric arrays such as a variance-covariance matrix
+### From a request by James Curran, 16 October 2015
+xtableMatharray <- function(x, caption = NULL, label = NULL,
+                            align = NULL, digits = NULL,
+                            display = NULL, auto = FALSE,
+                            ...) {
+  class(x) <- c("xtableMatharray","matrix")
+  xtbl <- xtable.matrix(x,
+                        caption = caption, label = label, align = align,
+                        digits = digits, display = display, auto = auto,
+                        ...)
+  class(xtbl) <- c("xtableMatharray","xtable","data.frame")
+  return(xtbl)
+}
+
+print.xtableMatharray <- function(x,
+           print.results = TRUE,
+           format.args = getOption("xtable.format.args", NULL),
+           scalebox = getOption("xtable.scalebox", NULL),
+           comment = FALSE,
+           timestamp = NULL,
+           ...)
+{
+  class(x) <- c("xtableMatharray","data.frame")
+  print.xtable(x, floating = FALSE,
+               tabular.environment = 'array',
+               include.rownames = FALSE, include.colnames = FALSE,
+               hline.after = NULL,
+               print.results = print.results,
+               format.args = format.args,
+               scalebox = scalebox,
+               comment = comment,
+               timestamp = timestamp,
+               ...)
+}
diff --git a/build/vignette.rds b/build/vignette.rds
index 74f8018..e930820 100644
Binary files a/build/vignette.rds and b/build/vignette.rds differ
diff --git a/data/tli.txt.gz b/data/tli.txt.gz
index 64d5ba5..00aa496 100644
Binary files a/data/tli.txt.gz and b/data/tli.txt.gz differ
diff --git a/inst/doc/OtherPackagesGallery.R b/inst/doc/OtherPackagesGallery.R
new file mode 100644
index 0000000..c9ab777
--- /dev/null
+++ b/inst/doc/OtherPackagesGallery.R
@@ -0,0 +1,153 @@
+## ----set, include=FALSE--------------------------------------------------
+library(knitr)
+opts_chunk$set(fig.path = 'Figures/other', debug = TRUE, echo = TRUE)
+opts_chunk$set(out.width = '0.9\\textwidth')
+
+## ----package, results='asis'------------------------------
+library(xtable)
+options(xtable.floating = FALSE)
+options(xtable.timestamp = "")
+options(width = 60)
+set.seed(1234)
+
+## ----dataspdep--------------------------------------------
+library(spdep)
+data("oldcol", package = "spdep")
+COL.lag.eig <- lagsarlm(CRIME ~ INC + HOVAL, data = COL.OLD[],
+                        nb2listw(COL.nb))
+class(COL.lag.eig)
+COL.errW.GM <- GMerrorsar(CRIME ~ INC + HOVAL, data = COL.OLD,
+                          nb2listw(COL.nb, style = "W"),
+                          returnHcov = TRUE)
+class(COL.errW.GM)
+COL.lag.stsls <- stsls(CRIME ~ INC + HOVAL, data = COL.OLD,
+                       nb2listw(COL.nb))
+class(COL.lag.stsls)
+
+p1 <- predict(COL.lag.eig, newdata = COL.OLD[45:49,],
+              listw = nb2listw(COL.nb))
+class(p1)
+p2 <- predict(COL.lag.eig, newdata = COL.OLD[45:49,],
+              pred.type = "trend", type = "trend")
+#type option for retrocompatibility with spdep 0.5-92
+class(p2)
+
+imp.exact <- impacts(COL.lag.eig, listw = nb2listw(COL.nb))
+class(imp.exact)
+imp.sim <- impacts(COL.lag.eig, listw = nb2listw(COL.nb), R = 200)
+class(imp.sim)
+
+## ----xtablesarlm, results = 'asis'------------------------
+xtable(COL.lag.eig)
+
+## ----xtablesarlmsumm, results = 'asis'--------------------
+xtable(summary(COL.lag.eig, correlation = TRUE))
+
+## ----xtablesarlmbooktabs, results = 'asis'----------------
+print(xtable(COL.lag.eig), booktabs = TRUE)
+
+## ----xtablegmsar, results = 'asis'------------------------
+xtable(COL.errW.GM)
+
+## ----xtablestsls, results = 'asis'------------------------
+xtable(COL.lag.stsls)
+
+## ----xtablesarlmpred, results = 'asis'--------------------
+xtable(p1)
+
+## ----xtablesarlmpred2, results = 'asis'-------------------
+xtable(p2)
+
+## ----xtablelagimpactexact, results = 'asis'---------------
+xtable(imp.exact)
+
+## ----xtablelagimpactmcmc, results = 'asis'----------------
+xtable(imp.sim)
+
+## ----minimalexample, results = 'hide'---------------------
+library(spdep)
+example(NY_data)
+spautolmOBJECT <- spautolm(Z ~ PEXPOSURE + PCTAGE65P,data = nydata,
+                           listw = listw_NY, family = "SAR",
+                           method = "eigen", verbose = TRUE)
+summary(spautolmOBJECT, Nagelkerke = TRUE)
+
+## ----spautolmclass----------------------------------------
+class(spautolmOBJECT)
+
+## ----xtablespautolm, results = 'asis'---------------------
+xtable(spautolmOBJECT,
+       display = c("s",rep("f", 3), "e"), digits = 4)
+
+## ----datasplm---------------------------------------------
+library(splm)
+data("Produc", package = "plm")
+data("usaww",  package = "splm")
+fm <- log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp
+respatlag <- spml(fm, data = Produc, listw = mat2listw(usaww),
+                   model="random", spatial.error="none", lag=TRUE)
+class(respatlag)
+GM <- spgm(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp, data = Produc,
+           listw = usaww, moments = "fullweights", spatial.error = TRUE)
+class(GM)
+
+imp.spml <- impacts(respatlag, listw = mat2listw(usaww, style = "W"), time = 17)
+class(imp.spml)
+
+## ----xtablesplm, results = 'asis'-------------------------
+xtable(respatlag)
+
+## ----xtablesplm1, results = 'asis'------------------------
+xtable(GM)
+
+## ----xtablesplmimpacts, results = 'asis'------------------
+xtable(imp.spml)
+
+## ----datasphet--------------------------------------------
+library(sphet)
+data("columbus", package = "spdep")
+listw <- nb2listw(col.gal.nb)
+data("coldis", package = "sphet")
+res.stsls <- stslshac(CRIME ~ HOVAL + INC, data = columbus, listw = listw,
+                      distance = coldis, type = 'Triangular')
+class(res.stsls)
+
+res.gstsls <- gstslshet(CRIME ~ HOVAL + INC, data = columbus, listw = listw)
+class(res.gstsls)
+
+imp.gstsls <- impacts(res.gstsls, listw = listw)
+class(imp.gstsls)
+
+## ----xtablesphet, results = 'asis'------------------------
+xtable(res.stsls)
+
+## ----xtablesphet1, results = 'asis'-----------------------
+xtable(res.gstsls)
+
+## ----xtablesphetimpacts, results = 'asis'-----------------
+xtable(imp.gstsls)
+
+## ----zoo, results = 'asis'--------------------------------
+library(zoo)
+xDate <- as.Date("2003-02-01") + c(1, 3, 7, 9, 14) - 1
+as.ts(xDate)
+x <- zoo(rnorm(5), xDate)
+xtable(x)
+
+## ----zoots, results = 'asis'------------------------------
+tempTs <- ts(cumsum(1 + round(rnorm(100), 0)),
+              start = c(1954, 7), frequency = 12)
+tempTable <- xtable(tempTs, digits = 0)
+tempTable
+tempZoo <- as.zoo(tempTs)
+xtable(tempZoo, digits = 0)
+
+## ----survival, results = 'asis'---------------------------
+library(survival)
+test1 <- list(time=c(4,3,1,1,2,2,3),
+              status=c(1,1,1,0,1,1,0),
+              x=c(0,2,1,1,1,0,0),
+              sex=c(0,0,0,0,1,1,1))
+coxFit <- coxph(Surv(time, status) ~ x + strata(sex), test1)
+xtable(coxFit)
+
diff --git a/inst/doc/OtherPackagesGallery.Rnw b/inst/doc/OtherPackagesGallery.Rnw
new file mode 100644
index 0000000..ffd5f95
--- /dev/null
+++ b/inst/doc/OtherPackagesGallery.Rnw
@@ -0,0 +1,322 @@
+%\VignetteIndexEntry{xtable List of Tables Gallery}
+%\VignetteDepends{xtable, spdep, splm, sphet}
+%\VignetteKeywords{LaTeX, HTML, table}
+%\VignettePackage{xtable}
+% !Rnw weave = knitr
+% \VignetteEngine{knitr::knitr}
+%**************************************************************************
+\documentclass{article}
+\usepackage[a4paper, height=24cm]{geometry} % geometry first
+\usepackage{array}
+\usepackage{booktabs}
+\usepackage{longtable}
+\usepackage{parskip}
+\usepackage{rotating}
+\usepackage{tabularx}
+\usepackage{titlesec}
+\usepackage{hyperref} % hyperref last
+\titleformat\subsubsection{\bfseries\itshape}{}{0pt}{}
+\newcommand\p{\vspace{2ex}}
+\newcommand\code[1]{\texttt{#1}}
+\newcommand\pkg[1]{\textbf{#1}}
+\setcounter{tocdepth}{2}
+\begin{document}
+
+\title{\bfseries\Large The Other Packages Gallery}
+\author{\bfseries David J. Scott}
+\maketitle
+
+\tableofcontents
+
+\newpage
+
+\section{Introduction}
+This document represents a test of the functions in \pkg{xtable} which
+deal with other packages.
+
+<<set, include=FALSE>>=
+library(knitr)
+opts_chunk$set(fig.path = 'Figures/other', debug = TRUE, echo = TRUE)
+opts_chunk$set(out.width = '0.9\\textwidth')
+@
+
+The first step is to load the package and set some options for this document.
+<<package, results='asis'>>=
+library(xtable)
+options(xtable.floating = FALSE)
+options(xtable.timestamp = "")
+options(width = 60)
+set.seed(1234)
+@
+
+\section{The packages \pkg{spdep}, \pkg{splm}, and \pkg{sphet}}
+
+Code for supporting these packages and most of the examples used in
+this section was originally provided by Martin Gubri
+(\url{martin.gubri at framasoft.org}).
+
+\subsection{The package \pkg{spdep}}
+\label{sec:package-pkgspdep}
+
+First load the package and create some objects.
+<<dataspdep>>=
+library(spdep)
+data("oldcol", package = "spdep")
+COL.lag.eig <- lagsarlm(CRIME ~ INC + HOVAL, data = COL.OLD[],
+                        nb2listw(COL.nb))
+class(COL.lag.eig)
+COL.errW.GM <- GMerrorsar(CRIME ~ INC + HOVAL, data = COL.OLD,
+                          nb2listw(COL.nb, style = "W"),
+                          returnHcov = TRUE)
+class(COL.errW.GM)
+COL.lag.stsls <- stsls(CRIME ~ INC + HOVAL, data = COL.OLD,
+                       nb2listw(COL.nb))
+class(COL.lag.stsls)
+
+p1 <- predict(COL.lag.eig, newdata = COL.OLD[45:49,],
+              listw = nb2listw(COL.nb))
+class(p1)
+p2 <- predict(COL.lag.eig, newdata = COL.OLD[45:49,],
+              pred.type = "trend", type = "trend")
+#type option for retrocompatibility with spdep 0.5-92
+class(p2)
+
+imp.exact <- impacts(COL.lag.eig, listw = nb2listw(COL.nb))
+class(imp.exact)
+imp.sim <- impacts(COL.lag.eig, listw = nb2listw(COL.nb), R = 200)
+class(imp.sim)
+@ %def
+
+
+\subsubsection{\code{sarlm} objects}
+\label{sec:codesarlm-objects}
+
+There is an \code{xtable} method for objects of this type.
+<<xtablesarlm, results = 'asis'>>=
+xtable(COL.lag.eig)
+@ %def
+
+The method for \code{xtable} actually uses the summary of the object,
+and an identical result is obtained when using the summary of the
+object, even if the summary contains more additional information.
+
+<<xtablesarlmsumm, results = 'asis'>>=
+xtable(summary(COL.lag.eig, correlation = TRUE))
+@ %def
+
+This same pattern applies to the other objects from this group of packages.
+
+Note that additional prettying of the resulting table is possible, as
+for any table produced using \code{xtable}. For example using the
+\pkg{booktabs} package we get:
+
+<<xtablesarlmbooktabs, results = 'asis'>>=
+print(xtable(COL.lag.eig), booktabs = TRUE)
+@ %def
+
+\subsubsection{\code{gmsar} objects}
+\label{sec:codegmsar-objects}
+
+
+<<xtablegmsar, results = 'asis'>>=
+xtable(COL.errW.GM)
+@ %def
+
+\subsubsection{\code{stsls} objects}
+\label{sec:codestsls-objects}
+
+
+<<xtablestsls, results = 'asis'>>=
+xtable(COL.lag.stsls)
+@ %def
+
+\subsubsection{\code{sarlm.pred} objects}
+\label{sec:codesarlmpred-objects}
+
+\code{xtable} has a method for predictions of \code{sarlm} models.
+
+<<xtablesarlmpred, results = 'asis'>>=
+xtable(p1)
+@ %def
+
+This method transforms the \code{sarlm.pred} objects into data frames,
+allowing any number of attributes vectors which may vary according to
+predictor types.
+
+<<xtablesarlmpred2, results = 'asis'>>=
+xtable(p2)
+@ %def
+
+\subsubsection{\code{lagImpact} objects}
+\label{sec:codelagimpact-objects}
+
+The \code{xtable} method returns the values of direct, indirect and
+total impacts for all the variables in the model. The class
+\code{lagImpact} has two different sets of attributes according to if
+simulations are used. But the \code{xtable} method always returns the
+three components of the non-simulation case.
+
+<<xtablelagimpactexact, results = 'asis'>>=
+xtable(imp.exact)
+@ %def
+
+\p
+<<xtablelagimpactmcmc, results = 'asis'>>=
+xtable(imp.sim)
+@ %def
+
+
+\subsubsection{\code{spautolm} objects}
+\label{sec:codespautolm-objects}
+
+The need for an \code{xtable} method for \code{spautolm} was expressed
+by Guido Schulz (\url{schulzgu at student.hu-berlin.de}), who also
+provided an example of an object of this type. The required code was
+implemented by David Scott (\url{d.scott at auckland.ac.nz}).
+
+First create an object of the required type.
+
+<<minimalexample, results = 'hide'>>=
+library(spdep)
+example(NY_data)
+spautolmOBJECT <- spautolm(Z ~ PEXPOSURE + PCTAGE65P,data = nydata,
+                           listw = listw_NY, family = "SAR",
+                           method = "eigen", verbose = TRUE)
+summary(spautolmOBJECT, Nagelkerke = TRUE)
+@ %def
+
+\p
+<<spautolmclass>>=
+class(spautolmOBJECT)
+@ %def
+
+
+<<xtablespautolm, results = 'asis'>>=
+xtable(spautolmOBJECT,
+       display = c("s",rep("f", 3), "e"), digits = 4)
+@ %def
+
+
+
+\subsection{The package \pkg{splm}}
+\label{sec:package-pkgsplm}
+
+First load the package and create some objects.
+<<datasplm>>=
+library(splm)
+data("Produc", package = "plm")
+data("usaww",  package = "splm")
+fm <- log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp
+respatlag <- spml(fm, data = Produc, listw = mat2listw(usaww),
+                   model="random", spatial.error="none", lag=TRUE)
+class(respatlag)
+GM <- spgm(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp, data = Produc,
+           listw = usaww, moments = "fullweights", spatial.error = TRUE)
+class(GM)
+
+imp.spml <- impacts(respatlag, listw = mat2listw(usaww, style = "W"), time = 17)
+class(imp.spml)
+@ %def
+
+
+\subsubsection{\code{splm} objects}
+\label{sec:codesplm-objects}
+
+<<xtablesplm, results = 'asis'>>=
+xtable(respatlag)
+@ %def
+
+
+\p
+<<xtablesplm1, results = 'asis'>>=
+xtable(GM)
+@ %def
+
+
+
+The \code{xtable} method works the same on impacts of \code{splm} models.
+
+<<xtablesplmimpacts, results = 'asis'>>=
+xtable(imp.spml)
+@ %def
+
+\subsection{The package \pkg{sphet}}
+\label{sec:package-pkgsphet}
+
+First load the package and create some objects.
+<<datasphet>>=
+library(sphet)
+data("columbus", package = "spdep")
+listw <- nb2listw(col.gal.nb)
+data("coldis", package = "sphet")
+res.stsls <- stslshac(CRIME ~ HOVAL + INC, data = columbus, listw = listw,
+                      distance = coldis, type = 'Triangular')
+class(res.stsls)
+
+res.gstsls <- gstslshet(CRIME ~ HOVAL + INC, data = columbus, listw = listw)
+class(res.gstsls)
+
+imp.gstsls <- impacts(res.gstsls, listw = listw)
+class(imp.gstsls)
+@ %def
+
+
+\subsubsection{\code{sphet} objects}
+\label{sec:codesphet-objects}
+
+<<xtablesphet, results = 'asis'>>=
+xtable(res.stsls)
+@ %def
+
+\p
+<<xtablesphet1, results = 'asis'>>=
+xtable(res.gstsls)
+@ %def
+
+
+\code{sphet} also provides a method for computing impacts.
+
+<<xtablesphetimpacts, results = 'asis'>>=
+xtable(imp.gstsls)
+@ %def
+
+\section{The \pkg{zoo} package}
+\label{sec:pkgzoo-package}
+
+
+<<zoo, results = 'asis'>>=
+library(zoo)
+xDate <- as.Date("2003-02-01") + c(1, 3, 7, 9, 14) - 1
+as.ts(xDate)
+x <- zoo(rnorm(5), xDate)
+xtable(x)
+@ %def
+
+
+\p
+
+<<zoots, results = 'asis'>>=
+tempTs <- ts(cumsum(1 + round(rnorm(100), 0)),
+              start = c(1954, 7), frequency = 12)
+tempTable <- xtable(tempTs, digits = 0)
+tempTable
+tempZoo <- as.zoo(tempTs)
+xtable(tempZoo, digits = 0)
+@ %def
+
+
+\section{The \pkg{survival} package}
+\label{sec:pkgsurvival-package}
+
+
+<<survival, results = 'asis'>>=
+library(survival)
+test1 <- list(time=c(4,3,1,1,2,2,3),
+              status=c(1,1,1,0,1,1,0),
+              x=c(0,2,1,1,1,0,0),
+              sex=c(0,0,0,0,1,1,1))
+coxFit <- coxph(Surv(time, status) ~ x + strata(sex), test1)
+xtable(coxFit)
+@ %def
+
+\end{document}
diff --git a/inst/doc/OtherPackagesGallery.pdf b/inst/doc/OtherPackagesGallery.pdf
new file mode 100644
index 0000000..91ba579
Binary files /dev/null and b/inst/doc/OtherPackagesGallery.pdf differ
diff --git a/inst/doc/listOfTablesGallery.R b/inst/doc/listOfTablesGallery.R
new file mode 100644
index 0000000..55269ed
--- /dev/null
+++ b/inst/doc/listOfTablesGallery.R
@@ -0,0 +1,144 @@
+## ----set, include=FALSE--------------------------------------------------
+library(knitr)
+opts_chunk$set(fig.path='Figures/list', debug=TRUE, echo=TRUE)
+opts_chunk$set(out.width='0.9\\textwidth')
+
+## ----package, results='asis'------------------------------
+library(xtable)
+options(xtable.floating = FALSE)
+options(xtable.timestamp = "")
+options(width = 60)
+
+## ----data-------------------------------------------------
+require(xtable)
+data(mtcars)
+mtcars <- mtcars[, 1:6]
+mtcarsList <- split(mtcars, f = mtcars$cyl)
+### Reduce the size of the list elements
+mtcarsList[[1]] <- mtcarsList[[1]][1,]
+mtcarsList[[2]] <- mtcarsList[[2]][1:2,]
+mtcarsList[[3]] <- mtcarsList[[3]][1:3,]
+attr(mtcarsList, "subheadings") <- paste0("Number of cylinders = ",
+                                          names(mtcarsList))
+attr(mtcarsList, "message") <- c("Line 1 of Message",
+                                 "Line 2 of Message")
+str(mtcarsList)
+attributes(mtcarsList)
+
+## ----xtablelist-------------------------------------------
+xList <- xtableList(mtcarsList)
+str(xList)
+
+## ----xtablelist1------------------------------------------
+xList1 <- xtableList(mtcarsList, digits = c(0,2,0,0,0,1,2))
+str(xList1)
+
+## ----xtablelist2------------------------------------------
+xList2 <- xtableList(mtcarsList, digits = c(0,2,0,0,0,1,2),
+                            caption = "Caption to List",
+                            label = "tbl:xtableList")
+str(xList2)
+
+## ----xtablelist3------------------------------------------
+attr(mtcarsList, "subheadings") <- NULL
+xList3 <- xtableList(mtcarsList)
+str(xList3)
+
+## ----xtablelist4------------------------------------------
+attr(mtcarsList, "message") <- NULL
+xList4 <- xtableList(mtcarsList)
+str(xList4)
+
+## ----singledefault, results='asis'------------------------
+print.xtableList(xList)
+
+## ----singlebooktabs, results='asis'-----------------------
+print.xtableList(xList, booktabs = TRUE)
+
+## ----singlebooktabs1, results='asis'----------------------
+print.xtableList(xList1, booktabs = TRUE)
+
+## ----sanitize---------------------------------------------
+large <- function(x){
+  paste0('{\\Large{\\bfseries ', x, '}}')
+}
+italic <- function(x){
+  paste0('{\\emph{ ', x, '}}')
+}
+bold <- function(x){
+  paste0('{\\bfseries ', x, '}')
+}
+red <- function(x){
+  paste0('{\\color{red} ', x, '}')
+}
+
+## ----sanitizesingle, results='asis'-----------------------
+print.xtableList(xList,
+                 sanitize.rownames.function = italic,
+                 sanitize.colnames.function = large,
+                 sanitize.subheadings.function = bold,
+                 sanitize.message.function = red,
+                 booktabs = TRUE)
+
+## ----singlecaption, results='asis'------------------------
+print.xtableList(xList2, floating = TRUE)
+
+## ----singlerotated, results='asis'------------------------
+print.xtableList(xList, rotate.colnames = TRUE)
+
+## ----nosubheadings, results='asis'------------------------
+print.xtableList(xList3)
+
+## ----nomessage, results='asis'----------------------------
+print.xtableList(xList4)
+
+## ----multipledefault, results='asis'----------------------
+print.xtableList(xList, colnames.format = "multiple")
+
+## ----multiplebooktabs, results='asis'---------------------
+print.xtableList(xList, colnames.format = "multiple",
+                 booktabs = TRUE)
+
+## ----sanitizemultiple, results='asis'---------------------
+print.xtableList(xList, colnames.format = "multiple",
+                 sanitize.rownames.function = italic,
+                 sanitize.colnames.function = large,
+                 sanitize.subheadings.function = bold,
+                 sanitize.message.function = red,                 
+                 booktabs = TRUE)
+
+## ----multiplecaption, results='asis'----------------------
+print.xtableList(xList2, colnames.format = "multiple",
+                 floating = TRUE)
+
+## ----multiplerotated, results='asis'----------------------
+print.xtableList(xList, colnames.format = "multiple",
+                 rotate.colnames = TRUE)
+
+## ----multiplenosubheadings, results='asis'----------------
+print.xtableList(xList3, colnames.format = "multiple")
+
+## ----multiplenomessage, results='asis'--------------------
+print.xtableList(xList4, colnames.format = "multiple")
+
+## ----lsmeans----------------------------------------------
+library(lsmeans)
+warp.lm <- lm(breaks ~ wool*tension, data = warpbreaks)
+warp.lsm <- lsmeans(warp.lm, ~ tension | wool)
+warp.sum <- summary(warp.lsm, adjust = "mvt")
+warp.xtblList <- xtableLSMeans(warp.sum, digits = c(0,0,2,2,0,2,2))
+str(warp.xtblList)
+
+## ----lsmeansstr-------------------------------------------
+print.xtableList(warp.xtblList, colnames.format = "multiple",
+                 include.rownames = FALSE)
+
+## ----lsmeanstable, results='asis'-------------------------
+print.xtableList(warp.xtblList, colnames.format = "multiple",
+                 include.rownames = FALSE)
+
+## ----lsmeansbooktabs, results='asis'----------------------
+print.xtableList(warp.xtblList, colnames.format = "multiple",
+                 booktabs = TRUE,
+                 include.rownames = FALSE)
+
diff --git a/inst/doc/listOfTablesGallery.Rnw b/inst/doc/listOfTablesGallery.Rnw
new file mode 100644
index 0000000..5d20236
--- /dev/null
+++ b/inst/doc/listOfTablesGallery.Rnw
@@ -0,0 +1,267 @@
+%\VignetteIndexEntry{xtable List of Tables Gallery}
+%\VignetteDepends{xtable, lsmeans}
+%\VignetteKeywords{LaTeX, HTML, table}
+%\VignettePackage{xtable}
+% !Rnw weave = knitr
+% \VignetteEngine{knitr::knitr}
+%**************************************************************************
+\documentclass{article}
+\usepackage[a4paper,height=24cm]{geometry} % geometry first
+\usepackage{array}
+\usepackage{booktabs}
+\usepackage{longtable}
+\usepackage{parskip}
+\usepackage{rotating}
+\usepackage{tabularx}
+\usepackage{titlesec}
+\usepackage{hyperref} % hyperref last
+\titleformat\subsubsection{\bfseries\itshape}{}{0pt}{}
+\newcommand\p{\vspace{2ex}}
+\newcommand\code[1]{\texttt{#1}}
+\newcommand\pkg[1]{\textbf{#1}}
+\setcounter{tocdepth}{2}
+\begin{document}
+
+\title{\bfseries\Large The \code{xtableList} Gallery}
+\author{\bfseries David J. Scott}
+\maketitle
+
+\tableofcontents
+
+\newpage
+
+\section{Introduction}
+This document represents a test of the functions in \pkg{xtable} which
+deal with lists of dataframes.
+
+<<set, include=FALSE>>=
+library(knitr)
+opts_chunk$set(fig.path='Figures/list', debug=TRUE, echo=TRUE)
+opts_chunk$set(out.width='0.9\\textwidth')
+@
+
+The first step is to load the package and set some options for this document.
+<<package, results='asis'>>=
+library(xtable)
+options(xtable.floating = FALSE)
+options(xtable.timestamp = "")
+options(width = 60)
+@
+
+
+Next we create a list of dataframes with attributes.
+
+<<data>>=
+require(xtable)
+data(mtcars)
+mtcars <- mtcars[, 1:6]
+mtcarsList <- split(mtcars, f = mtcars$cyl)
+### Reduce the size of the list elements
+mtcarsList[[1]] <- mtcarsList[[1]][1,]
+mtcarsList[[2]] <- mtcarsList[[2]][1:2,]
+mtcarsList[[3]] <- mtcarsList[[3]][1:3,]
+attr(mtcarsList, "subheadings") <- paste0("Number of cylinders = ",
+                                          names(mtcarsList))
+attr(mtcarsList, "message") <- c("Line 1 of Message",
+                                 "Line 2 of Message")
+str(mtcarsList)
+attributes(mtcarsList)
+@ %def
+
+Now create a list of \code{xtable} objects.
+
+
+<<xtablelist>>=
+xList <- xtableList(mtcarsList)
+str(xList)
+@ %def
+
+Create an alternative version where the lists have different values
+for \code{digits}.
+
+
+<<xtablelist1>>=
+xList1 <- xtableList(mtcarsList, digits = c(0,2,0,0,0,1,2))
+str(xList1)
+@ %def
+
+<<xtablelist2>>=
+xList2 <- xtableList(mtcarsList, digits = c(0,2,0,0,0,1,2),
+                            caption = "Caption to List",
+                            label = "tbl:xtableList")
+str(xList2)
+@ %def
+
+Further versions with no subheadings, and no message
+
+<<xtablelist3>>=
+attr(mtcarsList, "subheadings") <- NULL
+xList3 <- xtableList(mtcarsList)
+str(xList3)
+@ %def
+
+<<xtablelist4>>=
+attr(mtcarsList, "message") <- NULL
+xList4 <- xtableList(mtcarsList)
+str(xList4)
+@ %def
+
+\newpage
+
+\section{Single Column Names}
+\label{sec:single-column-names}
+
+Print the list of \code{xtable} objects with a single header of the
+column names.
+
+First the default.
+
+
+<<singledefault, results='asis'>>=
+print.xtableList(xList)
+@ %def
+
+Booktabs should work.
+<<singlebooktabs, results='asis'>>=
+print.xtableList(xList, booktabs = TRUE)
+@ %def
+
+With digits being specified.
+<<singlebooktabs1, results='asis'>>=
+print.xtableList(xList1, booktabs = TRUE)
+@ %def
+
+Row and column names, subheadings, and the message can be sanitized.
+
+<<sanitize>>=
+large <- function(x){
+  paste0('{\\Large{\\bfseries ', x, '}}')
+}
+italic <- function(x){
+  paste0('{\\emph{ ', x, '}}')
+}
+bold <- function(x){
+  paste0('{\\bfseries ', x, '}')
+}
+red <- function(x){
+  paste0('{\\color{red} ', x, '}')
+}
+@ %def
+
+
+<<sanitizesingle, results='asis'>>=
+print.xtableList(xList,
+                 sanitize.rownames.function = italic,
+                 sanitize.colnames.function = large,
+                 sanitize.subheadings.function = bold,
+                 sanitize.message.function = red,
+                 booktabs = TRUE)
+@ %def
+
+A label and caption can be added.
+<<singlecaption, results='asis'>>=
+print.xtableList(xList2, floating = TRUE)
+@ %def
+
+Rotated column names?
+<<singlerotated, results='asis'>>=
+print.xtableList(xList, rotate.colnames = TRUE)
+@ %def
+
+No subheadings?
+<<nosubheadings, results='asis'>>=
+print.xtableList(xList3)
+@ %def
+
+No message?
+<<nomessage, results='asis'>>=
+print.xtableList(xList4)
+@ %def
+
+
+\section{Multiple Column Names}
+\label{sec:multiple-column-names}
+
+Print the list of \code{xtable} objects with multiple headers of the
+column names.
+
+First the default with multiple column name headers.
+
+<<multipledefault, results='asis'>>=
+print.xtableList(xList, colnames.format = "multiple")
+@ %def
+
+Using booktabs:
+
+<<multiplebooktabs, results='asis'>>=
+print.xtableList(xList, colnames.format = "multiple",
+                 booktabs = TRUE)
+@ %def
+
+With sanitization.
+<<sanitizemultiple, results='asis'>>=
+print.xtableList(xList, colnames.format = "multiple",
+                 sanitize.rownames.function = italic,
+                 sanitize.colnames.function = large,
+                 sanitize.subheadings.function = bold,
+                 sanitize.message.function = red,                 
+                 booktabs = TRUE)
+@ %def
+
+A label and caption can be added.
+<<multiplecaption, results='asis'>>=
+print.xtableList(xList2, colnames.format = "multiple",
+                 floating = TRUE)
+@ %def
+
+Rotated column names?
+<<multiplerotated, results='asis'>>=
+print.xtableList(xList, colnames.format = "multiple",
+                 rotate.colnames = TRUE)
+@ %def
+
+No subheadings?
+<<multiplenosubheadings, results='asis'>>=
+print.xtableList(xList3, colnames.format = "multiple")
+@ %def
+
+No message?
+<<multiplenomessage, results='asis'>>=
+print.xtableList(xList4, colnames.format = "multiple")
+@ %def
+
+\section{lsmeans}
+\label{sec:lsmeans}
+
+Summaries from the \code{lsmeans} function from the \pkg{lsmeans}
+package can easily be produced using the function
+\code{xtableLSMeans}. This function produces a list of \pkg{xtable}
+objects.
+
+
+<<lsmeans>>=
+library(lsmeans)
+warp.lm <- lm(breaks ~ wool*tension, data = warpbreaks)
+warp.lsm <- lsmeans(warp.lm, ~ tension | wool)
+warp.sum <- summary(warp.lsm, adjust = "mvt")
+warp.xtblList <- xtableLSMeans(warp.sum, digits = c(0,0,2,2,0,2,2))
+str(warp.xtblList)
+@ %def
+
+<<lsmeansstr>>=
+print.xtableList(warp.xtblList, colnames.format = "multiple",
+                 include.rownames = FALSE)
+@ %def
+<<lsmeanstable, results='asis'>>=
+print.xtableList(warp.xtblList, colnames.format = "multiple",
+                 include.rownames = FALSE)
+@ %def
+\p
+<<lsmeansbooktabs, results='asis'>>=
+print.xtableList(warp.xtblList, colnames.format = "multiple",
+                 booktabs = TRUE,
+                 include.rownames = FALSE)
+@ %def
+
+
+\end{document}
diff --git a/inst/doc/listOfTablesGallery.pdf b/inst/doc/listOfTablesGallery.pdf
new file mode 100644
index 0000000..4a80e24
Binary files /dev/null and b/inst/doc/listOfTablesGallery.pdf differ
diff --git a/inst/doc/margintable.R b/inst/doc/margintable.R
index b4374a9..5cf608a 100644
--- a/inst/doc/margintable.R
+++ b/inst/doc/margintable.R
@@ -1,18 +1,13 @@
-### R code from vignette source 'margintable.Rnw'
-
-###################################################
-### code chunk number 1: margintable.Rnw:52-55
-###################################################
-library(xtable)
-x <- matrix(rnorm(6), ncol = 2)
-x.small <- xtable(x, label = 'tabsmall', caption = 'A margin table')
-
-
-###################################################
-### code chunk number 2: margintable.Rnw:58-61
-###################################################
-print(x.small,floating.environment='margintable',
-      latex.environments = "",
-      table.placement = NULL)
-
-
+## ----include=FALSE-------------------------------------------------------
+library(knitr)
+
+## ------------------------------------------------------------------------
+library(xtable)
+x <- matrix(rnorm(6), ncol = 2)
+x.small <- xtable(x, label = 'tabsmall', caption = 'A margin table')
+
+## ----results='asis'------------------------------------------------------
+print(x.small,floating.environment='margintable',
+      latex.environments = "",
+      table.placement = NULL)
+
diff --git a/inst/doc/margintable.Rnw b/inst/doc/margintable.Rnw
index b12c583..cf4fd4b 100644
--- a/inst/doc/margintable.Rnw
+++ b/inst/doc/margintable.Rnw
@@ -1,6 +1,7 @@
 %\VignetteIndexEntry{xtable margintable}
 %\VignetteKeywords{LaTeX, HTML, table, margintable}
-
+% !Rnw weave = knitr
+% \VignetteEngine{knitr::knitr}
 
 \documentclass{tufte-handout}
 
@@ -10,8 +11,12 @@ A Margin Table Example
 }
 \author{David J. Scott}
 
-\usepackage{Sweave}
-\SweaveOpts{prefix.string=figdir/fig,debug=TRUE,eps=FALSE,echo=TRUE}
+
+
+<<include=FALSE>>=
+library(knitr)
+@
+
 \usepackage{rotating}
 \usepackage{longtable}
 \usepackage{booktabs}
@@ -55,7 +60,7 @@ x <- matrix(rnorm(6), ncol = 2)
 x.small <- xtable(x, label = 'tabsmall', caption = 'A margin table')
 @
 
-<<results=tex>>=
+<<results='asis'>>=
 print(x.small,floating.environment='margintable',
       latex.environments = "",
       table.placement = NULL)
diff --git a/inst/doc/margintable.pdf b/inst/doc/margintable.pdf
index 4df077b..2c2c1fc 100644
Binary files a/inst/doc/margintable.pdf and b/inst/doc/margintable.pdf differ
diff --git a/inst/doc/xtableGallery.R b/inst/doc/xtableGallery.R
index cbd5474..03f3bee 100644
--- a/inst/doc/xtableGallery.R
+++ b/inst/doc/xtableGallery.R
@@ -1,583 +1,361 @@
-### R code from vignette source 'xtableGallery.snw'
-
-###################################################
-### code chunk number 1: xtableGallery.snw:14-20 (eval = FALSE)
-###################################################
-## makeme <- function() {
-## 	# I am a convenience function for debugging and can be ignored
-## 	setwd("C:/JonathanSwinton/PathwayModeling/src/R/SourcePackages/xtable/inst/doc")
-## 	Sweave("xtableGallery.RnW",stylepath=FALSE)
-## }
-## makeme()
-
-
-###################################################
-### code chunk number 2: xtableGallery.snw:45-46
-###################################################
-library(xtable)
-
-
-###################################################
-### code chunk number 3: xtableGallery.snw:52-57
-###################################################
-data(tli)
-
-## Demonstrate data.frame
-tli.table <- xtable(tli[1:10,])
-digits(tli.table)[c(2,6)] <- 0
-
-
-###################################################
-### code chunk number 4: xtableGallery.snw:59-60
-###################################################
-print(tli.table,floating=FALSE)
-
-
-###################################################
-### code chunk number 5: xtableGallery.snw:64-66
-###################################################
-design.matrix <- model.matrix(~ sex*grade, data=tli[1:10,])
-design.table <- xtable(design.matrix)
-
-
-###################################################
-### code chunk number 6: xtableGallery.snw:68-69
-###################################################
-print(design.table,floating=FALSE)
-
-
-###################################################
-### code chunk number 7: xtableGallery.snw:73-75
-###################################################
-fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data=tli)
-fm1.table <- xtable(fm1)
-
-
-###################################################
-### code chunk number 8: xtableGallery.snw:77-78
-###################################################
-print(fm1.table,floating=FALSE)
-
-
-###################################################
-### code chunk number 9: xtableGallery.snw:81-83
-###################################################
-fm2 <- lm(tlimth ~ sex*ethnicty, data=tli)
-fm2.table <- xtable(fm2)
-
-
-###################################################
-### code chunk number 10: xtableGallery.snw:85-86
-###################################################
-print(fm2.table,floating=FALSE)
-
-
-###################################################
-### code chunk number 11: xtableGallery.snw:90-91
-###################################################
-print(xtable(anova(fm2)),floating=FALSE)
-
-
-###################################################
-### code chunk number 12: xtableGallery.snw:94-95
-###################################################
-fm2b <- lm(tlimth ~ ethnicty, data=tli)
-
-
-###################################################
-### code chunk number 13: xtableGallery.snw:97-98
-###################################################
-print(xtable(anova(fm2b,fm2)),floating=FALSE)
-
-
-###################################################
-### code chunk number 14: xtableGallery.snw:104-108
-###################################################
-
-## Demonstrate glm
-fm3 <- glm(disadvg ~ ethnicty*grade, data=tli, family=binomial())
-fm3.table <- xtable(fm3)
-
-
-###################################################
-### code chunk number 15: xtableGallery.snw:110-111
-###################################################
-print(fm3.table,floating=FALSE)
-
-
-###################################################
-### code chunk number 16: xtableGallery.snw:116-117
-###################################################
-print(xtable(anova(fm3)),floating=FALSE)
-
-
-###################################################
-### code chunk number 17: xtableGallery.snw:122-137
-###################################################
-
-## Demonstrate aov
-## Taken from help(aov) in R 1.1.1
-## From Venables and Ripley (1997) p.210.
-N <- c(0,1,0,1,1,1,0,0,0,1,1,0,1,1,0,0,1,0,1,0,1,1,0,0)
-P <- c(1,1,0,0,0,1,0,1,1,1,0,0,0,1,0,1,1,0,0,1,0,1,1,0)
-K <- c(1,0,0,1,0,1,1,0,0,1,0,1,0,1,1,0,0,0,1,1,1,0,1,0)
-yield <- c(49.5,62.8,46.8,57.0,59.8,58.5,55.5,56.0,62.8,55.8,69.5,55.0,
-           62.0,48.8,45.5,44.2,52.0,51.5,49.8,48.8,57.2,59.0,53.2,56.0)
-npk <- data.frame(block=gl(6,4), N=factor(N), P=factor(P), K=factor(K), yield=yield)
-npk.aov <- aov(yield ~ block + N*P*K, npk)
-op <- options(contrasts=c("contr.helmert", "contr.treatment"))
-npk.aovE <- aov(yield ~  N*P*K + Error(block), npk)
-options(op)
-#summary(npk.aov)
-
-
-###################################################
-### code chunk number 18: xtableGallery.snw:139-140
-###################################################
-print(xtable(npk.aov),floating=FALSE)
-
-
-###################################################
-### code chunk number 19: xtableGallery.snw:144-145
-###################################################
-print(xtable(anova(npk.aov)),floating=FALSE)
-
-
-###################################################
-### code chunk number 20: xtableGallery.snw:149-150
-###################################################
-print(xtable(summary(npk.aov)),floating=FALSE)
-
-
-###################################################
-### code chunk number 21: xtableGallery.snw:153-154
-###################################################
-#summary(npk.aovE)
-
-
-###################################################
-### code chunk number 22: xtableGallery.snw:156-157
-###################################################
-print(xtable(npk.aovE),floating=FALSE)
-
-
-###################################################
-### code chunk number 23: xtableGallery.snw:161-162
-###################################################
-print(xtable(summary(npk.aovE)),floating=FALSE)
-
-
-###################################################
-### code chunk number 24: xtableGallery.snw:166-176
-###################################################
-
-## Demonstrate lm
-## Taken from help(lm) in R 1.1.1
-## Annette Dobson (1990) "An Introduction to Generalized Linear Models".
-## Page 9: Plant Weight Data.
-ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
-trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
-group <- gl(2,10,20, labels=c("Ctl","Trt"))
-weight <- c(ctl, trt)
-lm.D9 <- lm(weight ~ group)
-
-
-###################################################
-### code chunk number 25: xtableGallery.snw:178-179
-###################################################
-print(xtable(lm.D9),floating=FALSE)
-
-
-###################################################
-### code chunk number 26: xtableGallery.snw:183-184
-###################################################
-print(xtable(anova(lm.D9)),floating=FALSE)
-
-
-###################################################
-### code chunk number 27: xtableGallery.snw:188-198
-###################################################
-
-## Demonstrate glm
-## Taken from help(glm) in R 1.1.1
-## Annette Dobson (1990) "An Introduction to Generalized Linear Models".
-## Page 93: Randomized Controlled Trial :
-counts <- c(18,17,15,20,10,20,25,13,12)
-outcome <- gl(3,1,9)
-treatment <- gl(3,3)
-d.AD <- data.frame(treatment, outcome, counts)
-glm.D93 <- glm(counts ~ outcome + treatment, family=poisson())
-
-
-###################################################
-### code chunk number 28: xtableGallery.snw:200-201
-###################################################
-print(xtable(glm.D93,align="r|llrc"),floating=FALSE)
-
-
-###################################################
-### code chunk number 29: prcomp
-###################################################
-if(require(stats,quietly=TRUE)) {
-  ## Demonstrate prcomp
-  ## Taken from help(prcomp) in mva package of R 1.1.1
-  data(USArrests)
-  pr1 <- prcomp(USArrests)
-}
-
-
-###################################################
-### code chunk number 30: xtableGallery.snw:213-216
-###################################################
-if(require(stats,quietly=TRUE)) {
-  print(xtable(pr1),floating=FALSE)
-}
-
-
-###################################################
-### code chunk number 31: xtableGallery.snw:221-222
-###################################################
-  print(xtable(summary(pr1)),floating=FALSE)
-
-
-###################################################
-### code chunk number 32: xtableGallery.snw:227-231
-###################################################
-#  ## Demonstrate princomp
-#  ## Taken from help(princomp) in mva package of R 1.1.1
-#  pr2 <- princomp(USArrests)
-#  print(xtable(pr2))
-
-
-###################################################
-### code chunk number 33: xtableGallery.snw:235-238
-###################################################
-temp.ts <- ts(cumsum(1+round(rnorm(100), 0)), start = c(1954, 7), frequency=12)
-   temp.table <- xtable(temp.ts,digits=0)
-    caption(temp.table) <- "Time series example"
-
-
-###################################################
-### code chunk number 34: xtableGallery.snw:240-241
-###################################################
-    print(temp.table,floating=FALSE)
-
-
-###################################################
-### code chunk number 35: savetofile
-###################################################
-if (FALSE) {
-  for(i in c("latex","html")) {
-    outFileName <- paste("xtable.",ifelse(i=="latex","tex",i),sep="")
-    print(xtable(lm.D9),type=i,file=outFileName,append=TRUE,latex.environments=NULL)
-    print(xtable(lm.D9),type=i,file=outFileName,append=TRUE,latex.environments="")
-    print(xtable(lm.D9),type=i,file=outFileName,append=TRUE,latex.environments="center")
-    print(xtable(anova(glm.D93,test="Chisq")),type=i,file=outFileName,append=TRUE)
-    print(xtable(anova(glm.D93)),hline.after=c(1),size="small",type=i,file=outFileName,append=TRUE)
-      # print(xtable(pr2),type=i,file=outFileName,append=TRUE)
-         }
-}
-
-
-###################################################
-### code chunk number 36: xtableGallery.snw:258-261
-###################################################
-insane <- data.frame(Name=c("Ampersand","Greater than","Less than","Underscore","Per cent","Dollar","Backslash","Hash", "Caret", "Tilde","Left brace","Right brace"),
-				Character = I(c("&",">",		"<",		"_",		"%",		"$",		"\\", "#",	"^",		"~","{","}")))
-colnames(insane)[2] <- paste(insane[,2],collapse="")
-
-
-###################################################
-### code chunk number 37: pxti
-###################################################
-print( xtable(insane))
-
-
-###################################################
-### code chunk number 38: xtableGallery.snw:268-269
-###################################################
-wanttex <- xtable(data.frame( label=paste("Value_is $10^{-",1:3,"}$",sep="")))
-
-
-###################################################
-### code chunk number 39: xtableGallery.snw:271-272
-###################################################
-print(wanttex,sanitize.text.function=function(str)gsub("_","\\_",str,fixed=TRUE))
-
-
-###################################################
-### code chunk number 40: xtableGallery.snw:279-283
-###################################################
-mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4)
-rownames(mat) <- "$y_{t-1}$"
-colnames(mat) <- c("$R^2$", "$\\bar{R}^2$", "F-stat", "S.E.E", "DW")
-mat <- xtable(mat)
-
-
-###################################################
-### code chunk number 41: xtableGallery.snw:285-286
-###################################################
-print(mat, sanitize.text.function = function(x){x})
-
-
-###################################################
-### code chunk number 42: xtableGallery.snw:291-292
-###################################################
-money <- matrix(c("$1,000","$900","$100"),ncol=3,dimnames=list("$\\alpha$",c("Income (US$)","Expenses (US$)","Profit (US$)")))
-
-
-###################################################
-### code chunk number 43: xtableGallery.snw:294-295
-###################################################
-print(xtable(money),sanitize.rownames.function=function(x) {x})
-
-
-###################################################
-### code chunk number 44: xtableGallery.snw:300-303
-###################################################
-   print(xtable(lm.D9,caption="\\tt latex.environments=NULL"),latex.environments=NULL)
-    print(xtable(lm.D9,caption="\\tt latex.environments=\"\""),latex.environments="")
-    print(xtable(lm.D9,caption="\\tt latex.environments=\"center\""),latex.environments="center")
-
-
-###################################################
-### code chunk number 45: xtableGallery.snw:307-308
-###################################################
-tli.table <- xtable(tli[1:10,])
-
-
-###################################################
-### code chunk number 46: xtableGallery.snw:310-311
-###################################################
-align(tli.table) <- rep("r",6)
-
-
-###################################################
-### code chunk number 47: xtableGallery.snw:313-314
-###################################################
-print(tli.table,floating=FALSE)
-
-
-###################################################
-### code chunk number 48: xtableGallery.snw:317-318
-###################################################
-align(tli.table) <- "|rrl|l|lr|"
-
-
-###################################################
-### code chunk number 49: xtableGallery.snw:320-321
-###################################################
-print(tli.table,floating=FALSE)
-
-
-###################################################
-### code chunk number 50: xtableGallery.snw:324-325
-###################################################
-align(tli.table) <- "|rr|lp{3cm}l|r|"
-
-
-###################################################
-### code chunk number 51: xtableGallery.snw:327-328
-###################################################
-print(tli.table,floating=FALSE)
-
-
-###################################################
-### code chunk number 52: xtableGallery.snw:335-336
-###################################################
-digits(tli.table) <- 3
-
-
-###################################################
-### code chunk number 53: xtableGallery.snw:338-339
-###################################################
-print(tli.table,floating=FALSE,)
-
-
-###################################################
-### code chunk number 54: xtableGallery.snw:344-345
-###################################################
-digits(tli.table) <- 1:(ncol(tli)+1)
-
-
-###################################################
-### code chunk number 55: xtableGallery.snw:347-348
-###################################################
-print(tli.table,floating=FALSE,)
-
-
-###################################################
-### code chunk number 56: xtableGallery.snw:353-354
-###################################################
-digits(tli.table) <- matrix( 0:4, nrow = 10, ncol = ncol(tli)+1 )
-
-
-###################################################
-### code chunk number 57: xtableGallery.snw:356-357
-###################################################
-print(tli.table,floating=FALSE,)
-
-
-###################################################
-### code chunk number 58: xtableGallery.snw:361-362
-###################################################
-print((tli.table),include.rownames=FALSE,floating=FALSE)
-
-
-###################################################
-### code chunk number 59: xtableGallery.snw:366-367
-###################################################
-align(tli.table) <- "|r|r|lp{3cm}l|r|"
-
-
-###################################################
-### code chunk number 60: xtableGallery.snw:369-370
-###################################################
-print((tli.table),include.rownames=FALSE,floating=FALSE)
-
-
-###################################################
-### code chunk number 61: xtableGallery.snw:374-375
-###################################################
-align(tli.table) <- "|rr|lp{3cm}l|r|"
-
-
-###################################################
-### code chunk number 62: xtableGallery.snw:379-380
-###################################################
-print((tli.table),include.colnames=FALSE,floating=FALSE)
-
-
-###################################################
-### code chunk number 63: xtableGallery.snw:384-385
-###################################################
-print(tli.table,include.colnames=FALSE,floating=FALSE,hline.after=c(0,nrow(tli.table)))
-
-
-###################################################
-### code chunk number 64: xtableGallery.snw:389-390
-###################################################
-print((tli.table),include.colnames=FALSE,include.rownames=FALSE,floating=FALSE)
-
-
-###################################################
-### code chunk number 65: xtableGallery.snw:397-398
-###################################################
-print((tli.table),rotate.rownames=TRUE,rotate.colnames=TRUE)
-
-
-###################################################
-### code chunk number 66: xtableGallery.snw:407-408
-###################################################
-print(xtable(anova(glm.D93)),hline.after=c(1),floating=FALSE)
-
-
-###################################################
-### code chunk number 67: xtableGallery.snw:436-437
-###################################################
-print(tli.table, booktabs=TRUE, floating = FALSE)
-
-
-###################################################
-### code chunk number 68: xtableGallery.snw:449-451
-###################################################
-bktbs <- xtable(matrix(1:10, ncol = 2))
-hlines <- c(-1,0,1,nrow(bktbs))
-
-
-###################################################
-### code chunk number 69: xtableGallery.snw:454-455
-###################################################
-print(bktbs, booktabs = TRUE, hline.after = hlines, floating = FALSE)
-
-
-###################################################
-### code chunk number 70: xtableGallery.snw:460-461
-###################################################
-print(xtable(anova(glm.D93)),size="small",floating=FALSE)
-
-
-###################################################
-### code chunk number 71: longtable
-###################################################
-
-## Demonstration of longtable support.
-x <- matrix(rnorm(1000), ncol = 10)
-x.big <- xtable(x,label='tabbig',
-	caption='Example of longtable spanning several pages')
-
-
-###################################################
-### code chunk number 72: xtableGallery.snw:475-476
-###################################################
-print(x.big,tabular.environment='longtable',floating=FALSE)
-
-
-###################################################
-### code chunk number 73: xtableGallery.snw:514-516
-###################################################
-x <- x[1:30,]
-x.small <- xtable(x,label='tabsmall',caption='A sideways table')
-
-
-###################################################
-### code chunk number 74: xtableGallery.snw:519-520
-###################################################
-print(x.small,floating.environment='sidewaystable')
-
-
-###################################################
-### code chunk number 75: xtableGallery.snw:527-529
-###################################################
-x <- x[1:20,]
-x.rescale <- xtable(x,label='tabrescaled',caption='A rescaled table')
-
-
-###################################################
-### code chunk number 76: xtableGallery.snw:532-533
-###################################################
-print(x.rescale, scalebox=0.7)
-
-
-###################################################
-### code chunk number 77: xtableGallery.snw:542-552
-###################################################
-df.width <- data.frame(
-  "label 1 with much more text than is needed" = c("item 1", "A"),
-  "label 2 is also very long" = c("item 2","B"),
-  "label 3" = c("item 3","C"),
-  "label 4" = c("item 4 but again with too much text","D"),
-  check.names = FALSE)
-
-x.width <- xtable(df.width,
-  caption="Using the 'tabularx' environment")
-align(x.width) <- "|l|X|X|l|X|"
-
-
-###################################################
-### code chunk number 78: xtableGallery.snw:555-557
-###################################################
-print(x.width, tabular.environment="tabularx",
-  width="\\textwidth")
-
-
-###################################################
-### code chunk number 79: xtableGallery.snw:565-566
-###################################################
-x.out <- print(tli.table, print.results = FALSE)
-
-
-###################################################
-### code chunk number 80: xtableGallery.snw:573-576
-###################################################
-x.ltx <- toLatex(tli.table)
-class(x.ltx)
-x.ltx
-
-
-###################################################
-### code chunk number 81: xtableGallery.snw:582-583
-###################################################
-toLatex(sessionInfo())
-
-
+## ----include=FALSE-------------------------------------------------------
+library(knitr)
+opts_chunk$set(fig.path='figdir/fig', debug=TRUE, echo=TRUE)
+set.seed(1234)
+
+## ----results='asis'------------------------------------------------------
+library(xtable)
+options(xtable.floating = FALSE)
+options(xtable.timestamp = "")
+
+## ----results='asis'------------------------------------------------------
+data(tli)
+xtable(tli[1:10, ])
+
+## ----results='asis'------------------------------------------------------
+design.matrix <- model.matrix(~ sex*grade, data = tli[1:10, ])
+xtable(design.matrix, digits = 0)
+
+## ----results='asis'------------------------------------------------------
+fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data = tli)
+xtable(fm1)
+
+## ----results='asis'------------------------------------------------------
+fm2 <- lm(tlimth ~ sex*ethnicty, data = tli)
+xtable(fm2)
+
+## ----results='asis'------------------------------------------------------
+xtable(anova(fm2))
+
+## ----results='asis'------------------------------------------------------
+fm2b <- lm(tlimth ~ ethnicty, data = tli)
+xtable(anova(fm2b, fm2))
+
+## ----aovlist-------------------------------------------------------------
+Block <- gl(8, 4)
+A <- factor(c(0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
+              0,1,0,1,0,1,0,1,0,1,0,1))
+B <- factor(c(0,0,1,1,0,0,1,1,0,1,0,1,1,0,1,0,0,0,1,1,
+              0,0,1,1,0,0,1,1,0,0,1,1))
+C <- factor(c(0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,0,1,
+              1,0,1,0,0,0,1,1,1,1,0,0))
+Yield <- c(101, 373, 398, 291, 312, 106, 265, 450, 106, 306, 324, 449,
+           272, 89, 407, 338, 87, 324, 279, 471, 323, 128, 423, 334,
+           131, 103, 445, 437, 324, 361, 302, 272)
+aovdat <- data.frame(Block, A, B, C, Yield)
+
+old <- getOption("contrasts")
+options(contrasts = c("contr.helmert", "contr.poly"))
+(fit <- aov(Yield ~ A*B*C + Error(Block), data = aovdat))
+class(fit)
+summary(fit)
+options(contrasts = old)
+
+## ----xtableaovlist, results='asis'---------------------------------------
+xtable(fit)
+
+## ----results='asis'------------------------------------------------------
+fm3 <- glm(disadvg ~ ethnicty*grade, data = tli, family = binomial)
+xtable(fm3)
+
+## ----results='asis'------------------------------------------------------
+xtable(anova(fm3))
+
+## ----results='asis'------------------------------------------------------
+pr1 <- prcomp(USArrests)
+xtable(pr1)
+
+## ----results='asis'------------------------------------------------------
+xtable(summary(pr1))
+
+## ----include=FALSE-------------------------------------------------------
+# pr2 <- princomp(USArrests)
+# xtable(pr2)
+
+## ----results='asis'------------------------------------------------------
+temp.ts <- ts(cumsum(1 + round(rnorm(100), 0)),
+              start = c(1954, 7), frequency = 12)
+temp.table <- xtable(temp.ts, digits = 0)
+temp.table
+
+## ----ftable--------------------------------------------------------------
+data(mtcars)
+mtcars$cyl <- factor(mtcars$cyl, levels = c("4","6","8"),
+                     labels = c("four","six","eight"))
+tbl <- ftable(mtcars$cyl, mtcars$vs, mtcars$am, mtcars$gear,
+              row.vars = c(2, 4),
+              dnn = c("Cylinders", "V/S", "Transmission", "Gears"))
+tbl
+
+## ----ftablecheck---------------------------------------------------------
+xftbl <- xtableFtable(tbl, method = "compact")
+print.xtableFtable(xftbl, booktabs = TRUE)
+
+## ----ftable1, results = 'asis'-------------------------------------------
+xftbl <- xtableFtable(tbl)
+print.xtableFtable(xftbl)
+
+## ----ftable2, results = 'asis'-------------------------------------------
+xftbl <- xtableFtable(tbl, method = "col.compact")
+print.xtableFtable(xftbl, rotate.rownames = TRUE)
+
+## ----ftable3, results = 'asis'-------------------------------------------
+xftbl <- xtableFtable(tbl, method = "compact")
+print.xtableFtable(xftbl, booktabs = TRUE)
+
+## ----ftable4, results = 'asis'-------------------------------------------
+italic <- function(x){
+  paste0('{\\emph{', x, '}}')
+}
+mtcars$cyl <- factor(mtcars$cyl, levels = c("four","six","eight"),
+                     labels = c("four",italic("six"),"eight"))
+large <- function(x){
+  paste0('{\\Large ', x, '}')
+}
+bold <- function(x){
+  paste0('{\\bfseries ', x, '}')
+}
+tbl <- ftable(mtcars$cyl, mtcars$vs, mtcars$am, mtcars$gear,
+              row.vars = c(2, 4),
+              dnn = c("Cylinders", "V/S", "Transmission", "Gears"))
+xftbl <- xtableFtable(tbl, method = "row.compact")
+print.xtableFtable(xftbl,
+                   sanitize.rownames.function = large,
+                   sanitize.colnames.function = bold,
+                   rotate.colnames = TRUE,
+                   rotate.rownames = TRUE)
+
+## ----include=FALSE-------------------------------------------------------
+# ## Demonstrate saving to file
+# for(i in c("latex", "html")) {
+#   outFileName <- paste("xtable.", ifelse(i=="latex", "tex", i), sep = "")
+#   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
+#         latex.environments = NULL)
+#   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
+#         latex.environments = "")
+#   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
+#         latex.environments = "center")
+#   print(xtable(anova(glm.D93, test = "Chisq")),
+#         type = i, file = outFileName,
+#         append = TRUE)
+#   print(xtable(anova(glm.D93)), hline.after = c(1),
+#         size = "small", type = i,
+#         file = outFileName, append = TRUE)
+#   # print(xtable(pr2), type = i, file = outFileName, append = TRUE)
+# }
+
+## ----results='asis'------------------------------------------------------
+data(mtcars)
+dat <- mtcars[1:3, 1:6]
+x <- xtable(dat)
+x
+
+## ----results='asis'------------------------------------------------------
+align(x) <- xalign(x)
+digits(x) <- xdigits(x)
+display(x) <- xdisplay(x)
+x
+
+## ----results='asis'------------------------------------------------------
+xtable(dat, auto = TRUE)
+
+## ----results='asis'------------------------------------------------------
+x <- xtable(dat)
+autoformat(x)
+
+## ----results='asis'------------------------------------------------------
+print(xtable(data.frame(text = c("foo","bar"),
+                        googols = c(10e10,50e10),
+                        small = c(8e-24,7e-5),
+                        row.names = c("A","B")),
+             display = c("s","s","g","g")),
+      math.style.exponents = TRUE)
+
+## ----results='asis'------------------------------------------------------
+insane <- data.frame(Name = c("Ampersand","Greater than","Less than",
+                            "Underscore","Per cent","Dollar",
+                            "Backslash","Hash","Caret","Tilde",
+                            "Left brace","Right brace"),
+                     Character = I(c("&",">","<","_","%","$",
+                                     "\\","#","^","~","{","}")))
+colnames(insane)[2] <- paste(insane[, 2], collapse = "")
+xtable(insane)
+
+## ----results='asis'------------------------------------------------------
+wanttex <- xtable(data.frame(Column =
+                             paste("Value_is $10^{-",1:3,"}$", sep = "")))
+print(wanttex, sanitize.text.function =
+      function(str) gsub("_", "\\_", str, fixed = TRUE))
+
+## ----sanitize3-----------------------------------------------------------
+dat <- mtcars[1:3, 1:6]
+large <- function(x){
+  paste0('{\\Large{\\bfseries ', x, '}}')
+}
+italic <- function(x){
+  paste0('{\\emph{ ', x, '}}')
+}
+
+## ----sanitize4, results = 'asis'-----------------------------------------
+print(xtable(dat),
+      sanitize.rownames.function = italic,
+      sanitize.colnames.function = large,
+      booktabs = TRUE)
+
+## ----results='asis'------------------------------------------------------
+mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4)
+rownames(mat) <- "$y_{t-1}$"
+colnames(mat) <- c("$R^2$", "$\\bar{x}$", "F-stat", "S.E.E", "DW")
+mat <- xtable(mat)
+print(mat, sanitize.text.function = function(x) {x})
+
+## ----results='asis'------------------------------------------------------
+money <- matrix(c("$1,000","$900","$100"), ncol = 3,
+                dimnames = list("$\\alpha$",
+                                c("Income (US$)","Expenses (US$)",
+                                  "Profit (US$)")))
+print(xtable(money), sanitize.rownames.function = function(x) {x})
+
+## ----results='asis'------------------------------------------------------
+print(xtable(anova(fm3), caption = "\\tt latex.environments = \"\""),
+      floating = TRUE, latex.environments = "")
+print(xtable(anova(fm3), caption = "\\tt latex.environments = \"center\""),
+      floating = TRUE, latex.environments = "center")
+
+## ----results='asis'------------------------------------------------------
+tli.table <- xtable(tli[1:10, ])
+align(tli.table) <- rep("r", 6)
+tli.table
+
+## ----results='asis'------------------------------------------------------
+align(tli.table) <- "|rrl|l|lr|"
+tli.table
+
+## ----results='asis'------------------------------------------------------
+align(tli.table) <- "|rr|lp{3cm}l|r|"
+tli.table
+
+## ----results='asis'------------------------------------------------------
+display(tli.table)[c(2,6)] <- "f"
+digits(tli.table) <- 3
+tli.table
+
+## ----results='asis'------------------------------------------------------
+digits(tli.table) <- 1:(ncol(tli)+1)
+tli.table
+
+## ----results='asis'------------------------------------------------------
+digits(tli.table) <- matrix(0:4, nrow = 10, ncol = ncol(tli)+1)
+tli.table
+
+## ----results='asis'------------------------------------------------------
+tli.table <- xtable(tli[1:10, ])
+print(tli.table, include.rownames = FALSE)
+
+## ----results='asis'------------------------------------------------------
+align(tli.table) <- "|r|r|lp{3cm}l|r|"
+print(tli.table, include.rownames = FALSE)
+
+## ------------------------------------------------------------------------
+align(tli.table) <- "|rr|lp{3cm}l|r|"
+
+## ----results='asis'------------------------------------------------------
+print(tli.table, include.colnames = FALSE)
+
+## ----results='asis'------------------------------------------------------
+print(tli.table, include.colnames = FALSE,
+      hline.after = c(0,nrow(tli.table)))
+
+## ----results='asis'------------------------------------------------------
+print(tli.table, include.colnames = FALSE, include.rownames = FALSE)
+
+## ----results='asis'------------------------------------------------------
+print(tli.table, rotate.rownames = TRUE, rotate.colnames = TRUE)
+
+## ----results='asis'------------------------------------------------------
+print(xtable(anova(fm3)), hline.after = c(1))
+
+## ----results='asis'------------------------------------------------------
+tli.table <- xtable(tli[1:10, ])
+print(tli.table, include.rownames = FALSE, booktabs = TRUE)
+
+## ----results='asis'------------------------------------------------------
+bktbs <- xtable(matrix(1:10, ncol = 2))
+hlines <- c(-1, 0, 1, nrow(bktbs))
+print(bktbs, booktabs = TRUE, hline.after = hlines)
+
+## ----results='asis'------------------------------------------------------
+print(xtable(anova(fm3)), size = "large")
+
+## ----results='asis'------------------------------------------------------
+print(xtable(anova(fm3)), size = "\\setlength{\\tabcolsep}{12pt}")
+
+## ----results='asis'------------------------------------------------------
+x <- matrix(rnorm(1000), ncol = 10)
+x.big <- xtable(x, caption = "A \\code{longtable} spanning several pages")
+print(x.big, hline.after=c(-1, 0), tabular.environment = "longtable")
+
+## ----results='asis'------------------------------------------------------
+add.to.row <- list(pos = list(0), command = NULL)
+command <- paste0("\\hline\n\\endhead\n",
+                  "\\hline\n",
+                  "\\multicolumn{", dim(x)[2] + 1, "}{l}",
+                  "{\\footnotesize Continued on next page}\n",
+                  "\\endfoot\n",
+                  "\\endlastfoot\n")
+add.to.row$command <- command
+print(x.big, hline.after=c(-1), add.to.row = add.to.row,
+      tabular.environment = "longtable")
+
+## ------------------------------------------------------------------------
+Grade3 <- c("A","B","B","A","B","C","C","D","A","B",
+            "C","C","C","D","B","B","D","C","C","D")
+Grade6 <- c("A","A","A","B","B","B","B","B","C","C",
+            "A","C","C","C","D","D","D","D","D","D")
+Cohort <- table(Grade3, Grade6)
+Cohort
+
+## ----results='asis'------------------------------------------------------
+xtable(Cohort)
+
+## ----results='asis'------------------------------------------------------
+addtorow <- list()
+addtorow$pos <- list(0, 0)
+addtorow$command <- c("& \\multicolumn{4}{c}{Grade 6} \\\\\n",
+                      "Grade 3 & A & B & C & D \\\\\n")
+print(xtable(Cohort), add.to.row = addtorow, include.colnames = FALSE)
+
+## ----results='asis'------------------------------------------------------
+x <- x[1:30, ]
+x.side <- xtable(x, caption = "A sideways table")
+print(x.side, floating = TRUE, floating.environment = "sidewaystable")
+
+## ----results='asis'------------------------------------------------------
+x <- x[1:20, ]
+x.rescale <- xtable(x)
+print(x.rescale, scalebox = 0.7)
+
+## ----results='asis'------------------------------------------------------
+df <- data.frame(name = c("A","B"), right = c(1.4, 34.6),
+                 left = c(1.4, 34.6), text = c("txt1","txt2"))
+print(xtable(df, align = c("l", "|c", "|R{3cm}", "|L{3cm}", "| p{3cm}|")),
+      floating = FALSE, include.rownames = FALSE)
+
+## ----results='asis'------------------------------------------------------
+df.width <- data.frame(One = c("item 1", "A"), Two = c("item 2", "B"),
+                       Three = c("item 3", "C"), Four = c("item 4", "D"))
+x.width <- xtable(df.width)
+align(x.width) <- "|l|X|l|l|l|"
+print(x.width, tabular.environment = "tabularx", width = "\\textwidth")
+
+## ------------------------------------------------------------------------
+x.out <- print(tli.table, print.results = FALSE)
+
+## ------------------------------------------------------------------------
+x.ltx <- toLatex(tli.table)
+class(x.ltx)
+x.ltx
+
+## ----results='asis'------------------------------------------------------
+toLatex(sessionInfo())
+
diff --git a/inst/doc/xtableGallery.Rnw b/inst/doc/xtableGallery.Rnw
new file mode 100644
index 0000000..c618d49
--- /dev/null
+++ b/inst/doc/xtableGallery.Rnw
@@ -0,0 +1,731 @@
+%\VignetteIndexEntry{xtable Gallery}
+%\VignetteDepends{xtable}
+%\VignetteKeywords{LaTeX, HTML, table}
+%\VignettePackage{xtable}
+% !Rnw weave = knitr
+% \VignetteEngine{knitr::knitr}
+%**************************************************************************
+\documentclass{article}
+\usepackage[a4paper,height=24cm]{geometry} % geometry first
+\usepackage{array}
+\usepackage{booktabs}
+\usepackage{longtable}
+\usepackage{parskip}
+\usepackage{rotating}
+\usepackage{tabularx}
+\usepackage{titlesec}
+\usepackage{hyperref} % hyperref last
+\titleformat\subsubsection{\bfseries\itshape}{}{0pt}{}
+\newcommand\p{\vspace{2ex}}
+\newcommand\code[1]{\texttt{#1}}
+\newcommand\pkg[1]{\textbf{#1}}
+\setcounter{tocdepth}{2}
+\begin{document}
+
+\title{The \pkg{xtable} Gallery}
+\author{Jonathan Swinton and others}
+\maketitle
+
+\tableofcontents
+
+\newpage
+
+\section{Introduction}
+This document gives a gallery of tables which can be made using the
+\pkg{xtable} package to create \LaTeX\ output. It doubles as a
+regression check for the package.
+
+<<include=FALSE>>=
+library(knitr)
+opts_chunk$set(fig.path='figdir/fig', debug=TRUE, echo=TRUE)
+set.seed(1234)
+@
+
+The first step is to load the package and set an option for this document.
+<<results='asis'>>=
+library(xtable)
+options(xtable.floating = FALSE)
+options(xtable.timestamp = "")
+@
+
+\section{Gallery}
+\subsection{Data frame}
+<<results='asis'>>=
+data(tli)
+xtable(tli[1:10, ])
+@
+
+\subsection{Matrix}
+<<results='asis'>>=
+design.matrix <- model.matrix(~ sex*grade, data = tli[1:10, ])
+xtable(design.matrix, digits = 0)
+@
+
+\newpage
+\subsection{aov}
+<<results='asis'>>=
+fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data = tli)
+xtable(fm1)
+@
+
+\subsection{lm}
+<<results='asis'>>=
+fm2 <- lm(tlimth ~ sex*ethnicty, data = tli)
+xtable(fm2)
+@
+
+\subsubsection{Anova table (one model)}
+<<results='asis'>>=
+xtable(anova(fm2))
+@
+
+\subsubsection{Anova table (two models)}
+<<results='asis'>>=
+fm2b <- lm(tlimth ~ ethnicty, data = tli)
+xtable(anova(fm2b, fm2))
+@
+
+\subsubsection{Anova list}
+
+<<aovlist>>=
+Block <- gl(8, 4)
+A <- factor(c(0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
+              0,1,0,1,0,1,0,1,0,1,0,1))
+B <- factor(c(0,0,1,1,0,0,1,1,0,1,0,1,1,0,1,0,0,0,1,1,
+              0,0,1,1,0,0,1,1,0,0,1,1))
+C <- factor(c(0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,0,1,
+              1,0,1,0,0,0,1,1,1,1,0,0))
+Yield <- c(101, 373, 398, 291, 312, 106, 265, 450, 106, 306, 324, 449,
+           272, 89, 407, 338, 87, 324, 279, 471, 323, 128, 423, 334,
+           131, 103, 445, 437, 324, 361, 302, 272)
+aovdat <- data.frame(Block, A, B, C, Yield)
+
+old <- getOption("contrasts")
+options(contrasts = c("contr.helmert", "contr.poly"))
+(fit <- aov(Yield ~ A*B*C + Error(Block), data = aovdat))
+class(fit)
+summary(fit)
+options(contrasts = old)
+@
+
+\p
+
+<<xtableaovlist, results='asis'>>=
+xtable(fit)
+@
+
+
+\newpage
+\subsection{glm}
+<<results='asis'>>=
+fm3 <- glm(disadvg ~ ethnicty*grade, data = tli, family = binomial)
+xtable(fm3)
+@
+
+\subsubsection{Analysis of deviance}
+<<results='asis'>>=
+xtable(anova(fm3))
+@
+
+\subsection{prcomp}
+<<results='asis'>>=
+pr1 <- prcomp(USArrests)
+xtable(pr1)
+@
+
+\p
+<<results='asis'>>=
+xtable(summary(pr1))
+@
+
+<<include=FALSE>>=
+# pr2 <- princomp(USArrests)
+# xtable(pr2)
+@
+
+\newpage
+
+\subsection{Time series}
+<<results='asis'>>=
+temp.ts <- ts(cumsum(1 + round(rnorm(100), 0)),
+              start = c(1954, 7), frequency = 12)
+temp.table <- xtable(temp.ts, digits = 0)
+temp.table
+@
+
+\subsection{Flat tables}
+\label{sec:flat-tables}
+
+See the \textbf{Details} section of the help for \code{ftable} for a
+description of these tables, which are flat versions of
+multi-dimensional contingency tables. They require special methods to
+enable them to be printed using \pkg{xtable}
+
+
+<<ftable>>=
+data(mtcars)
+mtcars$cyl <- factor(mtcars$cyl, levels = c("4","6","8"),
+                     labels = c("four","six","eight"))
+tbl <- ftable(mtcars$cyl, mtcars$vs, mtcars$am, mtcars$gear,
+              row.vars = c(2, 4),
+              dnn = c("Cylinders", "V/S", "Transmission", "Gears"))
+tbl
+@ %def
+
+Here is the \LaTeX{} produced:
+
+<<ftablecheck>>=
+xftbl <- xtableFtable(tbl, method = "compact")
+print.xtableFtable(xftbl, booktabs = TRUE)
+@ %def
+
+And here is a basic flat table:
+
+<<ftable1, results = 'asis'>>=
+xftbl <- xtableFtable(tbl)
+print.xtableFtable(xftbl)
+@ %def
+
+This illustrates the \code{method} argument:
+
+<<ftable2, results = 'asis'>>=
+xftbl <- xtableFtable(tbl, method = "col.compact")
+print.xtableFtable(xftbl, rotate.rownames = TRUE)
+@ %def
+
+Booktabs is incompatible with vertical lines in tables, so the
+vertical dividing line is removed.
+
+<<ftable3, results = 'asis'>>=
+xftbl <- xtableFtable(tbl, method = "compact")
+print.xtableFtable(xftbl, booktabs = TRUE)
+@ %def
+\p
+
+Row and column variable names can be formatted specially using
+sanitization, and row and column variable names and labels can be
+rotated.
+
+If special formatting is required for row and column labels, that can
+be done as a workaround by redefining the data and associated labels.
+
+<<ftable4, results = 'asis'>>=
+italic <- function(x){
+  paste0('{\\emph{', x, '}}')
+}
+mtcars$cyl <- factor(mtcars$cyl, levels = c("four","six","eight"),
+                     labels = c("four",italic("six"),"eight"))
+large <- function(x){
+  paste0('{\\Large ', x, '}')
+}
+bold <- function(x){
+  paste0('{\\bfseries ', x, '}')
+}
+tbl <- ftable(mtcars$cyl, mtcars$vs, mtcars$am, mtcars$gear,
+              row.vars = c(2, 4),
+              dnn = c("Cylinders", "V/S", "Transmission", "Gears"))
+xftbl <- xtableFtable(tbl, method = "row.compact")
+print.xtableFtable(xftbl,
+                   sanitize.rownames.function = large,
+                   sanitize.colnames.function = bold,
+                   rotate.colnames = TRUE,
+                   rotate.rownames = TRUE)
+@ %def
+
+
+
+\newpage
+
+<<include=FALSE>>=
+# ## Demonstrate saving to file
+# for(i in c("latex", "html")) {
+#   outFileName <- paste("xtable.", ifelse(i=="latex", "tex", i), sep = "")
+#   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
+#         latex.environments = NULL)
+#   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
+#         latex.environments = "")
+#   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
+#         latex.environments = "center")
+#   print(xtable(anova(glm.D93, test = "Chisq")),
+#         type = i, file = outFileName,
+#         append = TRUE)
+#   print(xtable(anova(glm.D93)), hline.after = c(1),
+#         size = "small", type = i,
+#         file = outFileName, append = TRUE)
+#   # print(xtable(pr2), type = i, file = outFileName, append = TRUE)
+# }
+@
+
+\section{Automatic formatting}
+\subsection{Suggest alignment, digits, and display}
+The functions \code{xalign}, \code{xdigits}, and \code{xdisplay} are
+useful for formatting tables in a sensible way. Consider the output
+produced by the default formatting.
+
+<<results='asis'>>=
+data(mtcars)
+dat <- mtcars[1:3, 1:6]
+x <- xtable(dat)
+x
+@
+
+\p
+Now change the default alignment, digits and display using helper functions
+\code{xalign}, \code{xdigits}, and \code{xdisplay}. This produces a better
+format as shown below.
+
+<<results='asis'>>=
+align(x) <- xalign(x)
+digits(x) <- xdigits(x)
+display(x) <- xdisplay(x)
+x
+@
+
+\subsection{Shorthand notation}
+For convenience, the three `autoformat' functions (\code{xalign},
+\code{xdigits}, and \code{xdisplay}) can be applied together when an
+\code{xtable} is created, using the \code{auto} argument:
+
+<<results='asis'>>=
+xtable(dat, auto = TRUE)
+@
+
+\p
+Similarly, the \code{autoformat} function can be used to postprocess an
+existing \code{xtable}:
+
+<<results='asis'>>=
+x <- xtable(dat)
+autoformat(x)
+@
+
+\newpage
+
+\subsection{Math-Style Exponents}
+If you prefer $5 \times 10^5$ in your tables to 5e5, the
+\code{math.style.exponents} option to \code{print.xtable} is useful:
+
+<<results='asis'>>=
+print(xtable(data.frame(text = c("foo","bar"),
+                        googols = c(10e10,50e10),
+                        small = c(8e-24,7e-5),
+                        row.names = c("A","B")),
+             display = c("s","s","g","g")),
+      math.style.exponents = TRUE)
+@
+
+this option also supports the values \code{ensuremath} which uses
+\code{\char`\\ensuremath} instead of \code{\$\$} and \code{UTF-8}
+which uses UTF-8 to approximate the \LaTeX typesetting.
+
+
+\section{Sanitization}
+<<results='asis'>>=
+insane <- data.frame(Name = c("Ampersand","Greater than","Less than",
+                            "Underscore","Per cent","Dollar",
+                            "Backslash","Hash","Caret","Tilde",
+                            "Left brace","Right brace"),
+                     Character = I(c("&",">","<","_","%","$",
+                                     "\\","#","^","~","{","}")))
+colnames(insane)[2] <- paste(insane[, 2], collapse = "")
+xtable(insane)
+@
+
+\p
+Sometimes you might want to have your own sanitization function.
+
+
+<<results='asis'>>=
+wanttex <- xtable(data.frame(Column =
+                             paste("Value_is $10^{-",1:3,"}$", sep = "")))
+print(wanttex, sanitize.text.function =
+      function(str) gsub("_", "\\_", str, fixed = TRUE))
+@
+
+\p
+Sanitization can be useful in formatting column headings and row names:
+
+<<sanitize3>>=
+dat <- mtcars[1:3, 1:6]
+large <- function(x){
+  paste0('{\\Large{\\bfseries ', x, '}}')
+}
+italic <- function(x){
+  paste0('{\\emph{ ', x, '}}')
+}
+@ %def
+
+<<sanitize4, results = 'asis'>>=
+print(xtable(dat),
+      sanitize.rownames.function = italic,
+      sanitize.colnames.function = large,
+      booktabs = TRUE)
+@ %def
+
+
+
+\newpage
+
+\subsection{Markup in tables}
+Markup can be included in tables, including in column and row names,
+by using a custom \code{sanitize.text.function}.
+
+<<results='asis'>>=
+mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4)
+rownames(mat) <- "$y_{t-1}$"
+colnames(mat) <- c("$R^2$", "$\\bar{x}$", "F-stat", "S.E.E", "DW")
+mat <- xtable(mat)
+print(mat, sanitize.text.function = function(x) {x})
+@
+
+% By David Dahl to demonstrate contribution from David Whitting, 2007-10-09.
+\p
+You can also have sanitize functions that are specific to column or
+row names.  In the table below, the row name is not sanitized but
+column names and table elements are.
+
+<<results='asis'>>=
+money <- matrix(c("$1,000","$900","$100"), ncol = 3,
+                dimnames = list("$\\alpha$",
+                                c("Income (US$)","Expenses (US$)",
+                                  "Profit (US$)")))
+print(xtable(money), sanitize.rownames.function = function(x) {x})
+@
+
+\section{Format examples}
+\subsection{Adding a centering environment}
+<<results='asis'>>=
+print(xtable(anova(fm3), caption = "\\tt latex.environments = \"\""),
+      floating = TRUE, latex.environments = "")
+print(xtable(anova(fm3), caption = "\\tt latex.environments = \"center\""),
+      floating = TRUE, latex.environments = "center")
+@
+
+\newpage
+
+\subsection{Column alignment}
+<<results='asis'>>=
+tli.table <- xtable(tli[1:10, ])
+align(tli.table) <- rep("r", 6)
+tli.table
+@
+
+\subsubsection{Left aligned strings with column lines}
+<<results='asis'>>=
+align(tli.table) <- "|rrl|l|lr|"
+tli.table
+@
+
+\subsubsection{Fixed width columns}
+<<results='asis'>>=
+align(tli.table) <- "|rr|lp{3cm}l|r|"
+tli.table
+@
+
+\newpage
+
+\subsection{Number of digits}
+One number for all columns,
+<<results='asis'>>=
+display(tli.table)[c(2,6)] <- "f"
+digits(tli.table) <- 3
+tli.table
+@
+
+\p
+or one for each column, including the row names,
+<<results='asis'>>=
+digits(tli.table) <- 1:(ncol(tli)+1)
+tli.table
+@
+
+\p
+or as a full matrix.
+<<results='asis'>>=
+digits(tli.table) <- matrix(0:4, nrow = 10, ncol = ncol(tli)+1)
+tli.table
+@
+
+\newpage
+
+\subsection{Suppress row/column names}
+\subsubsection{Suppress row names}
+<<results='asis'>>=
+tli.table <- xtable(tli[1:10, ])
+print(tli.table, include.rownames = FALSE)
+@
+
+\p
+If you want a vertical line on the left, you need to change the \code{align}
+attribute.
+<<results='asis'>>=
+align(tli.table) <- "|r|r|lp{3cm}l|r|"
+print(tli.table, include.rownames = FALSE)
+@
+
+\p
+Revert the alignment to what is was before.
+<<>>=
+align(tli.table) <- "|rr|lp{3cm}l|r|"
+@
+
+\newpage
+
+\subsubsection{Suppress column names}
+<<results='asis'>>=
+print(tli.table, include.colnames = FALSE)
+@
+
+\p
+Note the doubled header lines which can be suppressed.
+<<results='asis'>>=
+print(tli.table, include.colnames = FALSE,
+      hline.after = c(0,nrow(tli.table)))
+@
+
+\subsubsection{Suppress row and column names}
+<<results='asis'>>=
+print(tli.table, include.colnames = FALSE, include.rownames = FALSE)
+@
+
+\newpage
+
+\subsection{Rotate row/column names}
+The \code{rotate.rownames} and \code{rotate.colnames} arguments can be
+used to rotate the row and/or column names. This requires
+\verb|\usepackage{rotating}| in the \LaTeX\ preamble.
+
+<<results='asis'>>=
+print(tli.table, rotate.rownames = TRUE, rotate.colnames = TRUE)
+@
+
+\newpage
+
+\subsection{Horizontal lines}
+\subsubsection{Line locations}
+Use the \code{hline.after} argument to specify the position of the
+horizontal lines.
+
+<<results='asis'>>=
+print(xtable(anova(fm3)), hline.after = c(1))
+@
+
+\subsubsection{Line styles}
+Specifying \code{booktabs = TRUE} will generate three line types. By
+default, when no value is given for \code{hline.after}, a
+\verb|\toprule| will be drawn above the table, a \verb|\midrule| after
+the table headings and a \verb|\bottomrule| below the table. This
+requires \verb|\usepackage{booktabs}| in the \LaTeX\ preamble.
+
+\p
+
+The top and bottom rules are slightly thicker than the mid rule. The
+thickness of the lines can be set via the \LaTeX\ lengths
+\verb|\heavyrulewidth| and \verb|\lightrulewidth|.
+
+<<results='asis'>>=
+tli.table <- xtable(tli[1:10, ])
+print(tli.table, include.rownames = FALSE, booktabs = TRUE)
+@
+
+\p
+
+If \code{hline.after} includes \code{-1}, a \verb|\toprule| will be
+drawn above the table. If \code{hline.after} includes the number of
+rows in the table, a \verb|\bottomrule| will be drawn below the
+table. For any other values specified in \code{hline.after}, a
+\verb|\midrule| will be drawn after that line of the table.
+
+\p
+The following table has more than one \verb|\midrule|.
+
+<<results='asis'>>=
+bktbs <- xtable(matrix(1:10, ncol = 2))
+hlines <- c(-1, 0, 1, nrow(bktbs))
+print(bktbs, booktabs = TRUE, hline.after = hlines)
+@
+
+\subsection{Table level commands}
+<<results='asis'>>=
+print(xtable(anova(fm3)), size = "large")
+@
+
+\p
+<<results='asis'>>=
+print(xtable(anova(fm3)), size = "\\setlength{\\tabcolsep}{12pt}")
+@
+
+\subsection{Long tables}
+Requires \verb|\usepackage{longtable}| in the \LaTeX\ preamble.
+
+<<results='asis'>>=
+x <- matrix(rnorm(1000), ncol = 10)
+x.big <- xtable(x, caption = "A \\code{longtable} spanning several pages")
+print(x.big, hline.after=c(-1, 0), tabular.environment = "longtable")
+@
+
+Extra features of the \pkg{longtable} \LaTeX{} package can typically
+be activated using \code{add.to.row}, as shown below.
+
+<<results='asis'>>=
+add.to.row <- list(pos = list(0), command = NULL)
+command <- paste0("\\hline\n\\endhead\n",
+                  "\\hline\n",
+                  "\\multicolumn{", dim(x)[2] + 1, "}{l}",
+                  "{\\footnotesize Continued on next page}\n",
+                  "\\endfoot\n",
+                  "\\endlastfoot\n")
+add.to.row$command <- command
+print(x.big, hline.after=c(-1), add.to.row = add.to.row,
+      tabular.environment = "longtable")
+@
+
+
+\newpage
+
+\subsection{Use of \code{add.to.row} argument}
+The following frequency table has outer dimnames: \code{Grade3} and
+\code{Grade6}.
+
+<<>>=
+Grade3 <- c("A","B","B","A","B","C","C","D","A","B",
+            "C","C","C","D","B","B","D","C","C","D")
+Grade6 <- c("A","A","A","B","B","B","B","B","C","C",
+            "A","C","C","C","D","D","D","D","D","D")
+Cohort <- table(Grade3, Grade6)
+Cohort
+@
+
+\p
+The default behavior of \code{print.xtable} is to strip outer dimnames.
+<<results='asis'>>=
+xtable(Cohort)
+@
+
+\p
+The desired column labels can be created using \code{add.to.row}, in this case
+applying two commands to ``row number zero'' while suppressing the basic column
+names.
+
+<<results='asis'>>=
+addtorow <- list()
+addtorow$pos <- list(0, 0)
+addtorow$command <- c("& \\multicolumn{4}{c}{Grade 6} \\\\\n",
+                      "Grade 3 & A & B & C & D \\\\\n")
+print(xtable(Cohort), add.to.row = addtorow, include.colnames = FALSE)
+@
+
+\subsection{Sideways tables}
+Requires \verb|\usepackage{rotating}| in the LaTeX
+preamble.  Sideways tables can't be forced in place with the \code{[H]}
+specifier, but you can use the \verb|\clearpage| command to get them
+fairly nearby.
+
+<<results='asis'>>=
+x <- x[1:30, ]
+x.side <- xtable(x, caption = "A sideways table")
+print(x.side, floating = TRUE, floating.environment = "sidewaystable")
+@
+\clearpage
+
+\subsection{Rescaled tables}
+Specify a \code{scalebox} value to rescale the table.
+<<results='asis'>>=
+x <- x[1:20, ]
+x.rescale <- xtable(x)
+print(x.rescale, scalebox = 0.7)
+@
+
+\subsection{Aligning fixed width columns}
+Note that using specifications such as \verb|p{2cm}| always
+produces a \textbf{left aligned} column. What if some other alignment
+is desired?
+
+This is not really a problem with \pkg{xtable} but with the formatting
+of tables with fixed width columns and different alignments using
+standard \LaTeX.
+
+One solution is to use the \verb|array| package, defining new
+column formats.
+
+\begin{verbatim}
+\newcolumntype{L}[1]{>{\raggedright\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{C}[1]{>{\centering\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{R}[1]{>{\raggedleft\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{P}[1]{>{\raggedright\tabularxbackslash}p{#1}}
+\end{verbatim}
+
+These allow for very sophisticated cell formatting, namely
+left-aligned, centred, or right-aligned text, with recognition of line
+breaks for the first three new column types. If these lines are
+included along with \verb|\usepackage{array}|, then the following is
+possible.
+
+\newcolumntype{L}[1]{>{\raggedright\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{C}[1]{>{\centering\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{R}[1]{>{\raggedleft\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{P}[1]{>{\raggedright\tabularxbackslash}p{#1}}
+
+<<results='asis'>>=
+df <- data.frame(name = c("A","B"), right = c(1.4, 34.6),
+                 left = c(1.4, 34.6), text = c("txt1","txt2"))
+print(xtable(df, align = c("l", "|c", "|R{3cm}", "|L{3cm}", "| p{3cm}|")),
+      floating = FALSE, include.rownames = FALSE)
+@
+
+\newpage
+
+\subsection{Table width}
+The \code{tabularx} environment is for typesetting tables whose
+overall width is fixed. The column alignment code \code{X} denotes
+columns that will be stretched to achieve the desired table
+width. Requires \verb|\usepackage{tabularx}| in the \LaTeX\ preamble.
+
+<<results='asis'>>=
+df.width <- data.frame(One = c("item 1", "A"), Two = c("item 2", "B"),
+                       Three = c("item 3", "C"), Four = c("item 4", "D"))
+x.width <- xtable(df.width)
+align(x.width) <- "|l|X|l|l|l|"
+print(x.width, tabular.environment = "tabularx", width = "\\textwidth")
+@
+
+\section{Suppressing printing}
+By default the \code{print} method will print the \LaTeX\ or HTML to
+standard output and also return the character strings invisibly.  The
+printing to standard output can be suppressed by specifying
+\code{print.results = FALSE}.
+
+<<>>=
+x.out <- print(tli.table, print.results = FALSE)
+@
+
+Formatted output can also be captured without printing with the
+\code{toLatex} method.  This function returns an object of class
+\code{"Latex"}.
+
+<<>>=
+x.ltx <- toLatex(tli.table)
+class(x.ltx)
+x.ltx
+@
+
+
+\newpage
+
+\section{Acknowledgements}
+Most of the examples in this gallery are taken from the \pkg{xtable}
+documentation. Two examples (\code{add.to.row} and `Aligning fixed width
+columns') are from Stack Exchange.
+
+\section{Session information}
+<<results='asis'>>=
+toLatex(sessionInfo())
+@
+
+\end{document}
diff --git a/inst/doc/xtableGallery.pdf b/inst/doc/xtableGallery.pdf
index bd71bc0..abe585e 100644
Binary files a/inst/doc/xtableGallery.pdf and b/inst/doc/xtableGallery.pdf differ
diff --git a/inst/doc/xtableGallery.snw b/inst/doc/xtableGallery.snw
deleted file mode 100644
index 2dfa32b..0000000
--- a/inst/doc/xtableGallery.snw
+++ /dev/null
@@ -1,585 +0,0 @@
-%\VignetteIndexEntry{xtable Gallery}
-%\VignetteDepends{xtable}
-%\VignetteKeywords{LaTeX,HTML,table}
-%\VignettePackage{xtable}
-
-%**************************************************************************
-%
-% # $Id:$
-
-% $Revision:  $
-% $Author: $
-% $Date:  $
-
-<<echo=FALSE,eval=FALSE>>=
-makeme <- function() {
-	# I am a convenience function for debugging and can be ignored
-	setwd("C:/JonathanSwinton/PathwayModeling/src/R/SourcePackages/xtable/inst/doc")
-	Sweave("xtableGallery.RnW",stylepath=FALSE)
-}
-makeme()
-@
-
-\documentclass[letterpaper]{article}
-
-\title{
-The xtable gallery
-}
-\author{Jonathan Swinton <jonathan at swintons.net>\\ with small contributions from others}
-
-\usepackage{Sweave}
-\SweaveOpts{prefix.string=figdir/fig,debug=TRUE,eps=FALSE,echo=TRUE}
-\usepackage{rotating}
-\usepackage{longtable}
-\usepackage{booktabs}
-\usepackage{tabularx}
-%\usepackage{hyperref}
-\begin{document}
-
-\maketitle
-\section{Summary}
-This document gives a gallery of tables which can be made
-by using the {\tt xtable} package to create \LaTeX\ output.
-It doubles as a regression check for the package.
-
-<<>>=
-library(xtable)
-@
-
-\section{Gallery}
-\subsection{Data frame}
-Load example dataset
-<<>>=
-data(tli)
-
-## Demonstrate data.frame
-tli.table <- xtable(tli[1:10,])
-digits(tli.table)[c(2,6)] <- 0
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE)
-@
-
-\subsection{Matrix}
-<<>>=
-design.matrix <- model.matrix(~ sex*grade, data=tli[1:10,])
-design.table <- xtable(design.matrix)
-@
-<<results=tex>>=
-print(design.table,floating=FALSE)
-@
-
-\subsection{aov}
-<<>>=
-fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data=tli)
-fm1.table <- xtable(fm1)
-@
-<<results=tex>>=
-print(fm1.table,floating=FALSE)
-@
-\subsection{lm}
-<<>>=
-fm2 <- lm(tlimth ~ sex*ethnicty, data=tli)
-fm2.table <- xtable(fm2)
-@
-<<results=tex>>=
-print(fm2.table,floating=FALSE)
-@
-\subsubsection{anova object}
-
-<<results=tex>>=
-print(xtable(anova(fm2)),floating=FALSE)
-@
-\subsubsection{Another anova object}
-<<>>=
-fm2b <- lm(tlimth ~ ethnicty, data=tli)
-@
-<<results=tex>>=
-print(xtable(anova(fm2b,fm2)),floating=FALSE)
-@
-
-
-\subsection{glm}
-
-<<>>=
-
-## Demonstrate glm
-fm3 <- glm(disadvg ~ ethnicty*grade, data=tli, family=binomial())
-fm3.table <- xtable(fm3)
-@
-<<results=tex>>=
-print(fm3.table,floating=FALSE)
-@
-
-\subsubsection{anova object}
-@
-<<results=tex>>=
-print(xtable(anova(fm3)),floating=FALSE)
-@
-
-
-\subsection{More aov}
-<<>>=
-
-## Demonstrate aov
-## Taken from help(aov) in R 1.1.1
-## From Venables and Ripley (1997) p.210.
-N <- c(0,1,0,1,1,1,0,0,0,1,1,0,1,1,0,0,1,0,1,0,1,1,0,0)
-P <- c(1,1,0,0,0,1,0,1,1,1,0,0,0,1,0,1,1,0,0,1,0,1,1,0)
-K <- c(1,0,0,1,0,1,1,0,0,1,0,1,0,1,1,0,0,0,1,1,1,0,1,0)
-yield <- c(49.5,62.8,46.8,57.0,59.8,58.5,55.5,56.0,62.8,55.8,69.5,55.0,
-           62.0,48.8,45.5,44.2,52.0,51.5,49.8,48.8,57.2,59.0,53.2,56.0)
-npk <- data.frame(block=gl(6,4), N=factor(N), P=factor(P), K=factor(K), yield=yield)
-npk.aov <- aov(yield ~ block + N*P*K, npk)
-op <- options(contrasts=c("contr.helmert", "contr.treatment"))
-npk.aovE <- aov(yield ~  N*P*K + Error(block), npk)
-options(op)
-#summary(npk.aov)
-@
-<<results=tex>>=
-print(xtable(npk.aov),floating=FALSE)
-@
-
-\subsubsection{anova object}
-<<results=tex>>=
-print(xtable(anova(npk.aov)),floating=FALSE)
-@
-
-\subsubsection{Another anova object}
-<<results=tex>>=
-print(xtable(summary(npk.aov)),floating=FALSE)
-@
-
-<<>>=
-#summary(npk.aovE)
-@
-<<results=tex>>=
-print(xtable(npk.aovE),floating=FALSE)
-@
-
-
-<<results=tex>>=
-print(xtable(summary(npk.aovE)),floating=FALSE)
-@
-
-\subsection{More lm}
-<<>>=
-
-## Demonstrate lm
-## Taken from help(lm) in R 1.1.1
-## Annette Dobson (1990) "An Introduction to Generalized Linear Models".
-## Page 9: Plant Weight Data.
-ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
-trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
-group <- gl(2,10,20, labels=c("Ctl","Trt"))
-weight <- c(ctl, trt)
-lm.D9 <- lm(weight ~ group)
-@
-<<results=tex>>=
-print(xtable(lm.D9),floating=FALSE)
-@
-
-
-<<results=tex>>=
-print(xtable(anova(lm.D9)),floating=FALSE)
-@
-
-\subsection{More glm}
-<<>>=
-
-## Demonstrate glm
-## Taken from help(glm) in R 1.1.1
-## Annette Dobson (1990) "An Introduction to Generalized Linear Models".
-## Page 93: Randomized Controlled Trial :
-counts <- c(18,17,15,20,10,20,25,13,12)
-outcome <- gl(3,1,9)
-treatment <- gl(3,3)
-d.AD <- data.frame(treatment, outcome, counts)
-glm.D93 <- glm(counts ~ outcome + treatment, family=poisson())
-@
-<<results=tex>>=
-print(xtable(glm.D93,align="r|llrc"),floating=FALSE)
-@
-
-\subsection{prcomp}
-<<prcomp>>=
-if(require(stats,quietly=TRUE)) {
-  ## Demonstrate prcomp
-  ## Taken from help(prcomp) in mva package of R 1.1.1
-  data(USArrests)
-  pr1 <- prcomp(USArrests)
-}
-@
-<<results=tex>>=
-if(require(stats,quietly=TRUE)) {
-  print(xtable(pr1),floating=FALSE)
-}
-@
-
-
-@
-<<results=tex>>=
-  print(xtable(summary(pr1)),floating=FALSE)
-@
-
-
-
-<<>>=
-#  ## Demonstrate princomp
-#  ## Taken from help(princomp) in mva package of R 1.1.1
-#  pr2 <- princomp(USArrests)
-#  print(xtable(pr2))
-@
-\subsection{Time series}
-
-<<>>=
-temp.ts <- ts(cumsum(1+round(rnorm(100), 0)), start = c(1954, 7), frequency=12)
-   temp.table <- xtable(temp.ts,digits=0)
-    caption(temp.table) <- "Time series example"
-@
-<<results=tex>>=
-    print(temp.table,floating=FALSE)
-@
-<<savetofile,echo=FALSE>>=
-if (FALSE) {
-  for(i in c("latex","html")) {
-    outFileName <- paste("xtable.",ifelse(i=="latex","tex",i),sep="")
-    print(xtable(lm.D9),type=i,file=outFileName,append=TRUE,latex.environments=NULL)
-    print(xtable(lm.D9),type=i,file=outFileName,append=TRUE,latex.environments="")
-    print(xtable(lm.D9),type=i,file=outFileName,append=TRUE,latex.environments="center")
-    print(xtable(anova(glm.D93,test="Chisq")),type=i,file=outFileName,append=TRUE)
-    print(xtable(anova(glm.D93)),hline.after=c(1),size="small",type=i,file=outFileName,append=TRUE)
-      # print(xtable(pr2),type=i,file=outFileName,append=TRUE)
-         }
-}
-@
-
-\section{Sanitization}
-<<>>=
-insane <- data.frame(Name=c("Ampersand","Greater than","Less than","Underscore","Per cent","Dollar","Backslash","Hash", "Caret", "Tilde","Left brace","Right brace"),
-				Character = I(c("&",">",		"<",		"_",		"%",		"$",		"\\", "#",	"^",		"~","{","}")))
-colnames(insane)[2] <- paste(insane[,2],collapse="")
-@
-
-<<pxti,results=tex>>=
-print( xtable(insane))
-@
-Sometimes you might want to have your own sanitization function
-<<>>=
-wanttex <- xtable(data.frame( label=paste("Value_is $10^{-",1:3,"}$",sep="")))
-@
-<<results=tex>>=
-print(wanttex,sanitize.text.function=function(str)gsub("_","\\_",str,fixed=TRUE))
-@
-
-\subsection{Markup in tables}
-
-Markup can be kept in tables, including column and row names, by using a custom sanitize.text.function:
-
-<<>>=
-mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4)
-rownames(mat) <- "$y_{t-1}$"
-colnames(mat) <- c("$R^2$", "$\\bar{R}^2$", "F-stat", "S.E.E", "DW")
-mat <- xtable(mat)
-@
-<<results=tex>>=
-print(mat, sanitize.text.function = function(x){x})
-@
-
-% By David Dahl to demonstrate contribution from David Whitting, 2007-10-09.
-You can also have sanitize functions that are specific to column or row names.  In the table below, the row name is not sanitized but column names and table elements are:
-<<>>=
-money <- matrix(c("$1,000","$900","$100"),ncol=3,dimnames=list("$\\alpha$",c("Income (US$)","Expenses (US$)","Profit (US$)")))
-@
-<<results=tex>>=
-print(xtable(money),sanitize.rownames.function=function(x) {x})
-@
-
-\section{Format examples}
-\subsection{Adding a centering environment }
-<<results=tex>>=
-   print(xtable(lm.D9,caption="\\tt latex.environments=NULL"),latex.environments=NULL)
-    print(xtable(lm.D9,caption="\\tt latex.environments=\"\""),latex.environments="")
-    print(xtable(lm.D9,caption="\\tt latex.environments=\"center\""),latex.environments="center")
-@
-\subsection{Column alignment}
-
-<<>>=
-tli.table <- xtable(tli[1:10,])
-@
-<<>>=
-align(tli.table) <- rep("r",6)
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE)
-@
-\subsubsection{Single string and column lines}
-<<>>=
-align(tli.table) <- "|rrl|l|lr|"
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE)
-@
-\subsubsection{Fixed width columns}
-<<>>=
-align(tli.table) <- "|rr|lp{3cm}l|r|"
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE)
-@
-
-\subsection{Significant digits}
-
-
-Specify with a single argument
-<<>>=
-digits(tli.table) <- 3
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE,)
-@
-
-
-or one for each column, counting the row names
-<<>>=
-digits(tli.table) <- 1:(ncol(tli)+1)
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE,)
-@
-
-
-or as a full matrix
-<<>>=
-digits(tli.table) <- matrix( 0:4, nrow = 10, ncol = ncol(tli)+1 )
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE,)
-@
-
-\subsection{Suppress row names}
-<<results=tex>>=
-print((tli.table),include.rownames=FALSE,floating=FALSE)
-@
-
-If you want a vertical line on the left, you need to change the align attribute.
-<<>>=
-align(tli.table) <- "|r|r|lp{3cm}l|r|"
-@
-<<results=tex>>=
-print((tli.table),include.rownames=FALSE,floating=FALSE)
-@
-
-Revert the alignment to what is was before.
-<<>>=
-align(tli.table) <- "|rr|lp{3cm}l|r|"
-@
-
-\subsection{Suppress column names}
-<<results=tex>>=
-print((tli.table),include.colnames=FALSE,floating=FALSE)
-@
-\\
-Note the doubled header lines which can be suppressed with, eg,
-<<results=tex>>=
-print(tli.table,include.colnames=FALSE,floating=FALSE,hline.after=c(0,nrow(tli.table)))
-@
-
-\subsection{Suppress row and column names}
-<<results=tex>>=
-print((tli.table),include.colnames=FALSE,include.rownames=FALSE,floating=FALSE)
-@
-
-\subsection{Rotate row and column names}
-The {\tt rotate.rownames } and {\tt rotate.colnames} arguments can be
-used to rotate the row and/or column names.
-
-<<results=tex>>=
-print((tli.table),rotate.rownames=TRUE,rotate.colnames=TRUE)
-@
-
-\subsection{Horizontal lines}
-
-\subsubsection{Line locations}
-
-Use the {\tt hline.after} argument to specify the position of the horizontal lines.
-
-<<results=tex>>=
-print(xtable(anova(glm.D93)),hline.after=c(1),floating=FALSE)
-@
-
-\subsubsection{Line styles}
-
-The \LaTeX package {\tt booktabs} can be used to specify different
-line style tags for top, middle, and bottom lines.  Specifying
-{\tt booktabs = TRUE} will lead to separate tags being generated
-for the three line types.
-
-Insert \verb|\usepackage{booktabs}| in your \LaTeX preamble and define
-the {\tt toprule}, {\tt midrule}, and {\tt bottomrule} tags to specify
-the line styles. By default, when no value is given for
-\texttt{hline.after}, a \texttt{toprule} will be drawn above the
-table, a \texttt{midrule} after the table headings and a
-\texttt{bottomrule} below the table. The width of the top and bottom
-rules can be set by supplying a value to \verb+\heavyrulewidth+. The
-width of the midrules can be set by supplying a value to
-\verb+\lightrulewidth+. The following tables have
-\verb+\heavyrulewidth = 2pt+ and \verb+\lightrulewidth = 0.5pt+, to
-ensure the difference in weight is noticeable.
-
-There is no support for \verb+\cmidrule+ or \verb+\specialrule+
-although they are part of the \texttt{booktabs} package.
-
-\heavyrulewidth = 2pt
-\lightrulewidth = 0.5pt
-
-<<results=tex>>=
-print(tli.table, booktabs=TRUE, floating = FALSE)
-@
-
-\vspace{12pt}
-If \texttt{hline.after} includes $-1$, a \texttt{toprule} will be
-drawn above the table. If \texttt{hline.after} includes the number of
-rows in the table, a \texttt{bottomrule} will be drawn below the
-table. For any other values specified in \texttt{hline.after}, a
-\texttt{midrule} will be drawn after that line of the table.
-
-The next table has more than one \texttt{midrule}.
-
-<<>>=
-bktbs <- xtable(matrix(1:10, ncol = 2))
-hlines <- c(-1,0,1,nrow(bktbs))
-@
-This command produces the required table.
-<<results=tex>>=
-print(bktbs, booktabs = TRUE, hline.after = hlines, floating = FALSE)
-@
-
-
-\subsection{Table-level \LaTeX}
-<<results=tex>>=
-print(xtable(anova(glm.D93)),size="small",floating=FALSE)
-@
-
-
-\subsection{Long tables}
-Remember to insert \verb|\usepackage{longtable}| in your \LaTeX preamble.
-
-<<longtable>>=
-
-## Demonstration of longtable support.
-x <- matrix(rnorm(1000), ncol = 10)
-x.big <- xtable(x,label='tabbig',
-	caption='Example of longtable spanning several pages')
-@
-<<results=tex>>=
-print(x.big,tabular.environment='longtable',floating=FALSE)
-@
-
-%%
-%% The column name alignment is off in the following example.
-%% It needs some revision before exposing it. - CR, 7/2/2012
-%%
-%
-%\subsubsection{Long tables with the header on each page}
-%
-%The {\tt add.to.row} argument can be used to display the header
-%for a long table on each page, and to add a "continued" footer
-%on all pages except the last page.
-%
-%<<results=tex>>=
-%library(xtable)
-%x<-matrix(rnorm(1000), ncol = 10)
-%addtorow<-list()
-%addtorow$pos<-list()
-%addtorow$pos[[1]]<-c(0)
-%addtorow$command<-c(paste(
-%    "\\hline \n",
-%    "  \\endhead \n",
-%    "  \\hline \n",
-%    "  {\\footnotesize Continued on next page} \n",
-%    "  \\endfoot \n",
-%    "  \\endlastfoot \n",sep=""))
-%x.big2 <- xtable(x, label = "tabbig2",
-%    caption = "Example of longtable with the header on each page")
-%print(x.big2, tabular.environment = "longtable", floating = FALSE,
-%include.rownames=FALSE, add.to.row=addtorow, hline.after=c(-1) )
-%@
-
-\subsection{Sideways tables}
-Remember to insert \verb|\usepackage{rotating}| in your LaTeX preamble.
-Sideways tables can't be forced in place with the `H' specifier, but you can
-use the \verb|\clearpage| command to get them fairly nearby.
-
-<<>>=
-x <- x[1:30,]
-x.small <- xtable(x,label='tabsmall',caption='A sideways table')
-@
-
-<<results=tex>>=
-print(x.small,floating.environment='sidewaystable')
-@
-\clearpage
-
-\subsection{Rescaled tables}
-Specify a {\tt scalebox} value to rescale the table.
-
-<<>>=
-x <- x[1:20,]
-x.rescale <- xtable(x,label='tabrescaled',caption='A rescaled table')
-@
-
-<<results=tex>>=
-print(x.rescale, scalebox=0.7)
-@
-
-\subsection{Table Width}
-The {\tt tabularx} tabular environment provides more alignment options,
-and has a {\tt width} argument to specify the table width.
-
-Remember to insert \verb|\usepackage{tabularx}| in your \LaTeX preamble.
-
-<<>>=
-df.width <- data.frame(
-  "label 1 with much more text than is needed" = c("item 1", "A"),
-  "label 2 is also very long" = c("item 2","B"),
-  "label 3" = c("item 3","C"),
-  "label 4" = c("item 4 but again with too much text","D"),
-  check.names = FALSE)
-
-x.width <- xtable(df.width,
-  caption="Using the 'tabularx' environment")
-align(x.width) <- "|l|X|X|l|X|"
-@
-
-<<results=tex>>=
-print(x.width, tabular.environment="tabularx",
-  width="\\textwidth")
-@
-
-\section{Suppressing Printing}
-By default the {\tt print} method will print the LaTeX or HTML to standard
-output and also return the character strings invisibly.  The printing to
-standard output can be suppressed by specifying {\tt print.results = FALSE}.
-
-<<>>=
-x.out <- print(tli.table, print.results = FALSE)
-@
-
-Formatted output can also be captured without printing with the
-{\tt toLatex} method.  This function returns an object of class
-{\tt "Latex"}.
-
-<<>>=
-x.ltx <- toLatex(tli.table)
-class(x.ltx)
-x.ltx
-@
-
-\section{Acknowledgements}
-Most of the examples in this gallery are taken from the {\tt xtable} documentation.
-\section{R Session information}
-<<results=tex>>=
-toLatex(sessionInfo())
-@
-\end{document}
diff --git a/man/autoformat.Rd b/man/autoformat.Rd
new file mode 100644
index 0000000..1e52242
--- /dev/null
+++ b/man/autoformat.Rd
@@ -0,0 +1,75 @@
+\name{autoformat}
+\alias{autoformat}
+\alias{xalign}
+\alias{xdigits}
+\alias{xdisplay}
+\title{Automatically Format Export Tables}
+\description{
+  Suggest an appropriate alignment, number of digits, and display type
+  for \code{xtable}.
+}
+\usage{
+autoformat(xtab, zap = getOption("digits"))
+
+xalign(x, pad = TRUE)
+xdigits(x, pad = TRUE, zap = getOption("digits"))
+xdisplay(x, pad = TRUE)
+}
+\arguments{
+  \item{xtab}{an object of class \code{xtable}.}
+  \item{x}{a vector, matrix, or data frame.}
+  \item{pad}{whether to format row names, when \code{x} is
+    two-dimensional.}
+  \item{zap}{the number of digits passed to \code{zapsmall}.}
+}
+\value{
+  \code{autoformat} returns a copy of \code{xtab}, after applying
+  \code{xalign}, \code{xdigits}, and \code{xdisplay}.
+
+  \code{xalign} returns a character vector consisting of \code{"l"} and
+  \code{"r"} elements, for left/right alignment.
+
+  \code{xdigits} returns an integer vector.
+
+  \code{xdisplay} returns a character vector of \code{"d"}, \code{"f"},
+  and \code{"s"} elements, for integer/double/string display.
+}
+\author{Arni Magnusson.}
+\seealso{
+  \code{\link{xtable}}, \code{\link{align}}, \code{\link{digits}},
+  \code{\link{display}}
+}
+\examples{
+## 1  Vector
+xalign(precip)
+xdigits(precip)
+xdisplay(precip)
+
+
+## 2  Data frame
+head(mtcars)
+xdigits(mtcars, pad = FALSE)
+xdigits(mtcars, pad = TRUE)
+xalign(mtcars)
+xdisplay(mtcars)
+
+
+## 3  Autoformat when xtable is created
+xtable(mtcars, align = xalign(mtcars), digits = xdigits(mtcars),
+       display = xdisplay(mtcars))
+
+## equivalent shortcut
+xtable(mtcars, auto = TRUE)
+
+
+## 4  Autoformat existing xtable
+mt <- xtable(mtcars)
+align(mt) <- xalign(mt)
+digits(mt) <- xdigits(mt)
+display(mt) <- xdisplay(mt)
+
+## equivalent shortcut
+mt <- autoformat(mt)
+}
+\keyword{array}
+\keyword{print}
diff --git a/man/print.xtable.Rd b/man/print.xtable.Rd
index aeda298..ce44b4d 100644
--- a/man/print.xtable.Rd
+++ b/man/print.xtable.Rd
@@ -30,6 +30,7 @@
   sanitize.colnames.function = getOption("xtable.sanitize.colnames.function",
                                          sanitize.text.function),
   math.style.negative = getOption("xtable.math.style.negative", FALSE),
+  math.style.exponents = getOption("xtable.math.style.exponents", FALSE),
   html.table.attributes = getOption("xtable.html.table.attributes",
                                     "border=1"),
   print.results = getOption("xtable.print.results", TRUE),
@@ -44,7 +45,7 @@
   ...)}
 \arguments{
   \item{x}{An object of class \code{"xtable"}.}
-  \item{type}{Type of table to produce.  Possible values for \code{type}
+  \item{type}{Type of table to produce. Possible values for \code{type}
     are \code{"latex"} or \code{"html"}.
     Default value is \code{"latex"}.}
   \item{file}{Name of file where the resulting code should be saved.  If
@@ -71,7 +72,7 @@
     \code{NULL} or contain only elements of
     \{"h","t","b","p","!","H"\}.
     Default value is \code{"ht"}.}
-  \item{caption.placement}{The caption will be have placed at the bottom
+  \item{caption.placement}{The caption will be placed at the bottom
     of the table if \code{caption.placement} is \code{"bottom"} and at
     the top of the table if it equals \code{"top"}.
     Default value is \code{"bottom"}.}
@@ -79,55 +80,56 @@
     of the specified width if \code{caption.width} is not \code{NULL} and
 	\code{type="latex"}. Default value is \code{NULL}.}
   \item{latex.environments}{If \code{floating=TRUE} and
-    \code{type="latex"}, the specificed latex environments (provided as
+    \code{type="latex"}, the specified LaTeX environments (provided as
     a character vector) will enclose the tabular environment.
     Default value is \code{"center"}. }
   \item{tabular.environment}{When \code{type="latex"}, the tabular
     environment that will be used.
-    Defaults to \code{"tabular"}.
     When working with tables that extend more than one page, using
-    \code{tabular.environment="longtable"} and the LaTeX package
-    \code{"longtable"} (see Fairbairns, 2005) allows one to typeset them
-    uniformly. Note that \code{"floating"} should be set to
-    \code{"FALSE"} when using the \code{"longtable"} environment.}
-  \item{size}{An arbitrary character vector intended to be used to set
-    the font size in a LaTeX table.  The supplied value (if not
-    \code{NULL}) is inserted just before the tabular environment
-    starts.
+    \code{tabular.environment="longtable"} with the corresponding
+    LaTeX package (see Fairbairns, 2005) allows one to typeset them
+    uniformly. Note that \code{floating} should be set to
+    \code{FALSE} when using the \code{longtable} environment.
+    Default value is \code{"tabular"}.}
+  \item{size}{A character vector that is inserted just before the
+    tabular environment starts. This can be used to set the font size
+    and a variety of other table settings. Initial backslashes are
+    automatically prefixed, if not supplied by user.
     Default value is \code{NULL}. }
   \item{hline.after}{When \code{type="latex"}, a vector of numbers
-    between -1 and \code{"nrow(x)"}, inclusive, indicating the rows
+    between -1 and \code{nrow(x)}, inclusive, indicating the rows
     after which a horizontal line should appear.  If \code{NULL} is used
-    no lines are produced.
+    no lines are produced. Repeated values are allowed.
     Default value is \code{c(-1,0,nrow(x))} which means draw a line
     before and after the columns names and at the end of the
-    table. Repeated values are allowed.}
+    table.}
   \item{NA.string}{String to be used for missing values in table
     entries.
     Default value is \code{""}.}
-  \item{include.rownames}{logical. If \code{TRUE} the rows names is
+  \item{include.rownames}{If \code{TRUE} the rows names are
     printed.
     Default value is \code{TRUE}.}
-  \item{include.colnames}{logical. If \code{TRUE} the columns names is
+  \item{include.colnames}{If \code{TRUE} the columns names are
     printed.
     Default value is \code{TRUE}.}
-  \item{only.contents}{logical. If \code{TRUE} only the rows of the
-    table is printed.
+  \item{only.contents}{If \code{TRUE} only the rows of the
+    table are printed.
     Default value is \code{FALSE}. }
-  \item{add.to.row}{a list of two components. The first component (which
-    should be called 'pos') is a list contains the position of rows on
-    which extra commands should be added at the end, The second
+  \item{add.to.row}{A list of two components. The first component (which
+    should be called 'pos') is a list that contains the position of rows on
+    which extra commands should be added at the end. The second
     component (which should be called 'command') is a character vector
-    of the same length of the first component which contains the command
+    of the same length as the first component, which contains the command
     that should be added at the end of the specified rows.
     Default value is \code{NULL}, i.e. do not add commands.}
-  \item{sanitize.text.function}{All non-numeric enteries (except row and
-    column names) are sanitised in an attempt to remove characters which
+  \item{sanitize.text.function}{All non-numeric entries (except row and
+    column names) are sanitized in an attempt to remove characters which
     have special meaning for the output format. If
-    \code{sanitize.text.function} is not NULL (the default), it should
+    \code{sanitize.text.function} is not \code{NULL}, it should
     be a function taking a character vector and returning one, and will
     be used for the sanitization instead of the default internal
-    function.}
+    function.
+    Default value is \code{NULL}.}
   \item{sanitize.rownames.function}{Like the
     \code{sanitize.text.function}, but applicable to row names.
     The default uses the \code{sanitize.text.function}. }
@@ -137,37 +139,50 @@
   \item{math.style.negative}{In a LaTeX table, if \code{TRUE}, then use
     $-$ for the negative sign (as was the behavior prior to version 1.5-3).
     Default value is \code{FALSE}.}
+  \item{math.style.exponents}{In a LaTeX table, if \code{TRUE} or
+    \code{"$$"}, then use \verb{$5 \times 10^{5}$} for 5e5. If
+    \code{"ensuremath"}, then use \verb{\\ensuremath{5 \times 10^{5}}}
+    for 5e5. If \code{"UTF-8"} or \code{"UTF-8"}, then use UTF-8 to
+    approximate the LaTeX typsetting for 5e5.
+    Default value is \code{FALSE}.}
   \item{html.table.attributes}{In an HTML table, attributes associated
-    with the \code{<TABLE>}tag.
-    Default value is \code{border=1}.}
+    with the \code{<TABLE>} tag.
+    Default value is \code{"border=1"}.}
   \item{print.results}{If \code{TRUE}, the generated table is printed to
     standard output.  Set this to \code{FALSE} if you will just be using
-    the character vector that is returned invisibly.}
+    the character vector that is returned invisibly.
+  Default value is \code{TRUE}.}
   \item{format.args}{List of arguments for the \code{formatC} function.
     For example, standard German number separators can be specified as
     \code{format.args=list(big.mark = "'", decimal.mark =
-      ","))}. \code{digits} and \code{format} arguments should not be
-    included in this list. See details. }
+      ","))}. The arguments \code{digits} and \code{format} should not be
+    included in this list. See details.
+    Default value is \code{NULL}.}
   \item{rotate.rownames}{If \code{TRUE}, the row names are displayed
-    vertically in LaTeX. }
+    vertically in LaTeX.
+    Default value is \code{FALSE}.}
   \item{rotate.colnames}{If \code{TRUE}, the column names are displayed
-    vertically in LaTeX. }
+    vertically in LaTeX.
+    Default value is \code{FALSE}.}
   \item{booktabs}{If \code{TRUE}, the \code{toprule}, \code{midrule} and
-    \code{bottomrule} tags from the LaTex "booktabs" package are used
+    \code{bottomrule} commands from the LaTeX "booktabs" package are used
     rather than \code{hline} for the horizontal line tags. }
   \item{scalebox}{If not \code{NULL}, a \code{scalebox} clause will be
     added around the tabular environment with the specified value used
-    as the scaling factor. }
+    as the scaling factor.
+    Default value is \code{NULL}.}
   \item{width}{If not \code{NULL}, the specified value is included in
-    parenthesis between the tabular environment \code{begin} tag and the
+    parentheses between the tabular environment \code{begin} tag and the
     alignment specification.  This allows specification of the table
     width when using tabular environments such as \code{tabular*} and
     \code{tabularx}.  Note that table width specification is not
-    supported with the \code{tabular} or \code{longtable} environments. }
+    supported with the \code{tabular} or \code{longtable} environments.
+    Default value is \code{NULL}.}
   \item{comment}{If \code{TRUE}, the version and timestamp comment is
     included.  Default value is \code{TRUE}. }
   \item{timestamp}{Timestamp to include in LaTeX comment.  Set this
-    to \code{NULL} to exclude the timestamp. Default value is \code{date()}. }
+    to \code{NULL} to exclude the timestamp. Default value is
+    \code{date()}. }
   \item{...}{Additional arguments.  (Currently ignored.) }
 }
 \details{
@@ -184,21 +199,21 @@
   where \code{nrow(x)} is the numbers of rows of the object.
 
   From version 1.4-3, all non-numeric columns are sanitized, and all
-  LaTeX special characters are sanitised for LaTeX output.  See Section
-  3 of the \code{xtableGallery} vignette for an example of customising
+  LaTeX special characters are sanitized for LaTeX output.  See Section
+  3 of the \code{xtableGallery} vignette for an example of customizing
   the sanitization. From version 1.4-4, the sanitization also applies to
   column names.  To remove any text sanitization, specify
   \code{sanitize.text.function=function(x){x}}.
 
   From version 1.6-1 the default values for the arguments other than
-  \code{x} are obtainined using \code{getOption()}.  Hence the user can
+  \code{x} are obtained using \code{getOption()}.  Hence the user can
   set the values once with \code{options()} rather than setting them in
   every call to \code{print.xtable()}.
 
   The argument \code{format.args} is used to supply arguments to the
   \code{formatC} function, but will throw an error if values for
   \code{digits} or \code{format} are included in the list of
-  arguments. The recommended approach is to specify \code{digits} supply
+  arguments. The recommended approach to specify \code{digits} is to supply
   the argument \code{digits} to \code{xtable}, and to specify
   \code{format} supply the argument \code{display} to \code{xtable}. See
   the examples.
@@ -208,7 +223,7 @@
   suggestions from many others (see source code).
 }
 \references{
-  Fairbairns, Robin (2005) \emph{Tables longer than a single page} The
+  Fairbairns, Robin (2005) \emph{Tables longer than a single page.} The
   UK List of TeX Frequently Asked Questions on the
   Web. \url{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=longtab}
 }
diff --git a/man/print.xtableMatharray.Rd b/man/print.xtableMatharray.Rd
new file mode 100644
index 0000000..b521e26
--- /dev/null
+++ b/man/print.xtableMatharray.Rd
@@ -0,0 +1,96 @@
+\name{print.xtableMatharray}
+\alias{print.xtableMatharray}
+\title{Print Math Array}
+\description{
+  For an object of class \code{"xtableMatharray"}, returns the LaTeX
+  commands to produce an array.
+}
+\usage{
+\method{print}{xtableMatharray}(x,
+  print.results = TRUE,
+  format.args = getOption("xtable.format.args", NULL),
+  scalebox = getOption("xtable.scalebox", NULL),
+  comment = FALSE,
+  timestamp = NULL,
+  ...)
+}
+\arguments{
+  \item{x}{An object of class \code{"xtableMatharray"}.}
+  \item{print.results}{If \code{TRUE}, the generated table is printed to
+    standard output.  Set this to \code{FALSE} if you will just be using
+    the character vector that is returned invisibly.
+    Default value is \code{TRUE}.}
+  \item{format.args}{List of arguments for the \code{formatC} function.
+    For example, standard German number separators can be specified as
+    \code{format.args=list(big.mark = "'", decimal.mark = ",")}. The
+    arguments \code{digits} and \code{format} should not be included in
+    this list. See details for function \code{\link{print.xtable}}.
+    Default value is \code{NULL}.}
+  \item{scalebox}{If not \code{NULL}, a \code{scalebox} clause will be
+    added around the tabular environment with the specified value used
+    as the scaling factor.
+    Default value is \code{NULL}.}
+  \item{comment}{If \code{TRUE}, the version and timestamp comment is
+    included.  Default value is \code{FALSE}. }
+  \item{timestamp}{Timestamp to include in LaTeX comment.  Set this
+    to \code{NULL} to exclude the timestamp. Default value is \code{NULL}. }
+  \item{...}{Additional arguments.  (Currently ignored.) }
+}
+\details{
+ This command prints an array of numbers which may be included in a
+ mathematical expression in a LaTeX document created using \pkg{Sweave}
+ or \pkg{knitr}. Internally it calls \code{print.data.frame} but with
+ special values for the arguments, namely that the tabular environment
+ is \code{array}, row names and column names are not included, and there
+ are no horizontal lines. Note that the default values for the arguments
+ \code{comment} and \code{timestamp} are different to the default values
+ for \code{print.xtable}, the justification being that comments would
+ make the resulting LaTeX harder to read.
+}
+\value{
+  A character vector containing the LaTeX code for incorporating an
+  array in a mathematical expression.
+}
+
+\author{
+  David Scott \email{d.scott at auckland.ac.nz}.
+}
+\seealso{
+  \code{\link{print.xtable}}
+}
+
+\examples{
+V <- matrix(c(1.140380e-03,  3.010497e-05,  7.334879e-05,
+              3.010497e-05,  3.320683e-04, -5.284854e-05,
+              7.334879e-05, -5.284854e-05,  3.520928e-04), nrow = 3)
+### Simple test of print.xtableMatharray
+print.xtableMatharray(xtable(V, display = rep("E", 4)))
+
+class(V) <- c("xtableMatharray")
+class(V)
+
+### Test without any additional arguments
+mth <- xtableMatharray(V)
+str(mth)
+print(mth)
+
+### Test with arguments to xtable
+mth <- xtableMatharray(V, display = rep("E", 4))
+str(mth)
+print(mth)
+
+mth <- xtableMatharray(V, digits = 6)
+str(mth)
+print(mth)
+
+### Test with additional print.xtableMatharray arguments
+mth <- xtableMatharray(V, digits = 6)
+str(mth)
+print(mth, format.args = list(decimal.mark = ","))
+print(mth, scalebox = 0.5)
+print(mth, comment = TRUE)
+print(mth, timestamp = "2000-01-01")
+print(mth, comment = TRUE, timestamp = "2000-01-01")
+}
+
+\keyword{print}
diff --git a/man/sanitize.Rd b/man/sanitize.Rd
new file mode 100644
index 0000000..f228a6d
--- /dev/null
+++ b/man/sanitize.Rd
@@ -0,0 +1,105 @@
+\name{sanitize}
+\alias{sanitize}
+\alias{sanitize.numbers}
+\alias{sanitize.final}
+\alias{as.is}
+\alias{as.math}
+
+\title{
+  Sanitization Functions
+}
+\description{
+  Functions for sanitizing elements of a table produced by
+  \pkg{xtable}. Used for dealing with characters which have special
+  meaning in the output format.
+}
+\usage{
+sanitize(str, type = "latex")
+sanitize.numbers(str, type, math.style.negative = FALSE,
+                 math.style.exponents = FALSE)
+sanitize.final(str, type)
+as.is(str)
+as.math(str, ...)
+}
+
+\arguments{
+  \item{str}{A character object to be sanitized.}
+  \item{type}{Type of table to produce. Possible values for \code{type}
+    are \code{"latex"} or \code{"html"}.
+    Default value is \code{"latex"}.}
+  \item{math.style.negative}{In a LaTeX table, if \code{TRUE}, then use
+    $-$ for the negative sign (as was the behavior prior to version 1.5-3).
+    Default value is \code{FALSE}.}
+  \item{math.style.exponents}{In a LaTeX table, if \code{TRUE} or
+    \code{"$$"}, then use \verb{$5 \times 10^{5}$} for 5e5. If
+    \code{"ensuremath"}, then use \verb{\ensuremath{5 \times 10^{5}}}
+    for 5e5. If \code{"UTF-8"} or \code{"UTF-8"}, then use UTF-8 to
+    approximate the LaTeX typsetting for 5e5.
+    Default value is \code{FALSE}.}
+  \item{\dots}{Additional arguments. Character strings or character
+    vectors.}
+}
+\details{
+
+  If \code{type} is \code{"latex"}, \code{sanitize()} will replace
+  special characters such as \verb{&} and the like by strings which will
+  reproduce the actual character, e.g. \verb{&} is replaced by
+  \verb{\\&}.
+
+  If \code{type} is \code{"html"}, \code{sanitize()} will replace
+  special characters such as \verb{<} and the like by strings which will
+  reproduce the actual character, e.g. \verb{<} is replaced by
+  \verb{<}.
+
+  When \code{math.style.negative} is \code{TRUE}, and \code{type} is
+  \code{"latex"}, $-$ is used for the negative sign rather than a
+  simple hyphen (-). No effect when \code{type} is \code{"html"}.
+
+  When \code{type} is \code{"latex"}, and \code{math.style.exponents}
+  is \code{TRUE} or \verb{"$$"}, then use \verb{$5 \times 10^{5}$} for
+  5e5. If \code{"ensuremath"}, then use \verb{\ensuremath{5 \times
+  10^{5}}} for 5e5. If \code{"UTF-8"} or \code{"UTF-8"}, then use UTF-8
+  to approximate the LaTeX typsetting for 5e5.
+
+  When \code{type} is \code{"latex"} \code{sanitize.final} has no
+  effect. When \code{type} is \code{"html"}, multiple spaces are
+  replaced by a single space and occurrences of \code{' align="left"'}
+  are eliminated.
+
+  \code{as.is} and \code{as.math} are trivial helper functions to
+  disable sanitizing and to insert a some mathematics in a string
+  respectively.
+}
+\value{
+  Returns the sanitized character object.
+}
+
+\author{
+  Code was extracted from \code{print.xtable()}, in version 1.8.0 of
+  \pkg{xtable}. Various authors contributed the original code: Jonathan
+  Swinton <jonathan at swintons.net>, Uwe Ligges
+  <ligges at statistik.uni-dortmund.de>, and probably David B. Dahl
+  <dahl at stat.byu.edu>.
+  \code{as.is} and \code{as.math} suggested and provided by Stefan
+  Edwards <sme at iysik.com>.
+}
+
+\examples{
+insane <- c("&",">", ">","_","\%","$","\\\\","#","^","~","{","}")
+names(insane) <- c("Ampersand","Greater than","Less than",
+                   "Underscore","Percent","Dollar",
+                   "Backslash","Hash","Caret","Tilde",
+                   "Left brace","Right brace")
+sanitize(insane, type = "latex")
+insane <- c("&",">","<")
+names(insane) <- c("Ampersand","Greater than","Less than")
+sanitize(insane, type = "html")
+x <- rnorm(10)
+sanitize.numbers(x, "latex", TRUE)
+sanitize.numbers(x*10^(10), "latex", TRUE, TRUE)
+sanitize.numbers(x, "html", TRUE, TRUE)
+as.is(insane)
+as.math("x10^10", ": mathematical expression")
+}
+
+\keyword{print }
diff --git a/man/string.Rd b/man/string.Rd
index c117fcf..88e9d2f 100644
--- a/man/string.Rd
+++ b/man/string.Rd
@@ -25,6 +25,9 @@
   These functions are private functions used by \code{print.xtable}.  They are
   not intended to be used elsewhere.
 }
-\author{David Dahl \email{dahl at stat.byu.edu} with contributions and suggestions from many others (see source code).}
+\author{
+  David Dahl \email{dahl at stat.byu.edu} with contributions and
+  suggestions from many others (see source code).
+}
 \seealso{\code{\link{print.xtable}}}
 \keyword{print}
diff --git a/man/table.attributes.Rd b/man/table.attributes.Rd
index d9da8a7..7d0b6e3 100644
--- a/man/table.attributes.Rd
+++ b/man/table.attributes.Rd
@@ -43,5 +43,10 @@
   \code{xtable} for a description of the options.
 }
 \author{David Dahl \email{dahl at stat.byu.edu} with contributions and suggestions from many others (see source code).}
-\seealso{\code{\link{xtable}}, \code{\link{print.xtable}}, \code{\link{formatC}}}
+\seealso{
+  \code{\link{xtable}}, \code{\link{print.xtable}}
+
+  \code{\link{autoformat}}, \code{\link{xalign}}, \code{\link{xdigits}},
+  \code{\link{xdisplay}}
+}
 \keyword{print}
diff --git a/man/tli.Rd b/man/tli.Rd
index f6c2b43..b1cfb72 100644
--- a/man/tli.Rd
+++ b/man/tli.Rd
@@ -7,7 +7,8 @@ This data set contains math scores and demographic data of
 Assessment of Academic Skills (TAAS).
 }
 \usage{data(tli)}
-\format{A data.frame containing 100 observations with the following columns:
+\format{A \code{data.frame} containing 100 observations with the
+  following columns:
         \describe{
           \item{\code{grade}}{Year in school of student}
           \item{\code{sex}}{Gender of student}
diff --git a/man/xtable-internal.Rd b/man/xtable-internal.Rd
new file mode 100644
index 0000000..a57ab00
--- /dev/null
+++ b/man/xtable-internal.Rd
@@ -0,0 +1,13 @@
+\name{xtable-internal}
+\alias{xtableLSMeans}
+\alias{lagImpactMat}
+
+\title{Internal xtable Functions}
+\description{
+  Internal functions for the package xtable
+}
+\details{
+  Functions which are either not intended to be called by the user or
+  are waiting to be documented.
+}
+\keyword{ internal }
diff --git a/man/xtable.Rd b/man/xtable.Rd
index 005382c..3277d56 100644
--- a/man/xtable.Rd
+++ b/man/xtable.Rd
@@ -7,6 +7,7 @@
 \alias{xtable.glm}
 \alias{xtable.lm}
 \alias{xtable.matrix}
+\alias{xtable.xtableMatharray}
 \alias{xtable.prcomp}
 \alias{xtable.coxph}
 \alias{xtable.summary.aov}
@@ -17,27 +18,43 @@
 \alias{xtable.ts}
 \alias{xtable.table}
 \alias{xtable.zoo}
+\alias{xtable.sarlm}
+\alias{xtable.summary.sarlm}
+\alias{xtable.gmsar}
+\alias{xtable.summary.gmsar}
+\alias{xtable.stsls}
+\alias{xtable.summary.stsls}
+\alias{xtable.sarlm.pred}
+%%%\alias{xtable.lagImpact}
+\alias{xtable.splm}
+\alias{xtable.summary.splm}
+\alias{xtable.sphet}
+\alias{xtable.summary.sphet}
+\alias{xtable.spautolm}
+\alias{xtable.summary.spautolm}
+
+
 \title{Create Export Tables}
 \description{
-  Function converting an R object to an \code{xtable} object, which can
+  Convert an \R object to an \code{xtable} object, which can
   then be printed as a LaTeX or HTML table.
 }
 \usage{
 xtable(x, caption = NULL, label = NULL, align = NULL, digits = NULL,
-       display = NULL, ...)
+       display = NULL, auto = FALSE, ...)
 }
 \arguments{
-  \item{x}{An R object of class found among \code{methods(xtable)}.  See
+  \item{x}{An \R object of class found among \code{methods(xtable)}.  See
     below on how to write additional method functions for \code{xtable}.}
   \item{caption}{Character vector of length 1 or 2 containing the
-    table's caption or title.  If length 2, the second item is the
+    table's caption or title.  If length is 2, the second item is the
     "short caption" used when LaTeX generates a "List of Tables". Set to
     \code{NULL} to suppress the caption.  Default value is \code{NULL}. }
   \item{label}{Character vector of length 1 containing the LaTeX label
     or HTML anchor. Set to \code{NULL} to suppress the label.  Default
     value is \code{NULL}. }
   \item{align}{Character vector of length equal to the number of columns
-    of the resulting table indicating the alignment of the corresponding
+    of the resulting table, indicating the alignment of the corresponding
     columns.  Also, \code{"|"} may be used to produce vertical lines
     between columns in LaTeX tables, but these are effectively ignored
     when considering the required length of the supplied vector.  If a
@@ -47,7 +64,7 @@ xtable(x, caption = NULL, label = NULL, align = NULL, digits = NULL,
     one greater than \code{ncol(x)} if \code{x} is a
     \code{data.frame}. Use \code{"l"}, \code{"r"}, and \code{"c"} to
     denote left, right, and center alignment, respectively.  Use
-    \code{"p\{3cm\}"} etc for a LaTeX column of the specified width. For
+    \code{"p{3cm}"} etc. for a LaTeX column of the specified width. For
     HTML output the \code{"p"} alignment is interpreted as \code{"l"},
     ignoring the width request. Default depends on the class of
     \code{x}. }
@@ -55,17 +72,17 @@ xtable(x, caption = NULL, label = NULL, align = NULL, digits = NULL,
     Numeric vector of length equal to one (in which case it will be
     replicated as necessary) or to the number of columns of the
     resulting table \bold{or} matrix of the same size as the resulting
-    table indicating the number of digits to display in the
+    table, indicating the number of digits to display in the
     corresponding columns. Since the row names are printed in the first
     column, the length of the vector \code{digits} or the number of
     columns of the matrix \code{digits} is one greater than
     \code{ncol(x)} if \code{x} is a \code{data.frame}. Default depends
-    of class of \code{x}. If values of \code{digits} are negative, the
+    on the class of \code{x}. If values of \code{digits} are negative, the
     corresponding values of \code{x} are displayed in scientific format
     with \code{abs(digits)} digits.}
   \item{display}{
     Character vector of length equal to the number of columns of the
-    resulting table indicating the format for the corresponding columns.
+    resulting table, indicating the format for the corresponding columns.
     Since the row names are printed in the first column, the length of
     \code{display} is one greater than \code{ncol(x)} if \code{x} is a
     \code{data.frame}.  These values are passed to the \code{formatC}
@@ -79,6 +96,12 @@ xtable(x, caption = NULL, label = NULL, align = NULL, digits = NULL,
     but \code{digits} as number of \emph{significant} digits.  Note that
     this can lead to quite long result strings.  Default depends on the
     class of \code{x}.}
+  \item{auto}{
+    Logical, indicating whether to apply automatic format when no value
+    is passed to \code{align}, \code{digits}, or \code{display}. This
+    \sQuote{autoformat} (based on \code{xalign}, \code{xdigits}, and
+    \code{xdisplay}) can be useful to quickly format a typical
+    \code{matrix} or \code{data.frame}. Default value is \code{FALSE}.}
   \item{...}{Additional arguments.  (Currently ignored.)}
 }
 \details{
@@ -87,35 +110,38 @@ xtable(x, caption = NULL, label = NULL, align = NULL, digits = NULL,
   an object of class \code{"xtable"}.  The nature of the table generated
   depends on the class of \code{x}.  For example, \code{aov} objects
   produce ANOVA tables while \code{data.frame} objects produce a table
-  of the entire data.frame.  One can optionally provide a caption
-  (called a title in HTML) or label (called an anchor in HTML), as well
+  of the entire data frame.  One can optionally provide a caption
+  or label (called an anchor in HTML), as well
   as formatting specifications.  Default values for \code{align},
   \code{digits}, and \code{display} are class dependent.
 
   The available method functions for \code{xtable} are given by
   \code{methods(xtable)}.  Users can extend the list of available
   classes by writing methods for the generic function \code{xtable}.
-  These methods functions should have \code{x} as their first argument
+  These methods functions should have \code{x} as their first argument,
   with additional arguments to specify \code{caption}, \code{label},
   \code{align}, \code{digits}, and \code{display}.  Optionally, other
-  arguments may be present to specify how the object \code{x} should be
+  arguments may be passed to specify how the object \code{x} should be
   manipulated.  All method functions should return an object whose class
-  if given by \code{c("xtable","data.frame")}.  The resulting object can
+  is \code{c("xtable","data.frame")}.  The resulting object can
   have attributes \code{caption} and \code{label}, but must have
-  attributes \code{align}, \code{digits}, and \code{display}.  It is
-  strongly recommened that you set these attributes through the provided
-  replacement functions as they perform validity checks.
-  }
-  \value{An object of class \code{"xtable"} which inherits the
-  \code{data.frame} class and contains several additional attributes
-  specifying the table formatting options.
+  attributes \code{align}, \code{digits}, and \code{display}.
+}
+\value{
+  For most \code{xtable} methods, an object of class \code{"xtable"}
+  which inherits the \code{data.frame} class and contains several
+  additional attributes specifying the table formatting options.
+
 }
 \author{David Dahl \email{dahl at stat.byu.edu} with contributions and
   suggestions from many others (see source code).
 }
-\seealso{\code{\link{print.xtable}}, \code{\link{caption}},
+\seealso{
+  \code{\link{print.xtable}}, \code{\link{caption}},
   \code{\link{label}}, \code{\link{align}}, \code{\link{digits}},
-  \code{\link{display}}, \code{\link{formatC}}, \code{\link{methods}}
+  \code{\link{display}}, \code{\link{autoformat}}, \code{\link{xalign}},
+  \code{\link{xdigits}}, \code{\link{xdisplay}},
+  \code{\link{xtableMatharray}}, \code{\link{xtableList}}
 }
 \examples{
 
@@ -124,19 +150,21 @@ data(tli)
 
 ## Demonstrate data.frame
 tli.table <- xtable(tli[1:20, ])
-digits(tli.table)[c(2, 6)] <- 0
 print(tli.table)
 print(tli.table, type = "html")
+xtable(mtcars)
+xtable(mtcars, auto = TRUE)
 
 ## Demonstrate data.frame with different digits in cells
 tli.table <- xtable(tli[1:20, ])
-digits(tli.table) <- matrix( 0:4, nrow = 20, ncol = ncol(tli)+1 )
+display(tli.table)[c(2,6)] <- "f"
+digits(tli.table) <- matrix(0:4, nrow = 20, ncol = ncol(tli)+1)
 print(tli.table)
 print(tli.table, type = "html")
 
 ## Demonstrate matrix
 design.matrix <- model.matrix(~ sex*grade, data = tli[1:20, ])
-design.table <- xtable(design.matrix)
+design.table <- xtable(design.matrix, auto = TRUE)
 print(design.table)
 print(design.table, type = "html")
 
diff --git a/man/xtableFtable.Rd b/man/xtableFtable.Rd
new file mode 100644
index 0000000..2e743b1
--- /dev/null
+++ b/man/xtableFtable.Rd
@@ -0,0 +1,347 @@
+\name{xtableFtable}
+\alias{xtableFtable}
+\alias{print.xtableFtable}
+
+\title{
+  Create and Export Flat Tables
+}
+\description{
+  \code{xtableFtable} creates an object which contains information about
+  a flat table which can be used by \code{print.xtableFtable} to produce
+  a character string which when included in a document produces a nicely
+  formatted flat table.
+}
+\usage{
+xtableFtable(x, caption = NULL, label = NULL,
+             align = NULL, digits = 0, display = NULL,
+             quote = FALSE,
+             method = c("non.compact", "row.compact",
+                         "col.compact", "compact"),
+             lsep = " $\\\\vert$ ", ...)
+
+\method{print}{xtableFtable}(x,
+  type = getOption("xtable.type", "latex"),
+  file = getOption("xtable.file", ""),
+  append = getOption("xtable.append", FALSE),
+  floating = getOption("xtable.floating", TRUE),
+  floating.environment = getOption("xtable.floating.environment", "table"),
+  table.placement = getOption("xtable.table.placement", "ht"),
+  caption.placement = getOption("xtable.caption.placement", "bottom"),
+  caption.width = getOption("xtable.caption.width", NULL),
+  latex.environments = getOption("xtable.latex.environments", c("center")),
+  tabular.environment = getOption("xtable.tabular.environment", "tabular"),
+  size = getOption("xtable.size", NULL),
+  hline.after = getOption("xtable.hline.after", NULL),
+  NA.string = getOption("xtable.NA.string", ""),
+  only.contents = getOption("xtable.only.contents", FALSE),
+  add.to.row = getOption("xtable.add.to.row", NULL),
+  sanitize.text.function = getOption("xtable.sanitize.text.function", as.is),
+  sanitize.rownames.function = getOption("xtable.sanitize.rownames.function",
+                                         sanitize.text.function),
+  sanitize.colnames.function = getOption("xtable.sanitize.colnames.function",
+                                         sanitize.text.function),
+  math.style.negative = getOption("xtable.math.style.negative", FALSE),
+  math.style.exponents = getOption("xtable.math.style.exponents", FALSE),
+  html.table.attributes = getOption("xtable.html.table.attributes",
+                                    "border=1"),
+  print.results = getOption("xtable.print.results", TRUE),
+  format.args = getOption("xtable.format.args", NULL),
+  rotate.rownames = getOption("xtable.rotate.rownames", FALSE),
+  rotate.colnames = getOption("xtable.rotate.colnames", FALSE),
+  booktabs = getOption("xtable.booktabs", FALSE),
+  scalebox = getOption("xtable.scalebox", NULL),
+  width = getOption("xtable.width", NULL),
+  comment = getOption("xtable.comment", TRUE),
+  timestamp = getOption("xtable.timestamp", date()),
+  ...)
+}
+
+\arguments{
+  \item{x}{For \code{xtableFtable}, an object of class
+  \code{"ftable"}. For \code{print.xtableFtable}, an object of class
+  \code{c("xtableFtable", "ftable")}.}
+  \item{caption}{Character vector of length 1 or 2 containing the
+    table's caption or title.  If length is 2, the second item is the
+    "short caption" used when LaTeX generates a "List of Tables". Set to
+    \code{NULL} to suppress the caption.  Default value is \code{NULL}. }
+  \item{label}{Character vector of length 1 containing the LaTeX label
+    or HTML anchor. Set to \code{NULL} to suppress the label.  Default
+    value is \code{NULL}. }
+  \item{align}{Character vector of length equal to the number of columns
+    of the resulting table, indicating the alignment of the corresponding
+    columns.  Also, \code{"|"} may be used to produce vertical lines
+    between columns in LaTeX tables, but these are effectively ignored
+    when considering the required length of the supplied vector.  If a
+    character vector of length one is supplied, it is split as
+    \code{strsplit(align, "")[[1]]} before processing. For a flat table,
+    the number of columns is the number of columns of data, plus the
+    number of row variables in the table, plus one for the row names,
+    even though row names are not printed.
+    Use \code{"l"}, \code{"r"}, and \code{"c"} to
+    denote left, right, and center alignment, respectively.  Use
+    \code{"p{3cm}"} etc. for a LaTeX column of the specified width. For
+    HTML output the \code{"p"} alignment is interpreted as \code{"l"},
+    ignoring the width request.
+    If \code{NULL} all row variable labels will be left aligned,
+    separated from the data columns by a vertical line, and all data
+    columns will be right aligned. The actual length of \code{align}
+    depends on the value of \code{method}.}
+  \item{digits}{
+    Numeric vector of length equal to one (in which case it will be
+    replicated as necessary) or to the number of columns in the
+    resulting table. Since data in the table consists of
+    counts, the default is 0. If the value of \code{digits} is negative, the
+    corresponding columns are displayed in scientific format
+    with \code{abs(digits)} digits.}
+  \item{display}{
+    Character vector of length equal to the number of columns of the
+    resulting table, indicating the format for the corresponding columns.
+    These values are passed to the \code{formatC}
+    function.  Use \code{"d"} (for integers), \code{"f"}, \code{"e"},
+    \code{"E"}, \code{"g"}, \code{"G"}, \code{"fg"} (for reals), or
+    \code{"s"} (for strings).  \code{"f"} gives numbers in the usual
+    \code{xxx.xxx} format; \code{"e"} and \code{"E"} give
+    \code{n.ddde+nn} or \code{n.dddE+nn} (scientific format); \code{"g"}
+    and \code{"G"} put \code{x[i]} into scientific format only if it
+    saves space to do so.  \code{"fg"} uses fixed format as \code{"f"},
+    but \code{digits} as number of \emph{significant} digits.  Note that
+    this can lead to quite long result strings.
+    If \code{NULL} all row variable names and labels will have format
+    \code{"s"}, and all data columns will have format \code{"d"}. The
+    actual length of \code{display} depends on the value of
+    \code{method}.}
+  \item{quote}{a character string giving the set of quoting characters
+    for \code{format.ftable} used in \code{print.xtableFtable}; to
+    disable quoting altogether, use \code{quote=""}.}
+
+  \item{method}{string specifying how the \code{"xtableFtable"} object is
+    printed in the \code{print} method.  Can be abbreviated.  Available
+    methods are (see the examples in \code{\link{print.ftable}}):
+    \describe{
+      \item{"non.compact"}{the default representation of an
+        \code{"ftable"} object.}
+      \item{"row.compact"}{a row-compact version without empty cells
+        below the column labels.}
+      \item{"col.compact"}{a column-compact version without empty cells
+        to the right of the row labels.}
+      \item{"compact"}{a row- and column-compact version.  This may imply
+        a row and a column label sharing the same cell.  They are then
+        separated by the string \code{lsep}.}
+    }
+  }
+  \item{lsep}{only for \code{method = "compact"}, the separation string
+    for row and column labels.}
+  \item{type}{Type of table to produce. Possible values for \code{type}
+    are \code{"latex"} or \code{"html"}.
+    Default value is \code{"latex"} and is the only type implemented so far.}
+  \item{file}{Name of file where the resulting code should be saved.  If
+    \code{file=""}, output is displayed on screen.  Note that the
+    function also (invisibly) returns a character vector of the results
+    (which can be helpful for post-processing).
+    Default value is \code{""}.}
+  \item{append}{If \code{TRUE} and \code{file!=""}, code will be
+    appended to \code{file} instead of overwriting \code{file}.
+    Default value is \code{FALSE}.}
+  \item{floating}{If \code{TRUE} and \code{type="latex"}, the resulting
+    table will be a floating table (using, for example,
+    \code{\\begin\{table\}} and \code{\\end\{table\}}).  See
+    \code{floating.environment} below.
+    Default value is \code{TRUE}. }
+  \item{floating.environment}{If \code{floating=TRUE} and
+    \code{type="latex"}, the resulting table uses the specified floating
+    environment. Possible values include \code{"table"}, \code{"table*"},
+    and other floating environments defined in LaTeX packages.
+    Default value is \code{"table"}.}
+  \item{table.placement}{If \code{floating=TRUE} and
+    \code{type="latex"}, the floating table will have placement given by
+    \code{table.placement} where \code{table.placement} must be
+    \code{NULL} or contain only elements of
+    \{"h","t","b","p","!","H"\}.
+    Default value is \code{"ht"}.}
+  \item{caption.placement}{The caption will be placed at the bottom
+    of the table if \code{caption.placement} is \code{"bottom"} and at
+    the top of the table if it equals \code{"top"}.
+    Default value is \code{"bottom"}.}
+  \item{caption.width}{The caption will be placed in a \code{"parbox"}
+    of the specified width if \code{caption.width} is not \code{NULL} and
+	\code{type="latex"}. Default value is \code{NULL}.}
+  \item{latex.environments}{If \code{floating=TRUE} and
+    \code{type="latex"}, the specified LaTeX environments (provided as
+    a character vector) will enclose the tabular environment.
+    Default value is \code{"center"}. }
+  \item{tabular.environment}{When \code{type="latex"}, the tabular
+    environment that will be used.
+    When working with tables that extend more than one page, using
+    \code{tabular.environment="longtable"} with the corresponding
+    LaTeX package (see Fairbairns, 2005) allows one to typeset them
+    uniformly. Note that \code{floating} should be set to
+    \code{FALSE} when using the \code{longtable} environment.
+    Default value is \code{"tabular"}.}
+  \item{size}{A character vector that is inserted just before the
+    tabular environment starts. This can be used to set the font size
+    and a variety of other table settings. Initial backslashes are
+    automatically prefixed, if not supplied by user.
+    Default value is \code{NULL}. }
+  \item{hline.after}{When \code{type="latex"}, a vector of numbers
+    between -1 and \code{nrow(x)}, inclusive, indicating the rows after
+    which a horizontal line should appear.  Repeated values are
+    allowed. If \code{NULL} the default is to draw a line before before
+    starting the table, after the column variable names and labels, and
+    at the end of the table.}
+  \item{NA.string}{String to be used for missing values in table
+    entries.
+    Default value is \code{""}.}
+ \item{only.contents}{If \code{TRUE} only the rows of the
+    table are printed.
+    Default value is \code{FALSE}. }
+  \item{add.to.row}{A list of two components. The first component (which
+    should be called 'pos') is a list that contains the position of rows on
+    which extra commands should be added at the end. The second
+    component (which should be called 'command') is a character vector
+    of the same length as the first component, which contains the command
+    that should be added at the end of the specified rows.
+    Default value is \code{NULL}, i.e. do not add commands.}
+  \item{sanitize.text.function}{Since the table entries are counts no
+    sanitization is necessary. The default is \code{as.is}, which is the
+    function which makes no changes. This also applies to the labels for
+    the row and column variables since these are also part of the table
+    which is printed using a call to \code{print.xtable}.}
+  \item{sanitize.rownames.function}{Like the
+    \code{sanitize.text.function}, but applicable to row names.
+    The default uses the \code{sanitize.text.function}. }
+  \item{sanitize.colnames.function}{Like the
+    \code{sanitize.text.function}, but applicable to column names.
+    The default uses the \code{sanitize.text.function}. }
+  \item{math.style.negative}{In a LaTeX table, if \code{TRUE}, then use
+    $-$ for the negative sign (as was the behavior prior to version 1.5-3).
+    Default value is \code{FALSE}.}
+  \item{math.style.exponents}{In a LaTeX table, if \code{TRUE} or
+    \code{"$$"}, then use \verb{$5 \times 10^{5}$} for 5e5. If
+    \code{"ensuremath"}, then use \verb{\\ensuremath{5 \times 10^{5}}}
+    for 5e5. If \code{"UTF-8"} or \code{"UTF-8"}, then use UTF-8 to
+    approximate the LaTeX typsetting for 5e5.
+    Default value is \code{FALSE}.}
+  \item{html.table.attributes}{In an HTML table, attributes associated
+    with the \code{<TABLE>} tag.
+    Default value is \code{"border=1"}.}
+  \item{print.results}{If \code{TRUE}, the generated table is printed to
+    standard output.  Set this to \code{FALSE} if you will just be using
+    the character vector that is returned invisibly.
+  Default value is \code{TRUE}.}
+  \item{format.args}{List of arguments for the \code{formatC} function.
+    For example, standard German number separators can be specified as
+    \code{format.args=list(big.mark = "'", decimal.mark =
+      ","))}. The arguments \code{digits} and \code{format} should not be
+    included in this list.
+    Default value is \code{NULL}.}
+  \item{rotate.rownames}{If \code{TRUE}, the row names and labels, and
+    column variable names are displayed vertically in LaTeX.
+    Default value is \code{FALSE}.}
+  \item{rotate.colnames}{If \code{TRUE}, the column names and labels,
+    and row variable names are displayed vertically in LaTeX.
+    Default value is \code{FALSE}.}
+  \item{booktabs}{If \code{TRUE}, the \code{toprule}, \code{midrule} and
+    \code{bottomrule} commands from the LaTeX "booktabs" package are used
+    rather than \code{hline} for the horizontal line tags. }
+  \item{scalebox}{If not \code{NULL}, a \code{scalebox} clause will be
+    added around the tabular environment with the specified value used
+    as the scaling factor.
+    Default value is \code{NULL}.}
+  \item{width}{If not \code{NULL}, the specified value is included in
+    parentheses between the tabular environment \code{begin} tag and the
+    alignment specification.  This allows specification of the table
+    width when using tabular environments such as \code{tabular*} and
+    \code{tabularx}.  Note that table width specification is not
+    supported with the \code{tabular} or \code{longtable} environments.
+    Default value is \code{NULL}.}
+  \item{comment}{If \code{TRUE}, the version and timestamp comment is
+    included.  Default value is \code{TRUE}. }
+  \item{timestamp}{Timestamp to include in LaTeX comment.  Set this
+    to \code{NULL} to exclude the timestamp. Default value is
+    \code{date()}. }
+  \item{...}{Additional arguments.  (Currently ignored.) }
+}
+\details{
+  \code{xtableFtable} carries out some calculations to determine the
+    number of rows and columns of names and labels which will be in the
+    table when formatted as a flat table, which depends on the value of
+    \code{method}. It uses the results of those calculations to set
+    sensible values for \code{align} and \code{display} if these have
+    not been supplied. It attaches attributes to the resulting object
+    which specify details of the function call which are needed when
+    printing the resulting object which is of class
+    \code{c("xtableFtable", "ftable")}.
+
+    \code{print.xtableFtable} uses the attributes attached to an object
+    of class \code{c("xtableFtable", "ftable")} to create a suitable
+    character matrix object for subsequent printing. Formatting is
+    carried out by changing the class of the \code{c("xtableFtable",
+    "ftable")} to \code{"ftable"} then using the generic \code{format}
+    to invoke \code{format.ftable}, from the \pkg{stats} package. The
+    matrix object produced is then printed via a call to
+    \code{print.xtable}.
+
+    Note that at present there is no code for \code{type = "html"}.
+}
+\value{
+  For \code{xtableFtable} an object of class \code{c("xtableFtable",
+    "ftable")}, with attributes
+  \item{ftableCaption}{the value of the \code{caption} argument}
+  \item{ftableLabel}{the value of the \code{label} argument}
+  \item{ftableAlign}{the value of the \code{label} argument}
+  \item{ftableDigits}{the value of the \code{digits} argument or the
+    default value if \code{digits = NULL}}
+  \item{quote}{the value of the \code{quote} argument}
+  \item{ftableDisplay}{the value of the \code{display} argument or the
+    default value if \code{align = NULL}}
+  \item{method}{the value of the \code{method} argument}
+  \item{lsep}{the value of the \code{lsep} argument}
+  \item{nChars}{a vector of length 2 giving the number of character rows
+    and the number of character columns}
+
+  For \code{print.xtableFtable} a character string which will produce a
+  formatted table when included in a LaTeX document.
+
+}
+\references{
+  Fairbairns, Robin (2005) \emph{Tables longer than a single page.} The
+  UK List of TeX Frequently Asked Questions on the
+  Web. \url{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=longtab}
+}
+\author{
+  David Scott \email{d.scott at auckland.ac.nz}.
+}
+\note{
+  The functions \code{xtableFtable} and \code{print.xtableFtable} are
+  new and their behaviour may change in the future based on user
+  experience and recommendations.
+
+  It is not recommended that users change the values of \code{align},
+  \code{digits} or \code{align}. First of all, alternative values have
+  not been tested. Secondly, it is most likely that to determine
+  appropriate values for these arguments, users will have to investigate
+  the code for \code{xtableFtable} and/or \code{print.xtableFtable}.
+}
+
+\seealso{
+  \code{\link{ftable}}, \code{\link{print.ftable}},
+  \code{\link{xtable}}, \code{\link{caption}}, \code{\link{label}},
+  \code{\link{align}}, \code{\link{digits}}, \code{\link{display}},
+  \code{\link{formatC}}
+}
+\examples{
+data(mtcars)
+mtcars$cyl <- factor(mtcars$cyl, levels = c("4","6","8"),
+                     labels = c("four","six","eight"))
+tbl <- ftable(mtcars$cyl, mtcars$vs, mtcars$am, mtcars$gear,
+              row.vars = c(2, 4),
+              dnn = c("Cylinders", "V/S", "Transmission", "Gears"))
+xftbl <- xtableFtable(tbl, method = "compact")
+print.xtableFtable(xftbl, booktabs = TRUE)
+xftbl <- xtableFtable(tbl, method = "row.compact")
+print.xtableFtable(xftbl, rotate.colnames = TRUE,
+                   rotate.rownames = TRUE)
+}
+
+\keyword{ category }
+\keyword{ print }
diff --git a/man/xtableList.Rd b/man/xtableList.Rd
new file mode 100644
index 0000000..1682689
--- /dev/null
+++ b/man/xtableList.Rd
@@ -0,0 +1,331 @@
+\name{xtableList}
+\alias{xtableList}
+\alias{print.xtableList}
+
+\title{
+  Create and Export Lists of Tables
+}
+\description{
+  \code{xtableList} creates an object which contains information about
+  lists of table which can be used by \code{print.xtableList} to produce
+  a character string which when included in a document produces a nicely
+  formatted table made up of the information in the individual tables
+  which comprised the original list of tables.
+}
+\usage{
+xtableList(x, caption = NULL, label = NULL,
+           align = NULL, digits = NULL, display = NULL, ...)
+
+\method{print}{xtableList}(x,
+  type = getOption("xtable.type", "latex"),
+  file = getOption("xtable.file", ""),
+  append = getOption("xtable.append", FALSE),
+  floating = getOption("xtable.floating", TRUE),
+  floating.environment = getOption("xtable.floating.environment", "table"),
+  table.placement = getOption("xtable.table.placement", "ht"),
+  caption.placement = getOption("xtable.caption.placement", "bottom"),
+  caption.width = getOption("xtable.caption.width", NULL),
+  latex.environments = getOption("xtable.latex.environments", c("center")),
+  tabular.environment = getOption("xtable.tabular.environment", "tabular"),
+  size = getOption("xtable.size", NULL),
+  hline.after = NULL,
+  NA.string = getOption("xtable.NA.string", ""),
+  include.rownames = getOption("xtable.include.rownames", TRUE),
+  colnames.format = "single",
+  only.contents = getOption("xtable.only.contents", FALSE),
+  add.to.row = NULL,
+  sanitize.text.function = getOption("xtable.sanitize.text.function", NULL),
+  sanitize.rownames.function = getOption("xtable.sanitize.rownames.function",
+                                         sanitize.text.function),
+  sanitize.colnames.function = getOption("xtable.sanitize.colnames.function",
+                                         sanitize.text.function),
+  sanitize.subheadings.function =
+    getOption("xtable.sanitize.subheadings.function",
+              sanitize.text.function),
+  sanitize.message.function =
+    getOption("xtable.sanitize.message.function",
+              sanitize.text.function),
+  math.style.negative = getOption("xtable.math.style.negative", FALSE),
+  math.style.exponents = getOption("xtable.math.style.exponents", FALSE),
+  html.table.attributes = getOption("xtable.html.table.attributes", "border=1"),
+  print.results = getOption("xtable.print.results", TRUE),
+  format.args = getOption("xtable.format.args", NULL),
+  rotate.rownames = getOption("xtable.rotate.rownames", FALSE),
+  rotate.colnames = getOption("xtable.rotate.colnames", FALSE),
+  booktabs = getOption("xtable.booktabs", FALSE),
+  scalebox = getOption("xtable.scalebox", NULL),
+  width = getOption("xtable.width", NULL),
+  comment = getOption("xtable.comment", TRUE),
+  timestamp = getOption("xtable.timestamp", date()),
+  ...)
+}
+\arguments{
+  \item{x}{
+    For \code{xtableList}, a list of \R objects all of the same class,
+    being a class found among \code{methods(xtable)}. The list may also
+    have attributes \code{"subheadings"} and \code{"message"}. The
+    attribute \code{"subheadings"} should be a character vector of the
+    same length as the list \code{x}. The attribute \code{"message"}
+    should be a character vector of any length.
+    For \code{print.xtableList}, an object of class \code{xtableList}
+    produced by a call to \code{xtableList}.}
+  \item{caption}{Character vector of length 1 or 2 containing the
+    table's caption or title.  If length is 2, the second item is the
+    "short caption" used when LaTeX generates a "List of Tables". Set to
+    \code{NULL} to suppress the caption.  Default value is \code{NULL}. }
+  \item{label}{Character vector of length 1 containing the LaTeX label
+    or HTML anchor. Set to \code{NULL} to suppress the label.  Default
+    value is \code{NULL}. }
+  \item{align}{Character vector of length equal to the number of columns
+    of the resulting table, indicating the alignment of the corresponding
+    columns.  Also, \code{"|"} may be used to produce vertical lines
+    between columns in LaTeX tables, but these are effectively ignored
+    when considering the required length of the supplied vector.  If a
+    character vector of length one is supplied, it is split as
+    \code{strsplit(align, "")[[1]]} before processing. Since the row
+    names are printed in the first column, the length of \code{align} is
+    one greater than \code{ncol(x)} if \code{x} is a
+    \code{data.frame}. Use \code{"l"}, \code{"r"}, and \code{"c"} to
+    denote left, right, and center alignment, respectively.  Use
+    \code{"p{3cm}"} etc. for a LaTeX column of the specified width. For
+    HTML output the \code{"p"} alignment is interpreted as \code{"l"},
+    ignoring the width request. Default depends on the class of
+    \code{x}. }
+  \item{digits}{
+    Either \code{NULL}, or a vector of length one, or a vector of length
+    equal to the number of columns in the resulting table, indicating
+    the number of digits to display in the corresponding columns, or a
+    list if length equal to the number of R objects making up \code{x},
+    all members being vectors of the same length, either length one or
+    of length equal to the number of columns in the resulting table. See
+    \sQuote{Details} for further information.}
+  \item{display}{
+    Either \code{NULL}, or a vector of length one, or a vector of length
+    equal to the number of columns in the resulting table, indicating
+    the format of the corresponding columns, or a
+    list if length equal to the number of R objects making up \code{x},
+    all members being vectors of the same length, either length one or
+    of length equal to the number of columns in the resulting table. See
+    \sQuote{Details} for further information.}
+  \item{type}{Type of table to produce. Possible values for \code{type}
+    are \code{"latex"} or \code{"html"}.
+    Default value is \code{"latex"}.}
+  \item{file}{Name of file where the resulting code should be saved.  If
+    \code{file=""}, output is displayed on screen.  Note that the
+    function also (invisibly) returns a character vector of the results
+    (which can be helpful for post-processing).
+    Default value is \code{""}.}
+  \item{append}{If \code{TRUE} and \code{file!=""}, code will be
+    appended to \code{file} instead of overwriting \code{file}.
+    Default value is \code{FALSE}.}
+  \item{floating}{If \code{TRUE} and \code{type="latex"}, the resulting
+    table will be a floating table (using, for example,
+    \code{\\begin\{table\}} and \code{\\end\{table\}}).  See
+    \code{floating.environment} below.
+    Default value is \code{TRUE}. }
+  \item{floating.environment}{If \code{floating=TRUE} and
+    \code{type="latex"}, the resulting table uses the specified floating
+    environment. Possible values include \code{"table"}, \code{"table*"},
+    and other floating environments defined in LaTeX packages.
+    Default value is \code{"table"}.}
+  \item{table.placement}{If \code{floating=TRUE} and
+    \code{type="latex"}, the floating table will have placement given by
+    \code{table.placement} where \code{table.placement} must be
+    \code{NULL} or contain only elements of
+    \{"h","t","b","p","!","H"\}.
+    Default value is \code{"ht"}.}
+  \item{caption.placement}{The caption will be placed at the bottom
+    of the table if \code{caption.placement} is \code{"bottom"} and at
+    the top of the table if it equals \code{"top"}.
+    Default value is \code{"bottom"}.}
+  \item{caption.width}{The caption will be placed in a \code{"parbox"}
+    of the specified width if \code{caption.width} is not \code{NULL} and
+	\code{type="latex"}. Default value is \code{NULL}.}
+  \item{latex.environments}{If \code{floating=TRUE} and
+    \code{type="latex"}, the specified LaTeX environments (provided as
+    a character vector) will enclose the tabular environment.
+    Default value is \code{"center"}. }
+  \item{tabular.environment}{When \code{type="latex"}, the tabular
+    environment that will be used.
+    When working with tables that extend more than one page, using
+    \code{tabular.environment="longtable"} with the corresponding
+    LaTeX package (see Fairbairns, 2005) allows one to typeset them
+    uniformly. Note that \code{floating} should be set to
+    \code{FALSE} when using the \code{longtable} environment.
+    Default value is \code{"tabular"}.}
+  \item{size}{A character vector that is inserted just before the
+    tabular environment starts. This can be used to set the font size
+    and a variety of other table settings. Initial backslashes are
+    automatically prefixed, if not supplied by user.
+    Default value is \code{NULL}. }
+  \item{hline.after}{When \code{type="latex"}, a vector of numbers
+    between -1 and the number of rows in the resulting table, inclusive,
+    indicating the rows after which a horizontal line should
+    appear. Determining row numbers is not straightforward since some
+    lines in the resulting table don't enter into the count.  The
+    default depends on the value of \code{col.names.format}.}
+  \item{NA.string}{String to be used for missing values in table
+    entries.
+    Default value is \code{""}.}
+  \item{include.rownames}{If \code{TRUE} the rows names are
+    printed.
+    Default value is \code{TRUE}.}
+  \item{colnames.format}{Either \code{"single"} or \code{"multiple"}.
+    Default is \code{"single"}.}
+  \item{only.contents}{If \code{TRUE} only the rows of the
+    table are printed.
+    Default value is \code{FALSE}. }
+  \item{add.to.row}{A list of two components. The first component (which
+    should be called 'pos') is a list that contains the position of rows on
+    which extra commands should be added at the end. The second
+    component (which should be called 'command') is a character vector
+    of the same length as the first component, which contains the command
+    that should be added at the end of the specified rows.
+    Default value is \code{NULL}, i.e. do not add commands.}
+  \item{sanitize.text.function}{All non-numeric entries (except row and
+    column names) are sanitized in an attempt to remove characters which
+    have special meaning for the output format. If
+    \code{sanitize.text.function} is not \code{NULL}, it should
+    be a function taking a character vector and returning one, and will
+    be used for the sanitization instead of the default internal
+    function.
+    Default value is \code{NULL}.}
+  \item{sanitize.rownames.function}{Like the
+    \code{sanitize.text.function}, but applicable to row names.
+    The default uses the \code{sanitize.text.function}. }
+  \item{sanitize.colnames.function}{Like the
+    \code{sanitize.text.function}, but applicable to column names.
+    The default uses the \code{sanitize.text.function}. }
+  \item{sanitize.subheadings.function}{Like the
+    \code{sanitize.text.function}, but applicable to subheadings.
+    The default uses the \code{sanitize.text.function}. }
+  \item{sanitize.message.function}{Like the
+    \code{sanitize.text.function}, but applicable to the message.
+    The default uses the \code{sanitize.text.function}. }
+  \item{math.style.negative}{In a LaTeX table, if \code{TRUE}, then use
+    $-$ for the negative sign (as was the behavior prior to version 1.5-3).
+    Default value is \code{FALSE}.}
+  \item{math.style.exponents}{In a LaTeX table, if \code{TRUE} or
+    \code{"$$"}, then use \verb{$5 \times 10^{5}$} for 5e5. If
+    \code{"ensuremath"}, then use \verb{\\ensuremath{5 \times 10^{5}}}
+    for 5e5. If \code{"UTF-8"} or \code{"UTF-8"}, then use UTF-8 to
+    approximate the LaTeX typsetting for 5e5.
+    Default value is \code{FALSE}.}
+  \item{html.table.attributes}{In an HTML table, attributes associated
+    with the \code{<TABLE>} tag.
+    Default value is \code{"border=1"}.}
+  \item{print.results}{If \code{TRUE}, the generated table is printed to
+    standard output.  Set this to \code{FALSE} if you will just be using
+    the character vector that is returned invisibly.
+  Default value is \code{TRUE}.}
+  \item{format.args}{List of arguments for the \code{formatC} function.
+    For example, standard German number separators can be specified as
+    \code{format.args=list(big.mark = "'", decimal.mark =
+      ","))}. The arguments \code{digits} and \code{format} should not be
+    included in this list. See details.
+    Default value is \code{NULL}.}
+  \item{rotate.rownames}{If \code{TRUE}, the row names are displayed
+    vertically in LaTeX.
+    Default value is \code{FALSE}.}
+  \item{rotate.colnames}{If \code{TRUE}, the column names are displayed
+    vertically in LaTeX.
+    Default value is \code{FALSE}.}
+  \item{booktabs}{If \code{TRUE}, the \code{toprule}, \code{midrule} and
+    \code{bottomrule} commands from the LaTeX "booktabs" package are used
+    rather than \code{hline} for the horizontal line tags. }
+  \item{scalebox}{If not \code{NULL}, a \code{scalebox} clause will be
+    added around the tabular environment with the specified value used
+    as the scaling factor.
+    Default value is \code{NULL}.}
+  \item{width}{If not \code{NULL}, the specified value is included in
+    parentheses between the tabular environment \code{begin} tag and the
+    alignment specification.  This allows specification of the table
+    width when using tabular environments such as \code{tabular*} and
+    \code{tabularx}.  Note that table width specification is not
+    supported with the \code{tabular} or \code{longtable} environments.
+    Default value is \code{NULL}.}
+  \item{comment}{If \code{TRUE}, the version and timestamp comment is
+    included.  Default value is \code{TRUE}. }
+  \item{timestamp}{Timestamp to include in LaTeX comment.  Set this
+    to \code{NULL} to exclude the timestamp. Default value is
+    \code{date()}. }
+  \item{\dots}{Additional arguments.  (Currently ignored.)}
+}
+\details{
+  \code{xtableList} produces an object suitable for printing using
+  \code{print.xtableList}.
+
+  The elements of the list \code{x} supplied to \code{xtableList} must
+  all have the same structure. When these list items are submitted to
+  \code{xtable} the resulting table must have the same number of columns
+  with the same column names and type of data.
+
+  The values supplied to arguments \code{digits} and \code{display},
+  must be composed of elements as specified in those same arguments for
+  the function \code{\link{xtable}}. See the help for
+  \code{\link{xtable}} for details.
+
+  \code{print.xtableList} produces tables in two different formats
+  depending on the value of \code{col.names.format}. If
+  \code{col.names.format = "single"}, the resulting table has only a
+  single heading row. If \code{col.names.format = "multiple"} there is a
+  heading row for each of the subtables making up the complete table.
+
+  By default if \code{col.names.format = "single"}, there are horizontal
+  lines above and below the heading row, and at the end of each
+  subtable. If \code{col.names.format = "multiple"}, there are
+  horizontal lines above and below each appearance of the heading row,
+  and at the end of each subtable.
+
+  If \code{"subheadings"} is not \code{NULL}, the individual elements of
+  this vector (which can include newlines \verb{\\n}) produce a heading
+  line or lines for the subtables. When \code{col.names.format =
+    "multiple"} these subheadings appear \emph{above} the heading rows.
+
+  If \code{"message"} is not \code{NULL} the vector produces a line or
+  lines at the end of the table.
+
+  Consult the vignette \sQuote{The \code{xtableList} Gallery} to see
+  the behaviour of these functions.
+
+  Note that at present there is no code for \code{type = "html"}.
+}
+\value{
+  \code{xtableList} produces an object of class
+  \code{"xtableList"}. An object of this class is a list of
+  \code{"xtable"} objects with some additional attributes. Each element
+  of the list can have a \code{"subheading"} attribute. The list can
+  also have a \code{"message"} attribute.
+
+  \code{print.xtableList} produces a character string containing LaTeX
+  markup which produces a nicely formatted table comprised of subtables,
+  when included in a LaTeX document.
+}
+\author{
+  David Scott \email{d.scott at auckland.ac.nz}.
+}
+\note{
+  The functions \code{xtableList} and \code{print.xtableList} are
+  new and their behaviour may change in the future based on user
+  experience and recommendations.
+}
+
+
+\seealso{
+  \code{\link{xtable}}, \code{\link{caption}}, \code{\link{label}},
+  \code{\link{align}}, \code{\link{digits}}, \code{\link{display}},
+  \code{\link{formatC}}, \code{\link{print.xtable}}.
+}
+\examples{
+data(mtcars)
+mtcars <- mtcars[, 1:6]
+mtcarsList <- split(mtcars, f = mtcars$cyl)
+attr(mtcarsList, "subheadings") <- paste0("Number of cylinders = ",
+                                          names(mtcarsList))
+attr(mtcarsList, "message") <- c("Line 1 of Message",
+                                 "Line 2 of Message")
+xList <- xtableList(mtcarsList)
+print.xtableList(xList)
+print.xtableList(xList, colnames.format = "multiple")
+}
+\keyword{ print }
diff --git a/man/xtableMatharray.Rd b/man/xtableMatharray.Rd
new file mode 100644
index 0000000..c050411
--- /dev/null
+++ b/man/xtableMatharray.Rd
@@ -0,0 +1,105 @@
+\name{xtableMatharray}
+\alias{xtableMatharray}
+
+\title{
+ Create LaTeX Mathematical Array
+}
+\description{
+  Convert an array of numbers or mathematical expressions into an
+ \code{xtableMatharray} object so it can be printed. A convenience
+ function to enable the printing of arrays in mathematical expressions
+ in LaTeX
+}
+\usage{
+xtableMatharray(x, caption = NULL, label = NULL, align = NULL,
+                digits = NULL, display = NULL, auto = FALSE, ...)
+}
+\arguments{
+  \item{x}{A numeric or character matrix.}
+  \item{caption}{Character vector of length 1 or 2 containing the
+    table's caption or title.  If length is 2, the second item is the
+    "short caption" used when LaTeX generates a "List of Tables". Set to
+    \code{NULL} to suppress the caption.  Default value is \code{NULL}.
+    Included here only for consistency with \code{xtable} methods. Not
+    expected to be of use.}
+  \item{label}{Character vector of length 1 containing the LaTeX
+    label. Set to \code{NULL} to suppress the label.
+    Default value is \code{NULL}. }
+  \item{align}{Character vector of length equal to the number of columns
+    of the resulting table, indicating the alignment of the corresponding
+    columns.  Also, \code{"|"} may be used to produce vertical lines
+    between columns in LaTeX tables, but these are effectively ignored
+    when considering the required length of the supplied vector.  If a
+    character vector of length one is supplied, it is split as
+    \code{strsplit(align, "")[[1]]} before processing. Since the row
+    names are printed in the first column, the length of \code{align} is
+    one greater than \code{ncol(x)} if \code{x} is a
+    \code{data.frame}. Use \code{"l"}, \code{"r"}, and \code{"c"} to
+    denote left, right, and center alignment, respectively.  Use
+    \code{"p{3cm}"} etc. for a LaTeX column of the specified width. For
+    HTML output the \code{"p"} alignment is interpreted as \code{"l"},
+    ignoring the width request. Default depends on the class of
+    \code{x}. }
+  \item{digits}{Numeric vector of length equal to one (in which case it
+    will be replicated as necessary) or to the number of columns of the
+    resulting table \bold{or} matrix of the same size as the resulting
+    table, indicating the number of digits to display in the
+    corresponding columns. Since the row names are printed in the first
+    column, the length of the vector \code{digits} or the number of
+    columns of the matrix \code{digits} is one greater than
+    \code{ncol(x)} if \code{x} is a \code{data.frame}. Default depends
+    on the class of \code{x}. If values of \code{digits} are negative,
+    the corresponding values of \code{x} are displayed in scientific
+    format with \code{abs(digits)} digits.}
+  \item{display}{
+    Character vector of length equal to the number of columns of the
+    resulting table, indicating the format for the corresponding columns.
+    Since the row names are printed in the first column, the length of
+    \code{display} is one greater than \code{ncol(x)} if \code{x} is a
+    \code{data.frame}.  These values are passed to the \code{formatC}
+    function.  Use \code{"d"} (for integers), \code{"f"}, \code{"e"},
+    \code{"E"}, \code{"g"}, \code{"G"}, \code{"fg"} (for reals), or
+    \code{"s"} (for strings).  \code{"f"} gives numbers in the usual
+    \code{xxx.xxx} format; \code{"e"} and \code{"E"} give
+    \code{n.ddde+nn} or \code{n.dddE+nn} (scientific format); \code{"g"}
+    and \code{"G"} put \code{x[i]} into scientific format only if it
+    saves space to do so.  \code{"fg"} uses fixed format as \code{"f"},
+    but \code{digits} as number of \emph{significant} digits.  Note that
+    this can lead to quite long result strings.  Default depends on the
+    class of \code{x}.}
+  \item{auto}{
+    Logical, indicating whether to apply automatic format when no value
+    is passed to \code{align}, \code{digits}, or \code{display}. This
+    \sQuote{autoformat} (based on \code{xalign}, \code{xdigits}, and
+    \code{xdisplay}) can be useful to quickly format a typical
+    \code{matrix} or \code{data.frame}. Default value is \code{FALSE}.}
+  \item{...}{Additional arguments.  (Currently ignored.)}
+}
+\details{
+  This function is only usable for production of LaTeX documents, not
+  HTML.
+
+  Creates an object of class
+ \code{c("xtableMatharray","xtable","data.frame")}, to ensure that it is
+ printed by the print method \code{print.xtableMatharray}.
+}
+\value{
+ An object of class \code{c("xtableMatharray","xtable","data.frame")}.
+}
+
+\author{
+  David Scott <d.scott at auckland.ac.nz>
+}
+\seealso{
+\code{\link{print.xtableMatharray}}
+}
+\examples{
+V <- matrix(c(1.140380e-03,  3.010497e-05,  7.334879e-05,
+              3.010497e-05,  3.320683e-04, -5.284854e-05,
+              7.334879e-05, -5.284854e-05,  3.520928e-04), nrow = 3)
+mth <- xtableMatharray(V)
+class(mth)
+str(mth)
+unclass(mth)
+}
+\keyword{ print }
diff --git a/tests/test.matharray.R b/tests/test.matharray.R
new file mode 100644
index 0000000..172ff92
--- /dev/null
+++ b/tests/test.matharray.R
@@ -0,0 +1,37 @@
+require(xtable)
+V <- matrix(c(1.140380e-03,  3.010497e-05,  7.334879e-05,
+              3.010497e-05,  3.320683e-04, -5.284854e-05,
+              7.334879e-05, -5.284854e-05,  3.520928e-04), nrow = 3)
+### Simple test of print.xtableMatharray
+print.xtableMatharray(xtable(V, display = rep("E", 4)))
+
+class(V) <- c("xtableMatharray")
+class(V)
+
+### Test without any additional arguments
+mth <- xtableMatharray(V)
+str(mth)
+print(mth)
+
+### Test with arguments to xtable
+mth <- xtableMatharray(V, display = rep("E", 4))
+str(mth)
+print(mth)
+
+mth <- xtableMatharray(V, digits = 6)
+str(mth)
+print(mth)
+
+### Test with additional print.xtableMatharray arguments
+mth <- xtableMatharray(V, digits = 6)
+str(mth)
+print(mth, format.args = list(decimal.mark = ","))
+print(mth, scalebox = 0.5)
+print(mth, comment = TRUE)
+print(mth, timestamp = "2000-01-01")
+print(mth, comment = TRUE, timestamp = "2000-01-01")
+
+
+
+
+
diff --git a/tests/test.xalign.xdigits.xdisplay.R b/tests/test.xalign.xdigits.xdisplay.R
new file mode 100644
index 0000000..70a3b1e
--- /dev/null
+++ b/tests/test.xalign.xdigits.xdisplay.R
@@ -0,0 +1,49 @@
+### Test of feature request #5686
+### Automatically suggesting alignment/digits/display for an xtable
+### Arni Magnusson, 14 Sep 2014
+
+require(xtable)
+dat <- mtcars[1:3, 1:6]
+x <- xtable(dat)
+x
+
+## % latex table generated in R 3.1.1 by xtable 1.7-4 package
+## % Sun Sep 14 22:32:17 2014
+## \begin{table}[ht]
+## \centering
+## \begin{tabular}{rrrrrrr}
+##   \hline
+##  & mpg & cyl & disp & hp & drat & wt \\
+##   \hline
+## Mazda RX4 & 21.00 & 6.00 & 160.00 & 110.00 & 3.90 & 2.62 \\
+##   Mazda RX4 Wag & 21.00 & 6.00 & 160.00 & 110.00 & 3.90 & 2.88 \\
+##   Datsun 710 & 22.80 & 4.00 & 108.00 & 93.00 & 3.85 & 2.32 \\
+##    \hline
+## \end{tabular}
+## \end{table}
+
+### Hmm, inappropriate alignment and digits.
+### Now try suggestions from xalign, xdigits, and xdisplay:
+
+### source("http://www.hafro.is/~arnima/r/xtable_5686.R")
+align(x) <- xalign(x)
+digits(x) <- xdigits(x)
+display(x) <- xdisplay(x)
+x
+
+## % latex table generated in R 3.1.1 by xtable 1.7-4 package
+## % Sun Sep 14 22:34:43 2014
+## \begin{table}[ht]
+## \centering
+## \begin{tabular}{lrrrrrr}
+##   \hline
+##  & mpg & cyl & disp & hp & drat & wt \\
+##   \hline
+## Mazda RX4 & 21.0 & 6 & 160 & 110 & 3.90 & 2.620 \\
+##   Mazda RX4 Wag & 21.0 & 6 & 160 & 110 & 3.90 & 2.875 \\
+##   Datsun 710 & 22.8 & 4 & 108 & 93 & 3.85 & 2.320 \\
+##    \hline
+## \end{tabular}
+## \end{table}
+
+### Excellent suggestions.
diff --git a/tests/test.xtable.xtableFtable.R b/tests/test.xtable.xtableFtable.R
new file mode 100644
index 0000000..5ac399f
--- /dev/null
+++ b/tests/test.xtable.xtableFtable.R
@@ -0,0 +1,24 @@
+### Test code for xtableFtable function
+### David Scott, <d.scott at auckland.ac.nz>, 2016-01-14
+library(xtable)
+
+
+tbl <- ftable(mtcars$cyl, mtcars$vs, mtcars$am, mtcars$gear, row.vars = c(2, 4),
+              dnn = c("Cylinders", "V/S", "Transmission", "Gears"))
+
+## debug(xtableFtable)
+xftbl <- xtableFtable(tbl)
+str(xftbl)
+unclass(xftbl)
+print.xtableFtable(xftbl)
+xftbl <- xtableFtable(tbl, method = "row.compact")
+print.xtableFtable(xftbl)
+xftbl <- xtableFtable(tbl, method = "col.compact")
+print.xtableFtable(xftbl)
+xftbl <- xtableFtable(tbl, method = "compact")
+print.xtableFtable(xftbl)
+## debug(print.xtableFtable)
+## undebug(print.xtableFtable)
+## debug(print.xtable)
+## undebug(print.xtable)
+
diff --git a/vignettes/OtherPackagesGallery.Rnw b/vignettes/OtherPackagesGallery.Rnw
new file mode 100644
index 0000000..ffd5f95
--- /dev/null
+++ b/vignettes/OtherPackagesGallery.Rnw
@@ -0,0 +1,322 @@
+%\VignetteIndexEntry{xtable List of Tables Gallery}
+%\VignetteDepends{xtable, spdep, splm, sphet}
+%\VignetteKeywords{LaTeX, HTML, table}
+%\VignettePackage{xtable}
+% !Rnw weave = knitr
+% \VignetteEngine{knitr::knitr}
+%**************************************************************************
+\documentclass{article}
+\usepackage[a4paper, height=24cm]{geometry} % geometry first
+\usepackage{array}
+\usepackage{booktabs}
+\usepackage{longtable}
+\usepackage{parskip}
+\usepackage{rotating}
+\usepackage{tabularx}
+\usepackage{titlesec}
+\usepackage{hyperref} % hyperref last
+\titleformat\subsubsection{\bfseries\itshape}{}{0pt}{}
+\newcommand\p{\vspace{2ex}}
+\newcommand\code[1]{\texttt{#1}}
+\newcommand\pkg[1]{\textbf{#1}}
+\setcounter{tocdepth}{2}
+\begin{document}
+
+\title{\bfseries\Large The Other Packages Gallery}
+\author{\bfseries David J. Scott}
+\maketitle
+
+\tableofcontents
+
+\newpage
+
+\section{Introduction}
+This document represents a test of the functions in \pkg{xtable} which
+deal with other packages.
+
+<<set, include=FALSE>>=
+library(knitr)
+opts_chunk$set(fig.path = 'Figures/other', debug = TRUE, echo = TRUE)
+opts_chunk$set(out.width = '0.9\\textwidth')
+@
+
+The first step is to load the package and set some options for this document.
+<<package, results='asis'>>=
+library(xtable)
+options(xtable.floating = FALSE)
+options(xtable.timestamp = "")
+options(width = 60)
+set.seed(1234)
+@
+
+\section{The packages \pkg{spdep}, \pkg{splm}, and \pkg{sphet}}
+
+Code for supporting these packages and most of the examples used in
+this section was originally provided by Martin Gubri
+(\url{martin.gubri at framasoft.org}).
+
+\subsection{The package \pkg{spdep}}
+\label{sec:package-pkgspdep}
+
+First load the package and create some objects.
+<<dataspdep>>=
+library(spdep)
+data("oldcol", package = "spdep")
+COL.lag.eig <- lagsarlm(CRIME ~ INC + HOVAL, data = COL.OLD[],
+                        nb2listw(COL.nb))
+class(COL.lag.eig)
+COL.errW.GM <- GMerrorsar(CRIME ~ INC + HOVAL, data = COL.OLD,
+                          nb2listw(COL.nb, style = "W"),
+                          returnHcov = TRUE)
+class(COL.errW.GM)
+COL.lag.stsls <- stsls(CRIME ~ INC + HOVAL, data = COL.OLD,
+                       nb2listw(COL.nb))
+class(COL.lag.stsls)
+
+p1 <- predict(COL.lag.eig, newdata = COL.OLD[45:49,],
+              listw = nb2listw(COL.nb))
+class(p1)
+p2 <- predict(COL.lag.eig, newdata = COL.OLD[45:49,],
+              pred.type = "trend", type = "trend")
+#type option for retrocompatibility with spdep 0.5-92
+class(p2)
+
+imp.exact <- impacts(COL.lag.eig, listw = nb2listw(COL.nb))
+class(imp.exact)
+imp.sim <- impacts(COL.lag.eig, listw = nb2listw(COL.nb), R = 200)
+class(imp.sim)
+@ %def
+
+
+\subsubsection{\code{sarlm} objects}
+\label{sec:codesarlm-objects}
+
+There is an \code{xtable} method for objects of this type.
+<<xtablesarlm, results = 'asis'>>=
+xtable(COL.lag.eig)
+@ %def
+
+The method for \code{xtable} actually uses the summary of the object,
+and an identical result is obtained when using the summary of the
+object, even if the summary contains more additional information.
+
+<<xtablesarlmsumm, results = 'asis'>>=
+xtable(summary(COL.lag.eig, correlation = TRUE))
+@ %def
+
+This same pattern applies to the other objects from this group of packages.
+
+Note that additional prettying of the resulting table is possible, as
+for any table produced using \code{xtable}. For example using the
+\pkg{booktabs} package we get:
+
+<<xtablesarlmbooktabs, results = 'asis'>>=
+print(xtable(COL.lag.eig), booktabs = TRUE)
+@ %def
+
+\subsubsection{\code{gmsar} objects}
+\label{sec:codegmsar-objects}
+
+
+<<xtablegmsar, results = 'asis'>>=
+xtable(COL.errW.GM)
+@ %def
+
+\subsubsection{\code{stsls} objects}
+\label{sec:codestsls-objects}
+
+
+<<xtablestsls, results = 'asis'>>=
+xtable(COL.lag.stsls)
+@ %def
+
+\subsubsection{\code{sarlm.pred} objects}
+\label{sec:codesarlmpred-objects}
+
+\code{xtable} has a method for predictions of \code{sarlm} models.
+
+<<xtablesarlmpred, results = 'asis'>>=
+xtable(p1)
+@ %def
+
+This method transforms the \code{sarlm.pred} objects into data frames,
+allowing any number of attributes vectors which may vary according to
+predictor types.
+
+<<xtablesarlmpred2, results = 'asis'>>=
+xtable(p2)
+@ %def
+
+\subsubsection{\code{lagImpact} objects}
+\label{sec:codelagimpact-objects}
+
+The \code{xtable} method returns the values of direct, indirect and
+total impacts for all the variables in the model. The class
+\code{lagImpact} has two different sets of attributes according to if
+simulations are used. But the \code{xtable} method always returns the
+three components of the non-simulation case.
+
+<<xtablelagimpactexact, results = 'asis'>>=
+xtable(imp.exact)
+@ %def
+
+\p
+<<xtablelagimpactmcmc, results = 'asis'>>=
+xtable(imp.sim)
+@ %def
+
+
+\subsubsection{\code{spautolm} objects}
+\label{sec:codespautolm-objects}
+
+The need for an \code{xtable} method for \code{spautolm} was expressed
+by Guido Schulz (\url{schulzgu at student.hu-berlin.de}), who also
+provided an example of an object of this type. The required code was
+implemented by David Scott (\url{d.scott at auckland.ac.nz}).
+
+First create an object of the required type.
+
+<<minimalexample, results = 'hide'>>=
+library(spdep)
+example(NY_data)
+spautolmOBJECT <- spautolm(Z ~ PEXPOSURE + PCTAGE65P,data = nydata,
+                           listw = listw_NY, family = "SAR",
+                           method = "eigen", verbose = TRUE)
+summary(spautolmOBJECT, Nagelkerke = TRUE)
+@ %def
+
+\p
+<<spautolmclass>>=
+class(spautolmOBJECT)
+@ %def
+
+
+<<xtablespautolm, results = 'asis'>>=
+xtable(spautolmOBJECT,
+       display = c("s",rep("f", 3), "e"), digits = 4)
+@ %def
+
+
+
+\subsection{The package \pkg{splm}}
+\label{sec:package-pkgsplm}
+
+First load the package and create some objects.
+<<datasplm>>=
+library(splm)
+data("Produc", package = "plm")
+data("usaww",  package = "splm")
+fm <- log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp
+respatlag <- spml(fm, data = Produc, listw = mat2listw(usaww),
+                   model="random", spatial.error="none", lag=TRUE)
+class(respatlag)
+GM <- spgm(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp, data = Produc,
+           listw = usaww, moments = "fullweights", spatial.error = TRUE)
+class(GM)
+
+imp.spml <- impacts(respatlag, listw = mat2listw(usaww, style = "W"), time = 17)
+class(imp.spml)
+@ %def
+
+
+\subsubsection{\code{splm} objects}
+\label{sec:codesplm-objects}
+
+<<xtablesplm, results = 'asis'>>=
+xtable(respatlag)
+@ %def
+
+
+\p
+<<xtablesplm1, results = 'asis'>>=
+xtable(GM)
+@ %def
+
+
+
+The \code{xtable} method works the same on impacts of \code{splm} models.
+
+<<xtablesplmimpacts, results = 'asis'>>=
+xtable(imp.spml)
+@ %def
+
+\subsection{The package \pkg{sphet}}
+\label{sec:package-pkgsphet}
+
+First load the package and create some objects.
+<<datasphet>>=
+library(sphet)
+data("columbus", package = "spdep")
+listw <- nb2listw(col.gal.nb)
+data("coldis", package = "sphet")
+res.stsls <- stslshac(CRIME ~ HOVAL + INC, data = columbus, listw = listw,
+                      distance = coldis, type = 'Triangular')
+class(res.stsls)
+
+res.gstsls <- gstslshet(CRIME ~ HOVAL + INC, data = columbus, listw = listw)
+class(res.gstsls)
+
+imp.gstsls <- impacts(res.gstsls, listw = listw)
+class(imp.gstsls)
+@ %def
+
+
+\subsubsection{\code{sphet} objects}
+\label{sec:codesphet-objects}
+
+<<xtablesphet, results = 'asis'>>=
+xtable(res.stsls)
+@ %def
+
+\p
+<<xtablesphet1, results = 'asis'>>=
+xtable(res.gstsls)
+@ %def
+
+
+\code{sphet} also provides a method for computing impacts.
+
+<<xtablesphetimpacts, results = 'asis'>>=
+xtable(imp.gstsls)
+@ %def
+
+\section{The \pkg{zoo} package}
+\label{sec:pkgzoo-package}
+
+
+<<zoo, results = 'asis'>>=
+library(zoo)
+xDate <- as.Date("2003-02-01") + c(1, 3, 7, 9, 14) - 1
+as.ts(xDate)
+x <- zoo(rnorm(5), xDate)
+xtable(x)
+@ %def
+
+
+\p
+
+<<zoots, results = 'asis'>>=
+tempTs <- ts(cumsum(1 + round(rnorm(100), 0)),
+              start = c(1954, 7), frequency = 12)
+tempTable <- xtable(tempTs, digits = 0)
+tempTable
+tempZoo <- as.zoo(tempTs)
+xtable(tempZoo, digits = 0)
+@ %def
+
+
+\section{The \pkg{survival} package}
+\label{sec:pkgsurvival-package}
+
+
+<<survival, results = 'asis'>>=
+library(survival)
+test1 <- list(time=c(4,3,1,1,2,2,3),
+              status=c(1,1,1,0,1,1,0),
+              x=c(0,2,1,1,1,0,0),
+              sex=c(0,0,0,0,1,1,1))
+coxFit <- coxph(Surv(time, status) ~ x + strata(sex), test1)
+xtable(coxFit)
+@ %def
+
+\end{document}
diff --git a/vignettes/listOfTablesGallery.Rnw b/vignettes/listOfTablesGallery.Rnw
new file mode 100644
index 0000000..5d20236
--- /dev/null
+++ b/vignettes/listOfTablesGallery.Rnw
@@ -0,0 +1,267 @@
+%\VignetteIndexEntry{xtable List of Tables Gallery}
+%\VignetteDepends{xtable, lsmeans}
+%\VignetteKeywords{LaTeX, HTML, table}
+%\VignettePackage{xtable}
+% !Rnw weave = knitr
+% \VignetteEngine{knitr::knitr}
+%**************************************************************************
+\documentclass{article}
+\usepackage[a4paper,height=24cm]{geometry} % geometry first
+\usepackage{array}
+\usepackage{booktabs}
+\usepackage{longtable}
+\usepackage{parskip}
+\usepackage{rotating}
+\usepackage{tabularx}
+\usepackage{titlesec}
+\usepackage{hyperref} % hyperref last
+\titleformat\subsubsection{\bfseries\itshape}{}{0pt}{}
+\newcommand\p{\vspace{2ex}}
+\newcommand\code[1]{\texttt{#1}}
+\newcommand\pkg[1]{\textbf{#1}}
+\setcounter{tocdepth}{2}
+\begin{document}
+
+\title{\bfseries\Large The \code{xtableList} Gallery}
+\author{\bfseries David J. Scott}
+\maketitle
+
+\tableofcontents
+
+\newpage
+
+\section{Introduction}
+This document represents a test of the functions in \pkg{xtable} which
+deal with lists of dataframes.
+
+<<set, include=FALSE>>=
+library(knitr)
+opts_chunk$set(fig.path='Figures/list', debug=TRUE, echo=TRUE)
+opts_chunk$set(out.width='0.9\\textwidth')
+@
+
+The first step is to load the package and set some options for this document.
+<<package, results='asis'>>=
+library(xtable)
+options(xtable.floating = FALSE)
+options(xtable.timestamp = "")
+options(width = 60)
+@
+
+
+Next we create a list of dataframes with attributes.
+
+<<data>>=
+require(xtable)
+data(mtcars)
+mtcars <- mtcars[, 1:6]
+mtcarsList <- split(mtcars, f = mtcars$cyl)
+### Reduce the size of the list elements
+mtcarsList[[1]] <- mtcarsList[[1]][1,]
+mtcarsList[[2]] <- mtcarsList[[2]][1:2,]
+mtcarsList[[3]] <- mtcarsList[[3]][1:3,]
+attr(mtcarsList, "subheadings") <- paste0("Number of cylinders = ",
+                                          names(mtcarsList))
+attr(mtcarsList, "message") <- c("Line 1 of Message",
+                                 "Line 2 of Message")
+str(mtcarsList)
+attributes(mtcarsList)
+@ %def
+
+Now create a list of \code{xtable} objects.
+
+
+<<xtablelist>>=
+xList <- xtableList(mtcarsList)
+str(xList)
+@ %def
+
+Create an alternative version where the lists have different values
+for \code{digits}.
+
+
+<<xtablelist1>>=
+xList1 <- xtableList(mtcarsList, digits = c(0,2,0,0,0,1,2))
+str(xList1)
+@ %def
+
+<<xtablelist2>>=
+xList2 <- xtableList(mtcarsList, digits = c(0,2,0,0,0,1,2),
+                            caption = "Caption to List",
+                            label = "tbl:xtableList")
+str(xList2)
+@ %def
+
+Further versions with no subheadings, and no message
+
+<<xtablelist3>>=
+attr(mtcarsList, "subheadings") <- NULL
+xList3 <- xtableList(mtcarsList)
+str(xList3)
+@ %def
+
+<<xtablelist4>>=
+attr(mtcarsList, "message") <- NULL
+xList4 <- xtableList(mtcarsList)
+str(xList4)
+@ %def
+
+\newpage
+
+\section{Single Column Names}
+\label{sec:single-column-names}
+
+Print the list of \code{xtable} objects with a single header of the
+column names.
+
+First the default.
+
+
+<<singledefault, results='asis'>>=
+print.xtableList(xList)
+@ %def
+
+Booktabs should work.
+<<singlebooktabs, results='asis'>>=
+print.xtableList(xList, booktabs = TRUE)
+@ %def
+
+With digits being specified.
+<<singlebooktabs1, results='asis'>>=
+print.xtableList(xList1, booktabs = TRUE)
+@ %def
+
+Row and column names, subheadings, and the message can be sanitized.
+
+<<sanitize>>=
+large <- function(x){
+  paste0('{\\Large{\\bfseries ', x, '}}')
+}
+italic <- function(x){
+  paste0('{\\emph{ ', x, '}}')
+}
+bold <- function(x){
+  paste0('{\\bfseries ', x, '}')
+}
+red <- function(x){
+  paste0('{\\color{red} ', x, '}')
+}
+@ %def
+
+
+<<sanitizesingle, results='asis'>>=
+print.xtableList(xList,
+                 sanitize.rownames.function = italic,
+                 sanitize.colnames.function = large,
+                 sanitize.subheadings.function = bold,
+                 sanitize.message.function = red,
+                 booktabs = TRUE)
+@ %def
+
+A label and caption can be added.
+<<singlecaption, results='asis'>>=
+print.xtableList(xList2, floating = TRUE)
+@ %def
+
+Rotated column names?
+<<singlerotated, results='asis'>>=
+print.xtableList(xList, rotate.colnames = TRUE)
+@ %def
+
+No subheadings?
+<<nosubheadings, results='asis'>>=
+print.xtableList(xList3)
+@ %def
+
+No message?
+<<nomessage, results='asis'>>=
+print.xtableList(xList4)
+@ %def
+
+
+\section{Multiple Column Names}
+\label{sec:multiple-column-names}
+
+Print the list of \code{xtable} objects with multiple headers of the
+column names.
+
+First the default with multiple column name headers.
+
+<<multipledefault, results='asis'>>=
+print.xtableList(xList, colnames.format = "multiple")
+@ %def
+
+Using booktabs:
+
+<<multiplebooktabs, results='asis'>>=
+print.xtableList(xList, colnames.format = "multiple",
+                 booktabs = TRUE)
+@ %def
+
+With sanitization.
+<<sanitizemultiple, results='asis'>>=
+print.xtableList(xList, colnames.format = "multiple",
+                 sanitize.rownames.function = italic,
+                 sanitize.colnames.function = large,
+                 sanitize.subheadings.function = bold,
+                 sanitize.message.function = red,                 
+                 booktabs = TRUE)
+@ %def
+
+A label and caption can be added.
+<<multiplecaption, results='asis'>>=
+print.xtableList(xList2, colnames.format = "multiple",
+                 floating = TRUE)
+@ %def
+
+Rotated column names?
+<<multiplerotated, results='asis'>>=
+print.xtableList(xList, colnames.format = "multiple",
+                 rotate.colnames = TRUE)
+@ %def
+
+No subheadings?
+<<multiplenosubheadings, results='asis'>>=
+print.xtableList(xList3, colnames.format = "multiple")
+@ %def
+
+No message?
+<<multiplenomessage, results='asis'>>=
+print.xtableList(xList4, colnames.format = "multiple")
+@ %def
+
+\section{lsmeans}
+\label{sec:lsmeans}
+
+Summaries from the \code{lsmeans} function from the \pkg{lsmeans}
+package can easily be produced using the function
+\code{xtableLSMeans}. This function produces a list of \pkg{xtable}
+objects.
+
+
+<<lsmeans>>=
+library(lsmeans)
+warp.lm <- lm(breaks ~ wool*tension, data = warpbreaks)
+warp.lsm <- lsmeans(warp.lm, ~ tension | wool)
+warp.sum <- summary(warp.lsm, adjust = "mvt")
+warp.xtblList <- xtableLSMeans(warp.sum, digits = c(0,0,2,2,0,2,2))
+str(warp.xtblList)
+@ %def
+
+<<lsmeansstr>>=
+print.xtableList(warp.xtblList, colnames.format = "multiple",
+                 include.rownames = FALSE)
+@ %def
+<<lsmeanstable, results='asis'>>=
+print.xtableList(warp.xtblList, colnames.format = "multiple",
+                 include.rownames = FALSE)
+@ %def
+\p
+<<lsmeansbooktabs, results='asis'>>=
+print.xtableList(warp.xtblList, colnames.format = "multiple",
+                 booktabs = TRUE,
+                 include.rownames = FALSE)
+@ %def
+
+
+\end{document}
diff --git a/vignettes/margintable.Rnw b/vignettes/margintable.Rnw
index b12c583..cf4fd4b 100644
--- a/vignettes/margintable.Rnw
+++ b/vignettes/margintable.Rnw
@@ -1,6 +1,7 @@
 %\VignetteIndexEntry{xtable margintable}
 %\VignetteKeywords{LaTeX, HTML, table, margintable}
-
+% !Rnw weave = knitr
+% \VignetteEngine{knitr::knitr}
 
 \documentclass{tufte-handout}
 
@@ -10,8 +11,12 @@ A Margin Table Example
 }
 \author{David J. Scott}
 
-\usepackage{Sweave}
-\SweaveOpts{prefix.string=figdir/fig,debug=TRUE,eps=FALSE,echo=TRUE}
+
+
+<<include=FALSE>>=
+library(knitr)
+@
+
 \usepackage{rotating}
 \usepackage{longtable}
 \usepackage{booktabs}
@@ -55,7 +60,7 @@ x <- matrix(rnorm(6), ncol = 2)
 x.small <- xtable(x, label = 'tabsmall', caption = 'A margin table')
 @
 
-<<results=tex>>=
+<<results='asis'>>=
 print(x.small,floating.environment='margintable',
       latex.environments = "",
       table.placement = NULL)
diff --git a/vignettes/xtableGallery.Rnw b/vignettes/xtableGallery.Rnw
new file mode 100644
index 0000000..c618d49
--- /dev/null
+++ b/vignettes/xtableGallery.Rnw
@@ -0,0 +1,731 @@
+%\VignetteIndexEntry{xtable Gallery}
+%\VignetteDepends{xtable}
+%\VignetteKeywords{LaTeX, HTML, table}
+%\VignettePackage{xtable}
+% !Rnw weave = knitr
+% \VignetteEngine{knitr::knitr}
+%**************************************************************************
+\documentclass{article}
+\usepackage[a4paper,height=24cm]{geometry} % geometry first
+\usepackage{array}
+\usepackage{booktabs}
+\usepackage{longtable}
+\usepackage{parskip}
+\usepackage{rotating}
+\usepackage{tabularx}
+\usepackage{titlesec}
+\usepackage{hyperref} % hyperref last
+\titleformat\subsubsection{\bfseries\itshape}{}{0pt}{}
+\newcommand\p{\vspace{2ex}}
+\newcommand\code[1]{\texttt{#1}}
+\newcommand\pkg[1]{\textbf{#1}}
+\setcounter{tocdepth}{2}
+\begin{document}
+
+\title{The \pkg{xtable} Gallery}
+\author{Jonathan Swinton and others}
+\maketitle
+
+\tableofcontents
+
+\newpage
+
+\section{Introduction}
+This document gives a gallery of tables which can be made using the
+\pkg{xtable} package to create \LaTeX\ output. It doubles as a
+regression check for the package.
+
+<<include=FALSE>>=
+library(knitr)
+opts_chunk$set(fig.path='figdir/fig', debug=TRUE, echo=TRUE)
+set.seed(1234)
+@
+
+The first step is to load the package and set an option for this document.
+<<results='asis'>>=
+library(xtable)
+options(xtable.floating = FALSE)
+options(xtable.timestamp = "")
+@
+
+\section{Gallery}
+\subsection{Data frame}
+<<results='asis'>>=
+data(tli)
+xtable(tli[1:10, ])
+@
+
+\subsection{Matrix}
+<<results='asis'>>=
+design.matrix <- model.matrix(~ sex*grade, data = tli[1:10, ])
+xtable(design.matrix, digits = 0)
+@
+
+\newpage
+\subsection{aov}
+<<results='asis'>>=
+fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data = tli)
+xtable(fm1)
+@
+
+\subsection{lm}
+<<results='asis'>>=
+fm2 <- lm(tlimth ~ sex*ethnicty, data = tli)
+xtable(fm2)
+@
+
+\subsubsection{Anova table (one model)}
+<<results='asis'>>=
+xtable(anova(fm2))
+@
+
+\subsubsection{Anova table (two models)}
+<<results='asis'>>=
+fm2b <- lm(tlimth ~ ethnicty, data = tli)
+xtable(anova(fm2b, fm2))
+@
+
+\subsubsection{Anova list}
+
+<<aovlist>>=
+Block <- gl(8, 4)
+A <- factor(c(0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
+              0,1,0,1,0,1,0,1,0,1,0,1))
+B <- factor(c(0,0,1,1,0,0,1,1,0,1,0,1,1,0,1,0,0,0,1,1,
+              0,0,1,1,0,0,1,1,0,0,1,1))
+C <- factor(c(0,1,1,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,0,1,
+              1,0,1,0,0,0,1,1,1,1,0,0))
+Yield <- c(101, 373, 398, 291, 312, 106, 265, 450, 106, 306, 324, 449,
+           272, 89, 407, 338, 87, 324, 279, 471, 323, 128, 423, 334,
+           131, 103, 445, 437, 324, 361, 302, 272)
+aovdat <- data.frame(Block, A, B, C, Yield)
+
+old <- getOption("contrasts")
+options(contrasts = c("contr.helmert", "contr.poly"))
+(fit <- aov(Yield ~ A*B*C + Error(Block), data = aovdat))
+class(fit)
+summary(fit)
+options(contrasts = old)
+@
+
+\p
+
+<<xtableaovlist, results='asis'>>=
+xtable(fit)
+@
+
+
+\newpage
+\subsection{glm}
+<<results='asis'>>=
+fm3 <- glm(disadvg ~ ethnicty*grade, data = tli, family = binomial)
+xtable(fm3)
+@
+
+\subsubsection{Analysis of deviance}
+<<results='asis'>>=
+xtable(anova(fm3))
+@
+
+\subsection{prcomp}
+<<results='asis'>>=
+pr1 <- prcomp(USArrests)
+xtable(pr1)
+@
+
+\p
+<<results='asis'>>=
+xtable(summary(pr1))
+@
+
+<<include=FALSE>>=
+# pr2 <- princomp(USArrests)
+# xtable(pr2)
+@
+
+\newpage
+
+\subsection{Time series}
+<<results='asis'>>=
+temp.ts <- ts(cumsum(1 + round(rnorm(100), 0)),
+              start = c(1954, 7), frequency = 12)
+temp.table <- xtable(temp.ts, digits = 0)
+temp.table
+@
+
+\subsection{Flat tables}
+\label{sec:flat-tables}
+
+See the \textbf{Details} section of the help for \code{ftable} for a
+description of these tables, which are flat versions of
+multi-dimensional contingency tables. They require special methods to
+enable them to be printed using \pkg{xtable}
+
+
+<<ftable>>=
+data(mtcars)
+mtcars$cyl <- factor(mtcars$cyl, levels = c("4","6","8"),
+                     labels = c("four","six","eight"))
+tbl <- ftable(mtcars$cyl, mtcars$vs, mtcars$am, mtcars$gear,
+              row.vars = c(2, 4),
+              dnn = c("Cylinders", "V/S", "Transmission", "Gears"))
+tbl
+@ %def
+
+Here is the \LaTeX{} produced:
+
+<<ftablecheck>>=
+xftbl <- xtableFtable(tbl, method = "compact")
+print.xtableFtable(xftbl, booktabs = TRUE)
+@ %def
+
+And here is a basic flat table:
+
+<<ftable1, results = 'asis'>>=
+xftbl <- xtableFtable(tbl)
+print.xtableFtable(xftbl)
+@ %def
+
+This illustrates the \code{method} argument:
+
+<<ftable2, results = 'asis'>>=
+xftbl <- xtableFtable(tbl, method = "col.compact")
+print.xtableFtable(xftbl, rotate.rownames = TRUE)
+@ %def
+
+Booktabs is incompatible with vertical lines in tables, so the
+vertical dividing line is removed.
+
+<<ftable3, results = 'asis'>>=
+xftbl <- xtableFtable(tbl, method = "compact")
+print.xtableFtable(xftbl, booktabs = TRUE)
+@ %def
+\p
+
+Row and column variable names can be formatted specially using
+sanitization, and row and column variable names and labels can be
+rotated.
+
+If special formatting is required for row and column labels, that can
+be done as a workaround by redefining the data and associated labels.
+
+<<ftable4, results = 'asis'>>=
+italic <- function(x){
+  paste0('{\\emph{', x, '}}')
+}
+mtcars$cyl <- factor(mtcars$cyl, levels = c("four","six","eight"),
+                     labels = c("four",italic("six"),"eight"))
+large <- function(x){
+  paste0('{\\Large ', x, '}')
+}
+bold <- function(x){
+  paste0('{\\bfseries ', x, '}')
+}
+tbl <- ftable(mtcars$cyl, mtcars$vs, mtcars$am, mtcars$gear,
+              row.vars = c(2, 4),
+              dnn = c("Cylinders", "V/S", "Transmission", "Gears"))
+xftbl <- xtableFtable(tbl, method = "row.compact")
+print.xtableFtable(xftbl,
+                   sanitize.rownames.function = large,
+                   sanitize.colnames.function = bold,
+                   rotate.colnames = TRUE,
+                   rotate.rownames = TRUE)
+@ %def
+
+
+
+\newpage
+
+<<include=FALSE>>=
+# ## Demonstrate saving to file
+# for(i in c("latex", "html")) {
+#   outFileName <- paste("xtable.", ifelse(i=="latex", "tex", i), sep = "")
+#   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
+#         latex.environments = NULL)
+#   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
+#         latex.environments = "")
+#   print(xtable(lm.D9), type = i, file = outFileName, append = TRUE,
+#         latex.environments = "center")
+#   print(xtable(anova(glm.D93, test = "Chisq")),
+#         type = i, file = outFileName,
+#         append = TRUE)
+#   print(xtable(anova(glm.D93)), hline.after = c(1),
+#         size = "small", type = i,
+#         file = outFileName, append = TRUE)
+#   # print(xtable(pr2), type = i, file = outFileName, append = TRUE)
+# }
+@
+
+\section{Automatic formatting}
+\subsection{Suggest alignment, digits, and display}
+The functions \code{xalign}, \code{xdigits}, and \code{xdisplay} are
+useful for formatting tables in a sensible way. Consider the output
+produced by the default formatting.
+
+<<results='asis'>>=
+data(mtcars)
+dat <- mtcars[1:3, 1:6]
+x <- xtable(dat)
+x
+@
+
+\p
+Now change the default alignment, digits and display using helper functions
+\code{xalign}, \code{xdigits}, and \code{xdisplay}. This produces a better
+format as shown below.
+
+<<results='asis'>>=
+align(x) <- xalign(x)
+digits(x) <- xdigits(x)
+display(x) <- xdisplay(x)
+x
+@
+
+\subsection{Shorthand notation}
+For convenience, the three `autoformat' functions (\code{xalign},
+\code{xdigits}, and \code{xdisplay}) can be applied together when an
+\code{xtable} is created, using the \code{auto} argument:
+
+<<results='asis'>>=
+xtable(dat, auto = TRUE)
+@
+
+\p
+Similarly, the \code{autoformat} function can be used to postprocess an
+existing \code{xtable}:
+
+<<results='asis'>>=
+x <- xtable(dat)
+autoformat(x)
+@
+
+\newpage
+
+\subsection{Math-Style Exponents}
+If you prefer $5 \times 10^5$ in your tables to 5e5, the
+\code{math.style.exponents} option to \code{print.xtable} is useful:
+
+<<results='asis'>>=
+print(xtable(data.frame(text = c("foo","bar"),
+                        googols = c(10e10,50e10),
+                        small = c(8e-24,7e-5),
+                        row.names = c("A","B")),
+             display = c("s","s","g","g")),
+      math.style.exponents = TRUE)
+@
+
+this option also supports the values \code{ensuremath} which uses
+\code{\char`\\ensuremath} instead of \code{\$\$} and \code{UTF-8}
+which uses UTF-8 to approximate the \LaTeX typesetting.
+
+
+\section{Sanitization}
+<<results='asis'>>=
+insane <- data.frame(Name = c("Ampersand","Greater than","Less than",
+                            "Underscore","Per cent","Dollar",
+                            "Backslash","Hash","Caret","Tilde",
+                            "Left brace","Right brace"),
+                     Character = I(c("&",">","<","_","%","$",
+                                     "\\","#","^","~","{","}")))
+colnames(insane)[2] <- paste(insane[, 2], collapse = "")
+xtable(insane)
+@
+
+\p
+Sometimes you might want to have your own sanitization function.
+
+
+<<results='asis'>>=
+wanttex <- xtable(data.frame(Column =
+                             paste("Value_is $10^{-",1:3,"}$", sep = "")))
+print(wanttex, sanitize.text.function =
+      function(str) gsub("_", "\\_", str, fixed = TRUE))
+@
+
+\p
+Sanitization can be useful in formatting column headings and row names:
+
+<<sanitize3>>=
+dat <- mtcars[1:3, 1:6]
+large <- function(x){
+  paste0('{\\Large{\\bfseries ', x, '}}')
+}
+italic <- function(x){
+  paste0('{\\emph{ ', x, '}}')
+}
+@ %def
+
+<<sanitize4, results = 'asis'>>=
+print(xtable(dat),
+      sanitize.rownames.function = italic,
+      sanitize.colnames.function = large,
+      booktabs = TRUE)
+@ %def
+
+
+
+\newpage
+
+\subsection{Markup in tables}
+Markup can be included in tables, including in column and row names,
+by using a custom \code{sanitize.text.function}.
+
+<<results='asis'>>=
+mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4)
+rownames(mat) <- "$y_{t-1}$"
+colnames(mat) <- c("$R^2$", "$\\bar{x}$", "F-stat", "S.E.E", "DW")
+mat <- xtable(mat)
+print(mat, sanitize.text.function = function(x) {x})
+@
+
+% By David Dahl to demonstrate contribution from David Whitting, 2007-10-09.
+\p
+You can also have sanitize functions that are specific to column or
+row names.  In the table below, the row name is not sanitized but
+column names and table elements are.
+
+<<results='asis'>>=
+money <- matrix(c("$1,000","$900","$100"), ncol = 3,
+                dimnames = list("$\\alpha$",
+                                c("Income (US$)","Expenses (US$)",
+                                  "Profit (US$)")))
+print(xtable(money), sanitize.rownames.function = function(x) {x})
+@
+
+\section{Format examples}
+\subsection{Adding a centering environment}
+<<results='asis'>>=
+print(xtable(anova(fm3), caption = "\\tt latex.environments = \"\""),
+      floating = TRUE, latex.environments = "")
+print(xtable(anova(fm3), caption = "\\tt latex.environments = \"center\""),
+      floating = TRUE, latex.environments = "center")
+@
+
+\newpage
+
+\subsection{Column alignment}
+<<results='asis'>>=
+tli.table <- xtable(tli[1:10, ])
+align(tli.table) <- rep("r", 6)
+tli.table
+@
+
+\subsubsection{Left aligned strings with column lines}
+<<results='asis'>>=
+align(tli.table) <- "|rrl|l|lr|"
+tli.table
+@
+
+\subsubsection{Fixed width columns}
+<<results='asis'>>=
+align(tli.table) <- "|rr|lp{3cm}l|r|"
+tli.table
+@
+
+\newpage
+
+\subsection{Number of digits}
+One number for all columns,
+<<results='asis'>>=
+display(tli.table)[c(2,6)] <- "f"
+digits(tli.table) <- 3
+tli.table
+@
+
+\p
+or one for each column, including the row names,
+<<results='asis'>>=
+digits(tli.table) <- 1:(ncol(tli)+1)
+tli.table
+@
+
+\p
+or as a full matrix.
+<<results='asis'>>=
+digits(tli.table) <- matrix(0:4, nrow = 10, ncol = ncol(tli)+1)
+tli.table
+@
+
+\newpage
+
+\subsection{Suppress row/column names}
+\subsubsection{Suppress row names}
+<<results='asis'>>=
+tli.table <- xtable(tli[1:10, ])
+print(tli.table, include.rownames = FALSE)
+@
+
+\p
+If you want a vertical line on the left, you need to change the \code{align}
+attribute.
+<<results='asis'>>=
+align(tli.table) <- "|r|r|lp{3cm}l|r|"
+print(tli.table, include.rownames = FALSE)
+@
+
+\p
+Revert the alignment to what is was before.
+<<>>=
+align(tli.table) <- "|rr|lp{3cm}l|r|"
+@
+
+\newpage
+
+\subsubsection{Suppress column names}
+<<results='asis'>>=
+print(tli.table, include.colnames = FALSE)
+@
+
+\p
+Note the doubled header lines which can be suppressed.
+<<results='asis'>>=
+print(tli.table, include.colnames = FALSE,
+      hline.after = c(0,nrow(tli.table)))
+@
+
+\subsubsection{Suppress row and column names}
+<<results='asis'>>=
+print(tli.table, include.colnames = FALSE, include.rownames = FALSE)
+@
+
+\newpage
+
+\subsection{Rotate row/column names}
+The \code{rotate.rownames} and \code{rotate.colnames} arguments can be
+used to rotate the row and/or column names. This requires
+\verb|\usepackage{rotating}| in the \LaTeX\ preamble.
+
+<<results='asis'>>=
+print(tli.table, rotate.rownames = TRUE, rotate.colnames = TRUE)
+@
+
+\newpage
+
+\subsection{Horizontal lines}
+\subsubsection{Line locations}
+Use the \code{hline.after} argument to specify the position of the
+horizontal lines.
+
+<<results='asis'>>=
+print(xtable(anova(fm3)), hline.after = c(1))
+@
+
+\subsubsection{Line styles}
+Specifying \code{booktabs = TRUE} will generate three line types. By
+default, when no value is given for \code{hline.after}, a
+\verb|\toprule| will be drawn above the table, a \verb|\midrule| after
+the table headings and a \verb|\bottomrule| below the table. This
+requires \verb|\usepackage{booktabs}| in the \LaTeX\ preamble.
+
+\p
+
+The top and bottom rules are slightly thicker than the mid rule. The
+thickness of the lines can be set via the \LaTeX\ lengths
+\verb|\heavyrulewidth| and \verb|\lightrulewidth|.
+
+<<results='asis'>>=
+tli.table <- xtable(tli[1:10, ])
+print(tli.table, include.rownames = FALSE, booktabs = TRUE)
+@
+
+\p
+
+If \code{hline.after} includes \code{-1}, a \verb|\toprule| will be
+drawn above the table. If \code{hline.after} includes the number of
+rows in the table, a \verb|\bottomrule| will be drawn below the
+table. For any other values specified in \code{hline.after}, a
+\verb|\midrule| will be drawn after that line of the table.
+
+\p
+The following table has more than one \verb|\midrule|.
+
+<<results='asis'>>=
+bktbs <- xtable(matrix(1:10, ncol = 2))
+hlines <- c(-1, 0, 1, nrow(bktbs))
+print(bktbs, booktabs = TRUE, hline.after = hlines)
+@
+
+\subsection{Table level commands}
+<<results='asis'>>=
+print(xtable(anova(fm3)), size = "large")
+@
+
+\p
+<<results='asis'>>=
+print(xtable(anova(fm3)), size = "\\setlength{\\tabcolsep}{12pt}")
+@
+
+\subsection{Long tables}
+Requires \verb|\usepackage{longtable}| in the \LaTeX\ preamble.
+
+<<results='asis'>>=
+x <- matrix(rnorm(1000), ncol = 10)
+x.big <- xtable(x, caption = "A \\code{longtable} spanning several pages")
+print(x.big, hline.after=c(-1, 0), tabular.environment = "longtable")
+@
+
+Extra features of the \pkg{longtable} \LaTeX{} package can typically
+be activated using \code{add.to.row}, as shown below.
+
+<<results='asis'>>=
+add.to.row <- list(pos = list(0), command = NULL)
+command <- paste0("\\hline\n\\endhead\n",
+                  "\\hline\n",
+                  "\\multicolumn{", dim(x)[2] + 1, "}{l}",
+                  "{\\footnotesize Continued on next page}\n",
+                  "\\endfoot\n",
+                  "\\endlastfoot\n")
+add.to.row$command <- command
+print(x.big, hline.after=c(-1), add.to.row = add.to.row,
+      tabular.environment = "longtable")
+@
+
+
+\newpage
+
+\subsection{Use of \code{add.to.row} argument}
+The following frequency table has outer dimnames: \code{Grade3} and
+\code{Grade6}.
+
+<<>>=
+Grade3 <- c("A","B","B","A","B","C","C","D","A","B",
+            "C","C","C","D","B","B","D","C","C","D")
+Grade6 <- c("A","A","A","B","B","B","B","B","C","C",
+            "A","C","C","C","D","D","D","D","D","D")
+Cohort <- table(Grade3, Grade6)
+Cohort
+@
+
+\p
+The default behavior of \code{print.xtable} is to strip outer dimnames.
+<<results='asis'>>=
+xtable(Cohort)
+@
+
+\p
+The desired column labels can be created using \code{add.to.row}, in this case
+applying two commands to ``row number zero'' while suppressing the basic column
+names.
+
+<<results='asis'>>=
+addtorow <- list()
+addtorow$pos <- list(0, 0)
+addtorow$command <- c("& \\multicolumn{4}{c}{Grade 6} \\\\\n",
+                      "Grade 3 & A & B & C & D \\\\\n")
+print(xtable(Cohort), add.to.row = addtorow, include.colnames = FALSE)
+@
+
+\subsection{Sideways tables}
+Requires \verb|\usepackage{rotating}| in the LaTeX
+preamble.  Sideways tables can't be forced in place with the \code{[H]}
+specifier, but you can use the \verb|\clearpage| command to get them
+fairly nearby.
+
+<<results='asis'>>=
+x <- x[1:30, ]
+x.side <- xtable(x, caption = "A sideways table")
+print(x.side, floating = TRUE, floating.environment = "sidewaystable")
+@
+\clearpage
+
+\subsection{Rescaled tables}
+Specify a \code{scalebox} value to rescale the table.
+<<results='asis'>>=
+x <- x[1:20, ]
+x.rescale <- xtable(x)
+print(x.rescale, scalebox = 0.7)
+@
+
+\subsection{Aligning fixed width columns}
+Note that using specifications such as \verb|p{2cm}| always
+produces a \textbf{left aligned} column. What if some other alignment
+is desired?
+
+This is not really a problem with \pkg{xtable} but with the formatting
+of tables with fixed width columns and different alignments using
+standard \LaTeX.
+
+One solution is to use the \verb|array| package, defining new
+column formats.
+
+\begin{verbatim}
+\newcolumntype{L}[1]{>{\raggedright\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{C}[1]{>{\centering\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{R}[1]{>{\raggedleft\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{P}[1]{>{\raggedright\tabularxbackslash}p{#1}}
+\end{verbatim}
+
+These allow for very sophisticated cell formatting, namely
+left-aligned, centred, or right-aligned text, with recognition of line
+breaks for the first three new column types. If these lines are
+included along with \verb|\usepackage{array}|, then the following is
+possible.
+
+\newcolumntype{L}[1]{>{\raggedright\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{C}[1]{>{\centering\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{R}[1]{>{\raggedleft\let\newline\\
+    \arraybackslash\hspace{0pt}}m{#1}}
+\newcolumntype{P}[1]{>{\raggedright\tabularxbackslash}p{#1}}
+
+<<results='asis'>>=
+df <- data.frame(name = c("A","B"), right = c(1.4, 34.6),
+                 left = c(1.4, 34.6), text = c("txt1","txt2"))
+print(xtable(df, align = c("l", "|c", "|R{3cm}", "|L{3cm}", "| p{3cm}|")),
+      floating = FALSE, include.rownames = FALSE)
+@
+
+\newpage
+
+\subsection{Table width}
+The \code{tabularx} environment is for typesetting tables whose
+overall width is fixed. The column alignment code \code{X} denotes
+columns that will be stretched to achieve the desired table
+width. Requires \verb|\usepackage{tabularx}| in the \LaTeX\ preamble.
+
+<<results='asis'>>=
+df.width <- data.frame(One = c("item 1", "A"), Two = c("item 2", "B"),
+                       Three = c("item 3", "C"), Four = c("item 4", "D"))
+x.width <- xtable(df.width)
+align(x.width) <- "|l|X|l|l|l|"
+print(x.width, tabular.environment = "tabularx", width = "\\textwidth")
+@
+
+\section{Suppressing printing}
+By default the \code{print} method will print the \LaTeX\ or HTML to
+standard output and also return the character strings invisibly.  The
+printing to standard output can be suppressed by specifying
+\code{print.results = FALSE}.
+
+<<>>=
+x.out <- print(tli.table, print.results = FALSE)
+@
+
+Formatted output can also be captured without printing with the
+\code{toLatex} method.  This function returns an object of class
+\code{"Latex"}.
+
+<<>>=
+x.ltx <- toLatex(tli.table)
+class(x.ltx)
+x.ltx
+@
+
+
+\newpage
+
+\section{Acknowledgements}
+Most of the examples in this gallery are taken from the \pkg{xtable}
+documentation. Two examples (\code{add.to.row} and `Aligning fixed width
+columns') are from Stack Exchange.
+
+\section{Session information}
+<<results='asis'>>=
+toLatex(sessionInfo())
+@
+
+\end{document}
diff --git a/vignettes/xtableGallery.snw b/vignettes/xtableGallery.snw
deleted file mode 100644
index 2dfa32b..0000000
--- a/vignettes/xtableGallery.snw
+++ /dev/null
@@ -1,585 +0,0 @@
-%\VignetteIndexEntry{xtable Gallery}
-%\VignetteDepends{xtable}
-%\VignetteKeywords{LaTeX,HTML,table}
-%\VignettePackage{xtable}
-
-%**************************************************************************
-%
-% # $Id:$
-
-% $Revision:  $
-% $Author: $
-% $Date:  $
-
-<<echo=FALSE,eval=FALSE>>=
-makeme <- function() {
-	# I am a convenience function for debugging and can be ignored
-	setwd("C:/JonathanSwinton/PathwayModeling/src/R/SourcePackages/xtable/inst/doc")
-	Sweave("xtableGallery.RnW",stylepath=FALSE)
-}
-makeme()
-@
-
-\documentclass[letterpaper]{article}
-
-\title{
-The xtable gallery
-}
-\author{Jonathan Swinton <jonathan at swintons.net>\\ with small contributions from others}
-
-\usepackage{Sweave}
-\SweaveOpts{prefix.string=figdir/fig,debug=TRUE,eps=FALSE,echo=TRUE}
-\usepackage{rotating}
-\usepackage{longtable}
-\usepackage{booktabs}
-\usepackage{tabularx}
-%\usepackage{hyperref}
-\begin{document}
-
-\maketitle
-\section{Summary}
-This document gives a gallery of tables which can be made
-by using the {\tt xtable} package to create \LaTeX\ output.
-It doubles as a regression check for the package.
-
-<<>>=
-library(xtable)
-@
-
-\section{Gallery}
-\subsection{Data frame}
-Load example dataset
-<<>>=
-data(tli)
-
-## Demonstrate data.frame
-tli.table <- xtable(tli[1:10,])
-digits(tli.table)[c(2,6)] <- 0
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE)
-@
-
-\subsection{Matrix}
-<<>>=
-design.matrix <- model.matrix(~ sex*grade, data=tli[1:10,])
-design.table <- xtable(design.matrix)
-@
-<<results=tex>>=
-print(design.table,floating=FALSE)
-@
-
-\subsection{aov}
-<<>>=
-fm1 <- aov(tlimth ~ sex + ethnicty + grade + disadvg, data=tli)
-fm1.table <- xtable(fm1)
-@
-<<results=tex>>=
-print(fm1.table,floating=FALSE)
-@
-\subsection{lm}
-<<>>=
-fm2 <- lm(tlimth ~ sex*ethnicty, data=tli)
-fm2.table <- xtable(fm2)
-@
-<<results=tex>>=
-print(fm2.table,floating=FALSE)
-@
-\subsubsection{anova object}
-
-<<results=tex>>=
-print(xtable(anova(fm2)),floating=FALSE)
-@
-\subsubsection{Another anova object}
-<<>>=
-fm2b <- lm(tlimth ~ ethnicty, data=tli)
-@
-<<results=tex>>=
-print(xtable(anova(fm2b,fm2)),floating=FALSE)
-@
-
-
-\subsection{glm}
-
-<<>>=
-
-## Demonstrate glm
-fm3 <- glm(disadvg ~ ethnicty*grade, data=tli, family=binomial())
-fm3.table <- xtable(fm3)
-@
-<<results=tex>>=
-print(fm3.table,floating=FALSE)
-@
-
-\subsubsection{anova object}
-@
-<<results=tex>>=
-print(xtable(anova(fm3)),floating=FALSE)
-@
-
-
-\subsection{More aov}
-<<>>=
-
-## Demonstrate aov
-## Taken from help(aov) in R 1.1.1
-## From Venables and Ripley (1997) p.210.
-N <- c(0,1,0,1,1,1,0,0,0,1,1,0,1,1,0,0,1,0,1,0,1,1,0,0)
-P <- c(1,1,0,0,0,1,0,1,1,1,0,0,0,1,0,1,1,0,0,1,0,1,1,0)
-K <- c(1,0,0,1,0,1,1,0,0,1,0,1,0,1,1,0,0,0,1,1,1,0,1,0)
-yield <- c(49.5,62.8,46.8,57.0,59.8,58.5,55.5,56.0,62.8,55.8,69.5,55.0,
-           62.0,48.8,45.5,44.2,52.0,51.5,49.8,48.8,57.2,59.0,53.2,56.0)
-npk <- data.frame(block=gl(6,4), N=factor(N), P=factor(P), K=factor(K), yield=yield)
-npk.aov <- aov(yield ~ block + N*P*K, npk)
-op <- options(contrasts=c("contr.helmert", "contr.treatment"))
-npk.aovE <- aov(yield ~  N*P*K + Error(block), npk)
-options(op)
-#summary(npk.aov)
-@
-<<results=tex>>=
-print(xtable(npk.aov),floating=FALSE)
-@
-
-\subsubsection{anova object}
-<<results=tex>>=
-print(xtable(anova(npk.aov)),floating=FALSE)
-@
-
-\subsubsection{Another anova object}
-<<results=tex>>=
-print(xtable(summary(npk.aov)),floating=FALSE)
-@
-
-<<>>=
-#summary(npk.aovE)
-@
-<<results=tex>>=
-print(xtable(npk.aovE),floating=FALSE)
-@
-
-
-<<results=tex>>=
-print(xtable(summary(npk.aovE)),floating=FALSE)
-@
-
-\subsection{More lm}
-<<>>=
-
-## Demonstrate lm
-## Taken from help(lm) in R 1.1.1
-## Annette Dobson (1990) "An Introduction to Generalized Linear Models".
-## Page 9: Plant Weight Data.
-ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
-trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
-group <- gl(2,10,20, labels=c("Ctl","Trt"))
-weight <- c(ctl, trt)
-lm.D9 <- lm(weight ~ group)
-@
-<<results=tex>>=
-print(xtable(lm.D9),floating=FALSE)
-@
-
-
-<<results=tex>>=
-print(xtable(anova(lm.D9)),floating=FALSE)
-@
-
-\subsection{More glm}
-<<>>=
-
-## Demonstrate glm
-## Taken from help(glm) in R 1.1.1
-## Annette Dobson (1990) "An Introduction to Generalized Linear Models".
-## Page 93: Randomized Controlled Trial :
-counts <- c(18,17,15,20,10,20,25,13,12)
-outcome <- gl(3,1,9)
-treatment <- gl(3,3)
-d.AD <- data.frame(treatment, outcome, counts)
-glm.D93 <- glm(counts ~ outcome + treatment, family=poisson())
-@
-<<results=tex>>=
-print(xtable(glm.D93,align="r|llrc"),floating=FALSE)
-@
-
-\subsection{prcomp}
-<<prcomp>>=
-if(require(stats,quietly=TRUE)) {
-  ## Demonstrate prcomp
-  ## Taken from help(prcomp) in mva package of R 1.1.1
-  data(USArrests)
-  pr1 <- prcomp(USArrests)
-}
-@
-<<results=tex>>=
-if(require(stats,quietly=TRUE)) {
-  print(xtable(pr1),floating=FALSE)
-}
-@
-
-
-@
-<<results=tex>>=
-  print(xtable(summary(pr1)),floating=FALSE)
-@
-
-
-
-<<>>=
-#  ## Demonstrate princomp
-#  ## Taken from help(princomp) in mva package of R 1.1.1
-#  pr2 <- princomp(USArrests)
-#  print(xtable(pr2))
-@
-\subsection{Time series}
-
-<<>>=
-temp.ts <- ts(cumsum(1+round(rnorm(100), 0)), start = c(1954, 7), frequency=12)
-   temp.table <- xtable(temp.ts,digits=0)
-    caption(temp.table) <- "Time series example"
-@
-<<results=tex>>=
-    print(temp.table,floating=FALSE)
-@
-<<savetofile,echo=FALSE>>=
-if (FALSE) {
-  for(i in c("latex","html")) {
-    outFileName <- paste("xtable.",ifelse(i=="latex","tex",i),sep="")
-    print(xtable(lm.D9),type=i,file=outFileName,append=TRUE,latex.environments=NULL)
-    print(xtable(lm.D9),type=i,file=outFileName,append=TRUE,latex.environments="")
-    print(xtable(lm.D9),type=i,file=outFileName,append=TRUE,latex.environments="center")
-    print(xtable(anova(glm.D93,test="Chisq")),type=i,file=outFileName,append=TRUE)
-    print(xtable(anova(glm.D93)),hline.after=c(1),size="small",type=i,file=outFileName,append=TRUE)
-      # print(xtable(pr2),type=i,file=outFileName,append=TRUE)
-         }
-}
-@
-
-\section{Sanitization}
-<<>>=
-insane <- data.frame(Name=c("Ampersand","Greater than","Less than","Underscore","Per cent","Dollar","Backslash","Hash", "Caret", "Tilde","Left brace","Right brace"),
-				Character = I(c("&",">",		"<",		"_",		"%",		"$",		"\\", "#",	"^",		"~","{","}")))
-colnames(insane)[2] <- paste(insane[,2],collapse="")
-@
-
-<<pxti,results=tex>>=
-print( xtable(insane))
-@
-Sometimes you might want to have your own sanitization function
-<<>>=
-wanttex <- xtable(data.frame( label=paste("Value_is $10^{-",1:3,"}$",sep="")))
-@
-<<results=tex>>=
-print(wanttex,sanitize.text.function=function(str)gsub("_","\\_",str,fixed=TRUE))
-@
-
-\subsection{Markup in tables}
-
-Markup can be kept in tables, including column and row names, by using a custom sanitize.text.function:
-
-<<>>=
-mat <- round(matrix(c(0.9, 0.89, 200, 0.045, 2.0), c(1, 5)), 4)
-rownames(mat) <- "$y_{t-1}$"
-colnames(mat) <- c("$R^2$", "$\\bar{R}^2$", "F-stat", "S.E.E", "DW")
-mat <- xtable(mat)
-@
-<<results=tex>>=
-print(mat, sanitize.text.function = function(x){x})
-@
-
-% By David Dahl to demonstrate contribution from David Whitting, 2007-10-09.
-You can also have sanitize functions that are specific to column or row names.  In the table below, the row name is not sanitized but column names and table elements are:
-<<>>=
-money <- matrix(c("$1,000","$900","$100"),ncol=3,dimnames=list("$\\alpha$",c("Income (US$)","Expenses (US$)","Profit (US$)")))
-@
-<<results=tex>>=
-print(xtable(money),sanitize.rownames.function=function(x) {x})
-@
-
-\section{Format examples}
-\subsection{Adding a centering environment }
-<<results=tex>>=
-   print(xtable(lm.D9,caption="\\tt latex.environments=NULL"),latex.environments=NULL)
-    print(xtable(lm.D9,caption="\\tt latex.environments=\"\""),latex.environments="")
-    print(xtable(lm.D9,caption="\\tt latex.environments=\"center\""),latex.environments="center")
-@
-\subsection{Column alignment}
-
-<<>>=
-tli.table <- xtable(tli[1:10,])
-@
-<<>>=
-align(tli.table) <- rep("r",6)
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE)
-@
-\subsubsection{Single string and column lines}
-<<>>=
-align(tli.table) <- "|rrl|l|lr|"
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE)
-@
-\subsubsection{Fixed width columns}
-<<>>=
-align(tli.table) <- "|rr|lp{3cm}l|r|"
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE)
-@
-
-\subsection{Significant digits}
-
-
-Specify with a single argument
-<<>>=
-digits(tli.table) <- 3
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE,)
-@
-
-
-or one for each column, counting the row names
-<<>>=
-digits(tli.table) <- 1:(ncol(tli)+1)
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE,)
-@
-
-
-or as a full matrix
-<<>>=
-digits(tli.table) <- matrix( 0:4, nrow = 10, ncol = ncol(tli)+1 )
-@
-<<results=tex>>=
-print(tli.table,floating=FALSE,)
-@
-
-\subsection{Suppress row names}
-<<results=tex>>=
-print((tli.table),include.rownames=FALSE,floating=FALSE)
-@
-
-If you want a vertical line on the left, you need to change the align attribute.
-<<>>=
-align(tli.table) <- "|r|r|lp{3cm}l|r|"
-@
-<<results=tex>>=
-print((tli.table),include.rownames=FALSE,floating=FALSE)
-@
-
-Revert the alignment to what is was before.
-<<>>=
-align(tli.table) <- "|rr|lp{3cm}l|r|"
-@
-
-\subsection{Suppress column names}
-<<results=tex>>=
-print((tli.table),include.colnames=FALSE,floating=FALSE)
-@
-\\
-Note the doubled header lines which can be suppressed with, eg,
-<<results=tex>>=
-print(tli.table,include.colnames=FALSE,floating=FALSE,hline.after=c(0,nrow(tli.table)))
-@
-
-\subsection{Suppress row and column names}
-<<results=tex>>=
-print((tli.table),include.colnames=FALSE,include.rownames=FALSE,floating=FALSE)
-@
-
-\subsection{Rotate row and column names}
-The {\tt rotate.rownames } and {\tt rotate.colnames} arguments can be
-used to rotate the row and/or column names.
-
-<<results=tex>>=
-print((tli.table),rotate.rownames=TRUE,rotate.colnames=TRUE)
-@
-
-\subsection{Horizontal lines}
-
-\subsubsection{Line locations}
-
-Use the {\tt hline.after} argument to specify the position of the horizontal lines.
-
-<<results=tex>>=
-print(xtable(anova(glm.D93)),hline.after=c(1),floating=FALSE)
-@
-
-\subsubsection{Line styles}
-
-The \LaTeX package {\tt booktabs} can be used to specify different
-line style tags for top, middle, and bottom lines.  Specifying
-{\tt booktabs = TRUE} will lead to separate tags being generated
-for the three line types.
-
-Insert \verb|\usepackage{booktabs}| in your \LaTeX preamble and define
-the {\tt toprule}, {\tt midrule}, and {\tt bottomrule} tags to specify
-the line styles. By default, when no value is given for
-\texttt{hline.after}, a \texttt{toprule} will be drawn above the
-table, a \texttt{midrule} after the table headings and a
-\texttt{bottomrule} below the table. The width of the top and bottom
-rules can be set by supplying a value to \verb+\heavyrulewidth+. The
-width of the midrules can be set by supplying a value to
-\verb+\lightrulewidth+. The following tables have
-\verb+\heavyrulewidth = 2pt+ and \verb+\lightrulewidth = 0.5pt+, to
-ensure the difference in weight is noticeable.
-
-There is no support for \verb+\cmidrule+ or \verb+\specialrule+
-although they are part of the \texttt{booktabs} package.
-
-\heavyrulewidth = 2pt
-\lightrulewidth = 0.5pt
-
-<<results=tex>>=
-print(tli.table, booktabs=TRUE, floating = FALSE)
-@
-
-\vspace{12pt}
-If \texttt{hline.after} includes $-1$, a \texttt{toprule} will be
-drawn above the table. If \texttt{hline.after} includes the number of
-rows in the table, a \texttt{bottomrule} will be drawn below the
-table. For any other values specified in \texttt{hline.after}, a
-\texttt{midrule} will be drawn after that line of the table.
-
-The next table has more than one \texttt{midrule}.
-
-<<>>=
-bktbs <- xtable(matrix(1:10, ncol = 2))
-hlines <- c(-1,0,1,nrow(bktbs))
-@
-This command produces the required table.
-<<results=tex>>=
-print(bktbs, booktabs = TRUE, hline.after = hlines, floating = FALSE)
-@
-
-
-\subsection{Table-level \LaTeX}
-<<results=tex>>=
-print(xtable(anova(glm.D93)),size="small",floating=FALSE)
-@
-
-
-\subsection{Long tables}
-Remember to insert \verb|\usepackage{longtable}| in your \LaTeX preamble.
-
-<<longtable>>=
-
-## Demonstration of longtable support.
-x <- matrix(rnorm(1000), ncol = 10)
-x.big <- xtable(x,label='tabbig',
-	caption='Example of longtable spanning several pages')
-@
-<<results=tex>>=
-print(x.big,tabular.environment='longtable',floating=FALSE)
-@
-
-%%
-%% The column name alignment is off in the following example.
-%% It needs some revision before exposing it. - CR, 7/2/2012
-%%
-%
-%\subsubsection{Long tables with the header on each page}
-%
-%The {\tt add.to.row} argument can be used to display the header
-%for a long table on each page, and to add a "continued" footer
-%on all pages except the last page.
-%
-%<<results=tex>>=
-%library(xtable)
-%x<-matrix(rnorm(1000), ncol = 10)
-%addtorow<-list()
-%addtorow$pos<-list()
-%addtorow$pos[[1]]<-c(0)
-%addtorow$command<-c(paste(
-%    "\\hline \n",
-%    "  \\endhead \n",
-%    "  \\hline \n",
-%    "  {\\footnotesize Continued on next page} \n",
-%    "  \\endfoot \n",
-%    "  \\endlastfoot \n",sep=""))
-%x.big2 <- xtable(x, label = "tabbig2",
-%    caption = "Example of longtable with the header on each page")
-%print(x.big2, tabular.environment = "longtable", floating = FALSE,
-%include.rownames=FALSE, add.to.row=addtorow, hline.after=c(-1) )
-%@
-
-\subsection{Sideways tables}
-Remember to insert \verb|\usepackage{rotating}| in your LaTeX preamble.
-Sideways tables can't be forced in place with the `H' specifier, but you can
-use the \verb|\clearpage| command to get them fairly nearby.
-
-<<>>=
-x <- x[1:30,]
-x.small <- xtable(x,label='tabsmall',caption='A sideways table')
-@
-
-<<results=tex>>=
-print(x.small,floating.environment='sidewaystable')
-@
-\clearpage
-
-\subsection{Rescaled tables}
-Specify a {\tt scalebox} value to rescale the table.
-
-<<>>=
-x <- x[1:20,]
-x.rescale <- xtable(x,label='tabrescaled',caption='A rescaled table')
-@
-
-<<results=tex>>=
-print(x.rescale, scalebox=0.7)
-@
-
-\subsection{Table Width}
-The {\tt tabularx} tabular environment provides more alignment options,
-and has a {\tt width} argument to specify the table width.
-
-Remember to insert \verb|\usepackage{tabularx}| in your \LaTeX preamble.
-
-<<>>=
-df.width <- data.frame(
-  "label 1 with much more text than is needed" = c("item 1", "A"),
-  "label 2 is also very long" = c("item 2","B"),
-  "label 3" = c("item 3","C"),
-  "label 4" = c("item 4 but again with too much text","D"),
-  check.names = FALSE)
-
-x.width <- xtable(df.width,
-  caption="Using the 'tabularx' environment")
-align(x.width) <- "|l|X|X|l|X|"
-@
-
-<<results=tex>>=
-print(x.width, tabular.environment="tabularx",
-  width="\\textwidth")
-@
-
-\section{Suppressing Printing}
-By default the {\tt print} method will print the LaTeX or HTML to standard
-output and also return the character strings invisibly.  The printing to
-standard output can be suppressed by specifying {\tt print.results = FALSE}.
-
-<<>>=
-x.out <- print(tli.table, print.results = FALSE)
-@
-
-Formatted output can also be captured without printing with the
-{\tt toLatex} method.  This function returns an object of class
-{\tt "Latex"}.
-
-<<>>=
-x.ltx <- toLatex(tli.table)
-class(x.ltx)
-x.ltx
-@
-
-\section{Acknowledgements}
-Most of the examples in this gallery are taken from the {\tt xtable} documentation.
-\section{R Session information}
-<<results=tex>>=
-toLatex(sessionInfo())
-@
-\end{document}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/r-cran-xtable.git



More information about the debian-science-commits mailing list