text:
<file_sep>[toc]

# The Main Buttons Bar

![Image of MenuBar](./src/images/menuBar.png)

This bar, located at the top of the Editor panel, lets you access the core functions of Natao.

## Zoom-In & Zoom-Out

 -  Increases the size of all the characters used in Natao's user interface.
 -  Decreases the size of all the characters used in Natao's user interface.

You should note that Natao saves interface modifications automatically. In other words, you won't have to go over them again after re-launching the program.

## Dyslexia

 Lets you activate *OpenDyslexic* characters for the whole of the program's interface. These characters are designed to help dyslexics read words on screen.

## The Three Panels

-  This button lets you hide/display your documents' navigation panel, which is also called **Documents**.
-  This button lets you hide/display the Markdown editor panel.
-  This button lets you hide/display the document Viewer panel.

## Print

 This button lets you print the document visible in the Viewer panel.

## Help

? This button lets you open Natao's Help window, which you are currently reading.

## Settings

 This button lets you access Natao's Settings.

# The Documents Panel

## The Documents Panel Tool Bar
![Image of ExplorerBar](./src/images/documents.png)

This bar displays a click-able title to switch from the **Trash-Bin** view to the **Documents** view.
This bar displays three extra buttons which let you:

-  Paste copied or cut content previously saved in Natao's clipboard.
-  Import content from a file.
-  Add a folder at the root of **Documents**. During the creation of the folder, you have the option of selecting one of Natao's folder-structure templates. This will add sub-folders to the folder you're creating.

## The Documents Explorer Tool Bar

![Image of Explorer](./src/images/explorer.png)

Here appear your folders and documents, organized as you see fit.

- One click on a folder icon will either reveal or hide its content.
- One click on the folder's name will open a pop-up tool menu that will let you edit the folder.
- One click on a document will open it in the Editor panel, as an editable Markdown text, and in the Viewer panel, as a digital preview of its printed version.

## The Pop-up Folder Tool Menu

![Image of Explorer](./src/images/folderOptions.png)

-  Lets you modify the folder's name, its color, and its default style-sheet. You should note that modifying the folder's style-sheet neither changes the style of that folder's sub-folders, nor the documents it contains.
-  Lets you add a sub-folder to the folder you've selected. You may also choose to use one Natao's folder-structure templates. Natao will automatically create sub-folders that correspond to that template.
-  Lets you add a document to the selected folder.
-  Lets you copy the selected folder and its content to Natao's clipboard.
-  Lets you cut the selected folder and its content to Natao's clipboard.
-  Lets you paste the selected folder and its content to Natao's clipboard.
-  Lets you export the selected folder and its content as a single file.
-  Lets you import a file's content to the selected folder.
-  Lets you save the selected folders' sub-folder structure as a new template. Be aware that the content of these folders and sub-folders is not saved. The new template will be usable each time you create new folders and sub-folders.
-  Lets you delete the selected folder and its content.

## The Trash-Bin

Selected, the trash-bin lets you see all the documents that you've marked for deletion.

You may :

-  Delete the documents for good.
-  Restore the documents marked for deletion to their original location (when possible).

# The Editor Panel

This panel lets you write your documents.

## Functions Overview

Three input-fields are available:

- *Title*: your document's title is independent of your document's core content. This allows you to see it within the Explorer panel. The document's title also appears in the Viewer panel.

- *Style*: the style you select modifies your document’s formatting in the Viewer pannel. You can modify these styles, as we'll see in a later part of our Help section.

- *Creation Date*: your document's creation date. By default, this is the date displayed by your computer. You can modify your document's creation date: you can, for instance, make it the date at which you're supposed to return your homework. Please note that the way the date appears in your document depends on the style-sheet you've selected.

Besides the three input-fields, additional buttons are present. These function similarly to the ones seen in the Explorer panel.

-  Lets you copy the active document, including its input-fields, to Natao's clipboard.
-  Lets you cuts the active document to Natao's clipboard.
-  Lets you export the active document to a file.
-  Lets you delete the active document. When you do, the Editor and Viewer windows will disappear, until you create a new document.

## Inserting an Image

-  Lets you insert an image in your document. The Markdown Help offers more details on this function in the *Images* chapter.

## The Editor Settings

The  button allows you to change the way the content seen in the Editor panel is displayed. The two available options are specifically designed to help people with visuospatial perception difficulties.

Specifically, this button lets you:

- Add gray and white stripes to your document. Some of the document's lines will turn gray, while others will remain white. This juxtaposition of gray and white lines will help you better navigate your document.
- Add space between lines by increasing their size, which adds space between the lines of text within your document.

## Text Search Function

The  button lets you open a search box above the Editor to look for text within the document currently being edited.

The text you insert in the search box will be highlighted within your document. The number of occurrences of the searched text will also be indicated.

The  and  arrows are designed to help you position the editing cursor on the various occurrences of the searched text. Said text will become highlighted with a darker color.

You may also replace the text you've searched for with whatever words you insert in the *Replace with* option.

-  lets you replace the text currently highlighted in your document.
-  lets you replace all the occurrences of the text you've searched for.

## The Markdown Editor

The Editor is composed of a window where you may write your Markdown text (to learn more about this syntax, I invite you  to consult the Markdown help section).

Alongside that window, a vertical bar either displays numbers or symbols depending on the context. Small triangles will appear here, ones that, once clicked, will open or fold you document to let you inspect its structure.

You will notice that the editor adds colors, differend font sizes, etc. to your Markdown text to hep you navigate it more easily.

# The Viewer Panel

This panel, the simplest of the three, may also be the most important. With it, you can see what your document will look like once it is printed. When you click on the  button, the entire Viewer panel will expand before asking you if you want to print your document or not.
<file_sep>(function () {
    "use strict";

    module.exports = (gulp,gulpSequence,fs,exec,config) => {

        var fileBasePathSDK = './'+ config.downloadFolder +'/nwjs-sdk-v' + config.version;
        var fileBasePathNormal = './'+ config.downloadFolder +'/nwjs-v' + config.version;

        gulp.task('unzip:Windows',function(cb) {
            var endFileName = '-win-x64.zip';

            exec('unzip ' + fileBasePathNormal + endFileName + ' -d ./' + config.unzipFolder, (error) => {
                if (error) {
                    console.error(`exec error: ${error}`);
                }
                cb()
            });

        });

        gulp.task('unzip:OSX',function(cb) {
            var endFileName = '-osx-x64.zip';
            // unzip with command line to keep the executables executables
            exec('unzip ' + fileBasePathNormal + endFileName + ' -d ./' + config.unzipFolder, (error) => {
                if (error) {
                    console.error(`exec error: ${error}`);
                }
                cb()
            });
        });

        gulp.task('unzip:Linux',function(cb) {
            var endFileName = '-linux-x64.tar.gz';
            // unzip with command line to keep the executables executables
            exec('gunzip -c '+ fileBasePathNormal + endFileName +' | tar -C ' + config.unzipFolder + ' -xopf -', (error) => {
                if (error) {
                    console.error(`exec error: ${error}`);
                }
                cb()
            });

        });

        gulp.task('unzip:WindowsSDK',function(cb) {
            var endFileName = '-win-x64.zip';

            // unzip with command line to keep the executables executables
            exec('unzip ' + fileBasePathSDK + endFileName + ' -d ./' + config.unzipFolder, (error) => {
                if (error) {
                    console.error(`exec error: ${error}`);
                }
                cb()
            });
        });

        gulp.task('unzip:OSXSDK',function(cb) {
            var endFileName = '-osx-x64.zip';
            // unzip with command line to keep the executables executables
            exec('unzip ' + fileBasePathSDK + endFileName + ' -d ./' + config.unzipFolder, (error) => {
                if (error) {
                    console.error(`exec error: ${error}`);
                }
                cb()
            });
        });

        gulp.task('unzip:LinuxSDK',function(cb) {
            var endFileName = '-linux-x64.tar.gz';
            // unzip with command line to keep the executables executables
            exec('gunzip -c '+ fileBasePathSDK + endFileName +' | tar -C ' + config.unzipFolder + ' -xopf -', (error) => {
                if (error) {
                    console.error(`exec error: ${error}`);
                }
                cb()
            });

        });

        gulp.task('unzip:All',gulpSequence(['unzip:Windows','unzip:Linux','unzip:OSX','unzip:WindowsSDK','unzip:LinuxSDK','unzip:OSXSDK']));

    };

}());

<file_sep>(function () {
    "use strict";

    var fs = require('fs');

    var modules = ['ngSanitize','pascalprecht.translate', 'tmh.dynamicLocale','ng-showdown'];

    angular
        .module('Natao', modules)
        .run(run);

    function run() {
    }

}());<file_sep>[toc]
# Comment signaler les formules AsciiMath
Pour signaler une formule mathématique, il suffit de l'entourer de 2 @.
Cela correspond à une formule dans la ligne courante. A toi de changer de paragraphe si tu souhaites la séparer du texte qui l'entoure.

	>Le partage du butin a été établi comme suit @@1/2@@ pour le capitaine, @@1/4@@ pour le navigateur, et l'équipage se partage le reste.

**donne ceci**:

>Le partage du butin a été établi comme suit @@1/2@@ pour le capitaine, @@1/4@@ pour le navigateur, et l'équipage se partage le reste.

# Les bases d'AsciiMath

## Poser des opérations
Tout d'abord, tu dois savoir que Natao ne te permet pas de poser des opérations, tu pourras seulement les écrire en ligne.
Je vais te donner de quoi commencer à l'utiliser:

| Caractère souhaité | Syntaxe |
|:------------------:|:-------:|
| @@=@@              | =       |
| @@+@@              | +       |
| @@-@@              | -       |
| @@xx@@             | xx      |
| @@-:@@             | -:      |
| @@!=@@             | !=      |
| @@<@@              | <       |
| @@<=@@             | <=      |
| @@>@@              | >       |
| @@>=@@             | >=      |

Ainsi tu peux écrire :

	>@@4 xx 3 = 12@@

    >@@100 -: 4 = 25@@

    >@@200mm < 25cm <= 3dm@@

pour obtenir :

>@@4 xx 3 = 12@@

>@@10 -: 2 = 5@@

>@@200mm < 25cm <= 3dm@@

Penses toujours à mettre des espaces autour des symboles < et > pour éviter qu'il y ait une confusion avec le html.

## Les fractions
Il est très simple d'écrire des fractions, il suffit d'utiliser le symbole "/" pour séparer les deux parties de celle-ci:
Tu peux donc ecrire ceci:

	>@@1/2 + 1/4 = 3/4@@

Pour obtenir cela:

>@@1/2 + 1/4 = 3/4@@

## pi
On va rajouter @@pi@@ pour ceux qui ont commencé les périmètres des cercles, et te voila déjà outillé pour les premières classes:

| Caractère souhaité | Syntaxe |
|:------------------:|:-------:|
| @@pi@@              | pi     |

Ainsi, tu pourras écrire:

@@périmètre = 2 xx pi xx rayon @@

# Concepts un peu plus avancés

## Indice et exposant
Tu peux utiliser le symbole "\_" pour mettre du texte en indice, et le symbole "^" pour mettre du texte en exposant.

	>@@x_1@@

    >@@x^2@@

    >@@x_1^2@@

**donne ceci**:

>@@x_1@@

>@@x^2@@

>@@x_1^2@@

Il est important de noter que quand tu as besoin des deux, tu dois toujours utiliser l'indice avant l'exposant.

Ces 2 syntaxes ont d'autres effets sur les éléments de formule qui ont besoin d'indice et/ou d'exposant :

	>@@sum_(n=1)^(n=5) 4^n@@

    >@@int_0^1 f(x)dx@@

>@@sum_(n=1)^(n=5) 4^n@@

>@@int_0^1 f(x)dx@@

## Les matrices et vecteurs

Il te suffit d'écrire ceci:

	>@@[[a,b],[c,d]]@@

Pour obtenir une matrice:

>@@[[a,b],[c,d]]@@

Et ceci:

	>@@((a,b),(c,d))@@

Pour obtenir un vecteur:

>@@((a,b),(c,d))@@

## Portée des symboles et fonctions

La plupart du temps, la portée des symboles s'applique au prochain caractère.

	>@@sqrt 1/3@@

**donne ceci**:

>@@sqrt 1/3@@

Si tu souhaites appliquer le symbole ou la fonction sur plusieurs caractères, il suffit de mettre des parenthèses autour de l'expression pour laquelle cela va s'appliquer.

	>@@sqrt(1/3)@@

**donne ceci**:

>@@sqrt(1/3)@@

On voit qu'ici, les parenthèses ne sont pas affichées, mais le symbole racine carrée s'applique à 1/3.

# Listes de symboles et fonctions

## Pour les opérations

| Caractère souhaité | Syntaxe    |
|:------------------:|:----------:|
| @@+@@              | +          |
| @@-@@              | -          |
| @@\*@@             | \*         |
| @@\*\*@@           | \*\*       |
| @@\*\*\*@@         | \*\*\*     |
| @@//@@             | //         |
| @@\\\\@@           | \\\\       |
| @@xx@@             | xx         |
| @@-:@@             | -:         |
| @@ @ @@            | @          |
| @@o+@@             | o+         |
| @@ox@@             | ox         |
| @@o.@@             | o.         |
| @@sqrt@@           | sqrt       |
| @@sum@@            | sum        |
| @@prod@@           | prod       |
| @@^^@@             | ^^         |
| @@^^^@@            | ^^^        |
| @@vv@@             | vv         |
| @@vvv@@            | vvv        |
| @@nn@@             | nn         |
| @@nnn@@            | nnn        |
| @@uu@@             | uu         |
| @@uuu@@            | uuu        |

## Pour les ensembles

| Caractère souhaité | Syntaxe    |
|:------------------:|:----------:|
| @@=@@              | =          |
| @@!=@@             | !=         |
| @@<@@              | <          |
| @@>@@              | >          |
| @@<=@@             | <=         |
| @@>=@@             | >=         |
| @@-<@@             | -<         |
| @@>-@@             | >-         |
| @@in@@             | in         |
| @@!in@@            | !in        |
| @@sub@@            | sub        |
| @@sup@@            | sup        |
| @@sube@@           | sube       |
| @@supe@@           | supe       |
| @@-=@@             | -=         |
| @@~=@@             | ~=         |
| @@\~~@@            | ~~         |
| @@prop@@           | prop       |

## Symboles logiques

| Caractère souhaité | Syntaxe    |
|:------------------:|:----------:|
| @@and@@            | and        |
| @@or@@             | or         |
| @@=>@@             | =>         |
| @@if@@             | if         |
| @@iff@@            | iff        |
| @@AA@@             | AA         |
| @@EE@@             | EE         |
| @@TT@@             | TT         |
| @@ \_|_ @@    | \_|\_ |
| @@ |-- @@     | |--   |
| @@ |== @@     | |==   |

## Groupements
| Caractère souhaité | Syntaxe    |
|:------------------:|:----------:|
| @@(@@              | (          |
| @@)@@              | )          |
| @@[@@              | [          |
| @@]@@              | ]          |
| @@{@@              | {          |
| @@}@@              | }          |
| @@(:@@             | (:         |
| @@:)@@             | :)         |
| @@{:@@             | {:         |
| @@:}@@             | :}         |

## Flèches
| Caractère souhaité | Syntaxe    |
|:------------------:|:----------:|
| @@uarr@@           | uarr       |
| @@darr@@           | darr       |
| @@rarr@@           | rarr       |
| @@->@@             | ->         |
| @@larr@@           | larr       |
| @@harr@@           | harr       |
| @@rArr@@           | rArr       |
| @@lArr@@           | lArr       |
| @@hArr@@           | hArr       |
| @@|->@@       | |->   |

## Accents

| Caractère souhaité | Syntaxe    |
|:------------------:|:----------:|
| @@hat x@@           | hat x     |
| @@bar x@@           | bar x     |
| @@ul x@@            | ul x      |
| @@vec x@@           | vec x     |
| @@dot x@@           | dot x     |
| @@ddot x@@          | ddot x    |

## Autres symboles

| Caractère souhaité | Syntaxe    |
|:------------------:|:----------:|
| @@sqrt@@           | sqrt       |
| @@int@@            | int        |
| @@oint@@           | oint       |
| @@del@@            | del        |
| @@grad@@           | grad       |
| @@+-@@             | +-         |
| @@O/@@             | O/         |
| @@oo@@             | oo         |
| @@aleph@@          | aleph      |
| @@/_@@             | /_         |
| @@:.@@             | :.         |
| @@cdots@@          | cdots      |
| @@vdots@@          | vdots      |
| @@ddots@@          | ddots      |
| @@diamond@@        | diamond    |
| @@square@@         | square     |
| @@CC@@             | CC         |
| @@NN@@             | NN         |
| @@QQ@@             | QQ         |
| @@RR@@             | RR         |
| @@ZZ@@             | ZZ         |

## Les lettres grecques

| Caractère souhaité | Syntaxe    |
|:------------------:|:----------:|
| @@alpha@@          | alpha      |
| @@beta@@           | beta       |
| @@chi@@            | chi        |
| @@delta@@          | delta      |
| @@Delta@@          | Delta      |
| @@epsilon@@        | epsilon    |
| @@varepsilon@@     | varepsilon |
| @@eta@@            | eta        |
| @@gamma@@          | gamma      |
| @@Gamma@@          | Gamma      |
| @@iota@@           | iota       |
| @@kappa@@          | kappa      |
| @@lambda@@         | lambda     |
| @@Lambda@@         | Lambda     |
| @@mu@@             | mu         |
| @@nu@@             | nu         |
| @@omega@@          | omega      |
| @@Omega@@          | Omega      |
| @@phi@@            | phi        |
| @@Phi@@            | Phi        |
| @@varphi@@         | varphi     |
| @@pi@@             | pi         |
| @@Pi@@             | Pi         |
| @@psi@@            | psi        |
| @@Psi@@            | Psi        |
| @@rho@@            | rho        |
| @@sigma@@          | sigma      |
| @@Sigma@@          | Sigma      |
| @@tau@@            | tau        |
| @@theta@@          | theta      |
| @@Theta@@          | Theta      |
| @@vartheta@@       | vartheta   |
| @@upsilon@@        | upsilon    |
| @@xi@@             | xi         |
| @@Xi@@             | Xi         |
| @@zeta@@           | zeta       |

# Tex

Il existe d'autres syntaxes pour écrire des formules mathématiques, la plus connue est TeX, et pour les utilisateurs qui connaissent déjà cette syntaxe, elle a été incluse dans Natao.

## Comment signaler les formules TeX
Pour TeX, il existe 2 signalétiques, la première permet d'utiliser des formules dans la ligne courante et utilise 2 $.

	>Le partage du butin a été établi comme suit $$\frac{1}{2}$$ pour le capitaine, $$\frac{1}{4}$$ pour le navigateur, et l'équipage se partage le reste.

**donne ceci**:

>Le partage du butin a été établi comme suit $$\frac{1}{2}$$ pour le capitaine, $$\frac{1}{4}$$ pour le navigateur, et l'équipage se partage le reste.

La seconde signalétique permet d'écrire la formule à la ligne et centrée. On utilise pour cela 3$.

	>Voici du texte suivi d'une formule $$$ \sqrt{\frac{1}{3}} $$$ et la formule et sa suite apparaissent séparés.

**donne ceci**:

>Voici du texte suivi d'une formule $$$ \sqrt{\frac{1}{3}} $$$ et la formule et sa suite apparaissent séparés.<file_sep>[toc]

Peut-être souhaites tu en savoir plus sur les raisons de faire ce logiciel, et sur la façon dont il est fait. Ce document est fait pour cela. Pour expliquer l'idée et les concepts derrière sa réalisation.

# Pourquoi ?

## Une petite histoire...
Je suis développeur, et comme la plupart de mes confrères, j'utilise des éditeurs de code qui me facilitent drôlement la vie, mais j'y reviendrais plus tard.

Mon fils est dyspraxique et on m'a demandé de lui fournir des modèles de documents Word, pour lui faciliter l'usage de l'ordinateur en classe. Et, si beaucoup pensent que c'est super cool d'utiliser un ordinateur en classe, je me suis dis que ce n'était pas aussi simple que ça en avait l'air. Et pourtant, ça le devrait.

Mais qu'est-ce qui ne va pas ?

## L'explorateur de fichiers
Un élève utilisant un ordinateur, doit classer ses documents dans des dossiers, dans une fenêtre *Explorateur de fichier* et les ouvrir dans une fenêtre à part *Traitement de texte*. Pour passer d'un document à un autre, il peut soit revenir sur la fenêtre *Explorateur de fichier*, soit aller explorer le menu du *Traitement de texte* pour aller ouvrir un document en ouvrant une mini fenêtre *Explorateur de fichier*.

Et bien pour les développeurs, la vie est plus douce. Nos éditeurs de code incluent bien souvent l'équivalent de l'*Explorateur de fichier* pratiquement affiché en permanence sur un panneau à gauche. Ainsi, nous ne perdons pas de vue, l'ensemble des fichiers de nos projets. Et mieux encore, un fichier que l'on ouvre ne surgit pas dans une nouvelle fenêtre, il est ouvert dans un panneau d'édition du même logiciel.

Voila pourquoi Natao inclut cette fonctionnalité essentielle.

Mais je me suis dit que je pouvais faire un peu mieux. Imaginons que cet *Explorateur de documents* puisse faciliter le rangement de ceux-ci.

