Skip to content

Commit

Permalink
initial commit for GitHub
Browse files Browse the repository at this point in the history
  • Loading branch information
davidweichiang committed Dec 16, 2022
0 parents commit 626f1e3
Show file tree
Hide file tree
Showing 11 changed files with 1,163 additions and 0 deletions.
7 changes: 7 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright 2002, 2009 by David Chiang

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# tikz-qtree

Version 1.2 (20 Apr 2012)

This package provides a macro for drawing trees with TikZ using the
easy syntax of Alexis Dimitriadis'
[Qtree](https://ctan.org/pkg/qtree). It improves on TikZ's standard
tree-drawing facility by laying out tree nodes without collisions, and
it improves on Qtree by adding lots of features from TikZ (for
example, edge labels, arrows between nodes).

Please see tikz-qtree-manual.pdf for instructions and examples.

Version history:
1.2 (2012/04/20)
- level-specific styles (thanks to Andrew Stacey)

1.12 (2011/10/10)
- fixed bug that was inserting spaces

1.11 (2010/12/25):
- options don't break options for standard TikZ trees

1.1 (2009/12/25):
- much deeper trees can be typeset without exceeding capacity
- sideways trees
- extra package for improved Qtree compatibility
- connections can be drawn to whole subtrees instead of nodes

1 (2009/12/22):
- initial release

## Credits

David Chiang ([email protected])

## License

This package is available under the MIT License. Please see LICENSE.md
for details.
4 changes: 4 additions & 0 deletions pgfsubpic.sty
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\RequirePackage{pgf}

\input{pgfsubpic.tex}
\endinput
209 changes: 209 additions & 0 deletions pgfsubpic.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
% pgfsubpic.tex
% Version 1.1, 25 Dec 2009

% Copyright 2009 by David Chiang

% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.

% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.

% You should have received a copy of the GNU General Public License along
% with this program; if not, write to the Free Software Foundation, Inc.,
% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

% New in version 1.1:
% - the ability to save a subpicture in local variables
% - nodes in subpictures are tracked if the subpicture is placed with arbitrary transforms
% - new \pgffitsubpicture macro to transform a subpicture (preserving aspect) to fit in a desired box

\newdimen\pgf@subpicminx
\newdimen\pgf@subpicminy
\newdimen\pgf@subpicmaxx
\newdimen\pgf@subpicmaxy

% Special virtual node for current subpicture's bounding box
\expandafter\def\csname pgf@sh@ns@current subpicture\endcsname{rectangle}
\expandafter\def\csname pgf@sh@np@current subpicture\endcsname{%
\def\southwest{\pgfqpoint{\pgf@subpicminx}{\pgf@subpicminy}}%
\def\northeast{\pgfqpoint{\pgf@subpicmaxx}{\pgf@subpicmaxy}}%
}
\expandafter\def\csname pgf@sh@nt@current subpicture\endcsname{{\pgf@pt@aa}{\pgf@pt@ab}{\pgf@pt@ba}{\pgf@pt@bb}{\the\pgf@pt@x}{\the\pgf@pt@y}} % the transformation at invocation time
\expandafter\def\csname pgf@sh@pi@current subpicture\endcsname{\pgfpictureid}

% Create a pgfpicture inside an hbox for delayed placement
\def\pgfsubpicture{%
\expandafter\global\expandafter\setbox\pgf@hbox=\hbox\bgroup
\pgfinterruptpicture
\pgfpicture
\relax % not sure why. otherwise a curly brace immediately after causes an error
}

\def\endpgfsubpicture{
\global\pgf@subpicminx=\pgf@picminx
\global\pgf@subpicminy=\pgf@picminy
\global\pgf@subpicmaxx=\pgf@picmaxx
\global\pgf@subpicmaxy=\pgf@picmaxy
\global\edef\subpictureid{\pgfpictureid}%
\pgfsetbaseline{\pgf@picminy}%
\endpgfpicture%
\endpgfinterruptpicture%
\egroup
}

% Allocate registers for saving a subpicture. #1 is text, not a control sequence.
\def\pgfnewsubpicture#1{%
\expandafter\newbox\csname pgf@subpic@hbox@#1\endcsname
\expandafter\newdimen\csname pgf@subpic@minx@#1\endcsname
\expandafter\newdimen\csname pgf@subpic@miny@#1\endcsname
\expandafter\newdimen\csname pgf@subpic@maxx@#1\endcsname
\expandafter\newdimen\csname pgf@subpic@maxy@#1\endcsname
}

