280 lines
7.1 KiB
Plaintext
280 lines
7.1 KiB
Plaintext
|
%%
|
||
|
%% Copyright (C) 2014 by Julien Cretel <jubobs.tex at gmail.com>
|
||
|
%%
|
||
|
%% 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 Julien Cretel.
|
||
|
%%
|
||
|
%% This work currently consists of the file gitdags.sty.
|
||
|
%%
|
||
|
\NeedsTeXFormat{LaTeX2e}[2011/06/27]
|
||
|
\ProvidesClass{gitdags}
|
||
|
[2014/08/28 v0.1 A package for drawing educational Git history graphs]
|
||
|
|
||
|
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{tikz}}
|
||
|
\ProcessOptions\relax
|
||
|
|
||
|
\RequirePackage{xcolor-solarized}
|
||
|
\RequirePackage{tikz}
|
||
|
\usetikzlibrary{
|
||
|
arrows.meta,
|
||
|
graphs,
|
||
|
positioning,
|
||
|
shadows,
|
||
|
shapes,
|
||
|
}
|
||
|
|
||
|
% conflict color
|
||
|
\colorlet{conflictcolor}{red}
|
||
|
|
||
|
% custom shape, adapted from 102.5.3 in the TikZ 3.0 manual
|
||
|
\pgfdeclareshape{dogeared}{
|
||
|
\inheritsavedanchors[from=rectangle]
|
||
|
\inheritanchorborder[from=rectangle]
|
||
|
\inheritanchor[from=rectangle]{center}
|
||
|
\inheritanchor[from=rectangle]{north}
|
||
|
\inheritanchor[from=rectangle]{south}
|
||
|
\inheritanchor[from=rectangle]{west}
|
||
|
\inheritanchor[from=rectangle]{east}
|
||
|
\backgroundpath{%
|
||
|
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
|
||
|
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
|
||
|
\pgf@xc=\pgf@xb \advance\pgf@xc by-5pt
|
||
|
\pgf@yc=\pgf@yb \advance\pgf@yc by-5pt
|
||
|
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
|
||
|
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
|
||
|
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yb}}
|
||
|
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
|
||
|
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
|
||
|
\pgfpathclose
|
||
|
\pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@yb}}
|
||
|
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
|
||
|
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
|
||
|
\pgfpathclose
|
||
|
}
|
||
|
}
|
||
|
|
||
|
% To cancel a shadow (see http://tex.stackexchange.com/a/198298/21891)
|
||
|
\tikzset{reset preaction/.code={\def\tikz@preactions{}}}
|
||
|
|
||
|
% --- repository history graphs ---
|
||
|
% style definitions
|
||
|
\tikzset{
|
||
|
gitdags node/.style={
|
||
|
draw,
|
||
|
node distance = 1.4em,
|
||
|
drop shadow = {opacity=0.15},
|
||
|
font = \fontfamily{lmtt}\selectfont\small,
|
||
|
},
|
||
|
DAGref/.style={
|
||
|
gitdags node,
|
||
|
shape = rectangle,
|
||
|
minimum height = 1.4em,
|
||
|
draw = solarized-base01,
|
||
|
thick,
|
||
|
font = \fontfamily{lmtt}\selectfont\scriptsize,
|
||
|
},
|
||
|
DAGedge/.style={
|
||
|
semithick,
|
||
|
Latex-,
|
||
|
draw = gray,
|
||
|
},
|
||
|
DAGrefedge/.style={
|
||
|
DAGedge,
|
||
|
thick,
|
||
|
densely dotted,
|
||
|
},
|
||
|
DAGcommit/.style={
|
||
|
gitdags node,
|
||
|
shape = rounded rectangle,
|
||
|
rounded rectangle arc length = 90,
|
||
|
minimum height = 1.6em,
|
||
|
minimum width = 2em,
|
||
|
draw = solarized-base01,
|
||
|
fill = solarized-green!20,
|
||
|
very thick,
|
||
|
},
|
||
|
graphs/DAG/.style={
|
||
|
nodes = DAGcommit,
|
||
|
edges = DAGedge,
|
||
|
branch down = 3em,
|
||
|
grow right sep = 1.5em,
|
||
|
},
|
||
|
gitareas/.style={
|
||
|
gitdags node,
|
||
|
shape = rectangle,
|
||
|
rounded corners = .5em,
|
||
|
minimum width = 7em,
|
||
|
minimum height = 3em,
|
||
|
text opacity = 0.75,
|
||
|
semithick,
|
||
|
},
|
||
|
gitSA/.style={
|
||
|
gitareas,
|
||
|
anchor = north west,
|
||
|
xshift = 1em,
|
||
|
yshift = -1em,
|
||
|
draw = solarized-orange,
|
||
|
fill = solarized-orange!5,
|
||
|
text = solarized-orange,
|
||
|
},
|
||
|
gitWT/.style={
|
||
|
gitareas,
|
||
|
node distance = .6em,
|
||
|
draw = solarized-violet,
|
||
|
fill = solarized-violet!5,
|
||
|
text = solarized-violet,
|
||
|
},
|
||
|
resetarrows/.style={
|
||
|
-Stealth,
|
||
|
dashed,
|
||
|
thick,
|
||
|
draw = solarized-base02,
|
||
|
draw opacity = .75,
|
||
|
},
|
||
|
highlighted commit/.style={
|
||
|
DAGcommit,
|
||
|
reset preaction,
|
||
|
fill opacity = 0,
|
||
|
draw = solarized-base02,
|
||
|
},
|
||
|
problematic commits/.style={
|
||
|
reset preaction,
|
||
|
draw opacity = .25,
|
||
|
fill opacity = .25,
|
||
|
},
|
||
|
graphs/unreachable/.style={
|
||
|
problematic commits,
|
||
|
target edge style = problematic commits,
|
||
|
},
|
||
|
graphs/conflict/.style={
|
||
|
empty nodes,
|
||
|
problematic commits,
|
||
|
target edge style = problematic commits,
|
||
|
draw = conflictcolor,
|
||
|
fill = conflictcolor!25,
|
||
|
},
|
||
|
placeholder commits/.style={
|
||
|
reset preaction,
|
||
|
draw opacity = 0,
|
||
|
fill opacity = 0,
|
||
|
},
|
||
|
graphs/placeholder/.style={
|
||
|
placeholder commits,
|
||
|
target edge style = placeholder commits,
|
||
|
},
|
||
|
blob/.style={
|
||
|
shape = dogeared,
|
||
|
minimum width = 2em,
|
||
|
minimum height = 2.82em,
|
||
|
node distance = .75em,
|
||
|
line join = bevel,
|
||
|
draw = black,
|
||
|
fill = white,
|
||
|
align = left,
|
||
|
font = \ttfamily\tiny,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
% directed acyclic graph
|
||
|
\newcommand\gitDAG[1][]{\graph[DAG,#1]}
|
||
|
|
||
|
% helper macro (let's check the name's availability)
|
||
|
\newcommand\nodename@gitdags{}
|
||
|
|
||
|
% local-branch reference
|
||
|
\newcommand\gitbranch[4][]{%
|
||
|
\renewcommand\nodename@gitdags{#1}%
|
||
|
\if\relax\detokenize{#1}\relax% check for empty optional argument
|
||
|
\renewcommand\nodename@gitdags{#2}%
|
||
|
\fi
|
||
|
\node[
|
||
|
DAGref,
|
||
|
fill = yellow!30,
|
||
|
] (\nodename@gitdags) [#3] {#2};
|
||
|
\draw[DAGrefedge] (#4) -- (\nodename@gitdags);
|
||
|
}
|
||
|
|
||
|
% remote-branch reference
|
||
|
\newcommand\gitremotebranch[4][]{%
|
||
|
\renewcommand\nodename@gitdags{#1}%
|
||
|
\if\relax\detokenize{#1}\relax% check for empty optional argument
|
||
|
\renewcommand\nodename@gitdags{#2}%
|
||
|
\fi
|
||
|
\node[
|
||
|
DAGref,
|
||
|
fill = solarized-blue!20,
|
||
|
] (\nodename@gitdags) [#3] {#2};
|
||
|
\draw[DAGrefedge] (#4) -- (\nodename@gitdags);
|
||
|
}
|
||
|
|
||
|
% tag reference
|
||
|
\newcommand\gittag[4][]{%
|
||
|
\renewcommand\nodename@gitdags{#1}%
|
||
|
\if\relax\detokenize{#1}\relax% check for empty optional argument
|
||
|
\renewcommand\nodename@gitdags{#2}%
|
||
|
\fi
|
||
|
\node[
|
||
|
DAGref,
|
||
|
fill = solarized-magenta!20,
|
||
|
] (\nodename@gitdags) [#3] {#2};
|
||
|
\draw[DAGrefedge] (#4) -- (\nodename@gitdags);
|
||
|
}
|
||
|
|
||
|
% HEAD symbolic reference
|
||
|
\newcommand\gitHEAD[2]{%
|
||
|
\node[
|
||
|
DAGref,
|
||
|
fill = solarized-red!20,
|
||
|
node distance = 1em,
|
||
|
] (gitHEAD) [#1] {HEAD};
|
||
|
\draw[DAGrefedge] (#2) -- (gitHEAD);
|
||
|
}
|
||
|
|
||
|
% the following macro is useful for explaining how merge conflicts arise
|
||
|
\newcommand\gitblob[2][]
|
||
|
{\node[blob,#1] {#2};}
|
||
|
|
||
|
% to highlight a merge conflict arising in a given file
|
||
|
\newcommand\gitblobmc[1]{%
|
||
|
\node[
|
||
|
blob,
|
||
|
draw = conflictcolor,
|
||
|
text = conflictcolor,
|
||
|
font = \scriptsize,
|
||
|
#1] {???};
|
||
|
}
|
||
|
|
||
|
% staging area and worktree
|
||
|
\newcommand\SAandWT{%
|
||
|
\node[
|
||
|
gitSA,
|
||
|
] (stagingarea) at (current bounding box.south east) {staging area};
|
||
|
\node[
|
||
|
gitWT,
|
||
|
below=of stagingarea,
|
||
|
] (workingtree) {working tree};
|
||
|
}
|
||
|
|
||
|
% arrows pointing from a commit to the staging area or working tree
|
||
|
\newcommand\toSAorWT[2]{%
|
||
|
\node[highlighted commit] at (#1) {\phantom{#1}};
|
||
|
\draw[resetarrows] (#1.south) to[out=290, in=170]
|
||
|
([xshift=1em,yshift=-1em]#2.north west);
|
||
|
}
|
||
|
|
||
|
\newcommand\toSAfrom[1]{\toSAorWT{#1}{stagingarea}}
|
||
|
\newcommand\toWTfrom[1]{\toSAorWT{#1}{workingtree}}
|
||
|
|
||
|
\endinput
|