-
Notifications
You must be signed in to change notification settings - Fork 9
/
journal.js
110 lines (87 loc) · 3.68 KB
/
journal.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
(function journalMacros() {
/**
<<journaladd "Santa Claus" "characters">>Lives on North Pole (this is journal entry content)<</journaladd>>
<<journaladd "Santa Claus" "characters">>Has 4 reindeers<</journaladd>>
<<journaldisplay "Santa Claus" "characters">>Gift giver (this serves as optional title)<</journaldisplay>>
// renders all entries in order they were entered
<<journalreplace "Santa Claus" "characters">>Doesn't exist!!!<</journalreplace>>
<<journaldisplay "Santa Claus" "characters">><</journaldisplay>>
// Will show only one entry
<<journalreplace "Santa Claus" "characters" true>>(Nothing will be shown when journaldisplay called)<</journalreplace>>
Note that you need to have exactly 3 arguments for this to work
All arguments are optional and defaults to empty strings
<<journaladd "Santa Claus">>Have all journal entries in one place<</journaladd>>
<<journalreplace "Santa Claus" "">><</journalreplace>>
Entries content gets rendered when <<journaldisplay>> is used, not when they are added:
<<set $melike = "pies">>
<<journaladd>>I like $melike!<</journaladd>>
<<set $melike = "ice cream">>
<<journaldisplay>>Me<</journaldisplay>>
Internally, all entries are stored in `State.variables.journal`.
*/
'use strict';
/* globals version, State, Macro */
if (!version || !version.title || 'SugarCube' !== version.title || !version.major || version.major < 2) {
throw new Error('<<journal*>> macros family requires SugarCube 2.0 or greater, aborting load');
}
if (!State.variables.journal) {
State.variables.journal = {};
}
function ensureNameType(args) {
let name = args[0] || '';
let type = args[1] || '';
if (name.startsWith('$')) {
name = State.variables.journal[name.slice(1)];
}
if (type.startsWith('$')) {
type = State.variables.journal[type.slice(1)];
}
if (!State.variables.journal[type]) {
State.variables.journal[type] = {};
}
return {name, type};
}
Macro.add('journaladd', {
tags: null,
handler () {
const {name, type} = ensureNameType(this.args);
const entry = this.payload[0].contents.trim();
if (!State.variables.journal[type][name]) {
State.variables.journal[type][name] = [];
}
State.variables.journal[type][name].push(entry);
},
});
Macro.add('journalreplace', {
tags: null,
handler () {
const {name, type} = ensureNameType(this.args);
if (this.args.length === 3 && this.args[2] === true) {
State.variables.journal[type][name] = [];
} else {
State.variables.journal[type][name] = [this.payload[0].contents];
}
},
});
function getTitle(payload) {
return payload[0].contents || '';
}
function renderJournalSection(title, entries) {
const ul = jQuery('<ul class="journalEntries"></ul>');
entries.forEach((entry) => jQuery('<li></li>').wiki(entry).appendTo(ul));
jQuery(`<header class="journalHeader">${title}</header>`).insertBefore(ul);
return ul;
}
Macro.add('journaldisplay', {
tags: null,
handler () {
const {name, type} = ensureNameType(this.args);
const title = getTitle(this.payload);
const entries = State.variables.journal[type][name];
if (entries && entries.length) {
const out = renderJournalSection(title, entries);
out.appendTo(this.output);
}
},
});
}());