% Generated by Sphinx.
\def\sphinxdocclass{report}
\documentclass[letterpaper,10pt,english]{sphinxmanual}
\usepackage[utf8]{inputenc}
\DeclareUnicodeCharacter{00A0}{\nobreakspace}
\usepackage{cmap}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{times}
\usepackage[Bjarne]{fncychap}
\usepackage{longtable}
\usepackage{sphinx}
\usepackage{multirow}


\addto\captionsenglish{\renewcommand{\figurename}{Fig. }}
\addto\captionsenglish{\renewcommand{\tablename}{Table }}
\floatname{literal-block}{Listing }

\usepackage{amsfonts,amsmath}

\title{cygenja's manual}
\date{January 18, 2016}
\release{0.3.0}
\author{Nikolaj van Omme\\Sylvain Arreckx\\Dominique Orban}
\newcommand{\sphinxlogo}{\includegraphics{cygenja-logo128.pdf}\par}
\renewcommand{\releasename}{Release}
\makeindex

\makeatletter
\def\PYG@reset{\let\PYG@it=\relax \let\PYG@bf=\relax%
    \let\PYG@ul=\relax \let\PYG@tc=\relax%
    \let\PYG@bc=\relax \let\PYG@ff=\relax}
\def\PYG@tok#1{\csname PYG@tok@#1\endcsname}
\def\PYG@toks#1+{\ifx\relax#1\empty\else%
    \PYG@tok{#1}\expandafter\PYG@toks\fi}
\def\PYG@do#1{\PYG@bc{\PYG@tc{\PYG@ul{%
    \PYG@it{\PYG@bf{\PYG@ff{#1}}}}}}}
\def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+\PYG@do{#2}}

\expandafter\def\csname PYG@tok@gd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
\expandafter\def\csname PYG@tok@gu\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
\expandafter\def\csname PYG@tok@gt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
\expandafter\def\csname PYG@tok@gs\endcsname{\let\PYG@bf=\textbf}
\expandafter\def\csname PYG@tok@gr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
\expandafter\def\csname PYG@tok@cm\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@vg\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@m\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@mh\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@cs\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
\expandafter\def\csname PYG@tok@ge\endcsname{\let\PYG@it=\textit}
\expandafter\def\csname PYG@tok@vc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@il\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@go\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.20}{##1}}}
\expandafter\def\csname PYG@tok@cp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@gi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
\expandafter\def\csname PYG@tok@gh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PYG@tok@ni\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.84,0.33,0.22}{##1}}}
\expandafter\def\csname PYG@tok@nl\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.13,0.44}{##1}}}
\expandafter\def\csname PYG@tok@nn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
\expandafter\def\csname PYG@tok@no\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.38,0.68,0.84}{##1}}}
\expandafter\def\csname PYG@tok@na\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@nb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@nc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
\expandafter\def\csname PYG@tok@nd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}}
\expandafter\def\csname PYG@tok@ne\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@nf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.49}{##1}}}
\expandafter\def\csname PYG@tok@si\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.44,0.63,0.82}{##1}}}
\expandafter\def\csname PYG@tok@s2\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@vi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@nt\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.45}{##1}}}
\expandafter\def\csname PYG@tok@nv\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@s1\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@gp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
\expandafter\def\csname PYG@tok@sh\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@ow\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@sx\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
\expandafter\def\csname PYG@tok@bp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@c1\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@kc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@c\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@mf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@err\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}
\expandafter\def\csname PYG@tok@mb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@ss\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.32,0.47,0.09}{##1}}}
\expandafter\def\csname PYG@tok@sr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.14,0.33,0.53}{##1}}}
\expandafter\def\csname PYG@tok@mo\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@kd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@mi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@kn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@o\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PYG@tok@kr\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@s\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@kp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@w\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
\expandafter\def\csname PYG@tok@kt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.56,0.13,0.00}{##1}}}
\expandafter\def\csname PYG@tok@sc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@sb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@k\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@se\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@sd\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}

\def\PYGZbs{\char`\\}
\def\PYGZus{\char`\_}
\def\PYGZob{\char`\{}
\def\PYGZcb{\char`\}}
\def\PYGZca{\char`\^}
\def\PYGZam{\char`\&}
\def\PYGZlt{\char`\<}
\def\PYGZgt{\char`\>}
\def\PYGZsh{\char`\#}
\def\PYGZpc{\char`\%}
\def\PYGZdl{\char`\$}
\def\PYGZhy{\char`\-}
\def\PYGZsq{\char`\'}
\def\PYGZdq{\char`\"}
\def\PYGZti{\char`\~}
% for compatibility with earlier versions
\def\PYGZat{@}
\def\PYGZlb{[}
\def\PYGZrb{]}
\makeatother

\renewcommand\PYGZsq{\textquotesingle}

\begin{document}

\maketitle
\tableofcontents
\phantomsection\label{contents::doc}

\begin{quote}\begin{description}
\item[{Release}] \leavevmode
0.3

\item[{Date}] \leavevmode
January 18, 2016

\end{description}\end{quote}


\chapter{Introduction}
\label{introduction:introduction}\label{introduction:cygenja-documentation}\label{introduction::doc}\label{introduction:cygenja-introduction}
\textbf{\texttt{cygenja}} is a small \href{https://docs.python.org/2/}{Python2} library to generate typed source files from
\href{http://jinja.pocoo.org/docs/dev/}{Jinja2} source templates. We use it extensively to generate our \href{http://cython.org/}{Cython}
projects. See {\hyperref[introduction:limitations]{\emph{Limitations}}} to see if this tool
is for you.


\section{What \textbf{\texttt{cygenja}} can do}
\label{introduction:what-cygenja-can-do}
From a bunch of templated (source) files, \textbf{\texttt{cygenja}} can generate several (source) files. The translation part is given to the powerful \href{http://jinja.pocoo.org/docs/dev/}{Jinja2} template engine.
\textbf{\texttt{cygenja}} is a layer above this template engine and is in charge of dispatching translation rules to the right subdirectories and apply them to the right bunch of files. A file is \textbf{only} generated if it is \textbf{older} than
the template file used to produce it, i.e. a change in a template file triggers a regeneration of the corresponding files \footnote[1]{
Of course, you can force a file generation.
}.


\section{How \textbf{\texttt{cygenja}} works}
\label{introduction:how-cygenja-works}
Within a \emph{root} directory, you provide some translation rules: each rule is attached to a subdirectory and a file pattern. You can define several rules for one subdirectory.
These rules (called \emph{actions} in \textbf{\texttt{cygenja}}) are user defined \emph{callbacks}. Once all rules are registered, the \textbf{\texttt{cygenja}} engine
is given a directory pattern and a file pattern: only the matching rules are triggered. See {\hyperref[usage:cygenja-usage]{\emph{Usage}}} or look at the {\hyperref[examples:cygenja-examples]{\emph{Examples}}} for more.


\section{Limitations}
\label{introduction:limitations}\label{introduction:id3}
Here is a small list of limitations \footnote[2]{
Most limitations described here can easily be overcome.
}. It is of course not exhaustive but it can already give you a hint if this tool is for you or not.


\subsection{\textbf{\texttt{cygenja}} only parses subdirectories}
\label{introduction:cygenja-only-parses-subdirectories}
\textbf{\texttt{cygenja}} can only parse subdirectories from a root directory. This means
that it \textbf{cannot} generate files located at the root directory level (or outside the root directory).


\subsection{\textbf{\texttt{cygenja}} generates files in place}
\label{introduction:cygenja-generates-files-in-place}
Files can only be generated in the same subdirectories as their corresponding templates.


\subsection{Templates and generated files \textbf{must} have different extensions}
\label{introduction:templates-and-generated-files-must-have-different-extensions}
Templates are identified by specific extensions. The corresponding generated files will be given specific corresponding extensions too. This extension correspondance is defined by the user but both extensions
\textbf{must} be different. For instance, \emph{*.cpd} templated files are transformed into \emph{*.pxd} files. Both extensions, \emph{.cpd} and \emph{.pxd} \textbf{are} be different.


\subsection{File patterns: only \textbf{\texttt{fnmatch}} patterns}
\label{introduction:file-patterns-only-fnmatch-patterns}
Translation rules can only be applied to files corresponding to \href{https://docs.python.org/2/library/fnmatch.html}{fnmatch} patterns. While this covers most cases, it might be a limitation for some.

We also use the same kind of file patterns to trigger the translation.


\subsection{Directory patterns: only \textbf{\texttt{glob}} patterns}
\label{introduction:directory-patterns-only-glob-patterns}
To select the subdirectory(ies) within which the rules will be applied by \textbf{\texttt{cygenja}}`s engine, only  \href{https://docs.python.org/2/library/glob.html}{glob} patterns can be used.


\subsection{Contradictory \emph{actions} are not filtered nor monitored}
\label{introduction:contradictory-actions-are-not-filtered-nor-monitored}
Nothing prevents you from registering conflicting actions. In this case, only the \textbf{first} registered action is guaranteed to be triggered.


\section{License}
\label{introduction:license}
\textbf{\texttt{cygenja}} is distributed under the \href{http://www.gnu.org/licenses/gpl-3.0.en.html}{GPLv3}.


\chapter{Installing \textbf{\texttt{cygenja}}}
\label{installation:cygenja-installation}\label{installation:installing-cygenja}\label{installation::doc}
Installing \textbf{\texttt{cygenja}} is really easy.


\section{Dependencies}
\label{installation:dependencies}
The only dependency is the \href{http://jinja.pocoo.org/}{Jinja2} library.

If you want to generate the documentation, you need \href{http://sphinx-doc.org/}{Sphinx} and the \href{https://ryan-roemer.github.io/sphinx-bootstrap-theme/README.html}{sphinx\_bootstrap\_theme} (and possibly \href{https://www.latex-project.org/}{LaTeX} and
several sub modules/packages). To generate the documentation, \textbf{\texttt{cygenja}} does not need to be installed.


\section{Installation}
\label{installation:installation}
Download source files from \href{https://github.com/PythonOptimizers/cygenja}{Github} (or clone the repository) and invoke the traditionnal:

\begin{Verbatim}[commandchars=\\\{\}]
python setup.py install
\end{Verbatim}

in a virtual environment or globally with full admin rights.


\chapter{Usage}
\label{usage:usage}\label{usage:cygenja-usage}\label{usage::doc}
We briefly describe the use of \textbf{\texttt{cygenja}}. Basically, you register some filters, file extensions and actions before triggering the translation.
In the {\hyperref[examples:cygenja-examples]{\emph{Examples}}} section, you can see \textbf{\texttt{cygenja}} in action as we detail its use to generate the \href{https://github.com/PythonOptimizers/cysparse}{CySparse} library.


\section{The \emph{Generator} class}
\label{usage:the-generator-class}\label{usage:generator-class}
The \code{Generator} class is the main class of the \textbf{\texttt{cygenja}} library. It also is the only
class you need to interact with. Its constructor is really simple:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k+kn}{from} \PYG{n+nn}{cygenja.generator} \PYG{k+kn}{import} \PYG{n}{Generator}
\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}

\PYG{n}{logger} \PYG{o}{=} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
\PYG{n}{env} \PYG{o}{=} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{root\PYGZus{}directory}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{n}{env}\PYG{p}{,} \PYG{n}{logger}\PYG{p}{,} \PYG{n+nb+bp}{True}\PYG{p}{)}
\end{Verbatim}

You provide a \code{root\_directory} directory, a \textbf{\texttt{Jinja2}}  environment, a \emph{logger}
(from the standard \code{logging} library) and decide if \emph{warnings} must raise \emph{Exception}s or not (default: \code{False}). The first two arguments are mandatory while the last two are optional. You don't have to provide
a logging engine. We describe the root directory a little further in {\hyperref[usage:root-directory]{\emph{The root directory}}}, refer the reader to \href{http://jinja.pocoo.org/docs/dev/api/\#jinja2.Environment}{jinja2.Environment} for more about
the \code{env} argument and discuss the two last arguments
in the next corresponding subsections.


\subsection{Logging}
\label{usage:logging}
A logging engine \emph{can} be used but is not mandatory. If you don't want to log \textbf{\texttt{cygenja}}`s behavior, simply pass \emph{None} as the value of the logger argument in the constructor (this is the default). The logging engine is
an object from Python's \href{https://docs.python.org/2/library/logging.html}{logging library}.

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k+kn}{from} \PYG{n+nn}{cygenja.generator} \PYG{k+kn}{import} \PYG{n}{Generator}
\PYG{k+kn}{import} \PYG{n+nn}{logging}

\PYG{n}{logger} \PYG{o}{=} \PYG{n}{logging}\PYG{o}{.}\PYG{n}{getLogger}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{Logger name}\PYG{l+s}{\PYGZsq{}}\PYG{p}{)}
\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{root\PYGZus{}directory}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{n}{logger}\PYG{p}{,} \PYG{n+nb+bp}{True}\PYG{p}{)}
\end{Verbatim}

Three message logging helpers are provided:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{log\PYGZus{}info}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{msg}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{log\PYGZus{}warning}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{msg}\PYG{p}{)}
\PYG{k}{def} \PYG{n+nf}{log\PYGZus{}error}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{msg}\PYG{p}{)}
\end{Verbatim}

Their names and signatures are quite self-explanatory.


\subsection{Raising exceptions on \emph{Warnings}}
\label{usage:raising-exceptions-on-warnings}
Errors \textbf{always} trigger \emph{RuntimeError}s while warnings may or may not trigger \emph{RuntimeError}s. To raise exceptions on warnings, set the \code{raise\_exception\_on\_warning} to \code{True} in the
constructor:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{root\PYGZus{}directory}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{n}{logger}\PYG{o}{=}\PYG{n}{logger}\PYG{p}{,} \PYG{n}{raise\PYGZus{}exception\PYGZus{}on\PYGZus{}warning}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{)}
\end{Verbatim}

