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.
package/build/es/index.js CHANGED
@@ -33,52 +33,62 @@ var commandType;
33
33
  commandType[commandType["setTransition"] = 30] = "setTransition";
34
34
  commandType[commandType["getUserInput"] = 31] = "getUserInput";
35
35
  commandType[commandType["applyStyle"] = 32] = "applyStyle";
36
+ commandType[commandType["wait"] = 33] = "wait";
36
37
  })(commandType || (commandType = {}));
37
38
 
38
39
  const SCRIPT_CONFIG = [
39
- { scriptString: 'intro', scriptType: commandType.intro },
40
+ { scriptString: 'say', scriptType: commandType.say },
40
41
  { scriptString: 'changeBg', scriptType: commandType.changeBg },
41
42
  { scriptString: 'changeFigure', scriptType: commandType.changeFigure },
43
+ { scriptString: 'bgm', scriptType: commandType.bgm },
44
+ { scriptString: 'playVideo', scriptType: commandType.video },
45
+ { scriptString: 'pixiPerform', scriptType: commandType.pixi },
46
+ { scriptString: 'pixiInit', scriptType: commandType.pixiInit },
47
+ { scriptString: 'intro', scriptType: commandType.intro },
42
48
  { scriptString: 'miniAvatar', scriptType: commandType.miniAvatar },
43
49
  { scriptString: 'changeScene', scriptType: commandType.changeScene },
44
50
  { scriptString: 'choose', scriptType: commandType.choose },
45
51
  { scriptString: 'end', scriptType: commandType.end },
46
- { scriptString: 'bgm', scriptType: commandType.bgm },
47
- { scriptString: 'playVideo', scriptType: commandType.video },
48
52
  {
49
53
  scriptString: 'setComplexAnimation',
50
54
  scriptType: commandType.setComplexAnimation,
51
55
  },
52
56
  { scriptString: 'setFilter', scriptType: commandType.setFilter },
53
- { scriptString: 'pixiInit', scriptType: commandType.pixiInit },
54
- { scriptString: 'pixiPerform', scriptType: commandType.pixi },
55
57
  { scriptString: 'label', scriptType: commandType.label },
56
58
  { scriptString: 'jumpLabel', scriptType: commandType.jumpLabel },
59
+ { scriptString: 'chooseLabel', scriptType: commandType.chooseLabel },
57
60
  { scriptString: 'setVar', scriptType: commandType.setVar },
61
+ { scriptString: 'if', scriptType: commandType.if },
58
62
  { scriptString: 'callScene', scriptType: commandType.callScene },
59
63
  { scriptString: 'showVars', scriptType: commandType.showVars },
60
64
  { scriptString: 'unlockCg', scriptType: commandType.unlockCg },
61
65
  { scriptString: 'unlockBgm', scriptType: commandType.unlockBgm },
62
- { scriptString: 'say', scriptType: commandType.say },
63
66
  { scriptString: 'filmMode', scriptType: commandType.filmMode },
64
- { scriptString: 'callScene', scriptType: commandType.callScene },
65
67
  { scriptString: 'setTextbox', scriptType: commandType.setTextbox },
66
68
  { scriptString: 'setAnimation', scriptType: commandType.setAnimation },
67
69
  { scriptString: 'playEffect', scriptType: commandType.playEffect },
70
+ { scriptString: 'setTempAnimation', scriptType: commandType.setTempAnimation },
71
+ // comment?
72
+ { scriptString: 'setTransform', scriptType: commandType.setTransform },
73
+ { scriptString: 'setTransition', scriptType: commandType.setTransition },
74
+ { scriptString: 'getUserInput', scriptType: commandType.getUserInput },
68
75
  { scriptString: 'applyStyle', scriptType: commandType.applyStyle },
76
+ { scriptString: 'wait', scriptType: commandType.wait },
69
77
  ];
