webgal-parser 4.5.2 → 4.5.16

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.
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Preprocessor for scene text.
3
+ *
4
+ * Use two-pass to generate a new scene text that concats multiline sequences
5
+ * into a single line and add placeholder lines to preserve the original number
6
+ * of lines.
7
+ *
8
+ * @param sceneText The original scene text
9
+ * @returns The processed scene text
10
+ */
11
+ export function sceneTextPreProcess(sceneText: string): string {
12
+ let lines = sceneText.replaceAll('\r', '').split('\n');
13
+
14
+ lines = sceneTextPreProcessPassOne(lines);
15
+ lines = sceneTextPreProcessPassTwo(lines);
16
+
17
+ return lines.join('\n');
18
+ }
19
+
20
+ /**
21
+ * Pass one.
22
+ *
23
+ * Add escape character to all lines that should be multiline.
24
+ *
25
+ * @param lines The original lines
26
+ * @returns The processed lines
27
+ */
28
+ function sceneTextPreProcessPassOne(lines: string[]): string[] {
29
+ const processedLines: string[] = [];
30
+ let lastLineIsMultiline = false;
31
+ let thisLineIsMultiline = false;
32
+
33
+ for (const line of lines) {
34
+ thisLineIsMultiline = false;
35
+
36
+ if (canBeMultiline(line)) {
37
+ thisLineIsMultiline = true;
38
+ }
39
+
40
+ if (shouldNotBeMultiline(line, lastLineIsMultiline)) {
41
+ thisLineIsMultiline = false;
42
+ }
43
+
44
+ if (thisLineIsMultiline) {
45
+ processedLines[processedLines.length - 1] += '\\';
46
+ }
47
+
48
+ processedLines.push(line);
49
+
50
+ lastLineIsMultiline = thisLineIsMultiline;
51
+ }
52
+
53
+ return processedLines;
54
+ }
55
+
56
+ function canBeMultiline(line: string): boolean {
57
+ if (!line.startsWith(' ')) {
58
+ return false;
59
+ }
60
+
61
+ const trimmedLine = line.trimStart();
62
+ return trimmedLine.startsWith('|') || trimmedLine.startsWith('-');
63
+ }
64
+
65
+ /**
66
+ * Logic to check if a line should not be multiline.
67
+ *
68
+ * @param line The line to check
69
+ * @returns If the line should not be multiline
70
+ */
71
+ function shouldNotBeMultiline(line: string, lastLineIsMultiline: boolean): boolean {
72
+ if (!lastLineIsMultiline && isEmptyLine(line)) {
73
+ return true;
74
+ }
75
+
76
+ // Custom logic: if the line contains -concat, it should not be multiline
77
+ if (line.indexOf('-concat') !== -1) {
78
+ return true;
79
+ }
80
+
81
+ return false;
82
+ }
83
+
84
+ function isEmptyLine(line: string): boolean {
85
+ return line.trim() === '';
86
+ }
87
+
88
+
89
+ /**
90
+ * Pass two.
91
+ *
92
+ * Traverse the lines to
93
+ * - remove escape characters
94
+ * - add placeholder lines to preserve the original number of lines.
95
+ *
96
+ * @param lines The lines in pass one
97
+ * @returns The processed lines
98
+ */
99
+ function sceneTextPreProcessPassTwo(lines: string[]): string[] {
100
+ const processedLines: string[] = [];
101
+ let currentMultilineContent = "";
102
+ let placeHolderLines: string[] = [];
103
+
104
+ function concat(line: string) {
105
+ let trimmed = line.trim();
106
+ if (trimmed.startsWith('-')) {
107
+ trimmed = " " + trimmed;
108
+ }
109
+ currentMultilineContent = currentMultilineContent + trimmed;
110
+ placeHolderLines.push(placeholderLine(line));
111
+ }
112
+
113
+ for (const line of lines) {
114
+ console.log(line);
115
+ if (line.endsWith('\\')) {
116
+ const trueLine = line.slice(0, -1);
117
+
118
+ if (currentMultilineContent === "") {
119
+ // first line
120
+ currentMultilineContent = trueLine;
121
+ } else {
122
+ // middle line
123
+ concat(trueLine);
124
+ }
125
+ continue;
126
+ }
127
+
128
+ if (currentMultilineContent !== "") {
129
+ // end line
130
+ concat(line);
131
+ processedLines.push(currentMultilineContent);
132
+ processedLines.push(...placeHolderLines);
133
+
134
+ placeHolderLines = [];
135
+ currentMultilineContent = "";
136
+ continue;
137
+ }
138
+
139
+ processedLines.push(line);
140
+ }
141
+
142
+ return processedLines;
143
+ }
144
+
145
+ /**
146
+ * Placeholder Line. Adding this line preserves the original number of lines
147
+ * in the scene text, so that it can be compatible with the graphical editor.
148
+ *
149
+ * @param content The original content on this line
150
+ * @returns The placeholder line
151
+ */
152
+ function placeholderLine(content = "") {
153
+ return ";_WEBGAL_LINE_BREAK_" + content;
154
+ }
155
+
156
+ // export function sceneTextPreProcess(sceneText: string): string {
157
+ // const lines = sceneText.replaceAll('\r', '').split('\n');
158
+ // const processedLines: string[] = [];
159
+ // let lastNonMultilineIndex = -1;
160
+ // let isInMultilineSequence = false;
161
+
162
+ // function isMultiline(line: string): boolean {
163
+ // if (!line.startsWith(' ')) return false;
164
+ // const trimmedLine = line.trimStart();
165
+ // return trimmedLine.startsWith('|') || trimmedLine.startsWith('-');
166
+ // }
167
+
168
+ // for (let i = 0; i < lines.length; i++) {
169
+ // const line = lines[i];
170
+
171
+ // if (line.trim() === '') {
172
+ // // Empty line handling
173
+ // if (isInMultilineSequence) {
174
+ // // Check if the next line is a multiline line
175
+
176
+ // let isStillInMulti = false;
177
+ // for (let j = i + 1; j < lines.length; j++) {
178
+ // const lookForwardLine = lines[j] || '';
179
+ // // 遇到正常语句了,直接中断
180
+ // if (lookForwardLine.trim() !== '' && !isMultiline(lookForwardLine)) {
181
+ // isStillInMulti = false;
182
+ // break;
183
+ // }
184
+ // // 必须找到后面接的是参数,并且中间没有遇到任何正常语句才行
185
+ // if (lookForwardLine.trim() !== '' && isMultiline(lookForwardLine)) {
186
+ // isStillInMulti = true;
187
+ // break;
188
+ // }
189
+ // }
190
+ // if (isStillInMulti) {
191
+ // // Still within a multiline sequence
192
+ // processedLines.push(';_WEBGAL_LINE_BREAK_');
193
+ // } else {
194
+ // // End of multiline sequence
195
+ // isInMultilineSequence = false;
196
+ // processedLines.push(line);
197
+ // }
198
+ // } else {
199
+ // // Preserve empty lines outside of multiline sequences
200
+ // processedLines.push(line);
201
+ // }
202
+ // } else if (isMultiline(line)) {
203
+ // // Multiline statement handling
204
+ // if (lastNonMultilineIndex >= 0) {
205
+ // // Concatenate to the previous non-multiline statement
206
+ // const trimedLine = line.trimStart();
207
+ // const addBlank = trimedLine.startsWith('-') ? ' ' : '';
208
+ // processedLines[lastNonMultilineIndex] += addBlank + trimedLine;
209
+ // }
210
+
211
+ // // Add the special comment line
212
+ // processedLines.push(';_WEBGAL_LINE_BREAK_' + line);
213
+ // isInMultilineSequence = true;
214
+ // } else {
215
+ // // Non-multiline statement handling
216
+ // processedLines.push(line);
217
+ // lastNonMultilineIndex = processedLines.length - 1;
218
+ // isInMultilineSequence = false;
219
+ // }
220
+ // }
221
+
222
+ // return processedLines.join('\n');
223
+ // }
@@ -23,10 +23,10 @@ export function argsParser(
23
23
  });
