Environment inside a longtable with LaTeX - 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.)

Related

How to wrap LaTex command in new environment

This question has already been answered once (wrap LaTeX command in environment), yet I still struggle to make my own rather simple new environment command work.
What I wanted to do is to convert the following LaTex block, which shows the output of some code, into a command I can reuse.
\fbox{\begin{minipage}{\textwidth}
\texttt{
>> CODE OUTPUT
\end{minipage}}
It is clear that in order to make a new environment command that replicates what I do above, I will have to make use of wrappers. (Because of the \fbox and the \texttt command.)
I would like to do this without having to download yet another package, or going into the secret realms of LaTex with some predefined \dir command that is only there to do the same job twice.
Checking the link from before, it seems that a productive solution is to use \bgroup and \egroup. I would therefore write something like this:
\newenvironment{CodeOutput}
{\fbox\bgroup\begin{minipage}{\textwidth}\texttt\bgroup}
{\egroup\end{minipage}\egroup}
Yet this will still not work. (On Overleaf at least.) It would be great if there was a straightforward way of making commands like these. Thanks for any useful suggestions!
If want to write a command that does what you're after, then the following would work:
\newcommand{\mycmd}[1]{%
\fbox{%
\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\ttfamily #1
\end{minipage}%
}%
}
The idea here works because the <arg>ument supplied to \mycmd{<arg>} is replaced by #1 in its entirety. If you want want to rewrite this as an environment, it's a little more difficult, purely because of \fbox. \fbox is doesn't have an environment-form equivalent the same way \texttt has \ttfamily (which is technically a font switch). There is a quick way around it provided by environ - it allows you to capture the contents of an environment in a macro \BODY:
\usepackage{environ}
\NewEnviron{myenvA}{%
\fbox{%
\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\ttfamily \BODY
\end{minipage}%
}%
}
However, you do have the option by capturing the content of an environment inside a box and then setting the box inside an \fbox:
\newsavebox{\codebox}% To store the content of myenvB
\newenvironment{myenvB}{%
\begin{lrbox}{\codebox}%
\ttfamily\ignorespaces
}{%
\end{lrbox}%
\fbox{\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\usebox{\codebox}%
\end{minipage}}%
}
The following minimal example shows all the above cases:
\documentclass{article}
\usepackage{environ}
\newcommand{\mycmd}[1]{%
\fbox{%
\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\ttfamily #1
\end{minipage}%
}%
}
\NewEnviron{myenvA}{%
\fbox{%
\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\ttfamily \BODY
\end{minipage}%
}%
}
\newsavebox{\codebox}
\newenvironment{myenvB}{%
\begin{lrbox}{\codebox}%
\ttfamily\ignorespaces
}{%
\end{lrbox}%
\fbox{\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\usebox{\codebox}%
\end{minipage}}%
}
\begin{document}
\noindent
\fbox{\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\ttfamily SoMe CoDe HeRe
\end{minipage}}
\bigskip
\noindent
\mycmd{SoMe CoDe HeRe}
\bigskip
\noindent
\begin{myenvA}
SoMe CoDe HeRe
\end{myenvA}
\bigskip
\begin{lrbox}{\codebox}
\ttfamily SoMe CoDe HeRe
\end{lrbox}
\noindent
\fbox{\begin{minipage}{\dimexpr\linewidth-2\fboxrule-2\fboxsep}
\usebox{\codebox}
\end{minipage}}
\bigskip
\noindent
\begin{myenvB}
SoMe CoDe HeRe
\end{myenvB}
\end{document}

[Beamer/Latex]: Getting \part name from different part

Hi I would like to create some sort of my own table of content in beamer presentation where there will be all parts with all sections listed.
To this moment I came up with this solution to list all \tableofcontents in one slide
\begin{frame}
\begin{multicols}{2}
\setcounter{tocdepth}{1}
\foreach\x in {1,...,\totvalue{part}}{%
\vskip 0.4cm
\tableofcontents[part=\x]%
}%
\setcounter{tocdepth}{2}
\end{multicols}
\end{frame}
Problem here is that I get section of each part but there is not partname listed.
Is there way how to access name of part by index \x of for-cycle? Something like \insertpart[\x]?
Ok with help of one co-student of mine I came up with solution to my problem.
\makeatletter
\AtBeginPart{
\write\#auxout{%
\noexpand\expandafter\noexpand\gdef\noexpand\csname
part\thepart name\noexpand\endcsname{\beamer#partname}}
}
\makeatother
\begin{document}
\frame{\maketitle}
\section*{Outline}
\begin{frame}{Outline of Presentation}
\begin{multicols}{2}
\setcounter{tocdepth}{1}
\foreach\x in {1,...,\totvalue{part}}{%
\medskip\expandafter\let\expandafter\partname
\csname part\x name\endcsname
\penalty-999
\textit{\partname}
\medskip
{\let\vfill=\relax\tableofcontents[part=\x]}\vfill
\penalty-999
}%
\setcounter{tocdepth}{2}
\end{multicols}
\end{frame}
Unfortunately I cannot write down deep description of how exactly it works but basically it takes names of parts during first run of pdflatex and saves them into .aux file. Then during second run of pdflatex it will correctly print them out. Then negative penalty is added to each block so partname is not splitted out of rest of part-toc.
So two runs of pdflatex are needed to work it correctly but it should work quite nicely. I managed to create table of content with 4 parts.
example
Hopefully it will help someone.

Using the booktabs \midrule and with brackets

I am having trouble using \midrule in a latex longtable along with brackets. For example, here is my latex document (test.tex):
\documentclass[a4paper]{article}\usepackage[]{graphicx}\usepackage[]{color}
\usepackage{longtable}
\usepackage{booktabs}
\begin{document}
\begin{longtable}{|l|l|}
\caption{} \\
\toprule
test & estimate\\
\midrule
(Intercept) & 10.000 \\
test & 20.000 \\
\bottomrule
\end{longtable}
\end{document}
When running pdflatex on this file:
pdflatex test.tex
I run into these errors:
! Undefined control sequence.
<argument> ...al \expandafter \let \cmrsideswitch
\#tempa \fi \fi
l.12 (Intercept)
& 10.000 \\
Removing the brackets fixes the issue. And interestingly switching the order of the 2 rows works too [i.e. the (Intercept) row as the second row). I can't figure out what is wrong. Has anyone encountered this?
OK, so I had the same problem with code generated from Pandoc (with bracket after \toprule), I fixed it by using \toprule{} instead, it seems that toprule eats the bracket otherwise. Maybe this will help you.
Another possibilty is to put empty \hbox{} before the opening bracket, which I used, since I could not modify tex produced by pandoc (but pandoc is capable of parsing latex snippets in markdown).

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...

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

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.

Resources