Skip to content

Commit eba9643

Browse files
Merge pull request #588 from OpenWebGAL/dev
4.5.10
2 parents f993450 + 4d6d69e commit eba9643

File tree

19 files changed

+540
-71
lines changed

19 files changed

+540
-71
lines changed

packages/parser/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"build": "rimraf -rf ./build && rollup --config",
99
"build-ci": "rollup --config",
1010
"debug": "tsx test/debug.ts",
11-
"debug-scss-parser": "tsx test/debugCssParser.ts"
11+
"debug-scss-parser": "tsx test/debugCssParser.ts",
12+
"debug-linebreak-parser": "tsx test/debug-linebreak.ts"
1213
},
1314
"types": "./build/types/index.d.ts",
1415
"module": "./build/es/index.js",

packages/parser/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import { configParser, WebgalConfig } from './configParser/configParser';
88
import { fileType } from './interface/assets';
99
import { IAsset } from './interface/sceneInterface';
1010
import { sceneParser } from './sceneParser';
11-
import {IWebGALStyleObj, scss2cssinjsParser} from "./styleParser";
11+
import { IWebGALStyleObj, scss2cssinjsParser } from "./styleParser";
12+
import { sceneTextPreProcess } from "./sceneTextPreProcessor";
1213

1314
export default class SceneParser {
1415
private readonly SCRIPT_CONFIG_MAP: ConfigMap;
@@ -76,3 +77,4 @@ export default class SceneParser {
7677
}
7778

7879
export { ADD_NEXT_ARG_LIST, SCRIPT_CONFIG };
80+
export { sceneTextPreProcess };
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
// }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {sceneTextPreProcess} from "../src/sceneTextPreProcessor";
2+
import * as fsp from "fs/promises";
3+
4+
5+
async function debug() {
6+
const sceneRaw = await fsp.readFile('test/test-resources/line-break.txt');
7+
const sceneText = sceneRaw.toString();
8+
const result = sceneTextPreProcess(sceneText)
9+
console.log(result)
10+
console.log(result.split('\n').length)
11+
}
12+
13+
debug();

0 commit comments

Comments
 (0)