webgal-parser 4.4.14 → 4.5.2

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.
@@ -36,6 +36,7 @@ var commandType;
36
36
  commandType[commandType["setTransform"] = 29] = "setTransform";
37
37
  commandType[commandType["setTransition"] = 30] = "setTransition";
38
38
  commandType[commandType["getUserInput"] = 31] = "getUserInput";
39
+ commandType[commandType["applyStyle"] = 32] = "applyStyle";
39
40
  })(commandType || (commandType = {}));
40
41
 
41
42
  const SCRIPT_CONFIG = [
@@ -68,6 +69,7 @@ const SCRIPT_CONFIG = [
68
69
  { scriptString: 'setTextbox', scriptType: commandType.setTextbox },
69
70
  { scriptString: 'setAnimation', scriptType: commandType.setAnimation },
70
71
  { scriptString: 'playEffect', scriptType: commandType.playEffect },
72
+ { scriptString: 'applyStyle', scriptType: commandType.applyStyle },
71
73
  ];
72
74
  const ADD_NEXT_ARG_LIST = [
73
75
  commandType.bgm,
@@ -434,8 +436,9 @@ const scriptParser = (sentenceRaw, assetSetter, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG
434
436
  let parsedCommand; // 解析后的命令
435
437
  let commandRaw;
436
438
  // 正式开始解析
437
- // 去分号,前面已做,这里不再需要
438
- let newSentenceRaw = sentenceRaw.split(';')[0];
439
+ // 去分号
440
+ let newSentenceRaw = sentenceRaw.split(/(?<!\\);/)[0];
441
+ newSentenceRaw = newSentenceRaw.replaceAll('\\;', ';');
439
442
  if (newSentenceRaw === '') {
440
443
  // 注释提前返回
441
444
  return {
@@ -485,12 +488,12 @@ const scriptParser = (sentenceRaw, assetSetter, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG
485
488
  args.push(e);
486
489
  }
487
490
  }
488
- content = contentParser(newSentenceRaw, command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
491
+ content = contentParser(newSentenceRaw.trim(), command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
489
492
  sentenceAssets = assetsScanner(command, content, args); // 扫描语句携带资源
490
493
  subScene = subSceneScanner(command, content); // 扫描语句携带子场景
491
494
  return {
492
495
  command: command,
493
- commandRaw: commandRaw,
496
+ commandRaw: commandRaw.trim(),
494
497
  content: content,
495
498
  args: args,
496
499
  sentenceAssets: sentenceAssets,
@@ -1800,15 +1803,14 @@ function parseCSS(css) {
1800
1803
  const result = {};
1801
1804
  let specialRules = '';
1802
1805
  let matches;
1803
- // 匹配类选择器和其内容,包括一层嵌套
1804
- const classRegex = /\.([^{\s]+)\s*{([^}]*?(?:\{[^}]*?\}[^}]*?)?)}/g;
1805
- // 更新特殊规则正则表达式以正确处理一层嵌套,并确保大括号成对出现
1806
+ // 使用非贪婪匹配,尝试正确处理任意层次的嵌套
1807
+ const classRegex = /\.([^{\s]+)\s*{((?:[^{}]*|{[^}]*})*)}/g;
1806
1808
  const specialRegex = /(@[^{]+{\s*(?:[^{}]*{[^}]*}[^{}]*)+\s*})/g;
1807
- // 提取类和样式
1808
1809
  while ((matches = classRegex.exec(css)) !== null) {
1809
- result[matches[1]] = matches[2].trim().replace(/\s*;\s*/g, ';\n');
1810
+ const key = matches[1];
1811
+ const value = matches[2].trim().replace(/\s*;\s*/g, ';\n');
1812
+ result[key] = value;
1810
1813
  }
1811
- // 提取特殊规则,并确保包含所有的大括号
1812
1814
  while ((matches = specialRegex.exec(css)) !== null) {
1813
1815
  specialRules += matches[1].trim() + '\n';
1814
1816
  }
@@ -2,7 +2,7 @@ import { ADD_NEXT_ARG_LIST, SCRIPT_CONFIG, ConfigMap, ConfigItem } from './confi
2
2
  import { WebgalConfig } from './configParser/configParser';
3
3
  import { fileType } from './interface/assets';
4
4
  import { IAsset } from './interface/sceneInterface';
5
- import { IWebGALStyleObj } from "@/styleParser";
5
+ import { IWebGALStyleObj } from "./styleParser";
6
6
  export default class SceneParser {
7
7
  private readonly assetsPrefetcher;
8
8
  private readonly assetSetter;
@@ -35,7 +35,8 @@ export declare enum commandType {
35
35
  comment = 28,
36
36
  setTransform = 29,
37
37
  setTransition = 30,
38
- getUserInput = 31
38
+ getUserInput = 31,
39
+ applyStyle = 32
39
40
  }
40
41
  /**
41
42
  * 单个参数接口
@@ -2,7 +2,7 @@ import { ADD_NEXT_ARG_LIST, SCRIPT_CONFIG, ConfigMap, ConfigItem } from './confi
2
2
  import { WebgalConfig } from './configParser/configParser';
3
3
  import { fileType } from './interface/assets';
4
4
  import { IAsset } from './interface/sceneInterface';
5
- import { IWebGALStyleObj } from "@/styleParser";
5
+ import { IWebGALStyleObj } from "./styleParser";
6
6
  export default class SceneParser {
7
7
  private readonly assetsPrefetcher;
8
8
  private readonly assetSetter;
package/build/es/index.js CHANGED
@@ -32,6 +32,7 @@ var commandType;
32
32
  commandType[commandType["setTransform"] = 29] = "setTransform";
33
33
  commandType[commandType["setTransition"] = 30] = "setTransition";
34
34
  commandType[commandType["getUserInput"] = 31] = "getUserInput";
35
+ commandType[commandType["applyStyle"] = 32] = "applyStyle";
35
36
  })(commandType || (commandType = {}));
36
37
 
37
38
  const SCRIPT_CONFIG = [
@@ -64,6 +65,7 @@ const SCRIPT_CONFIG = [
64
65
  { scriptString: 'setTextbox', scriptType: commandType.setTextbox },
65
66
  { scriptString: 'setAnimation', scriptType: commandType.setAnimation },
66
67
  { scriptString: 'playEffect', scriptType: commandType.playEffect },
68
+ { scriptString: 'applyStyle', scriptType: commandType.applyStyle },
67
69
  ];
68
70
  const ADD_NEXT_ARG_LIST = [
69
71
  commandType.bgm,
@@ -430,8 +432,9 @@ const scriptParser = (sentenceRaw, assetSetter, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG
430
432
  let parsedCommand; // 解析后的命令
431
433
  let commandRaw;
432
434
  // 正式开始解析
433
- // 去分号,前面已做,这里不再需要
434
- let newSentenceRaw = sentenceRaw.split(';')[0];
435
+ // 去分号
436
+ let newSentenceRaw = sentenceRaw.split(/(?<!\\);/)[0];
437
+ newSentenceRaw = newSentenceRaw.replaceAll('\\;', ';');
435
438
  if (newSentenceRaw === '') {
436
439
  // 注释提前返回
437
440
  return {
@@ -481,12 +484,12 @@ const scriptParser = (sentenceRaw, assetSetter, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG
481
484
  args.push(e);
482
485
  }
483
486
  }
484
- content = contentParser(newSentenceRaw, command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
487
+ content = contentParser(newSentenceRaw.trim(), command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
485
488
  sentenceAssets = assetsScanner(command, content, args); // 扫描语句携带资源
486
489
  subScene = subSceneScanner(command, content); // 扫描语句携带子场景
487
490
  return {
488
491
  command: command,
489
- commandRaw: commandRaw,
492
+ commandRaw: commandRaw.trim(),
490
493
  content: content,
491
494
  args: args,
492
495
  sentenceAssets: sentenceAssets,
@@ -1796,15 +1799,14 @@ function parseCSS(css) {
1796
1799
  const result = {};
1797
1800
  let specialRules = '';
1798
1801
  let matches;
1799
- // 匹配类选择器和其内容,包括一层嵌套
1800
- const classRegex = /\.([^{\s]+)\s*{([^}]*?(?:\{[^}]*?\}[^}]*?)?)}/g;
1801
- // 更新特殊规则正则表达式以正确处理一层嵌套,并确保大括号成对出现
1802
+ // 使用非贪婪匹配,尝试正确处理任意层次的嵌套
1803
+ const classRegex = /\.([^{\s]+)\s*{((?:[^{}]*|{[^}]*})*)}/g;
1802
1804
  const specialRegex = /(@[^{]+{\s*(?:[^{}]*{[^}]*}[^{}]*)+\s*})/g;
1803
- // 提取类和样式
1804
1805
  while ((matches = classRegex.exec(css)) !== null) {
1805
- result[matches[1]] = matches[2].trim().replace(/\s*;\s*/g, ';\n');
1806
+ const key = matches[1];
1807
+ const value = matches[2].trim().replace(/\s*;\s*/g, ';\n');
1808
+ result[key] = value;
1806
1809
  }
1807
- // 提取特殊规则,并确保包含所有的大括号
1808
1810
  while ((matches = specialRegex.exec(css)) !== null) {
1809
1811
  specialRules += matches[1].trim() + '\n';
1810
1812
  }
@@ -35,7 +35,8 @@ export declare enum commandType {
35
35
  comment = 28,
36
36
  setTransform = 29,
37
37
  setTransition = 30,
38
- getUserInput = 31
38
+ getUserInput = 31,
39
+ applyStyle = 32
39
40
  }
40
41
  /**
41
42
  * 单个参数接口
@@ -2,7 +2,7 @@ import { ADD_NEXT_ARG_LIST, SCRIPT_CONFIG, ConfigMap, ConfigItem } from './confi
2
2
  import { WebgalConfig } from './configParser/configParser';
3
3
  import { fileType } from './interface/assets';
4
4
  import { IAsset } from './interface/sceneInterface';
5
- import { IWebGALStyleObj } from "@/styleParser";
5
+ import { IWebGALStyleObj } from "./styleParser";
6
6
  export default class SceneParser {
7
7
  private readonly assetsPrefetcher;
8
8
  private readonly assetSetter;
@@ -35,7 +35,8 @@ export declare enum commandType {
35
35
  comment = 28,
36
36
  setTransform = 29,
37
37
  setTransition = 30,
38
- getUserInput = 31
38
+ getUserInput = 31,
39
+ applyStyle = 32
39
40
  }
40
41
  /**
41
42
  * 单个参数接口
@@ -35,6 +35,7 @@ var webgalParser = (function (exports) {
35
35
  commandType[commandType["setTransform"] = 29] = "setTransform";
36
36
  commandType[commandType["setTransition"] = 30] = "setTransition";
37
37
  commandType[commandType["getUserInput"] = 31] = "getUserInput";
38
+ commandType[commandType["applyStyle"] = 32] = "applyStyle";
38
39
  })(commandType || (commandType = {}));
39
40
 
40
41
  const SCRIPT_CONFIG = [
@@ -67,6 +68,7 @@ var webgalParser = (function (exports) {
67
68
  { scriptString: 'setTextbox', scriptType: commandType.setTextbox },
68
69
  { scriptString: 'setAnimation', scriptType: commandType.setAnimation },
69
70
  { scriptString: 'playEffect', scriptType: commandType.playEffect },
71
+ { scriptString: 'applyStyle', scriptType: commandType.applyStyle },
70
72
  ];
71
73
  const ADD_NEXT_ARG_LIST = [
72
74
  commandType.bgm,
@@ -433,8 +435,9 @@ var webgalParser = (function (exports) {
433
435
  let parsedCommand; // 解析后的命令
434
436
  let commandRaw;
435
437
  // 正式开始解析
436
- // 去分号,前面已做,这里不再需要
437
- let newSentenceRaw = sentenceRaw.split(';')[0];
438
+ // 去分号
439
+ let newSentenceRaw = sentenceRaw.split(/(?<!\\);/)[0];
440
+ newSentenceRaw = newSentenceRaw.replaceAll('\\;', ';');
438
441
  if (newSentenceRaw === '') {
439
442
  // 注释提前返回
440
443
  return {
@@ -484,12 +487,12 @@ var webgalParser = (function (exports) {
484
487
  args.push(e);
485
488
  }
486
489
  }
487
- content = contentParser(newSentenceRaw, command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
490
+ content = contentParser(newSentenceRaw.trim(), command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
488
491
  sentenceAssets = assetsScanner(command, content, args); // 扫描语句携带资源
489
492
  subScene = subSceneScanner(command, content); // 扫描语句携带子场景
490
493
  return {
491
494
  command: command,
492
- commandRaw: commandRaw,
495
+ commandRaw: commandRaw.trim(),
493
496
  content: content,
494
497
  args: args,
495
498
  sentenceAssets: sentenceAssets,
@@ -1799,15 +1802,14 @@ var webgalParser = (function (exports) {
1799
1802
  const result = {};
1800
1803
  let specialRules = '';
1801
1804
  let matches;
1802
- // 匹配类选择器和其内容,包括一层嵌套
1803
- const classRegex = /\.([^{\s]+)\s*{([^}]*?(?:\{[^}]*?\}[^}]*?)?)}/g;
1804
- // 更新特殊规则正则表达式以正确处理一层嵌套,并确保大括号成对出现
1805
+ // 使用非贪婪匹配,尝试正确处理任意层次的嵌套
1806
+ const classRegex = /\.([^{\s]+)\s*{((?:[^{}]*|{[^}]*})*)}/g;
1805
1807
  const specialRegex = /(@[^{]+{\s*(?:[^{}]*{[^}]*}[^{}]*)+\s*})/g;
1806
- // 提取类和样式
1807
1808
  while ((matches = classRegex.exec(css)) !== null) {
1808
- result[matches[1]] = matches[2].trim().replace(/\s*;\s*/g, ';\n');
1809
+ const key = matches[1];
1810
+ const value = matches[2].trim().replace(/\s*;\s*/g, ';\n');
1811
+ result[key] = value;
1809
1812
  }
1810
- // 提取特殊规则,并确保包含所有的大括号
1811
1813
  while ((matches = specialRegex.exec(css)) !== null) {
1812
1814
  specialRules += matches[1].trim() + '\n';
1813
1815
  }
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "webgal-parser",
3
- "version": "4.4.14",
3
+ "version": "4.5.2",
4
4
  "description": "WebGAL script parser",
5
5
  "scripts": {
6
6
  "test": "vitest",
7
7
  "coverage": "vitest run --coverage",
8
8
  "build": "rimraf -rf ./build && rollup --config",
9
9
  "build-ci": "rollup --config",
10
- "debug": "tsx test/debug.ts"
10
+ "debug": "tsx test/debug.ts",
11
+ "debug-scss-parser": "tsx test/debugCssParser.ts"
11
12
  },
12
13
  "types": "./build/types/index.d.ts",
13
14
  "module": "./build/es/index.js",
@@ -1,4 +1,4 @@
1
- import { commandType } from '../interface/sceneInterface';
1
+ import {commandType} from '../interface/sceneInterface';
2
2
 
3
3
  export const SCRIPT_CONFIG = [
4
4
  { scriptString: 'intro', scriptType: commandType.intro },
@@ -30,6 +30,7 @@ export const SCRIPT_CONFIG = [
30
30
  { scriptString: 'setTextbox', scriptType: commandType.setTextbox },
31
31
  { scriptString: 'setAnimation', scriptType: commandType.setAnimation },
32
32
  { scriptString: 'playEffect', scriptType: commandType.playEffect },
33
+ { scriptString: 'applyStyle', scriptType: commandType.applyStyle },
33
34
  ];
34
35
  export const ADD_NEXT_ARG_LIST = [
35
36
  commandType.bgm,
package/src/index.ts CHANGED
@@ -8,7 +8,7 @@ import { configParser, WebgalConfig } from './configParser/configParser';
8
8
  import { fileType } from './interface/assets';
9
9
  import { IAsset } from './interface/sceneInterface';
10
10
  import { sceneParser } from './sceneParser';
11
- import {IWebGALStyleObj, scss2cssinjsParser} from "@/styleParser";
11
+ import {IWebGALStyleObj, scss2cssinjsParser} from "./styleParser";
12
12
 
13
13
  export default class SceneParser {
14
14
  private readonly SCRIPT_CONFIG_MAP: ConfigMap;
@@ -37,6 +37,7 @@ export enum commandType {
37
37
  setTransform,
38
38
  setTransition,
39
39
  getUserInput,
40
+ applyStyle
40
41
  }
41
42
 
42
43
  /**
@@ -35,8 +35,9 @@ export const scriptParser = (
35
35
 
36
36
  // 正式开始解析
37
37
 
38
- // 去分号,前面已做,这里不再需要
39
- let newSentenceRaw = sentenceRaw.split(';')[0];
38
+ // 去分号
39
+ let newSentenceRaw = sentenceRaw.split(/(?<!\\);/)[0];
40
+ newSentenceRaw = newSentenceRaw.replaceAll('\\;',';');
40
41
  if (newSentenceRaw === '') {
41
42
  // 注释提前返回
42
43
  return {
@@ -56,7 +57,11 @@ export const scriptParser = (
56
57
  // 没有command,说明这是一条连续对话或单条语句
57
58
  if (getCommandResult === null) {
58
59
  commandRaw = newSentenceRaw;
59
- parsedCommand = commandParser(commandRaw, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG_MAP);
60
+ parsedCommand = commandParser(
61
+ commandRaw,
62
+ ADD_NEXT_ARG_LIST,
63
+ SCRIPT_CONFIG_MAP,
64
+ );
60
65
  command = parsedCommand.type;
61
66
  for (const e of parsedCommand.additionalArgs) {
62
67
  // 由于是连续对话,所以我们去除 speaker 参数。
@@ -72,7 +77,11 @@ export const scriptParser = (
72
77
  getCommandResult.index + 1,
73
78
  newSentenceRaw.length,
74
79
  );
75
- parsedCommand = commandParser(commandRaw, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG_MAP);
80
+ parsedCommand = commandParser(
81
+ commandRaw,
82
+ ADD_NEXT_ARG_LIST,
83
+ SCRIPT_CONFIG_MAP,
84
+ );
76
85
  command = parsedCommand.type;
77
86
  for (const e of parsedCommand.additionalArgs) {
78
87
  args.push(e);
@@ -91,12 +100,12 @@ export const scriptParser = (
91
100
  args.push(e);
92
101
  }
93
102
  }
94
- content = contentParser(newSentenceRaw, command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
103
+ content = contentParser(newSentenceRaw.trim(), command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
95
104
  sentenceAssets = assetsScanner(command, content, args); // 扫描语句携带资源
96
105
  subScene = subSceneScanner(command, content); // 扫描语句携带子场景
97
106
  return {
98
107
  command: command, // 语句类型
99
- commandRaw: commandRaw, // 命令原始内容,方便调试
108
+ commandRaw: commandRaw.trim(), // 命令原始内容,方便调试
100
109
  content: content, // 语句内容
101
110
  args: args, // 参数列表
102
111
  sentenceAssets: sentenceAssets, // 语句携带的资源列表
@@ -20,17 +20,17 @@ function parseCSS(css: string): [Record<string, string>, string] {
20
20
  const result: Record<string, string> = {};
21
21
  let specialRules = '';
22
22
  let matches;
23
- // 匹配类选择器和其内容,包括一层嵌套
24
- const classRegex = /\.([^{\s]+)\s*{([^}]*?(?:\{[^}]*?\}[^}]*?)?)}/g;
25
- // 更新特殊规则正则表达式以正确处理一层嵌套,并确保大括号成对出现
23
+
24
+ // 使用非贪婪匹配,尝试正确处理任意层次的嵌套
25
+ const classRegex = /\.([^{\s]+)\s*{((?:[^{}]*|{[^}]*})*)}/g;
26
26
  const specialRegex = /(@[^{]+{\s*(?:[^{}]*{[^}]*}[^{}]*)+\s*})/g;
27
27
 
28
- // 提取类和样式
29
28
  while ((matches = classRegex.exec(css)) !== null) {
30
- result[matches[1]] = matches[2].trim().replace(/\s*;\s*/g, ';\n');
29
+ const key = matches[1];
30
+ const value = matches[2].trim().replace(/\s*;\s*/g, ';\n');
31
+ result[key] = value;
31
32
  }
32
33
 
33
- // 提取特殊规则,并确保包含所有的大括号
34
34
  while ((matches = specialRegex.exec(css)) !== null) {
35
35
  specialRules += matches[1].trim() + '\n';
36
36
  }