如何使用 expl3 語法在零寬度和指定高度的方塊中設定內容(可選旋轉)?

如何使用 expl3 語法在零寬度和指定高度的方塊中設定內容(可選旋轉)?

使用Steven B. Segletes 的回答,我可以將某些東西水平居中,可以選擇旋轉它,使用

\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 語法,但遭遇了徹底的失敗。我懷疑我的困難與艾格格的回答但我不確定,也不知道如何修改程式碼。

如果我使用\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的回答非常好。但是,如果它對其他人有用,我也會發布我透過調整該答案而提出的程式碼。

程式碼的要點是排版圖像,該圖像對於可用空間而言確實太大,但實際上適合人類(非 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}

虛擬輸出

相關內容