J'ai donc intégré 2 fonctionnalités supplémentaires:
- La possibilité de colorer les titres de dossiers(là, c'est juste un repère visuel, et l'idée n'est pas de moi).
- La possibilité d'enregistrer une structure de dossiers et de sous-dossier, sous la forme d'un modèle pour recréer facilement un mode de rangement qui nous convient.

## L'éditeur Markdown
Je n'ai rien contre les logiciels de *Traitement de texte*, ce sont des outils formidables, offrant énormément de possibilités. Mais leur puissance et leur richesse diminuent leur simplicité. Et j'ai le sentiment que la simplicité est la clé de l'utilisation d'un ordinateur à l'école, surtout pour un enfant ayant des troubles Dys quels qu'ils soient.

Les développeurs ont-ils un traitement de texte plus facile ?

### LaTeX

Oui... et Non. Je ne vais pas parler au nom de tous les développeurs, car tous ne s'en servent pas, mais nous disposons d'un formidable *Traitement de texte* appelé **LaTeX**. Formidable, car il permet à celui qui le comprend de rédiger des documents d'une qualité irréprochable, sans avoir l'impression d'utiliser un *Traitement de texte* classique. Mais inaccessible pour le commun des mortels, car il faut littéralement coder son document.

Mais LaTeX m'a appris quelque chose de fondamental : **Séparer la forme du contenu**.

En LaTeX, on décrit un document. A l'aide de mots clés on permet à l'outil de comprendre la structure de notre document et de le mettre en forme uniformément. La syntaxe n'est pas aisée, mais elle est plutôt claire.
Là, où le bàt blesse, c'est qu'il est parfois assez difficile de faire sa propre mise en forme.

Inaccessible pour la plupart des adultes, alors pour un enfant...

### HTML / CSS
Actuellement un des meilleurs exemples de la séparation de la forme et du contenu.
Si vous ne savez pas ce que c'est, tous les sites webs sont faits avec ces 2 langages.
Le HTML, c'est le contenu, et le CSS la forme. Et le CSS permet vraiment de faire des choses superbes.
Malheureusement, ici c'est le HTML qui n'est pas aisé à écrire.

### Enfin, le Markdown
Le Markdown, ce sont les idées de LaTeX, en plus simple, et la puissance de CSS puisqu'au final, il génère du HTML.
Quand j'ai vu la simplicité de cette syntaxe, j'ai tout de suite imaginé le gain de temps à la saisie. Rester sur le clavier sans passer par l'étape clic de souris sur telle ou telle portion de texte, puis rechercher parmi toutes les options, celles qui nous conviennent.

Ici, on valorise son texte, on l'organise, et la mise en forme se fait à un autre endroit: l'éditeur de feuilles de style.
Quand la feuille de style est suffisante, elle est réutilisable à l'infini.

Je reconnais qu'écrire du CSS n'est pas à la portée de tout le monde, mais je vais travailler là dessus dans une prochaine version.

En tout cas, l'idée principale est là :
- Markdown pour le contenu.
- CSS pour la forme.

# Comment ?

Attention, ici on parle de technologie, alors si le sujet ne vous intéresse pas, inutile de poursuivre.
Précision importante toutes les technologies utilisées ici sont open-source et gratuites. N'importe qui peut créer gratuitement le logiciel qu'il a envie en assemblant ces composants.
Mais surtout, tous ont créé des outils formidables sans lesquels je n'aurais pas pu développer Natao.

## NW.js

Pour faire simple, disons que **NW.js** (anciennement NodeWebkit) est une machine virtuelle permettant de faire tourner une application de type web embarquée que l'on livre avec **NW.js**, et plus important encore qui permet de la faire fonctionner déconnectée d'internet.
Natao, c'est du javascript, du HTML et du CSS exécuté par **NW.js** et livré avec ce dernier.

**NW.js** est multi plate-formes, Windows, MacOSX et Linux. Du coup, le code permettant de faire Natao est développé une fois et tourne sur les 3 plate-formes nativement.

## Showdown
Le deuxième élément est Showdown. C'est ce dernier qui transforme le Markdown en HTML. Sans lui, pas de rendu. Et Showdown permet de lire en plus du Markdown étendu comme GFM (Github Flavored Markdown)

## MathJax
Celui-ci permet de faire le rendu des formules mathématiques.

## CodeMirror
Ce dernier est l'éditeur de texte qui valorise en cours de frappe le MarkDown et le CSS, numérote les lignes. etc...

## NeDB
Une base de données qui tourne nativement sous Node.js et qui permet notamment ici de tout enregistrer dans un seul fichier, plutôt que disperser vos documents un peu partout et les perdre.

## Angular
C'est le framework javascript développée par Google qui sert de pierre angulaire à l'application Natao.

## OpenDyslexic
Quand j'ai cherché une police pour dyslexique, je n'en ai trouvé qu'une seule d'open-source et plusieurs payantes. Très honnêtement, cela me désole qu'elles ne soient pas toutes open-source et gratuites...
Donc, un grand merci pour cette initiative.

## Et les autres
Il y a plusieurs librairies utilisées pour développer Natao, je vais essayer de les lister:
- **crypto-js** pour chiffrer le mot de passe
- **css** pour analyser le code css que vous rédigez
- **js-beautify** pour rendre le code HTML généré par Showdown lisible
- **lodash** une boite à outil indispensable
- **node-uuid** pour générer les id de chaque noeud de l'arborescence de l'explorateur
- **ng-showdown** pour faire fonctionner showdown avec Angular
- **typicons** toutes les icones utilisées ici
- **angular-tree-control$** l'explorateur de fichier
- **nw-fileDialog** les fenêtres d'ouverture de fichiers
- **angular-i18n** la base de l'internationalisation
- **angular-dynamic-locale** permettant de s'assurer que l'internationalisation fonctionne parfaitement
- **nsPopover** les petites fenêtres blanches de choix ou de confirmation
- **angular-ui-switch** les boutons switch dans l'éditeur de style notamment
- **angular-route** le routeur des différentes pages
- **ngjs-color-picker** qui permet d'adapter Inlet à Codemirror
- **angular-ui-codemirror** qui permet de faire tourner codemirror avec Angular
- **Inlet** le composant permettant de choisir les couleurs dans l'éditeur de CSS
- **angular-translate** la librairie permettant de gérer les langages
- **angular-translate-loader-static-files** pour charger des fichiers de langues
- **jquery** la base d'Angular
- **ngOnboarding** le composant qui permet de présenter Natao au premier démarrage

<file_sep>[toc]

# Writing formulae in AsciiMath

When you write a mathematical formula, surround it with two at-signs ( @@ ), as follows:

        >The loot was shared as follows, @@1/2@@ for the captain, @@1/4@@ for the helmsman, and the remainder for the rest of the crew.

Which gives:

>The loot was shared liek so: @@1/2@@ for the captain, @@1/4@@ for the helmsman, and the remainder for the rest of the crew.

As illustrated above, the math formula portion of your text will appear as an inline formula contained within the rest of your text. To separate the formula from your text, simply start a new paragraph by pressing once on your beyboard's Enter or Return key, thus adding a blank space between your formulae (as discussed in the Markdown Help document).

# Basic AsciiMath

## Basic Operations

With Natao, you may only write in-line operations.

Here are some examples:

|  AsciiMath Syntax  | Character |
|:------------------:|:--------------:|
| @@=@@              |        =       |
| @@+@@              |        +       |
| @@-@@              |        -       |
| @@xx@@             |        xx      |
| @@-:@@             |        -:      |
| @@!=@@             |        !=      |
| @@<@@              |        <       |
| @@<=@@             |        <=      |
| @@>@@              |        >       |
| @@>=@@             |        >=      |

You may thus write:

    >@@4 xx 3 = 12@@

    >@@100 -: 4 = 25@@

    >@@200mm < 25cm <= 3dm@@

to obtain:

>@@4 xx 3 = 12@@

>@@10 -: 2 = 5@@

>@@200mm < 25cm <= 3dm@@

Remember to leave spaces before and after the less-than ( < ) signs and greater-than signs ( > ) to avoid any confusion with HTML code.

## Fractions

Use the slash sign ( / ) to separate two portion of a single formula, as follows:

        >@@1/2 + 1/4 = 3/4@@

You should get the following:

>@@1/2 + 1/4 = 3/4@@

## Pi

If you've started learning how to calculate circle perimeters, you'll be asked to use the Pi sign in your calculations. Simply surround the word Pi with two at-signs ( @ ), as follows:

| AsciiMath Syntax | Charcater |
|:----------------:|:---------:|
| @@pi@@           | pi        |

You may thus write:

@@perimeter = 2 xx pi xx radius @@

# Advanced AsciiMath

## Indexes & Exponents

You may use the underscore-sign ( _ ) after a plain text number or expression to indicate that an index follows.

When a caret-sign ( ^ ) is written after a plain text number or expression, an exponent appears, as follows:

    >@@x_1@@

    >@@x^2@@

    >@@x_1^2@@

Which gives:

>@@x_1@@

>@@x^2@@

>@@x_1^2@@

You should note that when you need to show the index and the exponent symbols at the same time, you should always use the index sign first.

These two types of symbols can also be used to change the elements of a mathematical formula, as the following examples illustrate:

    >@@sum_(n=1)^(n=5) 4^n@@

    >@@int_0^1 f(x)dx@@

    >@@sum_(n=1)^(n=5) 4^n@@

    >@@int_0^1 f(x)dx@@

## Matrices & Vectors

The AsciiMath notation for matrices is as follows:

        >@@[[a,b],[c,d]]@@

You will then get the following matrix:

>@@[[a,b],[c,d]]@@

The AsciiMath notation for vectors is as follows:

        >@@((a,b),(c,d))@@

You will then obtain the following vector:

>@@((a,b),(c,d))@@

## Symbols & Functions

Usually, AsciiMath syntax symbols affect the characters that follow them. For instance, by writing the following example:

        >@@sqrt 1/3@@

You get:

>@@sqrt 1/3@@

If you wish to apply a symbol, or a function, to a group of characters, simply write parentheses around the group of characters, as follows:

    >@@sqrt(1/3)@@

You will then obtain:

>@@sqrt(1/3)@@

In the examples above, you will notice that the parentheses are not visible, and that the AsciiMath square root symbol is applied to (1/3).

# List of Symbols and Functions

## Operations

| AsciiMath Syntax | Character |
|:----------------:|:---------:|
| @@+@@            | +         |
| @@-@@            | -         |
| @@\*@@           | \*        |
| @@\*\*@@         | \*\*      |
| @@\*\*\*@@       | \*\*\*    |
| @@//@@           | //        |
| @@\\\\@@         | \\\\      |
| @@xx@@           | xx        |
| @@-:@@           | -:        |
| @@ @ @@          | @         |
| @@o+@@           | o+        |
| @@ox@@           | ox        |
| @@o.@@           | o.        |
| @@sqrt@@         | sqrt      |
| @@sum@@          | sum       |
| @@prod@@         | prod      |
| @@^^@@           | ^^        |
| @@^^^@@          | ^^^       |
| @@vv@@           | vv        |
| @@vvv@@          | vvv       |
| @@nn@@           | nn        |
| @@nnn@@          | nnn       |
| @@uu@@           | uu        |
| @@uuu@@          | uuu       |

## Ensembles

| AsciiMath Syntax | Character |
|:----------------:|:---------:|
| @@=@@            | =         |
| @@!=@@           | !=        |
| @@<@@            | <         |
| @@>@@            | >         |
| @@<=@@           | <=        |
| @@>=@@           | >=        |
| @@-<@@           | -<        |
| @@>-@@           | >-        |
| @@in@@           | in        |
| @@!in@@          | !in       |
| @@sub@@          | sub       |
| @@sup@@          | sup       |
| @@sube@@         | sube      |
| @@supe@@         | supe      |
| @@-=@@           | -=        |
| @@~=@@           | ~=        |
| @@\~~@@          | ~~        |
| @@prop@@         | prop      |

## Logic symbols

| AsciiMath Syntax | Character |
|:----------------:|:---------:|
| @@and@@          | and       |
| @@or@@           | or        |
| @@=>@@           | =>        |
| @@if@@           | if        |
| @@iff@@          | iff       |
| @@AA@@           | AA        |
| @@EE@@           | EE        |
| @@TT@@           | TT        |
| @@ \_|_ @@  | \_|\_ |
| @@ |-- @@   | |--   |
| @@ |== @@   | |==   |

## Grouping

| AsciiMath Syntax | Character |
|:----------------:|:---------:|
| @@(@@            | (         |
| @@)@@            | )         |
| @@[@@            | [         |
| @@]@@            | ]         |
| @@{@@            | {         |
| @@}@@            | }         |
| @@(:@@           | (:        |
| @@:)@@           | :)        |
| @@{:@@           | {:        |
| @@:}@@           | :}        |

## Arrows

| AsciiMath Syntax | Character |
|:----------------:|:---------:|
| @@uarr@@         | uarr      |
| @@darr@@         | darr      |
| @@rarr@@         | rarr      |
| @@->@@           | ->        |
| @@larr@@         | larr      |
| @@harr@@         | harr      |
| @@rArr@@         | rArr      |
| @@lArr@@         | lArr      |
| @@hArr@@         | hArr      |
| @@|->@@       | |->   |

## Accents

| AsciiMath Syntax | Character |
|:----------------:|:---------:|
| @@hat x@@        | hat x     |
| @@bar x@@        | bar x     |
| @@ul x@@         | ul x      |
| @@vec x@@        | vec x     |
| @@dot x@@        | dot x     |
| @@ddot x@@       | ddot x    |

## Other Symbols

| AsciiMath Syntax | Character |
|:----------------:|:---------:|
| @@sqrt@@         | sqrt      |
| @@int@@          | int       |
| @@oint@@         | oint      |
| @@del@@          | del       |
| @@grad@@         | grad      |
| @@+-@@           | +-        |
| @@O/@@           | O/        |
| @@oo@@           | oo        |
| @@aleph@@        | aleph     |
| @@/_@@           | /_        |
| @@:.@@           | :.        |
| @@cdots@@        | cdots     |
| @@vdots@@        | vdots     |
| @@ddots@@        | ddots     |
| @@diamond@@      | diamond   |
| @@square@@       | square    |
| @@CC@@           | CC        |
| @@NN@@           | NN        |
| @@QQ@@           | QQ        |
| @@RR@@           | RR        |
| @@ZZ@@           | ZZ        |

## Greek Letters

| AsciiMath Syntax   | Character  |
|:------------------:|:----------:|
| @@alpha@@          | alpha      |
| @@beta@@           | beta       |
| @@chi@@            | chi        |
| @@delta@@          | delta      |
| @@Delta@@          | Delta      |
| @@epsilon@@        | epsilon    |
| @@varepsilon@@     | varepsilon |
| @@eta@@            | eta        |
| @@gamma@@          | gamma      |
| @@Gamma@@          | Gamma      |
| @@iota@@           | iota       |
| @@kappa@@          | kappa      |
| @@lambda@@         | lambda     |
| @@Lambda@@         | Lambda     |
| @@mu@@             | mu         |
| @@nu@@             | nu         |
| @@omega@@          | omega      |
| @@Omega@@          | Omega      |
| @@phi@@            | phi        |
| @@Phi@@            | Phi        |
| @@varphi@@         | varphi     |
| @@pi@@             | pi         |
| @@Pi@@             | Pi         |
| @@psi@@            | psi        |
| @@Psi@@            | Psi        |
| @@rho@@            | rho        |
| @@sigma@@          | sigma      |
| @@Sigma@@          | Sigma      |
| @@tau@@            | tau        |
| @@theta@@          | theta      |
| @@Theta@@          | Theta      |
| @@vartheta@@       | vartheta   |
| @@upsilon@@        | upsilon    |
| @@xi@@             | xi         |
| @@Xi@@             | Xi         |
| @@zeta@@           | zeta       |

# TeX

Other syntax, besides AsciiMath, can be used to write mathematical formulae. The most known of these is called TeX (pronounced Tek). It has been included in Natao.

## Tex Mathematical Formulae

In TeX, formulae can either be centered or written as inline formulae.

### Inline Formulae:

The formula appears within a line of text. Simply start and end your formula with two dollar signs ( $$ ), as follows:

        >The loot was thus shared: $$\frac{1}{2}$$ for the captain, $$\frac{1}{4}$$ for the helmsman, and the remainder for the rest of the crew.

Which gives:

>The loot was thus shared: $$\frac{1}{2}$$ for the captain, $$\frac{1}{4}$$ for the helmsman, and the remainder for the rest of the crew.

### Centered Formulae:

The formula appears after the line of text, in the center of the document's page. Simply start and end your formula with three dollar signs ( $$$ ), like so:

        >Here is some text followed by a formula $$$\sqrt{\frac{1}{3}}$$$. The formula appears separately from the text.

Which gives:

>Here is some text followed by a formula $$$\sqrt{\frac{1}{3}}$$$. The formula appears separately from the text.
<file_sep>[toc]

# Why create Natao?

## A little story ...

I'm a software developer and, like many of my colleagues, I use text/code editors to help me do my work.

Because my son has dyspraxia, I was asked by his teacher to design MS Word document templates to help him use his laptop at school. Working with a computer at school may sound pretty fun, but, for anyone with dyspraxia, it's actually fraught with pitfalls.

To organize their document files, students must indeed file them into folders by opening a *File Explorer* window. To read, write and edit them, students have to open the document files with a *Word Processing* program. The documents then appear in a new window. Moreveor, to switch to any other document file, students must either go back to the *File Explorer* window, or open yet another window within the *Word Processing* program.
That's a lot of clicking around and navigating back and forth between windows.

For us, software developers, life's more straightforward. Often our text/code editor includes *File Explorer* panels that are continuously displayed to the left of our editor's windows. We therefore never lose sight of the files contained in our project. Even better, newly opened files don't pop up in new windows: they merely appear in the editor's central panel. It's a logical, efficient and time-saving way of working. Natao works similarly.

I then thought that I could give Natao additional functions. Indeed, what if the *File Explorer* window also helped users organize their document files? Done! So here's what Natao can do too:

- Give its users the ability to colorize folder names, so as to give its users helpful visual pointers (this idea has been implemented in other editors too).
- Let its users record folder/sub-folder structures as templates, to facilitate the organization of files and documents across projects.

## The Markdown editor

Let it be known that I have nothing against *Word Processing* programs! They are very powerful tools and work well for most users. But that power makes them complex to handle, which, I feel, doesn't help young students, some of whom struggle with conditions like dyspraxia.

So, are there simpler, non-*Word Processor* solutions out there that help people write and format documents? Yes! ... and no.

### LaTeX

I won't claim to speak for all developers, as not all of them use it, but LaTex is a very powerful *Word Processing* technology. For the ones who know how to harness its power, LaTex can indeed help people generate perfectly formatted texts, without having to use mainstream *Word Processing* programs. It does so by completely separating a document's form from its content.

Its main drawback? Its users have to code their documents, literally. By using certain key words, they indeed organize and structure their text. LaTex's syntax is not always easy to use though. And creating one's own formatting style can be arduous.

So if LaTex is difficult for adults to learn, how can one even think of having children use it? Is there any other technology out there that young students could use instead of it?

### HTML / CSS

The HTML and CSS syntax, which are both great examples of the form-separated-from-content approach to text formatting, offer solutions.
If you don't know what they are, just know that all web site are written in HTML and CSS: HTML handles content and CSS handles form, sometimes superbly. But in this particular case, it's the HTML syntax that's not easy to handle.

### Markdown

The Markdown language, which generates an HTML-like syntax, combines a simpler approach to some of the ideas found in LaTex and the power of the CSS code.

Upon discovering the Markdown language, I immediately noticed its simplicity and how much faster it was making the writing process. Markdown does that by letting its users stay focused on their text's content, without having to click on any portion of the text, or having to navigate through an array of formatting options to format it.
The formatting takes place elsewhere, in the style-sheet editor. And when a style-sheet works, it may be re-used in all subsequent documents.

I am aware that writing CSS code is not for everyone, but I hope to facilitate the process in a later version of Natao.

Still, at the core of Natao lie two approaches to text writing and text formatting:

- The Markdown syntax deals with content.
- The CSS syntax deals with form.

# How was Natao created?

(*Before going any further, let me state that the following section deals with coding technology. So if the subject doesn't appeal to you, skip it!*)

Before listing all the tools I used to create Natao, I'd like to mention that they are all open-source, and freely available online for all to use. Without these tools Natao could not have been put together.

## NW.js

To stay simple, **NW.js**, which used to be known as NodeWebkit, is a virtual machine that lets programs run without having to be linked to the Internet. Natao, which is written in JavaScript, HTML and CSS, therefore runs under **NW.js**, with which it is distributed.

Moreveor, **NW.js** is platform-independent: it runs equally well under the Windows, Mac OSX and Linux environments. This allows Natao to run on all three platforms, natively, without having to be coded three times.

## Showdown

**Showdown** transforms the Markdown language into HTML code. Without this tool, no Natao document could be rendered.
**Showdown** also allows the extended form of Markdown called GFM (Github Flavored Markdown) to be used.

## MathJax

This technology gives Natao the ability to render mathematical formulae.

## CodeMirror

This tool lets Natao number lines, highlight portions of the Markdown and CSS syntaxes, etc.

## NeDB

This technology creates a database that runs natively under **Node.js** and that lets Natao record all modifications and work done on one document in a single file. That way, files stay grouped and well organized.

## Angular

**Angular**, which is the javascript framework developed by Google, stands at the core of Natao.

## OpenDyslexic

I opted to use this font as it's the only one I found that's open-source and free for anyone to use. That almost all fonts for dyslexics are not free is a sad state of affair. So thank you very much to the people behind the OpenDyslexic initiative.

## And many others ...

A few libraries were used to develop Natao. Here's a list of them.

- **crypto-js** to encrypt the password.
- **css** to analyze the CSS code used by Natao's user.
- **js-beautify** to make the HTML code generated by Showdown readable.
- **lodash**, which is a key set of tools.
- **node-uuid** to generate unique identifiers for each of the explorer nodes.
- **ng-showdown** to make Showdown work with Angular.
- **typicons** used for all of Natao's icons.
- **angular-tree-control$** which is Natao's file explorer.
- **nw-fileDialog** which let the file windows open.
- **angular-i18n** which makes internationalization work.
- **angular-dynamic-locale** which makes sure that Natao's internationalization works perfectly.
- **nsPopover** which makes the little, white, choice or confirmation windows work.
- **angular-ui-switch** which make the switch buttons work, particularly the ones found in the Style Editor.
- **angular-route** which stands behind the proper routing of all of Natao's various pages.
- **ngjs-color-picker** to adapt Inlet to Codemirror.
- **angular-ui-codemirror** to make Codemirror work with Angular.
- **Inlet** which lets Natao's users pick colors in the CSS editor.
- **angular-translate** which is the library that organizes all languages.
- **angular-translate-loader-static-files** is used to load the various language files.
- **jquery** is Angular's base.
- **ngOnboarding** is the module that lets Natao appear on the first run.
<file_sep>(function () {
    "use strict";

    var beautify_html = require('js-beautify').html;
    var fs = require('fs');
    var uuid = require('node-uuid');
    var _ = require('lodash');

    angular
        .module('Natao')
        .controller('SettingsController', SettingsController);

    function SettingsController($rootScope,$scope,PreferencesService,DatabaseService,$location,$sce,fileDialog,OnBoardingService, ShowDownUtilService,
                                CssService,DocumentsService,TemplateTreeService,$showdown,focus,$timeout,TreeUtilService,MessageService, PrincipalTreeService) {

        var self = this;

        self.PreferencesService = PreferencesService;
        self.$sce = $sce;
        self.DatabaseService = DatabaseService;
        self.$scope = $scope;
        self.$rootScope = $rootScope;

        self.fileDialog = fileDialog;
        self.CssService = CssService;
        self.DocumentsService = DocumentsService;
        self.TemplateTreeService = TemplateTreeService;
        self.$showdown = $showdown;
        self.focus = focus;
        self.$timeout = $timeout;
        self.TreeUtilService = TreeUtilService;
        self.MessageService = MessageService;
        self.OnBoardingService = OnBoardingService;
        self.PrincipalTreeService = PrincipalTreeService;
        self.ShowDownUtilService = ShowDownUtilService;
        self.MessageService.changeMessage('');
        self.viewer = true;
        self.checkmark = false;
        self.disableDocumentChoice = true;
        self.otherAvailableCss = [];

        self.buffer = null;
        self.nodesPendingPaste = 0;

        //for codeMirror
        self.cssEditorOptions = {
            lineWrapping : true,
            lineNumbers: true,
            mode: 'css',
            foldGutter: true,
            gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
            extraKeys: {"Ctrl-Space": "autocomplete"}
        };

        self.htmlEditorOptions = {
            lineWrapping : true,
            lineNumbers: true,
            foldGutter: true,
            gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
            readOnly: 'nocursor'
        };

        // to ensure that the  wil open in a browser not in Natao
        // We have to watch the current markdown and force the behavior of all
        self.$rootScope.$watch(function(){
            return self.currentDoc.md;
        },function() {
            self.ShowDownUtilService.showDownHooks();
        });

        /**
         * reset the current doc in the css part
         */
        self.resetCurrentDoc = function() {
            self.currentDoc = {
                md:''
            };
        };
        //init currentDoc
        self.resetCurrentDoc();

        /**
         * this function set the css editor and associate Inlet to it
         * @param editor
         */
        self.setCssEditor = function(editor) {
            self.cssEditor = editor;
            Inlet(editor);
        };

        /**
         * check if a css is valid
         */
        self.settingsValide = function() {
            self.valid = self.PreferencesService.isValid();
        };

        /**
         * save editor preferences
         */
        self.save = function() {
            self.PreferencesService.save();
            $location.path( '/editor' );
        };

        /**
         * set a new database file
         */
        self.newDatabase = function() {
            self.fileDialog.saveAs(function(filename) {
                self.PreferencesService.settings.fileDatabase = filename;
                if (fs.existsSync(filename)) {
                    fs.unlinkSync(filename);
                }
                self.$scope.$apply();
            },'Natao.db',['db']);
        };

        /**
         * choose an existing database file
         */
        self.chooseDatabase = function() {
            self.fileDialog.openFile(function(filename){
                self.PreferencesService.settings.fileDatabase = filename;
                self.PreferencesService.saveSettings();
                self.PreferencesService.init();
            }, false, ['db']);
        };

        /* *************CSS**************** */

        /**
         * save the current css
         */
        self.saveCss = function() {
            if (self.currentCss) {
                self.CssService.initCurrentByContent(self.currentCss.css);
                self.CssService.saveCss(self.currentCss);
            }
        };

        /**
         * change the current html
         */
        self.changeDocument = function() {
            self.currentHTML = self.$showdown.makeHtml(self.currentDoc.md);
            self.allHtml();
        };

        /**
         * change the choice of documents for example
         */
        self.changeDocumentChoice = function() {
            self.resetCurrentDoc();

            self.documentsPromise = self.DocumentsService.getDocumentsByCss(self.currentCss._id);
            self.documentsPromise.then(function(docs) {
                if (!docs || docs.length === 0) {
                    self.documentsPromise = self.DocumentsService.getDocumentsByCss();
                    self.documentsPromise.then(function(docs) {
                        self.documents = docs;
                        self.disableDocumentChoice = false;
                    }).catch((err) => {
                        console.error(err);
                    })
                } else {
                    self.documents = docs;
                    self.disableDocumentChoice = false;
                }
            }).catch((err) => {
                console.error(err);
            });
        };

        /**
         * change the current css
         */
        self.changeCss = function() {
            self.CssService.initCurrentByContent(self.currentCss.css);
            self.focus('cssEditor');

            self.changeDocumentChoice();

            self.otherAvailableCss = self.CssService.otherCss(self.currentCss);
        };

        /**
         * init the popup to add new css
         */
        self.initAddCss= function() {
            self.newCssName = null;
            self.focus('addCssName');
        };

        /**
         * add a new css from the popup add
         * @param hide
         */
        self.addCss = function(hide) {
            self.CssService.addCssNamed(self.newCssName)
                .then(function(res) {
                    self.currentCss = res;
                    self.changeCss();
                })
                .catch(function(err) {
                    console.error(err);
                });
            self.focus('cssEditor');
            hide();
        };

        /**
         * delete a css from the popup delete
         * @param hide
         */
        self.deleteCss = function(hide) {
            self.CssService.deleteCss(self.currentCss, self.currentReplaceCss);
            self.currentCss = null;
            self.resetCurrentDoc();
            self.disableDocumentChoice = true;
            self.CssService.initCurrentByContent('');
            hide();
        };

        /**
         * set the editor read only for the html part
         * @param _editor
         */
        self.editorReadOnly = function(_editor) {
            // Options
            _editor.setReadOnly(true);
        };

        /**
         * generate the html code used in the visualisation
         */
        self.allHtml = function() {

            var completeHtml = '
' +
                '
' +
                '
' +
                '
' + self.PreferencesService.preferences.name +'
' +
                '
' + self.PreferencesService.preferences.firstName +'
' +
                '
' + self.PreferencesService.preferences.className + '
' +
                '
' +
                '
' +
                '
' + self.currentDoc.title +'
' +
                '
' + self.currentDoc.created + '
' +
                '
' +
                '
' +
                '

' +
                '
' +
                '

' +
                '
'+ self.currentHTML +'
' +
                '

';

            self.currentHtmlAll = beautify_html(completeHtml);
        };

        /**
         * the option tree used in codeMirror
         * @type {{nodeChildren: string, dirSelectable: boolean, injectClasses: {ul: string, li: string, liSelected: string, iExpanded: string, iCollapsed: string, iLeaf: string, label: string, labelSelected: string}, isLeaf: SettingsController.treeOptions.isLeaf}}
         */
        self.treeOptions = {
            nodeChildren: "children",
            dirSelectable: true,
            injectClasses: {
                ul: "a1",
                li: "a2",
                liSelected: "a7",
                iExpanded: "a3",
                iCollapsed: "a4",
                iLeaf: "a5",
                label: "a6",
                labelSelected: "a8"
            },
            isLeaf: function(node) {
                return node.leaf;
            }
        };

        /* *************Templates**************** */

        /**
         * save the current template
         */
        self.saveTemplate = function() {
            if (self.currentTemplate) {
                self.TemplateTreeService.saveTemplate(self.currentTemplate);
            }
        };

        /**
         * init the popu to add template
         */
        self.initAddTemplate= function() {
            self.newTemplateName = null;
            self.focus('addTemplateName');
        };

        /**
         * add a template from the popup
         * @param hide
         */
        self.addTemplate = function(hide) {
            self.TemplateTreeService.addTemplate(self.newTemplateName)
                .then(function(res) {
                    self.currentTemplate = res;
                })
                .catch(function(err) {
                    console.error(err);
                });
            hide();
        };

        /**
         * delete a template from the popup
         * @param hide
         */
        self.deleteTemplate = function(hide) {
            self.TemplateTreeService.deleteTemplate(self.currentTemplate);
            self.currentTemplate = null;
            hide();
        };

        /**
         * open th popover with all functionnalities
         * the possible values of folderPopover are ['buttonBar','edit','addFolder','delete']
         * @param node
         */
        self.openFolderPopover = function(node) {
            self.currentNode = node;
            self.newNameFolder = node.name;
            self.newDefaultCss = node.defaultCss;
            self.folderPopover = 'buttonBar';
            self.newColor = node.color;
        };

        /**
         * return true if there is something in the buffer
         * @returns {boolean}
         */
        self.pasteButtonDisabled = function() {
            return !(self.buffer);
        };

        /**
         * the popover in edit mode
         */
        self.editFolder = function() {
            self.folderPopover = 'edit';
            self.focus('folderName');
        };

        /**
         * the popover in add mode
         */
        self.openAddFolder = function() {
            self.newFolderName = null;
            self.folderPopover = 'addFolder';
            self.templateName = null;
            self.focus('addFolderName');
        };

        /**
         * the popover in delete mode
         */
        self.openDelete = function() {
            self.folderPopover = 'delete';
            self.cancel = false;
        };

        /**
         * the popover in confirm mode
         */
        self.openConfirmTemplate = function() {
            self.folderPopover = 'confirmTemplate';
            self.cancel = false;
        };

        /**
         * the cancel action from popover
         * @param hide
         */
        self.cancelAction = function(hide) {
            self.cancel = true;
            hide();
        };

        /**
         * the submit action from popover
         * with different modes
         * @param hide
         */
        self.submitFolderPopover = function(hide){
            switch (self.folderPopover) {
                case 'edit':
                    self.saveFolder(hide);
                    break;
                case 'addFolder':
                    self.addFolder(hide);
                    break;
                case 'delete':
                    if (!self.cancel) {
                        self.deleteNode(self.currentNode);
                    } else {
                        hide();
                    }
                    break;
                default: break;
            }
        };

        /**
         * copy folder in buffer
         * @param hide
         */
        self.copyFolder = function(hide) {

            self.TreeUtilService
                .nodeToBuffer(self.currentNode)
                .then(function(buffer) {
                    self.buffer = buffer;
                })
                .catch(function(err) {
                    console.error(err);
                });
            hide();
        };

        /**
         * cut folder in buffer
         * @param hide
         */
        self.cutFolder = function(hide) {

            self.TreeUtilService
                .nodeToBuffer(self.currentNode)
                .then(function(buffer) {
                    self.buffer = buffer;
                    self.deleteNode(self.currentNode);
                })
                .catch(function(err) {
                    console.error(err);
                });

            hide();
        };

        /**
         * paste from buffer
         * @param hide
         */
        self.pasteFolder = function(hide) {

            if (self.buffer) {
                self.TreeUtilService
                    .bufferToNode(self.buffer)
                    .then(function(node) {
                        if (self.currentNode && self.currentNode.children) {
                            self.currentNode.children.push(node);
                            self.buffer = null;
                            self.TemplateTreeService.saveTemplate(self.currentTemplate,self.currentTemplate.name);
                        }
                    })
                    .catch(function(err) {
                        console.error(err);
                    });
            }
            hide();

        };

        /**
         * add a new folder from popover
         * @param hide
         */
        self.addFolder = function(hide) {
            if (self.newFolderName && self.newFolderName.length > 0) {
                var newNode = {
                    id: uuid.v4(),
                    name: self.newFolderName,
                    color: '#000000',
                    children:[]
                };

                newNode.defaultCss = self.currentNode.defaultCss;
                self.currentNode.children.push(newNode);

                //and we open the node parent
                self.expandedNodes.push(self.currentNode);

                // if the new folder is the first one
                if (!self.selectedNode) {
                    self.selectedNode = newNode;
                }
            }
            //And we save the modifications
            self.TemplateTreeService.saveTemplate(self.currentTemplate,self.currentTemplate.name);
            hide();
        };

        /**
         * save the folder from popover
          * @param hide
         */
        self.saveFolder = function(hide) {
            if (self.newNameFolder && self.newNameFolder.length > 0) {
                self.currentNode.name = self.newNameFolder;
                self.currentNode.color = self.newColor;
                self.currentNode.defaultCss = self.newDefaultCss;

                //And we save the modifications
                self.TemplateTreeService.saveTemplate(self.currentTemplate,self.currentTemplate.name);
                hide();
            }
        };

        /**
         * delete node from  the template tree
         * @param node
         */
        self.deleteNode = function(node) {

            // delete the selectednode if it is the current node
            if (angular.equals(node,self.selectedNode)) {
                delete self.selectedNode;
            }

            // In all case we have to delete it from the tree
            self.TreeUtilService
                .deleteNode(node,self.currentTemplate)
                .then(function() {
                    //And we save the modifications
                    self.TemplateTreeService.saveTemplate(self.currentTemplate,self.currentTemplate.name);

                    //we have to clean the expandedNodes
                    var arrayOfNode = self.TreeUtilService.flatFolders(self.currentTemplate);
                    self.expandedNodes = _.intersectionWith(self.expandedNodes,arrayOfNode,function(object,other) {
                        return object.id === other.id;
                    });
                })
                .catch(function(err) {
                    console.error(err);
                });

        };

        /**
         * expande a node
         * @param node
         */
        self.expand = function(node) {
            if (self.expandedNodes.indexOf(node) < 0) {
                self.expandedNodes.push(node);
            }
        };

        /* ***************************** */
        /**
         * handle the drop
         * @param item
         * @param bin
         */
        self.handleDrop = function(item, bin) {

            var nodeDrag = self.TreeUtilService.getNode(item,self.currentTemplate);
            var nodeDrop = null;

            if (bin.startsWith('before')) {
                nodeDrop = self.TreeUtilService.getNode(bin.replace('before',''),self.currentTemplate);
                self.TreeUtilService.moveBefore(nodeDrag,nodeDrop,self.currentTemplate);
            } else {
                if (bin.startsWith('after')) {
                    nodeDrop = self.TreeUtilService.getNode(bin.replace('after',''),self.currentTemplate);
                    self.TreeUtilService.moveAfter(nodeDrag,nodeDrop,self.currentTemplate);
                } else {
                    nodeDrop = self.TreeUtilService.getNode(bin,self.currentTemplate);
                    self.TreeUtilService.moveIn(nodeDrag,nodeDrop,self.currentTemplate);
                    self.expand(nodeDrop);
                }
            }
        };

        /**
         * return true if a node is the first child the current template
         * @param node
         */
        self.isFirstChild = function(node) {
            return self.TreeUtilService.isFirstChild(node,self.currentTemplate);
        };

        /**
         * return true if the node is expanded
         * @param node
         * @returns {*|boolean}
         */
        self.isExpanded = function(node) {
            return self.expandedNodes && self.expandedNodes.indexOf(node) >= 0;
        };

        /**
         * return true if a node isn't expanded and have children
         * @param node
         * @returns {boolean}
         */
        self.showAfter = function(node) {
            return !(self.isExpanded(node) && node.children.length > 0);
        };

        /**
         * change the text in the messages zone
         * @param message
         */
        self.changeButtonText = function(message) {
            self.MessageService.changeMessage(message);
        };

        self.settingsValide();

        /************onBoarding Style******/
        self.onBoardingStepsStyle = self.OnBoardingService.getSteps('Style').steps;

        self.onboardingEnabledStyle = self.OnBoardingService.startFirstTour('Style');

        /**
         * finish the tour for the css
         */
        self.finishTourStyle = function() {
            self.OnBoardingService.finishTour('Style');
            self.onboardingEnabledStyle = false;
        };

        /**
         * start the tour for the css
         */
        self.startTourStyle = function() {
            self.onboardingIndexStyle = 0;
            self.onboardingEnabledStyle = true;
        };

        /************onBoarding Template******/
        self.onBoardingStepsTemplate = self.OnBoardingService.getSteps('Template').steps;

        self.onboardingEnabledTemplate = self.OnBoardingService.startFirstTour('Template');

        /**
         * finish the tour for the template
         */
        self.finishTourTemplate = function() {
            self.OnBoardingService.finishTour('Template');
            self.onboardingEnabledTemplate = false;
        };

        /**
         * start the tour for the template
         */
        self.startTourTemplate = function() {
            self.onboardingIndexTemplate = 0;
            self.onboardingEnabledTemplate = true;
        };

        /**
         * import help files
         */
        self.importHelpFiles = () => {
            self.PrincipalTreeService.addHelpFiles()
                .then(() => {
                    self.checkmark = true;
                })
                .catch((err) => {
                    console.error(err);
                })
        };

    }

}());<file_sep>(function () {
    "use strict";

    angular
        .module('Natao')
        .service('ShowDownUtilService', ShowDownUtilService)
        .run(run);

    //Start of the service
    function run() {
    }

    function ShowDownUtilService($timeout, $anchorScroll, $location) {

        var self = this;
        self.$timeout = $timeout;
        self.$anchorScroll = $anchorScroll;
        self.$location = $location;

        /**
         * hook for a href and highlight
         */
        self.showDownHooks = function () {
            self.$timeout(function() {
                // external links open in a browser
                $('#viewer a').not('[href^="#"]').on('click', function(){
                    require('nw.gui').Shell.openExternal( this.href );
                    return false;
                });

                // internal links generated bu showdown navigate with scrollTo
                $('#viewer a[href^="#"]').on('click', function(event){
                    self.scrollTo(event.currentTarget.hash.replace('#',''));
                    return false;
                });

                // Specify language or nohighlight in th first line inside :: like this ::nohighlight::
                $('pre code').each(function(i, block) {
                    if (block.textContent.startsWith('::')) {
                        var classe = block.textContent.split('\n')[0].replace('::','');
                        block.textContent = block.textContent.replace('::' + classe + '\n', '');
                        block.classList.add(classe);
                    } else {
                        // by default we add th class nohighlight
                        block.classList.add('nohighlight');
                    }
                    hljs.highlightBlock(block);
                });
            },0,false);
        };

        self.scrollTo = function(id) {
            $location.hash(id);
            $anchorScroll();
        };

        return self;

    }

}());<file_sep>(function () {
    "use strict";

    angular
        .module('Natao')
        .service('CodeMirrorUtilService', CodeMirrorUtilService)
        .run(run);

    //Start of the service
    function run() {
    }

    function SearchState() {
        this.posFrom = this.posTo = this.lastQuery = this.query = null;
        this.overlay = null;
    }

    function CodeMirrorUtilService($timeout) {

        var self = this;
        self.$timeout = $timeout;

        self.init = function(editor) {
            self.editor = editor;
        };

        /*************************** Search features *******************************************/

        /**
         * get current search state in the editor or set a new one
         * @param editor
         * @returns {*|SearchState|string|Symbol}
         */
        self.getSearchState = function() {
            return self.editor.state.search || (self.editor.state.search = new SearchState());
        };

        /**
         * return an overlay for highlight in CodeMirror
         * @param query
         * @returns {{token: token}}
         */
        self.searchOverlay = function(query) {
            if (typeof query == "string")
                query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), self.queryCaseInsensitive(query) ? "gi" : "g");
            else if (!query.global)
                query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");

            return {token: function(stream) {
                query.lastIndex = stream.pos;
                var match = query.exec(stream.string);
                if (match && match.index == stream.pos) {
                    stream.pos += match[0].length || 1;
                    return "searching";
                } else if (match) {
                    stream.pos = match.index;
                } else {
                    stream.skipToEnd();
                }
            }};
        };

        /**
         * if all the query string is lower case, it's caseInsensitive
         * @param query
         * @returns {boolean}
         */
        self.queryCaseInsensitive = function(query) {
            return typeof query == "string" && query == query.toLowerCase();
        };

        /**
         * return a search cursor from the editor
         * @param editor
         * @param query
         * @param pos
         * @returns {*}
         */
        self.getSearchCursor = function(query, pos) {
            return self.editor.getSearchCursor(query, pos, self.queryCaseInsensitive(query));
        };

        /**
         * start the search by setting an overlay on words found
         * @param query
         */
        self.startSearch = function(query) {
            var state = self.getSearchState();

            state.queryText = query;
            state.query = self.parseString(query);
            self.editor.removeOverlay(state.overlay, self.queryCaseInsensitive(state.query));
            state.overlay = self.searchOverlay(state.query, self.queryCaseInsensitive(state.query));
            self.editor.addOverlay(state.overlay);
        };

        /**
         * read the string
         * @param string
         * @returns {*|void|XML}
         */
        self.parseString = function(string) {
            return string.replace(/\\(.)/g, function(_, ch) {
                if (ch == "n") return "\n";
                if (ch == "r") return "\r";
                return ch;
            })
        };

        /**
         * go to the next word
         * @param reverse
         * @param callback
         */
        self.findNext = function(reverse, callback) {
            self.editor.operation(function() {
                var state = self.getSearchState();
                var cursor = self.getSearchCursor(state.query, reverse ? state.posFrom : state.posTo);
                if (!cursor.find(reverse)) {
                    cursor = self.getSearchCursor(state.query, reverse ? CodeMirror.Pos(self.editor.lastLine()) : CodeMirror.Pos(self.editor.firstLine(), 0));
                    if (!cursor.find(reverse)) return;
                }
                self.editor.setSelection(cursor.from(), cursor.to());
                self.editor.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
                state.posFrom = cursor.from(); state.posTo = cursor.to();
                state.cursor = cursor;
                if (callback) callback(cursor.from(), cursor.to())
            });
        };

        /**
         * replace all items found by text
         * @param text
         */
        self.replaceAll = function(text) {
            var state = self.getSearchState();
            self.editor.operation(function() {
                for (var cursor = self.getSearchCursor(state.query); cursor.findNext();) {
                    cursor.replace(text);
                }
            });
        };

        /**
         * replace current found item with text
         * @param text
         */
        self.replace = function(text) {

            var state = self.getSearchState();
            state.cursor.replace(text);
            self.findNext();
        };

        /**
         * clear the search effects on codeMirror
         */
        self.clearSearch = function() {
            self.editor.operation(function() {
                var state = self.getSearchState();
                state.lastQuery = state.query;
                if (!state.query) return;
                state.query = state.queryText = null;
                self.editor.removeOverlay(state.overlay);
                if (state.annotate) { state.annotate.clear(); state.annotate = null; }
            });
        };

        /** Function that count occurrences of a substring in a string;
         * @param {String} string               The string
         * @param {String} subString            The sub string to search for
         * @param {Boolean} [allowOverlapping]  Optional. (Default:false)
         * @author Vitim.us http://stackoverflow.com/questions/4009756/how-to-count-string-occurrence-in-string/7924240#7924240
         */
        self.occurrences = function(string, subString, allowOverlapping) {

            string += "";
            subString += "";
            if (subString.length <= 0) return (string.length + 1);

            var n = 0,
                pos = 0,
                step = allowOverlapping ? 1 : subString.length;

            while (true) {
                pos = string.indexOf(subString, pos);
                if (pos >= 0) {
                    ++n;
                    pos += step;
                } else break;
            }
            return n;
        };

        return self;

    }

}());<file_sep>(function () {
    "use strict";

    var fs = require('fs');

    angular
        .module('Natao')
        .controller('PrintController', PrintController);

    function PrintController($location,$showdown,$translate,tmhDynamicLocale,$rootScope,$timeout,DocumentsService, CssService, DatabaseService ) {

        var self = this;
        self.$location = $location;
        self.$showdown = $showdown;
        self.$showdown.setOption('tables',true);
        self.$showdown.setOption('strikethrough',true);
        self.$showdown.setOption('tasklists',true);
        self.$rootScope = $rootScope;
        self.$timeout = $timeout;
        self.DocumentsService = DocumentsService;
        self.CssService = CssService;
        self.DatabaseService = DatabaseService;

        // language and document from the url
        self.lang = $location.search().language;
        self.docId = $location.search().docId;
        self.showDys = ($location.search().showDys === 'true');

        //Set the language of the help
        var locale = self.lang.replace('_','-').toLowerCase();
        if (locale === 'fr') {
            locale = 'fr-fr';
        }
        tmhDynamicLocale.set(locale);

        //set the db
        self.DatabaseService.setDB(localStorage.getItem('nataoFileDatabase'));

        self.DatabaseService
            .find({docName:'Preferences'})
            .then(function(docs) {
                self.preferences = docs[0];
            })
            .catch(function(err) {
                console.error(err);
            });

        $translate.onReady()
            .then(function() {
                // Don't know why but language is not set here so we force it
                $translate.use(self.lang).then(function() {
                    self.CssService.getInitCss()
                        .then(function(defaultCss) {
                            //Init of the current Markdown
                            if (self.docId) {
                                self.DocumentsService
                                    .findDocument(self.docId)
                                    .then(function(docs) {
                                        self.currentMarkdown = docs[0];
                                        self.CssService.initCurrentById(self.currentMarkdown.css);

                                        self.$timeout(function() {
                                            $('a').on('click', function(){
                                                require('nw.gui').Shell.openExternal( this.href );
                                                return false;
                                            });

                                            // Specify language or nohighlight in th first line inside :: like this ::nohighlight::
                                            $('pre code').each(function(i, block) {
                                                if (block.textContent.startsWith('::')) {
                                                    var classe = block.textContent.split('\n')[0].replace('::','');
                                                    block.textContent = block.textContent.replace('::' + classe + '\n', '');
                                                    block.classList.add(classe);
                                                } else {
                                                    // by default we add th class nohighlight
                                                    block.classList.add('nohighlight');
                                                }
                                                hljs.highlightBlock(block);
                                            });
                                        },0,false);
                                        MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
                                        MathJax.Hub.Queue(self.print);
                                    }).catch(function(err) {
                                    console.error(err);
                                });
                            }
                        })
                        .catch(function(err) {
                            console.error(err);
                        });
                });

            });

        self.print = function() {
            window.print();
            window.close();
        };

    }

}());<file_sep>(function () {
    "use strict";

    angular
        .module('Natao')
        .service('DocumentsService', DocumentsService)
        .run(run);

    //Start of the service
    function run() {
    }

    function DocumentsService(DatabaseService,AppStateService,$q) {

        var self = this;
        self.DatabaseService = DatabaseService;
        self.AppStateService = AppStateService;
        self.$q = $q;

        self.getDocuments = function() {
            return self.DatabaseService.find({docName:'markdown'});
        };

        self.getDocumentsByCss = function(css) {
            if (css) {
                return self.DatabaseService.find({docName:'markdown', css: css}, 5);
            } else {
                return self.DatabaseService.find({docName:'markdown'}, 5);
            }
        };

        self.findDocument = function(id) {
            return self.DatabaseService.find({docName:'markdown',_id: id});
        };

        //Create new markdown with defaultCss, title and markdown
        self.addDocument = function(defaultCss,title,markdown) {

            return self.$q(function(resolve,reject) {

                var newMarkDown = {
                    docName: 'markdown',
                    title: title,
                    created: new Date(),
                    css: defaultCss,
                    md: ''
                };

                if (markdown) {
                    newMarkDown.md = markdown;
                }

                self.AppStateService.startWrite();
                self.DatabaseService
                    .save(newMarkDown)
                    .then(function(newDoc) {
                        self.AppStateService.stopWrite();
                        resolve(newDoc);
                    })
                    .catch(function(err) {
                        self.AppStateService.stopWrite();
                        reject(err);
                    });
            });
        };

        self.updateDocument = function(docSource) {
            return self.$q(function(resolve,reject) {

                self.AppStateService.startWrite();

                self.DatabaseService
                    .save(docSource)
                    .then(function(doc) {
                        self.AppStateService.stopWrite();
                        resolve(doc);
                    })
                    .catch(function(err) {
                        self.AppStateService.stopWrite();
                        reject(err);
                    });
            });
        };

        self.insertDocument = function(docSource) {
            return self.$q(function(resolve,reject) {

                self.AppStateService.startWrite();

                self.DatabaseService
                    .save(docSource)
                    .then(function(doc) {
                        self.AppStateService.stopWrite();
                        resolve(doc);
                    })
                    .catch(function(err) {
                        self.AppStateService.stopWrite();
                        reject(err);
                    });
            });
        };

        //delete of a document
        self.deleteDocument = function(id) {

            return self.$q(function(resolve,reject) {
                self.AppStateService.startWrite();

                self.DatabaseService
                    .delete(id)
                    .then(function(numRemoved) {
                        self.AppStateService.stopWrite();
                        resolve(numRemoved);
                    })
                    .catch(function(err) {
                        self.AppStateService.stopWrite();
                        reject(err);
                    });
            });

        };

        return self;

    }

}());<file_sep>// Font Variables
$font-family: RobotoDraft, Roboto, 'Helvetica Neue', sans-serif !default;
// Layout
// ------------------------------
$font-size: 14px;
$select-font-size: 16px;
$baseline-grid: 8px !default;
$layout-breakpoint-sm: 600px !default;
$layout-breakpoint-md: 960px !default;
$layout-breakpoint-lg: 1200px !default;
$layout-gutter-width: ($baseline-grid * 2) !default;
// App bar variables

