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
+ // }
0 commit comments