6/10/2013

ЛаТеХ для продвинутых. Floatrow - расположение иллюстрации и подписи

Одним из самых часто задаваемых вопросов о LaTeX является вопрос о вставке картинок. Рисунки чаще всего помещаются в так называемые плавающие объекты (floats). То, как ЛаТеХ размещает эти объекты, уже обсуждалось в одном из предыдущих постов из серии "ЛаТеХ для продвинутых". Теперь же стоит уделить внимание содержанию плавающего объекта: расположению картинок и подписей к ним внутри объекта float.

Одним из самых продвинутых средств в этой области является пакет floatrow. Он предоставляет удобный интерфейс для

  • изменения взаимного расположения подписи и рисунка или таблицы (подпись сверху, снизу, сбоку) без "ручного" перемещения команды \caption{};
  • выравнивания картинки/таблицы и подписи по горизонтали (влево, вправо, центрированно) и контроля полей;
  • расположения нескольких плавающих объектов в ряд и их взаимного выравнивания по вертикали;
  • дополнительных элементов оформления, таких как линий, рамок и теней, отделяющих объект от основного текста или картинку от подписи, и т.д., и т.п.

Целью данного поста является продемострировать возможности предоставляемые floatrow для контроля над расположением подписей к рисункам и таблицам.

Все примеры из поста могут быть найдены здесь и здесь в виде tex-файлов готовых к компиляции. Документация к пакету floatrow доступна на русском и английском языках.

Для нетерпеливых

После загрузки пакета

01:  \usepackage{floatrow}
настройка параметров плавающих объектов осуществляется командой
01:  \floatsetup[тип флоат]{параметр=значение,параметр=значение,...}
где тип флоат может быть, например, figure или table.

Наиболее интересные параметры, значение которых рассмотренно подробнее далее в тексте, приведены в таблице ниже

Параметр Значения, примеры Пояснения
capposition top, bottom, beside, TOP. Напр., capposition=top Положение подписи сверху, снизу, либо сбоку от картинки/таблицы.
capbesideposition {right/left/inside/outside, top/bottom/center}. Напр., capbesideposition= {right,bottom} Если подпись сбоку, её положение относительно картинки/таблицы.
capbesidewidth 10cm, 0.3\textwidth, sidefil. Напр., capbesidewidth= 0.5\textwidth Если подпись сбоку, её ширина
floatwidth 10cm, 0.3\textwidth. Напр., floatwidth= 0.5\textwidth Ширина, отводящаяся на весь флоат. Если подпись сбоку, ширина картинки.
margins raggedright, raggedleft, centering. Напр., margins= raggedright Положение ("выключка") всего плав. объекта по горизонтали на странице (см. рис.).
justification raggedright, raggedleft, centering. Напр., justification= raggedright Положение картинки внутри плав. объекта по горизонтали (см. рис.).

Подпись сверху, подпись снизу

Подпись к рисунку, схеме или таблице можно располагать сверху, снизу или сбоку от самого объекта. Традиционно, подписи к таблицам располагают над ними, тогда как рисунки подписывают снизу. Конечно, этого можно добиться переставляя команду \caption{} соответствующим образом вручную. Однако в мире ЛаТеХа действия "руками" являются моветоном, и поэтому floatrow полностью автоматизирует процесс с помощью команды \floatsetup{}. Например, вот такой код в преамбуле

01:  % загружаем пакеты
02:  \usepackage{floatrow}
03:  \usepackage{graphicx,wrapfigure}
04:  % настраиваем положение подписей
05:  \floatsetup[table]{capposition=top}
06:  \floatsetup[wrapfigure]{capposition=bottom}
07:  \floatsetup[figure]{capposition=beside,%
08:               capbesideposition={right,bottom},%
09:               capbesidewidth=0.3\textwidth,%
10:        capbesidesep=quad% разделитель между картинкой и подписью
11:  }
позволит автоматически перенести подписи ко всем таблицам наверх, все wrapfigure останутся подписанными снизу, а обычные figure плавающие объекты будут подписаны сбоку.
Уделим немного внимания команде \floatsetup[]{}. Она принимает два аргумента. Первый, необязательный, задаёт тип плавающего объекта. Если он не указан, то опции, следующие во втором (обязательном) аргументе будут применены ко всем типам floats в документе.