$purpleTheme: (
        DD: #54278f,
        MD: #756bb1,
        MM: #9e9ac8,
        ML: #cbc9e2,
        LL: #f2f0f7,
        TR: rgba(117, 107, 177, 0.3)
);

$greenTheme: (
        DD: #006d2c,
        MD: #2ca25f,
        MM: #66c2a4,
        ML: #b2e2e2,
        LL: #edf8fb,
        TR: rgba(44, 162, 95, 0.3)
);

$orangeTheme: (
        DD: #a63603,
        MD: #e6550d,
        MM: #fd8d3c,
        ML: #fdbe85,
        LL: #feedde,
        TR: rgba(230, 85, 13, 0.3)
);

$redTheme: (
        DD: #a50f15,
        MD: #de2d26,
        MM: #fb6a4a,
        ML: #fcae91,
        LL: #fee5d9,
        TR: rgba(222, 45, 38, 0.3)
);

$greyTheme: (
        DD: #252525,
        MD: #636363,
        MM: #969696,
        ML: #cccccc,
        LL: #f7f7f7,
        TR: rgba(99, 99, 99, 0.3)
);

$blueTheme: (
        DD: #08519c,
        MD: #3182bd,
        MM: #6baed6,
        ML: #bdd7e7,
        LL: #eff3ff,
        TR: rgba(49, 130, 189, 0.3)
);

$pinkTheme: (
        DD: #980043,
        MD: #dd1c77,
        MM: #df65b0,
        ML: #d7b5d8,
        LL: #f1eef6,
        TR: rgba(221, 28, 119, 0.3)
);

<file_sep>(function () {
    "use strict";

    var fs = require('fs');
    var nw = require('nw.gui');
    var uuid = require('node-uuid');
    var sha512 = require('crypto-js/sha512');

    angular
        .module('Natao')
        .controller('AppController', AppController)
        .directive("fileread", [function () {
            return {
                scope: {
                    fileread: "="
                },
                link: function (scope, element, attributes) {
                    element.bind("change", function (changeEvent) {
                        scope.$apply(function () {
                            scope.fileread = changeEvent.target.files[0];
                            // or all selected files:
                            // scope.fileread = changeEvent.target.files;
                        });
                    });
                }
            }
        }]);

    function AppController($location,PreferencesService,CssService,$translate,$showdown,tmhDynamicLocale,ColorPickerService) {

        // For a good date translation
        $translate.onReady().then(function() {
            var locale = $translate.proposedLanguage().replace('_','-').toLowerCase();
            if (locale === 'fr') {
                locale = 'fr-fr';
            }
            tmhDynamicLocale.set(locale);
        });

        var self = this;
        self.$location = $location;
        self.databaseFile = '';
        self.showDys = false;
        self.PreferencesService = PreferencesService;
        self.CssService = CssService;
        self.$translate = $translate;
        self.$showdown = $showdown;
        self.ColorPickerService = ColorPickerService;
        self.$showdown.setOption('tables',true);
        self.$showdown.setOption('strikethrough',true);
        self.$showdown.setOption('tasklists',true);
        self.isLocked = false;
        self.validPassword = false;

        self.help = function() {
            nw.Window.open('help.html?language=' + self.$translate.use()
                + '&theme=' + self.PreferencesService.preferences.colorTheme
                + '&showDys=' + self.PreferencesService.preferences.showDys, {
                position: 'center',
                width: 1366,
                height: 768
            });
        };

        self.print = function(docId) {
            nw.Window.open('print.html?language=' + self.$translate.use() + '&docId=' + docId + '&showDys=' + self.PreferencesService.preferences.showDys, {
                position: 'center',
                width: 1366,
                height: 768
            });
        };

        self.toggleDys = function() {
            self.PreferencesService.preferences.showDys = !self.PreferencesService.preferences.showDys;
            self.PreferencesService.savePreferences();
        };

        self.zoomHigher = function() {
            self.PreferencesService.preferences.zoomLevel++;
            self.PreferencesService.savePreferences();
            self.PreferencesService.zoomChange();
        };

        self.zoomLower = function() {
            self.PreferencesService.preferences.zoomLevel--;
            self.PreferencesService.savePreferences();
            self.PreferencesService.zoomChange();
        };

        self.toggleMenu = function() {
            self.PreferencesService.preferences.showMenu = !self.PreferencesService.preferences.showMenu;
            self.PreferencesService.savePreferences();
        };

        self.toggleEditor = function() {
            if (self.PreferencesService.preferences.showEditor && !self.PreferencesService.preferences.showViewer) {
                self.toggleViewer();
            }
            self.PreferencesService.preferences.showEditor = !self.PreferencesService.preferences.showEditor;
            self.PreferencesService.savePreferences();
        };

        self.toggleViewer = function() {
            if (self.PreferencesService.preferences.showViewer && !self.PreferencesService.preferences.showEditor) {
                self.toggleEditor();
            }
            if (!self.PreferencesService.preferences.showViewer) {
                self.PreferencesService.preferences.showViewer = false;
            }
            self.PreferencesService.preferences.showViewer = !self.PreferencesService.preferences.showViewer;
            self.PreferencesService.savePreferences();
        };

        self.goSettings = function() {
            self.$location.path( '/settings' );
        };

        self.goApp = function() {
            self.$location.path( '/editor' );
        };

        // ************************ Lock ********************

        self.checkStorePassword = function() {
            var hashPassword = localStorage.getItem('password');
            if (hashPassword) {
                self.PreferencesService.preferences.showMenu = false;
                self.isLocked = true;
            }
        };

        self.storePassword = function() {
            var salt = uuid.v4();
            var hashPassword = sha512(self.password + salt).toString();

            localStorage.setItem('password',<PASSWORD>Password);
            localStorage.setItem('salt',salt);
        };

        self.unstorePassword = function() {
            localStorage.removeItem('password');
            localStorage.removeItem('salt');
        };

        self.checkHashPassword = function() {
            var salt = localStorage.getItem('salt');
            var hashPassword = sha512(self.unlockPassword + salt).toString();

            return hashPassword === localStorage.getItem('password');
        };

        self.lock = function(hide) {
            self.PreferencesService.preferences.previousShowMenu = self.PreferencesService.preferences.showMenu;
            self.PreferencesService.preferences.showMenu = false;
            self.PreferencesService.savePreferences();
            self.isLocked = true;
            self.storePassword();
            self.password = <PASSWORD>;
            self.confirmation = null;
            hide();
        };

        self.unlock = function(hide) {

            if (self.forceUnlock || self.checkHashPassword()) {
                if (self.PreferencesService.preferences.previousShowMenu !== null) {
                    self.PreferencesService.preferences.showMenu = self.PreferencesService.preferences.previousShowMenu;
                    self.PreferencesService.preferences.previousShowMenu = null;
                    self.PreferencesService.savePreferences();
                }
                self.isLocked = false;
                self.unstorePassword();
                self.unlockPassword = null;
                self.forceUnlock = false;
            }
            hide();
        };

        self.validationPassword = function() {
            if (self.password && self.password.length > 0 && self.confirmation && self.confirmation.length >0) {
                self.validPassword = self.password === self.confirmation;
            } else {
                self.validPassword = false;
            }
        };

        /* ************************ init ************************* */
        self.PreferencesService.init();
        self.checkStorePassword();

    }

}());<file_sep># Hello and welcome to Natao.##

**Before We Start**

You may have noticed, in the guided tour, the buttons which are designed to help you adjust Natao's appearance, or User Interface, to your liking. Well, don't hesitate to use them, like the magnifying glass for instance, or the *OpenDyslexic* font option, until you're comfortable with Natao's User Interface.

You can choose to change Natao's appearance even more, by going into the **Editor** panel. There you will find buttons which will help you add space and/or gray stripes between your document's lines.

# So what's Natao good for?