By default, \code{raise\_exception\_on\_warning} is set to \code{False}.


\section{Patterns}
\label{usage:patterns}
\index{pattern!files}\index{files!pattern}\index{pattern!directories}\index{directories!pattern}
There are only \textbf{two} types of patterns:
\begin{itemize}
\item {} 
\href{https://docs.python.org/2/library/fnmatch.html}{fnmatch} patterns for file names and

\item {} 
\href{https://docs.python.org/2/library/glob.html}{glob} patterns for directory names.

\end{itemize}

This is a general rule for the whole library. When you register an action though, you must provide a directory name, \textbf{not} a directory name pattern.

We encourage the reader to (re)read the specifications of these two libraries.


\section{The \emph{root} directory}
\label{usage:root-directory}\label{usage:the-root-directory}
\index{root directory}
The root directory is really the main working directory: all file generations can \textbf{only} be done inside \textbf{subdirectories} of this directory.

This is so important that it is worth a warning:

\begin{notice}{warning}{Warning:}
File generations can \textbf{only} be done inside \textbf{subdirectories} of the \emph{root} directory.
\end{notice}

This directory is given as the first parameter of \code{Generator}`s constructor
and can be absolute or relative. At any moment, you can retrieve this directory as an absolute path:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{root\PYGZus{}directory}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{)}

\PYG{n}{absolute\PYGZus{}root\PYGZus{}directory} \PYG{o}{=} \PYG{n}{engine}\PYG{o}{.}\PYG{n}{root\PYGZus{}directory}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}


\section{Filters}
\label{usage:filters}
\index{filters}
Filters are simply \textbf{\texttt{Jinja2}} \href{http://jinja.pocoo.org/docs/dev/templates/\#filters}{filters}. These filters are \emph{registered}:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{my\PYGZus{}jinja2\PYGZus{}filter}\PYG{p}{(}\PYG{n}{filter\PYGZus{}argument}\PYG{p}{)}\PYG{p}{:}
    \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
    \PYG{k}{return} \PYG{n}{filter\PYGZus{}result}

\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{)}
\PYG{n}{engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}filter}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{my\PYGZus{}filter\PYGZus{}name}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{n}{my\PYGZus{}jinja2\PYGZus{}filter}\PYG{p}{)}
\end{Verbatim}

where \code{'my\_filter\_name'} is the name of the filter used inside your \textbf{\texttt{Jinja2}} template files and \code{my\_jinja2\_filter} is a reference to the actual filter.

The signature of \code{register\_filter} is:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{register\PYGZus{}filter}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{filter\PYGZus{}name}\PYG{p}{,} \PYG{n}{filter\PYGZus{}ref}\PYG{p}{,} \PYG{n}{force}\PYG{o}{=}\PYG{n+nb+bp}{False}\PYG{p}{)}
\end{Verbatim}

allowing you to register a new filter under an already existing filter name. If you keep \code{force} set to \code{False}, a warning is triggered each time you try to register a
new filter under an already existing filter name and this \textbf{new} filter is disregarded.

You also can register several filters at once with a dictionary of filters:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{)}
\PYG{n}{filters} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{f1}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{n}{filter1}\PYG{p}{,}
            \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{f2}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{n}{filter2}\PYG{p}{\PYGZcb{}}

\PYG{n}{engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}filters}\PYG{p}{(}\PYG{n}{filters}\PYG{p}{,} \PYG{n}{force}\PYG{o}{=}\PYG{n+nb+bp}{False}\PYG{p}{)}
\end{Verbatim}

At any time, you can list the registered filters:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{)}
\PYG{k}{print} \PYG{n}{engine}\PYG{o}{.}\PYG{n}{filters\PYGZus{}list}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

This list also includes predefined \textbf{\texttt{Jinja2}} filters (see \href{http://jinja.pocoo.org/docs/dev/templates/\#builtin-filters}{builtin filter}).
If you only want the filters you registered, invoke:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine}\PYG{o}{.}\PYG{n}{registered\PYGZus{}filters\PYGZus{}list}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}


\section{File extensions}
\label{usage:file-extensions}\label{usage:id2}
\textbf{\texttt{cygenja}} uses a correspondance table between template files and generated files. This table defines a correspondance between file \emph{extensions}. For instance, to have \emph{*.cpd} templates generate  \emph{*.pxd} files:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{)}
\PYG{n}{engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}extension}\PYG{p}{(}\PYG{l+s+sb}{{}`.cpd{}`}\PYG{p}{,} \PYG{l+s+sb}{{}`.pxd{}`}\PYG{p}{)}
\end{Verbatim}

Again, we use a \code{force} switch to force the redefinition of such a correspondance. By default, this switch is set to \code{False} and if you try to redefine an association with a given template extension, you will
trigger a warning and this new correspondance will be disregarded.

You can use a \code{dict} to register several extensions at once:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{)}
\PYG{n}{ext\PYGZus{}correspondance} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.cpd}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.pxd}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                       \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.cpx}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{pyx}\PYG{l+s}{\PYGZsq{}}\PYG{p}{\PYGZcb{}}
\PYG{n}{engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}extensions}\PYG{p}{(}\PYG{n}{ext\PYGZus{}correspondance}\PYG{p}{,} \PYG{n}{force}\PYG{o}{=}\PYG{n+nb+bp}{False}\PYG{p}{)}\PYG{p}{:}
\end{Verbatim}

As with filters, you can retrieve the registered extensions:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine}\PYG{o}{.}\PYG{n}{registered\PYGZus{}extensions\PYGZus{}list}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

Files with extensions registered as template file extensions are systematically parsed, i.e. you cannot use these extensions for files that are not templates because \textbf{\texttt{cygenja}} will try to parse them.
What about generated file extensions? Files with these extensions can peacefully coexist with generated files, i.e. existing files,
regardless of their extensions, can coexist with generated files and will not be plagued by \textbf{\texttt{cyjenja}}. This means that you can safely delete files: only generated files will be deleted \footnote[1]{
The user is responsible to not to define a translation rule that overwrites any existing files.
}.

\begin{notice}{note}{Note:}
Only generated files are deleted. You can thus safely delete files with \textbf{\texttt{cygenja}}.
\end{notice}


\section{Actions}
\label{usage:actions}
\index{action}
Actions (defined in the \code{GeneratorAction} class) are really the core concept of \textbf{\texttt{cygenja}}: an action correspond to a \emph{translation rule}. This translation rule makes a correspondance between a subdirectory
and a file pattern and a user callback. Here is the signature of the \code{register\_action} method:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{register\PYGZus{}action}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{relative\PYGZus{}directory}\PYG{p}{,} \PYG{n}{file\PYGZus{}pattern}\PYG{p}{,} \PYG{n}{action\PYGZus{}function}\PYG{p}{)}
\end{Verbatim}

The \code{relative\_directory} argument holds the name of a relative directory from the \emph{root} directory. The separator is OS dependent. For instance,
under linux, you can register the following:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{)}

\PYG{k}{def} \PYG{n+nf}{action\PYGZus{}function}\PYG{p}{(}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{)}\PYG{p}{:}
    \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
    \PYG{k}{return} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}

\PYG{n}{engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}action}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{cysparse/sparse/utils}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{find*.cpy}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{n}{action\PYGZus{}function}\PYG{p}{)}
\end{Verbatim}

This means that all files corresponding to the \code{'find*.cpy'} \href{https://docs.python.org/2/library/fnmatch.html}{fnmatch} pattern inside the \code{cysparse/sparse/utils}
directory can be dealt with the \code{action\_function}.

Contrary to filters and file extensions, you \textbf{cannot} ask for a list of registered actions. But you can ask \textbf{\texttt{cygenja}} to perform a \emph{dry} session: \textbf{\texttt{cygenja}} outputs what it would normaly do but without
taking any action \footnote[3]{
You also have access to the internal \code{TreeMap} object with the \code{registered\_actions\_treemap()} method and thus you have access to all its methods.
One interesting method is \code{to\_string()}. It gives you a representation of all involved subdirectories.
}.


\subsection{User callback}
\label{usage:user-callback}
The \code{action\_function()} is a user-defined callback without argument. It returns a file suffix with a corresponding \textbf{\texttt{Jinja2}}
\href{http://jinja.pocoo.org/docs/dev/templates/\#variables}{variables dict} (this is a simple \textbf{\texttt{Python}} \code{dict}). Let's illustrate this by an example:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{GENERAL\PYGZus{}CONTEXT} \PYG{o}{=} \PYG{p}{\PYGZob{}}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{\PYGZcb{}}
\PYG{n}{INDEX\PYGZus{}TYPES} \PYG{o}{=} \PYG{p}{[}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{INT32}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{INT64}\PYG{l+s}{\PYGZsq{}}\PYG{p}{]}
\PYG{n}{ELEMENT\PYGZus{}TYPES} \PYG{o}{=} \PYG{p}{[}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{FLOAT32}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{FLOAT64}\PYG{l+s}{\PYGZsq{}}\PYG{p}{]}

\PYG{k}{def} \PYG{n+nf}{generate\PYGZus{}following\PYGZus{}index\PYGZus{}and\PYGZus{}type}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
    \PYG{l+s+sd}{\PYGZdq{}\PYGZdq{}\PYGZdq{}}

\PYG{l+s+sd}{    \PYGZdq{}\PYGZdq{}\PYGZdq{}}
    \PYG{k}{for} \PYG{n}{index} \PYG{o+ow}{in} \PYG{n}{INDEX\PYGZus{}TYPES}\PYG{p}{:}
        \PYG{n}{GENERAL\PYGZus{}CONTEXT}\PYG{p}{[}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{index}\PYG{l+s}{\PYGZsq{}}\PYG{p}{]} \PYG{o}{=} \PYG{n}{index}
        \PYG{k}{for} \PYG{n+nb}{type} \PYG{o+ow}{in} \PYG{n}{ELEMENT\PYGZus{}TYPES}\PYG{p}{:}
            \PYG{n}{GENERAL\PYGZus{}CONTEXT}\PYG{p}{[}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{type}\PYG{l+s}{\PYGZsq{}}\PYG{p}{]} \PYG{o}{=} \PYG{n+nb}{type}
            \PYG{k}{yield} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{\PYGZus{}}\PYG{l+s+si}{\PYGZpc{}s}\PYG{l+s}{\PYGZus{}}\PYG{l+s+si}{\PYGZpc{}s}\PYG{l+s}{\PYGZsq{}} \PYG{o}{\PYGZpc{}} \PYG{p}{(}\PYG{n}{index}\PYG{p}{,} \PYG{n+nb}{type}\PYG{p}{)}\PYG{p}{,} \PYG{n}{GENERAL\PYGZus{}CONTEXT}
\end{Verbatim}

The user-defined callback \code{generate\_following\_index\_and\_type()} doesn't take any input argument and returns the \code{'\_\%s\_\%s'} suffix string together with the variables \code{dict} \code{GENERAL\_CONTEXT}.
This function allows \textbf{\texttt{cygenja}} to create files with this suffix from any matching template file. The \code{GENERAL\_CONTEXT} is given to \textbf{\texttt{Jinja2}} for the appropriate translation.

For instance, let's use the \code{ext\_correspondance} extensions \code{dict} discussed earlier (see {\hyperref[usage:file-extensions]{\emph{File extensions}}}):

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{ext\PYGZus{}correspondance} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.cpd}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.pxd}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                       \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.cpx}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{pyx}\PYG{l+s}{\PYGZsq{}}\PYG{p}{\PYGZcb{}}
\end{Verbatim}

Any template file with a \code{.cpd} or \code{.cpx} extension will be translated into a \code{\_index\_type.pxd} or \code{\_index\_type.pyx} file respectively. For instance, the template file \code{my\_template\_code\_file.cpd} will be translated to:
\begin{itemize}
\item {} 
\code{my\_template\_code\_file\_INT32\_FLOAT32.cpd}

\item {} 
\code{my\_template\_code\_file\_INT32\_FLOAT64.cpd}

\item {} 
\code{my\_template\_code\_file\_INT64\_FLOAT32.cpd}

\item {} 
\code{my\_template\_code\_file\_INT64\_FLOAT64.cpd}

\end{itemize}

As this function is defined by the user, you have total control on what you want to generate or not. In our example, we redefine \code{GENERAL\_CONTEXT{[}'index'{]}} and \code{GENERAL\_CONTEXT{[}'type'{]}} for each index and element types.

We use generators (\code{yield}) but you could return a \code{list} if you prefer.


\subsection{Incompatible actions}
\label{usage:incompatible-actions}
You could register incompatible actions, i.e. register competing actions that would translate a file in different ways. Our approach is to \textbf{only} use the first compatible action and to disregard all the other actions, regardless
if they could be applied or not. So the order in which you register your actions is important. A file will be dealt with the \textbf{first} compatible action found. This is worth a warning:

\begin{notice}{warning}{Warning:}
A template is translated with the \textbf{first} compatible action found and only that action.
\end{notice}


\subsection{Default action}
\label{usage:default-action}
\index{action default}
\textbf{\texttt{cygenja}} allows to define \textbf{one} default action that will be triggered when no other compatible action is found for a given
template file that corresponds to a \href{https://docs.python.org/2/library/fnmatch.html}{fnmatch} pattern:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{)}

\PYG{k}{def} \PYG{n+nf}{default\PYGZus{}action}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{return} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}

\PYG{n}{engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}default\PYGZus{}action}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{*.*}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}  \PYG{n}{default\PYGZus{}action}\PYG{p}{)}
\end{Verbatim}

Be careful when defining a default action. This action is applied to \textbf{all} template files (corresponding to the \textbf{\texttt{fnmatch}} pattern) for
which no compatible action is found. You might want to prefer declaring explicit actions than relying on this
implicit default action. That said, if you have lots of default cases, this
default action can be very convenient and avoid lots of unnecessary action declarations.


\section{File generation}
\label{usage:file-generation}
To generate the files from template files, there is only \textbf{one} method to invoke: \emph{generate()}. Its signature is:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{generate}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{dir\PYGZus{}pattern}\PYG{p}{,} \PYG{n}{file\PYGZus{}pattern}\PYG{p}{,} \PYG{n}{action\PYGZus{}ch}\PYG{o}{=}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{g}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
             \PYG{n}{recursively}\PYG{o}{=}\PYG{n+nb+bp}{False}\PYG{p}{,} \PYG{n}{force}\PYG{o}{=}\PYG{n+nb+bp}{False}\PYG{p}{)}
\end{Verbatim}

\code{dir\_pattern} is a \code{glob} pattern taken from the root directory and it is \textbf{only} used for directories while \code{file\_pattern} is a \code{fnmatch} pattern taken from all matching directories and is \textbf{only} used for files.
The \code{action\_ch} is a character that triggers different behaviours:
\begin{itemize}
\item {} 
\code{g}: Generate all files that match both directory and file patterns. This is the default behavior.

\item {} 
\code{d}: Same as \emph{g} but with doing anything, i.e. dry run.

\item {} 
\code{c}: Same as \emph{g} but erasing the generated files instead, i.e. clean.

\end{itemize}

These actions can be done in a given directory or in all its corresponding subdirectories. To choose between these two options, use the \code{recursively} switch. Finally, by default, files are only generated if they are
outdated, i.e. if they are older than the template they were originated from. You can force the generation with the \code{force} switch.


\chapter{Examples}
\label{examples::doc}\label{examples:examples}\label{examples:cygenja-examples}
In this section, we demonstrate the use of \textbf{\texttt{cygenja}} to generate the \href{https://github.com/PythonOptimizers/cysparse}{CySparse} library.


\section{Init}
\label{examples:init}
We start by creating a \textbf{\texttt{cygenja}} engine:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k+kn}{from} \PYG{n+nn}{cygenja.generator} \PYG{k+kn}{import} \PYG{n}{Generator}
\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}

\PYG{c}{\PYGZsh{} read cysparse.cfg}
\PYG{n}{cysparse\PYGZus{}config} \PYG{o}{=} \PYG{n}{ConfigParser}\PYG{o}{.}\PYG{n}{SafeConfigParser}\PYG{p}{(}\PYG{p}{)}
\PYG{n}{cysparse\PYGZus{}config}\PYG{o}{.}\PYG{n}{read}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{cysparse.cfg}\PYG{l+s}{\PYGZsq{}}\PYG{p}{)}

\PYG{c}{\PYGZsh{} create logger}
\PYG{n}{logger} \PYG{o}{=} \PYG{n}{make\PYGZus{}logger}\PYG{p}{(}\PYG{n}{cysparse\PYGZus{}config}\PYG{o}{=}\PYG{n}{cysparse\PYGZus{}config}\PYG{p}{)}

\PYG{c}{\PYGZsh{} cygenja engine}
\PYG{n}{current\PYGZus{}directory} \PYG{o}{=} \PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{dirname}\PYG{p}{(}\PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{abspath}\PYG{p}{(}\PYG{n}{\PYGZus{}\PYGZus{}file\PYGZus{}\PYGZus{}}\PYG{p}{)}\PYG{p}{)}
\PYG{n}{cygenja\PYGZus{}engine} \PYG{o}{=} \PYG{n}{Generator}\PYG{p}{(}\PYG{n}{current\PYGZus{}directory}\PYG{p}{,} \PYG{n}{logger}\PYG{o}{=}\PYG{n}{logger}\PYG{p}{)}
\end{Verbatim}

\code{make\_logger} is just a wrapper around a \href{https://docs.python.org/2/library/logging.html}{logging} logger. This logger is not mandatory but can be quite handy to debug sessions.
The \code{current\_directory} can be absolute or relative. In this example, let's say its value is \code{'cysparse'} \footnote[1]{
Yes, we are well aware that this not what is expected from the code. \code{os.path.abspath(\_\_file\_\_)} will never only return \code{cysparse}.
}, the main project directory.

We now define some variables:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{ELEMENT\PYGZus{}TYPES} \PYG{o}{=} \PYG{p}{[}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{INT32\PYGZus{}t}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{INT64\PYGZus{}t}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                 \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{FLOAT32\PYGZus{}t}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{FLOAT64\PYGZus{}t}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{FLOAT128\PYGZus{}t}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                 \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{COMPLEX64\PYGZus{}t}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{COMPLEX128\PYGZus{}t}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{COMPLEX256\PYGZus{}t}\PYG{l+s}{\PYGZsq{}}\PYG{p}{]}
\PYG{n}{INDEX\PYGZus{}TYPES} \PYG{o}{=} \PYG{p}{[}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{INT32\PYGZus{}t}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{INT64\PYGZus{}t}\PYG{l+s}{\PYGZsq{}}\PYG{p}{]}
\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}

\PYG{n}{GENERAL\PYGZus{}CONTEXT} \PYG{o}{=} \PYG{p}{\PYGZob{}}
                \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{type\PYGZus{}list}\PYG{l+s}{\PYGZsq{}}\PYG{p}{:} \PYG{n}{ELEMENT\PYGZus{}TYPES}\PYG{p}{,}
                \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{index\PYGZus{}list}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{n}{INDEX\PYGZus{}TYPES}\PYG{p}{,}
                \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{default\PYGZus{}index\PYGZus{}type}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{n}{DEFAULT\PYGZus{}INDEX\PYGZus{}TYPE}\PYG{p}{,}
                \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{integer\PYGZus{}list}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{n}{INTEGER\PYGZus{}ELEMENT\PYGZus{}TYPES}\PYG{p}{,}
                \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{real\PYGZus{}list}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{n}{REAL\PYGZus{}ELEMENT\PYGZus{}TYPES}\PYG{p}{,}
                \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{complex\PYGZus{}list}\PYG{l+s}{\PYGZsq{}} \PYG{p}{:} \PYG{n}{COMPLEX\PYGZus{}ELEMENT\PYGZus{}TYPES}\PYG{p}{,}
                \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
              \PYG{p}{\PYGZcb{}}
\end{Verbatim}


\section{File extensions}
\label{examples:file-extensions}
\textbf{\texttt{CySparse}} is written essentially in \href{http://cython.org/}{Cython}. We can thus generate four types of files: \code{.pyx}, \code{.pxd}, \code{.pxi} and of course \code{.py} files. For each type of file, we have defined
a corresponding extension for a template file: \code{.cpx}, \code{.cpd}, \code{.cpi} and \code{cpy}. We register this correspondance like so:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{c}{\PYGZsh{} register extensions}
\PYG{n}{cygenja\PYGZus{}engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}extension}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.cpy}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.py}\PYG{l+s}{\PYGZsq{}}\PYG{p}{)}
\PYG{n}{cygenja\PYGZus{}engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}extension}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.cpx}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.pyx}\PYG{l+s}{\PYGZsq{}}\PYG{p}{)}
\PYG{n}{cygenja\PYGZus{}engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}extension}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.cpd}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.pxd}\PYG{l+s}{\PYGZsq{}}\PYG{p}{)}
\PYG{n}{cygenja\PYGZus{}engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}extension}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.cpi}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{.pxi}\PYG{l+s}{\PYGZsq{}}\PYG{p}{)}
\end{Verbatim}

Now, each time \textbf{\texttt{cygenja}} will encounter a template \code{.cpx} file, it will generate one or several corresponding \code{.pyx} files.


\section{Filters}
\label{examples:filters}
\href{http://jinja.pocoo.org/docs/dev/templates/\#filters}{Jinja2 filters} are essentially functions that take a string as input and return a modified version of this string. Here is an example:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{cysparse\PYGZus{}type\PYGZus{}to\PYGZus{}numpy\PYGZus{}c\PYGZus{}type}\PYG{p}{(}\PYG{n}{cysparse\PYGZus{}type}\PYG{p}{)}\PYG{p}{:}
    \PYG{l+s+sd}{\PYGZdq{}\PYGZdq{}\PYGZdq{}}
\PYG{l+s+sd}{    Transform a :program:{}`CySparse{}` enum type into the corresponding}
\PYG{l+s+sd}{    :program:{}`NumPy{}` C\PYGZhy{}type.}

\PYG{l+s+sd}{    For instance:}

\PYG{l+s+sd}{        INT32\PYGZus{}T \PYGZhy{}\PYGZgt{} npy\PYGZus{}int32}

\PYG{l+s+sd}{    Args:}
\PYG{l+s+sd}{        cysparse\PYGZus{}type:}

\PYG{l+s+sd}{    \PYGZdq{}\PYGZdq{}\PYGZdq{}}
    \PYG{k}{return} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{npy\PYGZus{}}\PYG{l+s}{\PYGZsq{}} \PYG{o}{+} \PYG{n+nb}{str}\PYG{p}{(}\PYG{n}{cysparse\PYGZus{}type}\PYG{o}{.}\PYG{n}{lower}\PYG{p}{(}\PYG{p}{)}\PYG{p}{[}\PYG{p}{:}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{p}{)}
\end{Verbatim}

We keep the same name for the function as the function name itself to register it (this is not mandatory):

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}filter}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{cysparse\PYGZus{}type\PYGZus{}to\PYGZus{}numpy\PYGZus{}c\PYGZus{}type}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{n}{cysparse\PYGZus{}type\PYGZus{}to\PYGZus{}numpy\PYGZus{}c\PYGZus{}type}\PYG{p}{)}
\end{Verbatim}

Now you can use \code{cysparse\_type\_to\_numpy\_c\_type()} in your \textbf{\texttt{Jinja2}} template \footnote[2]{
\textbf{\texttt{CySparse}}`s \textbf{\texttt{Jinja2}} environment allows us to use variables names like so: \code{@my\_variable@}.
}:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{x}{cnp.ndarray[cnp.@index\textbar{}cysparse\PYGZus{}type\PYGZus{}to\PYGZus{}numpy\PYGZus{}c\PYGZus{}type@, ndim=1] a\PYGZus{}row =}
\PYG{x}{    cnp.PyArray\PYGZus{}SimpleNew( 1, dmat, cnp.@index\textbar{}cysparse\PYGZus{}type\PYGZus{}to\PYGZus{}numpy\PYGZus{}enum\PYGZus{}type@)}
\end{Verbatim}


\section{Actions}
\label{examples:actions}
Before we can register any \textbf{\texttt{cygenja}} actions, we need to define some callbacks. Here are a few examples:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{single\PYGZus{}generation}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{yield} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{n}{GENERAL\PYGZus{}CONTEXT}


\PYG{k}{def} \PYG{n+nf}{generate\PYGZus{}following\PYGZus{}only\PYGZus{}index}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
    \PYG{n}{GENERAL\PYGZus{}CONTEXT}\PYG{p}{[}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{type}\PYG{l+s}{\PYGZsq{}}\PYG{p}{]} \PYG{o}{=} \PYG{n+nb+bp}{None}
    \PYG{k}{for} \PYG{n}{index} \PYG{o+ow}{in} \PYG{n}{INDEX\PYGZus{}TYPES}\PYG{p}{:}
        \PYG{n}{GENERAL\PYGZus{}CONTEXT}\PYG{p}{[}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{index}\PYG{l+s}{\PYGZsq{}}\PYG{p}{]} \PYG{o}{=} \PYG{n}{index}

        \PYG{k}{yield} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{\PYGZus{}}\PYG{l+s+si}{\PYGZpc{}s}\PYG{l+s}{\PYGZsq{}} \PYG{o}{\PYGZpc{}} \PYG{n}{index}\PYG{p}{,} \PYG{n}{GENERAL\PYGZus{}CONTEXT}
\end{Verbatim}

The first function, \code{single\_generation}, only generates one file without changing its name (the extension will be changed though). The second function, \code{generate\_following\_only\_index}, is more interesting. It generates one file for each index type. These files
all have a suffix \code{\_index} attached to their names (i.e. \code{\_INT32\_t}, \code{\_INT64\_t}) and the \code{GENERAL\_CONTEXT} \code{dict} is changed every time with the corresponding entry \code{index} updated. Here is a more complex version where we generate files with
respect to an index type but also an element type:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{generate\PYGZus{}following\PYGZus{}index\PYGZus{}and\PYGZus{}element}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{for} \PYG{n}{index} \PYG{o+ow}{in} \PYG{n}{INDEX\PYGZus{}TYPES}\PYG{p}{:}
        \PYG{n}{GENERAL\PYGZus{}CONTEXT}\PYG{p}{[}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{index}\PYG{l+s}{\PYGZsq{}}\PYG{p}{]} \PYG{o}{=} \PYG{n}{index}
        \PYG{k}{for} \PYG{n+nb}{type} \PYG{o+ow}{in} \PYG{n}{ELEMENT\PYGZus{}TYPES}\PYG{p}{:}
            \PYG{n}{GENERAL\PYGZus{}CONTEXT}\PYG{p}{[}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{type}\PYG{l+s}{\PYGZsq{}}\PYG{p}{]} \PYG{o}{=} \PYG{n+nb}{type}
            \PYG{k}{yield} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{\PYGZus{}}\PYG{l+s+si}{\PYGZpc{}s}\PYG{l+s}{\PYGZus{}}\PYG{l+s+si}{\PYGZpc{}s}\PYG{l+s}{\PYGZsq{}} \PYG{o}{\PYGZpc{}} \PYG{p}{(}\PYG{n}{index}\PYG{p}{,} \PYG{n+nb}{type}\PYG{p}{)}\PYG{p}{,} \PYG{n}{GENERAL\PYGZus{}CONTEXT}
\end{Verbatim}

Because these functions are user-defined, you have total control and can generate any complicated combinations that you like.

Now we can use these callbacks and register them. For instance:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}action}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{config}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{*.*}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{n}{single\PYGZus{}generation}\PYG{p}{)}
\end{Verbatim}

