In diesem Paket (Das Gitblit Repository findet sich hier)
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.
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.
enableOfflineUsageIfNecessary
)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 (und nicht offline-fähig ist) oder diee IDE (aus
welchen Gründen auch immer) nicht einsatzbereit ist.
if(typeof MC !== "undefined"){
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 das Werkzeug vermutlich zum ersten mal gestartet das Werkzeug:
- Sich initialisieren (z.B. mit einem leeren oder beispielhaften internem Datenmodell)
- Das interne Datenmodell in die Kontext-Datei schreiben
- Die zugehörige Aufgabe generieren. Siehe auch createExerciseFile
weiter unten.
Andernfalls kann das zuvor gespeichertes Datenmodell 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 = createExerciseFile(contextFile);
if(contextFileIsEmpty){
// TODO: init application with new data model (maybe with example contents)
// write serialized model to context file, e.g. using JSON.stringify(...)
let dataModelAsString = JSON.stringify({/* TODO */});
await MC.ide.fs.writeFile(file, dataModelAsString);
// generate exercise
let generatedExerciseCode = "startup { print('Hallo Welt!') }"; // TODO
await MC.ide.fs.writeFile(exerciseFile, generatedExerciseCode);
}else{
// TODO: load data model, e.g. using JSON.parse(contextFileContent)
// TODO: (overwrite context file and generated exercise file)
// TODO: init application based on your data model
}
// show preview
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 generiert
- Die Vorschau zur generierten Aufgabe navigiert
Die generierte Aufgabe soll wie die Kontext-Datei benannt sein, sodass diese vom Benutzer schnell
zugeordnet werden können. Beispielsweise soll ein Werkzeug, welches mit der
Kontext-Datei /path/to/myExercise.mcq.json
gestartet wird die Aufgabe /path/to/myExercise.groovy
erzeugen.
/**
* Kontext-Datei (z.B. "/path/to/myExercise.mcq.json") auf
* Aufgaben-Datei (z.B. "/path/to/myExercise.groovy") abbilden.
*/
export function createExerciseFile(contextFile: MathCoach.File): MathCoach.File {
let file: MathCoach.File = {
part: contextFile.part,
owner: contextFile.owner,
path: contextFile.path.split(".")[0] + ".groovy"
};
return file;
}
Im Verzeichnis ./examples/
finden sich Beispiele für externe Werkzeuge.
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. Dies ist besonders während der Entwicklung nützlich.
import { enableOfflineUsageIfNecessary } from "@mathcoach/ide-api";
let offline: boolean = enableOfflineUsageIfNecessary();
// now use the IDE API
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
weiter unten.
Für größere Werkzeuge sollte ein Build-System wie webpack
oder PARCEL in Kombination mit
TypeScript 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.
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
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"
},
...
}
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):
/// <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)
der API zu erreichen. Lässt man die Versionierung weg, wird die
aktuellste Version verwendet. (Siehe Gitblit um verfügbare Versionen
einzusehen)
Zertifikat von Newton hinzufügen, damit npm auf das Repository zugreifen kann.
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 644 /usr/local/share/ca-certificates/newton.htwsaar.de/newton.htwsaar.de.crt
sudo update-ca-certificates
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.
In der IDE muss eine Werkzeug-Deklaration angelegt werden, dazu muss die Datei ide-settings.json
editiert werden:
{
...
"editor.external.declarations": [
{
"displayName": "Dummy",
"entry": "/mathcoach/www/YOURNAME/tool.html",
"description": "...",
"developer": "...",
"extension": "ext"
}
...
],
...
}
Schlüssel | Beschreibung | Beispiel |
---|---|---|
displayName | Der Name des Werkzeugs | "Fill-In-Blank-Editor" |
entry | Der Einstiegspunkt für das Werkzeugs muss sich auf dem selben Server wie die IDE befinden. | "/mathcoach/www/YOURNAME/tool.html" |
description | Eine kurze Beschreibung | |
developer | Name des Werkzeug-Entwicklers | |
extension | Dateien anhand der Datei-Erweiterung mit dem Werkzeug verknüpfen. Hier sollte etwas eindeutiges gewählt werden | "fib.json" für Dateien wie someExercise.fib.json |
.zip
-Datei an einen Administrator übergeben werden.
├── CHANGELOG.md // Dokumentation von Änderungen der API
├── examples // Beispiele
│ ├── ...
│ └── ...
├── src // Hilfsfunktionen für Werkzeugentwickler
│ ├── index.ts // Einstiegspunkt
│ └── ...
├── mathcoach-api.d.ts // Definition der API
├── package.json
├── package-lock.json
├── README.md
└── tsconfig.json
npm install && npm run build
package.json
eintragengit tag -a VERSION -m '...'
und pushenpackage.json
, ide-lib.js
, ...