Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In Automatic scaling of tikz images in floatrow I was asking how to scale several images in one row to the same height and to scale the resulting row to linewidth.

I would like to automate the process further and was wondering if it is possible to define an environment as follows (the desired behaviour will be explained below):

\begin{scaleRow}[\linewidth]
  \somecode{\scaledImage{image1code}}
  \othercode
  \somecode{\scaledImage{image2code}}
  ...
  \othercode\maybeDifferent
  \somecode{\scaledImage{image<N>code}}
\end{scaleRow}

The environment should collect all the code inside \scaledImage, so I can use the method given in the answer to the referenced question automatically to calculate the scaleratios for each image.

After running this calculations, I would like to replace \scaledImage{code} with code and every occurence of \scalefactor inside code with the scalefactor I calculated and actually render the code in the environment.

The reason why I want to render the image twice is that I aim to use tikzscale, otherwise I could replace code by the savebox I will need to calculate the width.

Note: I would like to at least try some of the required coding myself to get started with latex coding, however I am a complete novice, while I am sure that most of this is feasible, I am not sure about the extraction of the scaledImage part from the enviornment. I would appreciate a good pointer on that so I can try what I can put together from that point.

What makes the matter slightly more difficult is that I am afraid of side effects. So I think just executing all code twice (once hidden e.g. by putting it in an sbox or somehow throwing its output away) is dangerous, if for instance a counter is modified.

share|improve this question
add comment

1 Answer

Your specifications are somewhat vague, so I may have taken some liberties in interpreting what you wanted to do.

For those who are not familiar with your earlier question, I should point out here that you requested and I introduced the concept of a "row-figure" which is constructed of various sized subfigures, all of which are to be scaled (with aspect ratio preserved) in such a way as to occupy an overall width specified by the user (default \textwidth).

I have introduced the following commands that work inside an environment:

\rowfigurewidth{specified width of row-figure} - which defaults to \textwidth

\startrowfigure[starting subfig number]{left-most image to store in the new row-figure}

\addrowfigure{figure to store at current right-end of row-figure}

\presentrowfigure - regurgitates the currently constructed row figure

\showrowfigure{}{}{}{} - the macro that formats each subfigure component of the row-figure (not called by user, but determines format of presented row-figure)

rowfigcount is the counter that contains the current value of subfigs employed, if one wishes continue on a subsequent line (via \therowfigcount as optional argument to \startrowfigure.

Sample usage would be:

\begin{figure}[ht]
\startrowfigure{\figa}
\addrowfigure{\figb}
\addrowfigure{\figc}
\addrowfigure{\figd}
\presentrowfigure
\end{figure}

And the whole code is given below:

\documentclass{article}
\usepackage{scalerel}
\usepackage{fp}
\usepackage{stackengine}
\def\stacktype{L}
\usepackage{xcolor}
\newcount\figwidthc
\newcount\textwidthc
\newcounter{rowfigcount}
\newcounter{rowfigindex}
\newsavebox\compositefig
\newlength\rowfigwidth
\def\rowfigwidthstring{\textwidth}
\newcommand\rowfigurewidth[1]{\edef\rowfigwidthstring{#1}}
\newcommand\startrowfigure[2][0]{%
  \sbox\compositefig{#2}%
  \edef\rowfigstart{#1}%
  \setcounter{rowfigcount}{#1}%
  \addtocounter{rowfigcount}{1}%
  \expandafter\def\csname rowfig\roman{rowfigcount}\endcsname{#2}%
}
\newcommand\addrowfigure[1]{%
  \sbox\compositefig{\scalerel{\usebox{\compositefig}}{$#1$}}%
  \addtocounter{rowfigcount}{1}%
  \expandafter\def\csname rowfig\roman{rowfigcount}\endcsname{#1}%
}
\newcommand\presentrowfigure{%
  \figwidthc=\wd\compositefig%
  \setlength{\rowfigwidth}{\rowfigwidthstring}%
  \textwidthc=\rowfigwidth%
  \FPdiv\scaleratio{\the\textwidthc}{\the\figwidthc}%
  \setcounter{rowfigindex}{\rowfigstart}%
  \whiledo{\value{rowfigindex} < \value{rowfigcount}}{%
    \stepcounter{rowfigindex}%
    \showrowfigure%
      {\scaleratio}%
      {\alph{rowfigindex}}%
      {\csname rowfig\roman{rowfigindex}\endcsname}%
      {\csname rowfig\roman{rowfigcount}\endcsname}%
  }
}
\newcommand\showrowfigure[4]{%
  \stackunder{\scalebox{#1}{\scalerel*{$#3$}{$#4$}}}{(#2)}%
}
\begin{document}
\def\figa{\color{blue}\rule{.5in}{.7in}}
\def\figb{\color{red}\rule{.7in}{.3in}}
\def\figc{\color{green}\rule{.4in}{.5in}}
\def\figd{\color{black}\rule{1.in}{.8in}}

\def\fige{\color{red}\rule{1.5in}{.7in}}
\def\figf{\color{cyan}\rule{1.7in}{1.3in}}
\def\figg{\color{magenta}\rule{1.4in}{1.5in}}
\def\figh{\color{black}\rule{1.in}{.8in}}

Here I demonstrate row figures:

\begin{figure}[ht]
\startrowfigure{\figa}
\addrowfigure{\figb}
\addrowfigure{\figc}
\addrowfigure{\figd}
\presentrowfigure
\\
\vspace{1em}\\
\rowfigurewidth{.8\textwidth}
\startrowfigure[\therowfigcount]{\fige}
\addrowfigure{\figf}
\addrowfigure{\figg}
\addrowfigure{\figh}
\presentrowfigure
\caption{These are my row figures}
\end{figure}

which came from these raw images:

\begin{figure}[ht]
\figa\figb\figc\figd
\\
\vspace{1em}\\
\fige\figf\figg\figh
\caption{These are the unaltered images}
\end{figure}
\end{document} 

enter image description here

Obviously, if you wanted to do something more than just put a (subfig number) below the individual images, you would have to pass it to \startrowfig and \addrowfig, store it, and recall it via an entry in \showrowfigure

share|improve this answer
    
+1 for a nice almost solution. The idea of the question was that I could use floatrow to place the images (thus maintaining its labeling and captioning capabilities as well as its framing) and be able to actually use tikzscale to scale the images. Apparently there is no (easy) way to do so. If I adopt your solution I first have to start/addrowigure and then (width some modifications) I could create my floatrow code and insert e.g. tikzscale{scale=\rowFigScale}{figure}. (I would combine the two scalefactors, so I can apply them in one scale avoiding the quality loss from double scaling) –  ted Jul 31 '13 at 15:52
    
I was hoping I could prevent this and write code that can be inserted in the right spaces from the beginning (directly in the floatrow code.) –  ted Jul 31 '13 at 15:53
    
@ted. Got it. I'll give it some more thought, though I'd have to learn how floatrow works. In the meantime, perhaps the contents of \showrowfigure could somehow be passed to floatrow in some fashion, once the \startrowfigure and \addrowfigure are accomplished. –  Steven B. Segletes Jul 31 '13 at 15:59
    
I would like to chat about this with you, but I am not aware how the chat feature works... –  ted Jul 31 '13 at 16:03
1  
I was about to add a floatrow example but I think it does not quite belong in the question, therefor take a look at the mwe in this question. Also I am trying to write a package now, no doubt you will get credit what so ever, the question is if you would like to collaborate on it, if so we have to find a place where I can show you what I have come up width based on your awnser and my other quesitons. –  ted Aug 1 '13 at 16:47
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.