70
78
  const ADD_NEXT_ARG_LIST = [
71
79
  commandType.bgm,
72
80
  commandType.pixi,
73
81
  commandType.pixiInit,
82
+ commandType.miniAvatar,
74
83
  commandType.label,
75
84
  commandType.if,
76
- commandType.miniAvatar,
77
85
  commandType.setVar,
78
- commandType.unlockBgm,
79
86
  commandType.unlockCg,
87
+ commandType.unlockBgm,
80
88
  commandType.filmMode,
81
89
  commandType.playEffect,
90
+ commandType.setTransition,
91
+ commandType.applyStyle,
82
92
  ];
83
93
 
84
94
  /**
@@ -114,10 +124,10 @@ function argsParser(argsRaw, assetSetter) {
114
124
  });
115
125
  rawArgsList.forEach((e) => {
116
126
  const equalSignIndex = e.indexOf('=');
117
- let argName = e.slice(0, equalSignIndex);
118
- let argValue = e.slice(equalSignIndex + 1);
127
+ let argName = e.slice(0, equalSignIndex).trim();
128
+ let argValue = e.slice(equalSignIndex + 1).trim();
119
129
  if (equalSignIndex < 0) {
120
- argName = e;
130
+ argName = e.trim();
121
131
  argValue = undefined;
122
132
  }
123
133
  // 判断是不是语音参数
@@ -178,7 +188,7 @@ function configLineParser(inputLine) {
178
188
  };
179
189
  }
180
190
  // 截取命令
181
- const getCommandResult = /:/.exec(newSentenceRaw);
191
+ const getCommandResult = /\s*:\s*/.exec(newSentenceRaw);
182
192
  // 没有command
183
193
  if (getCommandResult === null) {
184
194
  command = '';
@@ -300,12 +310,12 @@ const contentParser = (contentRaw, type, assetSetter) => {
300
310
  }
301
311
  };
