
Tengo el siguiente árbol. Quiero que los techos sean tan anchos como el texto, no más anchos. ¿Hay alguna manera de hacer esto con forest
? En particular, debería ser el ancho del texto superior. Esto es importante en los casos en los que la traducción es mucho más amplia que el texto original. El techo debe ajustarse al texto original ya que es lo que se analiza, la traducción es extra y lógicamente no forma parte de la estructura.
\documentclass{minimal}
\usepackage{forest}
\forestset{
sn edges/.style={for tree={parent anchor=south, child anchor=north,align=center,base=bottom,where n children=0{tier=word}{}}},
background tree/.style={for tree={text opacity=0.2,draw opacity=0.2,edge={draw opacity=0.2}}}
}
\begin{document}
\begin{forest}
sn edges
[NP
[Det [das\\the] ]
[N'
[N'
[N [Bild\\picture] ]
[PP [vom Gleimtunnel\\of.the Gleimtunnel,triangle ] ] ]
[PP [im Gropiusbau\\in.the Gropiusbau,triangle ] ] ] ]
\end{forest}
\end{document}
Editar:Hay una solución casi perfecta de Sašo a continuación. Sin embargo, persiste un problema. Definí un comando \trace
que quiero usar en árboles. Si lo uso con el código de traducción, aparece el siguiente error:
! Argument of \@rsbox has an extra }.
<inserted text>
\par
l.45 \end{forest}
?
Este es el código:
\documentclass{minimal}
\usepackage{forest}
\forestset{
with translation/.style={
l sep=0,inner xsep=0,
append translation/.expanded/.wrap pgfmath arg={\gettranslation{##1}}{content},
content/.expanded/.wrap pgfmath arg={\gettext{##1}}{content},
},
append translation/.style={append={[#1,no edge,l=0,inner xsep=0,inner ysep=0,outer ysep=0,before
computing xy={l-=2pt}]}},
sn edges/.style={for tree={parent anchor=south, child anchor=north,align=center,base=top},
where n children=0{tier=word,delay=with translation}{} %,delay=with translation
}
}
\def\gettext#1{\gettextA#1;;\endget}
\def\gettextA#1;#2;{\removesep#1;}
\def\gettranslation#1{\gettranslationA#1;;\endget}
\def\gettranslationA#1;#2;{\removesep#2;}
\def\removesep#1;#2\endget{#1}
\newcommand{\trace}{\raisebox{0.2ex}{\_}\rule{0cm}{0.7em}}
\begin{document}
\begin{forest}
sn edges
[NP
[Det [eine;a] ]
[N$'$
[A [kluge;smart] ]
[N$'$
[N [\trace ] ] ] ] ]
\end{forest}
\end{document}
\end{forest}
¿Existe alguna forma de permitir este tipo de comandos en los árboles traducidos?
Respuesta1
A continuación, utilicé un truco que se muestra en el gran ejemplo del manual del bosque (sección 4.2) para analizar el contenido del nodo. Luego, (i) se crea un nodo adicional justo debajo del texto y se completa con la traducción (es decir, lo que venga después \\
en el contenido original) y (ii) la traducción se elimina del contenido. (Este mecanismo de análisis está configurado para aplicarse a todas las hojas del árbol).
Además, tikz
's inner xsep
está configurado en 0
para los nodos de texto y traducción, de modo que los triángulos se ajusten perfectamente al texto.
Editar: el código se cambia para aceptar nodos sin traducciones. Sin embargo, sólo pude hacer esto con un separador más simple; a continuación, ;
se utiliza.
Segunda edición: .expanded
los controladores en estilos append translation
y content
fueron reemplazados por una cadena de .expand once
y .expand twice
para abordar el problema adicional planteado por \trace
(consulte la pregunta editada de OP).
\documentclass{minimal}
\usepackage{forest}
\forestset{
with translation/.style={
l sep=0,inner xsep=0,
append translation/.expand once/.expand twice/.wrap pgfmath arg={\gettranslation{##1}}{content},
content/.expand once/.expand twice/.wrap pgfmath arg={\gettext{##1}}{content},
},
append translation/.style={append={[#1,no edge,l=0,inner xsep=0,inner ysep=0,outer ysep=0,before
computing xy={l-=2pt}]}},
sn edges/.style={for tree={parent anchor=south, child anchor=north,align=center,base=top},
if n children=0{tier=word,delay=with translation}{} %,delay=with translation
}
}
\def\gettext#1{\gettextA#1;;\endget}
\def\gettextA#1;#2;{\removesep#1;}
\def\gettranslation#1{\gettranslationA#1;;\endget}
\def\gettranslationA#1;#2;{\removesep#2;}
\def\removesep#1;#2\endget{#1}
\newcommand{\trace}{\raisebox{0.2ex}{\_}\rule{0cm}{0.7em}}
\begin{document}
\begin{forest}
sn edges,
[NP
[Det [das] ]
[N'
[N'
[N [Bild;picture] ]
[PP [vom Gleimtunnel;of.the Gleimtunnel,triangle]] ] ]
[PP [im Gropiusbau;in.the Gropiusbau,triangle ] ] ] ]
\end{forest}
\begin{forest}
sn edges
[NP
[Det [eine;a] ]
[N$'$
[A [kluge;smart] ]
[N$'$
[N [\trace ] ] ] ] ]
\end{forest}
\end{document}
Tercera edición: cambiada where n children=0
dentro de la definición de sn edges
a la lógicamente más correcta if n children=0
. Si bien esto no hace ninguna diferencia (excepto que se ejecuta más lentamente) en la versión actual (v1.0.10) del paquete, la where n children
versión produce un resultado incorrecto en la (próxima) v1.1 del paquete. Esto se debe a que la versión 1.1 corrige un error con delay
. En v1.0.x, cuando delay
se usaba más de una vez en un solo nodo, se olvidaba la primera invocación. Por lo tanto, la versión incorrecta del código anterior funciona en v1.0.x a pesar de que delay=with translation
se llama más de una vez. En v1.1, donde llamar delay=with translation
tres veces en realidad llama with translation
(más tarde) tres veces, esto da como resultado nodos vacíos superfluos.
Respuesta2
Una opción:
\documentclass{article}
\usepackage{forest}
\forestset{
sn edges/.style={for tree={parent anchor=south, child anchor=north,align=center,base=bottom,where n children=0{tier=word,inner xsep=0pt,outer sep=0pt}{}}},
background tree/.style={for tree={text opacity=0.2,draw opacity=0.2,edge={draw opacity=0.2}}}
}
\newcommand\HideWd[1]{%
\makebox[0pt]{#1}%
}
\begin{document}
The default behaviour:\par
\begin{forest}
sn edges,
[NP
[Det [das\\the] ]
[N',s sep=20pt
[N',s sep=15pt
[N [Bild\\picture] ]
[PP [vom Gleimtunnel\\ of.the Gleimtunnel,triangle ] ] ]
[PP [im Gropiusbau\\ in.the Gropiusbau,triangle ] ] ] ]
\end{forest}
Hiding the wider text:\par
\begin{forest}
sn edges,
[NP
[Det [das\\the] ]
[N'
[N'
[N [Bild\\picture] ]
[PP [vom Gleimtunnel\\ \HideWd{of.the Gleimtunnel},triangle ] ] ]
[PP [im Gropiusbau\\ \HideWd{in.the Gropiusbau},triangle ] ] ] ]
\end{forest}
Hiding the wider text and correcting the separation:\par
\begin{forest}
sn edges,
[NP
[Det [das\\the] ]
[N',s sep=20pt
[N',s sep=15pt
[N [Bild\\picture] ]
[PP [vom Gleimtunnel\\ \HideWd{of.the Gleimtunnel},triangle ] ] ]
[PP [im Gropiusbau\\ \HideWd{in.the Gropiusbau},triangle ] ] ] ]
\end{forest}
\end{document}
La idea es utilizar un cuadro que tenga un ancho de 0 puntos para "ocultar" el texto más amplio (esto es lo que \HideWd
hace el comando); esto, sin embargo, tendrá un efecto no deseado en el cálculo de la distancia entre los hermanos afectados (ver el segundo árbol en la imagen), por lo que será necesaria alguna intervención manual para proporcionar algunos valores apropiados para s sep
(ver los tres terceros en la imagen) .
Respuesta3
Esta es una respuesta a la pregunta editada sobre el problema que combina el código proporcionado enLa respuesta de Sašo Živanovićcon el uso de una macro personalizada.
El truco consiste en reemplazar el uso de \trace
en el árbol con un nuevo estilo, trace
que ejecuta la macro y anula la aplicación de with translation
a nodos con 0 hijos.
\documentclass[tikz, border=5pt]{standalone}
\usepackage{forest}
\forestset{
sn edges/.style={for tree={parent anchor=south, child anchor=north,align=center,base=top}, for tree={where n children=0{tier=word, delay=with translation}{}}},
trace/.style={
replace by={[\trace, delay={}, tier=word]}
},
with translation/.style={
l sep=0,
inner xsep=0,
append translation/.expanded/.wrap pgfmath arg={\gettranslation{##1}}{content},
content/.expanded/.wrap pgfmath arg={\gettext{##1}}{content},
},
append translation/.style={
append={
[
#1,
no edge,
l=0,
inner xsep=0,
inner ysep=0,
outer ysep=0,
before computing xy={
l-=2pt
}
]
},
},
}
\def\gettext#1{\gettextA#1;;\endget}
\def\gettextA#1;#2;{\removesep#1;}
\def\gettranslation#1{\gettranslationA#1;;\endget}
\def\gettranslationA#1;#2;{\removesep#2;}
\def\removesep#1;#2\endget{#1}
\newcommand{\trace}{\raisebox{0.2ex}{\_}\rule{0cm}{0.7em}}
\begin{document}
\begin{forest}
sn edges
[NP
[Det [eine;a] ]
[N$'$
[A [kluge;smart] ]
[N$'$
[N [, trace ] ] ] ] ]
\end{forest}
\end{document}