Natao has been designed to help you easily create elegant documents, filled with text and even basic mathematical formulae, if you need them.
To do so, Natao uses a computer syntax called Markdown which converts a simple text containing a few structurally significant characters, like hash-tag signs ( # ), star signs ( * ) or greater-than signs ( > ), into an easily readable and clearly formatted document.

Using the Markdown computer language lets you concentrate on your text body and not on unwieldy formatting windows, as is the case in traditional word processing programs.

Take a look at Natao's text Editor and text Viewer panels. You'll notice that they are very similar to each other, but for two key differences: in the Editor, single hash-tag signs ( # ) appear, whereas in the Viewer these have been replaced by roman numerals. Similarly, the double hash-tag signs ( ## ) seen in the Editor window have been replaced by numbers in the Viewer panel.

Hash-tag signs are only one of the types of characters recognized by Mardown. There are many others, which we will go over in some of Natao's Help documents. Just know that all these characters have one overall function: to help you, the user, create a variety of design elements within whichever document you write.

Some of these design elements include:

# Titles

Insert a single hash-tag sign ( # ) in front of a word, or sentence, and transform that word or sentence into a title. For instance:

 This word is not a title, but ...
 # these words are a title.

## Sub-titles

This time we're using two hash signs ( ## ) to create a ## subtitle.

### And we can even go further, with three hash signs ( ### ).

# Emphasizing words or sentences

Star signs ( * ) can be used to emphasize some text, as the two following examples illustrate:

- A single star sign ( * ) put before and after *a portion of text* italicizes it.
- Two star signs ( * * ) put before and after **a portion of text** underline and embolden it.

As mentioned earlier, the Markdown syntax offers a lot more tools for you to format your documents properly. We take a look at them in Natao's other Help sections.

By the way, the Markdown language can be used outside of Natao, to write online Wikis for instance, like Wikipedia. So learning it for Natao will pay off in the real world too.

## What if I want to my words to be red and underlined?

Well, it so happens that you can personalize the appearance of Natao's default document style.

Take a look at the top of the Editor window, and notice the *Style* option. Click on it and a drop-down menu will deploy, listing a series of document style-sheets. By switching to any of them, you'll be able to give the document on which you're working a complete overall.

For instance, by choosing the *Test* style-sheet, you'll get to write down your first and last names, as well as the day's date at the top of a document formatted with a margin, for your teacher's notes and comments.

Moreover, these style-sheets can be modified by you, the Natao's user. Whatever change you implement will be applied to the entirety of the you're currently working on. And, yes, that's how you'll be able to underline your text's words and make them red.

# Next Steps

You should now have a better idea of what Natao is and what it can allow you to accomplish. If you decide to go further, click on the question mark icon located at the top-right corner of Natao's interface. A new window will pop up and let you delve deeper into the program.

By the way, if you want to print any of the Help documents:

- Click on the *Settings* button, located at the top-right corner of Natao's interface,
- Click on the *Other* thumbnail,
- Click on the *Import* button.

These Help document files will appear in *Documents*, which will let you print them.

In any event, I hope you'll find Natao easy to use and useful to your work.

Thanks and good luck!
<file_sep>(function () {
    "use strict";

    angular
        .module('Natao')
        .config(AppConfigMathJax);

    function AppConfigMathJax() {

        MathJax.Hub.Config({
            messageStyle: 'none',
            asciimath2jax: {
                delimiters: [['@@','@@']],
                ignoreClass: ['customEditor']
            },
            tex2jax: {
                inlineMath: [ ['$$','$$'] ],
                displayMath: [ ['$$$','$$$'] ]
            }
        });

    }

}());<file_sep>[toc]

# The Markdown Computer Language

Working with Natao means using a simple, computer-based language called Markdown.

The Markdown computer syntax is designed to help its users format documents with common signs and characters, like the pound sign ( # ) or the greater-than sign ( > ). By inserting such signs within your Natao-produced document, you will similarly be able to format your document.

In the following sections, we are going to go over the Markdown syntax, starting with the basics.

By the way, the text you are currently reading was itself written in Markdown with Natao.

# Basic Syntax

## Separating Words

It's easy to add blank spaces between words to separate them. Simply add one or more spaces between each one of the words you write, as the following example illustrates:

I am                               hungry!

**Results in:**

I am hungry.

Note that no matter how many spaces you add between words, in your document's final, ready-to-print output, it will look like you only added one blank space, as is the norm in text formatting standards.
So, if adding blank spaces between words help you better read them, do so. In the final document, your words will be separated normally.

## Paragraphs

Create paragraphs by adding a blank space between your lines, by pressing on your keyboard's Return or Enter key. Otherwise Natao considers that your sentences are all part of the same paragraph or block of text.

	This is the first sentence. This is the second sentence. They are both part of the same paragraph.

	I've started a new paragraph by adding a blank space after the first paragraph's last sentence.

**Results in:**

This is the first sentence. This is the second sentence. They are both part of the same paragraph.

I've started a new paragraph by adding a blank space after the first paragraph's last sentence.

Keep in mind that as you write your text in Natao's Editor panel, you may insert as many line-breaks as you see fit. As long as you don't insert blank spaces, Natao will keep your sentences within the same paragraph.

## Titles

You can keep your document visually organized by creating titles. You create titles by adding one or a few pound or hash-tag signs ( # ) at the beginning of the text that you'd like to have appear as a title. The number of pound or hash-tag signs ( # ) you add determines how important the title is. Note that you may only add up to six ( # ) of these signs.

The following example shows you how the titles of this particular document have been designed.

::markdown::
# Basic Syntax
## Paragraphs
## Titles
### Within a Line
###### And the Maximum number of Pound Signs

To help readability, we recommend that you do not go beyond three title levels.

## Emphasizing Text Elements

You may decide to bring your readers' attention to specific parts of your text. You may do so for single words or for groups of words.

Place a single star sign ( * ) before and after the word(s) you'd like to highlight, and, by default, the text's letters will become slanted to the right, or italicized.

*This text will be italicized.*

Place two star signs ( * ) before and after the word(s) you'd like to emphasize, and, by default, the text's letters will become slighty thicker and darker, or bold.

**This text is in bold.**

You may also add a single underscore sign ( _ ) before and after some word or words to combine the italics and the bold letters.

    **Everyone _must_ arrive on time today.**

**Results in:**

**Everyone _must_ arrive on time today.**

You may also choose to strike-through a word or words by adding two tilde signs ( ~ ) before and after the word or words you'd like to cross out.

    ~~A mistake.~~

**Results in:**

~~A mistake.~~

As mentioned above, adding a single star sign ( * ) or a couple of them before and after words will respectively italicize or embolden your word or words. This default behavior may be changed by editing Natao's style-sheets. You could then decide that adding star signs in fact means underlining a word or a group of words with, for example, a red line.

## Special Characters

What if we wanted to have a star sign ( * ) or a hash tag ( # ) actually appear in our text, without having them influence the appearance of certain words or portions of text?

By placing a backlash sign ( \ ) before a special character, one may use any character without it interfering with the appearance of the text. For example, write \# within your text to have the hash sign ( \# ) appear as it is.

## Conclusion

The basic Markdown syntax allows anyone to write standard documents. But there's more. The simple elements of syntax that follow should allow you to go a step further. And it's still quite easy.

# Citations

You may create a citation by adding a greater-than symbol ( > ) in front of the text that you'd like to have appear as a quote. As long as your sentences start with ( > ), your text will remain part of the same citation.

    <NAME> wrote:

    > One need not be a chamber to be haunted.

**Results in:**

<NAME> wrote:

> One need not be a chamber to be haunted.

If you wish to have the name of the author appear in the citation block itself, add a greater-than symbol ( > ) before the authors' name, with a couple of star signs ( * ) for added emphasis, as follows:

    > One need not be a chamber to be haunted.

    > *<NAME>*

**Results in:**

> One need not be a chamber to be haunted.

> *<NAME>*

# Unformatted Blocks

## Within a Line

To display a word or words without any formatting, place a grave accent sign ( ` ) before and after the word or words. In the example that follows, the star signs ( * ) placed within the grave accent signs ( ` ) appear as what they are, as star signs.

    This text is `important` and here, it becomes even `**more**` important.

**Results in:**

This text is 'important' and here, it becomes even '**more**' important

## Over Many Lines

The grayed out block-quotes seen throughout this guide were created as follows: by inserting, before the lines of text that need to be part of the box, four empty character spaces, or one use of your keyboard's TAB-key.

    As an example, here's some text:

        An example of text.

**Results in:**

As an example, here's some text:

    An example of text.

You may also insert three grave accents ( ` ) to indicate the beginning and the end of a block of grayed out text:

  ::gfm
    Here's my formula:

    ```
    x = 0
    x = 2 + 2
    ```

**Results in:**

Here's my formula:

```
x = 0
x = 2 + 2
```

Because the content of the text is not formatted, three details become noticeable:

- The hash-tag and star signs don't impact the formatting.
- Each sentence appears as is, not as a paragraph.
- Each blank space remains as is.

# Highlighting Code

Unformatted block-quotes are often used to display programming code.

Because Natao is not intended for use by computer programmers, its capacities as a computer code editor are deactivated by default. You may reactivate these dormant capacities by starting your section of computer code with three grave accent signs ( ` ), followed by two colons signs ( : ) placed right before your first sentence, as follows:

    ```
	::typescript
    class MyClass extends MyfirstClass {

        constructor(private message: string){}

        public sayHello() {
        	console.log ('hello ' + message);
        }
    }
    ```

**Results in:**

```
::typescript
class MyClass extends MyfirstClass {

	constructor(private message: string){}

	public sayHello() {
		console.log ('hello ' + message);
	}
}
```

# Lists

## Unnumbered Lists

You may create an unnumbered list by adding a star sign ( * ) or a hyphen-minus sign ( - ) in front of each list item, as the following example illustrates:

    ::markdown
    * This is some text.
    * Here, some text!
    * I just wrote some words.

**and**

    ::markdown
    - This is some text
    - Here, some text.
    - I just wrote some words.

**Result in:**

- This is some text
- Here, some text!
- I just wrote some words.

We suggest you use a minus sign ( - ) instead of a star sign ( * ) for such lists, to avoid any confusion with emphasizing.

## Numbered Lists

You may create a numbered list simply and logically by beginning each list item by a number, as follows:

    ::markdown
    1. Item One
    2. Item Two
    3. Item Three

**Results in:**

1. Item One
2. Item Two
3. Item Three

## Indented Lists

You may indent a list by adding four blank spaces, or a TAB, before the item making up the indented list, as follows:

    ::markdown
    1. Write some text here:
        1. And add a detail about that text here.
        2. And another detail here.
    2. Write additional text here:
        * Add details to your text.
        * Keep writing.
        * And some last words.
    3. Start a new indented sentence.

**Results in:**

1. Write some text here:
    1. And add a detail about that text here.
    2. And another detail here.
2. Write additional text here:
  * Add details to your text.
  * Keep writing.
  * And some last words.
3. Start a new indented sentence.

# Tables

## A Basic Table

You may create a basic table by sketching one, right in your document in Natao's Editor panel, with pipe signs ( | ), hyphen-minus signs ( - ), and colon signs ( : ), like so:

	::gfm
    |A|B|
	|-|-|
	|z|w|
    |y|v|
    |x|u|

**Results in:**

|A|B|
|-|-|
|z|w|
|y|v|
|x|u|

This simple table's two columns were created by using the vertical bars ( | ). Its header was separated from the rows by using minus signs ( - ). The colon signs ( : ) were used to highlight the table's title.

Let's create another table, this time one that's a bit more complex.

In the Editor panel, let's write or paste-in the following section:

	::gfm
    |A pretty headline|
	    |----|
	    |b                       |
    |it's strange|
    |d|

**Results in:**

|A pretty headline|
|----|
|b                       |
|it's strange|
|d|

Here again, note that, although the table appears correctly in the Viewer panel, in the Editor, the text looks nothing like a table. In other words:

- No matter how many minus signs you include within the pipe signs, the table headline still appears correctly.
- No matter how many blank spaces you include, the table's appearance in the Viewer panel remains unchanged.
- All that matters is that the content of each columns must have a pipe sign before and after it.

That said, aligning the signs that make up your table in your Editor-panel makes reading the Markdown tables easier. So let's try to do that with our example table:

	::gfm
  |A pretty headline|
	|--------------|
	|b             |
	|it's strange  |
	|d             |

**Results in**

|A pretty headline|
|-----------------|
|b                |
|it's strange     |
|d                |

It is the same table as seen in the previous example, although, this time, its Editor panel version is easier to read.

Finally, note that tables appear in the center of the pages you create.

## Aligning Table Content

By default, table content is aligned to the left. However, that default position can be altered by using colon signs ( : ), as follows.

	::gfm
	|Pretty headline|Pretty headline bis  |
	|:------------:|-------------------:|
	|b             |b                   |
	|it's strange  |not so strange      |
	|d             |d                   |

**Results in:**

|Pretty headline|Pretty headline bis  |
|:------------:|-------------------:|
|b             |b                   |
|it's strange  |not so strange      |
|d             |d                   |

In other words:

- Placing one colon sign before and after the minus signs ( - ), the content is centered.
- Placing two colon signs after the minus signs ( - ), the content is aligned to the right.

## A Complex Table

In the following table, we have changed how content is aligned and how text is emphasized.

	::gfm
    | Tables         | Are              | Cool  |
    | -------------- |:----------------:| -----:|
    | **col 3 is**   | right aligned    | $1600 |
    | col 2 is       | *centered*       |   $12 |
    | zebra stripes  | ~~a mistake~~    |    $1 |

**Results in:**

| Tables         | Are              | Cool  |
| -------------- |:----------------:| -----:|
| **col 3 is**   | right aligned    | $1600 |
| col 2 is       | *centered*       |   $12 |
| zebra stripes  | ~~a mistake~~    |    $1 |

# Images

You may insert images in your document, as we've done with the Natao logo, like so:

    ::gfm
    ![Logo de Natao](./natao.png)

**Results in:**

![Logo de Natao](./natao.png)

## Using Natao to insert an image

- Create a folder called "Natao_images" within your database folder (if such folder doesn't already exist).
- Copy the image you would like to use to that folder.
- In the Editor panel, place your computer's cursor where you'd like to have the image appear.
- Click on Natao's "Insert Image" button.
- Select the image you've copied to your folder and let Natao create the Markdown code you are going to paste at your cursor's location.

## Breaking Down the Markdown Syntax

Here's an example of the sort of code Natao is going to generate for you:

	::gfm
	![newImage](file:/Mon%20chemin%20de%20fichier/mon%20image.png)

Let's deconstruct this code:

- The exclamation point sign ( ! ) announces the beginning of the code.
- The text surrounded by bracket signs ( [ ] ) is the text that appears in lieu of the image.
- The URL that starts with ( file:// ) shows the images' location on your computer. In this particular example, the word "file" indicates that the image is located on your machine. In the case of an image located online, the URL code would start with ( http:// ) or ( https:// ). For images already present within Natao, there is no need for anything.
- Note the %20: just like for internet URLs, the Markdown language doesn't like blank spaces and replaces them with %20.

# Links

## Online

You may create a hyperlink by:

1. Placing the linked-text within brackets ( [ ] ).
2. Wrapping the thus-created link between parentheses ( ( ) ).

	::gfm
    [Natao is on Github!](https://github.com/Ajrarn/Natao_legacy)

**Results in:**

[Natao is on Github!](https://github.com/Ajrarn/Natao_legacy)

## Reference Links

Reference-style links use a second set of square brackets, inside which you place a label of your own choosing to identify the link:

	::gfm
    Natao should be on [Github][github.natao].

**Results in:**

Natao should be on [Github][github.natao].

In the example above, [github.natao] is called the link-label. To transform it into a reference link, you need to define its destination.

To do so, anywhere in the document (usually at the end), paste-in your link-label, insert a colon after it, and place its URL destination right after. Then, between quotation marks, give your link-label the title that will pop up each time your drag your cursor over your link-label.

    ::gfm
    [github.natao]: https://github.com/Ajrarn/Natao_legacy  "Natao is on Github"

Note that, wherever you place them, link-labels remain invisible in the document's final, ready-to-print version. Their pop-up labels only appear when you drag your cursor above the link within your document.

Creating link-labels allows you to stay organized and use them more than once in your text. To do so, simply use the same link-label: for this [word][github.natao], we used the link-label used in the example above.

[github.natao]: https://github.com/Ajrarn/Natao_legacy  "Natao is on Github"
<file_sep>[English](https://github.com/Ajrarn/Natao_legacy)

# Natao

Natao est un éditeur Markdown à l'intention des étudiants dyspraxiques, dysgraphiques ou dyslexiques.

Il fonctionne sur:

- MacOS
- Windows
- Linux

## Comment l'instaler

Vous avez seulement besoin de récupérer Natao pour votre OS dans la partie [releases](https://github.com/Ajrarn/Natao_legacy/releases).

Dézippez l'archive où vous le souhaitez et démarrez Natao.

## Pourquoi un autre éditeur Markdown?

C'est avant tout un éditeur pour écrire ses leçons et ses devoirs avec le moins d'effort possible.

C'est pourquoi il utilise le Markdown.

L'autre objectif de Natao est d'aider à organiser ces documents. L'explorateur de documents permet donc de faciliter l'utilisation de structures de dossiers récurrentes.

## Aperçu

![NataoScreen](./NataoScreen.png)

## Auteurs

* **<NAME>** - Développeur principal - [Ajrarn](https://github.com/Ajrarn)

Vous pouvez voir également la liste des [contributeurs](https://github.com/Ajrarn/Natao_legacy/contributors) qui ont participé sur ce projet.

## Licence

Ce projet est fourni sous  MIT License - voir [LICENSE](LICENSE) pour les détails.

## Remerciements

* Tous mes amis pour leurs tests, conseils et spécialement <NAME> pour ses traductions anglaises.
* <NAME>, ergothérapeute, pour ses conseils.
* Tous ceux qui ont développé les librairies et outil utilisés par Natao:
	* [Nwjs](http://nwjs.io/)
    * [AngularJs](https://angularjs.org/)
    * [CodeMirror](https://codemirror.net/)
    * [Showdown](https://github.com/showdownjs/showdown)
    * [NeDB](https://github.com/louischatriot/nedb)
    * et tous les autres...
* Et ma femme et mes 2 enfants qui m'ont laissé le temps de réaliser ce logiciel.
<file_sep>[toc]

# Introduction

Ce document n'a pas pour vocation de t'expliquer tout le CSS, mais d'en comprendre au moins le minimum pour habiller tes documents Natao. Il n'est donc pas exhaustif.

Par contre, il y a de nombreuses notions à découvrir que tu pourrais trouver ardues. Si tu ne t'en sens pas le courage, et je peux le comprendre, fais toi aider par quelqu'un s'y connaissant un peu pour personnaliser tes feuilles de style. Il devrait trouver dans le présent document de précieuses informations pour l'aider.

# Notions de HTML indispensables

Avant de découvrir comment personnaliser les documents avec CSS, il faut comprendre comment ils sont construits.

## XML

### Les balises

Le XML est un langage de balisage qui permet de décrire n'importe quel document avec des balises personnalisées.
Ces balises marchent en général par paire ouvrante et fermante.

Une balise ouvrante, c'est un nom entouré des signes < et >, par exemple:

	::xml
	<paragraphe>

Une balise fermante comporte le même nom mais commence par `</`

	::xml
	</paragraphe>

Cette paire de balise définit une *boite* (tout simplement car elle contient quelque chose).

**Attention** le nom d'une balise ne contient qu'un seul mot (c'est à dire sans espace), l'exemple suivant ne sera pas valide :

	::xml
	<en tete></en tete>

mais le suivant si:

	::xml
	<en-tete></en-tete>

Donc, si je souhaite définir une boite paragraphe à l'aide de ma balise *paragraphe*, je vais l'écrire comme suit:

	::xml
	<paragraphe>Et voici la première phrase de mon paragraphe.
    Et maintenant, la deuxième.</paragraphe>

On peut également mettre à l'intérieur d'une boite d'autres boites:

	::xml
	<document>
    	<titre>Mon titre</titre>
    	<paragraphe>Un petit paragraphe.</paragraphe>
    	<paragraphe>Et un autre.</paragraphe>
    </document>

Ici, j'ai un ensemble appelé document contenant un titre et deux paragraphes.

Enfin, il existe un dernier type de balises qui sont ouvrantes et fermantes à la fois, car on ne peut rien mettre dedans. Par exemple:

	::xml
	<saut-de-page/>

Notes que le caractère / apparait juste avant le >.

### Les attributs

Examinons l'exemple suivant:

	::xml
	<paragraphe alignement="centré">Un petit paragraphe.</paragraphe>
    <paragraphe alignement="gauche">Un moins petit paragraphe.</paragraphe>
    <paragraphe invisible>Et un autre.</paragraphe>

Nous pouvons voir ici qu'à chaque balise *paragraphe*, nous avons ajouté des attributs avant de fermer la balise ouvrante.

Nous avons 2 attributs:
- l'attribut *alignement* qui a pour valeur 'centré' au premier paragraphe et 'gauche' au deuxième.
- l'attribut *invisible* qui n'a pas de valeur.

Chaque attribut ajoute une information exploitable à nos balises.

### Standards

Maintenant, j'ai arbitrairement choisi le nom de mes balises pour qu'elles m'aident à expliquer le concept. Tout le monde peut imaginer les balises qu'il souhaite utiliser et la manière de les agencer en XML. Mais ça deviendrait vite n'importe quoi si on se mettait tous à écrire des documents avec chacun nos balises personnelles.

Il existe donc des modèles standards utilisés dans l'industrie, DocBook par exemple pour rédiger des livres, ou le HTML pour les sites webs.

## HTML

Le HTML est donc un ensemble de balises permettant de décrire une page web. Le plus important à savoir, c'est que l'interpréteur Markdown génère du HTML et que c'est ce dernier que nous allons pouvoir habiller avec du CSS.

Donc, tu apprendras ici quelles balises sont générées et avec cela, tu pourras modifier l'apparence de ton document.

On ne va pas voir tout de suite les différentes balises, mais je vais te montrer l'exemple précédent en HTML.

	::html

        	...

Mon titre

Un petit paragraphe.

Et un autre.

une page web est en fait une page HTML, d'où les balises *html*.
Il y a une partie *header* qui ne s'affiche pas et que l'on ne détaillera donc pas ici.
Et enfin une partie *body* qui contient ce qui s'affiche, avec un titre de niveau 1 (les plus importants) *h1* et des paragraphes *p*.

# Structure d'un document Natao

	::html

Ton nom

Ton prénom

Ta classe

Titre

Date de création

                	...Et ici le contenu de ce que tu as rédigé en Markdown

Ca fait beaucoup de texte, et on n'a pas encore vu le Markdown transformé. Mais cette connaissance est indispensable à l'habillage d'un document.

Commençons par analyser la première balise :

	::html

J'ai mis dans l'exemple, la balise ouvrante et la balise fermante pour que tu puisses voir que le nom de la balise utilisée est *div* (qui est une boite sans signification particulière). Le plus important ici, ce sont les attributs :

	::string
	id="viewer" layout="column"

- *id* qui signifie identifiant.
- *layout* qui n'est pas un attribut standard, mais qui signifie la disposition au sein de cet élément dans Natao:
	- *column* signifie en colonne
    - *row* signifie en ligne

Donc, nous pouvons voir ici que notre élément *div* a pour identifiant *viewer* et une disposition en colonne. Les boites qui sont à l'intérieur se disposent en colonne.

Pour simplifier la compréhension, nous utiliserons l'identifiant des boites pour les désigner (car les div sont utilisés partout). Ainsi, au lieu de parler de boites *div*, nous parlerons de la boite *viewer*.

A l'intérieur de notre première boite, nous en avons une autre qui s'étire(*layout-align="start stretch"*) et prend toute la place disponible(*flex*) :

	::html

Sa disposition est en colonne et on peut voir qu'elle contient 3 boites intéressantes :

	::html

- une boite *header*
- une boite *separator*
- une boite *content*

## la boite *header*
```
::html
<div id="header" layout="row" layout-align="start stretch">
    <div id="identity" layout="column" layout-align="center stretch">
    	<p>Ton nom</p>
    	<p>Ton prénom</p>
    	<p>Ta classe</p>
    </div>
    <div id="title-zone" flex layout="column" layout-align="center stretch">
    	<h1>Titre</h1>
    	<p id="dateCreated">Date de création</p>
    </div>
</div>
```

Cette dernière est composée de 2 boites:
- *identity*
- *title-zone*

Ces 2 boites sont disposées sur la même ligne et vont s'étirer dans cette ligne en commençant à gauche:

	::html

Au sein de *identity*, ton nom, ton prénom et ta classe vont se disposer en colonne.

Au sein de *title-zone*, le titre du document et sa date de création apparaîtront en colonne.

## la boite *separator*

C'est une boite vide, qui servira à créer un espace de notation entre le titre et le contenu de ton devoir.

## la boite *content*

    ::html

        	...Et ici le contenu de ce que tu as rédigé en Markdown

Cette dernière est elle-même composé de 2 boites qu'elle va disposer en ligne:
- *margin* qui est une marge à gauche permettant à ton enseignant de corriger ton devoir.
- *made* qui est la zone de rendu de ton document Markdown.

# Une règle CSS

On y arrive enfin, tu vas pouvoir personnaliser ton document grace à ce qui suit. En CSS, on écrit des règles qui vont être appliquées au HTML. Voici un exemple de règle:

	::css
    #identity {
    	display: none;
	}

Parlons tout d'abord de *#identity*. Cette partie de la règle se situe avant les accolades ({ }), c'est ce que l'on appelle un sélecteur. Il va nous permettre de savoir à quella boite s'applique la règle.

Ici la règle s'applique à la boite dont l'identifiant est *identity*.

Ensuite, on peut voir 1 propriété qui est appliquée à cette boite.
- *display: none;* lui dit de ne pas s'afficher.

Dans le cas d'une leçon, je n'ai pas besoin de voir s'afficher la boite avec mon nom et mon prénom, voila comment lui dire de ne pas s'afficher et de ne pas prendre de place.

Je vais maintenant te donner les éléments qui te permettront de bien choisir les boites que tu vas relooker et les propriétés les plus utiles.

# les sélecteurs utiles

## Le sélecteur de boite

Pour sélectionner toutes les boites identiques, il me suffit d'utiliser comme sélecteur le nom de la balise:

	::css
    div {
    	display: none;
	}

Ce mauvais exemple va dissimuler toutes les boites *div*, autrement dit, tout ton document...

## Le sélecteur d'identifiant

Pour sélectionner une boite quel qu'elle soit sur son identifiant je vais utiliser un # devant l'identifiant, comme l'exemple vu en tout premier lieu.

## Le sélecteur de classe

Une boite possédant une propriété class comme par exemple:

	::html

    	du code

peut être sélectionnée, grace au sélecteur de classe(avec un . devant) comme suit:

	::css
    .java {
    	display: none;
	}

Et hop! Encore quelque chose d'intéressant qu'on passe à la trappe.

## Utiliser plusieurs sélecteurs en même temps

Tu peux aussi appliquer une règle à plusieurs sélecteurs, en les séparant par une virgule:

	::css
    h1, #header {
    	display: none;
    }

Ainsi, la règle s'applique à tous les éléments *h1* et à la boite *header*.

## Sélectionner les descendants de

Tu peux sélectionner les descendants de boites en mettant un espace entre le parent et le descendant :

	::css
    #title-zone h1 {
    	color: red
    }

Cet exemple modifie la couleur du titre de niveau 1 dans la boite #title-zone, mais n'impacte pas les autres titres dans d'autres boites.

# Agir sur les grands boites d'un document Natao

La première chose que l'on doit faire, c'est de décider les boites qui s'affichent dans notre feuille de style, leur taille et éventuellement les décorer.

## Les faire disparaître

Je te remets le premier exemple sur le CSS:

	::css
    #identity {
    	display: none;
	}

*display* permet de modifier la disposition des éléments enfants. Dans la mesure où cette disposition est pilotée d'une autre manière dans Natao, la seule valeur à connaître est *none* qui permet de masquer l'élément.

A appliquer sur les éléments suivants qui ne sont utiles que pour les devoirs:
- *identity*
- *separator*
- *margin*

## Modifier leur taille

### Hauteur et Largeur

    ::css
	#identity {
    	width: 200px;
	}

    #separator {
    	height: 200px;
    }

Dans l'exemple précédent, j'ai fixé la largeur(*width*) de la boite *identity* à 200 pixels, et la hauteur(*height*) de la boite *separator* également à 200 pixels.

En effet *identity* est dans une boite où les éléments sont disposés en ligne. Il prendra la largeur indiquée et les autres éléments de la même boite prendront la place restante.

Dans le cas de *separator*, il est dans une boite disposée en colonne. En fixant sa taille, la boite suivante prendra la hauteur qui reste.

### Unités

Dans l'exemple précédent, j'ai utilisé comme unité des pixels(px). Il y en a de nombreuses autres. Je vais t'en citer quelques unes intéressantes:

- *px* pour pixels(ce sont des points à l'écran)
- *pt* pour points(à l'impression)
- *%* qui comme son nom l'indique est une proportion de l'espace disponible. 50% siginifie qu'il occupe la moitité de l'espace.
- *em* qui est pour moi l'unité la plus intéressante. 1em = la taille de police du document. Tu vas donc pouvoir définir plusieurs éléments qui seront proportionnels à cette taille de police.

## Modifier leur couleur

### en écrivant les propriétés
	::css
    #identity {
    	background-color: red;
        color: #af2356;
    }

Voici 2 nouvelles propriétés permettant de modifier des couleurs:
- *color* permet de modifier la couleur du texte.
- *background-color* permet de modifier la couleur du fond.

Comme tu peux le voir, la propriété *background-color* contient un nom de couleur en anglais. La liste de couleurs disponibles est trop grande pour figurer dans ce document. Je t'invite à la consulter [ici](http://www.colors.commutercreative.com/grid/).

La propriété *color* contient un #, suivi d'une valeur de 6 caractères en hexadécimal. Je ne vais pas t'expliquer l'héxadécimal ici, mais ces 6 caractères sont en fait 3 fois 2 caractères. La première paire est pour la composante Rouge, la deuxième pour la composante Verte, et la dernière pour la composante Bleue. Soit RVB ou RGB en anglais. Cette façon d'écrire te permet de choisir très précisément la couleur que tu souhaites contrairement aux noms.

### en utilisant l'outil de choix de couleur

Natao intègre un outil pour t'aider à choisir les couleurs. Celui-ci s'active quand il voit un code couleur valide comme par exemple:

	::css
    color: #111111;

c'est à dire commençant par un # suivi de 6 chiffres.

Une fois que tu as tapé ce texte (#111111;), cliques dessus pour le voir apparaître.

![Chois de couleur](./src/images/thistle.png)

Tu peux y voir 3 composants:

- la barre d'aperçu, celle qui est toute en bas.
- la barre de luminosité, à droite.
- le cercle de teintes.

Tu peux agir sur le diamètre du cercle, en le rapprochant du centre (couleurs fades), ou l'éloignant (couleurs vives). Puis tu peux choisir la couleur en déplaçant le curseur dans le cercle. Enfin, la luminiusité avec le curseur présent dans la barre de droite.

## Modifier les bordures

### 2 syntaxes

Tu peux mettre sur chaque boite des bordures, comme ceci:

	::css
    #identity {
    	border-width: thin;
        border-style: solid;
        border-color: red;
    }

    #separator {
    	border: thin solid red;
    }

Dans cet exemple, nous avons appliqué la même bordure aux 2 boites *identity* et *separator*. Commençons par la syntaxe utilisée pour *identity*.

Tu peux voir 3 propriétés:
- *border-width* qui est l'épaisseur de la bordure, ici elle fine(thin).
- *border-style* qui est le style de la bordure, ici c'est un trait plein (solid).
- *border-color* qui est la couleur de la bordure, ici rouge (red).

Pour *separator* tu peux voir une syntaxe abrégée. Le mot clé *border* est suivi des 3 valeurs associées à la largeur, au style et à la couleur.

### L'épaisseur (width)

Pour cette propriété, il existe 3 valeurs standards:

- *thin* : pour une bordure fine.
- *medium* : pour une bordure moyenne.
- *thick* : pour une bordure épaisse.

Tu peux aussi y mettre des valeurs en pixels(px), en points(pt), etc...

### Le style

Voici 4 valeurs à connaître:

- *dotted* : pour obtenir un trait en pointillés.
- *dashed* : pour obtenir un trait en tirets.
- *solid* : pour obtenir un trait plein.
- *double* : pour obtenir un double-trait(visible à partir de medium).

### Des bordures partielles

Les propriétés que l'on a vu permettent de faire une bordure qui entoure complètement la boite. On peut avoir besoin de n'avoir qu'une bordure sur un ou 2 côtés. Chaque côté a un mot clé associé:

- *top* : pour la bordure supérieure.
- *bottom* : pour la bordure inférieure.
- *left* : pour la bordure gauche.
- *right* : pour la bordure droite.

Il suffit d'ajouter ce mot-clé après border comme suit:

	::css
    #separator {
    	border-top: thin solid blue;
        border-bottom: thin solid blue;
    }

    #margin {
    	border-right-width: thin;
        border-right-style: solid;
        border-right-color: red;
    }

Comme tu peux le voir, cela fonctionne aussi pour la forme abrégée.

## Modifier les marges

Chaque boite possède 2 types de marge:
- une marge extérieure (propriété *margin* qui n'est pas notre boite du même nom), qui permet de définir à quelle distance minimale d'une autre boite se situe la notre.
- une marge intérieur (mot-clé *padding*), qui permet de définir à quelle distance minimale d'un bord de notre boite apparaitra la première boite interne.

De la même manière que les bordures, les mots-clés peuvent être suffixés de *top*, *bottom*, *left* et *right* :

````
::css
#made {
	margin: 10px;
    padding: 20px;
}

#made h1 {
	margin-top: 30px;
}
```

Ici nous voyons que la boite *made* sera éloignée de la boite *separator* d'au moins 10pixels, et que les boites qu'elle contient seront à 20 pixels de ses bords.

Nous voyons également que les titres de niveau 1(*h1*), s'écarten de la boite précédente de 30 pixels.

# Agir globalement sur le texte

## Modifier la taille de référence du texte

Je te fais un petit rappel sur les unités de mesure:

- *px* pour pixels(ce sont des points à l'écran)
- *pt* pour points(à l'impression)
- *em* qui est pour moi l'unité la plus intéressante. 1em = la taille de police du document.

On peut fixer pour le contenu du document une taille de police de base. Par exemple:

	::css
    #made {
    	font-size: 16px;
    }

Cet exemple donne une taille de police de 16px, c'est la taille par défaut. C'est à partir de cette taille par défaut que je vais pouvoir ajuster celle des titres, par exemple.

	::css
    #made h1 {
    	font-size: 2em;
    }

    #made h2 {
    	font-size: 1.5em;
    }

Ainsi mon titre de niveau 1 (qui correspond à un seul #) fera 2 fois la taille de base, et le titre de niveau 2 (qui correspond à ##) fera 1,5 fois cette taille.

Si je change la taille de base à 20px, les titres resteront proportionnels.

## Modifier la police

On peut modifier la police utilisée grace à la propriété *font-family* comme ceci:

	::css
    #made {
    	font-family: RobotoDraft, Roboto, 'Helvetica Neue', sans-serif;
    }

La signification de cette ligne est la suivante : Prends la police *RobotoDraft*, si tu ne la trouve pas *Roboto*, si tu ne la trouve pas *Helvetica Neue* et si tu ne la trouves toujours pas prends la première police de type *sans-serif* que tu as.

Les polices disponibles dépendent du système d'exploitation sur lequel Natao tourne. Soit Windwos, soit MacOs, soit Linux. Il faut donc lui donner plusieurs pistes à explorer et à la fin une piste infaillible(la famille).

Voici quelques exemple courants de définition de *font-family*:

| famille    | définition                                          |
|------------|-----------------------------------------------------|
| Serif      | Georgia, serif                                      |
| Serif      | "Palatino Linotype", "Book Antiqua", Palatino, serif|
| Serif      | "Times New Roman", Times, serif                     |
| Sans-Serif | Arial, Helvetica, sans-serif                        |
| Sans-Serif | "Arial Black", Gadget, sans-serif                   |
| Sans-Serif | "Comic Sans MS", cursive, sans-serif                |
| Sans-Serif | Impact, Charcoal, sans-serif                        |
| Sans-Serif | "Lucida Sans Unicode", "Lucida Grande", sans-serif  |
| Sans-Serif | Tahoma, Geneva, sans-serif                          |
| Sans-Serif | "Trebuchet MS", Helvetica, sans-serif               |
| Sans-Serif | Verdana, Geneva, sans-serif                         |
| Monospace  | "Courier New", Courier, monospace                   |
| Monospace  | "Lucida Console", Monaco, monospace                 |

## Souligner du texte

Soulignons tout le texte:

	::css
    #made {
    	text-decoration: underline;
    }

## l'épaisseur du texte

La propriété *font-weight* permet de régler l'épaisseur du texte:
- *lighter* pour un texte plus fin que d'habitude
- *normal* pour un texte normal.
- *bold* pour un texte gras.
- *bolder* pour un texte très gras.

Mettons tout le texte en gras comme ceci:

	::css
    #made {
    	font-weight: bold;
    }

## Le style de texte

La propriété *font-style* permet de déterminer si un texte est:
- *normal*: avec des caractères verticaux.
- *italic*: avec des caractères penchés.

Mettons tout notre texte en italique comme ceci:

	::css
	#made {
    	font-style: italic;
    }

## L'alignement du texte

La propriété *text-align* permet de choisir l'alignement du texte. Elle peut avoir les valeurs suivantes:
- *left*, pour coller le texte à gauche.
- *right*, pour coller le texte à droite.
- *center*, pour centrer le texte.
- *justify*, pour que le texte se colle à la fois à gauche et à droite, qu'il prenne toute la place.

```
::css
#made p {
	text-align: center;
}
```

Pour les vers d'une poésie par exemple.

## Indenter la première ligne

La propriété *text-indent* permet d'indenter la première ligne d'une boite de texte:

	::css
    #made p {
    	text-indent: 1.5em;
    }

# Agir sur les boites de texte individuellement

Voici un exemple de document Markdown avec des paragraphes, des titres, et du texte valorisé:

	::markdown
    # Titre 1
    ## Titre 1.1
    ### Titre 1.1.1
    ...
    ###### Titre 1.1.1.1.1.1

    Voici mon premier paragraphe, avec sa première ligne simple.
    Suivie d'une deuxième ligne.

    Et maintenant le *paragraphe* suivant avec des mots **valorisés** voire ~~barrés~~

Ce texte en Markdown devrait donner ce code HTML:

	::html

Titre 1

Titre 1.1

Titre 1.1.1

    ...

Titre 1.1.1.1.1.1

Voici mon premier paragraphe, avec sa première ligne simple.Suivie d'une deuxième ligne.

Et maintenant le paragraphe suivant avec des mots valorisés voire barrés

Nous pouvons voir que le nombre de # d'un titre correspond au numéro qui suit le h de la boite de titre. Ainsi # devient une boite *h1* et ainsi de suite.

Les paragraphes sont dans des boites *p*.

Le mot *paragraphe* qui était entouré de 1 `*` est dans une boite *em*.

Le mot *valorisés* qui était entouré de 2 `*`est dans une boite *strong*.

Enfin, le mot *barrés* qui était entouré de 2 `~`est dans une boite *del*.

Tous ces boites sont des boites comme les autres. Par conséquent, tout ce que nous avons vu jusqu'à présent peut être appliqué à un de ceux-ci:
- les couleurs de fond et de texte
- le changement de police
- le changement de taille de police
- le soulignement
- l'épaisseur du texte
- son style

Ces boites ont déjà une apparence par défaut. Ainsi une boite *em* est par défaut en italique, une boite *strong* est par défaut en gras, une boite *del* est par défaut barré et les titres ont également des tailles par défaut. Ne modifiez que ce qui est utile.

Si tu as besoin qu'en plus d'être en gras, le texte très valorisé soit en rouge et souligné ecris ceci:

	::css
    strong {
    	color: red;
        text-decoration: underline;
    }

# La numérotation automatique

Voici le code que j'ai utilisé pour le style des leçons:

```
::css
#made {counter-reset: chapitre section sous-section;}

#made  h1 {
    font-family: "Courier New", Courier, monospace;
    margin-bottom: 20px;
    margin-top: 50px;
    font-size: 1.5em;
    counter-reset: section;
}

#made  h1:before {
	counter-increment: chapitre;
    content: counter(chapitre,upper-roman) " - ";
}

#made h2 {
    font-size: 1.2em;
    counter-reset: sous-section;
}

#made h2:before {
    counter-increment: section;
    content: counter(chapitre) "." counter(section) "  ";
}
#made  h3:before {
    counter-increment: sous-section;
    content: counter(chapitre) "." counter(section) "." counter(sous-section) "  ";
}
```

Tout d'abord je voudrais te montrer 2 nouveaux sélecteurs:
- *h1:before*
- *h1:after*

J'ai ajouté *:before* au sélecteur de boite *h1*. C'est une pseudo-classe, il y en a d'autres, mais celle-ci va nous permettre de rajouter du contenu avant la boite choisi. Au besoin on aurait pu faire la même chose avec la pseudo-classe *after*.

Et maintenant, nous allons parler des compteurs. Pour générer une numérotation automatique, j'utilise des compteurs. Je commence par initialiser leur valeur, les remettre à 1:

	::css
	#made {counter-reset: chapitre section sous-section;}

*counter-reset* remet tous les compteurs spécifiés à 0. Ici, les compteurs que l'on a nommé *chapitre*, *section* et *sous-section* prennent une valeur à 0.

Les compteurs sont chacun associés à un type de boite (de niveau de titre donc):
- *chapitre* pour *h1*.
- *section* pour *h2*.
- *sous-section* pour *h3*.

A chaque nouveau *h1*(chapitre), je remets à 0 le compteur de *h2*, *section*.

A chaque nouveau *h2*(section), je remets à 0 le compteur de *h3*, *sous-section*.

Ce qui se traduit par le css suivant.

````
::css
#made  h1 {
    counter-reset: section;
}

#made h2 {
    counter-reset: sous-section;
}
```

Examinons maintenant les *before* des boites h1 et h2:

```
::css
#made  h1:before {
    counter-increment: chapitre;
    content: counter(chapitre,upper-roman) " - ";
}

#made h2:before {
    counter-increment: section;
    content: counter(chapitre) "." counter(section) "  ";
}

```

La première chose à voir est l'utilisation de la propriété *counter-increment* associée au compteur *chapitre* pour *h1:before* et au compteur *section* pour *h2:before*. Cette instruction ajoute 1 au compteur sélectionné.

Ensuite, il y a la propriété *content*. Cette propriété permet de modifier le contenu d'une boite. Ici, nous nous situons avant(*before*) la boite *h1* ou avant la boite *h2*.

En commençant par la boite *h2*, tu peux voir que la propriété *content* contient *counter(chapitre) "." counter(section) "  "*. Cela veut dire:

- la valeur du compteur *chapitre* (*counter(chapitre)*),
- suivi d'un point,
- suivi de la valeur du compteur *section* (*counter(section)*),
- suivi d'un espace,
- et enfin suivi de notre boite *h2* donc notre titre, car tout ce l'on a vu avant s'écrit avant *h2*.

Maintenant si l'on regarde la boite *h1*, tu peux voir que la propriété *content* contient *counter(chapitre,upper-roman) " - "*. Cela veut dire:

- la valeur du compteur *chapitre*, mais en chiffre romains, en majuscule (*counter(chapitre,upper-roman)*),
- suivi d'un espace, d'un tiret, un nouvel espace,
- et enfin, suivi de notre boite *h1*.

Comme tu as du le remarquer, pour *h2* j'utilise *counter(section)* et pour *h1* j'utilise *counter(chapitre,upper-roman)*. Dans le deuxième cas, je spécifie l'écriture en chiffre romain, et dans le premier, je ne mets que le compteur.
C'est parce qu'il écrit par défaut en *decimal*. Je pourrais écrire *counter(section,decimal)*, mais il ferait exactement la même chose.

Voici les différentes valeurs possibles, et quand je le sais à quoi ça correspond:

- *decimal* pour l'affichage en chiffres arabes (ceux qu'on utilise d'habitude),
- *decimal-leading-zero* pour afficher en chiffres arabes, mais en rajoutant un 0 dans les dizaines,
- *lower-roman* en chiffre romains, mais en minuscules,
- *upper-roman* en chiffres romains et en majuscule,
- *lower-greek* en chiffres grecs,
- *lower-latin*,
- *upper-latin*,
- *armenian*,
- *georgian*,
- *lower-alpha* en lettres en minuscule,
- *upper-alpha* en lettre en majuscule.

<file_sep>[toc]

# Les bases

Pour rédiger un texte avec Natao, tu vas devoir apprendre un nouveau langage.
Rassures toi, ce n'est pas comme apprendre une langue étrangère.
Cela consiste à ajouter certains signes (ou caractères) à ton texte.
Ce langage permettra à Natao de comprendre comment tu souhaites organiser ton document.
Tu décris ce que tu souhaites et Natao met en page pour toi.
Ce langage s'appelle le **Markdown**. Nous allons commencer par les bases de la mise en page, et tu vas voir, c'est un langage très facile.

D'ailleurs, la documentation que tu es en train de lire a été écrite en Markdown, et avec Natao.

## Séparer des mots
C'est facile, il suffit de mettre un ou plusieurs espaces entre chaque mot. Alors pourquoi en faire un paragraphe ?

Ce qu'il y a d'important, c'est que tu peux utiliser *plusieurs* espaces pour séparer des mots, autant que tu veux. Quand ton document sera traité, il n'en mettra qu'un seul, voici un exemple:

	J'ai                                 faim !

**donne ceci**:

J'ai                                 faim !

Alors si espacer davantage les mots dans ton éditeur te permet de mieux les discerner, ne t'en prives pas ! Ton document, une fois mis en page et imprimé, respectera les normes classiques de mise en forme.

## Séparer des Paragraphes

Par défaut, tant que tu ne sépares pas tes phrases par des lignes vides, Natao considère qu'elles font partie d'un même paragraphe. Il ne va donc pas à la ligne et toutes tes phrases font partie d'un même bloc de phrases: c'est un paragraphe !

    j'écris une phrase courte. J'en écris une autre sur la même ligne.

    J'écris une autre phrase.
    Mais cette fois-ci, je vais à la ligne

**donne ceci**:

j'écris une phrase courte. J'en écris une autre sur la même ligne.

J'écris une autre phrase.
Mais cette fois-ci, je vais à la ligne

Notes que Natao n'est allé à la ligne que quand nous avons sauté une ligne. Sachant cela, tu peux aller à la ligne aussi souvent que tu le souhaites, tant que tu ne sautes pas de ligne, c'est le même paragraphe.

## Titres

Tu vas aussi avoir besoin d'organiser ton document. Et tu peux le faire grace aux différents titres.

Tu peux créer un titre en ajoutant un ou plusieurs # au début du texte de ton titre. Le nombre de # que tu utilises détermine l'importance du titre. Plus il y en a et moins il est important.
L'exemple ci-dessous ne sera pas illustré, car il perturberait la présentation de cette aide. Mais les premiers titres que tu vas voir sont ceux de ce document :

    ::markdown::
    # Les bases
    ## Séparer des mots
    ## Séparer des paragraphes
    ## Titres
    …
    ###### et tu peux aller jusqu'à 6 niveaux

## Mettre en valeur du texte

Tu peux valoriser du texte, c'est à dire faire ressortir certains mots ou phrases, pour qu'on les remarque.
Tu as deux niveaux de valorisation qui s'obtiennent en entourant le mot ou le groupe de mots du caractère \*.
Un seul \* le met en valeur, deux \* signifient qu'il est très important. Par défaut, la première mise en valeur, met le texte en italique, la deuxième, le met en gras.
Mais tu peux changer les règles (avec les feuilles de style qui sont expliquées dans une autre partie), en souligner un en rouge par exemple.

    *Ce texte sera valorisé*

    **Ce texte sera très remarqué**

**donne ceci**:

*Ce texte sera valorisé*

**Ce texte sera très remarqué**

Tu peux également utiliser le caractère '_' au lieu de '*', pour les valorisations. Cela te permet de combiner les 2 dans un même texte.

    **Tout le monde _doit_ arriver à l'heure aujourd'hui.**

**donne ceci**:

**Tout le monde _doit_ arriver à l'heure aujourd'hui.**

Enfin, il existe une dernière valorisation de texte qui consiste à signifier qu'il est faux, en le rayant par exemple

    ~~une bêtise~~

**donne ceci**:

~~une bêtise~~

## Afficher les caractères spéciaux
Nous avons vu que les # placés en début de ligne et les \* permettent de valoriser le texte.
Mais comment faire si on veut précisément afficher un # en début de ligne ou un \* dans notre texte ?

Nous allons utiliser ce qu'on appelle un caractère d'échappement. En mettant un \ devant le caractère en question, on dit à l'interpréteur MarkDown de l'afficher et de ne surtout pas l'interpréter. Par exemple :

	\# en début de texte, avec un \* sans valoriser ce qui suit.

**donne ceci**:

\# en début de texte, avec un \* sans valoriser ce qui suit.

## Conclusion

La syntaxe de base te permet déjà de rédiger de nombreux documents. Les éléments qui suivent te permettront de faire encore mieux.
Et c'est toujours aussi simple.

# Citation

Tu peux indiquer une citation avec un >. Tant que tes lignes commencent par des >, on reste dans le bloc de citation.

    <NAME> a dit:

    > Pardon my french

<NAME> a dit:

> Pardon my french

Si tu souhaites que l'auteur apparaisse dans le bloc de citation, il te suffit simplement de l'écrire comme ceci:

    > Pardon my french

    > *<NAME>*

> Pardon my french

> *<NAME>*

# Blocs non mis en page

## Au sein d'une ligne

Utilise des guillemets obliques \` pour afficher le texte tel quel, sans mise en page.

Dans l'exemple ci-dessous, les \* ne transformeront pas le texte super important, ils seront visibles (tout comme avec le caractère d'échappement) :

    Et voila un texte `important` mais là, il devient  `**Super**Important`.

**donne ceci**:

Et voila un texte `important` mais là, il devient  `**Super**Important`.

## Sur plusieurs lignes

Les encarts beiges que tu as vu jusqu'à présent pour te montrer des exemples ont été faits avec cette technique. Tu pourras maintenant facilement la reproduire.
Pour créer ce genre d'encart, il faut que toutes les lignes le composant commencent par 4 espaces ou une tabulation. Ca va te paraître bizarre, mais le premier encart gris est le code permettant de faire le deuxième bloc :

    Voici un exemple de code

        Le code en exemple...
        ...à la ligne

**donne ceci**:

Voici un exemple de code

    Le code en exemple...
    ...à la ligne

Tu peux aussi utiliser 3 guillemets obliques \` pour indiquer le début et la fin du bloc :

	::gfm
    Voici mon code:

    ```
    #x = 0
    x = 2 + 2
    	what **is**     x
    ```

**donne ceci**:

Voici mon code:

```
#x = 0
x = 2 + 2
	what **is**     x
```

Comme le contenu n'est pas mis en page, tu peux constater 3 choses:

- Les #, les \* ne participent pas à la mise en page.
- Chaque ligne est à sa place, elles ne sont pas redisposées pour faire des paragraphes.
- chaque espace est conservé.

## Valoriser du code

Les blocs non mis en page sont très souvent utilisés pour illustrer du code dans un langage de programmation.

Natao n'a pas été conçu spécialement pour des développeurs, la mise en valeur du code est donc par défaut désactivée.
Mais il n'y a pas de raison pour que tu ne puisses pas t'en servir si tu as des cours d'informatique.

Pour activer la mise en valeur du code, il te suffit de commencer la première ligne par :: suivi du langage à valoriser.

    ```
	::typescript
    class MyClass extends MyfirstClass {

        constructor(private message: string){}

        public sayHello() {
        	console.log ('hello ' + message);
        }
    }
    ```

**donne ceci**

```
::typescript
class MyClass extends MyfirstClass {

	constructor(private message: string){}

	public sayHello() {
		console.log ('hello ' + message);
	}
}
```

# Listes

## Listes non ordonnées

Tu peux créer une liste non ordonnée en mettant devant chaque article un \* ou un -, tous deux suivis d'un espace.

    ::markdown
    * Article
    * Article
    * Article

    - Article
    - Article
    - Article

**donne ceci**:

- Article
- Article
- Article

Préfères l'usage des tirets pour ne pas faire de confusion avec la valorisation. Mais il est bon de savoir que les \* peuvent faire la même chose.

## Listes ordonnées

Tu peux créer une liste ordonnée en précédant chaque article par un nombre.

    ::markdown
    1. Article 1
    2. Article 2
    3. Article 3

**donne ceci**:

1. Article 1
2. Article 2
3. Article 3

## Listes imbriquées

Tu peux créer des listes imbriquées en ajoutant 1 tabulation ou 4 espaces avant les articles de la liste 'fille'.

    ::markdown
    1. Article 1
        1. Un point important de l'article 1.
        2. Un autre point à considérer.
    2. Article 2
        * Une règle dont l'ordre nous indifère.
        * Une autre règle.
        * Et une dernière.
    3. Article 3

**donne ceci**:

1. Article 1
    1. Un point important de l'article 1.
    2. Un autre point à considérer.
2. Article 2
  * Une règle dont l'ordre nous indifère.
  * Une autre règle.
  * Et une dernière.
3. Article 3

# Tableaux

Pour faire un tableau présentable, il va falloir le dessiner avec les caractères *pipe* (|), *tiret*(-) et *deux-points*(:).

## Mon premier tableau

Commençons par le plus simple des tableaux.

	::gfm
    |A|B|
	|-|-|
	|z|w|
    |y|v|
    |x|u|

**donne ceci**:

|A|B|
|-|-|
|z|w|
|y|v|
|x|u|

Nous avons tout simplement représenté 2 colonne en entourant le contenu de chaque colonne par les pipes (|).

Nous avons également séparé l'en-tête du tableau, du reste des données par une ligne avec un tiret (-) dans chaque colonne.

L'en-tête est valorisé et se différencie du contenu du tableau.

## Aspect dans l'éditeur

Examinons le tableau suivant:

	::gfm
    |Un joli en-tête|
	|----|
	|b                       |
    |c'est bizarre|
    |d|

**donne ceci**:

|Un joli en-tête|
|----|
|b                       |
|c'est bizarre|
|d|

Notes que le résultat est un tableau correct, alors que le texte dans l'éditeur est difficile à associer à un tableau.

Mais regardons de plus près:
- le nombre de tirets entre 2 pipes n'a pas d'importance et sépare bien l'en-tête du reste des valeurs.
- le nombre d'espaces n'impacte pas non plus l'aspect du tableau
- Ce qui compte c'est que les contenus des colonnes soient entourés par des pipes.

Notre tableau est syntaxiquement correct, mais n'est pas très lisible dans l'éditeur. Essayons de le rendre lisible.

	::gfm
    |Un joli en-tête|
	|--------------|
	|b             |
	|c'est bizarre |
	|d             |

Ce tableau qui nous donne le même résultat est plus facile à lire.

|Un joli en-tête|
|--------------|
|b             |
|c'est bizarre |
|d             |

## Alignement
Nous allons maintenant préciser pour chaque colonne comment aligner les colonnes de données. Le tableau suivant:

	::gfm
	|Un joli en-tête|Un joli en-tête bis  |
	|:------------:|-------------------:|
	|b             |b                   |
	|c'est bizarre |c'est pas si bizarre|
	|d             |d                   |

**donne ceci**:

|Un joli en-tête|Un joli en-tête bis  |
|:------------:|-------------------:|
|b             |b                   |
|c'est bizarre |c'est pas si bizarre|
|d             |d                   |

La ligne qui sert de séparateur entre l'en-tête et les données a été agrémenté de nouveaux symboles: les deux-points(:).

- Si l'on entoure les tirets de deux-points(:), l'alignement est centré.
- Si l'on met les deux-points(:) à la fin, l'alignement est à droite.
- Inutile de les mettre à gauche, car l'alignement par défaut est à gauche.

## Un tableau avec plusieurs exemple

Le tableau ci-dessous utilise à la fois des propriétés d'alignement, et des propriétés de valorisation de texte.

	::gfm
    | Les Tables     | Sont             | Cool  |
    | -------------- |:----------------:| -----:|
    | **col 3 est**  | alignée à droite | $1600 |
    | col 2 est      | *centrée*        |   $12 |
    | zebra stripes  | ~~une bêtise~~   |    $1 |

**donne ceci**:

| Les Tables     | Sont             | Cool  |
| -------------- |:----------------:| -----:|
| **col 3 est**  | alignée à droite | $1600 |
| col 2 est      | *centrée*        |   $12 |
| zebra stripes  | ~~une bêtise~~   |    $1 |

Enfin, n'hésitez pas à copier/coller des lignes entières pour vous faciliter la création de tableaux.

# Images

Tu peux aussi insérer une image, dans l'exemple suivant, tu peux voir le logo de Natao qui est inclu dans le logiciel.

    ::gfm
    ![Logo de Natao](./natao.png)

**donne ceci**:

![Logo de Natao](./natao.png)

Avant de décortiquer le Markdown, nous allons voir la méthode super facile.

## Insérer une image super facilement.

Pour insérer une image dans ton document, positionnes le curseur dans l'éditeur à l'endroit où tu souhaites l'insérer.
Puis cliques sur le bouton , choisis une image et Natao va s'éxécuter.

En fait, il va faire 3 choses:

- créer un dossier *Natao_images* (s'il n'existe pas déjà) dans le même dossier que ton fichier de base de données.
- copier l'image que tu lui auras fourni dans ce dossier et éventuellement la renommer si une image du même nom y existe déjà.
- créer pour toi le Markdown nécessaire à l'emplacement de ton curseur.

## voyons maintenant le Markdown

Le Markdown qu'il aura généré ressemblera à quelque chose comme ça:

	::gfm
	![newImage](file:/Mon%20chemin%20de%20fichier/mon%20image.png)

Tout d'abord, j'attire ton attention sur les *%20*. Les URL sur internet n'aiment pas les espaces. Ben c'est pareil pour les URL dans le MarkDown, du coup *%20* veut dire espace.

Maintenant, comme tu peux le voir la syntaxe en 3 parties:
- ! (qui annonce le début de l'image
- un texte entre crochets ([]), c'est un texte qui s'affiche quand on ne voit pas l'image.
- l'URL ou le chemin menant à l'image entre parenthèses.

Cette URL peut commencer par:
- *http:* ou *https:* si cette image est sur internet.
- *file:* si cette image est sur ton ordinateur (et c'est le cas quand on utilise le bouton d'insertion).
- rien du tout...Uniquement pour mes exemples car ces images sont livrées avec Natao.

# Liens

## En ligne

Tu peux créer un lien en ligne en mettant le texte sur lequel figure le lien entre crochets ( `[ ]` ) et tout de suite après, entre parenthèse ( `( )` ), là où conduit ce lien :

	::gfm
    [Natao est sur Github!](https://github.com/Ajrarn/Natao_legacy)

**donne ceci**:

[Natao est sur Github!](https://github.com/Ajrarn/Natao_legacy)

## Référence

Le lien de type référence utilise une deuxième paire de crochets, dans lequel tu lui donnes un nom unique qui est son identifiant:

    ::gfm
    Natao est sur [Github][github.natao] normalement.

**donne ceci**:

Natao est sur [Github][github.natao] normalement.

Notes bien que tu n'as pas encore écrit où allait ce lien. Pour ce faire, mais généralement, on les mets à la fin, tu vas pouvoir définir où va ce lien et lui donner un titre (quand tu survoles le lien).

Donc tu remets l'identifiant entre crochets, suivi de :, de la destination et enfin d'un titre entre guillemets.

    ::gfm
    [github.natao]: https://github.com/Ajrarn/Natao_legacy  "Natao sur Github"

Tu noteras également que cette description ne s'affiche pas. Mais quand tu survoles le lien de ton texte, tu vois apparaître le titre. Mais à quoi cela peut-il servir ?
A organiser toutes tes références, mais surtout à réutiliser les mêmes à plusieurs endroits. Il te suffit d'utiliser le même identifiant.
Par exemple, [ici][github.natao], c'est le même lien que celui utilisé dans l'exemple.

[github.natao]: https://github.com/Ajrarn/Natao_legacy  "Natao sur Github"

<file_sep>(function () {
    "use strict";

    var _ = require('lodash')
        ,fs = require('fs')
        ,cssParser = require('css');

    const defaultCss = '#title-zone {\r'+
           '\t color: #000000;\r'+
        '}';

    angular
        .module('Natao')
        .service('CssService', CssService)
        .run(run);

    //Start of the service
    function run() {
    }

    /**
     * Create the CssService
     * @param $translate
     * @param $q
     * @param DatabaseService
     * @returns {CssService}
     * @constructor
     */
    function CssService($translate,$q,AppStateService,DatabaseService) {

        var self = this;

        self.$translate = $translate;
        self.$q = $q;
        self.AppStateService = AppStateService;
        self.DatabaseService = DatabaseService;

        /**
         * Initialization of the service
         * @returns {*} return a promise
         */
        self.getInitCss = function() {

            return self.$q(function(resolve,reject) {

                //Then we search for existing css documents
                self.DatabaseService
                    .find({docName:'css'})
                    .then(function(docs) {
                        if (docs.length === 0) {
                            //If there is no document we will add the defaults css

                            var language = self.$translate.use();

                            //First we load the names of the css in the appropriate language
                            self.cssNamesFile = fs.readFileSync('./languages/cssNames-' + language + '.json','utf8');
                            self.cssNames = {};

                            try {
                                self.cssNames = JSON.parse(self.cssNamesFile);
                            }
                            catch (err) {
                                reject(err);
                            }

                            var pathCss = './default_css';
                            self.availableCss = [];

                            //We will read the files in the path and add it to the availableCss
                            var defaultFilesCss = fs.readdirSync(pathCss);
                            var nbfilesPending = defaultFilesCss.length;

                            defaultFilesCss.forEach(function(file) {
                                var cssContent = fs.readFileSync(pathCss + '/' + file,'utf8');

                                var nameToTranslate = _.find(self.cssNames,{originalName:file});

                                var docCss = {
                                    docName:'css',
                                    name: nameToTranslate.inDatabaseName,
                                    default: nameToTranslate.default,
                                    css: cssContent
                                };

                                self.DatabaseService
                                    .save(docCss)
                                    .then(function(doc) {
                                        self.availableCss.push(doc);
                                        nbfilesPending--;
                                        if (nbfilesPending === 0) {
                                            self.defaultCss = _.find(self.availableCss, {default: true});
                                            resolve(self.defaultCss);
                                        }
                                    })
                                    .catch(function(err) {
                                        reject(err);
                                    });

                            });

                        } else {
                            self.availableCss = docs;
                            self.defaultCss = _.find(self.availableCss,{default:true});
                            resolve(self.defaultCss);
                        }
                    })
                    .catch(function(err) {
                        reject(err);
                    });
            });
        };

        /**
         * insert the new Css document in the database
         * @param newCss
         */
        self.addCss = function(newCss) {

            self.DatabaseService
                .save(newCss)
                .catch(function(err) {
                    console.error(err);
                });

        };

        /**
         * create a new css document with its name
         * and insert it in the database
         * @param nameCss
         * @returns {*} a promise
         */
        self.addCssNamed = function(nameCss) {
            var docCss = {
                docName:'css',
                name: nameCss,
                default: false,
                css: defaultCss
            };

            return self.$q(function(resolve,reject) {

                self.DatabaseService
                    .save(docCss)
                    .then(function(doc) {
                        self.availableCss.push(doc);
                        resolve(doc);
                    })
                    .catch(function(err) {
                        reject(err);
                    });
            });

        };

        /**
         * init the current css by finding it
         * in the database with its id
         * @param idCss
         */
        self.initCurrentById = function(idCss) {
            var css = _.find(self.availableCss,{_id:idCss});
            self.currentCss = self.safeCss(css.css);
        };

        /**
         * init the current css with a css document
         * already loaded
         * @param css
         */
        self.initCurrentByContent = function(css) {
            self.currentCss = self.safeCss(css);
        };

        self.findCssId = function(what) {
            var result = _.find(self.availableCss,{_id:what});
            if (!result) {
                result = _.find(self.availableCss, {name:what});

                if (!result) {
                    result = _.find(self.cssNames, {originalName:what});
                    if (result) {
                        result = _.find(self.availableCss,{name:result.inDatabaseName})
                    }
                }
            }

            return result._id;
        };

        /**
         * save a css document in the database
         * @param css
         */
        self.saveCss = function(css) {

            //default
            if (css.default) {
                if (css._id) {
                    var result = _.find(self.availableCss, {default:true});
                    if (result && css._id != result._id) {
                        css.default = false;
                    }
                } else {
                    css.default = false;
                }
            }
            if (css._id) {

                self.DatabaseService
                    .save(css)
                    .then(function(doc) {
                        css = doc;
                    })
                    .catch(function(err) {
                        console.error(err);
                    });

            } else {

                self.DatabaseService
                    .save(css)
                    .then(function(doc) {
                        self.availableCss.push(doc);
                        css = doc;
                    })
                    .catch(function(err) {
                        console.error(err);
                    });
            }
        };

        /**
         * delete a css document from the database
         * @param css
         */
        self.deleteCss = function(css, replacement) {
            if (css._id) {

                var indexCss = _.findIndex(self.availableCss,{_id: css._id});

                self.AppStateService.startWrite();
                self.DatabaseService
                    .updateMassive({css: css._id}, {css: replacement._id})
                    .then(() => {
                        // end of update
                        self.AppStateService.stopWrite();
                        // then we can delete the css not used
                        self.AppStateService.startWrite();
                        self.DatabaseService
                            .delete(css._id)
                            .then(() => {
                                self.AppStateService.stopWrite();

                                // reload the available css
                                self.DatabaseService
                                    .find({docName:'css'})
                                    .then(function(docs) {
                                        self.availableCss = docs;
                                    }).catch((err) => {
                                        console.error(err);
                                    });
                            })
                            .catch(function(err) {
                                console.error(err);
                                self.AppStateService.stopWrite();
                            });

                    }).catch((err) => {
                        console.error(err);
                        self.AppStateService.stopWrite();
                    });

            }
        };

        /**
         * to avoid css disease add #viewer to each rule
         * @param css
         * @returns {*}
         */
        self.safeCss = function(css) {
            var objCss = cssParser.parse(css);

            var newRules = objCss.stylesheet.rules.map(function(rule) {
                var newRule = rule;
                if (rule.type === 'rule') {

                    var newSelectors = rule.selectors.map(function(selector) {
                        if (!selector.startsWith('#viewer')) {
                            return '#viewer ' + selector;
                        } else {
                            return selector;
                        }
                    });

                    newRule.selectors = newSelectors;
                }
                return newRule
            });

            objCss.stylesheet.rules = newRules;

            return cssParser.stringify(objCss);

        };

        /**
         * get a list of all other css than those given
         * @param css
         */
        self.otherCss = (css) => {
            return self.availableCss.filter((item) => {
                return item._id !== css._id;
            });
        };

        return self;
    }

}());<file_sep>[toc]

# Preferences

When you start Natao for the first time, only three Preferences sections will need your input.

## Your Database File

This is the file that contains all of the documents that you will create within Natao.

## Your Identity

Your first and last names, as well as the name of your course (History, Calculus, etc.), will appear in your Natao document, but only if the document style-sheet you pick permits it.

Please note that, upon using Natao for the first time, only Natao's default "Test" style-sheet can allow you to display that information.

## Your Theme

This section lets you pick Natao's overall color scheme. It can be changed whenever you want.

# Styles

This section lets you modify or create style-sheets.

Two panels are prominently displayed:

* A CSS editor, for you to modify the style-sheet you've picked.
* A visualization panel, for you to look at your document's raw HTML code directly, or at its rendered version.

In a future version of Natao, a virtual assistant will help you modify the style-sheets provided within Natao, without your having to know any CSS syntax or HTML code.
For now though, the Styles section is the only means by which you may edit your documents' appearance.
Ask for help if you need any.

# Structures

This section lets you modify the way your document folders' are organized/structured. Note that the tools you get to use here are similar to the ones found in Natao's Editor panel. The only difference is that you cannot create documents in this section.

# Others

This section allows you do accomplish two tasks:

- Activate the "Guided Tour" buttons, as you saw them when you first booted up Natao.
- Import the Help Files found in "Documents", for you to edit or print them.
<file_sep>(function () {
    "use strict";

    angular
        .module('Natao')
        .service('ColorPickerService', ColorPickerService)
        .run(run);

    //Start of the service
    function run() {
    }

    function ColorPickerService() {

        var self = this;

        // options for the color Picker
        self.optionsColumn = {
            columns: 4,
            roundCorners: true
        };

        self.customColors = ['#7bd148', '#5484ed', '#a4bdfc', '#46d6db', '#7ae7bf', '#51b749', '#fbd75b', '#ffb878', '#ff887c', '#dc2127', '#dbadff', '#000000' ];

        return self;

    }

}());<file_sep>(function () {
    "use strict";

    var fs = require('fs');
    var fileName = 'NataoSetting.json';
    var urlFirstSetting = '/firstTimeSettings';
    var gui = require('nw.gui');

    angular
        .module('Natao')
        .service('PreferencesService', PreferencesService)
        .run(run);

    //Start of the service
    function run() {
    }

    //Service itself
    function PreferencesService(DatabaseService,$location,$rootScope,$translate) {

        var self = this;
        self.DatabaseService = DatabaseService;
        self.$location = $location;
        self.$rootScope=$rootScope;
        self.$translate = $translate;

        self.fileDatabaseExist = function() {
            if (self.settings && self.settings.fileDatabase) {
                return fs.existsSync(self.settings.fileDatabase);
            } else {
                return false;
            }
        };

        /* only one preferences will be in the localStorage, the path to find the database
        * the other preferences will be in the database
        * in the document {docName:'preferences'}
        */
        self.preferences = {
            docName:'Preferences',
            name: null,
            firstName: null,
            colorTheme: null,
            showDys: false,
            zoomLevel: 0,
            showMenu: true,
            showEditor: true,
            showViewer: true,
            showTours:false,
            toursSeen:[]
        };

       self.saveSettings = function() {
           localStorage.setItem('nataoFileDatabase',self.settings.fileDatabase);
           self.DatabaseService.setDB(self.settings.fileDatabase);
       };

        self.savePreferences = function() {
            return self.DatabaseService.save(self.preferences);
        };

        /*
         Check if the preferences/settings are valid
         */
        self.isValid = function() {
            var valid = self.settings && self.settings.fileDatabase;
            valid = valid && self.preferences && self.preferences.name;
            valid = valid && self.preferences && self.preferences.firstName;
            valid = valid && self.preferences && self.preferences.colorTheme;
            valid = valid && self.preferences && self.preferences.zoomLevel !== null;
            valid = valid && self.preferences && self.preferences.showDys !== null;
            valid = valid && self.preferences && self.preferences.showMenu !== null;
            valid = valid && self.preferences && self.preferences.showEditor !== null;
            valid = valid && self.preferences && self.preferences.showViewer !== null;

            return valid;
        };

        self.save = function() {
            self.saveSettings();

            return self.savePreferences();
        };

        self.zoomChange = function() {

            if ($rootScope.nodeWebkitVersion !== 'browser') {
                var win = gui.Window.get();
                win.zoomLevel = self.preferences.zoomLevel;
            }
        };

        self.init = function() {

            //First we have to parse the json file and check if it exist
            self.settings = {};
            self.settings.fileDatabase = localStorage.getItem('nataoFileDatabase');

            if (!self.settings.fileDatabase) {
                self.$location.path(urlFirstSetting);
            } else {
                if (self.fileDatabaseExist()) {
                    self.DatabaseService.setDB(self.settings.fileDatabase);

                    self.DatabaseService
                        .find({docName:'Preferences'})
                        .then(function(docs) {
                            self.preferences = docs[0];
                            if (self.isValid()) {
                                // and then go to the editor
                                self.$location.path('/loading');
                                self.zoomChange();
                            } else {
                                self.$location.path(urlFirstSetting);
                            }
                        })
                        .catch(function(err) {
                            console.error(err);
                            self.$location.path('/settings');
                    });

                } else {
                    self.settings.fileDatabase = null;
                    self.$location.path(urlFirstSetting);
                }
            }
        };

        return self;

    }

}());<file_sep>**Avant de commencer**

Tu as du voir dans la visite guidée, les boutons te permettant de rêgler Natao pour ton confort visuel. Alors commences par cela. Joues avec les loupes et la police open-dyslexic pour te sentir à l'aise.

Si cela n'est pas suffisant, on a encore quelques petits réglages qui peuvent aider. Dans **L'éditeur**, il y a un bouton de réglages. Tu peux ajouter des rayures pour mieux différencier les lignes et augmenter l'écart entre  les lignes.

# Oui, mais à quoi ça sert ?
Je sais que tu te demandes en quoi Natao pourrait t'aider.

Il devrait t'aider à rédiger rapidement des documents élégants. Mais comment ?

Si tu es un peu observateur, tu dois te rendre compte que le texte de l'éditeur et celui du panneau de visualisation sont les mêmes, à ceci près que les #(en début de ligne) ont disparu et ont été remplacés par des chiffres romains. Les ## ont aussi été remplacés par des numéros, d'ailleurs les lignes commençant par des # sont différentes des autres lignes .

# Des titres
Oui, les # en début de ligne ont une signification. Ils disent à Natao:

	Fais attention à la ligne après le #, c'est un titre important.

## Et des sous-titres
	Et cette ligne avec ## est un sous-titre du précédent titre

## Et encore un sous-titre

### Et on peut encore descendre

# Et c'est tout ?

Non, ce n'est pas tout. Il y a encore d'autres options de mise en page à l'aide de caractères spéciaux.

Les \* qui permettent de valoriser des portions de texte, voici 2 exemples d'utilisation :
- un *bout de texte en italique*.
- un autre en **gras souligne**

Et il y a encore 2 ou 3 petites choses que tu découvriras un peu plus loin.

Bon par contre, cette syntaxe qui permet de mettre en page les documents n'est pas une invention propre à *Natao*.
Cela s'appelle du **Markdown**. Cette syntaxe est très utilisée sur internet pour rédiger des wikis notamment.
Donc, apprendre cette syntaxe pourra être utile en dehors de *Natao*.

## oui mais moi, je préfèrerais que ce qui est en gras souligné soit en rouge !
Et je peux te comprendre. Tu voudrais personnaliser la mise en forme de tes documents.

Première chose, tout en haut de l'éditeur, tu as un champs *Style*, qui te propose une liste déroulante de feuilles de style. En changeant de feuille de style, tu changeras l'apparence de tes documents.
*Natao* en fournit un certain nombre par défaut qui devraient te dépanner.

Si tu choisis par exemple la feuille de style *Contrôle*, tu devrais voir apparaître tes noms et prénom, la date et des marges permettant de présenter un devoir à rendre.

Ces feuilles de style sont modifiables, et tu peux en créer de nouvelles qui s'appliqueront automatiquement à tout ton document.

Et c'est dans ces feuilles de style que tu pourras lui préciser que tu veux du rouge sur le texte en question.

# Aller plus loin
Voila, tu connais les grandes lignes de cette application. Si tu souhaites aller plus loin, je t'invite à cliquer sur le point d'interrogation en haut à droite. Cela ouvrira une fenêtre avec l'aide qui te permettra de mieux découvrir Natao et tout ce que tu peux faire avec.

Si tu souhaites imprimer l'aide:
- cliques sur le bouton *Réglages* en haut à droite,
- puis dans l'onglet *Autres*,
- et enfin sur le bouton *Importer*.

Les fichiers qui composent l'aide apparaitront dans *Documents* et tu pourras les imprimer un à un.

Si au contraire, tu n'y trouves rien d'intéressant, tant pis. J'espère que tu trouveras ce que tu cherches.

Dans tous les cas, à bientôt.<file_sep>(function () {
    "use strict";

    var uuid = require('node-uuid');
    var _ = require('lodash');
    var fs = require('fs');

    angular
        .module('Natao')
        .service('PrincipalTreeService', PrincipalTreeService)
        .run(run);

    //Start of the service
    function run() {
    }

    //Service itself
    function PrincipalTreeService(TreeUtilService,TemplateTreeService,$q,$translate,DatabaseService,DocumentsService,$rootScope, AppStateService) {

        var self = this;
        self.TreeUtilService = TreeUtilService;
        self.TemplateTreeService = TemplateTreeService;
        self.$q = $q;
        self.$translate = $translate;
        self.DatabaseService = DatabaseService;
        self.DocumentsService = DocumentsService;
        self.AppStateService = AppStateService;
        self.$rootScope = $rootScope;
        self.docsMarkdown = [];

        self.cutNodePending = null;
        self.exportFileName = null;
        self.docsPendingForBuffer = 0;
        self.nodesPendingPaste = 0;

        self.treeOptions = {
            nodeChildren: "children",
            dirSelectable: true,
            injectClasses: {
                ul: "a1",
                li: "a2",
                liSelected: "a7",
                iExpanded: "a3",
                iCollapsed: "a4",
                iLeaf: "a5",
                label: "a6",
                labelSelected: "a8"
            },
            isLeaf: function(node) {
                return node.leaf;
            }
        };

        // if we do the save on the select node, the selected node is not yet set
        // so we have to watch it
        // and don't save the first time
        self.principalTree = { selectedNode: null };
        self.initWatch = true;

        self.$rootScope.$watch(function(){
            return self.principalTree.selectedNode;
        },function() {
            if (self.initWatch) {
                self.initWatch = false;
            } else {
                self.save();
            }
        });

        /**
         * init the principal tree service
         * return a promise
         * @param defaultCss
         * @returns {*}
         */
        self.getInitTreeService = function(defaultCss) {

            return self.$q(function(resolve,reject) {

                self.principalTree = self.AppStateService.getPrincipalTree();

                if (!self.principalTree.tree.defaultCss) {

                    self.principalTree.tree.defaultCss = defaultCss._id;

                    //We will create the first document
                    self.$translate('FIRST_DOC').then(function (translation) {
                        self.addFolder(translation)
                            .then(function(node) {

                                self.principalTree.expandedNodes.push(node);

                                let welcomeMd = fs.readFileSync('./languages/welcome-' + self.$translate.use() + '.md','utf8');

                                self.DocumentsService
                                    .addDocument(self.principalTree.tree.defaultCss,translation,welcomeMd)
                                    .then(function(newDoc) {

                                        var newNode = {
                                            id: newDoc._id,
                                            name: newDoc.title,
                                            leaf: true
                                        };

                                        node.children.push(newNode);
                                        self.principalTree.selectedNode = newNode;
                                        self.save();

                                        resolve();
                                    })
                                    .catch(function(err ){
                                        reject(err);
                                    });

                            })
                            .catch(function(err) {
                                reject(err);
                            });

                    });

                } else {
                    resolve();
                }

            });
        };

        self.save = function() {
            self.AppStateService.setPrincipalTree(self.principalTree);
        };

        self.addFolder = function(nodeName,nodeParent,templateName) {

            return self.$q(function(resolve,reject) {

                if (!nodeParent) {
                    nodeParent = self.principalTree.tree;
                }

                if (templateName) {

                    // To make a good copy we will pass by the buffer
                    self.TreeUtilService
                        .nodeToBuffer(self.TemplateTreeService.getTemplate(templateName))
                        .then(function (buffer) {
                            self.TreeUtilService
                                .bufferToNode(buffer)
                                .then(function (node) {
                                    delete node.docName;
                                    node.name = nodeName;
                                    nodeParent.children.push(node);
                                    self.save();
                                    resolve(node);
                                })
                                .catch(function (err) {
                                    reject(err);
                                })
                        })
                        .catch(function (err) {
                            reject(err);
                        });
                } else {
                    var newNode = {
                        id: uuid.v4(),
                        name: nodeName,
                        color: '#000000',
                        defaultCss: nodeParent.defaultCss,
                        children: []
                    };

                    nodeParent.children.push(newNode);
                    self.save();
                    resolve(newNode);
                }

            });

        };

        //delete of a node
        self.deleteNode = function(node) {

            return self.$q(function(resolve,reject) {

                self.TreeUtilService
                    .deleteNode(node,self.principalTree.tree)
                    .then(function() {

                        //First we have to check if we have deleted the selected node
                        if(self.principalTree.selectedNode) {
                            var selNode = self.TreeUtilService.getNode(self.principalTree.selectedNode.id,self.principalTree.tree);
                            if (!selNode) {
                                delete self.principalTree.selectedNode;
                            }
                        }

                        //finally we have to clean the expandedNodes
                        var arrayOfNode = self.TreeUtilService.flatFolders(self.principalTree.tree);
                        self.expandedNodes = _.intersectionWith(self.expandedNodes,arrayOfNode,function(object,other) {
                            return object.id === other.id;
                        });

                        self.save();

                        resolve();

                    })
                    .catch(function(err) {
                        reject(err);
                    });
            });

        };

        self.addHelpFiles = function() {

            return self.$q((resolve, reject) => {
                // First we check the name of the folder who contains We will contain the files
                self.$translate('HELP_FOLDER')
                    .then(function (translation) {
                        // then we find and delete the previous folder and its content
                        var folderHelp = self.TreeUtilService.findNodeByName(self.principalTree.tree, translation);

                        if (folderHelp) {
                            self.TreeUtilService.deleteNode(folderHelp, self.principalTree.tree);
                        }

                        //And finally we create a new folder and import all the files in
                        self.addFolder(translation,self.principalTree.tree)
                            .then(function(node) {

                                var files = fs.readdirSync('./languages');
                                var helpFiles = files.filter(function(item) {
                                    return item.startsWith('help');
                                });

                                let nbFiles = helpFiles.length;

                                helpFiles.forEach(function(filename) {
                                    var file = fs.readFileSync('./languages/' + filename,'utf8');

                                    self.DocumentsService
                                        .addDocument(self.principalTree.tree.defaultCss, filename, file)
                                        .then(function(newDoc) {

                                            var newNode = {
                                                id: newDoc._id,
                                                name: newDoc.title,
                                                leaf: true
                                            };

                                            node.children.push(newNode);
                                            self.principalTree.selectedNode = newNode;
                                            self.save();

                                            // resolve the promise when all files are imported
                                            nbFiles--;
                                            if (nbFiles === 0) {
                                                resolve();
                                            }
                                        })
                                        .catch(function(err ){
                                            reject(err);
                                        });
                                });
                            })
                            .catch(function(err) {
                                reject(err);
                            });
                    });
            });

        };

        return self;

    }
}());<file_sep>(function () {
    "use strict";

    var _ = require('lodash');
    var uuid = require('node-uuid');
    var fs = require('fs');

    angular
        .module('Natao')
        .service('TreeUtilService', TreeUtilService)
        .run(run);

    //Start of the service
    function run() {
    }

    //Service itself
    function TreeUtilService(DocumentsService,$q,AppStateService,CssService) {

        var self = this;
        self.DocumentsService = DocumentsService;
        self.$q = $q;
        self.AppStateService = AppStateService;
        self.CssService = CssService;

        /**
         * Give all the ids of subfolder of the node in an array
         * this method don't return anything but change the arrayOfIds
         * @param node
         * @param arrayOfIds
         */
        self.allSubFoldersIds = function(node,arrayOfIds) {
            if (node) {
                if(!arrayOfIds) {
                    arrayOfIds = [];
                }
                if (!node.leaf) {
                    arrayOfIds.push(node.id);
                    if (node.children && node.children.length > 0) {
                        node.children.forEach(function(item) {
                            self.allSubFoldersIds(item,arrayOfIds);
                        });
                    }
                }
            }
        };

        /**
         * return the number of nodes inside a node
         * @param node
         * @returns {number}
         */
        self.howManyNodes = function(node) {
            if (node.leaf || node.children.length === 0) {
                return 1;
            } else {
                var nbNode = 1;
                node.children.forEach(function(item) {
                    nbNode = nbNode + self.howManyNodes(item);
                });
                return nbNode;
            }
        };

        /**
         * Method to find the parent of a node
         * @param node
         * @param nodeParent
         * @returns {*}
         */
        self.findParent = function(node, nodeParent) {

            if (nodeParent.leaf) {
                return null;
            } else {
                var item = _.find(nodeParent.children,{id:node.id});
                if (item) {
                    return nodeParent;
                } else {
                    var result = null;
                    for(var i=0; result == null && i < nodeParent.children.length; i++){
                        if (!nodeParent.children[i].leaf) {
                            result = self.findParent(node,nodeParent.children[i]);
                        }
                    }
                    return result;
                }
            }
        };

        /**
         * retrurn true if nodeParent is the direct parent of node
         * @param node
         * @param nodeParent
         * @returns {boolean}
         */
        self.isParent = function(node,nodeParent) {
            var parent = self.findParent(node,nodeParent);
            return parent != null;
        };

        /**
         * get a node in a tree from it's id
         * @param nodeId
         * @param nodeParent
         * @returns {*}
         */
        self.getNode = function(nodeId,nodeParent) {
            var nodeFound = null;
            if (nodeParent.id === nodeId) {
                nodeFound = nodeParent;
            } else {
                if (!nodeParent.leaf && nodeParent.children && nodeParent.children.length > 0) {
                    nodeParent.children.forEach(function(item) {
                        var nodeInSearch = self.getNode(nodeId,item);
                        if (nodeInSearch) {
                            nodeFound = nodeInSearch;
                        }
                    });
                }
            }
            return nodeFound;

        };

        /**
         * returns an array with the folders in an node
         * @param node
         * @returns {*}
         */
        self.flatFolders = function(node) {
            if (!node.leaf) {
                var arrayFolder = [node];
                if (node.children && node.children.length > 0) {
                    node.children.forEach(function(item) {
                        arrayFolder =  _.union(arrayFolder,self.flatFolders(item));
                    });
                }
                return arrayFolder;
            } else {
                return [];
            }
        };

        /**
         * Inventory of all documents in a structure
         * @param node
         * @returns {*}
         */
        self.documentsInStructure = function(node) {
            if (!node.leaf) {
                var arrayDocuments = [];
                if (node.children && node.children.length > 0) {
                    node.children.forEach(function(item) {
                        arrayDocuments =  _.union(arrayDocuments,self.documentsInStructure(item));
                    });
                }
                return arrayDocuments;
            } else {
                return [node];
            }
        };

        /**
         * return true if node is the first child of nodeRoot
         * @param node
         * @param nodeRoot
         * @returns {boolean}
         */
        self.isFirstChild = function(node,nodeRoot) {
            var parent = self.findParent(node,nodeRoot);
            return parent && parent.children && parent.children.indexOf(node) === 0;
        };

        /**
         * change Ids deeply in a node
         * @param node
         */
        self.changeIds = function(node) {

            if (!node.leaf) {
                node.id = uuid.v4();

                if(node.children && node.children.length > 0) {
                    node.children.forEach(function(item) {
                        self.changeIds(item);
                    });
                }
            }

        };

        /**
         * This function return a buffer with the node to copy/cut with all the documents it contains
         * @param node
         * @returns {*}
         */
        self.nodeToBuffer = function(node) {

            //First we proceed with a copy of the node
            var nodeInBuffer = {};
            angular.copy(node,nodeInBuffer);

            return self.$q(function(resolve,reject) {
                var buffer = {
                    node: nodeInBuffer,
                    documents : []
                };

                // we copy all documents in documents array
                // and resolve only when all documents are in the buffer
                var listDocs = self.documentsInStructure(node);

                if (listDocs && listDocs.length > 0) {
                    var nbDocsPending = listDocs.length;
                    listDocs.forEach(function(item) {
                        self.DocumentsService
                            .findDocument(item.id)
                            .then(function(docs) {
                                buffer.documents = _.union(buffer.documents,docs);
                                nbDocsPending--;
                                if (nbDocsPending === 0) {
                                    resolve(buffer);
                                }
                            })
                            .catch(function(err) {
                                reject(err);
                            });
                    });
                } else {
                    resolve(buffer);
                }
            });
        };

        /**
         * this method return a node from a buffer
         * @param buffer
         * @returns {*}
         */
        self.bufferToNode = function(buffer) {

            return self.$q(function(resolve,reject) {
                //First we proceed with a copy of the node required
                var nodeToReturn = {};
                angular.copy(buffer.node,nodeToReturn);

                self.changeIds(nodeToReturn);

                //then we have to copy all documents in the buffer by content, so new documents
                // but we have to keep the change of Ids
                if (buffer.documents && buffer.documents.length > 0) {
                    var nbDocsPending = buffer.documents.length;
                    buffer.documents.forEach(function(item) {

                        //For each document we find the node that represent it in the tree
                        var nodeDoc = self.getNode(item._id,nodeToReturn);

                        //we delete the previous Id
                        delete item._id;

                        // and the insert the new Doc
                        self.DocumentsService
                            .insertDocument(item)
                            .then(function(doc) {

                                nodeDoc.id = doc._id;

                                nbDocsPending--;
                                if (nbDocsPending === 0) {
                                    resolve(nodeToReturn);
                                }

                            })
                            .catch(function(err) {
                                reject(err);
                            });

                    });
                } else {
                    resolve(nodeToReturn);
                }
            });
        };

        /**
         * this method return a buffer from a file
         * @param fileName
         */
        self.fileToBuffer = function(fileName) {

            var extensionFile = fileName.split('.')[1];

            switch (extensionFile) {
                case 'md':
                    return self.markdownFileToBuffer(fileName);
                    break;
                default:
                    return self.jsonFileToBuffer(fileName);
            }

        };

        /**
         * this method return a buffer from a file in markdown
         * @param fileName
         * @returns {*}
         */
        self.markdownFileToBuffer = function(fileName) {
            return self.$q(function(resolve,reject) {
                self.AppStateService.startWrite();
                fs.readFile(fileName,'utf8',function(err,data) {
                    self.AppStateService.stopWrite();
                    if (err) {
                        reject(err);
                    } else {
                        var path = fileName.split('.')[0].split('/');
                        var nameFile = path[path.length - 1];

                        var buffer = {
                            node: {
                                id: nameFile,
                                name: nameFile,
                                leaf: true
                            },
                            documents: [
                                {
                                    _id: nameFile,
                                    docName: 'markdown',
                                    title: nameFile,
                                    created: new Date(),
                                    css: self.CssService.defaultCss._id,
                                    md: data

                                }
                            ]};

                        resolve(buffer);
                    }
                });
            });
        };

        /**
         * this method return a buffer from a file in json
         * @param fileName
         * @returns {*}
         */
        self.jsonFileToBuffer = function(fileName) {
            return self.$q(function(resolve,reject) {
                self.AppStateService.startWrite();
                fs.readFile(fileName,'utf8',function(err,data) {
                    self.AppStateService.stopWrite();
                    if (err) {
                        reject(err);
                    } else {
                        try {
                            var buffer = JSON.parse(data);
                            self.transformDatesInBuffer(buffer);
                            resolve(buffer);
                        }
                        catch (err) {
                            reject(err);
                        }
                    }
                });
            });
        };

        /**
         * this method write in fil from a buffer
         * @param buffer
         * @param fileName
         */
        self.bufferToFile = function(buffer,fileName) {

            var extensionFile = fileName.split('.')[1];

            switch (extensionFile) {
                case 'md':
                    return self.bufferToMarkdownFile(buffer,fileName);
                    break;
                default:
                    return self.bufferToJsonFile(buffer,fileName);
            }

        };

        /**
         * this method write in a markdown file from buffer
         * @param buffer
         * @param fileName
         * @returns {*}
         */
        self.bufferToMarkdownFile = function(buffer,fileName) {

            return self.$q(function(resolve,reject) {
                self.AppStateService.startWrite();
                if (fs.existsSync(fileName)) {
                    fs.unlinkSync(fileName);
                }

                fs.writeFile(fileName, buffer.documents[0].md, 'utf8', function(err) {
                    self.AppStateService.stopWrite();
                    if (err) {
                        reject(err);
                    } else {
                        resolve();
                    }
                });

            });
        };

        /**
         * this method write in a json file from buffer
         * @param buffer
         * @param fileName
         * @returns {*}
         */
        self.bufferToJsonFile = function(buffer,fileName) {

            return self.$q(function(resolve,reject) {
                self.AppStateService.startWrite();
                if (fs.existsSync(fileName)) {
                    fs.unlinkSync(fileName);
                }

                fs.writeFile(fileName, JSON.stringify(buffer), 'utf8', function(err) {
                    self.AppStateService.stopWrite();
                    if (err) {
                        reject(err);
                    } else {
                        resolve();
                    }
                });

            });
        };

        /**
         * transform the date in strin from the buffer in javascript date
         * @param buffer
         */
        self.transformDatesInBuffer = function(buffer) {
            buffer.documents.forEach(function (doc) {
                doc.created = new Date(doc.created);
            });
        };

        /**
         * move a nodeToMove before a nodeAfter in nodeRoot tree
         * @param nodeToMove
         * @param nodeAfter
         * @param nodeRoot
         */
        self.moveBefore = function(nodeToMove,nodeAfter,nodeRoot) {

            var parentDestination = self.findParent(nodeAfter,nodeRoot);

            if (!self.isParent(parentDestination,nodeToMove) && nodeToMove !== parentDestination) {
                var parentSource = self.findParent(nodeToMove,nodeRoot);
                var positionSource = parentSource.children.indexOf(nodeToMove);
                var positionAfter = parentDestination.children.indexOf(nodeAfter);

                //To make copy without errors we wil pass it in the buffer and the return a node
                self.nodeToBuffer(nodeToMove)
                    .then(function(buffer) {

                        //we can delete the original when the copy is in the buffer
                        parentSource.children.splice(positionSource,1);

                        self.bufferToNode(buffer)
                            .then(function(node) {

                                //when we have the new safe node we move the copy in the right place
                                if (positionAfter === 0) {
                                    parentDestination.children.unshift(node);
                                } else {
                                    parentDestination.children.splice(positionAfter,0,node);
                                }

                            })
                            .catch(function(err) {
                                console.error(err);
                            });

                    })
                    .catch(function(err) {
                        console.error(err);
                    });
            }

        };

        /**
         * move a nodeToMove after a nodeBefore in nodeRoot tree
         * @param nodeToMove
         * @param nodeBefore
         * @param nodeRoot
         */
        self.moveAfter = function(nodeToMove,nodeBefore,nodeRoot) {

            var parentDestination = self.findParent(nodeBefore,nodeRoot);

            if (!self.isParent(parentDestination,nodeToMove) && nodeToMove !== parentDestination) {
                var parentSource = self.findParent(nodeToMove,nodeRoot);
                var positionSource = parentSource.children.indexOf(nodeToMove);
                var positionBefore = parentDestination.children.indexOf(nodeBefore);

                //To make copy without errors we wil pass it in the buffer and the return a node
                self.nodeToBuffer(nodeToMove)
                    .then(function(buffer) {

                        //we can delete the original when the copy is in the buffer
                        parentSource.children.splice(positionSource,1);

                        self.bufferToNode(buffer)
                            .then(function(node) {

                                //when we have the new safe node we move the copy in the right place
                                if (positionBefore === parentDestination.children.length - 1) {
                                    parentDestination.children.push(node);
                                } else {
                                    parentDestination.children.splice(positionBefore + 1,0,node);
                                }

                            })
                            .catch(function(err) {
                                console.error(err);
                            });

                    })
                    .catch(function(err) {
                        console.error(err);
                    });
            }

        };

        /**
         * move a nodeToMove into a nodeMoveIn in nodeRoot tree
         * @param nodeToMove
         * @param nodeMoveIn
         * @param nodeRoot
         */
        self.moveIn = function(nodeToMove,nodeMoveIn,nodeRoot) {

            if (!self.isParent(nodeMoveIn,nodeToMove) && nodeMoveIn !== nodeToMove) {
                var parentSource = self.findParent(nodeToMove,nodeRoot);
                var positionSource = parentSource.children.indexOf(nodeToMove);

                //To make copy without errors we wil pass it in the buffer and the return a node
                self.nodeToBuffer(nodeToMove)
                    .then(function(buffer) {

                        //we can delete the original when the copy is in the buffer
                        parentSource.children.splice(positionSource,1);

                        self.bufferToNode(buffer)
                            .then(function(node) {

                                //when we have the new safe node we move the copy in the right place
                                if (!nodeMoveIn.leaf && nodeMoveIn.children) {
                                    nodeMoveIn.children.push(node);
                                }

                            })
                            .catch(function(err) {
                                console.error(err);
                            });

                    })
                    .catch(function(err) {
                        console.error(err);
                    });

            }

        };

        /**
         * this function effectively delete the node and all documents attached
         * it will be only use in the trash
         * for the principal tree the erase function will delete the node and preserve the documents
         * @param node
         * @param nodeRoot
         * @returns {*}
         */
        self.deleteNode = function(node,nodeRoot) {

            return self.$q(function(resolve,reject) {

                if (node.leaf) {
                    // If it's a document we have to delete it first from the markdown collection
                    self.DocumentsService
                        .deleteDocument(node.id)
                        .then(function () {

                            //now we will delete it from the tree
                            var parent = self.findParent(node,nodeRoot);
                            if (parent.children && parent.children.length > 0) {
                                var indexOfNode = _.findIndex(parent.children,{id:node.id});
                                if (indexOfNode >=0) {
                                    parent.children.splice(indexOfNode,1);
                                }
                            }
                            resolve();
                        })
                        .catch(function(err) {
                            reject(err);
                        });
                } else {
                    //If it's a folder we have to find all his documents in itself
                    var documents = self.documentsInStructure(node);
                    var nbDocsPending = documents.length;

                    if (nbDocsPending > 0) {
                        //and then delete all the documents
                        documents.forEach(function(document) {

                            self.DocumentsService
                                .deleteDocument(document.id)
                                .then(function() {
                                    nbDocsPending--;
                                    if (nbDocsPending === 0) {
                                        // In all case we have to delete it from the tree
                                        var parent = self.findParent(node,nodeRoot);

                                        if (parent.children && parent.children.length > 0) {
                                            var indexOfNode = _.findIndex(parent.children,{id:node.id});
                                            if (indexOfNode >=0) {
                                                parent.children.splice(indexOfNode,1);
                                            }
                                        }
                                        resolve();
                                    }
                                })
                                .catch(function(err) {
                                    reject(err);
                                });
                        });
                    } else {
                        // In all case we have to delete it from the tree
                        var parent = self.findParent(node,nodeRoot);

                        if (parent.children && parent.children.length > 0) {
                            var indexOfNode = _.findIndex(parent.children,{id:node.id});
                            if (indexOfNode >=0) {
                                parent.children.splice(indexOfNode,1);
                            }
                        }
                        resolve();
                    }

                }
            });
        };

        /**
         * this function only delete the node but not the documents attached
         * for the principal tree
         * @param node
         * @param nodeRoot
         * @returns {*}
         */
        self.eraseNode = function(node,nodeRoot) {
            return self.$q(function(resolve) {
                var parent = self.findParent(node,nodeRoot);
                if (parent.children && parent.children.length > 0) {
                    var indexOfNode = _.findIndex(parent.children,{id:node.id});
                    if (indexOfNode >=0) {
                        parent.children.splice(indexOfNode,1);
                    }
                }
                resolve();
            });
        };

        /**
         * search a node by it's name
         * @param node
         * @param name
         * @returns {*}
         */
        self.findNodeByName = function(node, name) {
            var nodeFound = null;
            if (node.name === name) {
                nodeFound = node;
            } else {
                if (node.children && node.children.length > 0) {
                    node.children.forEach(function(item) {
                        var nodeInSearch = self.findNodeByName(item, name);
                        if (nodeInSearch) {
                            nodeFound = nodeInSearch;
                        }
                    });
                }
            }
            return nodeFound;
        };

        /**
         * get the nodes id to make a path from a node to another
         * @param nodeFrom
         * @param nodeTo
         * @returns {*}
         */
        self.getPath = function(nodeFrom, nodeTo) {
            var path = [];

            if (nodeFrom.id !== nodeTo.id && nodeFrom.children) {
               for (var index = 0; path.length === 0 && index < nodeFrom.children.length; index++) {

                   if (nodeFrom.children[index].id === nodeTo.id) {
                       path = [nodeFrom.id];
                   } else {
                       path = self.getPath(nodeFrom.children[index], nodeTo);
                       if (path.length > 0) {
                           path.unshift(nodeFrom.id);
                       }
                   }
                }
           }
            return path;
        };

        /**
         * merge nodeToGet in nodeToReceive
         * it preserves nodes already in nodeToReceive
         * @param nodeToReceive
         * @param nodeToGet
         */
        self.mergeNodes = function(nodeToReceive, nodeToGet) {

            // We have to identify the nodes tha are already in destination
            // and those who just need to be add
            let receiveIds = nodeToReceive.children.map(item => item.id);
            let toGetIds = nodeToGet.children.map(item => item.id);

            let intersectionIds = _.intersection(receiveIds, toGetIds);
            let differenceIds = _.difference(toGetIds, receiveIds);

            // We first treat the intersection to merge it
            if (intersectionIds.length > 0) {
                let nodeToMerges = nodeToGet.children.filter((item) => {
                    return intersectionIds.indexOf(item.id) >= 0;
                });

                nodeToMerges.forEach((node) => {
                    if (!node.leaf) {
                        let nodeInReceiveToMerge = self.getNode(node.id, nodeToReceive);
                        self.mergeNodes(nodeInReceiveToMerge, node);
                    }
                });
            }

            // and then we simply add the others
            if (differenceIds.length > 0) {
                let nodesToAdd = nodeToGet.children.filter((item) => {
                    return differenceIds.indexOf(item.id) >= 0;
                });
                nodesToAdd.forEach((node) => {
                    nodeToReceive.children.push(node);
                });
            }

        };

        return self;

    }

}());
<file_sep>(function () {
    "use strict";

    var template = '
' +
        '' +
        '' +
        '
';

    angular
        .module('Natao')
        .directive('loader', function() {
            return {
                restrict: 'A',
                scope: {
                    loader: '='
                },
                link: function($scope, element, attrs) {

                    var loaderElm = angular.element(template);

                    $scope.$watch(
                        function() {
                            return $scope.loader;
                        },
                        function(val) {
                            if (val) {
                                loaderElm.show();
                            } else {
                                loaderElm.hide();
                            }
                    });
                    element.append(loaderElm);
                },
                template: template
            };
        });

}());

<file_sep>[toc]

# La barre de boutons principale

![Image of MenuBar](./src/images/menuBar.png)

Cette barre présente en haut de l'éditeur te donne accès aux fonctionnalités essentielles de Natao.

## Zoome et Dézoome

 -  te permet de diminuer la taille des caractères pour toute l'application.
 -  te permet d'augmenter la taille des caractères pour toute l'application.

Une chose que tu dois savoir à propos de Natao, c'est que tout est enregistré automatiquement. Les modifications que tu apportes en le règlant, par exemple ici avec ces boutons, est sauvegardé.
Tu n'auras pas à refaire ces réglages lorsque tu le redémarreras.

## Dyslexie

 te permet d'activer ou de désactiver pour toute l'application, la police de caractère open-dyslexic.
Cette dernière est spécialement étudiée pour améliorer le confort de lecture des dyslexiques.

Il y a une petite exception à cette règle : les polices explicitement choisies dans les feuilles de style, mais on verra cela plus tard.

## Les 3 panneaux

-  permet de masquer/afficher le panneau de navigation dans tes documents, appelé aussi **Documents**.
-  permet de masquer/afficher l'éditeur Markdown
-  permet de masquer/afficher le panneau de visualisation du résultat.

## Imprimer

 te permet d'imprimer le document actif.

## Aide

? te permet d'ouvrir une nouvelle fenêtre avec l'aide (ce que tu es en train de lire).

## Règlages

 te permet d'accéder aux réglages de Natao.

# Documents

## La barre d'outils de l'explorateur de documents
![Image of ExplorerBar](./src/images/documents.png)

Cette barre contient un titre cliquable pour basculer de la vue **Corbeille** à la vue **Documents**, et 3 boutons :
-  permet de coller un contenu préalablement copié ou coupé dans le presse-papiers de Natao.
-  permet d'importer un contenu depuis un fichier.
-  permet d'ajouter un dossier à la racine de **Documents**. Lors de la création d'un dossier, tu peux utiliser un modèle de structure qui ajoutera dans ton dossier des sous-dossier correspondant à l'organisation que tu as choisi.

## L'explorateur de documents

![Image of Explorer](./src/images/explorer.png)

Dans ce dernier apparaissent tes dossiers et documents, selon l'organisation qui te convient.
- Un clic sur une icône de dossier le sélectionnera, le pliera ou le dépliera.
- Un clic sur le nom du dossier ouvrira un menu d'actions sur ce dernier que l'on verra juste après.
- un clic sur un document, l'ouvrira dans la partie de droite, dans l'éditeur et le panneau de visualisation.

## Les actions sur les dossiers

 ![Image of Explorer](./src/images/folderOptions.png)

-  permet de modifier le nom du dossier, sa couleur, ou la feuille de style par défaut des documents qu'il contient. La modification du style par défaut n'est pas appliquée  à tous les sous-dossiers et documents de ce dernier.
-  permet d'ajouter un sous-dossier à celui que l'on a sélectionné. On peut également ici utiliser un modèle de structure pour créer automatiquement les sous-dossiers correspondant au modèle.
-  permet d'ajouter un document dans le dossier sélectionné.
-  permet de copier un dossier et tout son contenu dans le presse-papier de Natao.
-  permet de couper un dossier et tout son contenu dans le presse-papier de Natao.
-  permet de coller un contenu préalablement copié ou coupé dans le presse-papiers de Natao.
-  permet d'exporter dans un fichier un dossier et tout son contenu.
-  permet d'importer un contenu exporté depuis un fichier.
-  permet d'enregistrer la structure, tous les sous-dossiers sans les documents, en tant que modèle de structure. Ce modèle de structure pourra être utilisé à chaque création de dossier/sous-dossier.
-  permet de mettre le dossier dans la corbeille avec tout ce qu'il contient.

## Dans la corbeille
Tu peux y voir un arbre contenant les documents que tu y as mis. Il y a moins d'interactions dans cette vue.
Les seules choses que tu peux faire sur les dossiers et documents sont:

-  les supprimer définitivement.
-  les restaurer(si possible à leur emplacement d'origine).

# L'éditeur

## Généralités
 Voici l'outil principal de Natao. Celui qui te permet de rédiger tes documents. Tu peux y voir 3 champs de saisie/sélection:
- *Le titre* : Le titre de ton document n'est pas inclus dans la rédaction de ce dernier. Cela permet notamment de le voir dans le navigateur. Mais ne t'inquiètes pas, il apparait bien dans le panneau de visualisation et quand tu imprimes le document.
- *Le style* :  Le style que tu choisis ici modifie la mise en page de ton document dans le panneau de visualisation. On verra plus loin, comment créer ou modifier une feuille de style.
- *Créé le* : La date de création. Par défaut, c'est la date du jour, mais tu peux la modifier. Cette date apparaîtra dans ton document en fonction de la feuille de style choisie. Cela peut donc être la date de remise d'un devoir par exemple.

 Il y a également quelques boutons qui ont la même signification que dans le navigateur:
-  permet de copier le document courant(avec ses champs) dans le presse-papier de Natao.
-  permet de couper le document courant dans le presse-papi<NAME>.
-  permet d'exporter dans un fichier le document courant.
-  permet de supprimer le document courant.

## Insérer une image

-  te permet d'insérer une image dans ton document. Tu trouveras une explication détaillée de ce qu'il fait dans l'aide sur le Markdown dans le chapitre *Images*.

## Réglages de l'éditeur
Le bouton  te permet d'agir sur la présentation de l'éditeur avec 2 options très pratiques notamment en cas de troubles visuo-spatiaux:
- la possibilité de mettre des rayures. Les lignes (dans le sens de l'éditeur, voir le numéro à gauche) seront rayées blanches et grises te permettant de te situer plus rapidement dans le document.
- la possibilité d'augmenter la taille des lignes, et donc de séparer davantage les lignes de texte que par défaut.

## Rechercher du texte
Le bouton  te permet d'ouvrir un panneau de recherche au dessus de l'éditeur Markdown.

Ce panneau te permet de rechercher du texte dans l'éditeur Markdown.

En tapant le texte recherché dans le champs *Recherche*, celui-ci va surligner les occurences du mot trouvé dans le Markdown, il va également t'indiquer combien il en a trouvé.

Les flèches  et , te permettront de positionner l'éditeur sur le précédent ou le prochain mot correspondant. Tu verras l'occurence sélectionné dans une couleur plus foncée.

Mais tu peux également remplacer une ou plusieurs occurences avec le texte que tu écris dans le champs *Remplace par*.

- Le bouton  remplace l'occurence en cours.
- Le bouton  remplace toutes les occurences.

## L'éditeur Markdown

L'éditeur est composé d'un espace où tu peux saisir ton document en Markdown (pour connaître cette syntaxe, je t'invite à consulter la section d'aide dédiée), et d'une barre verticale contenant des numéros de lignes et qui peut aussi contenir d'autres symbôles suivant le contexte. Ici, tu pourras y voir des petits triangles te permettant de plier ou déplier ton document. Cela te permet entre autres de visualiser le plan de ton document.

Tu pourras également constater que l'éditeur met en valeur ton texte Markdown pour t'aider à t'y retrouver, à l'aide de couleurs, taille de caractères, etc...

# Le panneau de visualisation
C'est le panneau le plus simple, et finalement le plus important. C'est lui qui te montre à quoi ressemblera ton document une fois imprimé. Si tu cliques, sur le bouton , ce panneau prendra tout l'espace avant de te proposer l'impression.
<file_sep>(function () {
    "use strict";

    var fs = require('fs');

    // Load native UI library
    var gui = require('nw.gui'); //or global.window.nwDispatcher.requireNwGui() (see https://github.com/rogerwang/node-webkit/issues/707)

// Get the current window
    var win = gui.Window.get();

    var modules = ['ngSanitize', 'ng-showdown', 'ngRoute', 'pascalprecht.translate', 'tmh.dynamicLocale', 'treeControl', 'DWand.nw-fileDialog', 'nsPopover', 'uiSwitch','ngjsColorPicker','ui.codemirror','ngOnboarding'];

    angular
        .module('Natao', modules)
        .run(run);

    function run($rootScope, AppStateService) {

        //prevent properly close
        win.on('close', () => {

            AppStateService.resetBuffer();
            AppStateService.close()
                .subscribe(
                    (event) => {
                        console.log(event);
                    },
                    (err) => {
                        console.error(err);
                    },
                    () => {
                        win.hide(); // Pretend to be closed already
                        win.close(true);
                    }
                );
        });

        //Detect webkit and version
        if (typeof process !== "undefined") {
            $rootScope.nodeWebkitVersion = process.versions['node-webkit'];

            if (process.platform === "darwin") {
                var mb = new gui.Menu({type: 'menubar'});
                mb.createMacBuiltin('Natao', {
                    hideEdit: false,
                });
                gui.Window.get().menu = mb;
            }

        } else {
            $rootScope.nodeWebkitVersion = 'browser';
        }
    }
}());<file_sep>[toc]

# Préférences

Dans cette section, tu n'as que 3 parties à renseigner:
## Ton fichier base de données

c'est l'endroit où est stocké le fichier contenant tous tes documents Natao

## Ton identité

Les informations demandées, Nom, prénom et classe sont ceux qui pourront apparaître dans ton document, si tu choisis une feuille de style les affichant.

La feuille de style fournie par défaut "Contrôle" affiche ces informations.

## Ton thème

Ce n'est pas grand chose, mais pour que cela reste une expérience agréable, tu peux choisir un thème de couleur et en changer à ta convenance.

# Styles

Cette section te permet de modifier ou de créer les feuilles de style.

Elle est constituée de 2 panneaux:
* un éditeur Css, pour modifier la feuille de style.
* un panneau de visualisation te permettant de voir soit le rendu, soit le code HTML du document.

Dans une future version, j'essaierai de créer un assistant pour t'aider à modifier les feuilles de style sans connaissances de la syntaxe Css, ni du HTML. En attendant, c'est un passage obligé vers l'amélioration de tes documents. N'hésites pas à te faire aider.

# Structures

Cette dernière section te permet de manipuler les structures de dossiers. Ce sont les mêmes outils que dans l'éditeur normal, sauf que tu ne peux pas y créer de documents. Tu pourras donc facilement modifier tes modèles de structure préférés avant de les réutiliser dans l'éditeur.

# Autres
Cette dernière section te permet de faire 2 choses:
- Activer les boutons de visite guidée pour pouvoir les rejouer à volonté.
- Importer les fichier de l'aide dans *Documents*, tu pourras ainsi les éditer, les imprimer, etc.<file_sep>(function () {
    "use strict";

    var uuid = require('node-uuid');
    var fse = require('fs-extra');
    var path = require('path');

    angular
        .module('Natao')
        .controller('EditorController', EditorController);

    function EditorController($timeout,$translate,PreferencesService,PrincipalTreeService,TrashTreeService,TreeUtilService,CssService,TemplateTreeService,
                              focus,fileDialog,$location,DocumentsService,$rootScope,MessageService,OnBoardingService,CodeMirrorUtilService, AppStateService, ShowDownUtilService) {

        var self = this;
        self.$timeout = $timeout;
        self.$translate = $translate;
        self.PreferencesService = PreferencesService;
        self.PrincipalTreeService = PrincipalTreeService;
        self.TrashTreeService = TrashTreeService;
        self.TreeUtilService = TreeUtilService;
        self.CssService = CssService;
        self.TemplateTreeService = TemplateTreeService;
        self.DocumentsService = DocumentsService;
        self.$rootScope = $rootScope;
        self.fileDialog = fileDialog;
        self.$location = $location;
        self.MessageService = MessageService;
        self.OnBoardingService = OnBoardingService;
        self.CodeMirrorUtilService = CodeMirrorUtilService;
        self.ShowDownUtilService = ShowDownUtilService;
        self.AppStateService = AppStateService;
        self.MessageService.changeMessage('');
        self.focus = focus;
        self.editorOptions = {
            lineWrapping : true,
            lineNumbers: true,
            foldGutter: true,
            gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
            mode: 'gfm'
        };
        self.buttonTextActive = false;
        self.showTrash = false;
        self.switchTrashOpened = false;
        self.searchPanelOpen = false;
        self.occurrencesFound = 0;
        self.searchEditorWord = '';
        self.replaceEditorWord = '';

        //Init of the current Markdown
        if (self.PrincipalTreeService.principalTree.currentMarkdownId) {
            self.DocumentsService
                .findDocument(self.PrincipalTreeService.principalTree.currentMarkdownId)
                .then(function(docs) {
                    self.currentMarkdown = docs[0];
                    self.CssService.initCurrentById(self.currentMarkdown.css);
                    MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
                }).catch(function(err) {
                    console.error(err);
                });
        }

        // to ensure that the  wil open in a browser not in Natao
        // We have to watch the current markdown and force the behavior of all
        self.$rootScope.$watch(function(){
            return self.currentMarkdownCode;
        },function() {
            self.ShowDownUtilService.showDownHooks();
        });

        /**
         * switch visibility of search panel
         */
        self.switchSearch = function() {
            self.$timeout(function() {
                self.searchPanelOpen = !self.searchPanelOpen;
                if (!self.searchPanelOpen) {
                    self.occurrencesFound = 0;
                    self.searchEditorWord = '';
                    self.replaceEditorWord = '';
                    self.CodeMirrorUtilService.clearSearch();
                }
            },0);  //with angular $digest sometimes it will be called by codemirror

        };

        //catch after editor loaded
        self.codeMirrorLoaded = function(editor) {
            self.codeMirror = editor;

            //This will synchronize the 2 scrollbar
            var elements = $('.CodeMirror-vscrollbar');
            //var avgScroll = 0;
            var ratioTop = 0;
            elements.on('scroll', function(e){

                if (self.PreferencesService.preferences.syncScroll) {
                    if (e.isTrigger){
                        //e.target.scrollTop = Math.round(avgScroll * e.target.scrollHeight - e.target.clientHeight / 2);
                        e.target.scrollTop = Math.round((e.target.scrollHeight - e.target.clientHeight) * ratioTop);
                    }else {
                        //avgScroll = (e.target.scrollTop + e.target.clientHeight / 2) / e.target.scrollHeight;
                        ratioTop = e.target.scrollTop / (e.target.scrollHeight - e.target.clientHeight);

                        elements.each(function (element) {
                            if( !this.isSameNode(e.target) ){
                                $(this).trigger('scroll');
                            }
                        });
                    }
                }
            });

            self.CodeMirrorUtilService.init(self.codeMirror);

            CodeMirror.commands.find = self.switchSearch;

        };

        /**
         * execute search of searchEditorWord
         */
        self.searchCodeMirror = function() {
            if (self.searchEditorWord.length > 0) {
                self.CodeMirrorUtilService.startSearch(self.searchEditorWord);
                self.CodeMirrorUtilService.findNext();

                self.occurrencesFound = self.CodeMirrorUtilService.occurrences(self.currentMarkdown.md, self.searchEditorWord);
            } else {
                self.occurrencesFound = 0;
                self.CodeMirrorUtilService.clearSearch();
            }

        };

        /**
         * find next word
         */
        self.findNext = () => {
            self.CodeMirrorUtilService.findNext();
        };

        /**
         * find previous word
         */
        self.findPrevious = () => {
            self.CodeMirrorUtilService.findNext(true);
        };

        /**
         * execute replace with replaceEditorWord
         */
        self.replace = function() {
            self.occurrencesFound--;
            self.CodeMirrorUtilService.replace(self.replaceEditorWord);
        };

        /**
         * execute replaceAll with replaceEditorWord
         */
        self.replaceAll = function() {
            self.CodeMirrorUtilService.replaceAll(self.replaceEditorWord);
            self.occurrencesFound = 0;
        };

        /**
         * add some data at cursor position
         * @param data
         */
        self.updateCodeMirror = function(data){

            var doc = self.codeMirror.getDoc();
            var cursor = doc.getCursor(); // gets the line number in the cursor position
            var line = doc.getLine(cursor.line); // get the line contents
            var pos = { // create a new object to avoid mutation of the original selection
                line: cursor.line,
                ch: line.length - 1 // set the character position to the end of the line
            };
            doc.replaceRange('\n'+data+'\n', pos); // adds a new line
        };

        /**
         * add image in Natao_images folder
         * and write the markdown for it
         */
        self.addImage = function() {

            var dbLocation = path.dirname(self.PreferencesService.settings.fileDatabase);
            var imagePath = path.join(dbLocation, 'Natao_images');

            self.fileDialog.openFile(function(filePath) {

                fse.ensureDir(imagePath, function (err) {

                    if (err) {
                        console.error(err);
                    } else {
                        var fileNameSource = path.basename(filePath);
                        var filePathDest = '';

                        var imgDirContent = fse.readdirSync(imagePath);

                        if (imgDirContent.indexOf(fileNameSource) >= 0) {
                            //the file already exist so we give the dest a new name
                            var fileExtension = path.extname(filePath);
                            var fileName = path.basename(filePath, fileExtension).substring(0,50);

                            filePathDest = path.join(imagePath, fileName + uuid.v4() + fileExtension);

                        } else {
                            filePathDest = path.join(imagePath, path.basename(filePath));
                        }

                        fse.copy(filePath, filePathDest, function(err) {
                            if (err) {
                                console.error(err);
                            } else {
                                // finally when image imported we ca add it to the doc
                                self.updateCodeMirror('![newImage](file:' + filePathDest.replace(/ /g,'%20') +')')
                            }
                        });
                    }
                });
            }, false,['image/jpeg','image/png']);
        };

        self.refresh = function() {
            // to avoid save too frequent with autosave at each change, we use a timeout at 1s.
            //each time this function is called, the timeout restart
            if (self.refreshTimeout) {
                clearTimeout(self.refreshTimeout);
            }
            self.refreshTimeout = setTimeout(function() {
                self.refreshTimeout = null;
                self.saveCurrentMarkdown();

                // if any change in the editor when searching
                // we need to update the search counter
                if (self.searchPanelOpen) {
                    self.occurrencesFound = self.CodeMirrorUtilService.occurrences(self.currentMarkdown.md, self.searchEditorWord);
                }

                //this one is for the watcher of
                self.currentMarkdownCode = self.currentMarkdown.md;
            },1000);

        };

        self.refreshMath = function() {
            MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
        };

        self.saveCurrentMarkdown = function() {

            if (self.currentMarkdown) {
                self.CssService.initCurrentById(self.currentMarkdown.css);

                self.DocumentsService
                    .updateDocument(self.currentMarkdown)
                    .then(function(doc) {
                        self.PrincipalTreeService.principalTree.selectedNode.name = doc.title;

                        self.PrincipalTreeService.save();
                        setTimeout(self.refreshMath, 100);  //without angular $digest
                    })
                    .catch(function(err) {
                        console.error(err);
                    });
            }
        };

        self.selectNode = function(node) {
            if (node.leaf) {
                if ((!self.showTrash && ( !self.PrincipalTreeService.principalTree.currentMarkdownId || (self.PrincipalTreeService.principalTree.currentMarkdownId && node.id !== self.PrincipalTreeService.principalTree.currentMarkdownId)))
                || (self.showTrash && ( !self.TrashTreeService.trashTree.currentMarkdownId || (self.TrashTreeService.trashTree.currentMarkdownId && node.id !== self.TrashTreeService.trashTree.currentMarkdownId)))) {

                    self.loadDocument(node.id);

                }
            }
        };

        /**
         * load document in the codemirror editor
         * @param id
         */
        self.loadDocument = function(id) {
            self.DocumentsService
                .findDocument(id)
                .then(function(docs){
                    if (docs && docs.length > 0){
                        self.currentMarkdown = docs[0];
                        //this one is for the watcher of
                        self.currentMarkdownCode = self.currentMarkdown.md;
                        self.ShowDownUtilService.showDownHooks();
                        self.CssService.initCurrentById(self.currentMarkdown.css);

                        if (self.showTrash) {
                            self.TrashTreeService.trashTree.currentMarkdownId = self.currentMarkdown._id;
                            self.TrashTreeService.save();
                        } else {
                            self.PrincipalTreeService.principalTree.currentMarkdownId = self.currentMarkdown._id;
                            self.PrincipalTreeService.save();
                        }
                        setTimeout(self.refreshMath, 100);  //without angular $digest
                    }
                })
                .catch(function(err){
                    console.error(err);
                });
        };

        //select current selected node if necessary
        if(self.PrincipalTreeService && self.PrincipalTreeService.principalTree && self.PrincipalTreeService.principalTree.selectedNode) {
            self.selectNode(self.PrincipalTreeService.principalTree.selectedNode);
        }

        self.showViewer = function() {
            //return self.currentMarkdown && self.PreferencesService.preferences.showViewer;
            return self.PreferencesService.preferences.showViewer;
        };

        self.showEditor = function() {
            //return self.currentMarkdown && self.PreferencesService.preferences.showEditor;
            return self.PreferencesService.preferences.showEditor;
        };

        self.print = function() {
            self.PreferencesService.preferences.showViewer = true;
            setTimeout(window.print, 1050);       //without angular $digest
            self.$timeout(self.offPrint, 1150);  //with angular $digest
        };

        self.openClassPopover = function() {
            self.newClass = null;
            self.templateName = null;
            self.focus('newClassName');
        };

        self.addClassPopover = function(hide){
            if (self.newClass && self.newClass !== '') {
                self.PrincipalTreeService.addFolder(self.newClass,null,self.templateName);
            }
            hide();
        };

        // -------------------Folder Popover -----------------

        // the possible values of folderPopover are ['buttonBar','edit','addFolder','addDocument','delete','saveTemplate']

        self.changeButtonText = function(message) {
            self.MessageService.changeMessage(message);
        };

        self.openFolderPopover = function(node) {
            self.currentNode = node;
            self.newNameFolder = node.name;
            self.newDefaultCss = node.defaultCss;
            self.folderPopover = 'buttonBar';
            self.newColor = node.color;
        };

        self.pasteButtonDisabled = function() {
            return !(self.AppStateService.hasBuffer());
        };

        self.editFolder = function() {
            self.folderPopover = 'edit';
            self.focus('folderName');

        };

        self.openSaveTemplate = function() {
            self.folderPopover = 'saveTemplate';
            self.focus('templateName');
            self.templateName = null;

        };

        self.openAddFolder = function() {
            self.newFolderName = null;
            self.folderPopover = 'addFolder';
            self.templateName = null;
            self.focus('addFolderName');
        };

        self.openAddDocument = function() {
            self.folderPopover = 'addDocument';
            self.newDocumentName = null;
            self.focus('addDocumentName');
        };

        self.openDelete = function() {
            self.folderPopover = 'delete';
            self.cancel = false;
        };

        self.openConfirmTemplate = function() {
            self.folderPopover = 'confirmTemplate';
            self.cancel = false;
        };

        self.cancelAction = function(hide) {
            self.cancel = true;
            hide();
        };

        self.submitFolderPopover = function(hide){
            switch (self.folderPopover) {
                case 'edit':
                    self.saveFolder(hide);
                    break;
                case 'addFolder':
                    self.addFolder(hide);
                    break;
                case 'addDocument':
                    self.addDocument(hide);
                    break;
                case 'saveTemplate':
                    self.saveTemplate(hide);
                    break;
                case 'confirmTemplate':
                    if (!self.cancel) {
                        self.saveForceTemplate(hide);
                    } else {
                        hide();
                    }
                    break;
                case 'delete':
                    if (!self.cancel) {
                        self.putNodeInTrash(self.currentNode);
                    }
                    hide();
                    break;
                default: break;
            }
        };

        self.copyFolder = function(hide) {
            self.TreeUtilService
                .nodeToBuffer(self.currentNode)
                .then(function(buffer) {
                    self.AppStateService.setBuffer(buffer);
                })
                .catch(function(err) {
                    console.error(err);
                });
            hide();
        };

        self.copyDocument = function() {

            var documentNode = self.TreeUtilService.getNode(self.currentMarkdown._id,self.PrincipalTreeService.principalTree.tree);

            self.TreeUtilService
                .nodeToBuffer(documentNode)
                .then(function(buffer) {
                    self.AppStateService.setBuffer(buffer);
                })
                .catch(function(err) {
                    console.error(err);
                });
        };

        self.cutFolder = function(hide) {
            self.TreeUtilService
                .nodeToBuffer(self.currentNode)
                .then(function(buffer) {
                    self.AppStateService.setBuffer(buffer);
                    self.PrincipalTreeService
                        .deleteNode(self.currentNode)
                        .catch(function(err) {
                            console.error(err);
                        });
                })
                .catch(function(err) {
                    console.error(err);
                });
            hide();
        };

        self.cutDocument = function() {

            var documentNode = self.TreeUtilService.getNode(self.currentMarkdown._id,self.PrincipalTreeService.principalTree.tree);

            self.TreeUtilService
                .nodeToBuffer(documentNode)
                .then(function(buffer) {
                    self.AppStateService.setBuffer(buffer);
                    self.PrincipalTreeService
                        .deleteNode(documentNode)
                        .catch(function(err) {
                            console.error(err);
                        });
                })
                .catch(function(err) {
                    console.error(err);
                });
        };

        self.deleteDocument = function(hide) {

            var documentNode = self.TreeUtilService.getNode(self.currentMarkdown._id,self.PrincipalTreeService.principalTree.tree);

            self.putNodeInTrash(documentNode);
            self.PrincipalTreeService.principalTree.currentMarkdownId = null;
            self.currentMarkdown = null;

            hide();
        };

        self.exportDocument = function(hide) {

            hide();

            var defaultFile;
            var accept;

            switch (self.fileFormat) {
                case 'md':
                    defaultFile = self.currentMarkdown.title +'.md';
                    accept = 'text/markdown';
                    break;
                // json is the default file format
                default:
                    defaultFile = self.currentMarkdown.title +'.json';
                    accept = 'application/json';
                    break;
            }

            self.fileFormat = null;

            self.fileDialog.saveAs(function(filename) {

                var documentNode = self.TreeUtilService.getNode(self.currentMarkdown._id,self.PrincipalTreeService.principalTree.tree);

                self.TreeUtilService
                    .nodeToBuffer(documentNode)
                    .then(function(buffer) {
                        self.TreeUtilService
                            .bufferToFile(buffer,filename)
                            .catch(function(err) {
                                console.error(err);
                            })
                    })
                    .catch(function(err) {
                        console.error(err);
                    });

            },defaultFile,accept);

        };

        self.pasteFolder = function(hide) {

            if (self.AppStateService.hasBuffer()) {
                self.TreeUtilService
                    .bufferToNode(self.AppStateService.getBuffer())
                    .then(function(node) {
                        if (hide) {
                            // then the paste command is past from the tree
                            if (self.currentNode && self.currentNode.children) {
                                self.currentNode.children.push(node);
                            }
                            hide();
                        } else {
                            //the command was past by the toolbar
                            self.PrincipalTreeService.principalTree.tree.children.push(node);
                        }
                        self.AppStateService.resetBuffer();
                        self.PrincipalTreeService.save();

                    })
                    .catch(function(err) {
                        console.error(err);
                    });
            }
        };

        self.exportTo = function(hide) {
            self.fileDialog.saveAs(function(filename) {

                self.TreeUtilService
                    .nodeToBuffer(self.PrincipalTreeService.principalTree.selectedNode)
                    .then(function(buffer) {
                        self.TreeUtilService
                            .bufferToFile(buffer,filename)
                            .catch(function(err) {
                            console.error(err);
                        })
                    })
                    .catch(function(err) {
                        console.error(err);
                    });
                hide();
            },'nataoExport.json','application/json');
        };

        self.importFrom = function(hide) {

            var nodeIn;

            if (hide) {
                nodeIn = self.currentNode;
                hide();
            } else {
                nodeIn = self.PrincipalTreeService.principalTree.tree;
            }

            self.fileDialog.openFile(function(filename) {

                self.TreeUtilService
                    .fileToBuffer(filename)
                    .then(function(buffer) {

                        self.TreeUtilService
                            .bufferToNode(buffer)
                            .then(function(nodeToInsert) {
                                nodeIn.children.push(nodeToInsert);
                                self.expand(nodeIn);
                            })
                            .catch(function(err) {
                                console.error(err);
                            })

                    })
                    .catch(function(err) {
                        console.error(err);
                    })

            }, false,['text/markdown','application/json']);
        };

        self.saveTemplate = function(hide) {
            if (self.templateName && self.templateName.length > 0) {
                if (self.TemplateTreeService.getTemplate(self.templateName)) {
                    self.openConfirmTemplate();
                } else {
                    self.TemplateTreeService.saveTemplate(self.currentNode,self.templateName);
                    hide();
                }
            }
        };

        self.saveForceTemplate = function(hide) {
            self.TemplateTreeService.saveTemplate(self.currentNode,self.templateName);
            hide();
        };

        self.addFolder = function(hide) {
            if (self.newFolderName && self.newFolderName.length > 0) {
                self.PrincipalTreeService
                    .addFolder(self.newFolderName, self.currentNode, self.templateName)
                    .catch(function(err) {
                        console.error(err);
                    });
            }
            hide();
        };

        self.saveFolder = function(hide) {
            if (self.newNameFolder && self.newNameFolder.length > 0) {
                self.currentNode.name = self.newNameFolder;
                self.currentNode.color = self.newColor;
                self.currentNode.defaultCss = self.newDefaultCss;
                self.PrincipalTreeService.save();
            }
            hide();
        };

        self.addDocument = function(hide) {
            if (self.newDocumentName && self.newDocumentName.length > 0) {

                self.DocumentsService
                    .addDocument(self.currentNode.defaultCss,self.newDocumentName)
                    .then(function(newDoc) {
                        var newNode = {
                            id: newDoc._id,
                            name: newDoc.title,
                            leaf: true
                        };

                        self.currentNode.children.push(newNode);
                        self.PrincipalTreeService.principalTree.selectedNode = newNode;
                        self.selectNode(newNode);
                    })
                    .catch(function(err) {
                        console.error(err);
                    });
            }
            hide();
        };

        /* ************* Drag Drop ********/
        self.handleDrop = function(item, bin) {

            var nodeDrag = self.TreeUtilService.getNode(item,self.PrincipalTreeService.principalTree.tree);
            var nodeDrop = null;

            if (bin.startsWith('before')) {
                nodeDrop = self.TreeUtilService.getNode(bin.replace('before',''),self.PrincipalTreeService.principalTree.tree);
                self.TreeUtilService.moveBefore(nodeDrag,nodeDrop,self.PrincipalTreeService.principalTree.tree);
            } else {
                if (bin.startsWith('after')) {
                    nodeDrop = self.TreeUtilService.getNode(bin.replace('after',''),self.PrincipalTreeService.principalTree.tree);
                    self.TreeUtilService.moveAfter(nodeDrag,nodeDrop,self.PrincipalTreeService.principalTree.tree);
                } else {
                    nodeDrop = self.TreeUtilService.getNode(bin,self.PrincipalTreeService.principalTree.tree);
                    self.TreeUtilService.moveIn(nodeDrag,nodeDrop,self.PrincipalTreeService.principalTree.tree);
                    self.expand(nodeDrop);
                }
            }
        };

        self.expand = function(node) {
            if (self.PrincipalTreeService.principalTree.expandedNodes.indexOf(node) < 0) {
                self.PrincipalTreeService.principalTree.expandedNodes.push(node);
            }
        };

        self.isFirstChild = function(node) {
            return self.TreeUtilService.isFirstChild(node,self.PrincipalTreeService.principalTree.tree);
        };

        self.isExpanded = function(node) {
            return self.PrincipalTreeService.principalTree.expandedNodes && self.PrincipalTreeService.principalTree.expandedNodes.indexOf(node) >= 0;
        };

        self.showAfter = function(node) {
            return !(self.isExpanded(node) && node.children.length > 0);
        };

        /* *********** Editor Setting *************/
        self.changeSpace = function () {
            self.PreferencesService.savePreferences();
            var markdown = self.currentMarkdown;
            self.currentMarkdown = null;

            self.$timeout(function() {
                self.currentMarkdown = markdown;
            },100);

        };

        /************onBoarding ******/
        self.onBoardingSteps = self.OnBoardingService.getSteps('Editor').steps;

        self.onboardingEnabled = self.OnBoardingService.startFirstTour('Editor');

        self.finishTour = function() {
            self.OnBoardingService.finishTour('Editor');
            self.onboardingEnabled = false;
        };

        self.startTour = function() {
            if (self.currentMarkdown) {
                self.PreferencesService.preferences.showMenu = true;
                self.PreferencesService.preferences.showViewer = true;
                self.PreferencesService.preferences.showEditor = true;
                self.onboardingIndex = 0;
                self.onboardingEnabled = true;
            }
        };

        /************** Trash ***************/
        /**
         * switch trash/schoolbag
         */
        self.switchTrash = function(hidePopover) {
            self.showTrash = !self.showTrash;
            self.changeButtonText('');

            // We have to switch the current document
            if (self.showTrash) {

                if (self.TrashTreeService.trashTree.currentMarkdownId) {
                    self.loadDocument(self.TrashTreeService.trashTree.currentMarkdownId);
                } else {
                    self.currentMarkdown = null;
                }

                self.codeMirror.setOption("readOnly", true);
            } else {

                if (self.PrincipalTreeService.principalTree.currentMarkdownId) {
                    self.loadDocument(self.PrincipalTreeService.principalTree.currentMarkdownId);
                }else {
                    self.currentMarkdown = null;
                }

                self.codeMirror.setOption("readOnly", false);
            }

            hidePopover();

        };

        /**
         * open the switch and turn the arrow down
         */
        self.openSwitchTrash = function() {
            self.switchTrashOpened = true;
        };

        /**
         * close the switch and turn the arrow left
         */
        self.closeSwitchTrash = function() {
            self.switchTrashOpened = false;
        };

        /**
         * put the ndde in trash and keep safe documents
         * @param node
         */
        self.putNodeInTrash = function(node) {
            var nodeFrom = self.TreeUtilService.findParent(node, self.PrincipalTreeService.principalTree.tree);
            node.nodeFromId = nodeFrom.id;
            self.TrashTreeService.addNode(node);
            self.TreeUtilService.eraseNode(node,self.PrincipalTreeService.principalTree.tree);

            // And finally we save in the good order
            self.TrashTreeService.save();
            self.PrincipalTreeService.save();
        };

        /**
         * open the trash popover and set the current node
         * @param node
         */
        self.openTrashPopover = function(node) {
            self.currentNode = node;
            self.trashPopover = 'buttonBar';
        };

        /**
         * set the popover on delete mode
         */
        self.openTrashDelete = function() {
            self.trashPopover = 'delete';
        };

        /**
         * real delete of a node
         */
        self.trashDelete = function() {
            self.TrashTreeService.deleteNode(self.currentNode);
        };

        /**
         * restore the current node
         * @param node
         */
        self.restoreNode = function(node) {
            var topParent = self.TrashTreeService.getHighestParent(node);
            var nodeWhereRestore = self.TreeUtilService.getNode(topParent.nodeFromId,self.PrincipalTreeService.principalTree.tree);

            var path = self.TreeUtilService.getPath(topParent, node);
            path.push(node.id);

            //follow the path to restore the node
            var jobDone = false;
            while (!jobDone) {
                if (path[0] === node.id) {
                    // here the current node in the path is the node to restore
                    // we must check if it was partially restored
                    // if then restore only children not in principal tree

                    var nodeInPrincipalTree = self.TreeUtilService.getNode(path[0], self.PrincipalTreeService.principalTree.tree);
                    if (nodeInPrincipalTree) {
                        self.TreeUtilService.mergeNodes(nodeInPrincipalTree, node);
                    } else {
                        nodeWhereRestore.children.push(node);
                    }
                    jobDone = true;
                } else {
                    var foundNode = nodeWhereRestore.children.find(function(item) {
                        return item.id === path[0]
                    });
                    if (foundNode) {
                        // the node already exist so don't need to restore it
                        nodeWhereRestore = foundNode;
                    } else {
                        // we have to partially restore the node without children
                        var nodeInTrash = self.TreeUtilService.getNode(path[0], self.TrashTreeService.trashTree.tree);
                        var nodeToRestore = {};
                        angular.copy(nodeInTrash, nodeToRestore);
                        delete nodeToRestore.nodeFromId;
                        nodeToRestore.children = [];
                        nodeWhereRestore.children.push(nodeToRestore);
                        nodeWhereRestore = nodeToRestore;
                    }
                    path.shift();
                }
            }

            //When restored delete the node from the trash
            var parentNode = self.TreeUtilService.findParent(node, self.TrashTreeService.trashTree.tree);
            parentNode.children = parentNode.children.filter(function(item) {
                return item.id !== node.id;
            });

            self.PrincipalTreeService.save();
            self.TrashTreeService.save();
        };

        /**
         * restore a folder
         * @param hidePopover
         */
        self.restoreFolder = function(hidePopover) {
            self.restoreNode(self.currentNode);

            hidePopover();
        };

        /**
         * restore a document
         */
        self.restoreDocument = function() {
            var nodeToRestore = self.TreeUtilService.getNode(self.currentMarkdown._id, self.TrashTreeService.trashTree.tree);
            self.TrashTreeService.trashTree.currentMarkdownId = null;
            self.restoreNode(nodeToRestore);

            self.currentMarkdown = null;
        };

    }

}());<file_sep>(function () {
    "use strict";

    angular
        .module('Natao')
        .config(AppConfig);

    function AppConfig($translateProvider,tmhDynamicLocaleProvider, $locationProvider, $showdownProvider) {

        $locationProvider.html5Mode({
            enabled: true,
            requireBase: false
        }).hashPrefix('!');

        $showdownProvider.loadExtension(toc);

        $translateProvider.useStaticFilesLoader({
            prefix: './languages/locale-',
            suffix: '.json'
        }).registerAvailableLanguageKeys(['en', 'fr'], {
            'en*': 'en',
            'fr*': 'fr'
        }).determinePreferredLanguage(function() {
            if (!window.navigator.languages[0].startsWith(window.navigator.language)) {
                return window.navigator.language;
            } else {
                return window.navigator.languages[0];
            }
            }).fallbackLanguage(['en']);

        //$translateProvider.useSanitizeValueStrategy('sanitize');
        $translateProvider.useSanitizeValueStrategy('escape');

        tmhDynamicLocaleProvider.localeLocationPattern('./bower_components/angular-i18n/angular-locale_{{locale}}.js');

    }

    var toc = function(converter) {
        return [

            {
                type: 'output',
                filter: function(source) {

                    var tocHtml;

                    if (source.indexOf('[toc]') > 0) {
                        var elements = $('

');
                        elements.html(source);
                        var titles = $('h1,h2,h3,h4,h5,h6', elements);

                        tocHtml = '
';

                        var previousLevel = 0;
                        var currentLevel = 0;

                        titles.each((index, item) => {
                            currentLevel = parseInt(item.nodeName.replace('H', ''));

                            if (previousLevel === 0) {
                                tocHtml = tocHtml + '
'+ item.textContent +'
';
                            } else {
                                if (currentLevel === previousLevel) {
                                    tocHtml = tocHtml + '
'+ item.textContent +'
';
                                } else {
                                    if (currentLevel >= previousLevel) {
                                        tocHtml = tocHtml + '
';
                                        tocHtml = tocHtml + '
'+ item.textContent +'
';

                                    } else {
                                        switch (previousLevel - currentLevel) {
                                            case 2: tocHtml = tocHtml + '

';
                                                break;
                                            case 3: tocHtml = tocHtml + '

';
                                                break;
                                            case 4: tocHtml = tocHtml + '

';
                                                break;
                                            case 5: tocHtml = tocHtml + '

';
                                                break;
                                            default: tocHtml = tocHtml + '
';
                                                break;
                                        }
                                        tocHtml = tocHtml + '
'+ item.textContent +'
';
                                    }
                                }

                            }
                            previousLevel = currentLevel;
                        });

                        // at the end we close all the ol
                        switch (currentLevel) {
                            case 2: tocHtml = tocHtml + '

';
                                break;
                            case 3: tocHtml = tocHtml + '

';
                                break;
                            case 4: tocHtml = tocHtml + '

';
                                break;
                            case 5: tocHtml = tocHtml + '

';
                                break;
                            default: tocHtml = tocHtml + '
';
                                break;
                        }

                    }
                    source = source.replace('
[toc]
', tocHtml);
                    return source;
                }
            }

        ];
    };

}());<file_sep>(function () {
    "use strict";

    var Rx = require('rx');

    angular
        .module('Natao')
        .service('AppStateService', AppStateService)
        .run(run);

    //Start of the service
    function run() {
    }

    //Service itself
    function AppStateService($q, DatabaseService) {

        var self = this;

        self.$q = $q;
        self.DatabaseService = DatabaseService;

        self.stateEvents = new Rx.Subject();
        self.pendingSaveState = false;
        self.waitToClose = false;

        self.appState = {
            docName: 'AppState',
            principalTree: {
                tree: {
                    defaultCss: null,
                    children: []
                },
                expandedNodes: [],
                selectedNode: null
            },
            trashTree: {
                tree: {
                    children: []
                },
                expandedNodes: [],
                selectedNode: null
            },
            buffer: null
        };

        // receive the save event and save when it's time
        self.stateEvents.filter(item => item === 'save')
            .debounce(300)
            .subscribe(() => {
                    self.DatabaseService.save(self.appState)
                        .then(() => {
                            self.pendingSaveState = false;
                            self.checkClose();
                        })
                        .catch((err) => {
                            self.pendingSaveState = false;
                            self.checkClose();
                            console.error(err);
                        });

                },
                (err) => {
                    console.error(err);
                },
                () => {
                    self.pendingSaveState = false;
                });

        /**
         * get a promise that init the state of the app
         * @returns {*}
         */
        self.initAppState = () => {
            return self.$q(function(resolve,reject) {
                self.DatabaseService.find({docName:'AppState'})
                    .then(function(docs) {
                        if (docs.length === 0) {
                            self.DatabaseService
                                .save(self.appState)
                                .then(function(newDoc) {
                                    self.appState = newDoc;
                                    resolve();
                                })
                                .catch(function(err) {
                                    reject(err);
                                });
                        } else {
                            self.appState = docs[0];
                            resolve();
                        }
                    })
                    .catch(function(err) {
                        reject(err);
                    });
            });
        };

        /**
         * emit the save event
         */
        self.save = () => {
            self.pendingSaveState = true;
            self.stateEvents.onNext('save');
        };

        // ******************************* the trees ****************************************

        /**
         * return the principalTree from the appState
         * @returns {initialState.principalTree|{tree, expandedNodes, selectedNode}}
         */
        self.getPrincipalTree = function() {
            return self.appState.principalTree;
        };

        /**
         * set the principalTree
         * @param tree
         */
        self.setPrincipalTree = (tree) => {
            self.appState.principalTree = tree;
            self.save();
        };

        /**
         * return the trashTree from the appState
         * @returns {initialState.principalTree|{tree, expandedNodes, selectedNode}}
         */
        self.getTrashTree = () =>  {
            return self.appState.trashTree;
        };

        /**
         * set the trashTree
         * @param tree
         */
        self.setTrashTree = (tree) => {
            self.appState.trashTree = tree;
            self.save();
        };

        // ******************************* the buffer ****************************************

        /**
         * reset the buffer
         */
        self.resetBuffer = () => {
            self.appState.buffer = null;
            self.save();
        };

        /**
         * set a value in the buffer
         * @param buffer
         */
        self.setBuffer = (buffer) => {
            self.appState.buffer = buffer;
            self.save();
        };

        /**
         * return the currentBuffer
         * @returns {null|*}
         */
        self.getBuffer = () => {
            return self.appState.buffer;
        };

        /**
         * return true if buffer contains anything
         * @returns {boolean}
         */
        self.hasBuffer = () => {
            return self.appState.buffer !== null;
        };

        // ******************************* the saves in pendings ****************************************

        /*
        The precedent code follow the save in the same document appState
        here we will follow the write of the other documents: the markdown
        the object is to avoid close the apps before all writes are done
         */

        self.nbWritePendings = 0;

        /**
         * add a write action when asked
         */
        self.startWrite = () => {
            self.nbWritePendings++;
        };

        /**
         * remove a write action when finished
         */
        self.stopWrite = () => {
            self.nbWritePendings--;
            self.checkClose();
        };

        // ***************************** wait for the end of saves ************************************

        /**
         * prepare to close and return the events
         * @returns {Rx.Subject}
         */
        self.close = () => {
            self.waitToClose = true;
            self.checkClose();
            return self.stateEvents;
        };

        /**
         * emit complete en the stateEvents when all is saved
         */
        self.checkClose = () => {
            if (self.waitToClose && !self.pendingSaveState && self.nbWritePendings === 0){
                self.stateEvents.onCompleted();
            }
        };

        return self;

    }

}());
<file_sep>@import 'variables';
@import 'layout';
@import 'opendyslexic';
@import 'themeMixin';
@import 'spinner';
@import '../../bower_components/nsPopover/sass/ns-popover';

html, body {
  height: 100%;
  padding: 0;
  margin: 0;
  overflow: hidden;
  font-size: $font-size;
  color: #000;
  font-family: $font-family;

  &.dyslexic {
    font-family: opendyslexic !important;

    textarea {
      font-family: opendyslexic !important;
    }

    .tree-label {
      span {
        font-family: opendyslexic !important;
      }
    }

    .ace_text-layer {
      font-family: opendyslexic !important;
    }

    .CodeMirror {
      font-family: opendyslexic !important;
    }
  }
}

input {
  font-size: $font-size;
}

select {
  font-size: $select-font-size;
}

.ns-popover-tooltip {
  max-width: 100rem !important;
}

//hack for MathJax when opendyslexic is on
.MathJax {
  font-family: $font-family;
}

// A tester plus tard
/*@page {
  size: A4;
  //margin: 30mm 45mm 30mm 45mm; /* change the margins as you want them to be.
}*/

button,.button {

  padding: 1px 7px 5px 7px;
  margin: 5px;
  font-size: 1.5em;
  border-radius: 5px;
  border: none;
  color:white;

  cursor: pointer;

  &.small {
    padding: 1px 3px;
    margin: 2px;
    font-size: 1.2em;
  }

  &.black {
    color: black;
  }

  &:focus {
    outline: none;
  }

  &.toggle {
    padding: 1px 5px 5px 5px;
    border: solid 2px;
    border-radius: 30px;
  }

  &.help {
    padding: 1px 15px 5px 15px;
  }

  &.text {
    padding: 2px 6px 3px 6px;
    font-size: 1.2em;
  }

}

.buttonText {
  font-size: 1.6em;
  min-height: 1.2em;
  margin-top: 0.5em;
}

.bandeau {
  background-color: black;
  color:white;
  height: 50px;
  min-height: 50px;

  button {
    font-size: 1.7em;
  }

  .buttonText {
    min-width: 500px;
    width: 500px;

  }

}

.buttonText {
  margin-top: 0;
  text-align: center;
  visibility: hidden;
  opacity: 0;
  transition: visibility 1s, opacity 1s;

  &.active {
    visibility: visible;
    opacity: 1;
    transition: visibility 1s, opacity 1s;
  }
}

/* ************************ fields ******************/
.allInOne {
  input {
    margin-right: 0;
  }

  button {
    margin-left: 0;
    border-radius: 0;
    font-size: 1.2em;
  }
}

.principal {
  position: relative;
}

.left-panel {
  //width: 300px;
  opacity: 1;
  transition: opacity 1s;
  &.hidden {
    opacity: 0;
    transition: opacity 1s;
  }
}

.buttonBar {
  button,.button {
    margin: 2px;
  }
}

.menu {
  color:white;
  width: 300px;
  //overflow-x: auto;
}

.files {
  width: 300px;
}

.content {
  position: absolute;
  top: 0;
  left: 0;
  right:0;
  bottom: 0;

  transition: all 1s;

  &.goright{
    left: 300px;

    transition: all 1s;
  }
}

.search-panel {
  height: 0;
  opacity: 0;

  transition: all 1s;

  &.show {
    height: 102px;
    opacity:1;

    transition: all 1s;
  }
}

.editor {
  flex-grow:1;
  opacity: 1;
  margin: 10px;

  transition: all 1s;

  &.hidden {
    flex-grow:0.0001;
    opacity:0;
    transition: all 1s;
  }
}

.viewer {
  flex-grow:1;
  background-color: white;
  overflow: auto;
  box-shadow: 0px 10px 32px 0px rgba(0,0,0,0.75);
  margin: 10px;
  padding: 10px;
  opacity:1;
  position: relative;

  & > div {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
  }

  &.inprint {
    box-shadow: none;
    margin: 0;
    padding: 0;
  }

  transition: all 1s;

  &.hidden {
    width: 0;
    flex-grow:0.0001;
    opacity:0;
    margin: 0;
    padding: 0;
    transition: all 1s;
  }
}

.viewerHelp {
  overflow-y: auto;
}

/* ****************** codeMirror **********************/
ui-codemirror, div[ui-codemirror] {
  position: relative;

  &.space {
    .CodeMirror {
      Line-Height: 2;
    }
  }

  &.striped {
    .CodeMirror-code > div:nth-child(even) {
      background: whitesmoke;
    }
    .CodeMirror-code > div:nth-child(odd) {
      background: white;
    }

  }

}

.CodeMirror {
  border: 1px solid silver;
  height: auto;

  &.CodeMirror-wrap,&.cm-s-default {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
  }

  .cm-header {
    font-family: arial;
  }
  .cm-header-1 {
    font-size: 150%;
  }
  .cm-header-2 {
    font-size: 130%;
  }
  .cm-header-3 {
    font-size: 120%; }
  .cm-header-4 {
    font-size: 110%;
  }
  .cm-header-5 {
    font-size: 100%;
  }
  .cm-header-6 {
    font-size: 90%;
  }
  .cm-strong {
    font-size: 140%;
  }

}

/*********************** Base ***************************/
input,p{
  margin: 10px;
}

/*********************** Setting ************************/
.setting {
  margin: 10px;

  h1 {
    color: black;
    font-size: 24px;
  }

  .viewer {
    margin: 10px 0 0 10px;
  }

}
.tab-content {
  .tab-pane {
    display:none;

    &.active {
      display:flex;
    }
  }
}

.nav-tabs {
  width: 150px;
  margin: 0;
  list-style-type: none;
  padding: 0px;

  li {
    padding: 10px 2px;
    border-bottom: 1px solid;
    cursor: pointer;

    span {
      font-size: 1.5em;
    }
  }
}

.flexTable {
  width: 100%;
  height: 100%;
  tbody {
    tr {
      border-bottom: 1px solid #ddd;
      &:last-child {
        border-bottom: 0px;
      }

      td {
        padding: 10px;
      }
    }
  }
}

.chooser {
  margin: 10px;
}

.horizontal-flow {
  overflow-x: auto;
  position: relative;

  div {
    position: absolute;
    left: 0;
    bottom: 0;
    top: 0;
  }
}

hr {
  border: 0;
  height: 1px;
  width: 100%;
  background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));
}

.lineField {
  height: 3em;
  min-height: 3em;
}

.templateContainer {
  position: relative;

  treecontrol {
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
  }
}

/********************** First Times Setting ***********/
.firstTimeSetting {
  font-size: 1.2em;

  position: relative;
  background-color: map-get($blueTheme, ML);

  #background {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    opacity: 0.1;
    background-image: url("../../natao.png");
    background-repeat: no-repeat;
    background-position:center center;
  }

  #content {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    perspective: 1000;
    z-index: 1;

    .flip-card {
      width: 100%;
      height: 100%;
      transform-style: preserve-3d;
      transition: all 1.0s linear;

      .face {
        position: absolute;
        width: 100%;
        height: 100%;
        backface-visibility: hidden;

        &.back {
          display: block;
          transform: rotateY(180deg);
        }
      }
    }

    &.flip .flip-card {
      transform: rotateY(180deg);
    }
  }
}

.slideContainer {

  position: relative;
  height: 60vh;
  margin-top: 20vh;

  .slideContent {
    position: absolute;

    transition:all 1.0s ease-in-out;

    .slide {
      width: 100vw;
    }

    &.step1 {
      transform: translateX(-100vw);
      transition:all 1.0s ease-in-out;
    }
  }

}

#crumbs{
  ul {
    li {
      display: inline;

      p {
        display: block;
        float: left;
        text-align: center;
        padding: 10px 40px 10px 60px;
        position: relative;
        margin: 0 10px 0 0;

        font-size: 20px;
        text-decoration: none;
        color: #fff;

        &:after {
          content: "";
          border-top: 22px solid transparent;
          border-bottom: 22px solid transparent;
          position: absolute;
          right: -22px;
          top: 0;
          z-index: 1;
        }

        &:before {
          content: "";
          border-top: 22px solid transparent;
          border-bottom: 22px solid transparent;
          position: absolute;
          left: 0;
          top: 0;
        }
      }

      &:first-child {
        p {
          border-top-left-radius: 10px;
          border-bottom-left-radius: 10px;

          &:before {
            display: none;
          }
        }
      }

      &:last-child {
        p {
          padding-right: 60px;
          border-top-right-radius: 10px;
          border-bottom-right-radius: 10px;

          &:after {
            display: none;
          }

        }
      }
    }
  }
}

#crumbs ul li:last-child a:after {
  display: none;
}

/***********************TreeView***********************/

.treeContainer {
  position: relative;
  background-color: white;
  overflow-x: auto;
  overflow-y: auto;
}

treecontrol {
  position: absolute;
}

/***********************DragDrop***********************/
.drag {
  opacity: 0.5;
}

.over {
  font-weight: bold;
}

.anchor {
  position: relative;
  //background-color: red;

  .before {
    position: absolute;
    top: -0.1em;
    left: 0;
    right: 0;
    min-height: 0.24em;
    display: inline-block;

    hr {
      border: 0;
      height: 1px;
      width: 100%;
      margin: 0;
      background-image: none;
    }

    &.over {
      hr {
        border-bottom: solid 2px;
      }
    }

  }

  .after {
    position: absolute;
    top: 1.24em;
    left: 0;
    right: 0;
    min-height: 0.24em;
    display: inline-block;

    hr {
      border: 0;
      height: 1px;
      width: 100%;
      margin: 0;
      background-image: none;
    }

    &.over {
      hr {
        border-bottom: solid 2px;
      }
    }
  }

}

/********************* Check Mark *********************/

#check {
  fill: none;
  stroke: green;
  stroke-width: 20;
  stroke-linecap: round;
  stroke-dasharray: 180;
  stroke-dashoffset: 180;
  animation: draw 2s ease forwards;
}
@keyframes draw {
  to {
    stroke-dashoffset: 0;
  }
}

/***********************ColorChooser*****************/
.chooser-purple {
  @include color-square($purpleTheme);
}

.chooser-blue {
  @include color-square($blueTheme);
}

.chooser-red {
  @include color-square($redTheme);
}

.chooser-orange {
  @include color-square($orangeTheme);
}

.chooser-green {
  @include color-square($greenTheme);
}

.chooser-grey{
  @include color-square($greyTheme);
}
.chooser-pink{
  @include color-square($pinkTheme);
}

/**************************Themes********************/
.purple {
  @include color-theme($purpleTheme);
}

.blue {
  @include color-theme($blueTheme);
}

.red {
  @include color-theme($redTheme);
}

.pink {
  @include color-theme($pinkTheme);
}

.orange {
  @include color-theme($orangeTheme);
}

.green {
  @include color-theme($greenTheme);
}

.grey {
  @include color-theme($greyTheme);
}

<file_sep>(function () {
    "use strict";

    var fs = require('fs');

    angular
        .module('Natao')
        .controller('FirstTimeSettingsController', FirstTimeSettingsController);

    function FirstTimeSettingsController($rootScope,$scope,PreferencesService,DatabaseService,$location,$translate,$sce,fileDialog) {

        var self = this;

        self.PreferencesService = PreferencesService;
        self.$sce = $sce;
        self.DatabaseService = DatabaseService;
        self.$scope = $scope;

        self.fileDialog = fileDialog;

        self.step = 1;
        self.nameValid = false;

        self.PreferencesService.preferences.colorTheme = 'blue';

        $translate('SETTING_MESSAGE').then(function (translation) {
            self.welcomeMessage = translation;
        });

        $translate('SETTING_MESSAGE_DATABASE').then(function (translation) {
            self.databaseMessage = translation;
        });

        $translate('SETTING_MESSAGE_NAME').then(function (translation) {
            self.identityMessage = translation;
        });

        self.settingsValid = function() {
            if (self.PreferencesService.isValid()) {
                self.save();
            }
        };

        self.changeName = function() {
            if (self.PreferencesService.preferences.name && self.PreferencesService.preferences.firstName && self.PreferencesService.preferences.className
                && self.PreferencesService.preferences.name !== '' && self.PreferencesService.preferences.firstName !== '' && self.PreferencesService.preferences.className !== '') {
                self.nameValid = true;
            }
        };

        self.nextName = function() {
            self.step = 3;
        };

        self.previousColor = function() {
            self.step = 2;
        };

        self.save = function() {
            self.PreferencesService
                .save()
                .then(function() {
                    $location.path( '/loading' );
                })
                .catch(function(err) {
                    console.error(err);
                });

        };

        self.newDatabase = function() {
            self.fileDialog.saveAs(function(filename) {
                self.PreferencesService.settings.fileDatabase = filename;
                if (fs.existsSync(filename)) {
                    fs.unlinkSync(filename);
                }
                self.step = 2;
                self.$scope.$apply();
            },'Natao.db',['db']);
        };

        self.chooseDatabase = function() {
            self.fileDialog.openFile(function(filename){
                self.PreferencesService.settings.fileDatabase = filename;
                self.PreferencesService.saveSettings();
                self.PreferencesService.init();
            }, false, ['db']);
        };

        self.showMessage = function() {
            return (self.step > 0)
        };

        self.showFile = function() {
            return (self.step === 1)
        };

        self.showId = function() {
            return (self.step === 2)
        };

        self.showColor = function() {
            return (self.step === 3)
        };

    }

}());<file_sep>[toc]

# Introduction

The following document does not explain in detail how CSS works. It only describes how CSS works within Natao, with the express purpose of making it easy to change the appearance of documents produced within Natao.

Although this document's scope is limited, a few notions related to XML and HTML coding need to be explained nonetheless, even before we start discussing CSS. You may find it difficult to wrap your mind around some of these notions. Therefore, don't hesitate to seek the help of a person already familiar with CSS who might be able to help you customize your Natao style-sheets for you.

Ready? Ok. Let's start with HTML.

# Basic HTML

One needs to understand how Natao's documents are constructed, and, for that, one needs to know about HTML, which is used to structure Natao produced documents; CSS is used to change the appearance of that structure.

HTML is about displaying data or information. But to display such information or data, one has control and understand it. This is where XML comes in as it describes data, as well as it stores data within HTML. In that respect, XML is a complement of the HTML syntax.

## XML

### Tags

The XML language sets rules that help programs such as Natao encode and format documents in an easily readable manner.

To write an XML document that works, one must define which elements of the document appear within it, and how.

To do so, tags are used. These are case sensitive and are written between less-than ( < ) and greater-than signs ( > ), like so: <paragraph> or

Usually, all tags within a XML text appear in pairs: once as an opened tag, and once as a closed tag.

An opened tag appears as a word surrounded by a less-than ( < ) and greater-than sign ( > ), like so:

        ::xml
        <paragraph>

A closed tag appears as a word surrounded by a less-than ( < ) and a greater-than sign ( > ), with the addition of a slash sign ( / ) positioned right after the less-than sign ( < ), like so:

        ::xml
        </paragraph>

These tag pairs constitute "boxes". Like boxes in the real world, they contain items which in the case of XML coding are called "elements".

**Beware**: tags can only contain one word. If two are present, they must appear without space between them.

For instance, the following example is wrong:

        ::xml
        <contact info></contact info>

While the following example is correct:

        ::xml
        <contact-info></contact-info>

So, if I want to define a paragraph box with the paragraph tag, I need to write my XML code like so:

        ::xml
        <paragraph>This is my paragraph's first sentence.
And here is my second sentence.</paragraph>

Note: in the example above, the words "This is my paragraph's first sentence. And here is my second sentence." are the elements.

I can also put boxes within boxes, as follows:

        ::xml
    <document>
        <title>My title</title>
        <paragraph>A short paragraph.</paragraph>
        <paragraph>And another.</paragraph>
    </document>

Incidentally, I have now created "a document" containing a title and two paragraphs.

By the way, a third type of tag exists in the XML language. It is called the "solo tag", as opposed to the "pair tag". These solo tags are opened and closed at the same time. No element can therefore be placed between them. For instance:

        ::xml
        <Items/>

### Attributes

Let's take a look at the following example:

        ::xml
        <alignment paragraph="centered">A short paragraph.</paragraph>
        <alignment paragraph="left">A less short paragraph.</paragraph>
        <invisible paragraph>And another paragraph.</paragraph>

To each *paragraph* tag we have added attributes, between quotes, before closing the tag by using a greater-than sign ( > ). Each of these attributes makes the tags they refer to more specific by adding more information.

In the example above, we used two attributes:

- The *alignment* attribute, which value is 'centered' in the first paragraph and 'left' in the second paragraph.
- The *invisible* attribute which has no particular value.

Each new attributes adds details to their tags, details that Natao exploits to format the text appropriately.

### Standards

In the previous examples, I gave my tags random names, like *paragraph* or *contact-info*, to help me explain how tags work in XML. Continuously coming up with tags would make XML useless as a way for everyone to use it. That is why models have been devised to help people work in an efficient and consistent way, whether in the book publishing, by using the DocBook model, or in the web-publishing industry, by using HTML.

## HTML

As suggested above, HTML is therefore a set of tags. It is usually used to create web pages.

As regards Natao, just know that the Markdown syntax used in Natao generates HTML code natively, and that it is that HTML code that we are going to shape with CSS. As a result, we are only going to learn a few HTML tags here, the ones that you will need to modify Natao's style-sheets.

Let's get our HTML-feet wet by re-writing one of our previous examples, but this time in HTML:

        ::html

                ...

My title

A short paragraph.

And another.

This is basically how traditional web pages are written: there's a *header* section, which we won't get into here as it remains invisible in the final document; and there's a *body* section, which contains what's visible in the final document, with a level 1 title (the most important ones) written as *h1* and paragraphs noted as *p*.

# Structure of a Natao Document

Let's look at the core structure of a Natao document.

Note: it's going to be a lot to take in at first, mainly because we haven't yet talked about Markdown when it is transformed into HTML, but it's important to take note of it now, to help us understand how to edit the appearance of a Natao document later.

        ::html

Your last name

Your first name

Your grade

Titre

Creation date

                        Here will appear what you wrote in your document.

Let's take a look at the first tag:

        ::html

Note that I kept the open and closed *div* tags. In this instance they work together as a box with no particular signification.
What we need to pay attention to here are the attributes:

        ::string
        id="viewer" layout="column"

- *id* stands for identifier.
- *layout*, which is not a standard attribute, indicates how the layout elements appear in Natao:
        - *column* means that the elements appear as a column.
        - *row* means that the elements appear in a row.

In other words, *div* which is identified as *viewer* appears as a column. The boxes which appear within it appear as columns.

To simplify things further, we'll use the boxes' identification to designate them (because divs are used everywhere). We will therefore not speak of *div* boxes, but of the *viewer* box.

Inside the first box, we have a second one which is stretched out (*layout-align="start stretch"*), and which takes all the room it can take (*flex*), like so:

        ::html

It too appears as a column. Moreover, we can notice that it contains three interesting boxes:

        ::html

- A *header* box.
- A *separator* box.
- A *content* box.

## The *header* box

```
::html
<div id="header" layout="row" layout-align="start stretch">
    <div id="identity" layout="column" layout-align="center stretch">
        <p>Your last name</p>
        <p>Your first name</p>
        <p>Your grade</p>
    </div>
    <div id="title-zone" flex layout="column" layout-align="center stretch">
        <h1>Titre</h1>
        <p id="dateCreated">Creation Date</p>
    </div>
</div>
```

The *header* box is composed of two boxes:

- *identity*
- *title-zone*

These two boxes are written on the same line, and are going to stretch over that line, starting from the left:

        ::html

Within the *identity* box, your last name, your first name, and your grade will appear in a column.
Within the *title-zone* box, the document's title and its creation date will appear in a column.

## The *separator* box

The *separator* box is empty. It will create a blank space between your document's title and your written text.

## The *content* box

    ::html

                Here will appear what you wrote in your document.

The *content* box is composed of two boxes which will appear on the same line:

- *margin* stands for the margin to the left of your document, where your teacher will leave her or his marks.
- *made* stands for your Markdown document's render zone.

# A CSS Rule

This is the section where we start talking about modifying your document to fit it to your own personal needs.

CSS is used to write the formatting rules which will be applied to your document's HTML code. What follows is an example of one such rule:

        ::css
    #identity {
        display: none;
        }

Let's start with *#identity*:

This section of the CSS rule, positioned before the bracket signs ( { } ), is called a selector. Selectors indicate which box CSS rules are applied to. In the example above, the rule is applied to the *identity* identifier.

We then notice a particular property that's applied to this box:

- *display: none;*, which keeps the box from appearing and therefore taking up any extra room in the document.

How does this related to your homework or class assignment? In such case, you are not going to need the box to appear with your last and first names.

Let's now take a look at the bits that are going to help you pick the best box for your document, the boxes which you will transform to fit your formatting needs.

# The Useful Selectors

## The Box Selectors

To select all identical boxes, I merely need to use as selector the name of the tag:

        ::css
    div {
        display: none;
        }

This eroneous example is going to hide all the *div* boxes, that is, all your document.

## The Identifier Selector

To select any box, whatever might its identifier be, I'm going to use a hash-tag sign ( # ) in front of the identifier, as seen in our original example.

## The Class Selector

What follows is a box that has a class property:

        ::html

        some code

It may be selected thanks to the class selector with a period sign ( . ) in front of it, as follows:

        ::css
    .java {
        display: none;
        }

And here again, we make something interesting disappear.

## Using Many Selectors at Once

You may apply a rule to many selectors at the same time, by separating them with a comma, as follows:

        ::css
    h1, #header {
        display: none;
    }

Here, the rule is applied to all *h1* elements and to the *header* box.

## Selecting Box Descendants

You can select the box descendants by adding a space between the parent and the descendant:

        ::css
    #title-zone h1 {
        color: red
    }

The example above modifies the color of the level 1 title in the box #title-zone, without affecting any of the other box titles.

# Affecting Natao's Large Boxes

We must first decide which of the document's boxes will appear in our style-sheet, as well as their sizes. Once that is done, we can choose how best to change their appearance.

## Making Boxes Disappear

Once again, here's the first CSS example we used:

        ::css
    #identity {
        display: none;
        }

*display* allows us to modify the so-called child selectors. The way Natao modifies such selectors is unique to Natao. As a result, the only value one needs to know is *none*, which makes the elements invisible.

To be applied to the following elements, which are only useful for homework related documents:

- *identity*
- *separator*
- *margin*

## Modifying Box Sizes

### Height and Width

    ::css
        #identity {
        width: 200px;
        }

    #separator {
        height: 200px;
    }

In the preceding example, I fixed the *width* of the *identity* box to 200 pixels, and the *height* of the *separator* box to 200 pixels as well.

*identity* is located in a box which elements are in a line. The separator will use the indicated width and the other elements of the box will use the left-over room.

In the case of the *separator*, it is located in a column box. By fixing its size, the box that follows will use the height space that's left over.

### Units

In the preceding example, I used the pixels (px) units. There are many others units. We only need to be aware of a few here though. They are:

- *px* for pixels, which represent screen points.
- *pt* for points, which are used when printing documents.
- *%* used to delineate a usable portion of the screen. Note: 50% means that we are using half of the screen's space.
- *em*, which might be the most interesting unit. 1em represents the font size for the entirety of the document. You'll therefore be able to define a few elements which will be proportional to this font size.

## Modifying Colors

### By Changing Their Properties

        ::css
    #identity {
        background-color: red;
        color: #af2356;
    }

Here are two new properties to be use to modify colors:

- *color* lets you modify the text's color.
- *background-color*, as its name suggests, lets you modify the background color.

Note: the list of available colors is too large to be included here, but if you can still get it by using the following [link](http://www.colors.commutercreative.com/grid/).

In the example above you'll noticed that the *color* property contains a hash-tag sign ( # ), followed by six hexadecimal characters. These six characters are in fact made up of three pairs of characters: the first pair is for red, the second is for green, and the third is for blue: Red/Green/Blue, also known as the RGB color space. Being able to use the RGB color space in HTML coding lets you pick the colors you need very precisely. Neat stuff, no?

### By Using the Color Picker

A color picker has been integrated to Natao. It will come into play as soon as Natao recognizes a valid color code, which, as we've just seen, is series of six characters following a hash-tag sign, as follows:

        ::css
    color: #111111;

As soon as you've typed the color code, in this case (#111111;), click on it to see it pop up. Super neat stuff!

![Color choice](./src/images/thistle.png)

Three componants are noticeable:

- A preview bar, at the bottom.
- A brightness bar, on the right.
- A hue circle.

You can choose to play with the hue circle's diameter by bringing it closer to its center (the colors fade), or by bringing it away from the center (the colors intensity).
You can choose a color by moving your cursor within the circle.
You can pick your color's brightness by sliding the brightness bar shuttle.

## Modifying Borders

### Two Syntax

You may add borders to your boxes like so:

        ::css
    #identity {
        border-width: thin;
        border-style: solid;
        border-color: red;
    }

    #separator {
        border: thin solid red;
    }

In the previous example, we've applied the same border to the two boxes, *identity* and *separator*.

The *identity* box has three properties:

- *border-width* which describes the thickness of the border, which, in our example, is thin.
- *border-style* which describes the border's style, which in our example is a solid line.
- *border-color* which describes the border's color, which in our example is red.

The *separator* box uses three abbreviated syntax: the key word *border* is followed by three values referring to the border's width, style and color.

### Width

This property has three standard values:

- *thin* for a thin border.
- *medium* for a medium border.
- *thick* for a thick border.

You may also add other values to it, in pixels (px), or points (pt), etc.

### Style

Four values need to be known:

- *dotted* to get a dotted line border.
- *dashed* to get a border made of dashes.
- *solid* to get a plain line border.
- *double* to get a border made of two lines. Do note that this type of border only becomes visible with medium-sized borders and above.

### Partial Borders

You may chose to give your box a partial border, of either one or two or three sides. Each side has an associated word:

- *top* which refers to the top border.
- *bottom* which refers to the bottom border.
- *left* which refers to the left border.
- *right* which refers to the right border.

Simply add one of the above key words after border to affect it:

        ::css
    #separator {
        border-top: thin solid blue;
        border-bottom: thin solid blue;
    }

    #margin {
        border-right-width: thin;
        border-right-style: solid;
        border-right-color: red;
    }

## Modifying Margins

Each box has two types of margins:

- An external margin (that is, the *margin* property, not the similarly named box) om): it helps us define how close our margin will come to our box.
- An internal margin (key-word *padding*): it helps us define how close our margin will come to our internal box.

Just as is the case for borders, key-words can be followed by *top*, *bottom*, *left* et *right*, as follows:

````
::css
#made {
        margin: 10px;
    padding: 20px;
}

#made h1 {
        margin-top: 30px;
}
```

In the above example, we can see that our *made* box will be at least 10 pixels away from our *made* box, and that the box they contain will be 20 pixels away from the borders.

We can also notice that the level 1 titles (*h1*) will be 30 pixels (30px) away from the previous box.

# Applying Changes to the Text Globally

## Modifying the Overall Font t Size

Let's use this opportunity to go over the size units again:

- *px* for pixels, which represent screen points.
- *pt* for points, which are used for printing documents.
- *em*, which might be the most interesting unit. 1em represents the font size for the entirety of the document.

You can choose a font size for the entirety of your document, like so:

        ::css
    #made {
        font-size: 16px;
    }

This example gives us a default 16px font size. From here, you may adjust the font size of titles for example:

        ::css
    #made h1 {
        font-size: 2em;
    }

    #made h2 {
        font-size: 1.5em;
    }

Thus, my level 1 title, which corresponds to only one hash-tag sign ( # ), will be twice the size of the base font size. The level 2 title, which corresponds to two hash-tag signs ( ## ), will be 1.5 times the base font size.

If I change the default font size to 20px, the size of the document's title will change proportionally.

## Modifying the Overall Font

You can modify the font that's used in your document thanks to the *font-family* property, as follows:

        ::css
    #made {
        font-family: RobotoDraft, Roboto, 'Helvetica Neue', sans-serif;
    }

This line of code tells Natao to use the *RobotoDraft* font. If that font is not found, Natao is told to use the *Roboto* font. If that can't happen either, the *Helvetica Neue* font should be used. And in the case that this font can't be found, the first *sans-serif* font Natao finds should be used.

Note, as the example above suggests, that it is a good idea to give Natao the option to pick from two or three fonts, before asking it to use a family of fonts.

Note also that the font you will have access to to compose your Natao document will be dependent on the fonts present on your computer.

Here are a few of these *font-family*:

|Font-Family | Definition                                          |
|------------|-----------------------------------------------------|
| Serif      | Georgia, serif                                      |
| Serif      | "Palatino Linotype", "Book Antiqua", Palatino, serif|
| Serif      | "Times New Roman", Times, serif                     |
| Sans-Serif | Arial, Helvetica, sans-serif                        |
| Sans-Serif | "Arial Black", Gadget, sans-serif                   |
| Sans-Serif | "Comic Sans MS", cursive, sans-serif                |
| Sans-Serif | Impact, Charcoal, sans-serif                        |
| Sans-Serif | "Lucida Sans Unicode", "Lucida Grande", sans-serif  |
| Sans-Serif | Tahoma, Geneva, sans-serif                          |
| Sans-Serif | "Trebuchet MS", Helvetica, sans-serif               |
| Sans-Serif | Verdana, Geneva, sans-serif                         |
| Monospace  | "Courier New", Courier, monospace                   |
| Monospace  | "Lucida Console", Monaco, monospace                 |

## Underlining a Text

Let's underline a bit of text, like so:

        ::css
    #made {
        text-decoration: underline;
    }

## Text Thickness

The *font-weight* property lets you change the text's thickness:

- *lighter* for a text that's thinner than usual.
- *normal* for a normal text.
- *bold* for a bold text.
- *bolder* for an extra-bold text.

Let's put the entirety of our document's text in bold, like so:

        ::css
    #made {
        font-weight: bold;
    }