This registers any template file (\code{'*.*'}) located in \code{cysparse/config} (linux version) with the user callback \code{single\_generation}.

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}action}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{cysparse/sparse/sparse\PYGZus{}utils/generic}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                       \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{generate\PYGZus{}indices.*}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                       \PYG{n}{generate\PYGZus{}following\PYGZus{}only\PYGZus{}index}\PYG{p}{)}
\end{Verbatim}

This time, we associate template files with the name \code{generate\_indices} inside the subdirectory \code{cysparse/sparse/sparse\_utils/generic}
with the \code{generate\_following\_only\_index} callback \footnote[3]{
Thus the real directory is \code{cysparse/cysparse/sparse/sparse\_utils/generic}.
}.

Here, we only associate template files with extension \code{.cpi} to the \code{generate\_following\_index\_and\_element} callback inside subdirectory \code{cysparse/sparse/csc\_mat\_matrices/csc\_mat\_kernel}:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{cygenja\PYGZus{}engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}action}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{cysparse/sparse/csc\PYGZus{}mat\PYGZus{}matrices/csc\PYGZus{}mat\PYGZus{}kernel}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                               \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{*.cpi}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                               \PYG{n}{generate\PYGZus{}following\PYGZus{}index\PYGZus{}and\PYGZus{}element}\PYG{p}{)}
\end{Verbatim}

