LaTeX: Redefining starred command - latex

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.

Related

Building Latex/Tex arguments in lua

I use lua to make some complex job to prepare arguments for macros in Tex/LaTex.
Part I
Here is a stupid minimal example :
\newcommand{\test}{\luaexec{tex.print("11,12")}}% aim to create 11,12
\def\compare#1,#2.{\ifthenelse{#1<#2}{less}{more}}
\string\compare11,12. : \compare11,12.\\ %answer is less
\string\test : \test\\ % answer is 11,12
\string\compare : \compare\test. % generate an error
The last line creates an error. Obviously, Tex did not detect the "," included in \test.
How can I do so that \test is understood as 11 followed by , followed by 12 and not the string 11,12 and finally used as a correctly formed argument for \compare ?
There are several misunderstandings of how TeX works.
Your \compare macro wants to find something followed by a comma, then something followed by a period. However when you call
\compare\test
no comma is found, so TeX keeps looking for it until finding either the end of file or a \par (or a blank line as well). Note that TeX never expands macros when looking for the arguments to a macro.
You might do
\expandafter\compare\test.
provided that \test immediately expands to tokens in the required format, which however don't, because the expansion of \test is
\luaexec{tex.print("11,12")}
and the comma is hidden by the braces, so it doesn't count. But it wouldn't help nonetheless.
The problem is the same: when you do
\newcommand{\test}{\luaexec{tex.print("11,12")}}
the argument is not expanded. You might use “expanded definition” with \edef, but the problem is that \luaexec is not fully expandable.
If you do
\edef\test{\directlua{tex.sprint("11,12")}}
then
\expandafter\compare\test.
would work.

Redefining sectioning commands in latex, issues with references and labels

I'm trying to change the appearance of one of the native sectioning commands in LaTeX. But after doing so, latex cannot handle references as expected.
The code given later is expected to output a document with the text
1 One
See section 2.
2 Two
See section 1.
But instead I get the following.
1 One
See section .
2 Two
See section .
What can I change in the renewed command, such that the references will work again.
The code for the document is as follows:
\documentclass{article}
\newcounter{seccnt}
\renewcommand{\section}[1]{\vspace{2em}\stepcounter{seccnt} \theseccnt~ {\Large #1}\vspace{0.5em}}
\begin{document}
\section{One}
\label{secOne}
See section \ref{secTwo}.
\section{Two}
\label{secTwo}
See section \ref{secOne}.
\end{document}
I think you need to use \refstepcounter instead of \stepcounter, so that the reference is stored.

\newcommand / \newenvironment - optional parameters

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):

Triple-wrapping of \colorbox → \NewEnviron → \newenvironment fails

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
}%
}%
}%

How to put line break in a math

I'd like to express the following sentence (source_location is also italic, it's not correctly rendered):
Each entry has a list of tuple: < source_location, R/W, trip_counter, occurrence, killed (explained in the later) >
My current workaround for this is:
$ \left\langle
\textit{source\_location}, \textit{R/W}, \textit{trip\_counter},
\textit{occurrence}, \textit{killed} \text{(explained in the later)}
\right\rangle $
I'm using 2-column paper. This < .. > is too long, but no line break because it is a math. How do I automatically (or manually) put line break in such case? It seems that \left\langle and \right\rangle should be in a single math. So, hard to break into multiple maths.
$<$ and $>$ would be an alternative, but I don't like it.
LaTeX does allow inline maths to break over lines by default, but there are a number of restrictions. Specifically, in your case, using \left...\right puts everything inside a non-breakable math group, so the first step is to replace them with either just plain \langle...\rangle or perhaps \bigl\langle...\bigr\rangle.
However, this still isn't enough to permit linebreaking; usually that's still only allowed after relations or operators, not punctuation such as the comma. (I think this is what's going on anyway; I haven't stopped to look this up.) So you want indicate where allowable line breaks may occur by writing \linebreak[1] after each comma.
Depending how often you have to do this, it may be preferable to write a command to wrap your "tuples" into a nice command. In order to write this in your source:
$ \mytuple{ source\_location, R/W, trip\_counter, occurrence,
killed\upshape (explained in the later) } $
here's a definition of \mytuple that takes all of the above into account:
\makeatletter
\newcommand\mytuple[1]{%
\#tempcnta=0
\bigl\langle
\#for\#ii:=#1\do{%
\#insertbreakingcomma
\textit{\#ii}
}%
\bigr\rangle
}
\def\#insertbreakingcomma{%
\ifnum \#tempcnta = 0 \else\,,\ \linebreak[1] \fi
\advance\#tempcnta\#ne
}
\makeatother
Why not define a new command:
\newcommand{\tuple}[5]{$\langle$\textit{#1}, \textit{#2}, \textit{#3}, \textit{#4},
\textit{#5} (explained in the latter)$\rangle$}
Then use \tuple{sourcelocation}{R/W}{tripcounter}{occurrence}{killed}
There seems to be a package that addresses that problem, called breqn. You can try this and let us know (I haven't used that).
I'd use the align* environment from AMSmath. Furthermore you could just add "\" to break the lines? Should work in math environments, too. Alternatively you could separate the equations.
Use \linebreak inside the math expression wherever you want a new line even between 2 brackets. This will enforce the line to be broken.

Resources