% saved subpictures are local to the current group
\def\pgfsavesubpicture#1{%
\expandafter\setbox\csname pgf@subpic@hbox@#1\endcsname\box\pgf@hbox
\csname pgf@subpic@minx@#1\endcsname\pgf@subpicminx
\csname pgf@subpic@miny@#1\endcsname\pgf@subpicminy
\csname pgf@subpic@maxx@#1\endcsname\pgf@subpicmaxx
\csname pgf@subpic@maxy@#1\endcsname\pgf@subpicmaxy
\expandafter\edef\csname pgf@subpic@id@#1\endcsname{\subpictureid}%
}

% place current subpicture into named subpicture
\def\pgfmergesubpicture#1{%
\begin{pgfsubpicture}
% place current subpicture
\pgfplacesubpicture
% override containing picture
\expandafter\xdef\csname pgf@sh@pi@\subpictureid\endcsname{\csname pgf@subpic@id@#1\endcsname}%
% copy contents of #1
\pgfrestoresubpicture{#1}
\pgflowlevelobj{\pgftransformshift{\pgfqpoint{\the\pgf@subpicminx}{\the\pgf@subpicminy}}}{\pgfqbox\pgf@hbox}
\pgfpathrectanglecorners{\pgfqpoint{\the\pgf@subpicminx}{\the\pgf@subpicminy}}{\pgfqpoint{\the\pgf@subpicmaxx}{\the\pgf@subpicmaxy}}%
\pgfusepath{use as bounding box}%
%
\end{pgfsubpicture}
\expandafter\setbox\csname pgf@subpic@hbox@#1\endcsname\box\pgf@hbox
\csname pgf@subpic@minx@#1\endcsname\pgf@subpicminx
\csname pgf@subpic@miny@#1\endcsname\pgf@subpicminy
\csname pgf@subpic@maxx@#1\endcsname\pgf@subpicmaxx
\csname pgf@subpic@maxy@#1\endcsname\pgf@subpicmaxy
% but don't save the new picture id, keep the existing one
}

\def\pgfrestoresubpicture#1{%
\edef\act{\global\noexpand\setbox\pgf@hbox\noexpand\box\csname pgf@subpic@hbox@#1\endcsname}\act
\expandafter\global\expandafter\pgf@subpicminx\csname pgf@subpic@minx@#1\endcsname
\expandafter\global\expandafter\pgf@subpicminy\csname pgf@subpic@miny@#1\endcsname
\expandafter\global\expandafter\pgf@subpicmaxx\csname pgf@subpic@maxx@#1\endcsname
\expandafter\global\expandafter\pgf@subpicmaxy\csname pgf@subpic@maxy@#1\endcsname
\xdef\subpictureid{\csname pgf@subpic@id@#1\endcsname}%
}

% Place a previously-created subpicture, lining up its origin with the current origin
\def\pgfplacesubpicture{
\pgfscope
% expand current bounding box to accommodate subpicture
\pgfpathrectanglecorners{\pgfqpoint{\the\pgf@subpicminx}{\the\pgf@subpicminy}}{\pgfqpoint{\the\pgf@subpicmaxx}{\the\pgf@subpicmaxy}}%
\pgfusepath{use as bounding box}%
%
% make the subpicture a node in the containing picture
\expandafter\gdef\csname pgf@sh@ns@\subpictureid\endcsname{rectangle}%
\expandafter\xdef\csname pgf@sh@np@\subpictureid\endcsname{%
\noexpand\def\noexpand\southwest{\noexpand\pgfqpoint{\the\pgf@subpicminx}{\the\pgf@subpicminy}}%
\noexpand\def\noexpand\northeast{\noexpand\pgfqpoint{\the\pgf@subpicmaxx}{\the\pgf@subpicmaxy}}%
}%
\pgfgettransform\pgf@temp
\expandafter\xdef\csname pgf@sh@nt@\subpictureid\endcsname{\pgf@temp}%
\expandafter\xdef\csname pgf@sh@pi@\subpictureid\endcsname{\pgfpictureid}%
%
% align origin of subpicture with origin
\pgftransformshift{\pgfqpoint{\the\pgf@subpicminx}{\the\pgf@subpicminy}}%
\pgfqboxsynced{\pgf@hbox}%
\endpgfscope
}

% Hook onto existing macro \pgf@shape@interpictureshift.
% This is called whenever we look up an anchor of a node.
% This hook recursively checks to see if the node's picture
% is a subpicture of another, and if so, adjusts its position accordingly.

% This is slow. It makes drawing trees O(n^2) in the depth of the tree.
% The alternative is to store, for each picture, a list of the nodes
% inside it. But this way doesn't require us to hijack \pgfnode, and
% is robust to re-placement of a subpicture. A compromise would be
% to store, for each picture, a list of the *subpictures* inside it.

\let\orig@pgf@shape@interpictureshift\pgf@shape@interpictureshift
\def\unwind@subpic#1{%
% is #1 the current picture?
\edef\subpicid{#1}%
\ifx\subpicid\pgfpictureid
% yes, we're done
\else
% does #1 have a parent picture?
\expandafter\ifx\csname pgf@sh@pi@#1\endcsname\relax
% no, the original node was not inside the current picture
\fallback
\else
% yes, apply transform and move up to parent picture
{%
\pgfsettransform{\csname pgf@sh@nt@#1\endcsname}%
\pgf@pos@transform{\pgf@x}{\pgf@y}%
\global\pgf@x=\pgf@x
\global\pgf@y=\pgf@y
}%
\unwind@subpic{\csname pgf@sh@pi@#1\endcsname}%
\fi
\fi
}
\def\pgf@shape@interpictureshift#1{%
\edef\fallback{\pgf@x=\the\pgf@x\pgf@y=\the\pgf@y\noexpand\orig@pgf@shape@interpictureshift{#1}}%
\unwind@subpic{\csname pgf@sh@pi@#1\endcsname}%
}

% \pgffitsubpicture{sw}{ne}
% Make the subpicture fit in the rectangle from sw to ne, preserving its aspect ratio.
\def\pgffitsubpicture#1#2{%
% current size
\pgfpointdiff{\pgfpointanchor{current subpicture}{south west}}{\pgfpointanchor{current subpicture}{north east}}%
\pgf@xa=\pgf@x \pgf@ya=\pgf@y
% desired size
\pgf@process{\pgfpointdiff{#1}{#2}}%
\pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgfmathparse{min(\pgf@xb/\pgf@xa,\pgf@yb/\pgf@ya)}%
\pgfmathparse{min(1,\pgfmathresult)}%
\pgftransformscale{\pgfmathresult}%
%
% current position
\pgfpointanchor{current subpicture}{center}%
\pgf@xa=\pgf@x \pgf@ya=\pgf@y
% desired position
% we scaled transform, so apply reverse scaling to argument
\pgfmathparse{1/\pgfmathresult}%
\pgf@process{\pgfpointscale{\pgfmathresult}{\pgfpointlineattime{0.5}{#1}{#2}}}%
\pgf@xb=\pgf@x \pgf@yb=\pgf@y
\pgfpointdiff{\pgfpoint{\pgf@xa}{\pgf@ya}}{\pgfpoint{\pgf@xb}{\pgf@yb}}%
\pgftransformshift{\pgfpoint{\pgf@x}{\pgf@y}}%
}

% utility functions -- not currently used

\def\pgfnodedelete#1{%
\expandafter\global\expandafter\let\csname pgf@sh@ns@#1\endcsname\relax
\expandafter\global\expandafter\let\csname pgf@sh@np@#1\endcsname\relax
\expandafter\global\expandafter\let\csname pgf@sh@nt@#1\endcsname\relax
\expandafter\global\expandafter\let\csname pgf@sh@pi@#1\endcsname\relax
\expandafter\global\expandafter\let\csname pgf@sh@ma@#1\endcsname\relax
}

\def\pgfnodeifexists#1#2#3{%
\expandafter\ifx\csname pgf@sh@ns@#1\endcsname\relax#3\else#2\fi
}

6 changes: 6 additions & 0 deletions pgftree.sty
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
\RequirePackage{pgf}
\RequirePackage{pgffor}
\RequirePackage{pgfsubpic}

\input{pgftree.tex}
\endinput
Loading

0 comments on commit 626f1e3

Please sign in to comment.