С использованиемОтвет Стивена Б. Сеглетеса, я могу центрировать что-то горизонтально, при желании вращая его, используя
\centering
\makebox[0pt]{\rotatebox{<angle>}{<contents>}}
\par
Однако я также хотел бы указать, что у ящика есть определенная высота. Более того, поскольку я делаю это с помощью команды, которая уже использует синтаксис expl3, я подумал, что, возможно, имеет смысл попробовать использовать функции expl3. (Однако я не привязан к этой идее — мои макросы уже представляют собой колдовское варево из TeX, LaTeX2e и синтаксиса expl3, так что немного больше на самом деле не повредит ничему, против чего я уже не оскорбляюсь.)
Я могу добиться желаемого эффекта, используя следующее:
\documentclass[a4paper]{article}
\usepackage{expl3,xparse,geometry}
\geometry{margin=20mm}
\ExplSyntaxOn
\tl_new:N \l_cfr_troibocs_tl
\bool_new:N \l_cfr_bocs_bool
\keys_define:nn { mycommand }
{
hfit .bool_set:N = \l_cfr_hfit_bool,
hfit .default:n = true,
vfit .bool_set:N = \l_cfr_vfit_bool,
vfit .default:n = true,
rotate .code:n = {
\tl_set:Nn \l_cfr_troibocs_tl {#1}
\bool_set_true:N \l_cfr_troi_bool },
troi .bool_set:N = \l_cfr_troi_bool,
troi .default:n = true,
troibocs .tl_set:N = \l_cfr_troibocs_tl,
troibocs .initial:n = 0,
}
\NewDocumentCommand\mycommand { o m }{
\group_begin:
\IfValueT{#1}{ \keys_set:nn { mycommand } { #1 } }
% from Steven B. Segletes's answer at https://tex.stackexchange.com/a/162202/
\bool_if:NTF \l_cfr_troi_bool
{
\hbox_set:Nn \g_tmpa_box {\rotatebox[]{\l_cfr_troibocs_tl}{\file_input:n {#2}}}
}
{
\hbox_set:Nn \g_tmpa_box {\file_input:n {#2}}
}
\bool_if:NT \l_cfr_vfit_bool
{
\box_set_ht:Nn \g_tmpa_box {.8\textheight}
}
\centering
\bool_if:NTF \l_cfr_hfit_bool
{
\makebox[0pt]{\box_use:N \g_tmpa_box}
}{
\box_use:N \g_tmpa_box
}
\par
\group_end:
}
\ExplSyntaxOff
\usepackage{filecontents,tikz}
\begin{filecontents}{mytikz.tex}
\begin{tikzpicture}
\path [draw, fill] (0,0) rectangle +(265mm,175mm);
\end{tikzpicture}
\end{filecontents}
\begin{document}
\mycommand[
rotate=90,
vfit,
hfit
]{mytikz}
\end{document}
Есть ли лучший/более чистый способ сделать это?
Мои попытки перевести большую часть определения в синтаксис expl3 пока что потерпели полную неудачу. Я подозреваю, что мои трудности связаны сответ egregно я не уверен, и вообще не знаю, как изменить код.
Если я использую \hbox_to_zero:n
, то блок не центрируется горизонтально, но я не могу просто поставить \leavemode
перед ним в этом контексте, так как это просто сломает все полностью. Я также не могу изменить ширину блока, как я изменяю высоту, так как это \box_set_wd:Nn \g_tmpa_box {0pt}
не имеет никакого эффекта.
[Я также пытался заменить его \rotatebox
новым экспериментальным расширением \box_rotate:Nn
, но оно ведет себя странно по сравнению с моими ожиданиями, поэтому я отказался от этой идеи.]
решение1
Если я правильно понял ваши требования, то достаточно стандартных методов:
\documentclass{article}
\usepackage{graphicx,lipsum,color}
\newcommand\rotbox[3][\dimexpr\height+\depth\relax]{%
% #1 is the final height, #2 is the angle, #3 the contents
\raisebox{\depth}[#1][0pt]{%
\makebox[0pt]{%
\rotatebox{#2}{\color{red}#3}%
}%
}%
}
\begin{document}
\lipsum[3]
\begin{center}
XX\rotbox{45}{This text is rotated}XX
\end{center}
\lipsum*[2]
\begin{center}
XX\rotbox[4cm]{45}{This text is rotated}XX
\end{center}
\lipsum[2]
\end{document}
Я добавил красный цвет просто для большей ясности. Если вы хотите иметь естественную ширину (после поворота), опустите \makebox[0pt]
.
Возможная expl3
версия:
\documentclass{article}
\usepackage{graphicx,lipsum,color,xparse}
\ExplSyntaxOn
\NewDocumentCommand{\xrotbox}{O{}m}
{
\group_begin:
\keys_set:nn { cfr/rotbox } { #1 }
\cfr_xrotbox:n { #2 }
\group_end:
}
\keys_define:nn { cfr/rotbox }
{
hfit .bool_set:N = \l_cfr_hfit_bool,
hfit .default:n = true,
vfit .bool_set:N = \l_cfr_vfit_bool,
vfit .default:n = true,
rotate .fp_set:N = \l_cfr_rotate_fp,
rotate .initial:n = 0,
%troi .bool_set:N = \l_cfr_troi_bool,
%troi .default:n = true,
%troibocs .tl_set:N = \l_cfr_troibocs_tl,
%troibocs .initial:n = 0,
}
\box_new:N \l_cfr_xrotbox_box
\cs_new_protected:Npn \cfr_xrotbox:n #1
{
\hbox_set:Nn \l_cfr_xrotbox_box { #1 }
\fp_compare:nF { \l_cfr_rotate_fp = \c_zero_fp }
{
\box_rotate:Nn \l_cfr_xrotbox_box { \l_cfr_rotate_fp }
}
\hbox_set:Nn \l_cfr_xrotbox_box
{
\box_move_up:nn { \box_dp:N \l_cfr_xrotbox_box } { \box_use:N \l_cfr_xrotbox_box }
}
\bool_if:NF \l_cfr_hfit_bool
{
\hbox_set_to_wd:Nnn \l_cfr_xrotbox_box { 0pt }
{
\hss \box_use:N \l_cfr_xrotbox_box \hss
}
}
\bool_if:NF \l_cfr_vfit_bool
{
\box_set_ht:Nn \l_cfr_xrotbox_box { 0pt }
}
\leavevmode\box_use:N \l_cfr_xrotbox_box
}
\ExplSyntaxOn
\begin{document}
\lipsum[3]
\begin{center}
XX\xrotbox[rotate=45]{This text is rotated}XX
\end{center}
\lipsum*[2]
\begin{center}
XX\xrotbox[rotate=45,hfit,vfit]{This text is rotated}XX
\end{center}
\lipsum[2]
\end{document}
решение2
Это основано наответ egregно адаптирован к тому, что я на самом деле хотел сделать. Боюсь, что мой изначальный вопрос недостаточно объяснил контекст и поэтому был неясен. Таким образом, я считаю ответ egreg вполне хорошим. Однако, если это будет полезно кому-то еще, я также публикую код, который я придумал, адаптировав этот ответ.
Суть кода в том, чтобы набрать изображение, которое на самом деле слишком велико для доступного пространства, но которое на самом деле подходит с человеческой (не TeX) точки зрения. Например, ментальная карта может немного выходить за пределы области страницы, не «выглядя» слишком большой, поскольку она содержит разумное количество пустого пространства.
Команда, которую я на самом деле использую для этого, вводит файл и опционально набирает заголовок и подзаголовок, запись для оглавления и библиографию. Обычно вводится в основном текст. Однако я хотел использовать ту же команду для набора одностраничного изображения с заголовком, чтобы обеспечить единообразие форматирования и т. д. В этом случае содержимое файла помещается в поле и далее обрабатывается, тогда как в стандартном случае это просто обычный ввод.
Код ниже касается только случая изображения. То есть он не беспокоится о различии обычного случая от случая изображения или о заголовке, оглавлении или библиографии.
\mycommand[]{}
принимает необязательный аргумент, состоящий из 0–3 ключей:
rotate=<angle>
если содержимое следует повернуть;hfit
если содержимое должно быть размещено горизонтально, центрируя его в коробке шириной0pt
;vfit
если содержимое должно быть размещено вертикально, путем помещения его в коробку высотой.8\textheight
плюс половина разницы между естественной высотой коробки и.8\textheight
.
Обязательным аргументом является имя файла, который необходимо ввести, например, имя файла, содержащего tikzpicture
ментальную карту.
Пример изображения немного шире \textheight
и немного выше, чем \textwidth
. Поэтому, даже если его повернуть, оно слишком велико с точки зрения TeX. (Поскольку это один черный ящик, оно также выглядит слишком большим для человека. Но дело в том, что его размеры достаточно близки к виду изображения, которое меня интересует.)
Я не уверен, что это действительно правильно, но полная версия, похоже, пока работает...
\documentclass[a4paper]{article}
\usepackage{expl3,xparse,geometry}
\geometry{margin=20mm}
\ExplSyntaxOn
\fp_new:N \l_cfr_troibocs_fp
\bool_new:N \l_cfr_bocs_bool
\dim_zero_new:N \l_cfr_width_dim
\box_new:N \l_cfr_bocs_box
\NewDocumentCommand\mycommand{O{}m}
{
\group_begin:
\centering
\keys_set:nn { cfr/rotbox } { #1 }
\cfr_troibocs:n { 0pt } { .8\textheight } { #2 }
\par
\group_end:
}
\keys_define:nn { cfr/rotbox }
{
hfit .bool_set:N = \l_cfr_hfit_bool,
hfit .default:n = true,
vfit .bool_set:N = \l_cfr_vfit_bool,
vfit .default:n = true,
rotate .fp_set:N = \l_cfr_troibocs_fp,
rotate .initial:n = 0,
}
\cs_new_protected:Npn \cfr_troibocs:n #1 #2 #3
{
\hbox_set:Nn \l_cfr_bocs_box { #3 }
\fp_compare:nF { \l_cfr_troibocs_fp = \c_zero_fp }
{
\box_rotate:Nn \l_cfr_bocs_box { \l_cfr_troibocs_fp }
}
\hbox_set:Nn \l_cfr_bocs_box
{
\box_move_up:nn { \box_dp:N \l_cfr_bocs_box } { \box_use:N \l_cfr_bocs_box }
}
\bool_if:NT \l_cfr_hfit_bool
{
\hbox_set_to_wd:Nnn \l_cfr_bocs_box { #1 }
{
\hss \box_use:N \l_cfr_bocs_box \hss
}
}
\bool_if:NT \l_cfr_vfit_bool
{
\dim_set:Nn \l_cfr_width_dim { \box_ht:N \l_cfr_bocs_box }
\dim_sub:Nn \l_cfr_width_dim { #2 }
\dim_compare:nNnT {0pt} < \l_cfr_width_dim
{
\vbox_set_to_ht:Nnn \l_cfr_bocs_box { #2 + .5\l_cfr_width_dim }
{
\vss \box_use:N \l_cfr_bocs_box \vss
}
}
}
\leavevmode\box_use:N \l_cfr_bocs_box
}
\ExplSyntaxOff
\usepackage{filecontents,tikz}
\begin{filecontents}{mytikz.tex}
\begin{tikzpicture}
\path [draw, fill] (0,0) rectangle +(265mm,175mm);
\end{tikzpicture}
\end{filecontents}
\begin{document}
\mycommand[
rotate=90,
hfit,
vfit
]{\input{mytikz}}
\end{document}