GeneralIncrement (or decrement) a parameter in LaTeX

LaTeX specific issues not fitting into one of the other forums of this category.
Post Reply
robbins
Posts: 2
Joined: Mon Nov 16, 2009 6:49 pm

Increment (or decrement) a parameter in LaTeX

Post by robbins »

How can I increment or decrement a parameter in LaTeX?

For example, suppose I create an environment foo as follows:

\newenvironment{foo}[2]{\begin{tabular}{*{#1}c*{#2}r}}{\end{tabular}}

I can write

\begin{foo}{4}{3}
<tabular data in seven columns>
\end{foo}

But in my application, if the first parameter is n, then second is always n - 1. Is there a way to write this so that I need to pass only one parameter (in this case n), but which will produce the table with n + (n - 1) columns as in the environment foo?

Decrementing the parameter #1 inside the newenvironment -- if it is possible -- would surely work, but I don't know how to do it.

Note: The snippet
\let\temp#1
\advance\temp by -1
doesn't work because if I pass the parameter 4, \temp takes the value 'the character 4', which can't follow the \advance command.

I'm stuck. Any help?

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

josephwright
Site Moderator
Posts: 814
Joined: Tue Jul 01, 2008 2:19 pm

Increment (or decrement) a parameter in LaTeX

Post by josephwright »

You don't want \let, you want to do things with numbers proper. The thing is that they then to be assigned to TeX counters. You seem to want something like

Code: Select all

\newcount\mycount
\newenvironment{foo}[1]
  {%
    \mycount #1\relax
    \advance\mycount -1\relax
    \begin{tabular}{*{#1}c*{\the\mycount}r}%
  }
  {\end{tabular}}
Here, I'm using a TeX count register to do the maths. You can do the same with a LaTeX counter, but I find this route a bit easier for going downward. TeX assigns count registers locally, so the above should work in most cases.
Joseph Wright
robbins
Posts: 2
Joined: Mon Nov 16, 2009 6:49 pm

Re: Increment (or decrement) a parameter in LaTeX

Post by robbins »

Joseph Wright:

It works like a champ. Thanks!
Julian_S_Moore
Posts: 72
Joined: Sun Nov 16, 2008 1:26 pm

Re: Increment (or decrement) a parameter in LaTeX

Post by Julian_S_Moore »

Joseph Wright -

Could you also explain how to multiply values by real numbers?

I want to produce a sequence of characters decreasing in size proportionately, each say 0.8 of the size before. How can I get the current fontsize and scale it by a constant (not necessarily a parameter passed) to pass back to \fontspec?

e.g. (pseudo-code)
\fontspec{0.8*currentfontsize}{\baselineskip}
josephwright
Site Moderator
Posts: 814
Joined: Tue Jul 01, 2008 2:19 pm

Increment (or decrement) a parameter in LaTeX

Post by josephwright »

Real values are a pain in TeX. You can look at something like pgfmath or fp for this, but as a quick hack (if you don't need too much accuracy):

Code: Select all

\documentclass{article}
\newlength\mydimena
\newlength\mydimenb
\makeatletter
\newcommand*\Multiply[2]{%
  \mydimena \dimexpr #1 pt * 10 \relax
  \mydimenb \dimexpr #2 pt * 10 \relax
  \edef\temp{\strip@pt\mydimenb}%
  \edef\temp{\expandafter\Multiply@\temp.\@nil}%
  \mydimena \dimexpr \mydimena * \temp \relax
  \mydimena \dimexpr \mydimena / 100 \relax
  \edef\temp{\strip@pt\mydimena}\temp
}
\def\Multiply@#1.#2\@nil{#1}
\makeatother

\begin{document}

\Multiply{1.1}{0.35}
\Multiply{4.5}{4.5}

\end{document}
This uses the fact that dimensions can have a (limited number of) decimal places, and uses e-TeX's \dimexpr primitive. It could all be done in one rather complex \dimexpr, but I can't be bothered to debug it all!
Joseph Wright
Julian_S_Moore
Posts: 72
Joined: Sun Nov 16, 2008 1:26 pm

Re: Increment (or decrement) a parameter in LaTeX

Post by Julian_S_Moore »

You're not kidding! That's... absurd :o (slack jawed gawp of the ignorant)

Unfortunately running the example produced "*** (job aborted, no legal \end found)"... aha... That's because I was running XeLaTeX->PDF; works fine with LaTeX->PDF.

All I want to do is use the current font size call it "S" as follows

\fontsize(0.8S)

but \f@size (if there's no other way to get it) produces a number that I could never combine with "pt" without causing an error... hmmm... does this imply that I need to create a new length (\mydimA) and put \f@size into it with a \mydimA = \dimexpr \f@size * myconst pt \relax [what's the \relax for?]

and then use \fontsize{\mydimA}{\baselineskip} ? (Or, since myconst is real do I just give up?)

I see lots of places where one has as a paremeter e.g. {2\textwidth}... and I've done "1.5\headskip" myself in the current project... is there really no way to do a simply real multiply of the font size? He asked rhetorically, not knowing whether to expect a Yes or a No.

Since I am using XeLaTeX is there anything else I should be doing?
User avatar
gmedina
Posts: 2313
Joined: Wed Jul 11, 2007 11:45 pm

Increment (or decrement) a parameter in LaTeX

Post by gmedina »

Hi Julian_S_Moore,
Julian_S_Moore wrote:...I want to produce a sequence of characters decreasing in size proportionately, each say 0.8 of the size before...
There's an example in the TeX showcase page that could be useful for you. Follow the link I provided and search for diminuendo.tex.
1,1,2,3,5,8,13,21,34,55,89,144,233,...
Julian_S_Moore
Posts: 72
Joined: Sun Nov 16, 2008 1:26 pm

Re: Increment (or decrement) a parameter in LaTeX

Post by Julian_S_Moore »

Thanks gnedina... that's almost exactly what I want (apart from the macro knowing the font size in effect...)

I converted it to LaTeX OK but am having trouble customising it...

I'll post again with specifics and code later.

But one bservation on diminuendo for the benefit of others... the example decimals exhaust the diminuendo: add more digits and the font size reverts to the default.
Julian_S_Moore
Posts: 72
Joined: Sun Nov 16, 2008 1:26 pm

Increment (or decrement) a parameter in LaTeX

Post by Julian_S_Moore »

OK, here's an example that produces increasing and decreasing text. Thank you gnedina, that link was both helpful and educational.

Outstanding issues, which I'd be very grateful for help with

1. Instead of \fontpt=10pt, how does one get the nominal default font size (which the Memoir options I have used declare as 10pt).
2. I don't understand the coding structure (the use of the \let, the \next, etc. etc. ... Googling such things has proven pointless as Google insists in treating e.g. "\" as a space. Any tips on using Google for finding code?), so haven't been able to work out how to make the 1st character of the string appear at the nominal size and then increase/decrease thereafter.
3. The current code progresses from the current font size... suppose I wanted to progress to the current font size in steps dynamically calculated as the appropriate nth root of the parameter string length.

Thanks.

Code: Select all

% Crescendo and Diminuendo strings by analogy of Diminuendo by Peter Hammond at http://www.tug.org/texshowcase/
% Converted from Plain Tex to LaTeX
% This example uses Memoir and XeTeX to use a non-LaTeX font directly from the system

\documentclass[final,twoside,openright,showtrims,10pt]{memoir} %
\usepackage{xltxtra,fontspec,xunicode}
\setmainfont{Bookman Old Style}
\setlxvchars[\normalfont] % main font, involved in optimal character to line fitting

\newdimen\fontpt \fontpt=10pt
\def\newfont{ \font\nextfont = "Bookman Old Style" at \fontpt \relax \nextfont}
% Notes for beginners like me...
% 1. I tried to reformat the code for readability and found that extra spaces in "\ifx#1\end" e.g. "\ifx#1 \end" 
% will cause errors, presumably because the space changes the name being searched for.
% 2. \magnification in the original code doesn't work in LaTeX and isn't (apparently) required.
% 3. \magstephalf is sqrt{1.2} = 1.095 (which, given the nominal magnification is 1000 is used internally as 1095)
% since the magstep is from one nominal font size to the next, e.g. 10->12, so applying \magstephalf twice produces 
% a single "magnification"
% 4. The examples provided with the original code are the maximal diminuendo examples (for the given starting font
% size) - any more digits would be 0.0pt (and the font size then resets to default)

\newcommand\diminuendo[1]{\kern-0.8em\fontpt=10pt \newfont \dimin#1 \normalfont \end}
\newcommand\crescendo[1]{\kern-0.8em\fontpt=10pt \newfont \cresc#1 \normalfont \end} 

\def\dimin#1{\ifx#1\end \let\next=\relax
	\else\divide\fontpt by \magstephalf \multiply\fontpt by 1000 
		\newfont\negthinspace#1\negthinspace \let\next=\dimin\fi \next}
		
\def\cresc#1{\ifx#1\end \let\next=\relax
	\else\divide\fontpt by 1000 \multiply\fontpt by \magstephalf 
		\newfont\negthinspace#1\negthinspace \let\next=\cresc\fi \next}

\begin{document}
Diminishing Capital S's~ s| \diminuendo{SSSSS} \par
Diminishing Lower Case s's~ s| \diminuendo{sssss} \par
Increasing Capital S's~ S| \crescendo{SSSSS} \par
Increasing Lower Case~ s's s| \crescendo{sssss} \par
\end{document}
Post Reply