aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamil Staps2017-10-27 19:31:03 +0200
committerCamil Staps2017-10-27 19:31:03 +0200
commit9da3745a02e1760c1360a3e5d64090ab68374d99 (patch)
tree75a3d143d4511f38e88ee213d40e167d09f090ca
parentIntroduction, history, architecture (diff)
First rough version of full presentation
-rw-r--r--beamercolorthemecloogle.sty11
-rw-r--r--cloogle.tex412
-rw-r--r--clooglearch.sty113
-rw-r--r--scrot-search-class.pngbin0 -> 35204 bytes
-rw-r--r--scrot-search-name.pngbin0 -> 18268 bytes
-rw-r--r--scrot-search-typedef.pngbin0 -> 31663 bytes
-rw-r--r--scrot-search-unify.pngbin0 -> 22930 bytes
7 files changed, 417 insertions, 119 deletions
diff --git a/beamercolorthemecloogle.sty b/beamercolorthemecloogle.sty
index 1bdac31..165d7ce 100644
--- a/beamercolorthemecloogle.sty
+++ b/beamercolorthemecloogle.sty
@@ -12,8 +12,9 @@
\setbeamercolor{section in toc}{parent=normal text}
\setbeamercolor*{structure}{parent=normal text}
-\setbeamercolor*{palette secondary}{fg=cloogledark,bg=clooglelight}
-\setbeamercolor*{palette tertiary}{bg=clooglemain,fg=gray!5!white}
+\setbeamercolor*{palette primary}{fg=cloogledark,bg=clooglelight}
+\setbeamercolor*{palette secondary}{fg=cloogledark,bg=clooglelight!50!clooglemain}
+\setbeamercolor*{palette tertiary}{fg=gray!5!white,bg=clooglemain}
\setbeamercolor*{sidebar}{fg=darkred,bg=gray!15!white}
@@ -22,9 +23,9 @@
\setbeamercolor*{palette sidebar tertiary}{fg=darkred!50!black}
\setbeamercolor*{palette sidebar quaternary}{fg=gray!10!white}
-\setbeamercolor{titlelike}{parent=palette primary}
-\setbeamercolor{frametitle}{bg=clooglelightest}
-\setbeamercolor{frametitle right}{bg=gray!60!white}
+\setbeamercolor*{titlelike}{use=structure,fg=cloogledarkest}
+\setbeamercolor*{frametitle}{fg=cloogledarkest,bg=clooglelightest}
+\setbeamercolor*{frametitle right}{bg=gray!60!white}
\setbeamercolor*{separation line}{}
\setbeamercolor*{fine separation line}{}
diff --git a/cloogle.tex b/cloogle.tex
index 7d5023d..a45822c 100644
--- a/cloogle.tex
+++ b/cloogle.tex
@@ -1,161 +1,345 @@
\documentclass{beamer}
+\let\oldhref\href
+\def\href#1#2{\oldhref{#1}{\color{cloogledark!50!clooglemain} #2}}
+\def\https#1{\href{https://#1}{#1}}
+\def\mailto#1{\href{mailto:#1}{#1}}
+
\title{Cloogle}
\subtitle{A programming language search engine and its applications}
-\author{Camil Staps}
+\author[Camil Staps]{\texorpdfstring{Camil Staps\\[1em]\footnotesize\mailto{camil@cloogle.org}}{Camil Staps}}
\date{January 5\textsuperscript{th}, 2018}
-\usetheme{Szeged}
+\usetheme{CambridgeUS}
\usecolortheme{cloogle}
+\useinnertheme{circles}
+\setbeamertemplate{itemize item}[triangle]
+\setbeamertemplate{itemize subitem}[circle]
\usepackage[british]{babel}
\usepackage{csquotes}
\usepackage{tikz}
-\usetikzlibrary{calc,positioning}
-\newcommand{\module}[2]{#2\\[-4pt]\color{gray}{\tiny(#1)}}
-\tikzstyle{block}=[rectangle,align=center]
-\tikzset{
- doc/.pic={
- \coordinate (-east) at (0.309,0);
- \coordinate (-south) at (0,-0.4);
- \draw[pic actions] (-0.309,-0.4) -- ++(0,0.8) -- ++(0.518,0) -- ++(0,-0.1) -- ++(0.1,0) -- ++(0,-0.7) -- cycle;
- \draw[pic actions] (0.209,0.4) -- ++(0.1,-0.1);
- \draw[pic actions] (-0.209,-0.1) -- ++(0.418,0);
- \draw[pic actions] (-0.209, 0) -- ++(0.418,0);
- \draw[pic actions] (-0.209, 0.1) -- ++(0.418,0);
- },
- db/.pic={
- % https://tex.stackexchange.com/a/397862/23992
- \coordinate (-west) at (-0.3,0);
- \coordinate (-east) at ( 0.3,0);
- \coordinate (-south) at (0,-0.42);
- \foreach \y in {-0.33,-0.1,0.13} {
- \draw[fill=white] (-0.3,\y) to [looseness=0.5,bend right=90] ++(0.6,0)
- -- ++(0,0.2) to [looseness=0.5,bend left=90] ++(-0.6,0)
- -- ++(0,-0.2);
- \draw (-0.3,\y+0.2) edge[looseness=0.5,bend left=90] ++(0.6,0);
- }
- }
-}
+\usepackage{clooglearch}
\usepackage{minted}
\setminted{fontsize=\small}
+% https://tex.stackexchange.com/a/23522/23992
+\def\imagetop#1{\vtop{\null\hbox{#1}}}
+
\begin{document}
\maketitle
\section{Background}
+\subsection{Why build a search engine?}
\begin{frame}[fragile]{Background}
- What is wrong with this code?
-
- \begin{minted}[gobble=2]{clean}
- incAll :: [Int] -> [Int]
- incAll [] = []
- incAll [x:xs] = [x+1:incAll xs]
+ \begin{itemize}[<+->]
+ \item
+ What is wrong with this code?
- sortByKey :: [(a,b)] -> [(a,b)] | < a
- sortByKey [] = []
- sortByKey [(k,v):xs] = sortByKey ls ++ [(k,v):sortByKey hs]
- where (ls,hs) = partition (\(k`,_) -> k > k`) xs
- \end{minted}
+ \begin{minted}[gobble=4]{clean}
+ incAll :: [Int] -> [Int]
+ incAll [] = []
+ incAll [x:xs] = [x+1:incAll xs]
+ \end{minted}
- \pause
- Better:
- \begin{minted}[gobble=2]{clean}
- incAll :== map ((+) 1)
- sortByKey :== sortBy (on (<) fst)
- \end{minted}
+ \item
+ Better:
+ \begin{minted}[gobble=4]{clean}
+ incAll = map ((+) 1)
+ \end{minted}
+ \end{itemize}
\end{frame}
\begin{frame}{Background}
Lack of abstraction due to...
\begin{itemize}
\item Poor conceptualisation of the programmer?
+ \pause
\item Poor knowledge of the standard libraries?
- \begin{itemize}
- \item \enquote{There is this function \texttt{map}, but where is it defined?}
- \end{itemize}
+
+ \medskip
+ \quad\enquote{There is this function \texttt{map}, but where is it defined?}
\end{itemize}
+ \pause
Solution: build a search engine!
\end{frame}
-\begin{frame}{History}
- \begin{itemize}
- \item February 2016: PHP regex search
- \pause
- \item April: function type search; moved to Clean
- \pause
- \item June: type definition search; included classes and generics
- \pause
- \item August: included macros
- \pause
- \item October: moved to Docker containers; caching
- \pause
- \item November: unify with type synonyms
- \end{itemize}
+
+\subsection{Functionality}
+\begin{frame}{Functionality}
+ \centering
+ \begin{tabular}{l l}
+ \imagetop{\includegraphics[width=.45\textwidth]{scrot-search-name}} & \pause
+ \imagetop{\includegraphics[width=.45\textwidth]{scrot-search-unify}} \pause\\
+ \imagetop{\includegraphics[width=.45\textwidth]{scrot-search-typedef}} \pause&
+ \imagetop{\includegraphics[width=.45\textwidth]{scrot-search-class}}
+ \end{tabular}
\end{frame}
+
+\subsection{Architecture}
\begin{frame}{Architecture}
\centering
\footnotesize
- \def\tikzsource{%
- \pic (src) at (-5,3) {doc};
- }
- \def\tikzbuilddb{%
- \node (cocl) at (-2.5, 3.5 ) {\module{Clean}{Clean compiler}};
- \node (ppr) at (-2.5, 2.5 ) {\module{Clean}{Pretty printer}};
- \pic (db) at ( 0, 2.98) {db};
- \node[right=5pt of db-east,draw=none] {\module{\tiny JSON}{\scriptsize Database}};
- \draw[->] ($(src-east)+(0,0.18)$) -- (cocl.west);
- \draw[->] ($(src-east)-(0,0.18)$) -- (ppr.west);
- \draw[->] (cocl.east) -- ($(db-west)+(0,0.18)$);
- \draw[->] (ppr.east) -- ($(db-west)-(0,0.18)$);
- }
- \def\tikzbackend{%
- \node (web) at (0, 1) {\module{Clean, PHP, JS}{\textbf{cloogle.org}}};
- \node (uni) at (2, 2) {\module{Clean}{Type unifier}};
- \draw (uni) -- (web);
- \draw[->] (db-south) -- (web);
- }
- \def\tikzfrontend{%
- \node (hljs) at (-2, 0.5) {\module{JS}{clean.js}};
- \draw (hljs) -- (web);
- }
- \def\tikzfrontendsrc{%
- \node (pygm) at (-2.25, 1.5) {\module{Python}{pygments}};
- \draw[->] (src-south) -- (pygm);
- \draw (pygm) -- (web);
- }
- \def\tikzstats{%
- \node (stats) at (3, 1) {\module{Bash, JS, PHP, SQL}{Log \& Statistics}};
- \draw (web) -- (stats);
- }
- \def\tikzclientA{%
- \node (cli) at (-2,-2) {\module{Python}{CLI app}};
- \draw[->] (web) -- (cli);
- }
- \def\tikzclientB{%
- \node (tgm) at (0,-2) {\module{Python}{Telegram bot}}; % TODO more frontends?
- \draw[->] (web) -- (tgm);
- }
- \def\tikzclientC{%
- \node (vim) at (2,-2) {\module{Vim}{vim-clean}};
- \draw[->] (web) -- (vim);
- }
\begin{tikzpicture}[every node/.style={draw,block}]
- \useasboundingbox (-5,-4) rectangle (5,4);
+ \useasboundingbox (-5,-4) rectangle (3.5,4);
\only<1->\tikzsource
- \only<1-4>{\node[below=5pt of src-south,draw=none] {\scriptsize Source code};}
+ \only<1-5>{\node[below=5pt of src-south,draw=none] {\scriptsize Source code};}
\only<2->{\tikzbuilddb}
\only<3->{\tikzbackend}
- \only<4->{\tikzfrontend}
- \only<5->{\tikzfrontendsrc}
- \only<6->{\tikzstats}
- \only<7->{\tikzclientA}
- \only<8->{\tikzclientB}
- \only<9->{\tikzclientC}
+ \only<4->{\tikzcache}
+ \only<5->{\tikzfrontend}
+ \only<6->{\tikzfrontendsrc}
+ \only<7->{\tikzstats}
+ \only<8->{\tikzclientA}
+ \only<9->{\tikzclientB}
+ \only<10->{\tikzclientC}
+ \only<11->{\tikzclientD}
+ \only<12->{\tikzclientE}
\end{tikzpicture}
\end{frame}
+\section{Recent developments}
+
+\subsection{Efficient unification search}
+\begin{frame}{Efficient unification search}
+ \begin{itemize}[<+->]
+ \item With $\pm15,000$ functions, brute force unification search takes too long
+ \item Grouping types together still gives $\pm13,000$ unique types
+ \item If type $t$ generalises $u$, any $v$ that unifies with $u$ will also unify with $t$
+ \item This gives a partial ordering on types:
+
+ \begin{center}
+ \begin{tikzpicture}[level distance=2em]
+ \tikzstyle{level 1}=[sibling distance=14em]
+ \tikzstyle{level 2}=[sibling distance=7em]
+ \tikzstyle{level 3}=[sibling distance=2em]
+ \node {$a$}
+ child {node {$a \rightarrow b$}
+ child {node {$Int \rightarrow Int$} child {node {\vdots}} child {node {\vdots}}}
+ child {node {$a~a \rightarrow a$} child {node {\vdots}}}}
+ child {node {$f~Real$}
+ child {node {$Maybe~Real$}}
+ child {node {$Either~a~Real$} child {node {\vdots}}}};
+ \end{tikzpicture}
+ \end{center}
+
+ \item Early pruning speeds up unification search with a factor of $2-3$!
+ \end{itemize}
+\end{frame}
+
+\subsection{Running locally: cloogle-tags}
+\begin{frame}[fragile]{What if we want to run Cloogle locally?}
+ \begin{itemize}
+ \item Most common use case: finding definitions in personal libraries
+ \pause
+ \item Many editors support \emph{tagfiles}:
+
+ \begin{minted}[gobble=4]{text}
+ drop StdList.dcl 46
+ fopen StdFile.dcl 27
+ ...
+ \end{minted}
+ \end{itemize}
+\end{frame}
+\begin{frame}{Running locally: old architecture}
+ \centering
+ \footnotesize
+ \begin{tikzpicture}[every node/.style={draw,block}]
+ \useasboundingbox (-5,-4) rectangle (3.5,4);
+ \tikzsource
+ \tikzbuilddb
+ \tikzbackend
+ \tikzcache
+ \tikzfrontend
+ \tikzfrontendsrc
+ \tikzstats
+ \tikzclientA
+ \tikzclientB
+ \tikzclientC
+ \tikzclientD
+ \tikzclientE
+ \end{tikzpicture}
+\end{frame}
+\begin{frame}{Running locally: new architecture}
+ \centering
+ \footnotesize
+ \begin{tikzpicture}[every node/.style={draw,block}]
+ \useasboundingbox (-5,-4) rectangle (3.5,4);
+ \tikzsource
+ \tikzbuilddb
+ \only<1>{%
+ \tikzbackend[1]
+ \tikzcache[1]
+ \tikzfrontend[1]
+ \tikzfrontendsrc[1]
+ \tikzstats[1]
+ \tikzclientA
+ \tikzclientB
+ \tikzclientC
+ \tikzclientD
+ \tikzclientE}
+ \only<2->{%
+ \tikzbackend[2]
+ \tikzcache[2]
+ \tikzfrontend[2]
+ \tikzfrontendsrc[2]
+ \tikzstats[2]
+ \tikzclientB[2]
+ \tikzclientC[2]
+ \tikzclientD[2]
+ \tikzclientE[2]
+ \tikzcloogletags}
+ \only<2>{\tikzclientA[2]}
+ \only<3>{\tikzclientA[3]}
+ \only<4>{\tikzclientA[4]}
+ \end{tikzpicture}
+\end{frame}
+
+\section{The end}
+
+\subsection{Acknowledgements}
+\begin{frame}[shrink]{Acknowledgements}
+ Cloogle was conceived and built by:
+
+ \begin{itemize}
+ \item Camil Staps
+ \item Mart Lubbers
+ \end{itemize}
+
+ With contributions by:
+
+ \begin{itemize}
+ \item Erin van der Veen
+ \item Koen Dercksen
+ \end{itemize}
+
+ Using:
+
+ \begin{itemize}
+ \item The Clean compiler (the Clean team)
+ \end{itemize}
+
+ With thanks to:
+
+ \begin{itemize}
+ \item All users, for new ideas and bug reports (explicitly or in the query log)
+ \end{itemize}
+
+ Authors of clients:
+
+ \begin{itemize}
+ \item CLI app: Koen Dercksen
+ \item IRC bot: Mart Lubbers
+ \item vim-clean, Telegram bot, email client: Camil Staps
+ \item Visual Studio Code plugin: Lucas Franceschino
+ \end{itemize}
+\end{frame}
+
+\appendix
+\newcounter{finalframe}
+\setcounter{finalframe}{\value{framenumber}}
+
+\section{Appendices}
+
+\subsection{Can I use Cloogle for language X?}
+\begin{frame}{Can I use Cloogle for language X?}
+ \begin{itemize}
+ \item It will work best on a language with the Hindley-Milner type system
+ \begin{itemize}
+ \item It can still be useful to less strongly typed languages
+ \item It would be interesting to develop a search engine for dependent types
+ \end{itemize}
+ \item The search system is language-agnostic, but you need a tool to index source code into our JSON format
+ \item Also see: \https{neilmitchell.blogspot.nl/2011/03/hoogle-for-your-language-ie-f-scala-ml.html}
+ \item Contact me!
+ \end{itemize}
+\end{frame}
+
+\subsection{Numbers}
+\begin{frame}{Numbers\setcounter{footnote}{0}\footnotemark}
+ \setcounter{footnote}{1}
+ \begin{columns}[t]
+ \begin{column}{.5\textwidth}
+ \begin{itemize}
+ \item Database
+
+ \begin{description}[Syntax constructs]
+ \small
+ \item[Modules] 750
+ \item[Functions] 15,296
+ \item[Unique types] 13,570
+ \item[Type tree depth] 8
+ \item[Type definitions] 2,195
+ \item[Classes] 262
+ \item[Derivations] 1,182
+ \item[Syntax constructs] 35
+ \end{description}
+ \end{itemize}
+ \end{column}
+ \begin{column}{.5\textwidth}
+ \begin{itemize}
+ \item Lines of code\footnotemark
+ % cloc --exclude-dir=clean-compiler,CleanRep.2.2_files,CleanRep.2.2.css,storage,cache,Clean\ System\ Files,types.json,typetree.dot,cloogle.log,tags .
+
+ \begin{description}[Bourne Shell]
+ \small
+ \item[Clean] 4,739
+ \item[JavaScript] 1,657
+ \item[PHP] 831
+ \item[HTML] 569
+ \item[CSS] 406
+ \item[Python] 110
+ \item[Bourne Shell] 71
+ \end{description}
+ \end{itemize}
+ \end{column}
+ \end{columns}
+
+ \medskip
+ \begin{itemize}
+ \item Visitor statistics: \https{cloogle.org/stats/longterm.html}
+ \end{itemize}
+
+ \setcounter{footnote}{1}
+ \footnotetext{2017-10-27}
+ \setcounter{footnote}{2}
+ \footnotetext{On the web frontend and submodules, excluding the Clean compiler}
+\end{frame}
+
+\subsection{Links}
+\begin{frame}[shrink]{Links}
+ \footnotesize
+ \textbf{Core system:}
+ \begin{description}[VS Code plugin]
+ \item[API] \https{github.com/clean-cloogle/libcloogle}
+ \item[Core] \https{github.com/clean-cloogle/Cloogle}
+ \item[Web] \https{github.com/clean-cloogle/cloogle.org}
+ \item[JS highlighter] \https{github.com/clean-cloogle/clean.js}
+ \item[Pygments lexer] \https{github.com/clean-cloogle/pygments-lexer-clean}
+ \item[Pretty printer] \https{github.com/clean-cloogle/CleanPrettyPrint}
+ \item[Type unifier] \https{github.com/clean-cloogle/CleanTypeUnifier}
+ \end{description}
+
+ \textbf{Clients:}
+ \begin{description}[VS Code plugin]
+ \item[vim-clean] \https{github.com/camilstaps/vim-clean}
+ \item[CLI app] \https{github.com/clean-cloogle/cloogle-cli}
+ \item[Telegram bot] \https{telegram.me/CloogleBot}; \https{github.com/clean-cloogle/CloogleBot}
+ \item[IRC bot] \#cloogle on \https{freenode.net}; \https{github.com/clean-cloogle/clean-irc}
+ \item[Email client] \mailto{query@cloogle.org}; \https{github.com/clean-cloogle/cloogle-mail}
+ \item[VS Code plugin] \https{github.com/W95Psp/CleanForVSCode}
+ \end{description}
+
+ \textbf{Miscellaneous:}
+ \begin{description}[Pygments lexer]
+ \item[cloogle-tags] \https{github.com/clean-cloogle/cloogle-tags}
+ \item[These slides] \https{github.com/clean-cloogle/presentation-NL-FP-2018}
+ \end{description}
+\end{frame}
+
+\setcounter{framenumber}{\value{finalframe}}
+
\end{document}
diff --git a/clooglearch.sty b/clooglearch.sty
new file mode 100644
index 0000000..dd1b089
--- /dev/null
+++ b/clooglearch.sty
@@ -0,0 +1,113 @@
+\RequirePackage{tikz}
+\usetikzlibrary{calc,positioning}
+
+\newcommand{\module}[2]{#2\\[-4pt]\color{gray}{\tiny(#1)}}
+\newcommand{\tinymodule}[2]{\tiny\module{#1}{#2}}
+
+\tikzstyle{block}=[rectangle,align=center]
+\tikzset{
+ doc/.pic={
+ \coordinate (-east) at (0.309,0);
+ \coordinate (-south) at (0,-0.4);
+ \coordinate (-north) at (0,0.4);
+ \draw[pic actions] (-0.309,-0.4) -- ++(0,0.8) -- ++(0.518,0) -- ++(0,-0.1) -- ++(0.1,0) -- ++(0,-0.7) -- cycle;
+ \draw[pic actions] (0.209,0.4) -- ++(0.1,-0.1);
+ \draw[pic actions] (-0.209,-0.1) -- ++(0.418,0);
+ \draw[pic actions] (-0.209, 0) -- ++(0.418,0);
+ \draw[pic actions] (-0.209, 0.1) -- ++(0.418,0);
+ },
+ db/.pic={
+ % https://tex.stackexchange.com/a/397862/23992
+ \coordinate (-west) at (-0.3,0);
+ \coordinate (-east) at ( 0.3,0);
+ \coordinate (-south) at (0,-0.42);
+ \foreach \y in {-0.33,-0.1,0.13} {
+ \draw[fill=white] (-0.3,\y) to [looseness=0.5,bend right=90] ++(0.6,0)
+ -- ++(0,0.2) to [looseness=0.5,bend left=90] ++(-0.6,0)
+ -- ++(0,-0.2);
+ \draw (-0.3,\y+0.2) edge[looseness=0.5,bend left=90] ++(0.6,0);
+ }
+ }
+}
+
+\def\ifold#1{\ifnum#1=0 }
+\def\ifnew#1{\ifnum#1>0 }
+\def\oldornew#1#2{#2\ifnew#1-1\fi}
+\def\grayedout#1{\ifnum#1<2 dark\fi gray}
+
+\def\tikzsource{%
+ \pic (src) at (-5,3) {doc};
+}
+\def\tikzbuilddb{%
+ \node (cocl) at (-2.5, 3.5 ) {\module{Clean}{Clean compiler}};
+ \node (ppr) at (-2.5, 2.5 ) {\module{Clean}{Pretty printer}};
+ \pic (db) at ( 0, 2.98) {db};
+ \node[right=3pt of db-east,draw=none] {\module{\tiny JSON}{\scriptsize Database}};
+ \draw[->] ($(src-east)+(0,0.18)$) -- (cocl.west);
+ \draw[->] ($(src-east)-(0,0.18)$) -- (ppr.west);
+ \draw[->] (cocl.east) -- ($(db-west)+(0,0.18)$);
+ \draw[->] (ppr.east) -- ($(db-west)-(0,0.18)$);
+}
+\newcommand{\tikzbackend}[1][0]{%
+ \node[color=\grayedout#1] (web) at (0, \oldornew{#1}{1}) {\module{Clean, PHP, JS}{\ifold#1\bf\fi cloogle.org}};
+ \node (uni) at (3, 3) {\module{Clean}{Type unifier}};
+ \ifold#1
+ \draw[->] (db-south) -- (web);
+ \draw (uni) -- (web);
+ \else
+ \node (core) at (0,1.5) {\module{Clean}{\textbf{Cloogle}}};
+ \draw (uni) -- (core);
+ \draw[->] (db-south) -- (core);
+ \draw[color=\grayedout#1,->] (core) -- (web);
+ \fi
+}
+\newcommand{\tikzcache}[1][0]{%
+ \pic[color=\grayedout#1] (cch) at (2.5, \oldornew#1{1.48}) {db};
+ \node[color=\grayedout#1,right=3pt of cch-east,draw=none] {\module{\tiny JSON}{\scriptsize Cache}};
+ \draw[color=\grayedout#1,<->] (cch-west) -- (web);
+}
+\newcommand{\tikzfrontend}[1][0]{%
+ \node[color=\grayedout#1] (hljs) at (-2, \oldornew#1{0.5}) {\module{JS}{clean.js}};
+ \draw[color=\grayedout#1] (hljs) -- (web);
+}
+\newcommand{\tikzfrontendsrc}[1][0]{%
+ \node[color=\grayedout#1] (pygm) at (-2.25, \oldornew#1{1.5}) {\module{Python}{pygments}};
+ \draw[color=\grayedout#1,->] (src-south) -- (pygm);
+ \draw[color=\grayedout#1] (pygm) -- (web);
+}
+\newcommand{\tikzstats}[1][0]{%
+ \node[color=\grayedout#1] (stats) at (2.5, \oldornew#1{0.5}) {\module{Bash, JS, PHP, SQL}{Log \& Statistics}};
+ \draw[color=\grayedout#1] (web) -- (stats);
+}
+\newcommand{\tikzclientA}[1][0]{%
+ \def\tikzclientAcolor{\ifnum#1=3 \else dark\fi gray}
+ \node[color=\tikzclientAcolor] (vim) at (-3,-2) {\tinymodule{Vim}{vim-clean}};
+ \draw[color=\grayedout#1,->] (web) -- (vim);
+ \ifnum#1>2
+ \pic (tagfile) at (-5,-1.2) {doc};
+ \draw[->] (tags) -- (tagfile-north);
+ \ifnum#1>3
+ \draw (tagfile-south) edge[bend right,->] (vim);
+ \fi
+ \fi
+}
+\newcommand{\tikzclientB}[1][0]{%
+ \node[color=\grayedout#1] (tgm) at (-1.5,-2) {\tinymodule{Python}{Telegram bot}};
+ \draw[color=\grayedout#1,->] (web) -- (tgm);
+}
+\newcommand{\tikzclientC}[1][0]{%
+ \node[color=\grayedout#1] (cli) at (0,-2) {\tinymodule{Python}{CLI app}};
+ \draw[color=\grayedout#1,->] (web) -- (cli);
+}
+\newcommand{\tikzclientD}[1][0]{%
+ \node[color=\grayedout#1] (vim) at (1.4,-2) {\tinymodule{Python}{Email client}};
+ \draw[color=\grayedout#1,->] (web) -- (vim);
+}
+\newcommand{\tikzclientE}[1][0]{%
+ \node[color=\grayedout#1] (vim) at (2.7,-2) {\tinymodule{Clean}{IRC bot}};
+ \draw[color=\grayedout#1,->] (web) -- (vim);
+}
+\newcommand{\tikzcloogletags}[0]{%
+ \node (tags) at (-5,0) {\module{Clean}{cloogle-tags}};
+ \draw[->] (core) edge[bend right,out=-15] (tags);
+}
diff --git a/scrot-search-class.png b/scrot-search-class.png
new file mode 100644
index 0000000..eb7265f
--- /dev/null
+++ b/scrot-search-class.png
Binary files differ
diff --git a/scrot-search-name.png b/scrot-search-name.png
new file mode 100644
index 0000000..797aaa3
--- /dev/null
+++ b/scrot-search-name.png
Binary files differ
diff --git a/scrot-search-typedef.png b/scrot-search-typedef.png
new file mode 100644
index 0000000..91942a9
--- /dev/null
+++ b/scrot-search-typedef.png
Binary files differ
diff --git a/scrot-search-unify.png b/scrot-search-unify.png
new file mode 100644
index 0000000..cb319b8
--- /dev/null
+++ b/scrot-search-unify.png
Binary files differ