В данном случае мы использовали опцию capposition, которая может принимать значения top, bottom, TOP и beside. Первые два варианта приводят к очевидному эффекту. Параметр TOP имеет смысл только когда несколько объектов расположены в ряд и поэтому мы сейчас не будем останавливатся на нём в подробностях. Параметру beside стоит уделить чуть болeе внимания.

В комбинации с capbesideposition он позволяет разместить подпись слева capbesideposition={left,..} или справа capbesideposition={right,..} от рисунка. В случае двусторонней печати, можно использовать inside и outside: тогда подпись будет расположена, соответственно, на стороне "корочки" переплёта или на внешней стороне страницы. Помимо этого, capbesideposition контролирует и вертикальное положение подписи относительно рисунка. Надо лишь указать top, bottom или center. Например,

01:  \floatsetup[figure]{capposition=beside,%
02:       capbesideposition={right,bottom}%
03:  }
поместит подпись сбоку справа внизу.

Параметры capbesidewidth и capbesidesep контролируют ширину и отступ от рисунка. Ширину можно указывать в абсолютных величинах (например, 5cm), в долях от какой-либо длины (например, 0.3\textwidth), либо с помощью специального параметра sidefil, который выделит под подпись всю оставшуюся часть ширины страницы. Например,

01:  \floatsetup[figure]{capposition=beside,%
02:       floatwidth=0.6\textwidth,%
03:       capbesidewidth=sidefil% 
04:  }
выделит на картинку 60% страницы, а всё остальное отдаст под подпись. Заметьте, что здесь был использован ещё один параметр floatwidth. Обычно этот параметр задаёт ширину отводящуюся под весь флоат. Однако, если подпись находится сбоку, то floatwidth задаёт ширину отведённую под непосредственно саму картинку, вставленную, например, посредством \includegraphics{}.

Опции необязательно задавать глобально. Если использовать \thisfloatsetup{} вместо \floatsetup{}, то параметры будут применены только к одному плавающему объекту, который первым следует за этой командой.

Пропуски, поля и выравнивание

Всемогущая команда \floatsetup{} позволяет настроить расстояние между картинкой и подписью и в случае, если подпись находится сверху или снизу. Делается это с помощью ключа captionskip=<длина>.

01:  \floatsetup[figure]{capposition=bottom,%
02:              captionskip=5ex,%
03:       floatwidth=0.5\textwidth,%
04:       margins=raggedright% see page 43 of docs
05:  }
Кроме того, в примере задана ширина floatwidth всего float равной половине ширины текста и заказано разместить весь float слева: margins=raggedright (напомним, что по умолчанию и без floatrow, ЛаТеХ выравнивает плавающий объект по центру горизонтали).
Параметр margins принимает также значения centering (по умолчанию), raggedleft и др.

Если параметр margins регулирует, по сути, горизонтальное выравнивание всего float (картинка плюс подпись), то выравнивание по горизонтали картинки в пределах плавающего объекта контролируется с помощью justification. Обратите внимание, что если используется пакет floatrow, то не нужно явно задавать горизонтальное выравнивание картинки (\centering сразу после \begin{figure}) поскольку по умолчанию justification=centering. Другие значения, которые может принимать этот параметр, включают raggedright, raggedleft и justified. Первые два выравнивают картинку по левому и правому краю плавающего объекта, соответственно. justified для самой картинки просто означает, что она будет находиться слева. Однако, если внутри float есть текст (не относящийся к подписи!), то он будет набран, как параграф выравненный по всей ширине плавающего объекта. Например,

01:  \floatsetup[figure]{capposition=bottom,
02:               floatwidth=0.6\textwidth,
03:               margins=raggedright,
04:               justification=raggedleft
05:  }
приводит к такому результату

Все параметры схематически изображены на рисунке ниже.

Выравниваем подпись по ширине картинки

До настоящего момента мы в подробностях рассмотрели всевозможные варианты взаимного расположения и выравнивания картинки и подписи к ней. Один весьма специфический случай, однако, остался без внимания: как сделать так, чтобы весь флоат (то есть картинка и подпись) по ширине совпадали с шириной картинки. При этом хотелось бы, чтобы ширина определялась автоматически, а не вручную посредством floatwidth=ширина.

Сделать это можно с помощью команды \ffigbox{}{} для figure или \ttabbox{}{} для table. Здесь мы не будем обсуждать все возможности этой мощной команды, а приведём конкретный пример

