¿Cómo puedo configurar el contenido en un cuadro de ancho cero y alto especificado, opcionalmente rotando, usando la sintaxis expl3?

¿Cómo puedo configurar el contenido en un cuadro de ancho cero y alto especificado, opcionalmente rotando, usando la sintaxis expl3?

UsandoLa respuesta de Steven B. Segletes, puedo centrar algo horizontalmente, opcionalmente girándolo, usando

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

Sin embargo, también me gustaría especificar que el cuadro tenga una altura específica. Además, dado que estoy haciendo esto usando un comando que ya usa la sintaxis expl3, pensé que podría tener sentido intentar usar funciones expl3. (Sin embargo, no estoy aferrado a esta idea: mis macros ya son una mezcla de sintaxis TeX, LaTeX2e y expl3, por lo que un poco más realmente no dañará nada que no esté ofendiendo ya).

Puedo obtener el efecto que quiero usando lo siguiente:

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

¿Existe una forma mejor o más limpia de hacer esto?

Mis intentos de traducir más definición a la sintaxis expl3 han fracasado hasta ahora. Sospecho que mis dificultades están relacionadas conla respuesta de egregpero no estoy seguro y, de todos modos, no estoy seguro de cómo modificar el código.

Si uso \hbox_to_zero:n, entonces el cuadro no está centrado horizontalmente, pero no puedo ponerlo \leavemodedelante en este contexto ya que eso rompería las cosas por completo. Tampoco puedo alterar el ancho del cuadro como cambio el alto, ya que \box_set_wd:Nn \g_tmpa_box {0pt}no tiene ningún efecto.

[También intenté reemplazarla \rotateboxcon la nueva extensión experimental, \box_rotate:Nnpero se comporta de manera extraña, en relación con mis expectativas, así que abandoné esa idea.]

Respuesta1

Si entiendo bien sus necesidades, los métodos estándar son suficientes:

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

Agregué el color rojo solo para mayor claridad. Si desea tener el ancho natural (después de la rotación), suelte el archivo \makebox[0pt].

ingrese la descripción de la imagen aquí

Una posible expl3versión:

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

ingrese la descripción de la imagen aquí

Respuesta2

Esto se basa enla respuesta de egregpero se adapta a lo que realmente quería hacer. Me temo que mi pregunta original no explicaba suficientemente el contexto y, por lo tanto, no estaba clara. Como tal, creo que la respuesta de egreg es perfectamente buena. Sin embargo, en caso de que sea útil para alguien más, también publicaré el código que se me ocurrió adaptando esa respuesta.

El objetivo del código es componer una imagen que en realidad sea demasiado grande para el espacio disponible, pero que en realidad se ajuste desde una perspectiva humana (no TeX). Por ejemplo, un mapa mental puede desbordar ligeramente el área de la página sin "parecer" demasiado grande porque contiene una cantidad razonable de espacio vacío.

El comando que realmente estoy usando para hacer esto ingresa un archivo y, opcionalmente, escribe un título y un subtítulo, una entrada para el ToC y una bibliografía. Normalmente, lo que se ingresa es principalmente texto. Sin embargo, quería usar el mismo comando para componer una imagen de una sola página con un título para poder garantizar la coherencia del formato, etc. En este caso, el contenido del archivo se coloca en un cuadro y se manipula aún más, mientras que en el estándar En este caso, solo se ingresa normalmente.

El siguiente código solo se refiere al caso de la imagen. Es decir, no molesta en diferenciar el caso normal del caso de la imagen ni en preocuparse por el título, la ToC o la bibliografía.

\mycommand[]{}toma un argumento opcional que consta de 0 a 3 claves:

  • rotate=<angle>si se debe rotar el contenido;
  • hfitsi se debe forzar el contenido a encajar horizontalmente centrándolo en un cuadro de 0ptancho;
  • vfitsi se debe forzar el contenido a encajar verticalmente colocándolo en una caja de altura .8\textheightmás la mitad de la diferencia entre la altura natural de la caja y .8\textheight.

El argumento obligatorio es el nombre del archivo que se va a introducir, por ejemplo, el nombre del archivo que contiene el tikzpicturemapa mental.

La imagen de ejemplo es un poco más ancha \textheighty un poco más alta que \textwidth. Por lo tanto, incluso cuando se gira, es demasiado grande en lo que respecta a TeX. (Dado que es una sola caja negra, también parece demasiado grande para un humano. Pero el punto es que tiene dimensiones suficientemente similares a la especie de imagen que me interesa).

No estoy seguro de que esto sea realmente correcto, pero la versión completa parece funcionar hasta ahora...

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

salida ficticia

información relacionada