You are allowed to define multiple actions for one subdirectory:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{cygenja\PYGZus{}engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}action}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{cysparse/sparse/sparse\PYGZus{}utils/generic}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                               \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{find.*}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                               \PYG{n}{generate\PYGZus{}following\PYGZus{}index\PYGZus{}and\PYGZus{}element}\PYG{p}{)}

\PYG{n}{cygenja\PYGZus{}engine}\PYG{o}{.}\PYG{n}{register\PYGZus{}action}\PYG{p}{(}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{cysparse/sparse/sparse\PYGZus{}utils/generic}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                               \PYG{l+s}{\PYGZsq{}}\PYG{l+s}{generate\PYGZus{}indices.*}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,}
                               \PYG{n}{generate\PYGZus{}following\PYGZus{}only\PYGZus{}index}\PYG{p}{)}
\end{Verbatim}

Remember that if a template file can be associated with several actions, only the \textbf{first} action will be triggered.


\section{File generation}
\label{examples:file-generation}
We are now ready to generate some files from some templates. There is only one method to call: \code{generate}. Its signature is:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{engine}\PYG{o}{.}\PYG{n}{generate}\PYG{p}{(}\PYG{n}{dir\PYGZus{}pattern}\PYG{p}{,} \PYG{n}{file\PYGZus{}pattern}\PYG{p}{,} \PYG{n}{action\PYGZus{}ch}\PYG{o}{=}\PYG{l+s}{\PYGZsq{}}\PYG{l+s}{g}\PYG{l+s}{\PYGZsq{}}\PYG{p}{,} \PYG{n}{recursively}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{,} \PYG{n}{force}\PYG{o}{=}\PYG{n+nb+bp}{False}\PYG{p}{)}
\end{Verbatim}