01:  \begin{figure}
02:   \ffigbox[\FBwidth]{\caption{...}\label{...}}%
03:                      { \includegraphics{...} }
04:  \end{figure}
Трюк здесь состоит в том, что первый, необязательный, аргумент команды задаёт ширину плавающего объекта, а значит и подписи. Пакет floatrow определяет длину \FBwidth, которая равна ширине текущего объекта.

Для таблиц, просто заменяем \ffigbox на \ttabbox. Во всей своей мощи и красе \ffigbox и \FBwidth предстают при расположении плавающих объектов в ряд. Но об этом в следующий раз.

Стили

Пакет позволяет создавать стили, которые могут впоследствие быть использованы как

01:  \floatsetup[тип флоат]{style=стиль}
Мы не будем здесь рассматривать создание собственных стилей , а лишь заметим, что floatrow предоставляет набор стилей, некоторые из которых вполне могут буть использованы в реальных документах.

plain plaintop
boxed BOXED
ruled Полный список предопределённых стилей можно найти в документации на странице 31.

Стили можно комбинировать с другими командами, например

01:  \floatsetup[тип флоат]%
02:   {style=ruled,floatwidth=0.6\textwidth,...}

Заключение

Итак, пакет floatrow позволяет легко и непринуждённо управлять расположением различных частей плавающего объекта: например, картинки (таблицы) и подписи.

Осуществляется это посредством команд \floatsetup (для глобальных установок или установок в пределах блока) и \thisfloatsetup (только для первого следующего объекта):

01:  \floatsetup[тип флоат]{параметр=значение,...}
где тип флоат может быть, например, figure, table, wrapfigure, и т.п. Список наиболее интересных параметров можно найти в таблице приведённой выше.

Основным достоинством floatrow по сравнению с "ручными" способами, вроде использования minipages, является гибкий интерфейс, позволяющий одной командой \floatsetup настроить параметры всех плавающих объектов в документе.

Во всей своей красе floatrow проявляет себя при расположении плавающих объектов в ряд. Но об этом в следующий раз.

Все примеры из данного поста могут быть найдены здесь и здесь в виде tex-файлов готовых к компиляции.

Документация к пакету floatrow доступна на русском и английском языках.

4 комментария:

  1. Хм, неплохо. Надо будет принять на вооружение.

    ОтветитьУдалить
  2. Создается впечатление, что floatrow влияет только на взаимодействие рисунка и подписи, разве он не может намного большее? Хотелось бы узнать и о расположении нескольких картинок внутри одного рисунка. Я использовал subfig, но в этом блоге он не в почете.

    Однако в мире ЛаТеХа действия "руками" не являются моветоном
    «Не» не лишнее, случайно?

    ОтветитьУдалить
  3. @Sergy Kanaev комментирует...
    Надо будет принять на вооружение.
    Оно того стоит. Amorua, надо сказать, проделал отличную работу в этой серии постов - документация по floatrow выглядит пугающе, и я в своё время её не осилил. Пользуюсь \subfigure, пока хватает.

    Так что в этом посте я снова читатель, а не писатель.

    @iv_vl комментирует...
    Создается впечатление, что floatrow влияет только на взаимодействие рисунка и подписи, разве он не может намного большее?
    Насколько я понимаю, оно в самом деле может больше. Проблема только в том, что разобраться в этом обилии параметров довольно непросто. Это типа кофемашины с 20000 кнопок и ручек - а мне и нескафе голд сойдёт :-)

    Я использовал subfig, но в этом блоге он не в почете.
    Пошто напраслину возводишь, iv_vl? Subfig в почёте, вот я им только сегодня пользовался. Просто мало про него пишу.

    У меня сейчас довольно турбулентное время с устройством на новую работу и подачей на грант, так что не до блога.

    Но написанных постов хватит до октября, а там посмотрим.

    ОтветитьУдалить
  4. @ iv_vl комментирует...
    Создается впечатление, что floatrow влияет только на взаимодействие рисунка и подписи, разве он не может намного большее?
    Абсолютно верно. Просто в один пост всё не влазило. Об этом во второй части... (такая ненавязчивая реклама :)

    «Не» не лишнее, случайно?
    Лишнее, поправил.

    ОтветитьУдалить