24
24
  rawArgsList.forEach((e) => {
25
25
  const equalSignIndex = e.indexOf('=');
26
- let argName = e.slice(0, equalSignIndex);
27
- let argValue: string | undefined = e.slice(equalSignIndex + 1);
26
+ let argName = e.slice(0, equalSignIndex).trim();
27
+ let argValue: string | undefined = e.slice(equalSignIndex + 1).trim();
28
28
  if (equalSignIndex < 0) {
29
- argName = e;
29
+ argName = e.trim();
30
30
  argValue = undefined;
31
31
  }
32
32
  // 判断是不是语音参数
@@ -45,12 +45,12 @@ export const contentParser = (
45
45
  };
46
46
 
47
47
  function getChooseContent(contentRaw: string, assetSetter: any): string {
48
- const chooseList = contentRaw.split('|');
48
+ const chooseList = contentRaw.split(/(?<!\\)\|/);
49
49
  const chooseKeyList: Array<string> = [];
50
50
  const chooseValueList: Array<string> = [];
51
51
  for (const e of chooseList) {
52
- chooseKeyList.push(e.split(':')[0] ?? '');
53
- chooseValueList.push(e.split(':')[1] ?? '');
52
+ chooseKeyList.push(e.split(/(?<!\\):/)[0] ?? '');
53
+ chooseValueList.push(e.split(/(?<!\\):/)[1] ?? '');
54
54
  }
55
55
  const parsedChooseList = chooseValueList.map((e) => {
56
56
  if (e.match(/\./)) {
@@ -36,14 +36,16 @@ export const scriptParser = (
36
36
  // 正式开始解析
37
37
 
38
38
  // 去分号
39
- let newSentenceRaw = sentenceRaw.split(/(?<!\\);/)[0];
39
+ const commentSplit = sentenceRaw.split(/(?<!\\);/);
40
+ let newSentenceRaw = commentSplit[0].trim();
40
41
  newSentenceRaw = newSentenceRaw.replaceAll('\\;',';');
42
+ const sentenceComment = commentSplit[1] ?? '';
41
43
  if (newSentenceRaw === '') {
42
44
  // 注释提前返回
43
45
  return {
44
46
  command: commandType.comment, // 语句类型
45
47
  commandRaw: 'comment', // 命令原始内容,方便调试
46
- content: sentenceRaw.split(';')[1] ?? '', // 语句内容
48
+ content: sentenceComment.trim(), // 语句内容
47
49
  args: [{ key: 'next', value: true }], // 参数列表
48
50
  sentenceAssets: [], // 语句携带的资源列表
49
51
  subScene: [], // 语句携带的子场景