From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- graphics/pgf/contrib/forest/forest-libs.dtx | 528 ++++++++++++++++++++++++++++ 1 file changed, 528 insertions(+) create mode 100644 graphics/pgf/contrib/forest/forest-libs.dtx (limited to 'graphics/pgf/contrib/forest/forest-libs.dtx') diff --git a/graphics/pgf/contrib/forest/forest-libs.dtx b/graphics/pgf/contrib/forest/forest-libs.dtx new file mode 100644 index 0000000000..9873abfa54 --- /dev/null +++ b/graphics/pgf/contrib/forest/forest-libs.dtx @@ -0,0 +1,528 @@ +% \CheckSum{236} +% \iffalse meta-comment +% forest-libs.dtx +%% `forest-libs' is a collection of libraries for package `forest'. +%% +%% Copyright (c) 2012-2017 Saso Zivanovic +%% (Sa\v{s}o \v{Z}ivanovi\'{c}) +%% saso.zivanovic@guest.arnes.si +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% +%% http://www.latex-project.org/lppl.txt +%% +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `author-maintained'. +%% +%% This file is a part of package `forest'. For the list of files +%% constituting the package see main source file of the package, +%% `forest.dtx', or the derived `forest.sty'. +%% +% \fi +% +% \section{Libraries} +% +% This chapter contains not only the reference of commands found in libraries and some examples of +% their usage, but also their definitions. This is done in the hope that these definitions, being +% mostly styles, will be useful as examples of the core features of the package. I even managed to +% comment them a bit \dots +% +% \paragraph{Disclaimer.} At least in the initial stages of a library's development, the function +% and interface of macros and keys defined in a library might change without backwards compatibility +% support! Though I'll try to keep this from happening \dots +% +% \begin{macrocode} +\RequirePackage{forest} +% \end{macrocode} +% +%\iffalse +%<*linguistics> +%\fi +% \librarysection{linguistics} +% \begin{macrocode} +\ProvidesForestLibrary{linguistics}[2017/07/14 v0.1.2] +% \end{macrocode} +% +% Defaults: +% \begin{macrocode} +\forestset{ + linguistics@set@baseline/.style={ + if phantom={for next node=linguistics@set@baseline}{baseline} + }, + libraries/linguistics/defaults/.style={ + default preamble={ +% \end{macrocode} +% Edges of the children will ``meet'' under the node: +% \begin{macrocode} + sn edges, +% \end{macrocode} +% The root of the tree will be aligned with the text \dots\ or, more commonly, the example number. +% More precisely, we actually align the first (in linear order) non-phantom node. This covers the +% common case of side-by-side trees joined with a phantom root. +% \begin{macrocode} + before drawing tree={ + if nodewalk valid={name=forest@baseline@node}{}{linguistics@set@baseline}, + }, +% \end{macrocode} +% Enable (centered) multi-line nodes. +% \begin{macrocode} + for tree={align=center}, + }, + }, +} +% \end{macrocode} +% +% There's no linguistics without c-command\footnote{The definition of c-command is as follows: a node c-commands its siblings and their descendants.} \dots +% \begin{syntax} +% \indexitem{step>c-commanded} Visit all the nodes c-commanded by the current node. +% \indexitem{step>c-commanders} Visit all the c-commanders of the current node, starting from the closest. +% +% \begin{forestexample}[tree bin=minipage,index={branch',c-commanded}] +% \begin{forest} +% [VP +% [DP[John]] +% [V' +% [V, draw, for c-commanded={draw,circle} +% [sent] +% ] +% [DP[Mary]] +% [DP[D[a]][NP[letter]]] +% ] +% ] +% \end{forest} +% \end{forestexample} +% +% See how \indexex{branch'} is used to define |c-commanded|, and how \indexex{while nodewalk valid} and \indexex{nodewalk key>fake} are combined in the definition of |c-commanders|. +% \begin{macrocode} +\forestset{ + define long step={c-commanded}{style}{branch'={siblings,descendants}}, + define long step={c-commanders}{style}{while nodewalk valid={parent}{siblings,fake=parent}}, +} +% \end{macrocode} +% +% |c-commanders| could also be defined using \indexex{branch}: +% \begin{lstlisting} +% branch={current and ancestors, siblings} +% \end{lstlisting} +% +% \indexitem{node key>sn edges} +% +% In linguistics, most people want the parent-child edge to go from the \emph{s}outh of the parent +% to the \emph{n}orth of the child. This is achieved by this (badly named) style, which makes the +% entire (sub)tree have such edges. +% +% \begin{forestexample} +% \begin{forest} +% sn edges +% [VP +% [DP] +% [V' +% [V] +% [DP] +% ] +% ] +% \end{forest} +% \end{forestexample} +% +% \begin{macrocode} +\forestset{ + sn edges/.style={ + for tree={ + parent anchor=children, child anchor=parent + } + }, +} +% \end{macrocode} +% +% A note on implementation. Despite its name, this style does not refer to the |south| and |north| +% anchor of the parent and the child node directly. If it did so, it would only work for trees with +% standard linguistic \index{grow}|=-90|. So we rather use \FoRest;'s growth direction based +% anchors: \index{anchor>children} always faces the children and \index{anchor>parent} always faces +% the parent, so the edge will always be between them, and the normal, upward growing trees will +% look good as well. +% +% \begin{forestexample}[index={anchor>south,anchor>north,option>parent anchor,option>child anchor}] +% \begin{forest} +% [bad![VP,no edge, for tree={grow=90, edge=red}, +% for tree={parent anchor=south, child anchor=north} % bad +% [DP][V'[V][DP]]]] +% \end{forest} +% \begin{forest} +% [good![VP, no edge, for tree={grow=90, edge=green}, +% ~sn edges~ % good! +% [DP][V'[V][DP]]]] +% \end{forest} +% \end{forestexample} +% +% \indexitem{node key>roof} Makes the edge to parent a triangular roof. +% \begin{macrocode} +\forestset{ + roof/.style={edge path'={% + (.parent first)--(!u.children)--(.parent last)--cycle + } + }, +} +% \end{macrocode} +% +% \indexitem{node key>nice empty nodes} +% +% We often need empty nodes: tree (\ref{ex:niceemptynodes}a) shows how they look like by default: +% ugly. +% +% First, we don't want the gaps: we change the shape of empty nodes to coordinate. We get tree +% (\ref{ex:niceemptynodes}b). +% +% Second, the empty nodes seem too close +% to the other (especially empty) nodes (this is a result of a small +% default |s_sep|). We could use a greater \index{s sep}, but a better solution seems +% to be to use |calign=fixed_angles|. The result is shown in (\ref{ex:niceemptynodes}c). +% +% However, at the transitions from empty to non-empty nodes, tree (\ref{ex:niceemptynodes}c) +% seems to zigzag (although the base points of the spine nodes +% are perfectly in line), and the edge to the empty node left to VP +% seems too long (it reaches to the level of VP's base, while we'd +% prefer it to stop at the same level as the edge to VP itself). The +% first problem is solved by substituting |fixed_angles| for +% |fixed_edge_angles|; the second one, by anchoring siblings of +% empty nodes at north. VoilĂ , (\ref{ex:niceemptynodes}d)! +% +% \begin{forestexample}[label=ex:niceemptynodes,layout=tree on bottom,index={fixed angles,fixed edge angles,calign,tree,delay,where option,content,for step,step>parent,step>children,option>anchor}] +% \forestset{ +% xlist/.style={ +% phantom, +% for children={no edge,replace by={[,append, +% delay={content/.wrap pgfmath arg={\csname @alph\endcsname{##1}.}{n()+#1}} +% ]}} +% }, +% xlist/.default=0 +% } +% \begin{forest} +% [,~xlist~, +% for tree={after packing node={s+=0.1pt}}, % hack!!! +% [CP, %(a) +% [][[][[][VP[DP[John]][V'[V[loves]][DP[Mary]]]]]]] +% [CP, delay={where content={}{shape=coordinate}{}} %(b) +% [][[][[][VP[DP[John]][V'[V[loves]][DP[Mary]]]]]]] +% [CP, for tree={calign=fixed angles}, %(c) +% delay={where content={}{shape=coordinate}{}} +% [][[][[][VP[DP[John]][V'[V[loves]][DP[Mary]]]]]]] +% [CP, ~nice empty nodes~ %(d) +% [][[][[][VP[DP[John]][V'[V[loves]][DP[Mary]]]]]]] +% ] +% \end{forest} +% \end{forestexample} +% +% \begin{macrocode} +\forestset{ + nice empty nodes/.style={ + for tree={calign=fixed edge angles}, + delay={where content={}{shape=coordinate, + for current and siblings={anchor=north}}{}} + }, +} +% \end{macrocode} +% +% \indexitem{node key>draw brackets} Outputs the bracket representation of the tree. +% \indexitem{node key>draw brackets compact} +% \itemnosep +% \indexitem{node key>draw brackets wide} These keys control whether the brackets have extra +% spaces around them (|wide|) or not (|compact|). +% \begin{macrocode} +\providecommand\text[1]{\mbox{\scriptsize#1}} +\forestset{ + draw brackets compact/.code={\let\drawbracketsspace\relax}, + draw brackets wide/.code={\let\drawbracketsspace\space}, + draw brackets/.style={ +% \end{macrocode} +% There's stuff to do both before (output the opening bracket and the content) and after (output the +% closing bracket) processing the children, so we use \indexex{for tree'}. +% \begin{macrocode} + for tree'={ + TeX={[% +% \end{macrocode} +% Complication: \index{content format} must be expanded in advance, to correctly process tabular environments implicitely loaded by \index{align}|=|\index{value of=align>center}, which is the default in this library. (Not that one would want a multiline output in the bracket representation, but it's better than crashing.) +% \begin{macrocode} + \edef\forestdrawbracketscontentformat{\foresteoption{content format}}% + }, + if n children=0{ + TeX={\drawbracketsspace\forestdrawbracketscontentformat\drawbracketsspace} + }{ + TeX={\textsubscript{\text{\forestdrawbracketscontentformat}}\drawbracketsspace} + }, + }{ + TeX={]\drawbracketsspace}, + } + }, + draw brackets wide +} +% \end{macrocode} +% \end{syntax} +% +% \subsubsection{GP1} +% +% \begin{syntax} +% \indexitem{node key>GP1} +% +% For Government Phonology (v1) representations. Here, the big trick +% is to evenly space $\times$s by having a large enough |outer_xsep| +% (adjustable), and then, before drawing (timing control option +% |before_drawing_tree|), setting |outer_xsep| back to 0pt. The last step +% is important, otherwise the arrows between $\times$s won't draw! +% +% An example of an ``embedded'' |GP1| style: +% \begin{forestexample}[layout=tree on bottom,index={where option,tier,for step,step>children,content,tikz,option>l,dimen+,no edge},index>={!}] +% \begin{forest} +% myGP1/.style={ +% ~GP1~, +% delay={where tier={x}{ +% for children={content=\textipa{##1}}}{}}, +% tikz={\draw[dotted](.south)-- +% (!1.north west)--(!l.north east)--cycle;}, +% for children={l+=5mm,no edge} +% } +% [VP[DP[John,tier=word,myGP1 +% [O[x[dZ]]] +% [R[N[x[6]]]] +% [O[x[n]]] +% [R[N[x]]] +% ]][V'[V[loves,tier=word,myGP1 +% [O[x[l]]] +% [R[N[x[a]]]] +% [O[x[v]]] +% [R[N[x]]] +% [O[x[z]]] +% [R[N[x]]] +% ]][DP[Mary,tier=word,myGP1 +% [O[x[m]]] +% [R[N[x[e]]]] +% [O[x[r]]] +% [R[N[x[i]]]] +% ]]]] +% \end{forest}% +% \end{forestexample} +% +% And an example of annotations. +% \begin{forestexample} +% \begin{forest}[,phantom,s sep=1cm +% [{[ei]}, GP1 +% [R[N[x[A,~el~[I,~head~,~associate=N~]]][x]]] +% ] +% [{[mars]}, GP1 +% [O[x[m]]] +% [R[N[x[a]]][x,~encircle~,densely dotted[r]]] +% [O[x,~encircle~,~govern=<~[s]]] +% [R,~fen~[N[x]]] +% ] +% ]\end{forest} +% \end{forestexample} +% +% \begin{macrocode} +\newbox\standardnodestrutbox +\setbox\standardnodestrutbox=\hbox to 0pt{\phantom{\forestOve{standard node}{content}}} +\def\standardnodestrut{\copy\standardnodestrutbox} +\forestset{ + GP1/.style 2 args={ + for n={1}{baseline}, + s sep=0pt, l sep=0pt, + for descendants={ + l sep=0pt, l={#1}, + anchor=base,calign=first,child anchor=north, + inner xsep=1pt,inner ysep=2pt,outer sep=0pt,s sep=0pt, + }, + delay={ + if content={}{phantom}{for children={no edge}}, + for tree={ + if content={O}{tier=OR}{}, + if content={R}{tier=OR}{}, + if content={N}{tier=N}{}, + if content={x}{ + tier=x,content={$\times$},outer xsep={#2}, + for tree={calign=center}, + for descendants={content format={\noexpand\standardnodestrut\forestoption{content}}}, + before drawing tree={outer xsep=0pt,delay={typeset node}}, + s sep=4pt + }{}, + }, + }, + before drawing tree={where content={}{parent anchor=center,child anchor=center}{}}, + }, + GP1/.default={5ex}{8.0pt}, + associate/.style={% + tikz+={\draw[densely dotted](!)--(!#1);}}, + spread/.style={ + before drawing tree={tikz+={\draw[dotted](!)--(!#1);}}}, + govern/.style={ + before drawing tree={tikz+={\draw[->](!)--(!#1);}}}, + p-govern/.style={ + before drawing tree={tikz+={\draw[->](.north) to[out=150,in=30] (!#1.north);}}}, + no p-govern/.style={ + before drawing tree={tikz+={\draw[->,loosely dashed](.north) to[out=150,in=30] (!#1.north);}}}, + encircle/.style={before drawing tree={circle,draw,inner sep=0pt}}, + fen/.style={pin={[font=\footnotesize,inner sep=1pt,pin edge=<-]10:\textsc{Fen}}}, + el/.style={content=\textsc{\textbf{##1}}}, + head/.style={content=\textsc{\textbf{\underline{##1}}}} +} +% \end{macrocode} +% \end{syntax} +%\iffalse +% +%\fi +% +% +% +%\iffalse +%<*edges> +%\fi +% \librarysection{edges} +% \begin{macrocode} +\ProvidesForestLibrary{edges}[2016/12/05 v0.1.1] +% \end{macrocode} +% +% \begin{syntax} +% +% \indexitem{node key>forked edge'} +% +% Sets a forked edge to the current node. Arbitrary growth direction and node rotation are +% supported. +% +% \indexitem{node key>forked edge} +% +% Like \index{forked edge'}, but it also sets \index{option>parent anchor} and \index{option>child +% anchor} to the likely values of \index{anchor>children} and \index{anchor>parent}, respectively. +% +% \indexitem(tree){node key>forked edges}|=|\meta{nodewalk} +% +% Invokes \index{forked edge} for all nodes in the \meta{nodewalk}, by default the entire (sub)tree +% rooted in the current node. +% +% \indexitem{option>fork sep} The \index{forest cs>l}-distance between the parent anchor and the +% fork. +% +% \end{syntax} +% +% \begin{forestexample}[index={for step,tree,grow',forked edges}] +% \begin{forest} +% for tree={grow'=0,draw}, +% forked edges, +% [/ +% [home +% [saso +% [Download] +% [TeX] +% ] +% [alja] +% [joe] +% ] +% [usr +% [bin] +% [share] +% ] +% ] +% \end{forest} +% \end{forestexample} +% +% See how growth direction based anchors \indexex{anchor>children} and \indexex{anchor>parent} are +% used in the definition below to easily take care of arbitrary \index{grow} and +% \index{rotate}. +% \begin{macrocode} +\forestset{ + declare dimen={fork sep}{0.5em}, + forked edge'/.style={ + edge={rotate/.option=!parent.grow}, + edge path'={(!u.parent anchor) -- ++(\forestoption{fork sep},0) |- (.child anchor)}, + }, + forked edge/.style={ + on invalid={fake}{!parent.parent anchor=children}, + child anchor=parent, + forked edge', + }, + forked edges/.style={for nodewalk={#1}{forked edge}}, + forked edges/.default=tree, +} +% \end{macrocode} +% +% \begin{syntax} +% \indexitem{node key>folder} The children of the node are drawn like folders. +% +% All growth directions are supported (well, cardinal directions work perfectly; the others await +% the sensitivity of packing to \index{edge path}), as well as node rotation and \index{reversed} +% order of children. +% +% The outlook of the folder can be influenced by setting standard \foRest;'s options \index{l sep} +% and \index{s sep} any time before packing, or \index{option>l} and \index{option>s} after +% packing. Setting \index{option>l} and \index{option>s} before packing will have no influence on +% the layout of the tree. +% +% \begin{syntax} +% \indexitem(.45em){register>folder indent}|=|\meta{dimen} +% +% Specifies the shift of the parent's side of the edge in the \index{forest cs>l}-direction. +% \end{syntax} +% +% \end{syntax} +% +% \begin{forestexample}[index={for step,tree,grow',folder}] +% \begin{forest} +% for tree={grow'=0,~folder~,draw} +% [/ +% [home +% [saso +% [Download] +% [TeX] +% ] +% [alja] +% [joe] +% ] +% [usr +% [bin] +% [share] +% ] +% ] +% \end{forest} +% \end{forestexample} +% \begin{macrocode} +\forestset{ + declare dimen register=folder indent, + folder indent=.45em, + folder/.style={ + parent anchor=-children last, + anchor=parent first, + calign=child, + calign primary child=1, + for children={ + child anchor=parent, + anchor=parent first, + edge={rotate/.option=!parent.grow}, + edge path'/.expanded={ + ([xshift=\forestregister{folder indent}]!u.parent anchor) |- (.child anchor) + }, + }, + after packing node={ + if n children=0{}{ + tempdiml=l_sep()-l("!1"), + tempdims={-abs(max_s("","")-min_s("",""))-s_sep()}, + for children={ + l+=tempdiml, + s+=tempdims()*(reversed()-0.5)*2, + }, + }, + }, + } +} +% \end{macrocode} +%\iffalse +% +%\fi +% \forestset{every index end/.style={}} +% \endinput +% Local Variables: +% mode: doctex +% TeX-command-default: "sty" +% fill-column: 100 +% TeX-master: "forest" +% End: -- cgit v1.2.3