expl3 構文を使用して、幅がゼロで高さが指定されたボックスにコンテンツを設定し、オプションで回転させるにはどうすればよいでしょうか?

expl3 構文を使用して、幅がゼロで高さが指定されたボックスにコンテンツを設定し、オプションで回転させるにはどうすればよいでしょうか?

使用スティーブン・B・セグレテスの回答、水平方向に中央揃えしたり、回転したりすることができます。

\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}

ダミー出力

関連情報