New environment in latex using other environments, compiler doesn't find the \end - latex

I'm setting up a new environment for my latex document for consistent tables. It looks like this:
\newenvironment{defaultTable}[2] {
\begin{table}[h]
\noindent
\tabularx{\textwidth}{#1}
\specialrule{0.5pt}{10pt}{0pt} \rowcolor[gray]{.9}
} {
\bottomrule
\endtabularx
\caption{#2}
\end{table}
}
It doesn't seem to find the \end{table} though:
! LaTeX Error: \begin{table} on input line 23 ended by \end{document}.
Is there a way to avoid this?

Replace \begin{table} with \#float{table} and replace \end{table} with \end#float.
The \#float and \end#float are LaTeX's internal commands for starting and ending the float environment.
You'll also want to follow Alexey's advice on the #2 parameter. Store it in the first part of your environment (\gdef\mycaption{#2}) and then recall it later \caption{\mycaption} in the second part. Put \def\mycaption{\relax} just before the \begin{defaultTable} line.
Also, since \#float and \end#float have # signs in them, if this code is in the preamble of your document file (instead of say, a .sty file), you'll need to put \makeatletter before your \begin{defaultTable} and also \makeatother after \end{defaultTable}.

You can use #2 in the end if you use the xparse mechanism:
\usepackage{xparse}
\NewDocumentEnvironment{defaultTable}{+m+m}{%
\begin{table}[h]
\noindent
\tabularx{\textwidth}{#1}
\specialrule{0.5pt}{10pt}{0pt} \rowcolor[gray]{.9}
} {%
\bottomrule
\endtabularx
\caption{#2}
\end{table}
}

You can not use #2 in the last argument of the \newenvironment macros. You should use #1..#9 in the second argument only.
Save your #2 to \tempa (or any macros). And use \tempa in the caption.
\newenvironment{defaultTable}[2]{
\begin{table}[h]
\def\tempa{#2}
\noindent
\tabularx{\textwidth}{#1} \specialrule{0.5pt}{10pt}{0pt} \rowcolor[gray]{.9}
}{
\bottomrule
\endtabularx
\caption{\tempa}
\end{table}
}

I've has the same problem, and it is because of the "\end{tabularx}". The solution is:
\newenvironment{defaultTable}[3] {
\begin{table}[h]
\caption{#2}
\noindent
\begin{tabularx}{\textwidth}{#1}
\specialrule{0.5pt}{10pt}{0pt} \rowcolor[gray]{.9}
#3
\bottomrule
\end{tabularx} } {
\end{table} }
So you define the rows as a parameter.
Regards,
Eric

You could also just use a \newcommand similar to Eric's solution.
\documentclass{article}
\usepackage{tabularx}
% The table design.
\newcommand{\defaultTable}[2]{
\begin{table}[h]
\begin{tabularx}{\textwidth}{cc}
Column A & Column B \\
#2
\end{tabularx}
\caption{#1}
\end{table}
}
\newcommand{\defaultTableRow}[2]{#1 & #2 \\}
\begin{document}
% The creation of a table.
\defaultTable{Example}{
\defaultTableRow{bla}{0815}
\defaultTableRow{blup}{0815}
}
\end{document}
This will avoid both your problems (the missing \end{table} and the error when referencing arguments in the environments closing code) without much hassle.
In fact I also like the idea of separating the table design from the table data. Especially if you create multiple tables that need to look equal.

Related

knitr file ended while scanning use of \#xverbatim

I have the following .Rnw file:
\documentclass{article}
\usepackage[table]{xcolor}
\usepackage{multicol}
\begin{document}
\begin{multicols}{2}
\hskip-3.5cm\begin{tabular}{|l|}
\hline
\cellcolor[RGB]{0,0,140}{\large\textbf{\textcolor{white}{Bill To: }}}\\
\hline
\textbf{
"asdf"
}\\
\\[-1em]
\textbf{asdf#asdf.com} \\
\hline
\end{tabular}
\hskip6cm\begin{tabular}{|l|l|}
\hline
Date: & 05/31/2018 \\
\hline
Invoice \#: & 1234asdf \\
\hline
\end{tabular}
\end{multicols}
\end{document}
which gives me the expected pdf:
However, when I replace the "asdf" with R code:
\documentclass{article}
\usepackage[table]{xcolor}
\usepackage{multicol}
\begin{document}
\begin{multicols}{2}
\hskip-3.5cm\begin{tabular}{|l|}
\hline
\cellcolor[RGB]{0,0,140}{\large\textbf{\textcolor{white}{Bill To: }}}\\
\hline
\textbf{
<<asdf>>=
cat("asdf")
#
}\\
\\[-1em]
\textbf{asdf#asdf.com} \\
\hline
\end{tabular}
\hskip6cm\begin{tabular}{|l|l|}
\hline
Date: & 05/31/2018 \\
\hline
Invoice \#: & 1234asdf \\
\hline
\end{tabular}
\end{multicols}
\end{document}
I get the following error:
File ended while scanning use of \#xverbatim
Looking at the generated .tex file, this is the relevant part:
\textbf{
\begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{kframe}
\begin{alltt}
\hlkwd{cat}\hlstd{(}\hlstr{"asdf"}\hlstd{)}
\end{alltt}
\begin{verbatim}
## asdf
\end{verbatim}
\end{kframe}
\end{knitrout}
}\\
and this is what the .log file says:
Runaway argument?
#### asdf \end {verbatim} \end {kframe} \end {knitrout} \check#icr \expandafte
r \ETC.
! File ended while scanning use of \#xverbatim.
<inserted text>
\par
<*> test2.tex
I suspect you have forgotten a `}', causing me
to read past where you wanted me to stop.
I'll try to recover; but if the error is serious,
you'd better type `E' or `X' now and fix your file.
! Emergency stop.
<*> test2.tex
What am I doing wrong?
By default, R output is wrapped in a LaTeX verbatim environment, and you can't put one of those inside \textbf. There are a couple of different approaches to fix this.
The simplest is just to use the chunk option results='asis', i.e.
\textbf{
<<asdf,results='asis',echo=FALSE>>=
cat("asdf")
#
}
This will prevent knitr from adding the environment around the output; the LaTeX code will just be
\textbf{
asdf
}
which should be fine.
If you want the default formatting but just want to change the font or style of text, things are harder. You need to tell knitr to use a different environment instead of verbatim, e.g. the Verbatim environment provided by the fancyvrb package. You can do this by changing the output hook. For example, this should work
% in the preamble:
\usepackage{fancyvrb}
<<include=FALSE>>=
oldhook <- knitr::knit_hooks$get("output")
bold <- function(x, options)
paste0("\\begin{Verbatim}[fontseries=b]\n", x, "\\end{Verbatim}")
#
% in the body:
<<asdf,echo=FALSE>>=
knitr::knit_hooks$set(output = bold)
cat("asdf")
#
% Optionally restore the old hook...
<<include=FALSE>>=
knitr::knit_hooks$set(output = oldhook)
#
However, it doesn't always work, because some options (like fontseries=b) conflict with settings that knitr makes. You can change to italic (using fontshape=it), but not to bold. So stick with the first suggestion.

Environment inside a longtable with LaTeX

I would like to create a new environment to print a header and a footer between sections of a table.
I did this:
\documentclass{article}
\usepackage{longtable}
\newenvironment{env}{Heading&&& \\}{\hline \\}
\begin{document}
\begin{longtable}{p{7cm}lrr}
\begin{env}
Content&b&c&d
\end{env}
\end{longtable}
\end{document}
but I get insulted by the compiler. See here for the complete output.
Does someone see the problem?
There are two problems here. First, you need an \\ at the end of the "Content&b&c&d" line. Second, environments don't work inside tabular/longtable — that's where most of your error messages are coming from. It may be possible to diddle them into working, but it's way beyond my TeX-fu. This is the best I can come up with:
\documentclass{article}
\usepackage{longtable}
\newcommand{\startenv}{Heading\tabularnewline}
\newcommand{\stopenv}{\hline\tabularnewline}
\begin{document}
\begin{longtable}{p{7cm}lrr}
\startenv
Content&b&c&d \\
\stopenv
\end{longtable}
(It is not strictly necessary to use \tabularnewline instead of \\, but it will avoid headaches if you ever mix this with other environments that use \\ for their own purposes.)

How to create a \newenvironment in latex for a scaled table

I try to define a table as a new environment.
\newenvironment{scaledtable}[1]{%
\begin{table}[h]
\caption{xxx}
\label{tab:xxx}
\begin{center}
\begin{tabular}{rcrrrrrrrrrrrrcc}
}{
\hline
\end{tabular}
\end{center}
\end{table}}
The problem I have is that I can't use scalebox{}. If I put the closing bracket into the end definition of the environment, latex can't assign the brackets anymore. I also can not use PStricks because of pdflatex.
Use \lrbox to temporarily store the table, then scale it
\newsavebox{\scaledtablebox}
\newcommand*{\scaledtablefactor}{1}
\newenvironment{scaledtable}[1]{%
\renewcommand*{\scaledtablefactor}{#1}%
\begin{table}[h]%
\caption{xxx}%
\label{tab:xxx}%
%
\begin{lrbox}{\scaledtablebox}%
\begin{tabular}{ll}%
}{%
\hline%
\end{tabular}%
\end{lrbox}%
%
\begin{center}%
\scalebox{\scaledtablefactor}{\usebox{\scaledtablebox}}%
\end{center}%
\end{table}%
}
Works like this (0.5 is the scale factor):
\begin{scaledtable}{0.5}
Hello & World! \\
\end{scaledtable}

How to get the value of the document title in latex?

I am wondering how I can get the document title in LaTex, for use elsewhere in the document. I just want to be able to echo it.
Using \#title does not work because \maketitle clears \#title. This seems silly to me but that's the way it is. One solution is to redefine \title to save the title somewhere else. For instance,
\def\title#1{\gdef\#title{#1}\gdef\THETITLE{#1}}
then use \THETITLE.
You can do the other way around: \def\MYTITLE{...} then \title{\MYTITLE} and later use \MYTITLE again.
I had success just writing a new command.
\newcommand{\mytitle}{...}
\title{\mytitle}
There is a package called authoraftertitle that does exactly this
\documentclass{article}
\usepackage{authoraftertitle}
\setlength\parindent{0 pt}
\begin{document}
\title{a good title}
\author{a better author}
\date{the best date}
\maketitle
the title is: \textbf{\MyTitle} \\
the author is: \textbf{\MyAuthor} \\
the data is: \textbf{\MyDate} \\
\end{document}
This is a workaround...
\let\titleoriginal\title % save original \title macro
\renewcommand{\title}[1]{ % substitute for a new \title
\titleoriginal{#1}% % define the real title
\newcommand{\thetitle}{#1} % define \thetitle
}
\title{This is my title}
\begin{document}
\thetitle
\end{document}
The short version of the title was ignored here...

How to make a signature field in LaTeX

When I'm writing my laboratory reports in LaTeX, I recently had to make a signature field on the form.
Trondheim 4.september 2009
______________________ ___________________________
Ivar Nesje Team mate's name
The problem was that I could not find a easy way to do it so after a lot of searching on the net I came up with this simple solution
\newcommand{\doubleSignature}[3]{
\begin{minipage}[c]{\textwidth}
\vspace{2cm}
\makebox[12cm][c]{
#1, \today
}
\vspace{3cm}
\makebox[12cm][c]{
\hfill \makebox[5cm][c] {\hrulefill} \hfill \makebox[5cm][c] {\hrulefill} \hfill
}
\makebox[12cm][c]{
\hfill #2 \hfill #3 \hfill
}
\vspace{1cm}
\end{minipage}
}
This allowed me to type;
\doubleSignature{Trondheim}{Ivar Nesje}{Team mate's name}
To achieve the wanted result. If any of you have another way of doing this, not using the letter document class, I'd be really glad to hear your suggestions.
I think I would work from \rule[<raise>]{<width>}{<thickness>}. Because the reference point is the lower left corner, you probably don't even need the optional raising argument. Something like:
\newcommand{\doublesignature}[3][Ivar Nesje]{%
\parbox{\textwidth}{
\centering #3 \today\\
\vspace{2cm}
\parbox{7cm}{
\centering
\rule{6cm}{1pt}\\
#1
}
\hfill
\parbox{7cm}{
\centering
\rule{6cm}{1pt}\\
#2
}
}
}
I've re-ordered your arguments to make your name optional.
Assuming there aren't additional formatting restrictions, I probably would have used a tabular environment instead of boxes, and I would have used \rule{length}{width} instead of \hrulefill:
\newcommand{\doubleSignature}[3]{
\vspace{2cm}
\begin{center}
#1, \today
\end{center}
\vspace{3cm}
\noindent
\begin{tabular}{lcl}
\rule{5cm}{1pt} & \hspace{2cm} & \rule{5cm}{1pt} \\
#2 & & #3
\end{tabular}
\vspace{1cm}
}

Resources