Como posso definir o conteúdo em uma caixa de largura zero e altura especificada, girando opcionalmente, usando a sintaxe expl3?

Como posso definir o conteúdo em uma caixa de largura zero e altura especificada, girando opcionalmente, usando a sintaxe expl3?

UsandoResposta de Steven B. Segletes, posso centralizar algo horizontalmente, opcionalmente girando-o, usando

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

No entanto, também gostaria de especificar que a caixa tem uma altura específica. Além disso, como estou fazendo isso usando um comando que já usa a sintaxe expl3, pensei que faria sentido tentar usar funções expl3. (No entanto, não estou apegado a essa ideia - minhas macros já são uma mistura de sintaxe TeX, LaTeX2e e expl3, então um pouco mais realmente não vai prejudicar nada que eu já não esteja ofendendo.)

Posso obter o efeito desejado usando o seguinte:

\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 uma maneira melhor/mais limpa de fazer isso?

Minhas tentativas de traduzir mais da definição para a sintaxe expl3 até agora encontraram um fracasso total. Suspeito que minhas dificuldades estejam relacionadasresposta da egrégiamas não tenho certeza e não sei como modificar o código de qualquer maneira.

Se eu usar \hbox_to_zero:n, a caixa não será centralizada horizontalmente, mas não posso simplesmente colocá-la \leavemodeantes dela neste contexto, pois isso quebrará completamente as coisas. Também não posso alterar a largura da caixa assim como altero a altura, pois \box_set_wd:Nn \g_tmpa_box {0pt}não tem efeito.

[Também tentei substituir \rotateboxpela nova extensão experimental, \box_rotate:Nnmas ela se comporta de maneira bizarra, em relação às minhas expectativas, então abandonei essa ideia.]

Responder1

Se entendi bem sua exigência, os métodos padrão são 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}

Eu adicionei a cor vermelha apenas para melhor clareza. Se você quiser ter a largura natural (após a rotação), elimine o \makebox[0pt].

insira a descrição da imagem aqui

Uma versão possível 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}

insira a descrição da imagem aqui

Responder2

Isto é baseado emresposta da egrégiamas está adaptado ao que eu realmente queria fazer. Receio que a minha pergunta original não tenha explicado suficientemente o contexto e, portanto, não tenha sido clara. Como tal, acho que a resposta de egreg é perfeitamente boa. Porém, caso seja útil para mais alguém, também estou postando o código que criei ao adaptar essa resposta.

O objetivo do código é compor uma imagem que seja realmente grande demais para o espaço disponível, mas que na verdade caiba de uma perspectiva humana (não-TeX). Por exemplo, um mapa mental pode transbordar ligeiramente a área da página sem “parecer” muito grande porque contém uma quantidade razoável de espaço vazio.

O comando que estou usando para fazer isso insere um arquivo e, opcionalmente, compõe um título e subtítulo, entrada para o ToC e bibliografia. Normalmente, o que é inserido é principalmente texto. No entanto, eu queria usar o mesmo comando para compor uma imagem de página única com um título para poder garantir a consistência da formatação, etc. Nesse caso, o conteúdo do arquivo é colocado em uma caixa e posteriormente manipulado, enquanto no padrão caso, é apenas inserido normalmente.

O código abaixo diz respeito apenas ao caso da imagem. Ou seja, não se preocupa em diferenciar o caso normal do caso da imagem nem se preocupar com o título, ToC ou bibliografia.

\mycommand[]{}recebe um argumento opcional que consiste em 0 a 3 chaves:

  • rotate=<angle>se o conteúdo deve ser girado;
  • hfitse o conteúdo deve ser forçado a caber horizontalmente centralizando-o em uma caixa de 0ptlargura;
  • vfitse o conteúdo deve ser forçado a caber verticalmente, colocando-o em uma caixa de altura .8\textheightmais metade da diferença entre a altura natural da caixa e .8\textheight.

O argumento obrigatório é o nome do arquivo a ser inserido, por exemplo, o nome do arquivo que contém o tikzpicturemapa mental.

A imagem de exemplo é um pouco mais larga \textheighte um pouco mais alta que \textwidth. Conseqüentemente, mesmo quando girado, é muito grande no que diz respeito ao TeX. (Como é uma única caixa preta, também parece grande demais para um ser humano. Mas a questão é que tem dimensões suficientemente semelhantes às espécies de imagem que me interessam.)

Não tenho certeza se isso está realmente correto, mas a versão completa parece funcionar até agora....

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

saída fictícia

informação relacionada