Показаны сообщения с ярлыком ЛаТеХ. Показать все сообщения
Показаны сообщения с ярлыком ЛаТеХ. Показать все сообщения

Свистульки, бубенчики и рюшечки в документах LaTeX



13 коммент.
Как все уже хорошо знают, в ЛаТеХ добиться хорошего качества документов по умолчанию очень просто: используя десяток стандартных команд, вы получите неизменно превосходный результат (ТМ) без лишних усилий. То есть документ будет хорош, но ведь иногда хочется украшательств, мигалок, свистулек и бубенчиков. На эту тему автор уже собрал небольшую коллекцию, которой и рад поделиться. Кроме того, автор открыл для себя удивительные книги Edward Tufte, который знает толк в визуальной подаче информации.


Читать далее

Как написать статью в LaTeX



17 коммент.
Результатом любого приличного исследования являются публикации. Вы делаете что-то новое, и это по идее должно немного (или значительно) двинуть научное знание вперёд. А так как научные тексты удобнее писать в LaTeX, специально для этого созданным не абы кем, а Дональдом Кнутом, то возникает непраздный вопрос: как же написать статью в LaTeX?!

Вернее, вопросов два: как написать научную статью и как это сделать в ЛаТеХе?


Как написать научную статью
В Сети есть много хороших и правильных постов о том, как следовало бы писать статьи. Там вам скажут, что сначала придумывается заглавие, потом аннотация (abstract), потом красивое введение, потом, собственно, результаты исследований и, как апофеоз экзистенциального катарсиса, заключение.

В жизни всё несколько иначе. Обычно стоит большая задача, которую нужно решить. Мы сидим, чещем затылок и листаем журналы в поисках намёков на решение. Пробуем то и это, и чаще всего либо оно не работает вообще, либо работает, но не так, как надо. Потом иногда приходит какая-нибудь хорошая и свежая мысль, и внутренний голос говорит "О! Это интересно", а внешний - "Ахххаааа!".

После прихода этого самого "Аха!" вместе с хорошей идеей автор начинает что-то быстро писать на бумаге, прикидывать, покрякивать и энергично потирать ручонки. Далее, в состоянии полного угара творчества что-то ваяется, вычисляется, математически выводится, разливается по колбам, экспериментируется, программируется и численно симулируется. Это самое счастливое время, когда забываешь обо всём на свете и делаешь что-то занятное - за это, собственно, научным сотрудникам и платят деньги.

Через некоторое время угар творчества проходит и автор видит наброски, куски кода, булькающие колбы, вереницы данных, таблицы и графики. Работа принимает более организованный характер: нужно сравнить с имеющимися методами, провести дополнительные эксперименты или расчёты. Если это что-то, чего ещё никто не делал - самое время приступать к написанию статьи.

Основная часть таким образом у автора в том или ином виде уже есть, так что статья начинается с середины, а именно - с полученных данных. Всё, что написано про оформление диплома или курсового проекта в LaTeX, полностью справедливо и здесь.

В основной части считается хорошим тоном привести математическую формулировку или модель, которая соответствует процессам. Сравнение численной модели с реальным экспериментом тоже добавляет веса и доверию статье. Также стоит упомянуть, на каком компьютере проводились симуляции (особенно если вы предлагаете новый алгоритм и сравниваете с предыдущими), какое оборудование использовали и что булькало в пробирках.


Заглавие обычно выбирается из пары десятков нагенерированных коллегами и автором вариантов. Как правило, заглавие статьи должно содержать некие ключевые слова, которые описывают содержимое статьи. Это важно, так как позволяет быстрее и проще вашу статью потом найти другим людям в поисковых системах.


После этого пишется обычно одна из самых занудных частей статьи - Заключение. Дело это непростое и обычно приходит с опытом и набитием шишек. Так как люди обычно читают аннотацию (abstract), введение и заключение к статье, то они должны быть отполированы до зеркального блеска.

Обычно заключение отвечает на три вопроса:
  1. Что за проблема решалась в статье?
  2. Какие результаты были получены в статье?
  3. Ну и что!?
Для ответа на эти вопросы, в особенности на последний, хорошо поиграть в игру "Ну и что?!". То есть представьте, что вы беседуете с редактором журнала, и он вас спрашивает: "ну и что в статье интересного-то?" или "почему я должен обратить на это внимание?".


