@educspace/eval-editor
v0.4.0
Published
Angular components for authoring educspace exercises: per-kind forms, a markdown editor, and the pure Question↔form mapping behind them.
Readme
@educspace/eval-editor
Angular components for authoring exercises, as packages/element is for
answering them.
The same forms serve slate's console and the questions console. The two tools
disagree about storage, identity and everything around an exercise — sessions
and tags on one side, classes and deadlines on the other — but not about what an
exercise is. That part is Question, and this is its editor.
<eds-question-editor #editor [question]="question" kind="code" />
<button (click)="save(editor.current())">Enregistrer</button>Nothing here talks to a server: a host passes a Question in, reads one back,
and keeps its own vocabulary to itself.
What is in it
| | |
| --------------------------------------------------------------------------------- | -------------------------------------------------------- |
| QuestionEditor | title, prompt and the kind-specific half, assembled |
| FreeTextKind, ChoiceKind, OrderedListKind, CodeKind, WebKind, SqlKind | the halves, exported so a host can compose its own |
| MarkdownEditor | Write / Split / Preview, as a form control |
| renderMarkdown | markdown + $…$ KaTeX + highlighted code, sanitised |
| MonacoEditor, MonacoLoader | Monaco as a form control, from a CDN or the app's assets |
| toFormValue / toQuestion | the mapping, as pure functions |
That last row is the part worth knowing about. Seven kinds each have their own
config and their own way of being subtly wrong — a choice whose "correct" flag
follows the wrong index, a code exercise that loses its hidden post on save.
That is logic, not markup, so it lives apart from the components in
question-form.ts and is tested without a browser.
Wording
The labels are French by default. A library cannot use Angular's i18n
attributes usefully — extraction only scans an application's own sources — so
the strings are data instead:
{ provide: EDS_EDITOR_LABELS, useValue: myLabels }slate, which ships English and French, builds its EditorLabels from
$localize, so both go through its own i18n pipeline.
Monaco
Loaded from a CDN by default, so a consuming app needs no build configuration —
dropping in a component should not mean copying megabytes into someone's
assets/. An app that must work offline provides its own source instead:
{ provide: MONACO_SOURCE, useValue: localMonaco('assets/monaco') }slate does exactly that: it runs a classroom on a local network, sometimes with no internet at all. When Monaco cannot load either way, the editors fall back to plain textareas — authoring has to survive a bad network.
What it deliberately leaves out
- Identity, mode, policy, tags, sheets. All of it belongs to the host.
- The kind is fixed while editing: changing it would throw away everything typed so far, so a host that wants another kind creates another question.
- Attachments. The bytes need a store, which is the host's again. What the
library takes is a
resolveAttachmentfunction so the prompt preview can showattachments/<name>images when the host can resolve them.
Build
npm install
npm run build # dist/ — an Angular partial-compilation package
npm test # the form mapping