Wie kann ich mit der expl3-Syntax Inhalte in einem Feld mit der Breite Null und einer angegebenen Höhe, optional rotierend, festlegen?

Wie kann ich mit der expl3-Syntax Inhalte in einem Feld mit der Breite Null und einer angegebenen Höhe, optional rotierend, festlegen?

Verwenden vonAntwort von Steven B. Segleteskann ich etwas horizontal zentrieren und optional drehen, indem ich

\centering
\makebox[0pt]{\rotatebox{<angle>}{<contents>}}
\par

Ich möchte jedoch auch angeben, dass die Box eine bestimmte Höhe hat. Da ich dies außerdem mit einem Befehl mache, der bereits die expl3-Syntax verwendet, dachte ich, dass es sinnvoll sein könnte, zu versuchen, expl3-Funktionen zu verwenden. (Ich bin jedoch nicht an diese Idee gebunden – meine Makros sind bereits ein Hexengebräu aus TeX-, LaTeX2e- und expl3-Syntax, also wird ein bisschen mehr wirklich nicht schaden, da ich nicht bereits gegen etwas verstoße.)

Den gewünschten Effekt erziele ich mit Folgendem:

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

Gibt es eine bessere/sauberere Möglichkeit, dies zu tun?

Meine Versuche, mehr von der Definition in expl3-Syntax zu übersetzen, sind bisher kläglich gescheitert. Ich vermute, meine Schwierigkeiten hängen mitegregs Antwortaber ich bin nicht sicher, und ich weiß sowieso nicht, wie ich den Code ändern soll.

Wenn ich verwende \hbox_to_zero:n, wird das Feld nicht horizontal zentriert, aber ich kann \leavemodein diesem Kontext nicht einfach davor setzen, da das alles komplett kaputt machen würde. Ich kann die Breite des Felds auch nicht ändern, wenn ich die Höhe ändere, da dies \box_set_wd:Nn \g_tmpa_box {0pt}keine Auswirkung hat.

[Ich habe auch versucht, es \rotateboxdurch die neue experimentelle Erweiterung zu ersetzen \box_rotate:Nn, aber diese verhält sich im Vergleich zu meinen Erwartungen seltsam, daher habe ich diese Idee aufgegeben.]

Antwort1

Wenn ich Ihre Anforderung richtig verstehe, reichen Standardmethoden aus:

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

Ich habe die rote Farbe nur zur besseren Übersichtlichkeit hinzugefügt. Wenn Sie die natürliche Breite (nach der Drehung) haben möchten, lassen Sie das weg \makebox[0pt].

Bildbeschreibung hier eingeben

Eine mögliche expl3Version:

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

Bildbeschreibung hier eingeben

Antwort2

Dies basiert aufegregs Antwortaber es ist an das angepasst, was ich eigentlich tun wollte. Ich fürchte, meine ursprüngliche Frage hat den Kontext nicht ausreichend erklärt und war daher unklar. Daher halte ich egregs Antwort für vollkommen gut. Falls sie jedoch für irgendjemanden anderen nützlich ist, veröffentliche ich auch den Code, den ich durch Anpassen dieser Antwort erstellt habe.

Der Zweck des Codes besteht darin, ein Bild zu setzen, das eigentlich zu groß für den verfügbaren Platz ist, aber aus menschlicher (nicht TeX-)Perspektive tatsächlich passt. Beispielsweise kann eine Mindmap den Seitenbereich leicht überragen, ohne zu groß auszusehen, da sie eine angemessene Menge an Leerraum enthält.

Der Befehl, den ich tatsächlich dazu verwende, gibt eine Datei ein und setzt optional einen Titel und Untertitel, einen Eintrag für das Inhaltsverzeichnis und eine Bibliografie. Normalerweise besteht die Eingabe hauptsächlich aus Text. Ich wollte jedoch denselben Befehl verwenden, um ein einseitiges Bild mit einem Titel zu setzen, damit ich eine einheitliche Formatierung usw. sicherstellen konnte. In diesem Fall wird der Inhalt der Datei in eine Box eingefügt und weiter bearbeitet, während er im Standardfall nur normal eingegeben wird.

Der folgende Code betrifft nur die Bildschreibweise. Das heißt, er kümmert sich nicht darum, die normale Schreibweise von der Bildschreibweise zu unterscheiden oder sich um Titel, Inhaltsverzeichnis oder Bibliografie zu kümmern.

\mycommand[]{}nimmt ein optionales Argument bestehend aus 0 bis 3 Schlüsseln an:

  • rotate=<angle>ob der Inhalt gedreht werden soll;
  • hfitob der Inhalt durch Zentrieren in einem Feld mit der Breite horizontal ausgerichtet werden soll 0pt;
  • vfitwenn der Inhalt vertikal ausgerichtet werden soll, indem er in eine Box mit der Höhe .8\textheightplus der Hälfte der Differenz zwischen der natürlichen Höhe der Box und gesetzt wird .8\textheight.

Das obligatorische Argument ist der Name der einzugebenden Datei, z. B. der Name der Datei, die die Vorlage tikzpicturefür eine Mindmap enthält.

Das Beispielbild ist etwas breiter als \textheightund etwas höher als \textwidth. Daher ist es für TeX auch in gedrehter Form zu groß. (Da es sich um eine einzelne schwarze Box handelt, sieht es für einen Menschen auch zu groß aus. Aber der Punkt ist, dass seine Abmessungen denen der Bildart, mit der ich mich befasse, ausreichend ähnlich sind.)

Ich bin nicht sicher, ob das wirklich richtig ist, aber die Vollversion scheint bisher zu funktionieren …

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

Dummy-Ausgabe

verwandte Informationen