From b95c6a3de43121c061457039a4c926d5d34f2737 Mon Sep 17 00:00:00 2001
From: jsteuer <jan.steuer.htw@gmail.com>
Date: Mon, 16 Dec 2019 13:28:22 +0100
Subject: [PATCH] better docs, helpers namespace

---
 README.md |  288 +++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 216 insertions(+), 72 deletions(-)

diff --git a/README.md b/README.md
index ecec13f..d7f97fd 100644
--- a/README.md
+++ b/README.md
@@ -1,117 +1,259 @@
- 
+
 # MathCoach IDE API
 
 In diesem Paket ([Das Gitblit Repository findet sich hier](https://newton.htwsaar.de/gitblit/summary/mathcoach!mathcoach-ide-api.git)) 
-ist die öffentliche Schnittstelle zur MathCoach Entwicklungsumgebung (IDE)
-definiert. Mithilfe dieser Schnittstelle können externe Werkzeuge (z.B. Editoren) erstellt werden. 
-Für den Anwender stehen diese Werkzeuge dann komfortabel - in die IDE integriert - zur Verfügung.
+ist die öffentliche Schnittstelle zur MathCoach Entwicklungsumgebung (IDE) definiert. Mithilfe 
+dieser Schnittstelle können externe Werkzeuge (z.B. Editoren) erstellt werden. Ziel ist, dass 
+diese Werkzeuge für den Anwender komfortable - in die IDE integriert -zur Verfügung gestellt werden 
+können. Darüber hinaus werden als Ergänzung einige Hilfsfunktionen zum Bau von Werkzeugen angeboten.
 
 ![Demo](media/usage_author.gif)
+*Beispielhafte Anwendung: Eine Datei wird angelegt und einem Demo-Editor geöffnet. Dieser 
+generiert eine Groovy-Aufgabe*
+
+
+
+## Idee 
+Grundlegende Idee ist, dass ein externes Werkzeug nahtlos in die MathCoach IDE integriert werden 
+kann. Bestimmte Dateien werden anhand ihrer Dateiendung mit dem Werkzeug verknüpft, sodass der
+Benutzer das passende Werkzeug durch einen einfache Klick im Dateie-Explorer starten kann. Diese 
+Datei wird im folgenden Kontext-Datei genannt und soll dazu dienen das interene Datenmodell (also
+alle Informationen, die der Benutzer im Editor angibt) zu speichern. Das gespeicherte Datenmodell kann 
+zu einem späteren Zeitpunkt wieder geladen werden. Weiterhin kann das Werkzeug aus dem internen 
+Datenmodell eine MathCoach-Aufgabe (Groovy-Datei) generieren. Weitere Funktionalitäten - beispielsweise 
+das Starten der generierten Aufgabe in der Aufgaben-Vorschau der IDE - sind ebenfalls für den 
+Werkzeugentwickler verfügbar.
+
+Das Realisieren von Werkzeugen auf diese Art und Weise hat zahlreiche Vorteile:
+-   Werkzeuge werden einheitliche und benutzerfreundlich zur Verfügung gestellt
+-   Grundlegende Funktionalitäten (Anlegen von Dateien, Navigieren im Dateisystem) werden bereits 
+    durch die IDE bereitgestellt. So können Werkzeug-Entwickler ihren Fokus auf das Werkzeug legen.
+-   Die IDE kann gefährliche Situationen (z.B. das Überschreiben von Dateien) abfangen
+    und den Benutzer entscheiden lassen, wie fortgefahren werden soll.
+
+
+
+## Entwicklung externer Werkzeuge
+
+Externe Werkzeuge laufen ausschließlich im Webbrowser des Benutzers - es muss also
+auf `HTML`, `JavaScript` und `CSS` gesetzt werden. Außerdem muss das Werkzeug unter 
+der Domain des jeweiligen MathCoach-Servers erreichbar sein. Zur Entwicklungszeit legt man das Werkzeug 
+dazu im www-Verzeichnis ab. Die von der IDE bereitgestellte `ide-lib.js` Bibliothek 
+muss eingebunden werden. 
+
+    <script src="/mathcoach/ui/ide/ide-lib.js"/> 
+
+Dabei darf der MathCoach-Server **nicht** fest in die URL eincodiert werden. Andernfalls
+kann es zu Problemen kommen, wenn das Werkzeug auf unterschiedlichen Server bereitgestellt 
+wird. Bei korrekter Verwendung steht die IDE API nun durch die globale Varialbe `MC` zur 
+Verfügung - [Dokumentation der IDE API](./interfaces/mathcoach.api.html).
+
+> **Hinweis**: Es steht **ausschließlich** die API, welche über die globale Variable `MC`
+> definiert ist, zur Verfügung! Hilfsfunktionen wie `Helpers.enableOfflineUsageIfNecessary()` 
+> sind grundsätzlich nicht verfügbar und müssen vom Werkzeugentwickler eingebunden 
+> werden - siehe "Hilfunktionen für Werkzeug-Entwickler" weiter unten.
+
+> **Hinweis**: Erst, wenn das Werkzeug in die IDE integriert und aus dieser heraus
+> gestartet wurde, kann die IDE API verwendet werden! Soll das Werkzeug auch ohne die 
+> IDE nutzbar sein (z.B. zum Testen), muss dies bei der Implementierung berücksichtigt
+> werden. Konnte die `ide-lib.js` nicht eingebunden werden (weil das Werkzeug ohne IDE 
+> gestartet wurde - darum darf auch kein Server fest eincodiert werden), steht die 
+> globale Variable `MC` nicht zur Verfügung (`typeof MC === "undefined"`). Hier kann das 
+> Werkezug eine Fallunterscheidung treffen und beispielsweise eine eigene Implementierung 
+> über die globale Variable `MC` bereitstellen. Siehe auch `Helpers.enableOfflineUsageIfNecessary()` 
+> weiter unten.
+
+
+
+### Empfohlenes Vorgehen
+Damit externe Werkzeuge ein einheitliches Verhalten aufweisen, sollte wie folgt vorgegangen werden.
+
+Als erstes muss sichergestellt werden, dass die MathCoach IDE API auch verfügbar ist. Dies ist 
+beispielsweise nicht der Fall, wenn das Werkzeug ohne die IDE gestartet wurde oder die IDE (aus
+welchen Gründen auch immer) nicht einsatzbereit ist.
+
+    if(typeof MC === "undefined"){
+        // Hinweis: Hier kann die IDE API nachgebildet werden,
+        // sodass das Werkzeug auch "Offline" funktioniert. 
+        // Also: MC = { isReady: async () => true, ...}
+        throw new Error("IDE Lib nicht eingebunden"); // TODO: show error to user
+    }
+    const isReady = await MC.isReady();
+    if(!isReady){
+        throw new Error("Die MathCoach-API ist nicht einsatzbereit."); // TODO: show error to user
+    }
+    ...
+
+Von nun an kann die IDE API vollständig genutzt werden. Zunächst sollte die Kontext-Datei (die 
+Datei, mit der das Werkzeug gestartet wurde) geladen werden.
+
+Ist der Inhalt der Kontext-Datei leer, wurde die Datei neu angelegt und zum ersten mal geöffnet.
+Nun soll das Werkzeug:
+-   Sich initialisieren. Es ist sinnvoll, dass das Werkzeug mit einem beispielhaften
+    Datenmodell inititalisiert wird.
+-   Das interne Datenmodell in die Kontext-Datei schreiben 
+-   Die zugehörige Aufgabe generieren. Siehe auch `contextFileToExerciseFile` weiter unten.
+
+Andernfalls kann das zuvor gespeichertes Datenmodell aus der Kontext-Datei in den 
+Editor geladen werden. Anschließend sollte die generierten Aufgaben in der Vorschau gestartet werden, sodass der 
+Benutzer besser abschätzen kann, wie sich Änderungen im Werkzeug auf die Aufgabe auswirken.
+
+
+    let contextFile = await MC.ide.getContextFile(); // Datei, mit der der Editor gestartet wurde
+    let contextFileContent = await MC.ide.fs.readFile(contextFile);
+    let contextFileIsEmpty = contextFileContent === "";
+
+    let exerciseFile = contextFileToExerciseFile(contextFile);
+
+    if(contextFileIsEmpty){
+        // TODO: Datenmodell anlegen (Idealerweise mit beispielhaften Inhalt)
+        // TODO: Datenmodell in Kontext-Datei schreiben, z.B. mit JSON.stringify(...)
+        let dataModelAsString = JSON.stringify({/* TODO */});
+        await MC.ide.fs.writeFile(contextFile, dataModelAsString);
+        // TODO: Aufgabe generieren
+        let generatedExerciseCode = "startup { print('Hallo Welt!') }"; 
+        await MC.ide.fs.writeFile(exerciseFile, generatedExerciseCode);
+    }else{
+        // TODO: Datenmodell laden, z.B. mit JSON.parse(contextFileContent)
+        // TODO: (Aufgabe neu generieren)
+        // TODO: init application based on your data model
+    }
+
+    // Aufgabe anzeigen
+    await MC.ide.navigator.navigateToExercise(exerciseFile);
+
+Jedes Werkzeug sollte über eine "Speichern"-Funktion verfügen, mit der der Benutzer:
+- Das interne Datenmodell in die Kontext-Datei speichert (sodass es später wieder geladen werden kann)
+- Die zugehörige Aufgabe wird generiert und die Vorschau zu dieser navigiert
+
+  
+
+### Hilfsunktionen für Werkzeug-Entwickler
+
+[Dokumentation der Hilfsfunktionen](./modules/helpers.html)
+
+Dieses Paket beinhaltet zusätzlich Hilfsfunktionen für Werkzeug-Entwickler. Diese sind aktuell
+in `TypeScript` implementiert und können bei Bedarf auch zukünftig als ES6-JavaScript 
+bereitgestellt werden. Zum Einbinden der Funktionen wird demzufolge ein Build-System 
+vorausgesetzt. Keine der Hilfsfunktionen wird durch die `ide-lib.js` ausgeliefert!
+
+Beispielsweise werden diese wie folgt eingebunden und genutzt:
+
+    import { Helpers } from "@mathcoach/ide-api";
+    Helpers.enableOfflineUsageIfNecessary()
  
 
-## Entwicklung externer Werkzeuge 
+> **Hinweis**: Hilfunktionen ohne Build-System bereitzustellen gestaltet sich schwierig und
+> bringt große Nachteile mit sich:
+> - Als reine JavaScript-Datei - platziert auf einem Server - ist die die 
+>   Offline-Fähigkeit (siehe `Helpers.enableOfflineUsageIfNecessary()`) von Werkzeugen nicht 
+>   gewährleistet. 
+> - Werden Dateien oder Code-Ausschnitte von Hand kopiert, muss der Werkzeug-Entwickler sich
+>   um das Aktualisieren kümmern. 
+> 
+> Ein möglicher Kompromiss wäre die Hilsfunktionen als reine JavaScript-Datei (ES5 oder ES6) 
+> bereitzustellen und eine Kopie mit dem Werkezug auszuliefern. Der aktuelle Ansatz bettet 
+> Hilfsfunktionen durch den Build-Prozess in das Werkzeug ein.
 
--   Externe Werkzeuge müssen unter der Domain von MathCoach erreichbar sein. Zur Entwicklungszeit legt
-    man das Werkzeug dazu im www-Verzeichnis ab.
--   Die von der IDE bereitgestellte Bibliothek muss eingebunden werden 
-
-        <script src="/mathcoach/ui/ide/ide-lib.js"/>
-
--   Von nun an steht die hier definierte API durch die globale Variable `MC` zur Verfügung. 
--   **Hinweis**: Erst, wenn das Werkzeug in die IDE integriert und aus dieser heraus 
-    gestartet wurde, kann die API verwendet werden! (Hinweis: durch nachbilden der API kann 
-    eine Nutzung ohne IDE ermöglicht werden, siehe `enableOfflineUsageIfNecessary`)
 
 ### Beispiele
-Im Verzeichnis `./examples/` finden sich Beispiele für externe Werkzeuge. 
+Im Verzeichnis `./examples/` finden sich Beispiele für externe Werkzeuge.
 
-### Hilfunktionen für Werkzeug-Entwickler
-Dieses Paket beinhaltet zusätzlich Hilfsfunktionen für Werkzeug-Entwickler. Beispielsweise kann
-ein Werkzeug ohne IDE-Anbindung genutzt werden, indem die API nachgebildet wird - aktuell auf 
-Basis des LocalStorage des Browsers.
-
-    import { enableOfflineUsageIfNecessary } from "@mathcoach/ide-api";
-    let offline: boolean = enableOfflineUsageIfNecessary();
-
-
-### Kleinere Werkzeuge
-Für kleiner Werkzeuge bietet es sich an im WWW-Verzeichnis zu entwickeln  (z.B. 
+### Entwicklung kleinerer Werkzeuge
+Für kleiner Werkzeuge bietet es sich an im www-Verzeichnis zu entwickeln  (z.B.
 `myTool/tool.html` und `myTool/tool.js`). Die MathCoach-IDE stellt Autovervollständigung beim
-Editieren der `tool.js`-Datei zur Verfügung. Da es sich um eine JavaScript-Datei handelt, 
-ist keine Typsicherheit gegeben. Das Werkzeug muss lokal in die IDE integriert werden, siehe 
+Editieren der `tool.js`-Datei zur Verfügung. Da es sich um eine JavaScript-Datei handelt,
+ist keine Typsicherheit gegeben. Das Werkzeug muss lokal in die IDE integriert werden, siehe
 weiter unten.
 
 ![Demo](media/usage_tool_developer.gif)
 
-### Größere Werkzeuge
-Für größere Werkzeuge sollte ein Build-System wie [webpack](https://webpack.js.org/) 
-oder [PARCEL](https://parceljs.org/) in Kombination mit 
-[TypeScript](https://www.typescriptlang.org/) verwendet werden. Das Werkzeug muss nach dem
-Build-Prozess in das WWW-Verzeichnis kopiert und ebenfalls lokal in die IDE integriert werden, siehe
-weiter unten.
+### Entwicklung größerer Werkzeuge
+Für größere Werkzeuge sollten etablierte Entwicklungswerkzeuge verwendet werden, beispielsweise:
+- [npm](https://nodejs.org/en/) um externe Bibliotheken (u.A. dieses Paket) einzubinden
+- [webpack](https://webpack.js.org/) oder [Parcel](https://parceljs.org/) als Build-System um den Quellcode des Werkzeuges zu "bündeln"
+- [TypeScript](https://www.typescriptlang.org/) zum typsischeren Programmieren (und/oder Dateien zu ES6 oder ES5 konformen JavaScript umzuformen)
+- [Git](https://git-scm.com/) zur Versionierung des Quellcodes
+- [Visual Studio Code](https://code.visualstudio.com/) als Entwicklungsumgebung
+- Unit Tests
+
+Das "gebündelte" Werkzeug muss nach dem Build-Prozess in das WWW-Verzeichnis kopiert und ebenfalls 
+lokal in die IDE integriert werden, siehe weiter unten.
 
 
-Die MathCoach-API kann auch als npm-Package eingebunden werden, sodass eine typsichere 
-und komfortable Entwicklung (z.B. mit Visual Studio Code) möglich ist. Hierzu muss 
+#### MathCoach-API als npm-Package einbinden
+
+Die MathCoach-API kann auch als npm-Package eingebunden werden, sodass eine typsichere
+und komfortable Entwicklung (z.B. mit Visual Studio Code) möglich ist. Außerdem wird es 
+möglich die angebotenen [Hilfsfunktionen](./modules/helpers.html) zu einzubinden. Hierzu muss
 die `package.json` des Werkzeug-Projektes wie folgt ergänzt werden:
 
     {
         ...
         "devDependencies": {
-            "@mathcoach/ide-api": "git+https://newton.htwsaar.de/gitblit/r/mathcoach/mathcoach-ide-api.git#1.1.0" 
+            "@mathcoach/ide-api": "git+https://newton.htwsaar.de/gitblit/r/mathcoach/mathcoach-ide-api.git#1.2.0"
         },
         ...
     }
+ 
 
-Bei Verwendung einer Entwicklungsumgebung wie Visual Studio Code kann die Typdefinition der 
-API auch für JavaScript eingebunden werden. Hierfür ist ggf. ein spezielles Kommentar am Anfang
-der Datei notwendig (Pfad falls nötig anpassen):
+Wie man der Git-Repo URL ansieht, werden Git-Tags verwendet um eine Versionierung 
+[(Semantic Versioning)](https://semver.org/lang/de/) der API zu erreichen. Lässt man die Versionierung weg, 
+wird die aktuellste Version verwendet. (Siehe Gitblit um verfügbare Versionen einzusehen)
+ 
+
+
+ 
+#### Typdefinition auch ohne Build-System nutzen
+Beim Arbeiten mit Visual Studio Code kann man auch ohne Einsatz weiterer Entwicklungswerkzeuge 
+und Build-Systeme von der Typdefinition der IDE API profitieren. Hierzu muss ein spezielles Kommentar 
+an den Anfang der JavaScript-Datei platziert werden (Pfad anpassen!): 
 
     /// <reference path="../node_modules/@mathcoach/ide-api/mathcoach-api.d.ts"/>
 
-Wie man der Git-Repo URL ansieht, werden Git-Tags verwendet um eine 
-Versionierung [(Semantic Versioning)](https://semver.org/lang/de/)
-der API zu erreichen. Lässt man die Versionierung weg, wird die 
-aktuellste Version verwendet. (Siehe Gitblit um verfügbare Versionen
-einzusehen)
+Dies sorgt dafür, dass Visual Studio Code Autovervollständigung samt Dokumentation der 
+IDE API anbieten kann. Nachteilig ist, dass die `mathcoach-api.d.ts` dazu heruntergeladen
+werden muss.
 
-
-Zertifikat von Newton hinzufügen, damit npm auf das Repository zugreifen kann.
+#### Zertifikat-Problem beheben
+Falls es Probleme mit dem HTW Zertifikat gibt, muss das Zertifikat von Newton ggf. von
+Hand hinzugefügt werden. Nur so kann npm auf das Git-Repository zugreifen und den 
+Inhalt automatisch herunterladen.
 
     cd /usr/local/share/ca-certificates/
     sudo mkdir newton.htwsaar.de
-    
+
     sudo cp path/to/newton.htwsaar.de.crt /usr/local/share/ca-certificates/newton.htwsaar.de/
-    
-    sudo chown 755 /usr/local/share/ca-certificates/newton.htwsaar.de 
+
+    sudo chown 755 /usr/local/share/ca-certificates/newton.htwsaar.de
     sudo chown 644 /usr/local/share/ca-certificates/newton.htwsaar.de/newton.htwsaar.de.crt
     sudo update-ca-certificates
 
 
-    
+
 ## Werkzeuge in die IDE integrieren
 Damit die IDE das Werkzeug integrieren kann, muss eine Werkzeug-Deklaration registriert werden. Zur
-Entwicklungszeit kann der Werkzeug-Entwickler dies lokal vornehmen. Anschließend können verknüpfte 
-Dateien mit dem Werkzeug geöffnet werden und erstellt werden (siehe Kontext-Menüs im IDE-Explorer).  
-Eine Freischaltung des Werkzeugs für alle Autoren erfolgt durch einen Administrator. 
+Entwicklungszeit kann der Werkzeug-Entwickler dies lokal vornehmen. Anschließend können verknüpfte
+Dateien mit dem Werkzeug geöffnet werden und erstellt werden (siehe Kontext-Menüs im IDE-Explorer).
+Eine Freischaltung des Werkzeugs für alle Autoren erfolgt durch einen Administrator.
 
-### Lokal (Nur für den Entwickler des Werkzeugs) 
-In der IDE muss eine Werkzeug-Deklaration angelegt werden, dazu muss die Datei `ide-settings.json` editiert werden:  
+### Lokal (Nur für den Entwickler des Werkzeugs)
+In der IDE muss eine Werkzeug-Deklaration angelegt werden, dazu muss die Datei `ide-settings.json` editiert werden:
 
     {
         ...
-        "editor.external.declarations": [ 
+        "editor.external.declarations": [
             {
-                "displayName": "Dummy",                          
-                "entry": "/mathcoach/www/YOURNAME/tool.html",   
-                "description": "...",                            
-                "developer": "...",                              
-                "extension": "ext"                             
+                "displayName": "Dummy",
+                "entry": "/mathcoach/www/YOURNAME/tool.html",
+                "description": "...",
+                "developer": "...",
+                "extension": "fib.json"
             }
             ...
-        ], 
+        ],
         ...
-    } 
+    }
 
 | Schlüssel | Beschreibung  | Beispiel  |
 |---------------|---|---|
@@ -124,30 +266,32 @@
 
 
 ### Global (Für alle Autoren)
--   Das Werkzeug samt Werkzeug-Deklaration muss als `.zip`-Datei an einen Administrator übergeben werden
+-   Das Werkzeug samt Werkzeug-Deklaration muss an einen Administrator übergeben werden
 -   Der Administrator schaltet das Werkzeug nach einer kurzen Prüfung (Keine Konflikte mit anderen
     Dateierweiterung, usw) frei. Beim nächsten Release von MathCoach ist das Werkzeug dann für alle
     Autoren verfügbar.
- 
 
 
- 
+
+
 ## Infos zu diesem Repository
 
     .
     ├── CHANGELOG.md                // Dokumentation von Änderungen der API
     ├── examples                    // Beispiele
-    │   ├── ... 
+    │   ├── ...
+    │   └── ...
+    ├── media                       // Grafiken
     │   └── ...
     ├── src                         // Hilfsfunktionen für Werkzeugentwickler
     │   ├── index.ts                // Einstiegspunkt
     │   └── ...
-    ├── mathcoach-api.d.ts          // Definition der API
-    ├── package.json                
+    ├── mathcoach-api.d.ts          // Typ-Definition der API
+    ├── package.json
     ├── package-lock.json
     ├── README.md
     └── tsconfig.json
-    
+
 
 ### Dokumentation erzeugen
 

--
Gitblit v1.10.0-SNAPSHOT