Введение это вторая по трудности часть после заключения. Введение обычно даёт формулировку целей исследования и достаточный обзор существующей литературы. Но это легко сказать, а что писать-то? Ну, например, автор этих строк пользуется следующей болванкой:
  1. Почему это исследование вообще проводилось?
  2. Какая литература уже существует по этому вопросу? Здесь можно провести обзор и показать ту брешь, которую вы хотите заткнуть своей статьёй.
  3. Какова конкретная цель исследований? Это теоретическое обоснование чего-то, или экспериментальная работа, или численные симуляции.
  4. В чём новизна работы?
После написания введения и заключения можно писать аннотацию (abstract).


Аннотация (abstract) это короткое описание цели работы, результатов и что в работе сообщается. В целом, аннотация пишется обычно из надёрганных предложений из Введения и Заключения. Обычно аннотации короткие и должны быть не длиннее, скажем, 250 слов (у журналов и конференций по этому поводу свои правила).






Как написать научную статью в LaTeX
Эпиграф:
LaTeX is capable of most things 
but not always in the most obvious manner.

Собственно, как уже говорилось выше, почти всё, что нужно для этого, есть в постах о написании диплома в LaTeX:
Есть одно НО: у каждого журнала или конференции есть свой собственный, не имеющий аналогов в мире, стилевой файл  LaTeX разной степени корявости и тухлости. Как правило, там содержится рабочий пример статьи, так что лучше попробовать сначала собрать пример.

Но если вы думаете, что отправленную вами в журнал статью примут "с колёс" и без редакции, то вы либо крутой нобелевский лауреат, либо большой оптимист. И поэтому скорее всего вам предстоит общение с рецензентами и редактором журнала. Вот тут-то LaTeX нам и сослужит добрую службу....


Рецензии и правки научных статей в LaTeX
Ещё до того, как вы отправите статью, лучше всего использовать одноколоночный набор и включить нумерацию строк, чтобы рецензенты ссылались не просто на страницу, а сразу на конкретную строку.


Нумерация строк в LaTeX
Нумерация строк включается пакетом lineno, который можно скачать здесь. В преамбуле документа добавляем
\usepackage[mathlines]{lineno}% Enable numbering 
Отлично, теперь вставляем команду:
\linenumbers\par %%% <---- turn on the numeration of lines
там, где мы хотим начать нумерацию линий. Если нужно оборвать нумерацию в конце статьи перед, скажем, списком литературы, команда выглядит так:
\nolinenumbers %%% do not use line numbers any more.
Важно то, что пакет lineno позволяет не только автоматически проставлять номера строк, но ещё и ссылаться на них. Автор настоятельно рекомендует использовать эту возможность, чтобы не сойти с ума самому при правках и не злить рецензентов.

Для этого в том месте, которое вы обещаете рецензенту поправить (и делаете это), ставим ссылку:
\linelabel{review:1R1}
Как и везде в ЛаТеХе, ссылки стоит ставить разумные: например, здесь написано, что это ответ на замечание 1 от рецензента 1 (они обычно анонимные).

Далее в тексте ответа на замечания рецензентов пишем что-то типа:
We clarified this on page~\pageref{review:1R1} line~\ref{review:1R1}.

Наступает счастье: здесь мы приводим не только ссылку на строку (\ref{review:1R1}) но и сразу на страницу (\pageref{review:1R1}).

Вместо конструкции $$ ..... $$  следует использовать \[ ... \] или \begin{displaymath} ....\end{displaymath}, тогда пакет lineno правильно проставит номера строк в тексте с математическими формулами.

Больше о нумерации строк вам расскажет весьма толковая документация к пакету lineno.


Ссылка на сноски в LaTeX
Допустим, вы сказали, что угоняете часть тектса в сноску. Об этом лучше написать рецензенту прямо, чтобы он не искал кусок пропавшего текста по всему документу.

