
Eu tenho a seguinte árvore. Quero que os telhados sejam tão largos quanto o texto e não mais largos. Existe uma maneira de fazer isso com forest
? Em particular, deve ser a largura do texto superior. Isto é importante nos casos em que a tradução é muito mais ampla que o texto original. A cobertura deverá caber no texto original, pois é isso que se analisa, a tradução é extra e logicamente não faz parte da estrutura.
\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:Há uma solução quase perfeita de Sašo abaixo. No entanto, um problema permanece. Eu defini um comando \trace
que quero usar nas árvores. Se eu usá-lo com o código de tradução, recebo o seguinte erro:
! Argument of \@rsbox has an extra }.
<inserted text>
\par
l.45 \end{forest}
?
Este é o 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 uma maneira de permitir tais comandos em árvores traduzidas?
Responder1
Abaixo, usei um truque mostrado no grande exemplo do manual florestal (seção 4.2) para analisar o conteúdo do nó. Então, (i) um nó adicional é criado logo abaixo do texto e preenchido com a tradução (ou seja, o que vem depois \\
no conteúdo original) e (ii) a tradução é excluída do conteúdo. (Este mecanismo de análise está configurado para ser aplicado a todas as folhas da árvore.)
Além disso, tikz
's inner xsep
é definido como 0
para os nós de texto e tradução, para que os triângulos se ajustem perfeitamente ao texto.
Editar: o código foi alterado para aceitar nós sem traduções. No entanto, só consegui fazer isso com um separador mais simples; abaixo, ;
é usado.
Segunda edição: .expanded
manipuladores em estilos append translation
e content
foram substituídos por uma cadeia de .expand once
e .expand twice
para lidar com o problema adicional apresentado por \trace
(consulte a pergunta editada do 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}
Terceira edição: alterada where n children=0
dentro da definição sn edges
para logicamente mais correta if n children=0
. Embora isso não faça diferença (exceto rodar mais lentamente) na versão atual (v1.0.10) do pacote, a where n children
versão produz um resultado errado na (próxima) v1.1 do pacote. Isso ocorre porque a v1.1 corrige um bug no delay
. Na v1.0.x, quando delay
utilizado mais de uma vez em um único nó, a primeira invocação era esquecida. A versão errada do código acima funciona na v1.0.x, apesar de delay=with translation
ser chamada mais de uma vez. Na v1.1, onde chamar delay=with translation
três vezes na verdade chama with translation
(mais tarde) três vezes, isso resulta em nós vazios supérfluos.
Responder2
Uma opção:
\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}
A idéia é usar uma caixa com largura de 0pt para "ocultar" o texto mais largo (é isso que o \HideWd
comando faz); isso, no entanto, terá um efeito indesejado no cálculo da distância entre os irmãos afetados (veja a segunda árvore na imagem), portanto será necessária alguma intervenção manual para fornecer alguns valores apropriados para s sep
(veja os três terceiros na imagem) .
Responder3
Esta é uma resposta à pergunta editada sobre o problema de combinar o código fornecido emA resposta de Saso Živanovićcom o uso de uma macro personalizada.
O truque é substituir o uso de \trace
na árvore por um novo estilo, trace
que executa a macro e substitui a aplicação de with translation
aos nós com 0 filhos.
\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}