I am trying to wrap an environment created with \NewEnviron (package 'environ') into an old good \newenvironment:
\NewEnviron{test}{\colorbox[gray]{0.7}{\BODY}}
\newenvironment{wrapper}{\begin{test}}{\end{test}}
\begin{wrapper}
debug me
\end{wrapper}
However, this gives me a strange error:
LaTeX Error: \begin{test} on input line 15 ended by \end{wrapper}.
LaTeX Error: \begin{wrapper} on input line 15 ended by \end{document}.
If I replace \NewEnviron{test}{aaa(\BODY)bbb} with \newenvironment{test}{aaa(}{)bbb} — everything works as expected! It seems like \NewEnviron fails to find its end for some reason.
I'm trying to do some magic with 'floatfig' wrapped into a \colorbox so I need a way to convert \colorbox to an environment and wrap it into another one. I can define a new command but it's not a very good idea.
The thing is that \NewEviron and \newenvironment works in different ways.
1) \newenvironment{test}{aaa(}{)bbb} defines two commands: \test is aaa( and \endtest is )bbb.
\begin{test} is expanded to \test.
\end{test} is expanded to \endtest and checks that your scope begins with begin{test} rather \begin{something else}, for example \begin{wrapper}.
2) \NewEviron{test}{aaa(\BODY)bbb} defines \test in different way. First of all \test catches the \BODY using the following trick
\def\test#1\end{\def\BODY{#1}aaa(\BODY)bbb\testcontinue}
(name \testcontinue may be different) and inserts aaa(\BODY)bbb. Then \testcontinue checks that \end on some input line ended by \end{test} rather than \end{something else}. Macro \endtest
is not needed because it is never executed.
Look on your code:
\begin{wrapper}
debug me
\end{wrapper}
\begin{wrapper} is expanded to \begin{test}. Then
\begin{test} is expanded to \test. \test catch \BODY.
Attention! \BODY is equal to debug me. And now \testcontionue checks
that \end after \BODY ended by \end{test}. It is not true. \end{test} is absent.
There is \end{wrapper}.
You want to say that \end{wrapper} must be expanded to \end{test}. But \end before wrapper was eaten by
macro \test: #1\end{\def\BODY{#1}aaa(\BODY)bbb\testcontinue}
and can not be executed.
I hope I success to explain.
I've found a hacky trick to create an environment that can be wrapped in another one. One should use saveBoxes like this:
\newenvironment{example}[2][]{%
\newsavebox{\exampleStore} % Box storage
\begin{lrbox}{\exampleStore} % Start capturing the input
}{%
\end{lrbox} % Stop capturing the input
\colorbox[gray]{0.7}{%
\usebox{\NBstorage} % Load the box's contents
}%
}%
}%
Related
I'm a LaTeX newbie, but I've been doing my homework, and now I have a question that I can't seem to find the answer to.
I create the definition of an equation, let's just say it's this one:
The potential is characterized by a length $\sigma$ and an energy $\epsilon$.
In reality, this equation is more complex, which is why I wanted to try a shortcut. If my equation were this simplistic, I wouldn't try my substitution technique.
I use the \renewcommand to save me some time:
\renewcommand{\sigma}{1}
And this works fabulously and will replace all instances of sigma with 1. Unfortunately though, since \sigma has a global scope, I need to reset it.
I tried a couple different ways:
Attempt 1: -deadlock due to circular reference?
\newcommand{\holdsigma}{\sigma}
\renewcommand{\sigma}{1}
The potential is characterized by a length $\sigma$ and an energy $\epsilon$.
\renewcommand{\sigma}{\holdsigma}
I would think to reset the command, it should look something like this:
\renewcommand{\sigma}{\greek{\sigma}}
but that obviously hasn't worked out for me.
Any idea about how the greek letters are originally defined in the language?
I have to admit that I don't understand why you want to do what you're asking, but this should work:
\documentclass{article}
\begin{document}
Before redefinition, \verb|\sigma| looks like $\sigma$.
% Copy the current definition of \sigma to \oldsigma
\let\oldsigma\sigma
% Redefine \sigma to be '1'
\renewcommand{\sigma}{1}
After redefinition, \verb|\sigma| looks like $\sigma$.
You can still use \verb|\oldsigma| if you want to use the original definition $\oldsigma$.
% Restore the original definition of \sigma
\let\sigma\oldsigma
Now \verb|\sigma| is back to its normal appearance $\sigma$.
\end{document}
To find out how \sigma or any other command is originally defined, you can use \show\sigma. (The answer is that \sigma is defined as \mathchar"11B.) You can type this either in your document itself — compilation will pause and you can type Enter after reading the reply — or you can type this in TeX/LaTeX's interactive mode.
Example with a document:
\documentclass{article}
\begin{document}
What is $\sigma$? % Prints "What is σ" in the DVI/PS/PDF.
\show\sigma % Prints "> \sigma=\mathchar"11B." in the compilation.
Now that we know, let us redefine it.
\renewcommand{\sigma}{1}
Now it is: $\sigma$. % Prints "Now it is: 1." in the DVI/PS/PDF.
OK, let's go back.
\renewcommand{\sigma}{\mathchar"11B}
We again have: $\sigma$. %Prints "We again have: σ." in the DVI/PS/PDF.
\end{document}
Or else at the command prompt, type latex, then type \relax, then type \show\sigma, read what it says, then type x to exit.
I'm trying to make Latex usable, by introducing some timesavers, but I'm having trouble with defining new commands that terminate environments, completely at random.
This works:
\newcommand{\bcv}{\ensuremath{\begin{smallmatrix}}}
\newcommand{\ecv}{\ensuremath{\end{smallmatrix}}}
\newcommand{\be}{\begin{enumerate}}
\newcommand{\ee}{\end{enumerate}}
This does not work:
\newcommand{\bal}{\begin{align*}}
\newcommand{\eal}{\end{align*}}
\newcommand{\verbass}[1]{\begin{verbatim} #1 \end {verbatim}}
Specifically, I think the \end value is just ignored?
When I try to use \verbass{Halp} I get an error: !File ended while scanning use of \#xverbatim.
Obviously I can use \begin{foo} ... \end{foo} at all locations as needed, but really, this should work!
How \begin{verbatim} works. briefly and roughly.
\begin{verbatim} is expanded to \verbatim.
Then \verbatim sets category code of each characters to 11.
Now all chars is letters.
Then \verbatim sets font, parindent and calls \#xverbatim.
\#xverbatim catches the end of verbatim using the following trick:
\def\#xverbatim#1\end{#1\end}
Then \end{verbatim} finishes work.
How \newcommand{\verbass}[1]{\begin{verbatim} #1 \end {verbatim}} work.
First of all \verbass{Halp} reads its argument.
#1 --> Halp
\verbass expands to \begin{verbatim} Halp \end {verbatim}.
Important: backslash of \end has category 0 rather than 11.
Moreover { and } have categories 1 and 2 rather than 11.
Then \begin{verbatim} expands to \varbatim.
\varbatim changes all categories and font. But (important)
the category of backslash (in \end) remains equal to 0.
Then \verbatim calls \#xverbatim.
\#xverbatim tries to catch your argument using the following trick:
\def\#xverbatim#1\end{#1\end}
but it is impossible because of \#xverbatim tries to catch
\end where all letters (\,e,n,d) have the category 11.
But in fact there are four letters with other category code:
\ with category 0 and e,n,d with category 11.
\#xverbatim is trying and trying to find \end where backslash (\) has category 11 but.... File ended while scanning use of \#xverbatim
There's a very brief explanation here about verb and verbatim. Basically, LaTeX insists verb and verbatim get the first "look" at their contents.
I am far away from being a professional programmer, but a quick-and-dirty-solutions could be:
\newcommand{\myverbatim}[1]{\begin{tt} \detokenize{#1} \end{tt} \\ }
The output is not very nice, because linebreaks are ignored. If this is desired one could repeat the command line-by-line (?).
I'm experimenting with my own commands and environments and now I'm facing those problems:
How to create command \foo{parameter}[optional] or environment called \begin{bar}{parameter}[optional]?
How to create command \foo[optional_1]...[optional_n]{parameter}
I've tried
\newcommand{\foo}[3][][]{#1#2#3} - failed
\newcommand{\foo}[3][2][][]{#1#2#3} - failed
Does anyone know some hint? Thanks a lot.
You can't create a \foo{parameter}[optional] command simply; you can, however, create a \foo[optional]{parameter} command with
\newcommand{\foo}[2][default]{Mandatory: #2; optional: #1}
If you call it as \foo{given}, it will produce Mandatory: given, optional: default; if you call it as \foo[bonus]{given}, it will produce Mandatory: given, optional: bonus. This is probably how you should do it—that will look better with the rest of your LaTeX code. Creating a new environment with optional parameters is done similarly with
\newenvironment{env}[2][def]{(#1,#2)\begingroup}{\endgroup}
where #1 is again the optional argument; this is again written as \begin{env}[opt]{req}...\end{env}. If you really want a command in the other form, see the end of my answer.
The TeX FAQ has an answer about writing commands with more than one optional argument. There are two options to how to do it. The underlying idea is to define a command which takes an optional argument, and then runs another command which itself takes an optional argument, etc.; the twoopt package encapsulates this.
If you really want a command like \reversed{mandatory}[optional], you can do it like so. First, you define a command which takes a required argument, stores it in a macro, and then forward it onto another command. This second command takes an optional argument, and uses the defined command and the optional argument. Putting this all together, we get
\makeatletter
\newcommand{\reversed}[1]{\def\reversed#required{#1}\reversed#opt}
\newcommand{\reversed#opt}[1][def]{Required: \reversed#required; optional: #1}
\makeatother
You can then use \reversed{mandatory}[optional] or just \reversed{mandatory}, and everything should work.
Using the xparse package (part of the LaTeX3 development efforts):
\usepackage{xparse}
\NewDocumentCommand\foo{O{}O{}m}{%
% Code with optional #1 and #2 with empty defaults
}
\NewDocumentCommand\foo{mO{}}{%
% Code with optional #2 with empty default
}
\NewDocumentEnvironment{foo}{O{}}{%
% Start code with optional #1
}{%
% End code with optional #1
}
Optional arguments are a bit different in xparse to with \newcommand. You can detect whether one is given or not:
\NewDocumentCommand\foo{mo}{%
\IfNoValueTF{#2}
{Code without #2}
{Code with #2}%
}
You'll see that this works by using a lower case 'o', whereas the upper case 'O' then requires a default value (which I've made empty by including an empty group).
Consider also the xargs package. The following is an example from its documentation.
Set it up in the usual way,
\usepackage{xargs}
and then if you define
\newcommandx*\coord[3][1=1, 3=n]{(#2_{#1},\ldots,#2_{#3})}
(which means to use "1" for the first argument, if it is not specified, and to use "n" for the third). Then
$\coord{x}$
yields (sans subscripts)
(x1, . . . , xn)
and
$\coord[0]{y}$
yields (again, sans subscripts, and y replaces the mandatory parameter)
(y0, ..., yn)
I know there are already comprehensive answers, but is some cases, I want to give different definitions for different situations. There is a still very basic yet simple solution for this. I write it down in case any other need it.
% ----------------------------------
%! TEX program = XeLaTeX
% !TeX encoding = UTF-8
% Author: Troy_Daniel
% Email: Troy_Daniel#163.com
% ----------------------------------
\documentclass{article}
\usepackage{xcolor}
\newcommand{\Caption}[3]{%
\textcolor[rgb]{0.36, 0.72, 0.80}{\Large #1}
{\def\tmp{#3}
\ifx\tmp\empty % the third parameter is not provieded
\textcolor[rgb]{0.96, 0.66, 0.35}{\small#2}
\else % non-empty third parameter
\textcolor[rgb]{0.96, 0.66, 0.35}{\small[#3]#2}
\fi}}
\begin{document}
\Caption{First}{Second}{}
\Caption{First}{Second}{Third}
\end{document}
And the result is shown below, different definitions for optional parameter(s):
I want to redefine the \part* command so that it automatically adds a contents line. This proves difficult since I want to reuse the original \part* command inside my starred version.
Normally (i.e. for unstarred commands) I would do it like this:
\let\old#part\part
\renewcommand\part[2][]{
\old#part[#1]{#2}
… rest of definition}
That is, I would save the original definition of \part in \old#part and use that.
However, this doesn’t work for starred commands since they don’t define a single lexeme (unlike the \part command in the example above). This boils down to the following question: How can I save a starred command?
Notice that I already know how to redefine a starred command itself, using the \WithSuffix command from the suffix package. This isn’t the problem.
There is no \part* command. What happens is the \part command takes a look at the next character after it (with \#ifstar) and dispatches to one of two other routines that does the actual work based on whether there's an asterisk there or not.
Reference: TeX FAQ entry Commands defined with * options
Thanks to #smg’s answer, I’ve cobbled together a solution that works perfectly. Here’s the complete source, along with explanatory comments:
% If this is in *.tex file, uncomment the following line.
%\makeatletter
% Save the original \part declaration
\let\old#part\part
% To that definition, add a new special starred version.
\WithSuffix\def\part*{
% Handle the optional parameter.
\ifx\next[%
\let\next\thesis#part#star%
\else
\def\next{\thesis#part#star[]}%
\fi
\next}
% The actual macro definition.
\def\thesis#part#star[#1]#2{
\ifthenelse{\equal{#1}{}}
{% If the first argument isn’t given, default to the second one.
\def\thesis#part#short{#2}
% Insert the actual (unnumbered) \part header.
\old#part*{#2}}
{% Short name is given.
\def\thesis#part#short{#1}
% Insert the actual (unnumbered) \part header with short name.
\old#part*[#1]{#2}}
% Last, add the part to the table of contents. Use the short name, if provided.
\addcontentsline{toc}{part}{\thesis#part#short}
}
% If this is in *.tex file, uncomment the following line.
%\makeatother
(This needs the packages suffix and ifthen.)
Now, we can use it:
\part*{Example 1}
This will be an unnumbered part that appears in the TOC.
\part{Example 2}
Yes, the unstarred version of \verb/\part/ still works, too.
I'm trying to write a simple example command that prints nothing without an argument, but with an argument it surrounds it with something.
I've read that the default value should be \#empty and the simple \ifx\#empty#1 condition should do the job:
\newcommand{\optarg}[1][\#empty]{%
\ifx\#empty#1 {} \else {(((#1)))} \fi
}
\optarg % (((empty)))
\optarg{} % (((empty)))
\optarg{test} % (((empty))) test
The latter three commands all print the empty word for some reason, and I want the first two to print nothing and the last to print (((test))).
I'm using TeXLive/Ubuntu. An ideas?
Try the following test:
\documentclass{article}
\usepackage{xifthen}% provides \isempty test
\newcommand{\optarg}[1][]{%
\ifthenelse{\isempty{#1}}%
{}% if #1 is empty
{(((#1)))}% if #1 is not empty
}
\begin{document}
Testing \verb|\optarg|: \optarg% prints nothing
Testing \verb|\optarg[]|: \optarg[]% prints nothing
Testing \verb|\optarg[test]|: \optarg[test]% prints (((test)))
\end{document}
The xifthen package provides the \ifthenelse construct and the \isempty test.
Another option is to use the ifmtarg package (see the ifmtarg.sty file for the documentation).
Using the LaTeX3 xparse package:
\usepackage{xparse}
\NewDocumentCommand\optarg{g}{%
\IfNoValueF{#1}{(((#1)))}%
}
In the underlying TeX engine with which LaTeX is written, the number of arguments a command can take is fixed. What you've done with the default [\#empty] is ask LaTeX to examine the next token to see if it is an open square bracket [. If so, LaTeX takes the contents of square brackets as the argument, if not, the next token is put back into the input stream and the default \#empty argument is used instead. So to get your idea to work, you have to use square brackets to delimit the optional argument when present:
\optarg
\optarg[]
\optarg[test]
You should have better luck with this notation.
It's annoying that you can't use the same brackets for an optional argument as you use for a required argument, but that's the way it is.
\documentclass{article}
\usepackage{ifthen} % provides \ifthenelse test
\usepackage{xifthen} % provides \isempty test
\newcommand{\inlinenote}[2][]{%
{\bfseries{Note:}}%
\ifthenelse{\isempty{#1}}
{#2} % if no title option given
{~\emph{#1} #2} % if title given
}
\begin{document}
\inlinenote{
simple note
}
\inlinenote[the title]{
simple note with title
}
\end{document}