questmark-webrenderer 1.0.0 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -0
- package/dist/main.js +36 -4
- package/dist/webRender-basic.js +9 -0
- package/main.mjs +10 -1
- package/package.json +2 -2
- package/webRender-basic.js +9 -0
- package/examples/space-alien.html +0 -173
package/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Questmark-Webrenderer
|
|
2
|
+
|
|
3
|
+
This is a simple "inline web renderer and interpreter" for Questmark.
|
|
4
|
+
|
|
5
|
+
It allows you to create "live" Questmark documents that you can easily work on and test in your browser!
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
1. Save your Questmark document (in Markdown source code form!) as a `.html` file
|
|
10
|
+
2. Add the following lines to the bottom of the file, exactly as shown:
|
|
11
|
+
~~~
|
|
12
|
+
```comment
|
|
13
|
+
<script src="https://unpkg.com/questmark-webrenderer@1.0.4/dist/webRender-basic.js"></script>
|
|
14
|
+
<script src="https://unpkg.com/questmark-webrenderer@1.0.4/dist/main.js" type="module"></script>
|
|
15
|
+
```
|
|
16
|
+
~~~
|
|
17
|
+
3. Open the .html file on your browser!
|
|
18
|
+
|
|
19
|
+
(see [space-alien.md.html](https://github.com/jorisvddonk/questmark-webrenderer/blob/master/examples/space-alien.md.html) ([demo](https://raw.githack.com/jorisvddonk/questmark-webrenderer/main/examples/space-alien.md.html)) for an example)
|
|
20
|
+
|
|
21
|
+
You can also save your Questmark documents as `.md` files, but then you need to open them using a webserver that forces the `text/html` Content-Type header. [local-web-server](https://github.com/lwsjs/local-web-server) can do this using the following config file, for example:
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
module.exports = {
|
|
25
|
+
mime: {
|
|
26
|
+
'text/html': ['html', 'md']
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
and then run
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx local-web-server --config-file ws_config.js
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## alternative usage
|
|
38
|
+
|
|
39
|
+
Alternatively, you could load a .md file in your browser, open the browser console, and then paste and execute the following:
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
const qm_wr1 = document.createElement('script'); qm_wr1.setAttribute('src', 'https://unpkg.com/questmark-webrenderer@1.0.4/dist/webRender-basic.js');
|
|
43
|
+
const qm_wr2 = document.createElement('script'); qm_wr2.setAttribute('type', 'module'); qm_wr2.setAttribute('src', 'https://unpkg.com/questmark-webrenderer@1.0.4/dist/main.js');
|
|
44
|
+
document.body.appendChild(qm_wr1);
|
|
45
|
+
document.body.appendChild(qm_wr2);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
try it out [here](https://ghcdn.rawgit.org/jorisvddonk/questmark/master/examples/self-describing.md), for example!
|
|
49
|
+
|
|
50
|
+
## Customization
|
|
51
|
+
|
|
52
|
+
You can currently customize the following things:
|
|
53
|
+
|
|
54
|
+
* Extra foreign functions can be supplied to the VM by setting the global variable `extraForeignFunctions` to a JavaScript object, with the keys mapping to foreign functions passed to the VM. See [foreign-function.md.html](https://github.com/jorisvddonk/questmark-webrenderer/blob/master/examples/foreign-function.md.html) ([demo](https://raw.githack.com/jorisvddonk/questmark-webrenderer/main/examples/foreign-function.md.html)) for an example.
|
|
55
|
+
* The VM can be modified prior to it starting, and can be prevented from auto-starting, by setting the global variable `preRun` to a function that receives the `vm` instance. Return `false` from this function to prevent the VM from auto-starting. See [prerun.md.html](https://github.com/jorisvddonk/questmark-webrenderer/blob/master/examples/prerun.md.html) ([demo](https://raw.githack.com/jorisvddonk/questmark-webrenderer/main/examples/prerun.md.html)).
|
|
56
|
+
|
package/dist/main.js
CHANGED
|
@@ -15904,6 +15904,7 @@
|
|
|
15904
15904
|
const root = unistBuilder('questmarkDocument', { options: {} }, []);
|
|
15905
15905
|
let last_once_directive_nr = 0;
|
|
15906
15906
|
let noLinkBehaviour = NoLinkBehaviour.LOOPBACK_TO_OPTIONS;
|
|
15907
|
+
let retainWhitespace = false;
|
|
15907
15908
|
unistUtilVisitParents$1(tree, 'heading', (x, ancestors) => {
|
|
15908
15909
|
if (ancestors.length > 1) {
|
|
15909
15910
|
return;
|
|
@@ -16044,6 +16045,23 @@
|
|
|
16044
16045
|
qvmState.programList.push(a);
|
|
16045
16046
|
};
|
|
16046
16047
|
const visitorFunc = (node, index, parent) => {
|
|
16048
|
+
let fixText = (n) => {
|
|
16049
|
+
let text = "";
|
|
16050
|
+
if (retainWhitespace) {
|
|
16051
|
+
text = file_contents.substring(n.position.start.offset, n.position.end.offset);
|
|
16052
|
+
}
|
|
16053
|
+
else {
|
|
16054
|
+
text = n.value;
|
|
16055
|
+
}
|
|
16056
|
+
if (parent.type === "paragraph" && parent.children.indexOf(n) === parent.children.length - 1) {
|
|
16057
|
+
text = text + '\n\n';
|
|
16058
|
+
}
|
|
16059
|
+
text = text.replaceAll('\\*', '*').replaceAll('\\[', '[').replaceAll('\\]', ']').replaceAll('\\#', '#').replaceAll('\\`', '`').replaceAll('\\(', '(').replaceAll('\\)', ')');
|
|
16060
|
+
if (parent.type === "emphasis" || parent.type === "strong") {
|
|
16061
|
+
text = `*${text}*`;
|
|
16062
|
+
}
|
|
16063
|
+
return text;
|
|
16064
|
+
};
|
|
16047
16065
|
if (parent === undefined && node.type !== "questmarkDocument") {
|
|
16048
16066
|
return;
|
|
16049
16067
|
}
|
|
@@ -16078,6 +16096,11 @@
|
|
|
16078
16096
|
throw new Error(`Unknown 'options.no_link_behaviour': ${node.options["options"]["no_link_behaviour"]}`);
|
|
16079
16097
|
}
|
|
16080
16098
|
}
|
|
16099
|
+
if (node.options["options"]["whitespace"]) {
|
|
16100
|
+
if (node.options["options"]["whitespace"] === "retain") {
|
|
16101
|
+
retainWhitespace = true;
|
|
16102
|
+
}
|
|
16103
|
+
}
|
|
16081
16104
|
}
|
|
16082
16105
|
}
|
|
16083
16106
|
break;
|
|
@@ -16120,7 +16143,7 @@
|
|
|
16120
16143
|
if (option.text !== null) {
|
|
16121
16144
|
if (option.text.includes("`")) {
|
|
16122
16145
|
// TODO: support inlineCode in options. Can do via `concat`.
|
|
16123
|
-
console.warn("Option text contains a backtick. Inline code elements in option blocks is currently not supported!");
|
|
16146
|
+
console.warn("WARN: Option text contains a backtick. Inline code elements in option blocks is currently not supported!");
|
|
16124
16147
|
}
|
|
16125
16148
|
q(pushString(option.text));
|
|
16126
16149
|
}
|
|
@@ -16148,7 +16171,7 @@
|
|
|
16148
16171
|
instructions.forEach(i => q(i));
|
|
16149
16172
|
}
|
|
16150
16173
|
else {
|
|
16151
|
-
q(pushString(child
|
|
16174
|
+
q(pushString(fixText(child)));
|
|
16152
16175
|
q(invokeFunction("emit"));
|
|
16153
16176
|
}
|
|
16154
16177
|
});
|
|
@@ -16188,7 +16211,7 @@
|
|
|
16188
16211
|
instructions.forEach(i => q(i));
|
|
16189
16212
|
break;
|
|
16190
16213
|
case "text":
|
|
16191
|
-
q(pushString(node
|
|
16214
|
+
q(pushString(fixText(node)));
|
|
16192
16215
|
q(invokeFunction("emit"));
|
|
16193
16216
|
break;
|
|
16194
16217
|
}
|
|
@@ -16210,7 +16233,16 @@
|
|
|
16210
16233
|
const vmState = parseMarkdown(document.body.textContent).qvmState;
|
|
16211
16234
|
console.log(vmState);
|
|
16212
16235
|
vm.loadVMState(vmState);
|
|
16213
|
-
|
|
16236
|
+
let run = true;
|
|
16237
|
+
if (globalThis.preRun) {
|
|
16238
|
+
let result = globalThis.preRun(vm);
|
|
16239
|
+
if (result === false) {
|
|
16240
|
+
run = false;
|
|
16241
|
+
}
|
|
16242
|
+
}
|
|
16243
|
+
if (run) {
|
|
16244
|
+
vm.run();
|
|
16245
|
+
}
|
|
16214
16246
|
|
|
16215
16247
|
globalThis.vm = vm;
|
|
16216
16248
|
|
package/dist/webRender-basic.js
CHANGED
|
@@ -22,6 +22,7 @@ window.choices = (choices) => {
|
|
|
22
22
|
choices.forEach(element => {
|
|
23
23
|
const button = document.createElement('button');
|
|
24
24
|
button.textContent = element.title;
|
|
25
|
+
button.classList.add('questmark');
|
|
25
26
|
button.onclick = () => {
|
|
26
27
|
clear();
|
|
27
28
|
console.log(`Picked #${element.id}: "${element.title}" `);
|
|
@@ -35,12 +36,20 @@ window.emit = (body) => {
|
|
|
35
36
|
if (firstTime === false) {
|
|
36
37
|
document.body.textContent = '';
|
|
37
38
|
firstTime = true;
|
|
39
|
+
|
|
40
|
+
const style = document.createElement('style');
|
|
41
|
+
style.textContent = `span.questmark {
|
|
42
|
+
white-space: pre-line;
|
|
43
|
+
}`;
|
|
44
|
+
document.head.appendChild(style);
|
|
45
|
+
|
|
38
46
|
window.logElement = document.createElement('div');
|
|
39
47
|
document.body.appendChild(window.logElement);
|
|
40
48
|
log = (body) => {
|
|
41
49
|
console.log(body);
|
|
42
50
|
const span = document.createElement('span');
|
|
43
51
|
span.textContent = body;
|
|
52
|
+
span.classList.add('questmark');
|
|
44
53
|
window.logElement.appendChild(span);
|
|
45
54
|
}
|
|
46
55
|
clear = () => {
|
package/main.mjs
CHANGED
|
@@ -9,6 +9,15 @@ const vm = new QuestVM(body => {
|
|
|
9
9
|
const vmState = parseMarkdown(document.body.textContent).qvmState;
|
|
10
10
|
console.log(vmState);
|
|
11
11
|
vm.loadVMState(vmState);
|
|
12
|
-
|
|
12
|
+
let run = true;
|
|
13
|
+
if (globalThis.preRun) {
|
|
14
|
+
let result = globalThis.preRun(vm);
|
|
15
|
+
if (result === false) {
|
|
16
|
+
run = false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
if (run) {
|
|
20
|
+
vm.run();
|
|
21
|
+
}
|
|
13
22
|
|
|
14
23
|
globalThis.vm = vm;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "questmark-webrenderer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "A simple inline parser and renderer for Questmark, to create live testable Questmark documents easily",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"scripts": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"rollup-plugin-shim": "^1.0.0"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"questmark": "^0.0.
|
|
23
|
+
"questmark": "^0.0.11",
|
|
24
24
|
"tzo": "^1.0.10"
|
|
25
25
|
}
|
|
26
26
|
}
|
package/webRender-basic.js
CHANGED
|
@@ -22,6 +22,7 @@ window.choices = (choices) => {
|
|
|
22
22
|
choices.forEach(element => {
|
|
23
23
|
const button = document.createElement('button');
|
|
24
24
|
button.textContent = element.title;
|
|
25
|
+
button.classList.add('questmark');
|
|
25
26
|
button.onclick = () => {
|
|
26
27
|
clear();
|
|
27
28
|
console.log(`Picked #${element.id}: "${element.title}" `);
|
|
@@ -35,12 +36,20 @@ window.emit = (body) => {
|
|
|
35
36
|
if (firstTime === false) {
|
|
36
37
|
document.body.textContent = '';
|
|
37
38
|
firstTime = true;
|
|
39
|
+
|
|
40
|
+
const style = document.createElement('style');
|
|
41
|
+
style.textContent = `span.questmark {
|
|
42
|
+
white-space: pre-line;
|
|
43
|
+
}`;
|
|
44
|
+
document.head.appendChild(style);
|
|
45
|
+
|
|
38
46
|
window.logElement = document.createElement('div');
|
|
39
47
|
document.body.appendChild(window.logElement);
|
|
40
48
|
log = (body) => {
|
|
41
49
|
console.log(body);
|
|
42
50
|
const span = document.createElement('span');
|
|
43
51
|
span.textContent = body;
|
|
52
|
+
span.classList.add('questmark');
|
|
44
53
|
window.logElement.appendChild(span);
|
|
45
54
|
}
|
|
46
55
|
clear = () => {
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
# QUESTMARK-OPTIONS-HEADER
|
|
2
|
-
|
|
3
|
-
{
|
|
4
|
-
"questmark-spec": "1.0",
|
|
5
|
-
"initial-state": "init",
|
|
6
|
-
"initial-context": {
|
|
7
|
-
"asked_about_glowy_bits": 0,
|
|
8
|
-
"cars_not_spaceships": 0,
|
|
9
|
-
"know_about_cheese": 0,
|
|
10
|
-
"know_alien_name": 0,
|
|
11
|
-
"details_about_hamsters": 0,
|
|
12
|
-
"bad_details_about_hamsters": 0
|
|
13
|
-
},
|
|
14
|
-
"options": {
|
|
15
|
-
"no_link_behaviour": "loopback_to_options"
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
# init
|
|
20
|
-
|
|
21
|
-
Greetings, Human! Glad you've finally woken up! You banged your head quite badly there and we were worried that your central processing unit was severely damaged, but it seems that you're fine enough to open your eyes! Wonderful. How do you feel?
|
|
22
|
-
|
|
23
|
-
* `@once` Uuuuh... "central processing unit"?
|
|
24
|
-
|
|
25
|
-
Oh! Right, sorry. "brain" you call it, I think. Funny word. Sounds almost fake, if you ask me.
|
|
26
|
-
|
|
27
|
-
* `@once` Hey! What are those glowy bits inside you? `1 "asked_about_glowy_bits" setContext`
|
|
28
|
-
|
|
29
|
-
Ah, those are a private matter to us. Please don't ask about our glowy bits ever again, thanks.
|
|
30
|
-
|
|
31
|
-
* [What happened?](#what_happen)
|
|
32
|
-
|
|
33
|
-
# what_happen
|
|
34
|
-
|
|
35
|
-
Well, we were zipping around space in our awesome spaceship, when we randomly stumbled upon your nice planet.
|
|
36
|
-
Our pilot figured it'd be great to land on your world, and we did!
|
|
37
|
-
Or, well, we tried to.
|
|
38
|
-
See, the thing is, our spaceship is rather difficult to control in atmospheres as thick as around your world.
|
|
39
|
-
..and... well...
|
|
40
|
-
We happened to accidentally veer widely off course and land RIGHT on top of your parked spaceship.
|
|
41
|
-
Sorry about that!
|
|
42
|
-
|
|
43
|
-
* `0 "cars_not_spaceships" getContext eq` Err... Spaceship? I don't have a spaceship. You mean my car? `1 "cars_not_spaceships" setContext`
|
|
44
|
-
|
|
45
|
-
"Car"? Is that what you call spaceships?
|
|
46
|
-
|
|
47
|
-
* `1 "cars_not_spaceships" getContext eq` No; cars are something different entirely. They're on wheels. We don't have spaceships; not really at least. `2 "cars_not_spaceships" setContext`
|
|
48
|
-
|
|
49
|
-
You don't have spaceships!? Wow! How do you people even get to space?
|
|
50
|
-
|
|
51
|
-
* `2 "cars_not_spaceships" getContext eq` [We don't go to space. Well, not really. Most of us don't. Some do. It's complicated.](#now_what)
|
|
52
|
-
|
|
53
|
-
Oh, I see this bothers you.
|
|
54
|
-
`"asked_about_glowy_bits" getContext jgz {`
|
|
55
|
-
Just like our glowy bits bother us when you ask about it.
|
|
56
|
-
`}`
|
|
57
|
-
We won't mention cars again. Sorry.
|
|
58
|
-
|
|
59
|
-
# now_what
|
|
60
|
-
|
|
61
|
-
* `@once` So, who are you? `1 "know_alien_name" setContext`
|
|
62
|
-
|
|
63
|
-
We are the Humsters. We're intergalactical space travellers! Awesome, huh?
|
|
64
|
-
|
|
65
|
-
* `@once` `"know_alien_name" getContext 1 eq "know_about_cheese" getContext 0 eq and` "Humsters"? That's a bit of a weird name. Sounds familiar.
|
|
66
|
-
|
|
67
|
-
Yeah, some other humanoid-like creature gave it to us. We don't really know why.
|
|
68
|
-
|
|
69
|
-
* `@once` `"know_alien_name" getContext 1 eq "know_about_cheese" getContext 1 eq and` [Oh, no. You're called "Humsters" because you're like Hamsters and like cheese!?](#about_hamsters)
|
|
70
|
-
|
|
71
|
-
```comment
|
|
72
|
-
If you know both their name AND about cheese, you can connect the dots.
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Huh? "Hamsters"? That name sounds just like ours... What are "Hamsters"? Are they also intergalactical space travellers!? We'd love to get to meet more advanced species that also travel across space!
|
|
76
|
-
|
|
77
|
-
* `@once` What are you doing in our solar system? `1 "know_about_cheese" setContext`
|
|
78
|
-
|
|
79
|
-
We're just travelling and looking for cheese.
|
|
80
|
-
|
|
81
|
-
* `@once` `"know_about_cheese" getContext` Cheese?
|
|
82
|
-
|
|
83
|
-
Yeah, we love cheese!
|
|
84
|
-
|
|
85
|
-
* I have had enough. Goodbye!
|
|
86
|
-
|
|
87
|
-
Goodbye, human!
|
|
88
|
-
|
|
89
|
-
`exit`
|
|
90
|
-
|
|
91
|
-
# about_hamsters
|
|
92
|
-
|
|
93
|
-
* [Hamsters are AWESOME](#awesome_hamsters)
|
|
94
|
-
|
|
95
|
-
Wow, they sound amazing!
|
|
96
|
-
|
|
97
|
-
* [Hamsters aren't particularly awesome](#bad_hamsters)
|
|
98
|
-
* Oh, look at my watch, it's time to go. Goodbye!
|
|
99
|
-
|
|
100
|
-
What is a watch?
|
|
101
|
-
Oh... You are already gone.
|
|
102
|
-
Well, goodbye then.
|
|
103
|
-
|
|
104
|
-
`exit`
|
|
105
|
-
|
|
106
|
-
# awesome_hamsters
|
|
107
|
-
|
|
108
|
-
Can you tell us more about hamsters please?
|
|
109
|
-
|
|
110
|
-
* `@once` Hamsters have soft hair `"details_about_hamsters" getContext 1 + "details_about_hamsters" setContext`
|
|
111
|
-
|
|
112
|
-
We have soft hair!
|
|
113
|
-
|
|
114
|
-
* `@once` Hamsters have cute eyes `"details_about_hamsters" getContext 1 + "details_about_hamsters" setContext`
|
|
115
|
-
|
|
116
|
-
We have cute eyes!
|
|
117
|
-
|
|
118
|
-
* `@once` Hamsters have a fuzzy tail `"details_about_hamsters" getContext 1 + "details_about_hamsters" setContext`
|
|
119
|
-
|
|
120
|
-
We have a fuzzy tail!
|
|
121
|
-
|
|
122
|
-
* `@once` `"details_about_hamsters" getContext 3 eq` [Hamsters are great at running in wheels](#humsters_are_hamsters)
|
|
123
|
-
|
|
124
|
-
WE ARE GREAT AT RUNNING IN WHEELS!
|
|
125
|
-
|
|
126
|
-
Wow, Human! It seems that we just discovered something AWESOME.
|
|
127
|
-
|
|
128
|
-
WE.
|
|
129
|
-
ARE.
|
|
130
|
-
HAMSTERS!
|
|
131
|
-
Not Humsters!
|
|
132
|
-
|
|
133
|
-
Wow!
|
|
134
|
-
|
|
135
|
-
# bad_hamsters
|
|
136
|
-
|
|
137
|
-
* `@once` Hamsters smell `"bad_details_about_hamsters" getContext 1 + "bad_details_about_hamsters" setContext`
|
|
138
|
-
|
|
139
|
-
Are you sure about this?
|
|
140
|
-
|
|
141
|
-
* `@once` Hamsters poop `"bad_details_about_hamsters" getContext 1 + "bad_details_about_hamsters" setContext`
|
|
142
|
-
|
|
143
|
-
Are you sure about this?
|
|
144
|
-
|
|
145
|
-
* `@once` Hamsters make lots of noise `"bad_details_about_hamsters" getContext 1 + "bad_details_about_hamsters" setContext`
|
|
146
|
-
|
|
147
|
-
Are you sure about this?
|
|
148
|
-
|
|
149
|
-
* `@once` `"bad_details_about_hamsters" getContext 3 eq` [Hmm, you're right, I might be wrong about hamsters. Now they actually sound pretty awesome](#awesome_hamsters)
|
|
150
|
-
|
|
151
|
-
Wow, I'm sure!
|
|
152
|
-
|
|
153
|
-
# humsters_are_hamsters
|
|
154
|
-
|
|
155
|
-
* Wow, that's amazing.
|
|
156
|
-
|
|
157
|
-
Sure is! I'm glad we managed to figure that out, Human!
|
|
158
|
-
|
|
159
|
-
Now, it seems that it is time for us to run around in a hamster wheel.
|
|
160
|
-
|
|
161
|
-
Goodbye, human!
|
|
162
|
-
|
|
163
|
-
`"goodbye" goto`
|
|
164
|
-
|
|
165
|
-
# goodbye
|
|
166
|
-
|
|
167
|
-
* Goodbye, humsters! `exit`
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
```comment
|
|
171
|
-
<script src="webRender-basic.js"></script>
|
|
172
|
-
<script src="./dist/main.js" type="module"></script>
|
|
173
|
-
```
|