Для этого пишем в преамбуле документа:
\newcommand{\footnoteremember}[2]{\footnote{#2} \newcounter{#1} \setcounter{#1}{\value{footnote}}} \newcommand{\footnoterecall}[1]{\footnotemark[\value{#1}]}
Теперь в тексте можно написать:

The Finite Element Analysis was perfomed on a crappy computer\footnoteremember{footnotelatitude}{Simulations were run on the Dell Latitude E5400 notebook with Intel Celeron 2.2 GHz processor, 2GB DDR2 SDRAM, 120 GB SATA HDD 5400 rpm under Debian GNU/Linux v 5.0 with MATLAB v2007b for UNIX.}.

Так что у нас есть ссылка footnotelatitude которая ведёт на сноску. Теперь сослаться на неё можно так:
(see footnote\footnoterecall{footnotelatitude})
И вы теперь сможете видеть номер сноски, на которую вы ссылаетесь. Трюк позаимствован отсюда.


Перевод PDF в простой текст
Сгенерированные ЛаТеХом документы часто переводятся в PDF, но иногда требуется перевести всё в простой текст. Часто это следует делать с сохранением структуры, и тут нам поможет pdftotext:
pdftotext -layout  -nopgbrk   reviewnotes_12-0238_MS.pdf
где ключи означают:
 -layout           : maintain original physical layout
 -nopgbrk          : don't insert page breaks between pages
Если нужно перевести в текст только со страницы 5 по страницу 10, даём команду:
pdftotext  -f 5 -l 10 reviewnotes_12-0238_MS.pdf
После этого текст можно вставлять в веб-форму для ответа рецензентам.




Ссылка название раздела или главы в LaTeX
Тоже часто используется, особенно если вы при правках радикально меняете структуру статьи (скажем, рецензенты вам это настоятельно советуют). Делается ссылка на название раздела с помощью пакета nameref и который входит в пакет hyperref - он входит в стандартный набор TexLive и потому уже должен быть установлен.

Включаем пакет в преамбуле:
\usepackage{nameref}

Ставим метку для раздела (section):

\section{Introduction}\label{intro}
И ссылемся в тексте:
See more details in the \nameref{intro} section that has number \ref{intro}.
Вместо этого мы при компиляции увидим:
See more details in the Introduction section that has number 1.
Этот удобный и простой трюк подсмотрен тут.


Вместо заключения
Собственно, этот пост - небольшая зарубка на память и собрание нескольких рецептов из моего уже порядком разросшегося черновика. Полностью приведённый пример можно посмотреть на моей странице в Google Code.

Читать далее

Как сделать календарь в LaTeX на год и месяц автоматически?



7 коммент.
Это краткая заметка в стиле "как отстрелить себе ногу с помощью LaTeX". Автору этих строк потребовалось сделать себе календарик, в котором отображались бы оповещения о событиях, и чтобы это дело регенерировалось автоматически при смене месяца.

Предисловие

Автор этих строк - человек очень ленивый, но любопытный и обожающий ковырять свой Дебиан на предмет того, как бы сбросить побольше рутины на компьютер. Так появилась LaTeX-реализация организационной системы Getting Things Done, которая выполнена полностью на латехе, вместе с адресной книгой и календарём.

Календарь на LaTeX реализован с помощью пакета расширений calendar [скачать ZIP-файл]. Проблема в том, что месяцы в календаре нужно обновлять самому, а вот это как раз и забывается чаще всего. Поэтому хочется, чтобы дни, месяцы и годы в календарике LaTeX обновлялись автомагически латехом и без вмешательства ленивого и забывчивого автора этих строк.
Нужно сказать, что LaTeX является Turing complete language, то есть на нем можно писать любые программы. Например, можно написать интерпретатор Бейсика, симулятор машины Тьюринга, Mandelbrot with LaTeX и другие программы. То есть на латехе можно писать что угодно. Не всегда это просто (особенно в случае с календарём), но можно.
Пост поделён на две части: сначала немного о возможностях пакета Calendar, а потом про то, как обновление названий месяцев сделать автоматически из LaTeX.

Возможности пакета Calendar в LaTeX

О возможностях пакета Calendar уже говорилось, но тем не менее. Последнюю версию пакета расширений calendar, который можно загрузить отсюда. Файлы примеров этого поста доступны здесь, батарейки в комплекте (пакет calendar там уже есть).

После распаковки всех файлов в преамбуле документа подключаем пакеты:
%%% Turning on the Monthly calendar and Event list
\usepackage{monthly,evntlist,lscape} \parindent=0pt
для календаря на месяц и списка событий, и:
%%% Turning on the Yearly calendar
\usepackage{yearly}
для календаря на год соответсвенно.

Создание событий для календаря

Пакет calendar не просто создаёт календарь, но и позволяет отображать в нём события. Все события хранятся в одном текстовом файле myEvents.cld из которого они дёргаются календарём. Файл событий выглядит так:
%%%%%%% My Personal Calendar
range Essentials/Calendar/year2010 %% What year do we want?
%% ONE-TIME EVENTS
january 28 2010 {Описать GTD} [Описать GTD для блога]
%%%%% RECURRING EVENTS
every Sunday {Еженед. обзор} [Еженед. обзор]
Сначала указываем год в отдельном файле Essentials/Calenda/year2010.cld в котором пишем:
%% Span the whole year here
January 1 2010 to December 31 2010 {The year 2010}
Повторяющиеся события будут определены только в интервале из этого файла.

Список событий из календаря

Часто нужно просто видеть события, приуроченные к календарным датам (особенно если их не так много). Для этого мы пользуемся окружением eventlist, которое предоставляет пакет calendar. Настройки того, как выглядит список событий, хранятся в файле evntlist.sty который можно приукрасить разными значками и иконками.

Чтобы распечатать события между нужными датами, вы просто ставите две даты, между которыми хотите показывать события (хранятся в файле events.cld):
\begin{eventlist} {} {Essentials/Calendar/myEvents}
january 24 2010 to january 30 2010
\end{eventlist}
и собираете LaTeXом документ, получая список календарных событий на это время:



Иконки сделаны пакетами шрифтов marvosym и wasysym.

Календарь на месяц с отображением событий

Пакет calendar может больше - можно создать календарь на месяц и показывать там события. Код такой:
\begin{monthly}
{firstday=1} %% begins with Monday
{Essentials/Calendar/myEvents}
jan 2010
\end{monthly}
Все события в календаре на указанный месяц (январь 2010 в данном случае) берутся из того же файла events.cld, который мы использовали для генерации списка календарных дней на неделю.
Компилируем документ и вот он, календарь на месяц, обновлённый и со вставленными событиями:


Календарь работает с кириллицей, во всяком случае кодировка KOI8-R у него возражений не вызывает.

Календарь на год

Места для отображения событий в календаре на год особенно не много, но возможность сгенерировать годовой календарь, не отходя от кассы выходя из латеха весьма кстати. Код для этого:
\begin{yearly}
 {title= \begin{center} \textbf{\Large The Year 2013}\end{center} \normalsize,firstday=1}
{}
2013
\end{yearly}
После сборки документа годовой календарик будет выглядеть так:



Можно посылать в печать.

Вызов скриптов из LaTeX

С календарём всё сравнительно понятно, и теперь настало время его автоматизировать: хочется, чтобы названия месяцев и дней подставлялись автоматически. Это не такая простая задача, как может показаться. Дело в том, что стандартные команды типа \the\year с пакетом calendar работать не будут, как не получится и подставлять значения из файлов через команду \input.

Поэтому мы пойдём другим путём, как завещал нам Ильич, и напишем скрипт на питоне, генерирующий полный текст латеховского файла с использованием безграничных возможностей команды date. Собственно, идея в том, чтобы написать простенький скрипт на Питоне и вызывать его каждый раз латехом для обновления файлов календаря.

Скрипт на Питоне для генерации файлов календаря

Скрипт просто склеивает строки для латеха, дёргая команду date и вставляя даты куда нужно. В примере ниже показана часть генерации файла календаря на месяц.

Весь латеховский файл представляет собой склеенные строки в переменной out. Вставка символа r в строках out +=r'\begin{landscape}'+'\n' указывает Питону не интерпретировать \b а печатать как есть. Вызов команды date делается через os.popen(cmd), хотя теперь так уже не модно (но тем не менее работает), а модно через subprocess.check_output (но у меня так не получилось).

От полученной строки из команды date отдельно откусывается символ новой строки через .rstrip('\n') и далее сшивается с другими стоками. Результат записывается в файл tmpCalendarMonth.tex, который в свою очередь вставляется в ЛаТеХ через \input{Calendar/tmpCalendarMonth} и обрабатывается при сборке. Скрипт на питоне ниже:
#! /usr/bin/python
import string, os
import commands

kmvStartDir = '.'
kmvDestDir = kmvStartDir+'/Calendar/' #destination directory for graphs

###### Getting dates and months as text using DATE command in Linux ####
cmd='date --date="today" +%Y'
stdout_handle = os.popen(cmd)
kmv_year = stdout_handle.read()
kmv_year = kmv_year.rstrip('\n')
stdout_handle.close()

cmd='date --date="today" +%B'
stdout_handle = os.popen(cmd)
kmv_month = stdout_handle.read()
kmv_month = kmv_month.rstrip('\n')
stdout_handle.close()

cmd='date --date="today" +%e'
stdout_handle = os.popen(cmd)
kmv_day = stdout_handle.read()
kmv_day = kmv_day.rstrip('\n')
stdout_handle.close()

####################################
#### Month Calendar regeneration ###
####################################
kmvCalName = kmvDestDir+'tmpCalendarMonth'

out = '' 
out +=r'\begin{landscape}'+'\n'
out +=r'\begin{monthly}'
out +='\n {firstday=1} \n'
out +='{Calendar/myEvents} \n'
out +=kmv_month+' '+kmv_year+'\n'
out +='\end{monthly}\n'
out +='\end{landscape}\n'

### Output to the Calendar's file ######
kmvCalName+='.tex'
fout=open(kmvCalName,'w')
fout.write(out)
fout.close()
####################################

Скрипт calendar_regenerate.py и все остальные файлы можно взять отсюда. Скрипт написан для того, чтобы быть максимально понятным, а не красивым или эффективным.

Вызов скрипта на Питоне из LaTeX

Вызывать скрипты из латеха можно несколькими способами:
Здесь я приведу второй вариант, как наиболее простой. Для этого мы помещаем питоний скрипт calendar_regenerate.py в тот же каталог, где лежит файл 4myGTD.tex, из которого скрипт будет вызываться. В преамбуле документа пишем:

%%% Python script for calendar regeneration
\immediate\write18{./calendar_regenerate.py}

Чтобы всё это заработало, нужно вызывать LaTeX с параметром -shell-escape который позволяет выполнение внешних скриптов.

Кто такой \write18 и почему так называется?!

Команда \write это низкоуровневая инструкция TeX, которая используется для того, чтобы производить запись в файловые "потоки". ТеХ ссылается на каждый открытый файл не по имени, а по номеру. Поток 18 является особым и зарезервирован для того, чтобы попросить операционную систему что-то выполнить - например, внешний скрипт.
Внимание! Как совершенно справедливо отмечается многими, подобный трюк в сочетании с параметром –shell-escape небезопасен и представляет собой потенциальную дыру в безопасности. Так можно написать вредоносный документ с командой типа \write18{rm -rf ~} в Unix. По этому поводу есть статья (PDF) об этой и других опасных командах в LaTeX.
Команда \immediate приказывает ЛаТеХ выполнить скрипт немедленно, не дожидаясь окончания генерации всего документа. В данном случае это оправдано, так как мы хотим, чтобы в документ вставился уже обновлённый календарь.

Заключение

Заметка имеет своей целью показать возможности автоматизации в латехе с использованием сторонних скриптов на примере автоматизированной генерации календарей. Пакет calendar довольно навороченный, потому его описание заняло добрую половину поста. Пример в посте доступен здесь.
Читать далее

Перенос таблиц из MS Excel или OpenOffice Calc в LaTeX через Calc2LaTeX



8 коммент.
Это небольшая заметка может пригодится помимо автора этих строк тем, кому нужно переносить или создавать сравнительно простые таблицы из Excel или Calc в LaTeX, потому как создание таблиц в LaTeX это занятие, часто причиняющее адские боли ниже поясницы.

Читать далее

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



3 коммент.

Как уже обсуждалось в предыдущем посте из серии "ЛаТеХ для продвинутых", одним из самых универсальных средств для контроля над расположением картинок, таблиц и подписей к ним в пределах плавaющего объекта является пакет floatrow.

В предыдущей части мы рассмотрели всевозможные способы взаимного расположения картинки и подписи (снизу, сверху, сбоку), выравнивания их по горизонтали и т.п. Этот же пост будет посвящён расположению нескольких объектов (рисунков, таблиц) в ряд. Обратите внимание, что имеется в виду именно расположение нескольких объектов типа figure и/или table, а не нескольких картинок/таблиц (обычно помеченных как а, б, в, ...) в пределах одного объекта, как это делают пакеты subcaption или subfig.

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

Краткий анонс

Сначала мы познакомимся с командами \ffigbox{}{} и \ttabbox{}{}, которые создают бокс для картинки/таблицы и соответствующей подписи.

Затем будут освещены средства, необходимые для контроля над горизонтальным выравниванием:

  • Окружение floatrow для расположения иллюстраций и таблиц в ряд.
  • Длины FBwidth (ширина картинки) и Xhsize (ширина остатка страницы).
  • Параметр floatrowsep, определяющий расстояние между картинками в ряду.

И, наконец, будут разобраны способы выравнивания объектов по вертикали, как то

  • Команды \TopFloatBoxes, \BottomFloatBoxes, \CenterFloatBoxes, выравнивающие весь float.
  • Параметры heightadjust и valign для выравнивания только картинки/таблицы.
  • Выравнивание подписей.

Команда \ffigbox

Основной рабочей лошадкой во всех примерах ниже является команда \ffigbox предоставляемая пакетом floatrow. Её синтаксис прост:

01:  \ffigbox[ширина][высота][вертикальное положение]{подпись}{картинка}
Она определяет бокс, в который помещается картинка и подпись к ней, например
01:  \usepackage{floatrow}
02:  \usepackage{graphicx}
03:  ...
04:  \begin{figure}[!h]
05:   \ffigbox{\caption{My Caption}\label{fig:ffb}}%
06:           {\includegraphics{roman_a}}
07:  \end{figure}
создаст обычный плавающий объект, как произошло бы и без использования \ffigbox, с той единственной разницей, что благодаря \ffigbox автоматически включается горизонтальное выравнивание по центру.

Для таблиц определена аналогичная команда \ttabbox: далее мы сосредоточимся на картинках, но всё без исключения применимо и к таблицам.

Расположить несколько рисунков в ряд нам поможет окружение floatrow:

01:  \begin{figure}
02:  \begin{floatrow}
03:   \ffigbox{\caption{My Caption left}\label{...}}%
04:           {\includegraphics{...}}
05:   \ffigbox{\caption{My Caption right}\label{...}}%
06:           {\includegraphics{...}}         
07:  \end{floatrow}
08:  \end{figure}

По умолчанию, страница просто поделена на две равные по ширине части, в каждую из которых вставлен рисунок и отцентрирован по горизонтали. Просто и незатейливо,... но не всегда достаточно, чтобы добиться идеального результата. Итак, за дело: в путь к идеалу!

Горизонтальное выравнивание

Волшебная длина \FBwidth

Предыдущий рисунок выглядит очень неуравновешенно, так как ширина отводящаяся на подпись не соответствует ширине картинки. Гораздо более симпатичного результата можно добиться вот так:

01:  \usepackage{floatrow,graphicx,calc}
02:  % Создаёем новый разделитель
03:  \DeclareFloatSeparators{mysep}{\hspace{3cm}}
04:  ...
05:  % Настраиваем значение разделителя для объектов 
06:  \thisfloatsetup{floatrowsep=mysep}
07:  % А вот и сам плавающий объект
08:  \begin{figure}
09:   \begin{floatrow}
10:    \ffigbox[\FBwidth+1cm]{\caption{...}}%
11:            {\includegraphics{...}}
12:    \ffigbox[\FBwidth+1cm]{\caption{...}}%
13:            {\includegraphics{...}}         
14:   \end{floatrow}
15:  \end{figure}

По порядку

  1. В строках 10 и 12 использован необязательный аргумент в \ffigbox, который задаёт ширину плавающего объекта. В этом примере мы задаём ширину на 1см больше, чем ширина соответствующего изображения: т.е. подпись будет выдаваться на 0.5см с каждой стороны. Заметьте, что ширина самого изображения доступна через \FBwidth, a для того, чтобы можно было к ней прибавить 1см, надо загрузить пакет calc в строке 1.
  2. Расстояние между двумя объектами (Figure 3 и Figure 4) задано в строке 6 с помощью параметра floatrowsep. Обратите внимание, что нельзя просто написать floatrowsep=3cm, вместо этого надо определить новый разделитель (назовём его mysep) в строке 3, а затем использовать в floatrowsep=mysep. Пакет предопределяет следующие разделители: none, quad (=1em), qquad (=2em), columnsep (равен длине \columnsep, которую ЛаТеХ использует для разделения двух колонок текста).

Волшебная длина \Xhsize

Помимо очень полезной длины \FBwidth, пакет предопределяет длину (точнее, ширину) \Xhsize, равную оставшейся ширине страницы. Эта длина может быть использована точно так же, как и \FBwidth, в первом необязательном аргументе \ffigbox.

Например, в случае, когда одна из подписей очень длинная, под неё может быть желательно выделить побольше места:

01:  \begin{figure}
02:   \begin{floatrow}
03:    \ffigbox[\FBwidth+1cm]{\caption{My Caption left}}%
04:            {\includegraphics{...}}
05:    \ffigbox[\Xhsize]{\caption{My Caption right very .... very long}}%
06:            {\includegraphics{...}}         
07:   \end{floatrow}
08:  \end{figure}

Несколько картинок в ряд

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

01:  \thisfloatsetup{floatrowsep=qquad}
02:  \begin{figure}
03:  \begin{floatrow}[3] % три рисунка в ряд!
04:   \ffigbox[\FBwidth+0.5cm]{\caption{...}}{\includegraphics{...}}
05:   \ffigbox[\Xhsize/3*2]{\caption{...}}{\includegraphics{...}}  
06:   \ffigbox[\Xhsize]{\caption{...}}{\includegraphics{...}} 
07:  \end{floatrow}
08:  \end{figure}

Из этого же примера очевидна гибкость использования \FBwidth и \Xhsize: к ним можно прибавлять длины, их можно умножать на скаляры. Кроме того, обратите внимание, что параметр \Xhsize в строках 5 и 6 имеет разные значения: он каждый раз означает ширину, оставшуюся на странице на момент вызова \ffigbox!

Вертикальное выравнивание

Весь объект

До сих пор во всех примерах использовались картинки приблизительно одинаковой высоты, т.е. особой нужды в форматировании их вертикального положения не возникало. Если же рисунки отличаются по высоте, то встаёт вопрос об их вертикальном положении относительно друг друга.

Эта проблема решается с помощью одной из команд
\BottomFloatBoxes (выравнивание по низу),
\TopFloatBoxes (выравнивание по верху),
\CenterFloatBoxes (выравнивание по центру),
которая должна следовать сразу после \begin{figure}.

Например
01:  \begin{figure}[!h]\TopFloatBoxes % or \BottomFloatBoxes or \CenterFloatBoxes
02:   \begin{floatrow}
03:     \ffigbox{...}{...}
04:     \ffigbox{...}{...}
05:   \end{floatrow}
06:  \end{figure}
приводит к такому результату:

Только картинки

В большинстве случаев, однако, необходимо выровнять только картинки, а подписи к ним оставить на одном уровне. Без проблем:

01:  \begin{figure}[!h]
02:   \floatsetup{heightadjust=object,valign=c}
03:   \begin{floatrow}
04:    \ffigbox{\caption{...}}%
05:            {\includegraphics{...}}
06:    \ffigbox{\caption{...}}%
07:            {\includegraphics{...}}         
08:   \end{floatrow}
09:  \end{figure}

Здесь использованы два параметра:

heightadjust: какие части float в ряду должны быть одинаковой высоты. Соответственно, его значения

  1. object: место, отводящееся под саму картинку, выполнить одинаковой высоты для всех картинок;
  2. caption: то же, но для места, отводящегося под подпись;
  3. all: первое и второе вместе;
  4. noobject, nocaption, none: отрицание, соответственно, первого, второго и третьего
В нашем примере, floatrow инструктирован выделить под обе картинке блоки одинаковой высоты.

valign: "тип" вертикального выравнивания. Может быть t (по верху), b (по низу), c (по центру).

Подписи

Для рисунков, когда подписи размещены под иллюстрацией, нет необходимости их дополнительно "выравнивать": подписи и так выровнены "по верху". Однако у таблиц, когда подписи размещены сверху, так как использована директива

01:  \floatsetup[table]{style=plaintop}
или, что то же самое,
01:  \floatsetup[table]{capposition=top}
то подписи автоматически оказываются вырoвненными "по низу", вот так:

Чтобы вырoвнять их "по верху" используем

01:  \floatsetup[table]{style=Plaintop}
или же
01:  \floatsetup[table]{capposition=TOP}

Полностью код примера выше: открыть

01:  % используем стиль, в котором подписи таблиц 
02:  % сверху и выравнены "по верху"
03:  \floatsetup[table]{style=Plaintop,floatrowsep=qquad}
04:  %
05:  % Теперь сами таблицы в ряд
06:  \begin{table}[!h]
07:  \begin{floatrow}
08:   % первая таблица
09:   \ttabbox[\FBwidth]{\caption{My Caption left}}%
10:           {\begin{tabular}{c|cc}
11:             Column 1 & Column 2 & Column 3 \\ \hline
12:               a      &  b       &  c       \\
13:               a      &  b       &  c       \\
14:               a      &  b       &  c       \\
15:               a      &  b       &  c       \\
16:               a      &  b       &  c
17:            \end{tabular}
18:    }
19:   % вторая таблица
20:   \ttabbox[\FBwidth]{\caption{My Caption right, let us 
21:                             make it somewhat longer}}%
22:           {\begin{tabular}{c|cc}
23:                      Column 1 & Column 2 & Column 3 \\ 
24:                      \hline
25:                        a      &  b       &  c       \\
26:                        a      &  b       &  c       \\
27:                        a      &  b       &  c       
28:            \end{tabular}
29:           }
30:  \end{floatrow}
31:  \end{table}

Картинка рядом с таблицей

Все трюки, приведённые выше, обсуждались на примере или картинок, или таблиц. Если картинка и таблица должны находиться рядом, нужно воспользоваться командой \killfloatstyle. Например
01:  \begin{figure}[!h]\CenterFloatBoxes
02:   \begin{floatrow}
03:     \ffigbox[...]{\caption{...}}{...}   
04:    %
05:    \killfloatstyle
06:    %
07:     \ttabbox[...]{\caption{...}}{...}
08:   \end{floatrow}
09:  \end{figure} 
произведёт следующий результат

И всё-таки subfloats

Хотя во введении и было обещано не рассматривать вопросы, связанные с расположением "подрисунков" (subfigures, subtables), стоит отметить, что все вышеприведённые рецепты действуют и в их случае с той лишь разницей, что надо использовать окружение subfloatrow вместо floatrow.

Простой пример ниже демонстрирует это в деталях

01:  \usepackage{subcaption,floatrow,graphicx,calc}
02:  \floatsetup{floatrowsep=qquad}
03:  ...
04:  \begin{figure}[!h]
05:  \ffigbox{
06:    % объявляем, что будут 3 картинки в ряд
07:    \begin{subfloatrow}[3]
08:       \ffigbox[\FBwidth+1cm]{\caption{My Caption left}}{\includegraphics{...}}
09:       \ffigbox[\FBwidth+1cm]{\caption{My Caption mid...}}{\includegraphics{...}} 
10:       \ffigbox[\FBwidth+1cm]{\caption{My Caption right...}}{\includegraphics{...}} 
11:    \end{subfloatrow}
12:  }
13:  { % подпись ко всему float 
14:    \caption{Overall caption.}
15:  }
16:  \end{figure}
Пара пунктов, на которые стоит обратить внимание:
  1. надо загрузить дополнительно пакет subcaption;
  2. вместо окружения floatrow используем subfloatrow;
  3. причём помещаем его внутрь первого аргумента \ffigbox (строка 5);
  4. а во втором аргументе \ffigbox помещаем подпись ко всему ряду рисунков (строка 14).

Абсолютно аналогично можно это применить и к таблицам, заменив \ffigbox на \ttabbox

Заключительный сложный пример для любознательных

Помимо рассмотренных выше трюков, floatrow позволяет создавать собственные типы float. Кроме того, пакет иеально функционирует в тандеме с другим пакетом caption, который позволяет должным образом оформить подпись.

В следующем примере использованны эти возможности:

  1. Определен новый тип float под названием Photo (с собственным счётчиком и другими атрибутами), подпись которого набирается справа от картинки.
  2. Для таблиц и др. объектов, подпись отфoрмaтирована специальным образом.

Подробные разъяснения приведены в коде: открыть
01:  \usepackage{caption,floatrow}
02:  %------------------------------------------------
03:  % Форматируем подписи к таблицам, благодаря пакету caption
04:  \DeclareCaptionLabelFormat{rightline}{\rightline{\bothIfFirst{#1}{ }#2}}
05:  % метка Table справа, затем новая строка, метка наклонным, сама подпись жирным малым шрифтом
06:  \captionsetup[table]{labelformat=rightline,labelsep=newline,%
07:                       labelfont={md,sl},textfont={bf,small}}
08:  % Подпись размещаем вверху от таблицы
09:  \floatsetup[table]{style=Plaintop}
10:  %-------------------------------------------------
11:  % Создаём новый тип float: photo
12:  % Команда \DeclareNewFloatType{тип}{опции} из пакета floatrow
13:  \DeclareNewFloatType{photo}{name={Photo},placement=tbp}
14:  % Определяем аналог \ffigbox для photo
15:  % с помощью \newfloatcommand{команда}{тип}[преамбула][ширина]   
16:  \newfloatcommand{photobox}{photo}%
17:    [{\capbeside
18:      \thisfloatsetup{capbesideposition={right,bottom},% подпись справа внизу
19:                      capbesidewidth=3cm}% ширина подписи 3см
20:    }]%
21:    [\FBwidth]
22:  % форматируем подпись с помощью пакета caption  
23:  \captionsetup[photo]{labelformat=rightline,labelsep=newline,%
24:                       labelfont={md,sl},textfont={bf,small}}%
25:  %--------------------------------------------------
26:  % для обычного "Figure"
27:  \floatsetup[figure]{capposition=bottom}
28:  \captionsetup[figure]{labelfont={md,sl},textfont={bf,small}}%
29:  %---------------------------------------------------
30:  ...
31:  \begin{table}[!h]\CenterFloatBoxes
32:  \begin{floatrow}
33:   \ttabbox[\FBwidth]{\caption{My Caption left}\label{tab:1}}%
34:           {\begin{tabular}{c|c}
35:             ...   
36:     \end{tabular}
37:           }
38:   %  
39:   \killfloatstyle 
40:   % 
41:   \photobox{\caption{Here goes a photo}\label{ph:1}}{\includegraphics{...}}
42:  \end{floatrow}
43:  \end{table}
44:  
45:  See Table~\ref{tab:1} and Photo~\ref{ph:1}. Also a ``normal'' Figure~\ref{fig:1}.
46:  
47:  \begin{figure}[!h]
48:   \ffigbox{\caption{Graph of a function}\label{fig:1}}{\includegraphics{...}}
49:  \end{figure}

Подведение итогов

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

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

Читать далее

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



4 коммент.

Одним из самых часто задаваемых вопросов о 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 доступна на русском и английском языках.

Читать далее