## Text Style

The *font-style* property lets us decide if a portion of text is:

- *normal*: with straight characters.
- *italic*: with slanted characters.

Let's put the entirety of our document's text in italic, like so:

        ::css
        #made {
        font-style: italic;
    }

## Text Alignment

The *text-align* property lets us pick how our text is aligned. It is used as follows:

- *left*, to move the text to the left.
- *right*, to move the text to the right.
- *center*, to center the text.
- *justify*, for the text to spread evenly.

Let's write an example which we could use to write a poem's verses:

```
::css
#made p {
        text-align: center;
}
```

## Indenting a First Line

The *text-indent* property lets us indent a box's first line, like so:

        ::css
    #made p {
        text-indent: 1.5em;
    }

# Affecting Individual Text Boxes

What follows is an example of a Markdown document containing paragraphs, titles, and some emphasized text:

        ::markdown
    # Title 1
    ## Title 1.1
    ### Title 1.1.1
    ...
    ###### Title 1.1.1.1.1.1

The code written above describes that a first paragraph is followed by a first line followed by a second line.
The following *paragraph* with **emphasized** and even ~~struck-through~~ words.

Written in HTML, this Markdown text gives the following code:

        ::html

Title 1

Title 1.1

Title 1.1.1

    ...

Title 1.1.1.1.1.1