where \code{dir\_pattern} is a \textbf{\texttt{glob}} pattern used to match directories and \code{file\_pattern} a \textbf{\texttt{fnmatch}} pattern taken from all matching directories. This combination allows you to refine your operations with
a great flexibility. The \code{action\_ch} argument can be \code{g} (generate files), \code{c} (clean or erase files) or \code{d} (dry run).

This is the beginning of the output \textbf{\texttt{cygenja}} generates when asked a dry run for \textbf{all} file generation:

\begin{Verbatim}[commandchars=\\\{\}]
Process file \PYG{l+s+s1}{\PYGZsq{}config/setup.cpy\PYGZsq{}} with \PYG{k}{function} \PYG{l+s+s1}{\PYGZsq{}single\PYGZus{}generation\PYGZsq{}}:
   \PYGZhy{}\PYGZgt{} config/setup.py
Process file \PYG{l+s+s1}{\PYGZsq{}cysparse/sparse/ll\PYGZus{}mat.cpx\PYGZsq{}} with \PYG{k}{function} \PYG{l+s+s1}{\PYGZsq{}single\PYGZus{}generation\PYGZsq{}}:
   \PYGZhy{}\PYGZgt{} cysparse/sparse/ll\PYGZus{}mat.pyx
Process file \PYG{l+s+s1}{\PYGZsq{}cysparse/sparse/csc\PYGZus{}mat\PYGZus{}matrices/csc\PYGZus{}mat.cpx\PYGZsq{}} with
                            \PYG{k}{function} \PYG{l+s+s1}{\PYGZsq{}generate\PYGZus{}following\PYGZus{}index\PYGZus{}and\PYGZus{}element\PYGZsq{}}:
   \PYGZhy{}\PYGZgt{} cysparse/sparse/csc\PYGZus{}mat\PYGZus{}matrices/csc\PYGZus{}mat\PYGZus{}INT32\PYGZus{}t\PYGZus{}INT32\PYGZus{}t.pyx
   \PYGZhy{}\PYGZgt{} cysparse/sparse/csc\PYGZus{}mat\PYGZus{}matrices/csc\PYGZus{}mat\PYGZus{}INT32\PYGZus{}t\PYGZus{}INT64\PYGZus{}t.pyx
   \PYGZhy{}\PYGZgt{} cysparse/sparse/csc\PYGZus{}mat\PYGZus{}matrices/csc\PYGZus{}mat\PYGZus{}INT32\PYGZus{}t\PYGZus{}FLOAT32\PYGZus{}t.pyx
   \PYGZhy{}\PYGZgt{} cysparse/sparse/csc\PYGZus{}mat\PYGZus{}matrices/csc\PYGZus{}mat\PYGZus{}INT32\PYGZus{}t\PYGZus{}FLOAT64\PYGZus{}t.pyx
   \PYGZhy{}\PYGZgt{} cysparse/sparse/csc\PYGZus{}mat\PYGZus{}matrices/csc\PYGZus{}mat\PYGZus{}INT32\PYGZus{}t\PYGZus{}FLOAT128\PYGZus{}t.pyx
   \PYGZhy{}\PYGZgt{} cysparse/sparse/csc\PYGZus{}mat\PYGZus{}matrices/csc\PYGZus{}mat\PYGZus{}INT32\PYGZus{}t\PYGZus{}COMPLEX64\PYGZus{}t.pyx
   \PYGZhy{}\PYGZgt{} cysparse/sparse/csc\PYGZus{}mat\PYGZus{}matrices/csc\PYGZus{}mat\PYGZus{}INT32\PYGZus{}t\PYGZus{}COMPLEX128\PYGZus{}t.pyx
...
\end{Verbatim}

At the moment of writing, we have 23 registered actions that trigger 492 file generations.



\renewcommand{\indexname}{Index}
\printindex
\end{document}
