Compare commits
7 Commits
master
...
georges-tr
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f110a36916 | ||
![]() |
1e15ba95f5 | ||
![]() |
6f02242bbb | ||
![]() |
d1970c9a83 | ||
![]() |
ca127548e1 | ||
![]() |
ea6f4ec8b9 | ||
![]() |
20355f9c01 |
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -7,3 +7,5 @@
|
|||
*.out
|
||||
*.toc
|
||||
*.lof
|
||||
travis-deploy-key-id_rsa
|
||||
travis-deploy-key-id_rsa.pub
|
||||
|
|
31
.travis.yml
Normal file
31
.travis.yml
Normal file
|
@ -0,0 +1,31 @@
|
|||
language: c
|
||||
sudo: false
|
||||
|
||||
env:
|
||||
- PATH="$HOME/texlive/bin/x86_64-linux:$PATH"
|
||||
|
||||
before_install:
|
||||
- true
|
||||
|
||||
install:
|
||||
- echo "Installing LaTeX and LaTeX packages."
|
||||
- curl -L -o texlive.tar.gz https://github.com/yihui/ubuntu-bin/releases/download/latest/texlive.tar.gz
|
||||
- tar -C "$HOME/" -zxf texlive.tar.gz
|
||||
- tlmgr update --self
|
||||
- tlmgr install newunicodechar mathpartir pgf pgfplots bera float cancel pgfopts elocalloc environ savesym bbding wasy wasysym epigraph
|
||||
- echo "Finished installing LaTeX and LaTeX packages."
|
||||
# ################## #
|
||||
# Actual LaTeX build #
|
||||
# ################## #
|
||||
- pdflatex -halt-on-error -interaction=nonstopmode main.tex
|
||||
- bibtex main
|
||||
- pdflatex -halt-on-error -interaction=nonstopmode main.tex
|
||||
- pdflatex -halt-on-error -interaction=nonstopmode main.tex
|
||||
- pdflatex -halt-on-error -interaction=nonstopmode main.tex
|
||||
# ################## #
|
||||
# End of LaTeX build #
|
||||
# ################## #
|
||||
- bash ./auto-push-gh-pages.sh
|
||||
|
||||
script:
|
||||
- true
|
8
README.md
Normal file
8
README.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
[](https://travis-ci.org/jsmaniac/journal-article)
|
||||
[](http://jsmaniac.github.io/travis-stats/#jsmaniac/journal-article)
|
||||
[](http://ajl-demo.fr/2016/)
|
||||
[](https://jsmaniac.github.io/journal-article-gh-pages/main.pdf)
|
||||
|
||||
# journal-article
|
||||
|
||||
This repository contains the LaTeX code for our upcoming journal article.
|
50
auto-push-gh-pages.sh
Executable file
50
auto-push-gh-pages.sh
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
set +x
|
||||
if test "$(git config remote.origin.url)" != "https://github.com/jsmaniac/journal-article.git"; then
|
||||
echo "Not on official repo, will not deploy gh-pages."
|
||||
elif test "$TRAVIS_PULL_REQUEST" != "false"; then
|
||||
echo "This is a Pull Request, will not deploy gh-pages."
|
||||
elif test "$TRAVIS_BRANCH" != "master"; then
|
||||
echo "Not on master branch (TRAVIS_BRANCH = $TRAVIS_BRANCH), will not deploy gh-pages."
|
||||
# A key can be created following the steps at https://docs.travis-ci.com/user/encrypting-files/ .
|
||||
# ssh-keygen -f travis-deploy-key-id_rsa -C 'Deploy key for travis-ci'
|
||||
# travis encrypt-file travis-deploy-key-id_rsa
|
||||
elif test -z "${encrypted_264397dfc790_key:-}" -o -z "${encrypted_264397dfc790_iv:-}"; then
|
||||
echo "Travis CI secure environment variables are unavailable, will not deploy gh-pages."
|
||||
else
|
||||
set -x
|
||||
echo "Automatic push to gh-pages"
|
||||
|
||||
# Git configuration:
|
||||
git config --global user.name "$(git log --format="%aN" HEAD -1) (Travis CI automatic commit)"
|
||||
git config --global user.email "$(git log --format="%aE" HEAD -1)"
|
||||
|
||||
# SSH configuration
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
set +x
|
||||
if openssl aes-256-cbc -K $encrypted_264397dfc790_key -iv $encrypted_264397dfc790_iv -in travis-deploy-key-id_rsa.enc -out travis-deploy-key-id_rsa -d >/dev/null 2>&1; then
|
||||
echo "Decrypted key successfully."
|
||||
else
|
||||
echo "Error while decrypting key."
|
||||
fi
|
||||
mv travis-deploy-key-id_rsa ~/.ssh/travis-deploy-key-id_rsa
|
||||
set -x
|
||||
chmod 600 ~/.ssh/travis-deploy-key-id_rsa
|
||||
set +x
|
||||
eval `ssh-agent -s`
|
||||
set -x
|
||||
ssh-add ~/.ssh/travis-deploy-key-id_rsa
|
||||
|
||||
TRAVIS_GH_PAGES_DIR="$HOME/travis-gh-pages-$(date +%s)"
|
||||
if test -e $TRAVIS_GH_PAGES_DIR; then rm -rf $TRAVIS_GH_PAGES_DIR; fi
|
||||
mkdir -p "$TRAVIS_GH_PAGES_DIR"
|
||||
mv -i main.pdf $TRAVIS_GH_PAGES_DIR/main.pdf
|
||||
git init $TRAVIS_GH_PAGES_DIR
|
||||
touch $TRAVIS_GH_PAGES_DIR/.nojekyll
|
||||
(cd $TRAVIS_GH_PAGES_DIR && git add -A . && git commit -m "Auto-publish to gh-pages") > commit.log || (cat commit.log && exit 1)
|
||||
(cd $TRAVIS_GH_PAGES_DIR && git log --oneline --decorate --graph -10)
|
||||
echo '(cd '"$TRAVIS_GH_PAGES_DIR"'; git push --force --quiet "git@github.com/jsmaniac/journal-article-gh-pages.git" master:gh-pages)'
|
||||
(cd $TRAVIS_GH_PAGES_DIR; git push --force --quiet "git@github.com:jsmaniac/journal-article-gh-pages.git" master:gh-pages >/dev/null 2>&1) >/dev/null 2>&1 # redirect to /dev/null to avoid showing credentials.
|
||||
fi
|
0
biblio.bib
Executable file → Normal file
0
biblio.bib
Executable file → Normal file
234
correlation-macros.tex
Normal file
234
correlation-macros.tex
Normal file
|
@ -0,0 +1,234 @@
|
|||
|
||||
%%Macros
|
||||
% This is the definition of meet_r
|
||||
\def\meetR{%
|
||||
\alignedmathop{%
|
||||
\bigwedge%
|
||||
}{%
|
||||
\mathchoice%
|
||||
{\bigwedge\mkern-0.5mu\smash{\raisebox{-0.9ex}{$\resetstyle\mathlarger{\mathlarger{{}_{\mathcal{R}}}}$}}}%
|
||||
{\bigwedge\mkern-1.5mu\smash{\raisebox{-0.6ex}{$\resetstyle\mathlarger{\mathlarger{{}_{\mathcal{R}}}}$}}}%
|
||||
{\bigwedge\mkern-2.25mu\smash{\raisebox{-0.3ex}{$\resetstyle\mathlarger{\mathlarger{{}_{\mathcal{R}}}}$}}}%
|
||||
{\bigwedge\mkern-2.5mu\smash{\raisebox{-0.35ex}{$\resetstyle\mathlarger{{}_{\mathcal{R}}}$}}}%
|
||||
}%
|
||||
}
|
||||
%
|
||||
% This is the definition of join_k
|
||||
\def\ijoin{%
|
||||
\alignedmathop{%
|
||||
\bigvee%
|
||||
}{%
|
||||
\mathchoice%
|
||||
{\bigvee\mkern-6mu\smash{\raisebox{-0.9ex}{$\resetstyle\mathlarger{\mathlarger{{}_{\mathcal{K}}}}$}}}%
|
||||
{\bigvee\mkern-5mu\smash{\raisebox{-0.6ex}{$\resetstyle\mathlarger{\mathlarger{{}_{\mathcal{K}}}}$}}}%
|
||||
{\bigvee\mkern-2.25mu\smash{\raisebox{-0.3ex}{$\resetstyle\mathlarger{\mathlarger{{}_{\mathcal{K}}}}$}}}%
|
||||
{\bigvee\mkern-2.5mu\smash{\raisebox{-0.35ex}{$\resetstyle\mathlarger{{}_{\mathcal{K}}}$}}}%
|
||||
}%
|
||||
}
|
||||
\def\largeijoin{%
|
||||
\alignedmathop{%
|
||||
\bigvee%
|
||||
}{%
|
||||
\mathchoice%
|
||||
{\bigvee\mkern-7mu\smash{\raisebox{-0.6ex}{$\resetstyle\mathlarger{{}_{\mathcal{K}}}$}}}%
|
||||
{\bigvee\mkern-5mu\smash{\raisebox{-0.6ex}{$\resetstyle\mathlarger{\mathlarger{{}_{\mathcal{K}}}}$}}}%
|
||||
{\bigvee\mkern-2.25mu\smash{\raisebox{-0.3ex}{$\resetstyle\mathlarger{\mathlarger{{}_{\mathcal{K}}}}$}}}%
|
||||
{\bigvee\mkern-2.5mu\smash{\raisebox{-0.35ex}{$\resetstyle\mathlarger{{}_{\mathcal{K}}}$}}}%
|
||||
}%
|
||||
}
|
||||
|
||||
|
||||
|
||||
%%For Tikz figures
|
||||
%%%%% Custom pattern definition (not my code):
|
||||
% defining the new dimensions
|
||||
\newlength{\hatchspread}
|
||||
\newlength{\hatchoffset}
|
||||
\newlength{\hatchthickness}
|
||||
% declaring the keys in tikz
|
||||
\tikzset{
|
||||
hatchspread/.code={\setlength{\hatchspread}{#1}},
|
||||
hatchoffset/.code={\setlength{\hatchoffset}{#1}},
|
||||
hatchthickness/.code={\setlength{\hatchthickness}{#1}}
|
||||
}
|
||||
% setting the default values
|
||||
\tikzset{
|
||||
hatchspread=.5cm,
|
||||
hatchoffset=0.4pt,
|
||||
hatchthickness=0.4pt
|
||||
}
|
||||
% declaring the pattern
|
||||
\pgfdeclarepatternformonly[\hatchspread,\hatchthickness]% variables
|
||||
{custom north east lines}% name
|
||||
{\pgfqpoint{-2\hatchthickness}{-2\hatchthickness}}% lower left corner
|
||||
{\pgfqpoint{\dimexpr\hatchspread+2\hatchthickness}{\dimexpr\hatchspread+2\hatchthickness}}% upper right corner
|
||||
{\pgfqpoint{\hatchspread}{\hatchspread}}% tile size
|
||||
{% shape description
|
||||
\pgfsetlinewidth{\hatchthickness}
|
||||
\pgfpathmoveto{\pgfqpoint{0pt}{\hatchoffset}}
|
||||
\pgfpathlineto{\pgfqpoint{\dimexpr\hatchspread-\hatchoffset}{\hatchspread}}
|
||||
\pgfpathmoveto{\pgfqpoint{\dimexpr\hatchspread-\hatchoffset}{0pt}}
|
||||
\pgfpathlineto{\pgfqpoint{\dimexpr\hatchspread}{\hatchoffset}}
|
||||
\pgfusepath{stroke}
|
||||
}
|
||||
%%%%% End custom pattern definition.
|
||||
|
||||
%\pgfmathparse{\year+\time+\currenthour+\currentminute*\currentsecond}
|
||||
\edef\rndseed{4101} %%%%% To choose a fixed seed
|
||||
%\edef\rndseed{\pgfmathresult} %%%%% Random seed
|
||||
\pgfmathsetseed{\rndseed}
|
||||
|
||||
\def\cellw{.7cm}
|
||||
\def\cellh{.8cm}
|
||||
\def\minth{.15cm}
|
||||
\def\vtpadding{.2cm}
|
||||
\def\vbpadding{.1cm}
|
||||
\def\hpadding{.05cm}
|
||||
\def\nbnodes{4}
|
||||
\def\minrand{0.3}
|
||||
\def\borderh{0.2cm}
|
||||
|
||||
\def\triangleArray#1#2{
|
||||
\foreach \i in {0,...,\nbnodes} {%
|
||||
\node[inner sep=0pt,minimum height=\cellh, minimum width=\cellw, alias=#1-last, anchor=north west, xshift=\i*\cellw] (#1-\i) at #2 {};
|
||||
|
||||
% Magic coordinate calculations
|
||||
% Fixed top position:
|
||||
\pgfmathsetmacro{\tpos}{0}
|
||||
% Random top position:
|
||||
% \pgfmathsetmacro{\tpos}{rnd*(1-\minrand)+\minrand}
|
||||
\pgfmathsetmacro{\trih}{rnd*(1-\minrand)+\minrand}
|
||||
\def\tposformula{(\vtpadding+\tpos*(\cellh-\minth-\vtpadding-\vbpadding))}
|
||||
\def\thformula{min(\trih*(\cellh-\tposformula-\vbpadding), \cellw*(1/.5555)*.5-2*\hpadding)}
|
||||
% Triangle:
|
||||
\draw #2 ++(\i*\cellw+.5*\cellw,{-\tposformula}) coordinate (#1-tt-\i) -- ++({.5555*\thformula},{-\thformula}) coordinate (#1-tr-\i) -- ++({-.5555*\thformula*2},0) coordinate (#1-tl-\i) -- cycle;
|
||||
\coordinate (#1-tc-\i) at (barycentric cs:#1-tt-\i=1,#1-tr-\i=1,#1-tl-\i=1);
|
||||
\coordinate (#1-tb-\i) at ($(#1-tl-\i)!.5!(#1-tr-\i)$);
|
||||
}
|
||||
|
||||
% \draw (#1-0.north west) ++(0,\borderh) -- ($(#1-last.north east)+(0,\borderh)$) -- (#1-last.south east) -- (#1-0.south west) -- cycle;
|
||||
% \draw (#1-0.north west) -- (#1-last.north east);
|
||||
|
||||
\draw (#1-last.north east) -- (#1-last.south east) -- (#1-0.south west) -- (#1-0.north west);
|
||||
\draw[fill=black!7] (#1-0.north west) -- (#1-last.north east) -- ++(0,\borderh) -- ($(#1-0.north west)+(0,\borderh)$) -- cycle;
|
||||
|
||||
\foreach \i in {1,...,\nbnodes} {
|
||||
\draw (#1-\i.north west) -- (#1-\i.south west);
|
||||
}
|
||||
}
|
||||
|
||||
%Leq for pequiv
|
||||
\def\rleq{\mathrel{\sqsubseteq_{\kern0.15pt\rdom}}}
|
||||
\def\rjoin{\mathrel{\vee_{\kern-0.25pt\rdom}}}
|
||||
\def\rmeet{\mathrel{\wedge_{\kern0.15pt\rdom}}}
|
||||
%\DeclareMathOperator*{\rbigwedge}{\bigwedge_\rdom}
|
||||
|
||||
|
||||
%Macros for pequiv relations
|
||||
\def\rdom{\mathscr{R}}
|
||||
\def\equal{\textsf{Equal}}
|
||||
\def\qmark{\textsf{Any}}
|
||||
|
||||
%\def\rel{\mathit{\mathcal{R}}}
|
||||
\def\rel{R}
|
||||
\newcommand{\srel}[2]{\{#1_1 \mapsto \rel_1; \ldots; #1_{#2} \mapsto \rel_{#2}\}}
|
||||
\newcommand{\sreljoin}[2]{\{#1_1 \mapsto \rel_1 \rjoin \rel'_1; \ldots; #1_{#2} \mapsto \rel_{#2} \rjoin \rel'_{#2} \}}
|
||||
\newcommand{\srelmeet}[2]{\{#1_1 \mapsto \rel_1 \rmeet \rel'_1; \ldots; #1_{#2} \mapsto \rel_{#2} \rmeet \rel'_{#2} \}}
|
||||
\newcommand{\sreli}[2]{\{#1_1 \mapsto \rel_1; \ldots; #1_i \mapsto \rel_i; \ldots; #1_{#2} \mapsto \rel_{#2}\}}
|
||||
\newcommand{\srelitop}[3]{\{#1_1 \mapsto \qmark; \ldots; #1_i \mapsto #3; \ldots; #1_{#2} \mapsto \qmark\}}
|
||||
\def\srelibot{\{f_1 \mapsto \equal; \ldots; f_i \mapsto \qmark; \ldots; f_n \mapsto \equal\}}
|
||||
|
||||
\newcommand{\vrel}[2]{[#1_1 \mapsto \rel_1; \ldots; #1_{#2} \mapsto \rel_{#2}]}
|
||||
\newcommand{\vreljoin}[2]{[#1_1 \mapsto \rel_1 \rjoin \rel'_1; \ldots; #1_{#2} \mapsto \rel_{#2} \rjoin \rel'_{#2}]}
|
||||
\newcommand{\vrelmeet}[2]{[#1_1 \mapsto \rel_1 \rmeet \rel'_1; \ldots; #1_{#2} \mapsto \rel_{#2} \rmeet \rel'_{#2}]}
|
||||
\newcommand{\vreli}[2]{[#1_1 \mapsto \rel_1; \ldots; #1_i \mapsto \rel_i; \ldots; #1_{#2} \mapsto \rel_{#2}]}
|
||||
\newcommand{\vrelitop}[3]{[#1_1 \mapsto \qmark; \ldots; #1_i \mapsto #3; \ldots; #1_{#2} \mapsto \qmark]}
|
||||
|
||||
|
||||
\newcommand{\arel}[1]{\langle #1 \rangle}
|
||||
\newcommand{\aerel}[3]{\left\langle #1 \triangleright #2: \; #3 \right\rangle}
|
||||
\newcommand{\aerelnoleftright}[3]{\langle #1 \triangleright #2: \; #3 \rangle}
|
||||
|
||||
\newcommand{\rels}{\srel{f}{n}}
|
||||
\newcommand{\relsi}{\sreli{f}{n}}
|
||||
\newcommand{\relv}{\vrel{C}{n}}
|
||||
\newcommand{\relvi}{\vreli{C}{n}}
|
||||
\newcommand{\rela}{\arel{\rel}}
|
||||
\newcommand{\relai}{\langle \rel_{\mathit{def}} \triangleright i \;: \; \rel_{\mathit{exc}} \rangle}
|
||||
\def\relaitop{\langle \equal \triangleright i \;: \; \qmark \rangle}
|
||||
|
||||
\newcommand{\srelv}[3]{\{#1_1 \mapsto #3_1; \ldots; #1_{#2} \mapsto #3_{#2}\}}
|
||||
\newcommand{\vrelv}[3]{[#1_1 \mapsto #3_1; \ldots; #1_{#2} \mapsto #3_{#2}]}
|
||||
|
||||
\newcommand{\semrel}[2]{\llbracket #1 \rrbracket^{#2}}
|
||||
|
||||
|
||||
%Projections on pequiv
|
||||
\def\fieldp{\textrm{\textsf{\emph{extr}}}_f}
|
||||
\def\consp{\textrm{\textsf{\emph{extr}}}_C}
|
||||
\def\allp{\textrm{\textsf{\emph{extr}}}_{\langle * \rangle}}
|
||||
\def\cellp{\textrm{\textsf{\emph{extr}}}_{\langle i \rangle}}
|
||||
\def\outp{\textrm{\textsf{\emph{extr}}}_{\langle * \setminus i \rangle}}
|
||||
|
||||
|
||||
%Macros for paths
|
||||
\def\pcell{\langle i \rangle}
|
||||
\def\pstruct{.f}
|
||||
\def\pvar{@C}
|
||||
\def\pempty{\widehat{\varepsilon}}
|
||||
\def\identical{\textsf{Identical}}
|
||||
\def\incompatible{\textsf{Incompatible}}
|
||||
\def\leftcase{\textsf{Left}}
|
||||
\def\rightcase{\textsf{Right}}
|
||||
\def\findl{\curlywedge}
|
||||
\def\append{\dblcolon}
|
||||
|
||||
%Macros for path operators:
|
||||
%\DeclareMathOperator{\pproj}{\rightsquigarrow}
|
||||
%\DeclareMathOperator{\pinj}{\curvearrowleft}
|
||||
|
||||
%Macros for correlations
|
||||
%\def\cor{\hat{\mathcal{C}}}
|
||||
\def\cor{\mathscr{K}}
|
||||
%\def\corv{\hat{c}}
|
||||
\def\corv{\kappa}
|
||||
\def\aleq{\mathrel{\hat{\sqsubseteq}}}
|
||||
%\DeclareMathOperator*{\ajoin}{\hat{\bigvee}}
|
||||
%\DeclareMathOperator*{\hatbigwedge}{\hat{\bigwedge}}
|
||||
\def\acompose{\mathop{\ocircle}}
|
||||
\def\raligned{\rel_{\aligned(\pi', \rho')}^{(\pi, \rho)}}
|
||||
\def\ralignedc{\rel_{\aligned\corv}^{(\pi, \rho)}}
|
||||
\def\ralignedv{\rel_{\aligned\corv_1}^{(\pi, \rho)}}
|
||||
\def\ralignedw{\rel_{\aligned\corv_2}^{(\pi, \rho)}}
|
||||
|
||||
%Macros for intra domains
|
||||
\def\ileq{\sqsubseteq_{\mathcal{K}}}
|
||||
%\def\ijoin{\bigvee_{\mathcal{K}}}
|
||||
\def\justif{\Vvdash}
|
||||
\def\aligned{\parallel}
|
||||
\def\intracor{K}
|
||||
\def\compose{\odot}
|
||||
|
||||
%Macros for equations
|
||||
\newcommand{\Ctransfer}[3]{\mathbb{C}^{#2}_{#3}(#1)}
|
||||
|
||||
\def\inter{\mathcal{K}_p}
|
||||
%Colors
|
||||
%\definecolor{indianred}{rgb}{0.8, 0.36, 0.36}
|
||||
\definecolor{iburg}{rgb}{0.75, 0.0, 0.2}
|
||||
|
||||
% hat math variables
|
||||
|
||||
\def\cptype{\ensuremath{\widehat{\Pi}}}
|
||||
\def\cpath{\ensuremath{\widehat{\pi}}}
|
||||
\def\crho{\ensuremath{\widehat{\rho}}}
|
||||
\def\csigma{\ensuremath{\widehat{\sigma}}}
|
||||
\def\calpha{\ensuremath{\widehat{\alpha}}}
|
||||
\def\cbeta{\ensuremath{\widehat{\beta}}}
|
||||
\def\cgamma{\ensuremath{\widehat{\gamma}}}
|
||||
\def\cdelta{\ensuremath{\widehat{\delta}}}
|
||||
|
||||
\def\kset{$\textrm{\emph{kill}}_\lambda$}
|
||||
\def\kseti{$\textrm{\emph{kill}}_i$}
|
||||
\def\ksettrue{$\textrm{\emph{kill}}_{\mathit{true}}$}
|
||||
\def\dls{c_{\lambda}^s}
|
190
forest-compat.sty
Normal file
190
forest-compat.sty
Normal file
|
@ -0,0 +1,190 @@
|
|||
% \CheckSum{12884}
|
||||
% \iffalse meta-comment
|
||||
% forest-index.dtx
|
||||
%% `forest-compat' defines a compatibility layer of package `forest'.
|
||||
%%
|
||||
%% Copyright (c) 2015 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'.
|
||||
|
||||
\ProvidesPackage{forest-compat}
|
||||
|
||||
\def\forest@deprecated#1{%
|
||||
\PackageWarning{forest}{Compatibility mode for #1}%
|
||||
}
|
||||
\forestset{@@deprecated/.code={\forest@deprecated{#1}}}
|
||||
\def\forestcompat#1{\pgfqkeys{/forest/@compat}{#1}}
|
||||
\forestcompat{
|
||||
silent/.style={\def\forest@deprecated##1{}},
|
||||
%%% begin listing region: compat_keys
|
||||
most/.style={1.0-most},
|
||||
all/.style={1.0-all},
|
||||
none/.style={},
|
||||
1.0-most/.style={
|
||||
1.0-triangle,1.0-linear,1.0-nodewalk,1.0-ancestors,
|
||||
1.0-fittotree,1.0-for,1.0-forall
|
||||
},
|
||||
1.0-all/.style={
|
||||
1.0-most,
|
||||
1.0-forstep,1.0-rotate,1.0-stages,1.0-name,
|
||||
2.0.2-all,
|
||||
},
|
||||
2.0.2-all/.style={
|
||||
2.0.2-delayn,2.0.2-wrapnpgfmathargs,
|
||||
},
|
||||
%%% end listing region: compat_keys
|
||||
1.0-triangle/.style={
|
||||
/forest/triangle/.style={
|
||||
@@deprecated={key "triangle" from v1.0.x. Use key "roof" from library "linguistics" instead},
|
||||
edge path'={%
|
||||
(.north west)--(!u.south)--(.north east)--cycle
|
||||
}
|
||||
}
|
||||
},
|
||||
1.0-linear/.style={
|
||||
/forest/define long step={linear next}{autostep}{%
|
||||
\forest@deprecated{nodewalk step "linear next" from v1.0. Use key "next node" instead.}%
|
||||
\edef\forest@cn{\forest@node@linearnextid}},
|
||||
/forest/define long step={linear previous}{autostep}{%
|
||||
\forest@deprecated{nodewalk step "linear previous" from v1.0. Use key "previous node" instead.}%
|
||||
\edef\forest@cn{\forest@node@linearpreviousid}},
|
||||
},
|
||||
1.0-nodewalk/.style={
|
||||
/forest/node walk/before walk/.style={},
|
||||
/forest/node walk/every step/.style={},
|
||||
/forest/node walk/after walk/.style={},
|
||||
/forest/node walk/.style={
|
||||
@@deprecated={key "node walk" from v1.0. Use key "nodewalk" instead.},
|
||||
/forest/node walk/before walk,
|
||||
/forest/nodewalk/before walk/.style={/forest/node walk/before walk},
|
||||
/forest/nodewalk/every step/.style={/forest/node walk/every step},
|
||||
/forest/nodewalk/after walk/.style={/forest/node walk/after walk},
|
||||
/forest/nodewalk/node walk/.style={before walk,for nodewalk={####1,options={/forest/nodewalk/after walk}}{/forest/nodewalk/every step}},
|
||||
for nodewalk={##1,options={/forest/nodewalk/after walk}}{/forest/nodewalk/every step},
|
||||
},
|
||||
},
|
||||
1.0-ancestors/.style={
|
||||
/forest/for ancestors'/.style={
|
||||
@@deprecated={key "for ancestors'" from v1.0.x. Use key "for current and ancestors" instead.},
|
||||
for current and ancestors={##1}},
|
||||
},
|
||||
1.0-fittotree/.style={%
|
||||
/tikz/fit to tree/.style={
|
||||
/forest/@@deprecated={key "/tikz/fit to tree" from v1.0.x. Use "/tikz/fit to=tree" instead.},
|
||||
inner sep=0pt,fit to=tree
|
||||
}
|
||||
},
|
||||
1.0-for/.style={
|
||||
/forest/for/.code 2 args={% #1 = nodewalk, #2 = after walk keylist
|
||||
\forest@deprecated{Key "for" from v1.0.x. Use key "for group" instead.}%
|
||||
\forest@forthis{\forest@nodewalk{##1,options={##2}}{}}%
|
||||
}
|
||||
},
|
||||
1.0-forall/.style={
|
||||
/forest/for all next/.style={
|
||||
@@deprecated={Key "for all next" from v1.0.x. Use key "for following siblings" instead.},
|
||||
for following siblings={##1}},
|
||||
/forest/for all previous/.style={
|
||||
@@deprecated={Key "for all previous" from v1.0.x. Use key "for preceding siblings" instead.},
|
||||
for preceding siblings={##1}},
|
||||
},
|
||||
1.0-forstep/.code={%
|
||||
\def\forest@forstepwrapper##1##2{%
|
||||
\def\forest@nodewalk@config@everystep@method{independent}%
|
||||
\def\forest@nodewalk@config@history@method{independent}%
|
||||
\edef\forest@marshal{%
|
||||
\def\noexpand\forest@nodewalk@config@oninvalid{compatfake}%
|
||||
\unexpanded{\forest@Nodewalk{##1}{##2}}%
|
||||
\def\noexpand\forest@cn{\forest@cn}%
|
||||
\def\noexpand\forest@nodewalk@config@oninvalid{\forest@nodewalk@config@oninvalid}%
|
||||
}\forest@marshal
|
||||
}%
|
||||
\def\forest@relatednode@option@compat@ignoreinvalidsteps##1{%
|
||||
\forest@saveandrestoremacro\forest@nodewalk@oninvalid{%
|
||||
\def\forest@nodewalk@oninvalid{compatfake}%
|
||||
##1%
|
||||
}%
|
||||
}%
|
||||
},
|
||||
1.0-rotate/.style={
|
||||
/forest/undef option=rotate,
|
||||
rotate/.style={
|
||||
@@deprecate={Using non-autoforwarded key "rotate". Some keys, like "forked edges" and "folder", might produce a wrong result.},
|
||||
node options={rotate={##1}},
|
||||
},
|
||||
},
|
||||
1.0-stages/.style={
|
||||
/forest/@@deprecated={Using v1.0.x "stages" style},
|
||||
/forest/stages/.style={
|
||||
process keylist=before typesetting nodes,
|
||||
typeset nodes stage,
|
||||
process keylist=before packing,
|
||||
pack stage,
|
||||
process keylist=before computing xy,
|
||||
compute xy stage,
|
||||
process keylist=before drawing tree,
|
||||
draw tree stage,
|
||||
},
|
||||
/forest/TeX={%
|
||||
\def\forest@defstages##1{%
|
||||
\def\forest@stages{%
|
||||
begin forest,
|
||||
for root'={
|
||||
process keylist register=default preamble,
|
||||
process keylist register=preamble
|
||||
},
|
||||
process keylist=given options,
|
||||
##1,
|
||||
end forest
|
||||
}%
|
||||
}%
|
||||
},
|
||||
},
|
||||
1.0-name/.code={%
|
||||
\forest@deprecated{key "name": using key "name" from v1.0.x, which does not enforce uniqueness. If you really need this, you're doing something wrong.}%
|
||||
\def\forest@node@setname##1{%
|
||||
\ifstrempty{##1}{}{%
|
||||
\forestoeset{name}{##1}%
|
||||
\csedef{forest@id@of@##1}{\forest@cn}%
|
||||
}%
|
||||
}%
|
||||
\def\forest@node@setalias##1{%
|
||||
\ifstrempty{##1}{}{%
|
||||
\csedef{forest@id@of@##1}{\forest@cn}%
|
||||
}%
|
||||
}%
|
||||
},
|
||||
2.0.2-delayn/.style={
|
||||
/forest/delay@n/.style 2 args={
|
||||
@@deprecated={propagator "delay n" (it introduces two levels of hash doubling)},
|
||||
if={##1==1}{delay={##2}}{delay={delay@n/.wrap pgfmath arg={{####1}{##2}}{##1-1}}}
|
||||
},
|
||||
},
|
||||
2.0.2-wrapnpgfmathargs/.code={
|
||||
\def\forest@wrap@pgfmath@args@@@wrapandpasson{%
|
||||
\forest@deprecated{handler "wrap n pgfmath args" (it introduces two levels of hash doubling)}%
|
||||
\expandafter\expandafter\expandafter\def
|
||||
\expandafter\expandafter\expandafter\forest@wrapped
|
||||
\expandafter\expandafter\expandafter{%
|
||||
\expandafter\forest@wrap@code\forest@wrap@args}%
|
||||
\expandafter\pgfkeysalso\expandafter{\expandafter\pgfkeyscurrentpath\expandafter=\expandafter{\forest@wrapped}}%
|
||||
}%
|
||||
},
|
||||
}
|
||||
\expandafter\forestcompat\expandafter{\forest@compat}
|
240
forest-doc.sty
Normal file
240
forest-doc.sty
Normal file
|
@ -0,0 +1,240 @@
|
|||
%% forest-doc.sty
|
||||
%% `forest-doc.sty` is an auxiliary package needed to compile the documentation of package `forest`.
|
||||
%%
|
||||
%% Copyright (c) 2015 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'.
|
||||
%%
|
||||
\ProvidesPackage{forest-doc}
|
||||
\RequirePackage{lstdoc}
|
||||
\RequirePackage{pgfkeys}
|
||||
\RequirePackage{forest-index}
|
||||
% if you want index support, load package "forest-index", but later
|
||||
|
||||
\lstset{language={[LaTeX]TeX},tabsize=4,gobble=2,%
|
||||
basicstyle=\small\ttfamily,basewidth=0.51em,boxpos=c,pointstyle=\pstyle,moredelim=[is][\pstyle]{~}{~}}
|
||||
%\lst@InstallKeywords{p}{point}{pointstyle}\relax{keywordstyle}{}ld
|
||||
\def\pstyle{\color{darkgreen}}
|
||||
\def\itemnosep{\vspace{-1.4ex}}
|
||||
\lstset{
|
||||
rangebeginprefix=\ \ \%\%\%\ begin\ listing\ region:\ ,
|
||||
rangebeginsuffix=,
|
||||
rangeendprefix=\ \ \%\%\%\ end\ listing\ region:\ ,
|
||||
rangeendsuffix=,
|
||||
includerangemarker=false,
|
||||
keepspaces=true,
|
||||
}
|
||||
\newcommand\lstinputregion[3][]{\lstinputlisting[linerange=#3-#3,#1]{#2}}
|
||||
\def\lst@outputspace{{\ifx\lst@bkgcolor\empty\color{white}\else\lst@bkgcolor\fi\lst@visiblespace}}% this works for acroread, but not for atril :-(
|
||||
|
||||
\lstnewenvironment{forestexample}[1][]{%
|
||||
\PackageWarning{forest-doc}{Compiling example}{}%
|
||||
\global\let\lst@intname\@empty
|
||||
\gdef\lst@sample{}%
|
||||
\def\forestexample@layout{tree on left}%
|
||||
\def\forestexample@treebin{box}%
|
||||
\pgfqkeys{/forestexample}{label format,#1}%
|
||||
\pgfkeysgetvalue{/forestexample/counter}\forestexample@temp
|
||||
\ifdefempty\forestexample@temp{}{\addtocounter{\forestexample@temp}{1}}%
|
||||
\setbox\lst@samplebox=\hbox\bgroup
|
||||
\pgfkeysvalueof{/forestexample/tree prefix}%
|
||||
\lst@BeginAlsoWriteFile{\jobname.tmp}%
|
||||
}{%
|
||||
\lst@EndWriteFile
|
||||
\pgfkeysvalueof{/forestexample/tree suffix}%
|
||||
\egroup
|
||||
\global\setbox\codebox=\box\lst@samplebox
|
||||
\global\setbox
|
||||
\treebox
|
||||
\csname forestexample@treebin@\forestexample@treebin\endcsname
|
||||
\pgfkeys{/forestexample/do layout/.expanded=\forestexample@layout}%
|
||||
}
|
||||
\pgfqkeys{/forestexample}{%
|
||||
.unknown/.code={\lstset{\pgfkeyscurrentname={#1}}},
|
||||
index/.code={\indexex[not print]{#1}},
|
||||
index>/.code={\indexex[not print]>{#1}},
|
||||
code prefix/.code={\gdef\lst@sample{#1}},
|
||||
tree prefix/.initial={},
|
||||
tree suffix/.initial={},
|
||||
counter/.initial=lstlisting,
|
||||
no label/.style={counter={}},
|
||||
label format/.store in=\@currentlabel,
|
||||
label format/.default={\arabic{\pgfkeysvalueof{/forestexample/counter}}},
|
||||
tree width/.initial={\dimexpr\linewidth-\wd\codebox-
|
||||
\glueexpr\pgfkeysvalueof{/forestexample/center skip}\relax\relax},
|
||||
layout/.store in=\forestexample@layout,
|
||||
tree bin/.store in=\forestexample@treebin,
|
||||
do layout/.is choice,
|
||||
do layout/export/.code={%
|
||||
\pgfkeysgetvalue{/forestexample/counter}\forestexample@temp
|
||||
\ifdefempty\forestexample@temp{}{\addtocounter{\forestexample@temp}{-1}}%
|
||||
},
|
||||
left skip/.initial={\glueexpr 0pt plus .4\linewidth minus \marginparsep + 0pt minus \@totalleftmargin + 0pt minus .75\marginparwidth},
|
||||
center skip/.initial={3em plus 0.1\linewidth minus 2em},
|
||||
right skip/.initial={0pt plus .4\linewidth},
|
||||
tree left skip/.initial=0pt,
|
||||
tree right skip/.initial=0pt,
|
||||
code left skip/.initial=0pt,
|
||||
code right skip/.initial=0pt,
|
||||
label y offset/.initial={\height-1ex}, % looks better to me this way
|
||||
do layout/tree on left/.code={%
|
||||
\begin{list}{}{\leftmargin 0pt}
|
||||
\item
|
||||
\@tempdima=\ifdim\totalht\treebox>\totalht\codebox
|
||||
\dimexpr0.5 \totalht\treebox\relax
|
||||
\else
|
||||
\dimexpr0.5 \totalht\codebox\relax
|
||||
\fi
|
||||
\mbox{%
|
||||
\mbox{\hbox to \linewidth{%
|
||||
\hskip\pgfkeysvalueof{/forestexample/left skip}\relax
|
||||
\textvcenter{\box\treebox}%
|
||||
\hskip\pgfkeysvalueof{/forestexample/center skip}\relax
|
||||
\hbox{\hskip-\@totalleftmargin\box\codebox\hskip\@totalleftmargin}%
|
||||
\hskip\pgfkeysvalueof{/forestexample/right skip}\relax
|
||||
}}%
|
||||
\forestexample@label
|
||||
}%
|
||||
\end{list}
|
||||
},
|
||||
v sep/.initial={1ex},
|
||||
align/.initial=center,
|
||||
do layout/tree on top/.code={%
|
||||
\begin{list}{}{\leftmargin 0pt \parsep 0pt \itemsep \pgfkeysvalueof{/forestexample/v sep}\relax}
|
||||
\item \forestexample@align{tree}\forestexample@label
|
||||
\item \forestexample@align{code}
|
||||
\end{list}
|
||||
},
|
||||
do layout/tree on bottom/.code={%
|
||||
\begin{list}{}{\leftmargin 0pt \parsep 0pt \itemsep \pgfkeysvalueof{/forestexample/v sep}\relax}
|
||||
\item \forestexample@align{code}\forestexample@label
|
||||
\item \forestexample@align{tree}
|
||||
\end{list}
|
||||
},
|
||||
do layout/only tree/.code={%
|
||||
\forestexample@align{tree}\forestexample@label
|
||||
},
|
||||
do layout/only code/.code={%
|
||||
\forestexample@align{code}\forestexample@label
|
||||
},
|
||||
}
|
||||
\newbox\treebox
|
||||
\newbox\codebox
|
||||
\def\forestexample@treebin@box{%
|
||||
\hbox{\lst@sampleInput}%
|
||||
}
|
||||
\def\forestexample@treebin@minipage{%
|
||||
\hbox{%
|
||||
\begin{minipage}{\pgfkeysvalueof{/forestexample/tree width}}%
|
||||
\lst@sampleInput
|
||||
\end{minipage}%
|
||||
}%
|
||||
}
|
||||
\def\forestexample@label{%
|
||||
\pgfkeysgetvalue{/forestexample/counter}\forestexample@temp
|
||||
\ifdefempty\forestexample@temp{}{%
|
||||
\makebox[0pt][l]{%
|
||||
\hskip-\linewidth
|
||||
\hskip-\@totalleftmargin
|
||||
\hskip\textwidth
|
||||
\hskip\marginparsep
|
||||
\raisebox
|
||||
{\dimexpr\@tempdima+\depth-\pgfkeysvalueof{/forestexample/label y offset}}%
|
||||
{\hbox to 0pt{\scriptsize(\@currentlabel)}}%
|
||||
}%
|
||||
}%
|
||||
}
|
||||
\def\forestexample@align#1{%
|
||||
\pgfkeysgetvalue{/forestexample/align}\forestexample@temp
|
||||
\mbox{\hbox to \linewidth{%
|
||||
\csname forestexample@align@left@\forestexample@temp\endcsname
|
||||
\hspace*{\pgfkeysvalueof{/forestexample/#1 left skip}}%
|
||||
\mbox{\expandafter\box\csname #1box\endcsname}%
|
||||
\hspace*{\pgfkeysvalueof{/forestexample/#1 right skip}}%
|
||||
\csname forestexample@align@right@\forestexample@temp\endcsname
|
||||
}}%
|
||||
}
|
||||
\def\forestexample@align@left@left{}
|
||||
\def\forestexample@align@right@left{}
|
||||
\def\forestexample@align@left@right{\hfill}
|
||||
\def\forestexample@align@right@right{}
|
||||
\def\forestexample@align@left@center{\hfill}
|
||||
\def\forestexample@align@right@center{\hfill}
|
||||
\newcommand\forestexampleimport[1][]{%
|
||||
\def\forestexample@layout{tree on left}%
|
||||
\pgfkeysgetvalue{/forestexample/counter}\forestexample@temp
|
||||
\ifdefempty\forestexample@temp{}{\addtocounter{\forestexample@temp}{1}}%
|
||||
\pgfqkeys{/forestexample}{%
|
||||
label format,
|
||||
do layout/.expanded=\forestexample@layout
|
||||
}%
|
||||
}
|
||||
|
||||
\def\totalht#1{\dimexpr\ht#1 + \dp#1\relax}
|
||||
\def\textvcenter#1{\raisebox{\dimexpr .5\depth-.5\height}{#1}}
|
||||
|
||||
% For some reason, lstdoc's version kills all spaces in defaults ...
|
||||
\def\lst@syntaxlabel@#1>#2\relax
|
||||
%{\edef\lst@temp{\zap@space#2 \@empty}}
|
||||
{\edef\lst@temp{#2}}
|
||||
|
||||
|
||||
|
||||
|
||||
\def\getforestversion#1/#2/#3 v#4 #5\getforestversion{v#4}
|
||||
\edef\forestversion{%
|
||||
\expandafter\expandafter\expandafter\getforestversion
|
||||
\csname ver@forest.sty\endcsname\getforestversion}
|
||||
|
||||
\def\settodayfromforestdateA#1/#2/#3 v#4 #5\settodayfromforestdateA{\def\year{#1}\def\month{#2}\def\day{#3}}
|
||||
\def\settodayfromforestdate{\expandafter\expandafter\expandafter\settodayfromforestdateA\csname ver@forest.sty\endcsname\settodayfromforestdateA}
|
||||
|
||||
\def\TikZ;{{\rm Ti\emph{k}Z}}
|
||||
\def\PGF;{\textsc{pgf}}
|
||||
\def\foRest;{\textsc{Forest}}
|
||||
\def\FoRest;{\textsc{Forest}}
|
||||
|
||||
\let\keyname\texttt
|
||||
\newcommand\cmdname[1]{\texttt{\char\escapechar#1}}
|
||||
|
||||
\gdef\greaterthan{>}
|
||||
\def\gobbleone#1{}
|
||||
|
||||
\newcommand{\Repeat}[1]{% from tex.se http://tex.stackexchange.com/a/16194/16819
|
||||
\expandafter\@Repeat\expandafter{\the\numexpr #1\relax}%
|
||||
}
|
||||
\def\@Repeat#1{%
|
||||
\ifnum#1>0
|
||||
\expandafter\@@Repeat\expandafter{\the\numexpr #1-1\expandafter\relax\expandafter}%
|
||||
\else
|
||||
\expandafter\@gobble
|
||||
\fi
|
||||
}
|
||||
\def\@@Repeat#1#2{%
|
||||
\@Repeat{#1}{#2}#2%
|
||||
}
|
||||
\def\spaces#1{\Repeat{#1}\space}
|
||||
|
||||
|
||||
%%% Local Variables:
|
||||
%%% mode: latex
|
||||
%%% fill-column: 100
|
||||
%%% TeX-command-default: "Make PDF"
|
||||
%%% TeX-master: "forest-doc"
|
||||
%%% End:
|
74
forest-lib-edges.sty
Normal file
74
forest-lib-edges.sty
Normal file
|
@ -0,0 +1,74 @@
|
|||
%%
|
||||
%% This is file `forest-lib-edges.sty',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% forest-libs.dtx (with options: `edges')
|
||||
%%
|
||||
%% `forest-libs' is a collection of libraries for package `forest'.
|
||||
%%
|
||||
%% Copyright (c) 2015 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'.
|
||||
%%
|
||||
\RequirePackage{forest}
|
||||
\ProvidesForestLibrary{edges}[2015/11/14 v0.1]
|
||||
\forestset{
|
||||
declare dimen={fork sep}{0.5em},
|
||||
forked edge/.style={
|
||||
edge={rotate/.pgfmath=grow()},
|
||||
edge path'={(!u.parent anchor) -- ++(\forestoption{fork sep},0) |- (.child anchor)},
|
||||
},
|
||||
forked edges/.style={
|
||||
for tree={parent anchor=children},
|
||||
for descendants={child anchor=parent,forked edge}
|
||||
},
|
||||
}
|
||||
\forestset{
|
||||
declare dimen register=folder indent,
|
||||
folder indent=.45em,
|
||||
folder/.style={
|
||||
parent anchor=parent last,
|
||||
anchor=parent first,
|
||||
calign=child,
|
||||
calign primary child=1,
|
||||
for children={
|
||||
child anchor=parent,
|
||||
anchor=parent first,
|
||||
edge={rotate/.pgfmath=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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `forest-lib-edges.sty'.
|
133
forest-lib-linguistics.sty
Normal file
133
forest-lib-linguistics.sty
Normal file
|
@ -0,0 +1,133 @@
|
|||
%%
|
||||
%% This is file `forest-lib-linguistics.sty',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% forest-libs.dtx (with options: `linguistics')
|
||||
%%
|
||||
%% `forest-libs' is a collection of libraries for package `forest'.
|
||||
%%
|
||||
%% Copyright (c) 2015 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'.
|
||||
%%
|
||||
\RequirePackage{forest}
|
||||
\ProvidesForestLibrary{linguistics}[2015/11/14 v0.1]
|
||||
\forestset{
|
||||
libraries/linguistics/defaults/.style={
|
||||
default preamble={
|
||||
sn edges,
|
||||
baseline,
|
||||
for tree={align=center},
|
||||
},
|
||||
},
|
||||
}
|
||||
\forestset{
|
||||
define long step={c-commanded}{style}{branch'={siblings,descendants}},
|
||||
define long step={c-commanders}{style}{while nodewalk valid={parent}{siblings,fake=parent}},
|
||||
}
|
||||
\forestset{
|
||||
sn edges/.style={
|
||||
for tree={
|
||||
parent anchor=children, child anchor=parent
|
||||
}
|
||||
},
|
||||
}
|
||||
\forestset{
|
||||
roof/.style={edge path'={%
|
||||
(.parent first)--(!u.children)--(.parent last)--cycle
|
||||
}
|
||||
},
|
||||
}
|
||||
\forestset{
|
||||
nice empty nodes/.style={
|
||||
for tree={calign=fixed edge angles},
|
||||
delay={where content={}{shape=coordinate,for parent={
|
||||
for children={anchor=north}}}{}}
|
||||
},
|
||||
}
|
||||
\providecommand\text[1]{\mbox{\scriptsize#1}}
|
||||
\forestset{
|
||||
draw brackets compact/.code={\let\drawbracketsspace\relax},
|
||||
draw brackets wide/.code={\let\drawbracketsspace\space},
|
||||
draw brackets/.style={
|
||||
for tree'={
|
||||
TeX={[%
|
||||
\edef\forestdrawbracketscontentformat{\foresteoption{content format}}%
|
||||
},
|
||||
if n children=0{
|
||||
TeX={\drawbracketsspace\forestdrawbracketscontentformat\drawbracketsspace}
|
||||
}{
|
||||
TeX={\textsubscript{\text{\forestdrawbracketscontentformat}}\drawbracketsspace}
|
||||
},
|
||||
}{
|
||||
TeX={]\drawbracketsspace},
|
||||
}
|
||||
},
|
||||
draw brackets wide
|
||||
}
|
||||
\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}}}}
|
||||
}
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `forest-lib-linguistics.sty'.
|
7497
forest.sty
Normal file
7497
forest.sty
Normal file
File diff suppressed because it is too large
Load Diff
125
growingwave.sty
Normal file
125
growingwave.sty
Normal file
|
@ -0,0 +1,125 @@
|
|||
\def\pgfdecorationgrowthstart{0cm}
|
||||
\def\pgfdecorationgrowthendsizelist{0cm}
|
||||
\def\pgfdecorationgrowthwavelengthlist{0cm}
|
||||
\def\pgfdecorationgrowthendstepslist{1}
|
||||
\def\pgfdecorationgrowthendstep{1}
|
||||
\newif\ifpgfdecorationgrowthsine
|
||||
\newif\ifpgfdecorationgrowthcosine
|
||||
\newif\ifpgfdecorationonewavelength
|
||||
\pgfdecorationgrowthcosinefalse
|
||||
\pgfdecorationgrowthsinetrue
|
||||
\pgfkeys{%
|
||||
/pgf/decoration/.cd,
|
||||
growth start size/.initial=0.5cm,
|
||||
growth end size/.initial=3cm,
|
||||
growth end steps/.initial=1,
|
||||
growth wave length/.initial=3pt,
|
||||
growth sine/.code={\pgfdecorationgrowthsinetrue\pgfdecorationgrowthcosinefalse},
|
||||
growth cosine/.code={\pgfdecorationgrowthsinefalse\pgfdecorationgrowthcosinetrue}
|
||||
}
|
||||
\def\pgfdecorationgrowthsetup{%
|
||||
\global\edef\pgfdecorationgrowthstart{\pgfkeysvalueof{/pgf/decoration/growth start size}}%
|
||||
\global\edef\pgfdecorationgrowthendsizelist{\pgfkeysvalueof{/pgf/decoration/growth end size}}%
|
||||
\global\edef\pgfdecorationgrowthendstepslist{\pgfkeysvalueof{/pgf/decoration/growth end steps}}%
|
||||
\global\edef\pgfdecorationgrowthwavelengthlist{\pgfkeysvalueof{/pgf/decoration/growth wave length}}%
|
||||
}
|
||||
|
||||
\def\pgfdecorationgrowthsteps{1} % To keep track of steps from ending
|
||||
\def\pgfdecorationliststeps{2} % To keep track of list items from ending, has to start from 2
|
||||
|
||||
\pgfdeclaredecoration{growth wave}{initial}%
|
||||
{
|
||||
\state{initial}[width=0pt,next state=first] {%
|
||||
\pgfdecorationgrowthsetup%
|
||||
\pgfpathlineto{\pgfqpoint{0pt}{0pt}}%
|
||||
\global\edef\pgfdecorationgrowthsteps{0}%
|
||||
\global\edef\pgfdecorationliststeps{2}%
|
||||
\foreach \endsize in \pgfdecorationgrowthendsizelist {%
|
||||
\global\edef\pgfdecorationgrowthendsize{\endsize}%
|
||||
\breakforeach%
|
||||
}%
|
||||
\foreach \growthstep in \pgfdecorationgrowthendstepslist {%
|
||||
\global\edef\pgfdecorationgrowthendstep{\growthstep}%
|
||||
\breakforeach%
|
||||
}%
|
||||
\foreach \wavelength in \pgfdecorationgrowthwavelengthlist {%
|
||||
\global\edef\pgfdecorationgrowthwavelength{\wavelength}%
|
||||
\breakforeach%
|
||||
}%
|
||||
\pgfmathparse{(\pgfdecorationgrowthendsize - \pgfdecorationgrowthstart) * 2 * %
|
||||
\pgfdecorationgrowthwavelength / ( \pgfdecoratedremainingdistance * \pgfdecorationgrowthendstep)}%
|
||||
\global\edef\pgfdecorationgrowth{\pgfmathresult}%
|
||||
}%
|
||||
|
||||
\state{first}[width=2*\pgfdecorationgrowthwavelength,next state=second] {%
|
||||
\pgfdecorationgrowthstepcounters%
|
||||
\pgfmathparse{\pgfdecorationgrowthstart + \pgfdecorationgrowthsteps * \pgfdecorationgrowth}%
|
||||
% The wave starts
|
||||
\ifpgfdecorationgrowthsine%
|
||||
\pgfpathsine{\pgfqpoint{\pgfdecorationgrowthwavelength}{\pgfmathresult pt}}%
|
||||
\pgfpathcosine{\pgfqpoint{\pgfdecorationgrowthwavelength}{-\pgfmathresult pt}}%
|
||||
\fi%
|
||||
\ifpgfdecorationgrowthcosine%
|
||||
\pgfpathsine{\pgfqpoint{\pgfdecorationgrowthwavelength}{-\pgfmathresult pt}}%
|
||||
\pgfpathcosine{\pgfqpoint{\pgfdecorationgrowthwavelength}{\pgfmathresult pt}}%
|
||||
\fi%
|
||||
\pgfdecorationgrowthstateend%
|
||||
}%
|
||||
|
||||
\state{second}[width=2*\pgfdecorationgrowthwavelength,next state=first] {%
|
||||
\pgfdecorationgrowthstepcounters%
|
||||
\pgfmathparse{\pgfdecorationgrowthstart + \pgfdecorationgrowthsteps * \pgfdecorationgrowth}%
|
||||
% The wave continues
|
||||
\ifpgfdecorationgrowthsine%
|
||||
\pgfpathsine{\pgfqpoint{\pgfdecorationgrowthwavelength}{-\pgfmathresult pt}}%
|
||||
\pgfpathcosine{\pgfqpoint{\pgfdecorationgrowthwavelength}{\pgfmathresult pt}}%
|
||||
\fi%
|
||||
\ifpgfdecorationgrowthcosine%
|
||||
\pgfpathsine{\pgfqpoint{\pgfdecorationgrowthwavelength}{\pgfmathresult pt}}%
|
||||
\pgfpathcosine{\pgfqpoint{\pgfdecorationgrowthwavelength}{-\pgfmathresult pt}}%
|
||||
\fi%
|
||||
\pgfdecorationgrowthstateend%
|
||||
}
|
||||
\state{final} {%
|
||||
\pgfpathlineto{\pgfpointdecoratedpathlast}%
|
||||
}%
|
||||
}
|
||||
\def\pgfdecorationgrowthstateend{%
|
||||
\pgfmathadd{\pgfdecorationgrowthsteps}{1}%
|
||||
\global\edef\pgfdecorationgrowthsteps{\pgfmathresult} % Redefine the steps counter, globally.
|
||||
}
|
||||
|
||||
\def\pgfdecorationgrowthstepcounters{%
|
||||
\pgfmathparse{\pgfdecorationgrowthendstep * \pgfdecoratedpathlength}
|
||||
\ifdim\pgfdecoratedcompleteddistance>\pgfmathresult pt%
|
||||
\foreach \endsize [count=\count] in \pgfdecorationgrowthendsizelist {%
|
||||
\ifnum\count=\pgfdecorationliststeps%
|
||||
\global\edef\pgfdecorationgrowthendsize{\endsize}%
|
||||
\breakforeach%
|
||||
\else%
|
||||
\global\edef\pgfdecorationgrowthstart{\endsize}%
|
||||
\fi%
|
||||
}%
|
||||
\global\edef\tempa{0}%
|
||||
\foreach \growthstep [count=\count] in \pgfdecorationgrowthendstepslist {%
|
||||
\ifnum\count=\pgfdecorationliststeps%
|
||||
\global\edef\pgfdecorationgrowthendstep{\growthstep}%
|
||||
\breakforeach%
|
||||
\else%
|
||||
\global\edef\tempa{\growthstep}%
|
||||
\fi%
|
||||
}%
|
||||
\foreach \wavelength [count=\count] in \pgfdecorationgrowthwavelengthlist {%
|
||||
\ifnum\count=\pgfdecorationliststeps%
|
||||
\global\edef\pgfdecorationgrowthwavelength{\wavelength}%
|
||||
\breakforeach%
|
||||
\fi%
|
||||
}%
|
||||
\pgfmathparse{int(\pgfdecorationliststeps+1)}%
|
||||
\global\edef\pgfdecorationliststeps{\pgfmathresult}%
|
||||
\global\edef\pgfdecorationgrowthsteps{0}% Redefine the steps counter, globally.
|
||||
\pgfmathparse{(\pgfdecorationgrowthendsize-\pgfdecorationgrowthstart) * 2 %
|
||||
* \pgfdecorationgrowthwavelength / (\pgfdecoratedpathlength * (\pgfdecorationgrowthendstep -\tempa))}%
|
||||
\global\edef\pgfdecorationgrowth{\pgfmathresult}%
|
||||
\fi%
|
||||
}
|
165
justtrees.sty
Normal file
165
justtrees.sty
Normal file
|
@ -0,0 +1,165 @@
|
|||
x%% Copyright 2016 Clea F. Rees
|
||||
%
|
||||
% 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 `maintained'.
|
||||
%
|
||||
% The Current Maintainer of this work is Clea F. Rees.
|
||||
%
|
||||
% This work consists of the file justtrees.sty.
|
||||
%%
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\RequirePackage{svn-prov}
|
||||
\ProvidesPackageSVN{$Id: justtrees.sty 4959 2016-05-27 23:00:49Z cfrees $}[v0.08 \revinfo]
|
||||
\RequirePackage{forest}
|
||||
\newlength{\justtrees@tempa}
|
||||
\tikzset{%
|
||||
justifier format/.style={font=\justtrees@justifier@font},
|
||||
justifier font/.store in=\justtrees@justifier@font,
|
||||
justifier font=\normalfont\normalsize,
|
||||
left justifier format/.style={},
|
||||
right justifier format/.style={},
|
||||
}
|
||||
\forestset{%
|
||||
declare boolean register={left justifiers},% left justifications
|
||||
not left justifieers,
|
||||
declare boolean register={right justifiers},% right justifications
|
||||
not right justifiers,
|
||||
declare dimen register={left justifiers width},
|
||||
left justifiers width'=0pt,
|
||||
declare dimen register={right justifiers width},
|
||||
right justifiers width'=0pt,
|
||||
declare toks register={left justifiers align},
|
||||
left justifiers align={right},
|
||||
declare toks register={right justifiers align},
|
||||
right justifiers align={left},
|
||||
declare boolean register={empty nodes},
|
||||
empty nodes,
|
||||
just format/.style={%
|
||||
/tikz/justifier format/.append style={#1},
|
||||
},
|
||||
left just format/.style={%
|
||||
/tikz/left justifier format/.append style={#1},
|
||||
},
|
||||
right just format/.style={%
|
||||
/tikz/right justifier format/.append style={#1},
|
||||
},
|
||||
left justifications/.style={%
|
||||
left justifiers,
|
||||
},
|
||||
right justifications/.style={%
|
||||
right justifiers,
|
||||
},
|
||||
left just align/.style={%
|
||||
left justifiers align=#1,
|
||||
if={strequal(left_justifiers_align,"right")}{}
|
||||
{%
|
||||
left just/.append style={%
|
||||
TeX={\settowidth\justtrees@tempa{\justtrees@justifier@font ##1}},
|
||||
if={\justtrees@tempa>left_justifiers_width}
|
||||
{%
|
||||
left justifiers width=\justtrees@tempa,
|
||||
}{}
|
||||
},
|
||||
},
|
||||
},
|
||||
right just align/.style={%
|
||||
right justifiers align=#1,
|
||||
if={strequal(right_justifiers_align,"left")}{}
|
||||
{%
|
||||
right just/.append style={%
|
||||
TeX={\settowidth\justtrees@tempa{\justtrees@justifier@font ##1}},
|
||||
if={\justtrees@tempa>right_justifiers_width}
|
||||
{%
|
||||
right justifiers width=\justtrees@tempa,
|
||||
}{}
|
||||
},
|
||||
},
|
||||
},
|
||||
right just/.style={%
|
||||
right justifiers,
|
||||
tikz+/.wrap pgfmath arg={%
|
||||
\node (right just ##1) [anchor=base west, justifier format, right justifier format] at (.base -| just tree east) {#1};
|
||||
}{level()}
|
||||
},
|
||||
left just/.style={%
|
||||
left justifiers,
|
||||
tikz+/.wrap pgfmath arg={%
|
||||
\node (left just ##1) [anchor=base east, justifier format, left justifier format] at (.base -| just tree west) {#1};
|
||||
}{level()}
|
||||
},
|
||||
just/.style={%
|
||||
if right justifiers={%
|
||||
right just={#1}
|
||||
}{%
|
||||
if left justifiers={%
|
||||
left just={#1},
|
||||
}{%
|
||||
right just={#1},
|
||||
},
|
||||
},
|
||||
},
|
||||
just tree/.style={%
|
||||
for tree={%
|
||||
parent anchor=children,
|
||||
before typesetting nodes={%
|
||||
if empty nodes={%
|
||||
where content={}{%
|
||||
shape=coordinate,
|
||||
}{}
|
||||
}{},
|
||||
},
|
||||
},
|
||||
where level=0{%
|
||||
tikz+={%
|
||||
\coordinate (just tree north) at (current bounding box.north);
|
||||
\coordinate (just tree south) at (current bounding box.south);
|
||||
\coordinate (just tree west) at (current bounding box.west);
|
||||
\coordinate (just tree east) at (current bounding box.east);
|
||||
},
|
||||
for children={%
|
||||
no edge,
|
||||
},
|
||||
before typesetting nodes={%
|
||||
if content={}{phantom}{},
|
||||
},
|
||||
}{},
|
||||
before packing={%
|
||||
for tree={%
|
||||
tier/.wrap pgfmath arg={tier ##1}{level()},
|
||||
},
|
||||
},
|
||||
before drawing tree={%
|
||||
if={strequal(left_justifiers_align,"right")}{}
|
||||
{%
|
||||
left just format={%
|
||||
text width/.register=left justifiers width,
|
||||
align/.register=left justifiers align,
|
||||
},
|
||||
},
|
||||
if={strequal(right_justifiers_align,"left")}{}
|
||||
{%
|
||||
right just format={%
|
||||
text width/.register=right justifiers width,
|
||||
align/.register=right justifiers align,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
\environbodyname\justtreebody
|
||||
\bracketset{action character=@}
|
||||
\NewEnviron{justtree}[1]{% \forest/\endforest from egreg's answer at http://tex.stackexchange.com/a/229608/
|
||||
\forest
|
||||
just tree,
|
||||
#1,
|
||||
[@\justtreebody]
|
||||
\endforest}
|
||||
\endinput
|
||||
%% end justtrees.sty
|
246
main.tex
246
main.tex
|
@ -1,7 +1,6 @@
|
|||
\documentclass[11pt]{article}
|
||||
|
||||
\usepackage{a4wide}
|
||||
|
||||
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage[scaled=.7]{beramono}
|
||||
|
@ -33,8 +32,8 @@
|
|||
\usepackage{forest}
|
||||
\usepackage{tikz,datetime}
|
||||
\usetikzlibrary{decorations.pathreplacing,trees,calc,fit,positioning,chains,arrows,arrows.meta,automata,shapes,graphs,shapes.geometric,shapes.symbols,
|
||||
decorations.markings,patterns,matrix,decorations.pathmorphing,mindmap,math}
|
||||
%,triangle-fit,decorations.growingwave,oni-squiggly}
|
||||
decorations.markings,patterns,matrix,decorations.pathmorphing,mindmap,math,
|
||||
triangle-fit,decorations.growingwave,oni-squiggly}
|
||||
\usepackage{pgf}
|
||||
\usepackage{pgfplots}
|
||||
\usepackage{graphicx}
|
||||
|
@ -53,20 +52,19 @@ decorations.markings,patterns,matrix,decorations.pathmorphing,mindmap,math}
|
|||
\restoresymbol{bb}{Cross}% Restore original \Cross from marvosym + rename bbding's \Cross to \bbCross.
|
||||
\usepackage{relsize}
|
||||
\usepackage{wasysym}
|
||||
%\usepackage{growingwave}
|
||||
\usepackage{growingwave}
|
||||
\pgfdeclarelayer{background}
|
||||
\pgfdeclarelayer{foreground}
|
||||
\pgfsetlayers{background,main,foreground}
|
||||
\usepackage{epigraph}
|
||||
%\usepackage{oni-trees}
|
||||
%\usepackage{oni-tree-defaults}
|
||||
\usepackage{oni-trees}
|
||||
\usepackage{oni-tree-defaults}
|
||||
%\usepackage[backend=bibtex,style=authoryear,natbib=true,maxbibnames=99]{biblatex}
|
||||
%% User the bibtex backend with the authoryear citation style (which
|
||||
%% resembles APA)
|
||||
\usepackage{tikz,datetime}
|
||||
\usetikzlibrary{decorations.pathreplacing,trees,calc,fit,positioning,chains,arrows,arrows.meta,automata,shapes,graphs,shapes.geometric,shapes.symbols,
|
||||
decorations.markings,patterns,matrix,decorations.pathmorphing,mindmap,math}
|
||||
%,triangle-fit,decorations.growingwave,oni-squiggly}
|
||||
decorations.markings,patterns,matrix,decorations.pathmorphing,mindmap,math,triangle-fit,decorations.growingwave,oni-squiggly}
|
||||
\usepackage{pgf}
|
||||
\usepackage{pgfplots}
|
||||
\usepackage{graphicx}
|
||||
|
@ -113,6 +111,8 @@ decorations.markings,patterns,matrix,decorations.pathmorphing,mindmap,math}
|
|||
%Valuation
|
||||
\def\env{\ensuremath{E}}
|
||||
|
||||
|
||||
|
||||
%% Types
|
||||
\def\primtyp{\tau}
|
||||
|
||||
|
@ -413,6 +413,7 @@ subset that is disjoint from an operation's \emph{frame}, i.e. the
|
|||
state subset it modifies.
|
||||
|
||||
\subsection{Methodology}
|
||||
\label{sec:methodology}
|
||||
|
||||
To this end, we propose a solution based on static analysis which does not
|
||||
require any additional frame annotations. By detecting the subset
|
||||
|
@ -2241,6 +2242,235 @@ ti $\mapsto$ $\top$\\
|
|||
\subsection{An inter-procedural extension}
|
||||
|
||||
\section{Correlation analysis}
|
||||
\input{correlation-macros}
|
||||
|
||||
Recall from Section~\ref{sec:methodology} that our overall methodology
|
||||
for tackling the frame problem consists in combining a dependency
|
||||
analysis with a correlation analysis, that identifies what part of the
|
||||
input is copied to the output without being modified.
|
||||
%
|
||||
In this section, we present a static
|
||||
\emph{correlation} analysis which, when given a predicate that manipulates a
|
||||
structured input, determines automatically the subset of the input that remains
|
||||
unchanged and is further propagated into the output. Thus, the behaviour of a
|
||||
predicate is summarised by computing relations between parts of the input and
|
||||
parts of the output.
|
||||
|
||||
%The computed \emph{correlation summaries} are a safe
|
||||
%approximation of what part of an input state of a predicate is copied to the
|
||||
%output state.
|
||||
|
||||
The correlation analysis is a conservative static analysis inferring what is
|
||||
modified by an operation and to what extent. It approximates the flow of input
|
||||
values into output values, by uncovering \emph{equalities} and computing
|
||||
\emph{correlations} as pairs between input parts and the output parts
|
||||
into which these are injected. What is marked as being equal is
|
||||
definitely equal. As equalities iin general only pertain to parts of a data
|
||||
structure, we shall formalize them as \emph{partial equivalence
|
||||
relations} on structured data.
|
||||
|
||||
\begin{figure}[!h]
|
||||
\minipage[c]{\textwidth}
|
||||
\centering
|
||||
\centering
|
||||
\begin{forest}
|
||||
oni tree defaults,
|
||||
[, % Start directly with a comma: no node contents
|
||||
phantom,% phantom == invisible node, just here for the layout. It is the fake "common ancestor" to both trees shown in this diagram
|
||||
s sep=3.5cm,% Trees have two axes for layout s (sibling), the "horizontal" axis, and l (level), the "vertical" axis. Make the two trees separated by a centimeter
|
||||
%
|
||||
% Do not leave blank lines, always put a % when you want to skip a line, otherwise it crashes forest
|
||||
%First
|
||||
[, dot tree,name=ba1, triangle fit whole subtree={bottom space=.15cm},% start squiggly tree,
|
||||
[,zag=6mm,
|
||||
[;$\pi$, zig=3mm,
|
||||
[,name=o1, zag=3mm, triangle fit whole subtree={triangle sep=1mm, bottom space=0.01cm, iburg,}, %pattern=north east lines, pattern color=iburg},
|
||||
[, name=d1, invisible tree,
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
[,zig=5mm,
|
||||
[,zag=2mm,
|
||||
[, zig=1mm,
|
||||
[;$\rho$,name=g1, zag=2mm,triangle fit whole subtree={triangle sep=0.5mm, bottom space=0.01cm,draw=caribbeangreen, fill=caribbeangreen},
|
||||
[, invisible tree,
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
%Second
|
||||
[, dot tree,name=ba2, triangle fit whole subtree={bottom space=.1cm},% start squiggly tree,
|
||||
[,zag=8mm
|
||||
[, zig=2mm,
|
||||
[,name=ax2, zag=7mm,
|
||||
[,zig =2mm,
|
||||
[;$\pi'$, name=o2, zag=6mm,triangle fit whole subtree={triangle sep=1mm, bottom space=0.01cm,thick, iburg},
|
||||
[, name=d2, invisible tree,
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
[,zig=4mm
|
||||
[, zag=2mm,
|
||||
[;$\rho'$,name=g2, zig=1mm, triangle fit whole subtree={triangle sep=0.5mm, bottom space=0.01cm, draw=caribbeangreen, fill=caribbeangreen},
|
||||
[, invisible tree,
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
\draw[<->, shorten=2pt, thick, caribbeangreen] (g1) edge[bend left] node[above]{$\rel'$} (g2);
|
||||
\draw[<->, shorten=2pt, thick, iburg] (o1) edge[bend right, out=60] node[below]{$\rel$} (o2);
|
||||
\end{forest}
|
||||
\endminipage\hfill
|
||||
\caption{Intraprocedural Correlations -- General Representation}
|
||||
\label{cor:fig:intra}
|
||||
\end{figure}
|
||||
|
||||
Outputs are often complex compounds of different subparts of different
|
||||
input variables: a subset of the input is modified, while the rest is
|
||||
injected as is. We track the origin of subparts of the output and
|
||||
relate it to subparts of the input. As previously illustrated on our
|
||||
\disp{stop_thread} example predicate, in order to prevent avoidable
|
||||
over-approximations, we need to avoid dealing with data in a
|
||||
monolithic manner. To this end, it is imperative to consider pairs of
|
||||
different types and granularities as well. As a consequence, we are
|
||||
forced to introduce an additional level of granularity allowing us to
|
||||
refer not only to variables, but also to substructures within them. At
|
||||
the intraprocedural level, illustrated in Figure~\ref{cor:fig:intra},
|
||||
we define correlations as mappings between pairs of inputs and outputs
|
||||
to which we associate mappings between pairs of valid inner paths and
|
||||
the relations binding them. Correlations for arrays and variants are
|
||||
exemplified in
|
||||
Figures~\ref{fig:cor:examples}-a)~and~\ref{fig:cor:examples}-b).
|
||||
|
||||
\begin{figure}[!hbt]\centering
|
||||
\begin{tabular}{@{}cc@{}}
|
||||
\toprule
|
||||
\minipage{0.38\textwidth}
|
||||
\centering
|
||||
\begin{tikzpicture}[thick,scale=0.5, every node/.style={scale=0.5}]
|
||||
% \node[shape=multipart rectangle,parts=2] {a\second b};
|
||||
\matrix[matrix of nodes, row sep=0pt, column sep=0pt] (m) {
|
||||
\phantom{i} &
|
||||
\phantom{i} &
|
||||
|[fill=gray!20!white,alias=mi]| \large{i} &
|
||||
\phantom{i} &
|
||||
\phantom{i} &
|
||||
\phantom{i} &
|
||||
\phantom{i} &
|
||||
\phantom{i} \\
|
||||
};
|
||||
|
||||
\draw (m-1-1.north west) -- (m-1-8.north east) -- (m-1-8.south east) -- (m-1-1.south west) -- cycle;
|
||||
\foreach \i in {1,...,7} {% 8 - 1 to not have double line on the last cell.
|
||||
\draw (m-1-\i.north east) -- (m-1-\i.south east);
|
||||
}
|
||||
|
||||
\matrix[matrix of nodes, row sep=0pt, column sep=0pt, right=0.5cm of m] (n) {
|
||||
\phantom{i} &
|
||||
\phantom{i} &
|
||||
|[fill=gray!20!white,alias=ni]| \large{i} &
|
||||
\phantom{i} &
|
||||
\phantom{i} &
|
||||
\phantom{i} &
|
||||
\phantom{i} &
|
||||
\phantom{i} \\
|
||||
};
|
||||
|
||||
\draw (n-1-1.north west) -- (n-1-8.north east) -- (n-1-8.south east) -- (n-1-1.south west) -- cycle;
|
||||
\foreach \i in {1,...,7} {% 8 - 1 to not have double line on the last cell.
|
||||
\draw (n-1-\i.north east) -- (n-1-\i.south east);
|
||||
}
|
||||
|
||||
\def\braceAmplitude{6pt}
|
||||
\def\braceRaise{2pt}
|
||||
|
||||
% decoration={…,mirror,…} to have the brace the other way round
|
||||
\draw (m-1-1.south west) edge[decorate,decoration={brace,amplitude=\braceAmplitude,raise=\braceRaise,mirror}] node[coordinate,yshift=8pt] (mx) {} (m-1-8.south east);
|
||||
\draw (n-1-1.south west) edge[decorate,decoration={brace,amplitude=\braceAmplitude,raise=\braceRaise,mirror}] node[coordinate,yshift=8pt] (nx) {} (n-1-8.south east);
|
||||
|
||||
% \draw (mi.south) edge[<->,>=stealth,looseness=.5,out=-70,in=-110,shorten <=1.5pt, shorten >=1.5pt] node[below]{\large$\mathcal{R}$} (ni.south);
|
||||
\draw ([yshift=-1cm]mx) edge[<->,>=stealth,looseness=.5,out=-70,in=-110] node[below]{\large$\rel$} ([yshift=-1cm]nx);
|
||||
|
||||
% Background:
|
||||
\path[fill=white,opacity=.3]
|
||||
($(mi.north west) + (0, \braceAmplitude*0.5+\braceRaise) + (0,1pt)$)
|
||||
rectangle
|
||||
($(mi.north east) + (0, \braceAmplitude*0.5+\braceRaise) - (0,1pt)$);
|
||||
|
||||
\coordinate (miX) at ($(mi.north west) + (0, \braceAmplitude*0.5+\braceRaise) + (1pt,0)$);
|
||||
\coordinate (miY) at ($(mi.north east) + (0, \braceAmplitude*0.5+\braceRaise) - (.5pt,0)$);
|
||||
|
||||
% \foreach \i in {0,0.2,...,1} {
|
||||
% \draw[black!70] ($(miX)!\i!(miY)-(1pt,1pt)$) -- ($(miX)!\i!(miY)+(1pt,1pt)$);
|
||||
% }
|
||||
|
||||
%%%%
|
||||
|
||||
% Background:
|
||||
\path[fill=white,opacity=.3]
|
||||
($(ni.north west) + (0, \braceAmplitude*0.5+\braceRaise) + (0,1pt)$)
|
||||
rectangle
|
||||
($(ni.north east) + (0, \braceAmplitude*0.5+\braceRaise) - (0,1pt)$);
|
||||
|
||||
\coordinate (niX) at ($(ni.north west) + (0, \braceAmplitude*0.5+\braceRaise) + (1pt,0)$);
|
||||
\coordinate (niY) at ($(ni.north east) + (0, \braceAmplitude*0.5+\braceRaise) - (.5pt,0)$);
|
||||
\end{tikzpicture}
|
||||
|
||||
\endminipage
|
||||
\minipage{0.35\textwidth}
|
||||
\centering
|
||||
\begin{tikzpicture} [thick,scale=0.55, every node/.style={scale=0.55}]
|
||||
\pgfmathsetseed{\rndseed}
|
||||
\triangleArray{n}{(0,0)}
|
||||
|
||||
\pgfmathsetseed{\rndseed}
|
||||
\triangleArray{m}{($(n-0.south west) + (.5cm,-1cm)$)}
|
||||
|
||||
% Arrows:
|
||||
\foreach \i in {0,...,\nbnodes} {%
|
||||
% Centers: tc
|
||||
% Top: tt, left: tl, right: tr, bottom: tb
|
||||
\draw (n-tb-\i) edge[<->,>=stealth,out=-90,in=90, shorten <=.5pt, shorten >=.5pt] (m-tt-\i);
|
||||
}
|
||||
|
||||
\end{tikzpicture}
|
||||
\endminipage%
|
||||
\\
|
||||
\hspace{-0.1\textwidth}\minipage{0.48\textwidth}
|
||||
\centering\small a) Arrays: $\;\forall i, \; a{\left[i\right]} \mathbin{\rel} b{\left[i\right]}$
|
||||
\endminipage\hspace{-0.1\textwidth}
|
||||
\minipage{0.25\textwidth}
|
||||
\centering\small b) Variants
|
||||
\endminipage
|
||||
\\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Intraprocedural Domain -- Examples}
|
||||
\label{fig:cor:examples}
|
||||
\end{figure}
|
||||
|
||||
Similarly to our dependency analysis presented in Chapter~\ref{chapter5}, the
|
||||
correlation analysis is an interprocedural, flow-sensitive, field-sensitive,
|
||||
label-sensitive analysis that handles associative arrays, structures and variant
|
||||
data types. However, unlike the dependency analysis for which we introduced a
|
||||
relaxed form of context-sensitivity in Chapter~\ref{chapter6}, the correlation
|
||||
analysis is context-insensitive. Fine-grained equivalence relations between the
|
||||
inputs and outputs of a predicate are computed once and subsequently propagated
|
||||
to its callers.
|
||||
|
||||
Our correlation analysis is meant to be used in an interactive verification
|
||||
context. Precise correlation summaries must be computed quickly in order to
|
||||
answer effectively, when combined with dependency summaries, queries
|
||||
regarding the preservation of certain invariants.
|
||||
|
||||
|
||||
\subsection{Introductory example}
|
||||
|
||||
|
|
35
oni-tree-defaults.sty
Normal file
35
oni-tree-defaults.sty
Normal file
|
@ -0,0 +1,35 @@
|
|||
\forestset{
|
||||
oni tree defaults/.style={
|
||||
% These options apply to all nodes in the tree
|
||||
for tree={
|
||||
fit=band,% Use fit=tight for a more compact tree (see the docs at http://mirrors.ctan.org/graphics/pgf/contrib/forest/forest-doc.pdf )
|
||||
label style+={% style for labels next to dots:
|
||||
label distance=1pt,
|
||||
ellipse,
|
||||
inner sep=0.5pt,
|
||||
fill=white!80!black,
|
||||
fill opacity=0.4,% draw a semi-transparent background
|
||||
text opacity=1,% but draw the text fully opaque
|
||||
},
|
||||
edge label distance={1mm},
|
||||
edge label node style+={% Style for labels next to edges
|
||||
ellipse,
|
||||
inner sep=0.5pt,
|
||||
fill=white!80!black,
|
||||
fill opacity=0.4,% draw a semi-transparent background
|
||||
text opacity=1,% but draw the text fully opaque
|
||||
},
|
||||
edge label pin style={
|
||||
draw=none,
|
||||
% draw,
|
||||
% if edge label swap={bend left}{bend right},
|
||||
% densely dotted,
|
||||
},
|
||||
l sep=5mm,% default inter-line separation
|
||||
},
|
||||
for level<={3}{l sep=2mm},% Make the first three rows much thinner
|
||||
% Adjust a bit the horizontal (sibbling) spacing, because the labels currently are not taken into account.
|
||||
for level={4}{s sep=.5cm},
|
||||
for level={5}{s sep=.5cm},
|
||||
}
|
||||
}
|
308
oni-trees.sty
Normal file
308
oni-trees.sty
Normal file
|
@ -0,0 +1,308 @@
|
|||
\usetikzlibrary{decorations.markings}
|
||||
|
||||
% From http://tex.stackexchange.com/questions/20425/z-level-in-tikz, does not work in this case.
|
||||
% \makeatletter
|
||||
% \pgfkeys{%
|
||||
% /tikz/on layer/.code={
|
||||
% \def\tikz@path@do@at@end{\endpgfonlayer\endgroup\tikz@path@do@at@end}%
|
||||
% \pgfonlayer{#1}\begingroup%
|
||||
% }%
|
||||
% }
|
||||
% \makeatother
|
||||
|
||||
|
||||
%%%%%%%%%%%
|
||||
% Hairy stuff copied from the manual, nothing interesting to see…
|
||||
\forestStandardNode[.]{%
|
||||
\forestOve{\csname forest@id@of@standard node\endcsname}{content},%
|
||||
\the\ht\strutbox,\the\pgflinewidth,%
|
||||
\pgfkeysvalueof{/pgf/inner ysep},\pgfkeysvalueof{/pgf/outer ysep},%
|
||||
\pgfkeysvalueof{/pgf/inner xsep},\pgfkeysvalueof{/pgf/outer xsep}%
|
||||
}{
|
||||
l sep={0},%\the\ht\strutbox+\pgfkeysvalueof{/pgf/inner ysep}},
|
||||
l={l_sep()+abs(max_y()-min_y())+2*\pgfkeysvalueof{/pgf/outer ysep}},
|
||||
s sep={2*\pgfkeysvalueof{/pgf/inner xsep}}
|
||||
}{
|
||||
l sep,l,s sep
|
||||
}
|
||||
%%%%%%%%%%%
|
||||
|
||||
% Beamer animation stuff:
|
||||
\forestset{
|
||||
all opacities/.style={opacity=#1,draw opacity=#1,fill opacity=#1,text opacity=#1,},
|
||||
invisible/.style={
|
||||
all opacities=0,
|
||||
edge={/forest/all opacities=0,},
|
||||
label style={/forest/all opacities=0,},
|
||||
edge label node style={opacity=0,draw opacity=0,fill opacity=0,text opacity=0,},
|
||||
edge label pin style={opacity=0,draw opacity=0,fill opacity=0,text opacity=0,},
|
||||
},
|
||||
invisible tree/.style={for tree={invisible},},
|
||||
alt/.code args={<#1>#2#3}{
|
||||
\alt<#1>{
|
||||
\pgfkeysalso{#2}
|
||||
}{
|
||||
\pgfkeysalso{#3}
|
||||
}
|
||||
},
|
||||
only/.code args={<#1>#2}{
|
||||
\only<#1>{
|
||||
\pgfkeysalso{#2}
|
||||
}
|
||||
},
|
||||
only not/.code args={<#1>#2}{
|
||||
\alt<#1>{
|
||||
}{
|
||||
\pgfkeysalso{#2}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
\tikzset{
|
||||
% only/.forward to={/forest/only},
|
||||
% only not/.forward to={/forest/only not},
|
||||
% all opacities/.forward to={/forest/all opacities},
|
||||
all opacities/.style={opacity=#1,draw opacity=#1,fill opacity=#1,text opacity=#1,},
|
||||
invisible/.style={all opacities=0,},
|
||||
alt/.code args={<#1>#2#3}{
|
||||
\alt<#1>{
|
||||
\pgfkeysalso{#2}
|
||||
}{
|
||||
\pgfkeysalso{#3}
|
||||
}
|
||||
},
|
||||
only/.code args={<#1>#2}{
|
||||
\only<#1>{
|
||||
\pgfkeysalso{#2}
|
||||
}
|
||||
},
|
||||
only not/.code args={<#1>#2}{
|
||||
\alt<#1>{
|
||||
}{
|
||||
\pgfkeysalso{#2}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
% Handy node walk from one node to some ancestor
|
||||
\forestset{
|
||||
define long step={current if not name}{n args=1}{if={strequal(name("!current"),"#1")}{}{current}},
|
||||
define long step={ancestors from after name until before name}{n args=2}{if={strequal("#1","#2")}{}{fake={name=#1},ancestors until before name=#2}},
|
||||
define long step= {ancestors until before name}{n args=1}{if={strequal(name("!parent"),"#1")}{}{parent,ancestors until before name=#1,last valid}},
|
||||
define long step={current and ancestors until before name}{n args=1}{current if not name=#1,ancestors until before name=#1},
|
||||
define long step= {ancestors until name}{n args=1}{ancestors until before name=#1,name=#1},
|
||||
define long step={current and ancestors until name}{n args=1}{current if not name=#1,ancestors until before name=#1,name=#1},
|
||||
declare toks={highlight path/from}{},
|
||||
declare toks={highlight path/to}{},
|
||||
declare toks={highlight path/first}{},
|
||||
declare toks={highlight path/mid}{},
|
||||
declare toks={highlight path/last}{},
|
||||
declare toks={highlight path/edges}{},
|
||||
highlight path/.style={
|
||||
highlight path/.cd,
|
||||
#1
|
||||
/forest/.cd,
|
||||
if={strequal(\forestoption{highlight path/from}, "")}{
|
||||
/utils/exec={\pgfmathsetmacro\highlightPathFrom{name()}},
|
||||
highlight path/from={\highlightPathFrom},
|
||||
}{
|
||||
},
|
||||
for name/.expanded={\forestoption{highlight path/from}}{
|
||||
\forestoption{highlight path/first},
|
||||
if={strequal("\foresteoption{highlight path/from}","\foresteoption{highlight path/to}")}{
|
||||
}{
|
||||
edge+={\forestoption{highlight path/edges},},
|
||||
},
|
||||
},
|
||||
% For some reason, putting \foresteoption{highlight path/to} directly in
|
||||
% the second argument of "for ancestors from after name until before name"
|
||||
% causes an error, so we're expanding it first into a macro.
|
||||
/utils/exec={\edef\highlightPathTo{\foresteoption{highlight path/to}}},
|
||||
for ancestors from after name until before name/.expanded={\foresteoption{highlight path/from}}{\highlightPathTo}{
|
||||
\forestoption{highlight path/mid},
|
||||
edge+={\forestoption{highlight path/edges},},
|
||||
},
|
||||
for name/.expanded={\forestoption{highlight path/to}}{\forestoption{highlight path/last}},
|
||||
},
|
||||
}
|
||||
|
||||
% These keys are available by default only in "\begin{forest}…\end{forest}",
|
||||
% but not in "\begin{tikzpicture}…\end{tikzpicture}". This is because the
|
||||
% full key name is "/forest/foo", instead of "/tikz/foo", and
|
||||
% "\begin{forest}" searches inside "/forest/" by default, whereas
|
||||
% "\begin{tikzpicture}" searches inside "/tikz/" by default.
|
||||
\tikzset{
|
||||
shorten/.style={shorten <=#1, shorten >=#1,},% Convenient alias to shorten the edge on both sides by the same amount
|
||||
edge label distance/.forward to={/forest/edge label distance},% Alias for the forest-specific edge label distance declared below
|
||||
}
|
||||
\forestset{
|
||||
% Circumvent bug in if={strequal("a","b")}{}{} when a or b contain math accents.
|
||||
% Because math accents are expressed with \mathaccent "1234, the extra " character
|
||||
% breaks the string, and I don't see an obvious way to escape it. This bug probably
|
||||
% still lurks in all uses of strequal() in this and other files.
|
||||
% Note this is defined as the /forest/ifstrequal key, not as /tikz/ifstrequal
|
||||
ifstrequal/.code n args={4}{
|
||||
\ifthenelse{\equal{#1}{#2}}{%
|
||||
\forestset{#3}%
|
||||
}{%
|
||||
\forestset{#4}%
|
||||
}%
|
||||
},%
|
||||
%
|
||||
% Copied and adjusted from the forest manual, section "5.1 Decision tree" page 73 of manual version 2.0.3:
|
||||
% http://mirrors.ctan.org/graphics/pgf/contrib/forest/forest-doc.pdf
|
||||
anchors/.style={anchor=#1, child anchor=#1, parent anchor=#1},
|
||||
declare keylist={label style}{},
|
||||
declare keylist={edge label node style}{},
|
||||
declare keylist={edge label pin style}{},
|
||||
% edge label node/.style={},
|
||||
% edge label pin/.style={},
|
||||
declare boolean={edge label swapped}{false},
|
||||
edge label swap/.style={
|
||||
if={\forestoption{edge label swapped}}{
|
||||
edge label swapped=false,
|
||||
}{
|
||||
edge label swapped=true,
|
||||
}
|
||||
},
|
||||
if edge label swap/.style 2 args={
|
||||
if={\forestoption{edge label swapped}}{
|
||||
#1
|
||||
}{
|
||||
#2
|
||||
}
|
||||
},
|
||||
/tikz/if edge label swap/.style 2 args={
|
||||
/forest/if={\forestoption{edge label swapped}}{
|
||||
#1
|
||||
}{
|
||||
#2
|
||||
}
|
||||
},
|
||||
declare dimen={edge label distance}{0pt},
|
||||
dot/.default=2pt,
|
||||
label content/.style={
|
||||
ifstrequal={#1}{}{
|
||||
% Nothing to do, label is empty.
|
||||
}{
|
||||
% The label is implicitly named (xxx-label), where xxx is the node's name as given with [some label, name=xxx, …]
|
||||
% But it currently doesn't work
|
||||
/utils/exec={\pgfmathsetmacro{\dottreenode}{name()}},
|
||||
label/.expanded={[alias=\dottreenode-label,\forestoption{label style}]:#1},% #1 is the label content.
|
||||
},
|
||||
},
|
||||
%
|
||||
edge label content/.style={
|
||||
% edge label/.expanded={node[\forestoption{edge label style}] {#1}},
|
||||
ifstrequal={#1}{}{
|
||||
% No label, nothing to do.
|
||||
}{
|
||||
edge={
|
||||
postaction={
|
||||
draw,
|
||||
decorate,
|
||||
decoration={
|
||||
markings,
|
||||
mark=at position 0.5 with {
|
||||
\tikzmath{
|
||||
real \edgeLabelDirection;
|
||||
if \forestoption{edge label swapped} then {
|
||||
\edgeLabelDirection = 1;
|
||||
} else {
|
||||
\edgeLabelDirection = -1;
|
||||
};
|
||||
}
|
||||
\coordinate (-mark1) at (0,0);
|
||||
\coordinate (-mark2) at (0,-\edgeLabelDirection);
|
||||
\pgftransformresetnontranslations
|
||||
\tikzmath{
|
||||
coordinate \markdiff,\marknorm;
|
||||
real \markangle;
|
||||
%%
|
||||
%%
|
||||
\markdiff=(-mark2) - (-mark1);
|
||||
\marknormx=\markdiffx / sqrt(\markdiffx*\markdiffx + \markdiffy*\markdiffy);
|
||||
\marknormy=\markdiffy / sqrt(\markdiffx*\markdiffx + \markdiffy*\markdiffy);
|
||||
if \markdiffy == 0 then {
|
||||
if \markdiffx > 0 then {
|
||||
if \forestoption{edge label swapped} then {
|
||||
\markangle = 0;
|
||||
} else {
|
||||
\markangle = 180;
|
||||
};
|
||||
} else {
|
||||
if \forestoption{edge label swapped} then {
|
||||
\markangle = 0;
|
||||
} else {
|
||||
\markangle = 180;
|
||||
};
|
||||
};
|
||||
} else {
|
||||
if \markdiffy > 0 then {
|
||||
\markangle = acos(\marknormx);
|
||||
} else {
|
||||
\markangle = 180+acos(-\marknormx);
|
||||
};
|
||||
};
|
||||
}
|
||||
\tikzset{
|
||||
edge label node style exp/.style/.expanded={\forestoption{edge label node style}},
|
||||
edge label pin style exp/.style/.expanded={\forestoption{edge label pin style}},
|
||||
}
|
||||
\path (-mark1) ++(\markangle:\forestoption{edge label distance}) node[anchor=180+\markangle, edge label node style exp] (edge label) {#1};
|
||||
\path (-mark1) edge[edge label pin style exp] (edge label);%++(\markangle:\forestoption{edge label distance});
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dot/.style={
|
||||
% This is delayed into a second processing pass, otheriwse the "content" is re-overridden by the explicitly set content
|
||||
delay={
|
||||
split option={content}{;}{label content,edge label content},
|
||||
content={},% Remove the content from the node, as it is typeset into a separate label node.
|
||||
},
|
||||
ellipse,
|
||||
fill,
|
||||
inner sep=0pt,
|
||||
minimum size=2*#1,% You can use […, dot] to get the default radius ("dot/.default=2pt", see just above), or […, dot=5pt] to choose the radius.
|
||||
},
|
||||
dot tree/.style={
|
||||
for tree={% These options apply to all nodes in the (sub-)tree
|
||||
dot,% Draw as a dot, defined above
|
||||
% Position of the label:
|
||||
if n children=0{% Leaf node, has "0 children"
|
||||
label style+={label position=below},
|
||||
}{% Non-leaf node
|
||||
if n=1{% First (leftmost) child, has "current node index = 1"
|
||||
label style+={label position=left},
|
||||
}{% Other child
|
||||
label style+={label position=right},
|
||||
},
|
||||
},
|
||||
% Position of the edge label:
|
||||
if n=1{% First (leftmost) child, has "current node index = 1"
|
||||
edge label swap,
|
||||
}{% Other child
|
||||
edge label swap,
|
||||
},
|
||||
},
|
||||
label style+={label position=above},% Override the label position for the label of the root node (for this subtree).
|
||||
% There is no edge label style to override for the root, as it has no incoming edge label.
|
||||
},
|
||||
% Zig-zag distances
|
||||
declare dimen={zig distance}{.3cm},
|
||||
declare dimen={Zig distance}{.5cm},
|
||||
declare dimen={ZIG distance}{.7cm},
|
||||
% Zigs and zags can easily be swapped globally by puting the minus "-" sign in the zigs instead of the zags, if needed.
|
||||
zig/.style={edge label swap, calign with current={#1},},
|
||||
zig/.default={\forestoption{zig distance}},
|
||||
Zig/.style={edge label swap, calign with current={\forestoption{Zig distance}},},
|
||||
ZIG/.style={edge label swap, calign with current={\forestoption{ZIG distance}}, for parent={l sep+=.2cm,},},
|
||||
%
|
||||
zag/.style={calign with current={-#1},},
|
||||
zag/.default={\forestoption{zig distance}},
|
||||
Zag/.style={calign with current={-\forestoption{Zig distance}},},
|
||||
ZAG/.style={calign with current={-\forestoption{ZIG distance}}, for parent={l sep+=.2cm,},},
|
||||
}
|
126
tikzlibrarydecorations.growingwave.code.tex
Normal file
126
tikzlibrarydecorations.growingwave.code.tex
Normal file
|
@ -0,0 +1,126 @@
|
|||
\usetikzlibrary{decorations.pathreplacing}
|
||||
\def\pgfdecorationgrowthstart{0cm}
|
||||
\def\pgfdecorationgrowthendsizelist{0cm}
|
||||
\def\pgfdecorationgrowthwavelengthlist{0cm}
|
||||
\def\pgfdecorationgrowthendstepslist{1}
|
||||
\def\pgfdecorationgrowthendstep{1}
|
||||
\newif\ifpgfdecorationgrowthsine
|
||||
\newif\ifpgfdecorationgrowthcosine
|
||||
\newif\ifpgfdecorationonewavelength
|
||||
\pgfdecorationgrowthcosinefalse
|
||||
\pgfdecorationgrowthsinetrue
|
||||
\pgfkeys{%
|
||||
/pgf/decoration/.cd,
|
||||
growth start size/.initial=0.5cm,
|
||||
growth end size/.initial=3cm,
|
||||
growth end steps/.initial=1,
|
||||
growth wave length/.initial=3pt,
|
||||
growth sine/.code={\pgfdecorationgrowthsinetrue\pgfdecorationgrowthcosinefalse},
|
||||
growth cosine/.code={\pgfdecorationgrowthsinefalse\pgfdecorationgrowthcosinetrue}
|
||||
}
|
||||
\def\pgfdecorationgrowthsetup{%
|
||||
\global\edef\pgfdecorationgrowthstart{\pgfkeysvalueof{/pgf/decoration/growth start size}}%
|
||||
\global\edef\pgfdecorationgrowthendsizelist{\pgfkeysvalueof{/pgf/decoration/growth end size}}%
|
||||
\global\edef\pgfdecorationgrowthendstepslist{\pgfkeysvalueof{/pgf/decoration/growth end steps}}%
|
||||
\global\edef\pgfdecorationgrowthwavelengthlist{\pgfkeysvalueof{/pgf/decoration/growth wave length}}%
|
||||
}
|
||||
|
||||
\def\pgfdecorationgrowthsteps{1} % To keep track of steps from ending
|
||||
\def\pgfdecorationliststeps{2} % To keep track of list items from ending, has to start from 2
|
||||
|
||||
\pgfdeclaredecoration{growth wave}{initial}%
|
||||
{
|
||||
\state{initial}[width=0pt,next state=first] {%
|
||||
\pgfdecorationgrowthsetup%
|
||||
\pgfpathlineto{\pgfqpoint{0pt}{0pt}}%
|
||||
\global\edef\pgfdecorationgrowthsteps{0}%
|
||||
\global\edef\pgfdecorationliststeps{2}%
|
||||
\foreach \endsize in \pgfdecorationgrowthendsizelist {%
|
||||
\global\edef\pgfdecorationgrowthendsize{\endsize}%
|
||||
\breakforeach%
|
||||
}%
|
||||
\foreach \growthstep in \pgfdecorationgrowthendstepslist {%
|
||||
\global\edef\pgfdecorationgrowthendstep{\growthstep}%
|
||||
\breakforeach%
|
||||
}%
|
||||
\foreach \wavelength in \pgfdecorationgrowthwavelengthlist {%
|
||||
\global\edef\pgfdecorationgrowthwavelength{\wavelength}%
|
||||
\breakforeach%
|
||||
}%
|
||||
\pgfmathparse{(\pgfdecorationgrowthendsize - \pgfdecorationgrowthstart) * 2 * %
|
||||
\pgfdecorationgrowthwavelength / ( \pgfdecoratedremainingdistance * \pgfdecorationgrowthendstep)}%
|
||||
\global\edef\pgfdecorationgrowth{\pgfmathresult}%
|
||||
}%
|
||||
|
||||
\state{first}[width=2*\pgfdecorationgrowthwavelength,next state=second] {%
|
||||
\pgfdecorationgrowthstepcounters%
|
||||
\pgfmathparse{\pgfdecorationgrowthstart + \pgfdecorationgrowthsteps * \pgfdecorationgrowth}%
|
||||
% The wave starts
|
||||
\ifpgfdecorationgrowthsine%
|
||||
\pgfpathsine{\pgfqpoint{\pgfdecorationgrowthwavelength}{\pgfmathresult pt}}%
|
||||
\pgfpathcosine{\pgfqpoint{\pgfdecorationgrowthwavelength}{-\pgfmathresult pt}}%
|
||||
\fi%
|
||||
\ifpgfdecorationgrowthcosine%
|
||||
\pgfpathsine{\pgfqpoint{\pgfdecorationgrowthwavelength}{-\pgfmathresult pt}}%
|
||||
\pgfpathcosine{\pgfqpoint{\pgfdecorationgrowthwavelength}{\pgfmathresult pt}}%
|
||||
\fi%
|
||||
\pgfdecorationgrowthstateend%
|
||||
}%
|
||||
|
||||
\state{second}[width=2*\pgfdecorationgrowthwavelength,next state=first] {%
|
||||
\pgfdecorationgrowthstepcounters%
|
||||
\pgfmathparse{\pgfdecorationgrowthstart + \pgfdecorationgrowthsteps * \pgfdecorationgrowth}%
|
||||
% The wave continues
|
||||
\ifpgfdecorationgrowthsine%
|
||||
\pgfpathsine{\pgfqpoint{\pgfdecorationgrowthwavelength}{-\pgfmathresult pt}}%
|
||||
\pgfpathcosine{\pgfqpoint{\pgfdecorationgrowthwavelength}{\pgfmathresult pt}}%
|
||||
\fi%
|
||||
\ifpgfdecorationgrowthcosine%
|
||||
\pgfpathsine{\pgfqpoint{\pgfdecorationgrowthwavelength}{\pgfmathresult pt}}%
|
||||
\pgfpathcosine{\pgfqpoint{\pgfdecorationgrowthwavelength}{-\pgfmathresult pt}}%
|
||||
\fi%
|
||||
\pgfdecorationgrowthstateend%
|
||||
}
|
||||
\state{final} {%
|
||||
\pgfpathlineto{\pgfpointdecoratedpathlast}%
|
||||
}%
|
||||
}
|
||||
\def\pgfdecorationgrowthstateend{%
|
||||
\pgfmathadd{\pgfdecorationgrowthsteps}{1}%
|
||||
\global\edef\pgfdecorationgrowthsteps{\pgfmathresult} % Redefine the steps counter, globally.
|
||||
}
|
||||
|
||||
\def\pgfdecorationgrowthstepcounters{%
|
||||
\pgfmathparse{\pgfdecorationgrowthendstep * \pgfdecoratedpathlength}
|
||||
\ifdim\pgfdecoratedcompleteddistance>\pgfmathresult pt%
|
||||
\foreach \endsize [count=\count] in \pgfdecorationgrowthendsizelist {%
|
||||
\ifnum\count=\pgfdecorationliststeps%
|
||||
\global\edef\pgfdecorationgrowthendsize{\endsize}%
|
||||
\breakforeach%
|
||||
\else%
|
||||
\global\edef\pgfdecorationgrowthstart{\endsize}%
|
||||
\fi%
|
||||
}%
|
||||
\global\edef\tempa{0}%
|
||||
\foreach \growthstep [count=\count] in \pgfdecorationgrowthendstepslist {%
|
||||
\ifnum\count=\pgfdecorationliststeps%
|
||||
\global\edef\pgfdecorationgrowthendstep{\growthstep}%
|
||||
\breakforeach%
|
||||
\else%
|
||||
\global\edef\tempa{\growthstep}%
|
||||
\fi%
|
||||
}%
|
||||
\foreach \wavelength [count=\count] in \pgfdecorationgrowthwavelengthlist {%
|
||||
\ifnum\count=\pgfdecorationliststeps%
|
||||
\global\edef\pgfdecorationgrowthwavelength{\wavelength}%
|
||||
\breakforeach%
|
||||
\fi%
|
||||
}%
|
||||
\pgfmathparse{int(\pgfdecorationliststeps+1)}%
|
||||
\global\edef\pgfdecorationliststeps{\pgfmathresult}%
|
||||
\global\edef\pgfdecorationgrowthsteps{0}% Redefine the steps counter, globally.
|
||||
\pgfmathparse{(\pgfdecorationgrowthendsize-\pgfdecorationgrowthstart) * 2 %
|
||||
* \pgfdecorationgrowthwavelength / (\pgfdecoratedpathlength * (\pgfdecorationgrowthendstep -\tempa))}%
|
||||
\global\edef\pgfdecorationgrowth{\pgfmathresult}%
|
||||
\fi%
|
||||
}
|
83
tikzlibraryoni-squiggly.code.tex
Normal file
83
tikzlibraryoni-squiggly.code.tex
Normal file
|
@ -0,0 +1,83 @@
|
|||
\usetikzlibrary{decorations.growingwave}
|
||||
\tikzset{
|
||||
small squiggly line fade in/.style={
|
||||
-,% No arrow head
|
||||
shorten >=0pt,%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
decorate,
|
||||
decoration={
|
||||
growth wave,
|
||||
growth start size=0pt,
|
||||
growth end size=-1pt,%{-1pt,-1pt,0pt},%%%%%%%%%
|
||||
% growth end steps={0.6,.7},
|
||||
%growth end steps={0.2,0.6,1},%%%%%%%%
|
||||
growth wave length=1pt,%{1pt,1pt,1pt},%%%%%
|
||||
growth cosine,
|
||||
% pre length=5mm,
|
||||
post length=0mm,%%%%%%%%%%%%%%%%%%%%%%
|
||||
},
|
||||
},
|
||||
small squiggly line no fade/.style={
|
||||
-,% No arrow head
|
||||
shorten >=0pt,%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
decorate,
|
||||
decoration={
|
||||
growth wave,
|
||||
growth start size=-1pt,
|
||||
growth end size=-1pt,%{-1pt,-1pt,0pt},%%%%%%%%%
|
||||
% growth end steps={0.6,.7},
|
||||
% growth end steps={0.2,0.6,1},
|
||||
growth wave length=1pt,%{1pt,1pt,1pt},%%%%%
|
||||
growth cosine,
|
||||
pre length=1pt,%%%%%%%%%%%%%%%%
|
||||
post length=1pt,%%%%%%%%%%%%%%%%%%%%%%
|
||||
},
|
||||
},
|
||||
squiggly line/.style={
|
||||
-,% No arrow head
|
||||
shorten >=0pt,%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
decorate,
|
||||
decoration={
|
||||
growth wave,
|
||||
growth start size=0pt,
|
||||
growth end size=2pt,%{3pt,0pt},
|
||||
% growth end steps={0.6,.7},
|
||||
% growth end steps={0.8,1},
|
||||
growth wave length=2pt,%{2pt,1pt},
|
||||
growth cosine,
|
||||
% pre length=5mm,
|
||||
post length=0mm%%%%%%%%%%%%%%%%%%%%%%
|
||||
},
|
||||
},
|
||||
squiggly arrow/.style={
|
||||
->,
|
||||
shorten >=1.5pt,
|
||||
decorate,
|
||||
decoration={
|
||||
growth wave,
|
||||
growth start size=0pt,
|
||||
growth end size=2pt,%{3pt,0pt},
|
||||
% growth end steps={0.6,.7},
|
||||
% growth end steps={0.8,1},
|
||||
growth wave length=2pt,%{2pt,1pt},
|
||||
growth cosine,
|
||||
% pre length=5mm,
|
||||
post length=2mm
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
\tikzset{
|
||||
/forest/.cd, % Set forest styles
|
||||
start squiggly tree/.style={
|
||||
for children={
|
||||
edge={small squiggly line fade in,},
|
||||
continue squiggly tree,
|
||||
}
|
||||
},
|
||||
continue squiggly tree/.style={
|
||||
for children={
|
||||
edge={small squiggly line no fade,},
|
||||
continue squiggly tree,
|
||||
}
|
||||
}
|
||||
}
|
184
tikzlibrarytree-triangle-fit.code.tex
Normal file
184
tikzlibrarytree-triangle-fit.code.tex
Normal file
|
@ -0,0 +1,184 @@
|
|||
% %%%%%%%
|
||||
% % From http://tex.stackexchange.com/questions/314053/how-to-declare-a-tikz-directory-or-group-of-keys/314065?noredirect=1#comment765927_314065
|
||||
% \pgfkeys{
|
||||
% /handlers/.is directory/.code={
|
||||
% \pgfkeysedef{\pgfkeyscurrentpath}{
|
||||
% \noexpand\pgfkeys{\pgfkeyscurrentpath/.cd,##1}
|
||||
% }
|
||||
% }
|
||||
% }
|
||||
% %%%%%%%
|
||||
|
||||
\ifx\pgfmathsign\relax%
|
||||
\tikzmath{
|
||||
function sign(\x) {
|
||||
if (\x < 0) then {
|
||||
return -1;
|
||||
} else {
|
||||
if (\x > 0) then {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
\fi%
|
||||
|
||||
\newif\iftrianglefitisosceles
|
||||
\newif\iftrianglefitbackground
|
||||
\tikzset{
|
||||
triangle fit current style/.style={},
|
||||
triangle fit current background style/.style={},
|
||||
triangle fit/.unknown/.code={
|
||||
% \message{triangle fit unknown:\pgfkeyscurrentkeyRAW=#1^^J}
|
||||
\let\trianglefitstorekey=\pgfkeyscurrentkeyRAW
|
||||
\edef\triangleExp{
|
||||
\noexpand\tikzset{
|
||||
/tikz/triangle fit current style/.append style={
|
||||
\trianglefitstorekey=\noexpand#1
|
||||
}
|
||||
}
|
||||
}
|
||||
\triangleExp
|
||||
%\pgfqkeys{/tikz}{}
|
||||
},
|
||||
triangle fit/triangle sep/.initial=0.15em,
|
||||
triangle fit/triangle sep/.default=0.15em,
|
||||
triangle fit/top space/.initial=1.5ex,
|
||||
triangle fit/top space/.default=1.5ex,
|
||||
triangle fit/bottom space/.initial=0ex,
|
||||
triangle fit/bottom space/.default=0ex,
|
||||
triangle fit/top/.initial=,
|
||||
triangle fit/nodes/.initial=,
|
||||
triangle fit/no rounded corners/.style={/tikz/rounded corners=0pt},
|
||||
every triangle fit/.style={
|
||||
triangle sep=.15em,
|
||||
rounded corners=5pt,
|
||||
isosceles,
|
||||
},
|
||||
triangle fit/isosceles/.is if=trianglefitisosceles,
|
||||
triangle fit/not isosceles/.style={isosceles=false},
|
||||
triangle fit/bg/.code={
|
||||
\tikzset{
|
||||
triangle fit current background style/.style={#1},
|
||||
}
|
||||
},
|
||||
triangle fit/.code={
|
||||
\tikzset{
|
||||
/tikz/triangle fit current style/.style={},
|
||||
/tikz/triangle fit/.cd,
|
||||
/tikz/every triangle fit,
|
||||
#1,
|
||||
}
|
||||
% \node[draw, /tikz/every triangle fit] {EEE}
|
||||
% \edef\currenttrianglestyle{\pgfkeysvalueof{/tikz/triangle fit/style}}
|
||||
% \message{\currenttrianglestyle}
|
||||
% \tikzset{
|
||||
% triangle fit current style/.style=\currenttrianglestyle,
|
||||
% }
|
||||
% Compute the minimum and maxiumum slope, as well as the maximum y (i.e. height) for the triangle.
|
||||
\tikzmath{
|
||||
coordinate \pt,\ttop;
|
||||
% int \found;
|
||||
% \found{top} = 0;
|
||||
% \found{bot} = 0;
|
||||
\ttop=([yshift=\pgfkeysvalueof{/tikz/triangle fit/top space}]\pgfkeysvalueof{/tikz/triangle fit/top});
|
||||
\slopeleft = 0;
|
||||
\sloperight = 0;
|
||||
\maxdy = 0;
|
||||
}
|
||||
% Foreach loop over all nodes, which computes the max and min slopes and triangle height
|
||||
\edef\triangleFitItems{\pgfkeysvalueof{/tikz/triangle fit/nodes}}
|
||||
\foreach \i in \triangleFitItems{
|
||||
\foreach \ii in {(\i.north east),(\i.south east),(\i.south west),(\i.north west)} {
|
||||
\tikzmath{
|
||||
\pt = \ii;
|
||||
\dx = \ptx - \ttopx;
|
||||
\dx = \dx + \pgfkeysvalueof{/tikz/triangle fit/triangle sep} * sign(\dx);
|
||||
\dy = \ttopy - \pty;
|
||||
\dy = \dy + \pgfkeysvalueof{/tikz/triangle fit/triangle sep} * sign(\dy);
|
||||
\slope = \dx / \dy;
|
||||
if \slope > \sloperight then {
|
||||
\sloperight = \slope;
|
||||
};
|
||||
if \slope < \slopeleft then {
|
||||
\slopeleft = \slope;
|
||||
};
|
||||
if \dy > \maxdy then {
|
||||
\maxdy = \dy;
|
||||
};
|
||||
}
|
||||
\global\let\sloperight\sloperight%
|
||||
\global\let\slopeleft\slopeleft%
|
||||
\global\let\maxdy\maxdy%
|
||||
% \message{\ii, ptx=\ptx, pty=\pty, dx=\dx, dy=\dy, slope=\slope, sloperight=\sloperight, slopeleft=\slopeleft, maxdy=\maxdy^^J}
|
||||
}
|
||||
}
|
||||
\tikzmath{
|
||||
\maxdy = \maxdy + \pgfkeysvalueof{/tikz/triangle fit/bottom space};
|
||||
}
|
||||
\iftrianglefitisosceles
|
||||
\tikzmath{
|
||||
if -\sloperight < \slopeleft then {
|
||||
\slopeleft = -\sloperight;
|
||||
};
|
||||
if -\slopeleft > \sloperight then {
|
||||
\sloperight = -\slopeleft;
|
||||
};
|
||||
}
|
||||
\fi
|
||||
% Draw the triangle:
|
||||
\draw[/tikz/triangle fit current style]
|
||||
(\ttopx,\ttopy)
|
||||
-- +(\sloperight*\maxdy pt,-\maxdy pt)
|
||||
-- +(\slopeleft*\maxdy pt,-\maxdy pt)
|
||||
-- cycle;
|
||||
|
||||
% Draw the background
|
||||
\begin{pgfonlayer}{background}
|
||||
\path[/tikz/triangle fit current background style]
|
||||
(\ttopx,\ttopy)
|
||||
-- +(\sloperight*\maxdy pt,-\maxdy pt)
|
||||
-- +(\slopeleft*\maxdy pt,-\maxdy pt)
|
||||
-- cycle;
|
||||
\end{pgfonlayer}
|
||||
}
|
||||
}
|
||||
|
||||
\def\nodx{
|
||||
node[draw, every triangle fit, triangle fit={top={\fittriangletop},nodes={\fittriangletop\foresteoption{fit these}}}] {nodes:\fittriangletop\foresteoption{fit these}}
|
||||
}
|
||||
% \forestset{
|
||||
% % every triangle fit/.forward to=/tikz/every triangle fit,
|
||||
% every triangle fit/append/.forward to=/tikz/every triangle fit/append,
|
||||
% every triangle fit/style/.forward to=/tikz/every triangle fit/style,
|
||||
% declare toks={fit these}{},
|
||||
% triangle fit whole subtree/.style={
|
||||
% delay={
|
||||
% temptoksa=,
|
||||
% for descendants={%
|
||||
% temptoksa+/.wrap pgfmath arg={,##1}{name()},
|
||||
% },
|
||||
% fit these/.register=temptoksa,
|
||||
% delay={
|
||||
% % /utils/exec={
|
||||
% % \pgfmathsetmacro{\fittriangletop}{name()}
|
||||
% % \message{^^JFIT THESE=\foresteoption{fit these}, NAME=\fittriangletop^^J}
|
||||
% % },
|
||||
% % append after command={
|
||||
% % \nodx
|
||||
% % },
|
||||
% tikz+={
|
||||
% \pgfmathsetmacro{\fittriangletop}{name()}
|
||||
% % \message{\foresteoption{fit these}}
|
||||
% \path[triangle fit={
|
||||
% top=\fittriangletop.north,
|
||||
% nodes={\fittriangletop\foresteoption{fit these}},
|
||||
% #1
|
||||
% }];
|
||||
% },
|
||||
% },
|
||||
% },
|
||||
% },
|
||||
% }
|
191
tikzlibrarytriangle-fit.code.tex
Normal file
191
tikzlibrarytriangle-fit.code.tex
Normal file
|
@ -0,0 +1,191 @@
|
|||
% %%%%%%%
|
||||
% % From http://tex.stackexchange.com/questions/314053/how-to-declare-a-tikz-directory-or-group-of-keys/314065?noredirect=1#comment765927_314065
|
||||
% \pgfkeys{
|
||||
% /handlers/.is directory/.code={
|
||||
% \pgfkeysedef{\pgfkeyscurrentpath}{
|
||||
% \noexpand\pgfkeys{\pgfkeyscurrentpath/.cd,##1}
|
||||
% }
|
||||
% }
|
||||
% }
|
||||
% %%%%%%%
|
||||
|
||||
\ifx\pgfmathsign\relax%
|
||||
\tikzmath{
|
||||
function sign(\x) {
|
||||
if (\x < 0) then {
|
||||
return -1;
|
||||
} else {
|
||||
if (\x > 0) then {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
\fi%
|
||||
|
||||
\newif\iftrianglefitisosceles
|
||||
\newif\iftrianglefitbackground
|
||||
\tikzset{
|
||||
triangle fit current style/.style={},
|
||||
triangle fit current background style/.style={},
|
||||
triangle fit/.unknown/.code={
|
||||
% \message{triangle fit unknown:\pgfkeyscurrentkeyRAW=#1^^J}
|
||||
\let\trianglefitstorekey=\pgfkeyscurrentkeyRAW
|
||||
\edef\triangleExp{
|
||||
\noexpand\tikzset{
|
||||
/tikz/triangle fit current style/.append style={
|
||||
\trianglefitstorekey=\noexpand#1
|
||||
}
|
||||
}
|
||||
}
|
||||
\triangleExp
|
||||
%\pgfqkeys{/tikz}{}
|
||||
},
|
||||
triangle fit/triangle sep/.initial=0.15em,
|
||||
triangle fit/triangle sep/.default=0.15em,
|
||||
triangle fit/top space/.initial=1.5ex,
|
||||
triangle fit/top space/.default=1.5ex,
|
||||
triangle fit/top xshift/.initial=0pt,
|
||||
triangle fit/top xshift/.default=0pt,
|
||||
triangle fit/bottom space/.initial=0ex,
|
||||
triangle fit/bottom space/.default=0ex,
|
||||
triangle fit/top/.initial=,
|
||||
triangle fit/nodes/.initial=,
|
||||
triangle fit/no rounded corners/.style={/tikz/rounded corners=0pt},
|
||||
every triangle fit/.style={
|
||||
triangle sep=.15em,
|
||||
rounded corners=5pt,
|
||||
isosceles,
|
||||
},
|
||||
triangle fit/isosceles/.is if=trianglefitisosceles,
|
||||
triangle fit/not isosceles/.style={isosceles=false},
|
||||
triangle fit/bg+/.code={
|
||||
\tikzset{
|
||||
triangle fit current background style/.style={#1},
|
||||
}
|
||||
},
|
||||
triangle fit/.code={
|
||||
\tikzset{
|
||||
/tikz/triangle fit current style/.style={},
|
||||
/tikz/triangle fit/.cd,
|
||||
/tikz/every triangle fit,
|
||||
#1,
|
||||
}
|
||||
% \node[draw, /tikz/every triangle fit] {EEE}
|
||||
% \edef\currenttrianglestyle{\pgfkeysvalueof{/tikz/triangle fit/style}}
|
||||
% \message{\currenttrianglestyle}
|
||||
% \tikzset{
|
||||
% triangle fit current style/.style=\currenttrianglestyle,
|
||||
% }
|
||||
% Compute the minimum and maxiumum slope, as well as the maximum y (i.e. height) for the triangle.
|
||||
\tikzmath{
|
||||
coordinate \pt,\ttop;
|
||||
% int \found;
|
||||
% \found{top} = 0;
|
||||
% \found{bot} = 0;
|
||||
\ttop=(\pgfkeysvalueof{/tikz/triangle fit/top}) + (\pgfkeysvalueof{/tikz/triangle fit/top xshift},\pgfkeysvalueof{/tikz/triangle fit/top space}+\pgfkeysvalueof{/tikz/triangle fit/triangle sep});
|
||||
\slopeleft = 0;
|
||||
\sloperight = 0;
|
||||
\maxdy = 0;
|
||||
}
|
||||
% Foreach loop over all nodes, which computes the max and min slopes and triangle height
|
||||
\edef\triangleFitItems{\pgfkeysvalueof{/tikz/triangle fit/nodes}}
|
||||
\foreach \i in \triangleFitItems{
|
||||
\foreach \ii/\sgx/\sgy in {(\i.north east)/1/1,(\i.south east)/1/-1,(\i.south west)/-1/-1,(\i.north west)/-1/1} {
|
||||
\tikzmath{
|
||||
\pt = \ii;
|
||||
\dx = \ptx - \ttopx;
|
||||
\dx = \dx + \pgfkeysvalueof{/tikz/triangle fit/triangle sep} * \sgx;%sign(\dx);
|
||||
\dy = \ttopy - \pty;
|
||||
\dy = \dy + \pgfkeysvalueof{/tikz/triangle fit/triangle sep} * \sgy;%sign(\dy);
|
||||
\slope = \dx / \dy;
|
||||
if \slope > \sloperight then {
|
||||
\sloperight = \slope;
|
||||
};
|
||||
if \slope < \slopeleft then {
|
||||
\slopeleft = \slope;
|
||||
};
|
||||
if \dy > \maxdy then {
|
||||
\maxdy = \dy;
|
||||
};
|
||||
}
|
||||
% \begin{pgfonlayer}{foreground}
|
||||
% \path (\ttopx,\ttopy) ++(\dx pt,-\dy pt) node[fill=blue,circle,inner sep=0.3pt] {};
|
||||
% \end{pgfonlayer}
|
||||
\global\let\sloperight\sloperight%
|
||||
\global\let\slopeleft\slopeleft%
|
||||
\global\let\maxdy\maxdy%
|
||||
% \message{\ii, ptx=\ptx, pty=\pty, dx=\dx, dy=\dy, slope=\slope, sloperight=\sloperight, slopeleft=\slopeleft, maxdy=\maxdy^^J}
|
||||
}
|
||||
}
|
||||
\tikzmath{
|
||||
\maxdy = \maxdy + \pgfkeysvalueof{/tikz/triangle fit/bottom space};
|
||||
}
|
||||
\iftrianglefitisosceles
|
||||
\tikzmath{
|
||||
if -\sloperight < \slopeleft then {
|
||||
\slopeleft = -\sloperight;
|
||||
};
|
||||
if -\slopeleft > \sloperight then {
|
||||
\sloperight = -\slopeleft;
|
||||
};
|
||||
}
|
||||
\fi
|
||||
% Draw the background
|
||||
\begin{pgfonlayer}{background}
|
||||
\path[/tikz/triangle fit current style, /tikz/triangle fit current background style]
|
||||
(\ttopx,\ttopy)
|
||||
-- +(\sloperight*\maxdy pt,-\maxdy pt)
|
||||
-- +(\slopeleft*\maxdy pt,-\maxdy pt)
|
||||
-- cycle;
|
||||
\end{pgfonlayer}
|
||||
%
|
||||
% Draw the triangle:
|
||||
\begin{pgfonlayer}{background}% Draw it on the background, it gives better results for now.
|
||||
\draw[/tikz/triangle fit current style]
|
||||
(\ttopx,\ttopy)
|
||||
-- +(\sloperight*\maxdy pt,-\maxdy pt)
|
||||
-- +(\slopeleft*\maxdy pt,-\maxdy pt)
|
||||
-- cycle;
|
||||
\end{pgfonlayer}
|
||||
}
|
||||
}
|
||||
|
||||
\def\nodx{
|
||||
node[draw, every triangle fit, triangle fit={top={\fittriangletop},nodes={\fittriangletop\foresteoption{fit these}}}] {nodes:\fittriangletop\foresteoption{fit these}}
|
||||
}
|
||||
\forestset{
|
||||
% every triangle fit/.forward to=/tikz/every triangle fit,
|
||||
every triangle fit/append/.forward to=/tikz/every triangle fit/append,
|
||||
every triangle fit/style/.forward to=/tikz/every triangle fit/style,
|
||||
declare toks={fit these}{},
|
||||
triangle fit whole subtree/.style={
|
||||
delay={
|
||||
temptoksa=,
|
||||
for descendants={%
|
||||
temptoksa+/.wrap pgfmath arg={,##1}{name()},
|
||||
},
|
||||
fit these/.register=temptoksa,
|
||||
delay={
|
||||
% /utils/exec={
|
||||
% \pgfmathsetmacro{\fittriangletop}{name()}
|
||||
% \message{^^JFIT THESE=\foresteoption{fit these}, NAME=\fittriangletop^^J}
|
||||
% },
|
||||
% append after command={
|
||||
% \nodx
|
||||
% },
|
||||
tikz+={
|
||||
\pgfmathsetmacro{\fittriangletop}{name()}
|
||||
% \message{\foresteoption{fit these}}
|
||||
\path[triangle fit={
|
||||
top=\fittriangletop.parent anchor,
|
||||
nodes={\fittriangletop\foresteoption{fit these}},
|
||||
#1
|
||||
}];
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
BIN
travis-deploy-key-id_rsa.enc
Normal file
BIN
travis-deploy-key-id_rsa.enc
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user