The code written above describes that a first paragraph is followed by a first line followed by a second line.

The following paragraph with emphasized and even struck-through words.

You can notice here that the number of hash-tag signs ( # ) used in a title corresponds to the number that follows the <h> of the title box. In other words, one hash-tag sign becomes *h1* and so on.

The paragraphs are in the *p* boxes.
The word *paragraph* which was surrounded by one star sign ( * ) is in the *em* box.
The word *emphasized* which was surrounded by two star signs ( ** ) is in the *strong* box.
The word *struck-through* which was surrounded by two tilde signs ( ~ ) is in the *del box.

All of the boxes referred to above are normal boxes. As a result, everything we've seen so far on how to modify boxes can be used on them:

- Changing the background and text colors.
- Changing the font.
- Changing the font size.
- Underlining.
- Changing the thickness of the text.
- Changing the style of the text.

These boxes have a default appearance. A *em* box is in italic by default. A *strong* box is in bold by default. A *del* box is struck-through by default. And the titles also have default sizes.
I suggest that you only modify the bits that you need to modify.

If you also need the embolden text to be made red or underlined, do it as follows:

        ::css
    strong {
        color: red;
        text-decoration: underline;
    }

# Automatic Numerotation

Here's the code I used for the lesson style:

```
::css
#made {counter-reset: chapter section sub-section;}

#made  h1 {
    font-family: "Courier New", Courier, monospace;
    margin-bottom: 20px;
    margin-top: 50px;
    font-size: 1.5em;
    counter-reset: section;
}

#made  h1:before {
        counter-increment: chapter;
    content: counter(chapter,upper-roman) " - ";
}

#made h2 {
    font-size: 1.2em;
    counter-reset: sub-section;
}

#made h2:before {
    counter-increment: section;
    content: counter(chapter) "." counter(section) "  ";
}
#made  h3:before {
    counter-increment: sub-section;
    content: counter(chapter) "." counter(section) "." counter(sub-section) "  ";
}
```

I'd like to use this opportunity to show you two new selectors:
- *h1:before*
- *h1:after*

I've added *:before* to the *h1* box selector as a pseudo-class. There are others like it, but this one is going to allow us to add content to whatever box we chose. We could have done the same with the *after* pseudo-class.

Let's talk about counters. To generate numbers automatically, I use counters. I start by initializing their value by setting them to 1:

        ::css
        #made {counter-reset: chapter section sub-section;}

*counter-reset* sets all the specified counters to 0. Here the counters which we've called *chapter*, *section*, and *sub-section* all get a value of 0.

These counters are all linked to a title-level type of box:

- *chapter* for *h1*.
- *section* for *h2*.
- *sub-section* for *h3*.

For each new *h1* level (chapter), I set the *h2* level (*section*) counter to 0.
For each new *h2* level (section), I set the *h3* level (*sub-section*) counter to 0.

In CSS we then get the following:

````
::css
#made  h1 {
    counter-reset: section;
}