302
312
  function getChooseContent(contentRaw, assetSetter) {
303
- const chooseList = contentRaw.split('|');
313
+ const chooseList = contentRaw.split(/(?<!\\)\|/);
304
314
  const chooseKeyList = [];
305
315
  const chooseValueList = [];
306
316
  for (const e of chooseList) {
307
- chooseKeyList.push(e.split(':')[0] ?? '');
308
- chooseValueList.push(e.split(':')[1] ?? '');
317
+ chooseKeyList.push(e.split(/(?<!\\):/)[0] ?? '');
318
+ chooseValueList.push(e.split(/(?<!\\):/)[1] ?? '');
309
319
  }
310
320
  const parsedChooseList = chooseValueList.map((e) => {
311
321
  if (e.match(/\./)) {
@@ -433,14 +443,16 @@ const scriptParser = (sentenceRaw, assetSetter, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG
433
443
  let commandRaw;
434
444
  // 正式开始解析
435
445
  // 去分号
436
- let newSentenceRaw = sentenceRaw.split(/(?<!\\);/)[0];
446
+ const commentSplit = sentenceRaw.split(/(?<!\\);/);
447
+ let newSentenceRaw = commentSplit[0].trim();
437
448
  newSentenceRaw = newSentenceRaw.replaceAll('\\;', ';');
449
+ const sentenceComment = commentSplit[1] ?? '';
438
450
  if (newSentenceRaw === '') {
439
451
  // 注释提前返回
440
452
  return {
441
453
  command: commandType.comment,
442
454
  commandRaw: 'comment',
443
- content: sentenceRaw.split(';')[1] ?? '',
455
+ content: sentenceComment.trim(),
444
456
  args: [{ key: 'next', value: true }],
445
457
  sentenceAssets: [],
446
458
  subScene: [], // 语句携带的子场景
@@ -1757,7 +1769,7 @@ var uniqWith_1 = uniqWith;
1757
1769
  * @return {IScene} 解析后的场景
1758
1770
  */
1759
1771
  const sceneParser = (rawScene, sceneName, sceneUrl, assetsPrefetcher, assetSetter, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG_MAP) => {
1760
- const rawSentenceList = rawScene.split('\n'); // 原始句子列表
1772
+ const rawSentenceList = rawScene.replaceAll('\r', '').split('\n'); // 原始句子列表
1761
1773
  // 去分号留到后面去做了,现在注释要单独处理
1762
1774
  const rawSentenceListWithoutEmpty = rawSentenceList;
1763
1775
  // .map((sentence) => sentence.split(";")[0])
@@ -1813,6 +1825,198 @@ function parseCSS(css) {
1813
1825
  return [result, specialRules.trim()];
1814
1826
  }
1815
1827
 
1828
+ /**
1829
+ * Preprocessor for scene text.
1830
+ *
1831
+ * Use two-pass to generate a new scene text that concats multiline sequences
1832
+ * into a single line and add placeholder lines to preserve the original number
1833
+ * of lines.
1834
+ *
1835
+ * @param sceneText The original scene text
1836
+ * @returns The processed scene text
1837
+ */
1838
+ function sceneTextPreProcess(sceneText) {
1839
+ let lines = sceneText.replaceAll('\r', '').split('\n');
1840
+ lines = sceneTextPreProcessPassOne(lines);
1841
+ lines = sceneTextPreProcessPassTwo(lines);
1842
+ return lines.join('\n');
1843
+ }
1844
+ /**
1845
+ * Pass one.
1846
+ *
1847
+ * Add escape character to all lines that should be multiline.
1848
+ *
1849
+ * @param lines The original lines
1850
+ * @returns The processed lines
1851
+ */
1852
+ function sceneTextPreProcessPassOne(lines) {
1853
+ const processedLines = [];
1854
+ let lastLineIsMultiline = false;
1855
+ let thisLineIsMultiline = false;
1856
+ for (const line of lines) {
1857
+ thisLineIsMultiline = false;
1858
+ if (canBeMultiline(line)) {
1859
+ thisLineIsMultiline = true;
1860
+ }
1861
+ if (shouldNotBeMultiline(line, lastLineIsMultiline)) {
1862
+ thisLineIsMultiline = false;
1863
+ }
1864
+ if (thisLineIsMultiline) {
1865
+ processedLines[processedLines.length - 1] += '\\';
1866
+ }
1867
+ processedLines.push(line);
1868
+ lastLineIsMultiline = thisLineIsMultiline;
1869
+ }
1870
+ return processedLines;
1871
+ }
1872
+ function canBeMultiline(line) {
1873
+ if (!line.startsWith(' ')) {
1874
+ return false;
1875
+ }
1876
+ const trimmedLine = line.trimStart();
1877
+ return trimmedLine.startsWith('|') || trimmedLine.startsWith('-');
1878
+ }
1879
+ /**
1880
+ * Logic to check if a line should not be multiline.
1881
+ *
1882
+ * @param line The line to check
1883
+ * @returns If the line should not be multiline
1884
+ */
1885
+ function shouldNotBeMultiline(line, lastLineIsMultiline) {
1886
+ if (!lastLineIsMultiline && isEmptyLine(line)) {
1887
+ return true;
1888
+ }
1889
+ // Custom logic: if the line contains -concat, it should not be multiline
1890
+ if (line.indexOf('-concat') !== -1) {
1891
+ return true;
1892
+ }
1893
+ return false;
1894
+ }
1895
+ function isEmptyLine(line) {
1896
+ return line.trim() === '';
1897
+ }
1898
+ /**
1899
+ * Pass two.
1900
+ *
1901
+ * Traverse the lines to
1902
+ * - remove escape characters
1903
+ * - add placeholder lines to preserve the original number of lines.
1904
+ *
1905
+ * @param lines The lines in pass one
1906
+ * @returns The processed lines
1907
+ */
1908
+ function sceneTextPreProcessPassTwo(lines) {
1909
+ const processedLines = [];
1910
+ let currentMultilineContent = "";
1911
+ let placeHolderLines = [];
1912
+ function concat(line) {
1913
+ let trimmed = line.trim();
1914
+ if (trimmed.startsWith('-')) {
1915
+ trimmed = " " + trimmed;
1916
+ }
1917
+ currentMultilineContent = currentMultilineContent + trimmed;
1918
+ placeHolderLines.push(placeholderLine(line));
1919
+ }
1920
+ for (const line of lines) {
1921
+ console.log(line);
1922
+ if (line.endsWith('\\')) {
1923
+ const trueLine = line.slice(0, -1);
1924
+ if (currentMultilineContent === "") {
1925
+ // first line
1926
+ currentMultilineContent = trueLine;
1927
+ }
1928
+ else {
1929
+ // middle line
1930
+ concat(trueLine);
1931
+ }
1932
+ continue;
1933
+ }
1934
+ if (currentMultilineContent !== "") {
1935
+ // end line
1936
+ concat(line);
1937
+ processedLines.push(currentMultilineContent);
1938
+ processedLines.push(...placeHolderLines);
1939
+ placeHolderLines = [];
1940
+ currentMultilineContent = "";
1941
+ continue;
1942
+ }
1943
+ processedLines.push(line);
1944
+ }
1945
+ return processedLines;
1946
+ }
1947
+ /**
1948
+ * Placeholder Line. Adding this line preserves the original number of lines
1949
+ * in the scene text, so that it can be compatible with the graphical editor.
1950
+ *
1951
+ * @param content The original content on this line
1952
+ * @returns The placeholder line
1953
+ */
1954
+ function placeholderLine(content = "") {
1955
+ return ";_WEBGAL_LINE_BREAK_" + content;
1956
+ }
1957
+ // export function sceneTextPreProcess(sceneText: string): string {
1958
+ // const lines = sceneText.replaceAll('\r', '').split('\n');
1959
+ // const processedLines: string[] = [];
1960
+ // let lastNonMultilineIndex = -1;
1961
+ // let isInMultilineSequence = false;
1962
+ // function isMultiline(line: string): boolean {
1963
+ // if (!line.startsWith(' ')) return false;
1964
+ // const trimmedLine = line.trimStart();
1965
+ // return trimmedLine.startsWith('|') || trimmedLine.startsWith('-');
1966
+ // }
1967
+ // for (let i = 0; i < lines.length; i++) {
1968
+ // const line = lines[i];
1969
+ // if (line.trim() === '') {
1970
+ // // Empty line handling
1971
+ // if (isInMultilineSequence) {
1972
+ // // Check if the next line is a multiline line
1973
+ // let isStillInMulti = false;
1974
+ // for (let j = i + 1; j < lines.length; j++) {
1975
+ // const lookForwardLine = lines[j] || '';
1976
+ // // 遇到正常语句了,直接中断
1977
+ // if (lookForwardLine.trim() !== '' && !isMultiline(lookForwardLine)) {
1978
+ // isStillInMulti = false;
1979
+ // break;
1980
+ // }
1981
+ // // 必须找到后面接的是参数,并且中间没有遇到任何正常语句才行
1982
+ // if (lookForwardLine.trim() !== '' && isMultiline(lookForwardLine)) {
1983
+ // isStillInMulti = true;
1984
+ // break;
1985
+ // }
1986
+ // }
1987
+ // if (isStillInMulti) {
1988
+ // // Still within a multiline sequence
1989
+ // processedLines.push(';_WEBGAL_LINE_BREAK_');
1990
+ // } else {
1991
+ // // End of multiline sequence
1992
+ // isInMultilineSequence = false;
1993
+ // processedLines.push(line);
1994
+ // }
1995
+ // } else {
1996
+ // // Preserve empty lines outside of multiline sequences
1997
+ // processedLines.push(line);
1998
+ // }
1999
+ // } else if (isMultiline(line)) {
2000
+ // // Multiline statement handling
2001
+ // if (lastNonMultilineIndex >= 0) {
2002
+ // // Concatenate to the previous non-multiline statement
2003
+ // const trimedLine = line.trimStart();
2004
+ // const addBlank = trimedLine.startsWith('-') ? ' ' : '';
2005
+ // processedLines[lastNonMultilineIndex] += addBlank + trimedLine;
2006
+ // }
2007
+ // // Add the special comment line
2008
+ // processedLines.push(';_WEBGAL_LINE_BREAK_' + line);
2009
+ // isInMultilineSequence = true;
2010
+ // } else {
2011
+ // // Non-multiline statement handling
2012
+ // processedLines.push(line);
2013
+ // lastNonMultilineIndex = processedLines.length - 1;
2014
+ // isInMultilineSequence = false;
2015
+ // }
2016
+ // }
2017
+ // return processedLines.join('\n');
2018
+ // }
2019
+
1816
2020
  class SceneParser {
1817
2021
  assetsPrefetcher;
1818
2022
  assetSetter;
@@ -1856,4 +2060,4 @@ class SceneParser {
1856
2060
  }
1857
2061
  }
1858
2062
 
1859
- export { ADD_NEXT_ARG_LIST, SCRIPT_CONFIG, SceneParser as default };
2063
+ export { ADD_NEXT_ARG_LIST, SCRIPT_CONFIG, SceneParser as default, sceneTextPreProcess };
@@ -7,3 +7,9 @@ export interface sceneEntry {
7
7
  sceneUrl: string;
8
8
  continueLine: number;
9
9
  }
10
+ /**
11
+ * 场景栈条目接口 (兼容性别名)
12
+ * @interface ISceneEntry
13
+ */
14
+ export interface ISceneEntry extends sceneEntry {
15
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 语句类型
3
3
  */
4
- import { sceneEntry } from './runtimeInterface';
4
+ import { ISceneEntry } from './runtimeInterface';
5
5
  import { fileType } from './assets';
6
6
  export declare enum commandType {
7
7
  say = 0,
@@ -36,7 +36,8 @@ export declare enum commandType {
36
36
  setTransform = 29,
37
37
  setTransition = 30,
38
38
  getUserInput = 31,
39
- applyStyle = 32
39
+ applyStyle = 32,
40
+ wait = 33
40
41
  }
41
42
  /**
42
43
  * 单个参数接口
@@ -85,7 +86,7 @@ export interface IScene {
85
86
  */
86
87
  export interface ISceneData {
87
88
  currentSentenceId: number;
88
- sceneStack: Array<sceneEntry>;
89
+ sceneStack: Array<ISceneEntry>;
89
90
  currentScene: IScene;
90
91
  }
91
92
  /**
@@ -0,0 +1,11 @@
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 declare function sceneTextPreProcess(sceneText: string): string;
@@ -3,6 +3,7 @@ import { WebgalConfig } from './configParser/configParser';
3
3
  import { fileType } from './interface/assets';
4
4
  import { IAsset } from './interface/sceneInterface';
5
5
  import { IWebGALStyleObj } from "./styleParser";
6
+ import { sceneTextPreProcess } from "./sceneTextPreProcessor";
6
7
  export default class SceneParser {
7
8
  private readonly assetsPrefetcher;
8
9
  private readonly assetSetter;
@@ -22,3 +23,4 @@ export default class SceneParser {
22
23
  parseScssToWebgalStyleObj(scssString: string): IWebGALStyleObj;
23
24
  }
24
25
  export { ADD_NEXT_ARG_LIST, SCRIPT_CONFIG };
26
+ export { sceneTextPreProcess };
@@ -7,3 +7,9 @@ export interface sceneEntry {
7
7
  sceneUrl: string;
8
8
  continueLine: number;
9
9
  }
10
+ /**
11
+ * 场景栈条目接口 (兼容性别名)
12
+ * @interface ISceneEntry
13
+ */
14
+ export interface ISceneEntry extends sceneEntry {
15
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 语句类型
3
3
  */
4
- import { sceneEntry } from './runtimeInterface';
4
+ import { ISceneEntry } from './runtimeInterface';
5
5
  import { fileType } from './assets';
6
6
  export declare enum commandType {
7
7
  say = 0,
@@ -36,7 +36,8 @@ export declare enum commandType {
36
36
  setTransform = 29,
37
37
  setTransition = 30,
38
38
  getUserInput = 31,
39
- applyStyle = 32
39
+ applyStyle = 32,
40
+ wait = 33
40
41
  }
41
42
  /**
42
43
  * 单个参数接口
@@ -85,7 +86,7 @@ export interface IScene {
85
86
  */
86
87
  export interface ISceneData {
87
88
  currentSentenceId: number;
88
- sceneStack: Array<sceneEntry>;
89
+ sceneStack: Array<ISceneEntry>;
89
90
  currentScene: IScene;
90
91
  }
91
92
  /**
@@ -0,0 +1,11 @@
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 declare function sceneTextPreProcess(sceneText: string): string;