Document markup and improve choice tags

This commit is contained in:
2026-05-17 15:52:41 +02:00
parent c2fb27b6b8
commit 2c54498ee2
52 changed files with 3485 additions and 377 deletions
+31 -6
View File
@@ -8,8 +8,9 @@ class ChoiceDisplayModule extends BaseModule {
constructor() {
super('choice-display', 'Choice Display');
this.dependencies = ['socket-client'];
this.dependencies = ['socket-client', 'markup-parser'];
this.socketClient = null;
this.markupParser = null;
this.container = null;
this.choices = [];
this.inputMode = 'text';
@@ -37,12 +38,14 @@ class ChoiceDisplayModule extends BaseModule {
'assignLetters',
'selectChoice',
'getTagValue',
'getTemplateCell'
'getTemplateCell',
'renderChoiceText'
]);
}
async initialize() {
this.socketClient = this.getModule('socket-client');
this.markupParser = this.getModule('markup-parser');
this.setupContainer();
this.addEventListener(document, 'story:choices', (event) => {
@@ -157,9 +160,14 @@ class ChoiceDisplayModule extends BaseModule {
.trim()
.charAt(0)
.toUpperCase();
if (alphabet.includes(explicit) && !reserved.has(explicit)) {
choice.letter = explicit;
reserved.add(explicit);
const keyExplicit = String(choice.letter || this.getTagValue(choice.tags, 'key') || '')
.trim()
.charAt(0)
.toUpperCase();
const reservedLetter = explicit || keyExplicit;
if (alphabet.includes(reservedLetter) && !reserved.has(reservedLetter)) {
choice.letter = reservedLetter;
reserved.add(reservedLetter);
}
});
@@ -225,7 +233,7 @@ class ChoiceDisplayModule extends BaseModule {
const button = document.createElement('button');
button.type = 'button';
button.className = 'choice-button';
button.innerHTML = `<kbd>${choice.letter}</kbd><span>${this.escapeHtml(choice.text)}</span>`;
button.innerHTML = `<kbd>${this.escapeHtml(choice.letter)}</kbd><span>${this.renderChoiceText(choice.text)}</span>`;
button.addEventListener('click', () => this.selectChoice(choice.index));
item.appendChild(button);
list.appendChild(item);
@@ -265,6 +273,23 @@ class ChoiceDisplayModule extends BaseModule {
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
renderChoiceText(text) {
if (!this.markupParser) {
this.markupParser = this.getModule('markup-parser');
}
if (this.markupParser && typeof this.markupParser.markdownToHtml === 'function') {
return this.markupParser.markdownToHtml(String(text || ''));
}
return this.escapeHtml(text)
.replace(/\*\*\*([^*]+?)\*\*\*/g, '<strong><em>$1</em></strong>')
.replace(/___([^_]+?)___/g, '<strong><em>$1</em></strong>')
.replace(/\*\*([^*]+?)\*\*/g, '<strong>$1</strong>')
.replace(/__([^_]+?)__/g, '<strong>$1</strong>')
.replace(/\*([^*\s][^*]*?)\*/g, '<em>$1</em>')
.replace(/_([^_\s][^_]*?)_/g, '<em>$1</em>');
}
}
const choiceDisplay = new ChoiceDisplayModule();