#made h2 {
    counter-reset: sub-section;
}
```

Let's now take a look at the *before* of the h1 and h2 boxes:

```
::css
#made  h1:before {
    counter-increment: chapter;
    content: counter(chapter,upper-roman) " - ";
}

#made h2:before {
    counter-increment: section;
    content: counter(chapter) "." counter(section) "  ";
}

```

Let's first look at the use of the *counter-increment* property, which is linked to the *chapter* counter for *h1:before* and to the *section* counter for *h2:before*. This order adds 1 to the selected counter.

Then comes the *content* property. It lets us modify the content of a box. Here, we're positioned *before* the *h1* box or *before* the *h2* box.

Starting with the *h2* box, we can see that the *content* property contains *counter(chapter) "." counter(section) "  "*, which broken down means:

- The value of the *chapter* counter (*counter(chapitre)*),
- followed by a period,
- followed by the value of the *section* counter (*counter(section)*),
- followed by a blank space,
- and finally followed by our *h2* box, and therefore our title, because everything we've looked at before is situated before *h2*.

If we look at the *h1* box, you may notice that the *content* property contains *counter(chapter,upper-roman) " - "*, which means:

- The value of the *chapter* counter, in upper case roman numerals (*counter(chapter,upper-roman)*),
- followed by a blank-space, and a blank-space,
- and finally, our *h1* box.

For *h2*, I use *counter(section)*, and for *h1* and use *counter(chapter,upper-roman)*. In the second case, I specify that roman numerals need to be used, and in the first, I don't put in the counter. This is because it is written in *decimal* by default. I could have written *counter(section,decimal)*, but it would have been the same thing.

Here are the various possible values, and when I know what they correspond to:

- *decimal* to write Arabic numerals (which we usually use),
- *decimal-leading-zero* to write Arabic numbers with a 0 in the decimals,
- *lower-roman* in roman numerals, lower case,
- *upper-roman* in roman numerals, upper case,
- *lower-greek* in Greek numerals,
- *lower-latin*,
- *upper-latin*,
- *armenian*,
- *georgian*,
- *lower-alpha* in lower case letters,
- *upper-alpha* in upper case letters.
<file_sep>[Français](https://github.com/Ajrarn/Natao_legacy/blob/develop/README-fr.md)

# Natao

Natao is a Markdown Editor that has been specifically designed to help dyspraxic, dysgraphic and dyslexic students easily produce
their homework and compose school/college essays on computers.

Natao is Operating System (OS) independent, that is, it works equally well on OSX, Linux and Windows machines.

## Getting Started

Find the Natao release that corresponds to your computer's OS here:

[releases](https://github.com/Ajrarn/Natao_legacy/releases).

Unzip the application's folder wherever you want on your computer, and start using Natao right away.

## Why another Markdown Editor ?

Unlike other more conventional Markdown Editors, Natao has been designed, from the ground up, to help students write essays and
calculate mathematical formulas clearly, easily, and elegantly.

Natao has also been designed to help its users organize their Natao-produced documents along standardized folder structures.

## Screenshot

![NataoScreen](./NataoScreen.png)

## Authors

* **<NAME>** - *Lead Programmer* - [Ajrarn](https://github.com/Ajrarn)

See also the list of [contributors](https://github.com/Ajrarn/Natao_legacy/contributors) who participated in this project.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details

## Acknowledgments

* Thanks to all my friends, for their insights and time spent testing Natao. And special thanks to <NAME> who helped on the French-to-English translation.
* Thanks to <NAME>, ergotherapist, for her ideas and suggestions.
* Thanks to all the programers who created the library and tools used by Natao:
    * [Nwjs](http://nwjs.io/)
    * [AngularJs](https://angularjs.org/)
    * [CodeMirror](https://codemirror.net/)
    * [Showdown](https://github.com/showdownjs/showdown)
    * [NeDB](https://github.com/louischatriot/nedb)
    * and many others.
* Finally, my heartfelt thanks to my wife and our two kids who gave me the time and space to create Natao.

branch_name: refs/heads/develop

languages: Markdown SCSS JavaScript

repo_name: Ajrarn/Natao