nadesiko3 3.7.20 → 3.7.22

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.
Files changed (162) hide show
  1. package/batch/command.txt +483 -445
  2. package/batch/jsplugin2text.nako3 +1 -1
  3. package/batch/pickup_command.nako3 +12 -0
  4. package/core/command/snako.mts +5 -1
  5. package/core/deno/snako.ts +5 -1
  6. package/core/package-lock.json +382 -21
  7. package/core/package.json +4 -4
  8. package/core/src/README.md +98 -0
  9. package/core/src/nako3.mts +178 -614
  10. package/core/src/nako_basic_plugins.mts +39 -0
  11. package/core/src/nako_core_version.mts +2 -2
  12. package/core/src/nako_csv.mts +0 -1
  13. package/core/src/nako_event.mts +49 -0
  14. package/core/src/nako_gen.mts +291 -202
  15. package/core/src/nako_indent_inline.mts +2 -2
  16. package/core/src/nako_lex_rules.mts +1 -1
  17. package/core/src/nako_parser3.mts +106 -165
  18. package/core/src/nako_parser_async.mts +97 -0
  19. package/core/src/nako_parser_base.mts +4 -55
  20. package/core/src/nako_parser_message.mts +105 -0
  21. package/core/src/nako_parser_operator.mts +93 -0
  22. package/core/src/nako_plugin_manager.mts +260 -0
  23. package/core/src/nako_require.mts +292 -0
  24. package/core/src/nako_runner.mts +191 -0
  25. package/core/src/nako_tokenizer.mts +221 -0
  26. package/core/src/plugin_csv.mts +1 -1
  27. package/core/src/plugin_system.mts +34 -3259
  28. package/core/src/plugin_system_array.mts +699 -0
  29. package/core/src/plugin_system_datetime.mts +368 -0
  30. package/core/src/plugin_system_debug.mts +403 -0
  31. package/core/src/plugin_system_dict.mts +85 -0
  32. package/core/src/plugin_system_json.mts +73 -0
  33. package/core/src/plugin_system_math.mts +383 -0
  34. package/core/src/plugin_system_regexp.mts +120 -0
  35. package/core/src/plugin_system_stdio.mts +86 -0
  36. package/core/src/plugin_system_string.mts +666 -0
  37. package/core/src/plugin_system_timer.mts +152 -0
  38. package/core/src/plugin_system_types.mts +151 -0
  39. package/core/src/plugin_system_url.mts +193 -0
  40. package/core/src/plugin_toml.mts +3 -3
  41. package/core/test/fixtures/README.md +39 -0
  42. package/core/test/fixtures/make_parser_ast_golden.mjs +31 -0
  43. package/core/test/fixtures/parser_ast_golden.json +8027 -0
  44. package/core/test/fixtures/parser_corpus.mjs +120 -0
  45. package/core/test/indent_test.mjs +6 -0
  46. package/core/test/nako_basic_plugins_test.mjs +44 -0
  47. package/core/test/nako_event_test.mjs +85 -0
  48. package/core/test/nako_gen_perf_test.mjs +178 -0
  49. package/core/test/nako_parser_async_test.mjs +112 -0
  50. package/core/test/nako_parser_test.mjs +160 -0
  51. package/core/test/nako_plugin_manager_test.mjs +185 -0
  52. package/core/test/nako_require_test.mjs +153 -0
  53. package/core/test/nako_runner_test.mjs +114 -0
  54. package/core/test/nako_tokenizer_test.mjs +115 -0
  55. package/core/test/plugin_system_debug_test.mjs +141 -0
  56. package/core/test/plugin_system_split_test.mjs +179 -0
  57. package/core/test/plugin_system_test.mjs +6 -0
  58. package/core/tsconfig.json +0 -1
  59. package/package.json +24 -34
  60. package/release/_hash.txt +40 -40
  61. package/release/_script-tags.txt +16 -16
  62. package/release/command.json +1 -1
  63. package/release/command.json.js +1 -1
  64. package/release/command_cnako3.json +1 -1
  65. package/release/command_list.json +1 -1
  66. package/release/edit_main.js +6 -6
  67. package/release/edit_main.js.map +3 -3
  68. package/release/editor.js +6 -6
  69. package/release/plugin_datetime.js +1 -1
  70. package/release/plugin_datetime.js.map +3 -3
  71. package/release/plugin_keigo.js.map +3 -3
  72. package/release/plugin_markup.js +47 -47
  73. package/release/plugin_markup.js.map +3 -3
  74. package/release/plugin_weykturtle3d.js +1 -1
  75. package/release/plugin_weykturtle3d.js.map +3 -3
  76. package/release/version.js +2 -2
  77. package/release/version_main.js +2 -2
  78. package/release/version_main.js.map +2 -2
  79. package/release/wnako3.js +187 -214
  80. package/release/wnako3.js.map +4 -4
  81. package/release/wnako3webworker.js +172 -199
  82. package/release/wnako3webworker.js.map +4 -4
  83. package/src/cnako3mod.mjs +8 -4
  84. package/src/cnako3mod.mts +8 -4
  85. package/src/nako_version.mjs +2 -2
  86. package/src/nako_version.mts +2 -2
  87. package/src/plugin_browser_ajax.mjs +4 -4
  88. package/src/plugin_browser_ajax.mts +4 -4
  89. package/src/plugin_browser_audio.mjs +10 -10
  90. package/src/plugin_browser_audio.mts +10 -10
  91. package/src/plugin_browser_camera.mjs +4 -4
  92. package/src/plugin_browser_camera.mts +4 -4
  93. package/src/plugin_browser_canvas.mjs +2 -2
  94. package/src/plugin_browser_canvas.mts +2 -2
  95. package/src/plugin_browser_crypto.mjs +3 -3
  96. package/src/plugin_browser_crypto.mts +3 -3
  97. package/src/plugin_browser_dom_event.mjs +1 -1
  98. package/src/plugin_browser_dom_event.mts +1 -1
  99. package/src/plugin_browser_geolocation.mjs +1 -1
  100. package/src/plugin_browser_geolocation.mts +1 -1
  101. package/src/plugin_browser_hotkey.mjs +1 -1
  102. package/src/plugin_browser_hotkey.mts +1 -1
  103. package/src/plugin_browser_html.mjs +1 -1
  104. package/src/plugin_browser_html.mts +1 -1
  105. package/src/plugin_browser_location.mjs +1 -1
  106. package/src/plugin_browser_location.mts +1 -1
  107. package/src/plugin_browser_speech.mjs +1 -1
  108. package/src/plugin_browser_speech.mts +1 -1
  109. package/src/plugin_browser_storage.mjs +2 -2
  110. package/src/plugin_browser_storage.mts +2 -2
  111. package/src/plugin_httpserver.mjs +186 -15
  112. package/src/plugin_httpserver.mts +178 -12
  113. package/src/plugin_keigo.mjs +2 -2
  114. package/src/plugin_keigo.mts +2 -2
  115. package/src/plugin_node.mjs +48 -49
  116. package/src/plugin_node.mts +53 -54
  117. package/src/plugin_weykturtle3d.mjs +56 -56
  118. package/src/plugin_weykturtle3d.mts +56 -56
  119. package/src/wnako3.mjs +1 -1
  120. package/src/wnako3.mts +1 -1
  121. package/src/wnako3_editor.mjs +5 -5
  122. package/src/wnako3_editor.mts +5 -5
  123. package/src/wnako3mod.mjs +5 -2
  124. package/src/wnako3mod.mts +5 -2
  125. package/test/common/wnako3mod_test.mjs +48 -0
  126. package/test/node/package_json_test.mjs +17 -0
  127. package/test/node/plugin_httpserver_test.mjs +239 -0
  128. package/tools/nako3server/index.nako3 +4 -2
  129. package/core/src/nako3.mjs +0 -1021
  130. package/core/src/nako_ast.mjs +0 -4
  131. package/core/src/nako_colors.mjs +0 -77
  132. package/core/src/nako_core_version.mjs +0 -8
  133. package/core/src/nako_csv.mjs +0 -193
  134. package/core/src/nako_errors.mjs +0 -166
  135. package/core/src/nako_from_dncl.mjs +0 -285
  136. package/core/src/nako_from_dncl2.mjs +0 -347
  137. package/core/src/nako_gen.mjs +0 -2500
  138. package/core/src/nako_global.mjs +0 -138
  139. package/core/src/nako_indent.mjs +0 -442
  140. package/core/src/nako_indent_chars.mjs +0 -29
  141. package/core/src/nako_indent_inline.mjs +0 -361
  142. package/core/src/nako_josi_list.mjs +0 -47
  143. package/core/src/nako_lex_rules.mjs +0 -319
  144. package/core/src/nako_lexer.mjs +0 -794
  145. package/core/src/nako_logger.mjs +0 -221
  146. package/core/src/nako_parser3.mjs +0 -3250
  147. package/core/src/nako_parser_base.mjs +0 -403
  148. package/core/src/nako_parser_const.mjs +0 -37
  149. package/core/src/nako_prepare.mjs +0 -329
  150. package/core/src/nako_reserved_words.mjs +0 -42
  151. package/core/src/nako_source_mapping.mjs +0 -207
  152. package/core/src/nako_test.mjs +0 -37
  153. package/core/src/nako_token.mjs +0 -1
  154. package/core/src/nako_tools.mjs +0 -53
  155. package/core/src/nako_types.mjs +0 -14
  156. package/core/src/plugin_api.mjs +0 -4
  157. package/core/src/plugin_csv.mjs +0 -97
  158. package/core/src/plugin_math.mjs +0 -352
  159. package/core/src/plugin_promise.mjs +0 -102
  160. package/core/src/plugin_system.mjs +0 -3810
  161. package/core/src/plugin_test.mjs +0 -52
  162. package/core/src/plugin_toml.mjs +0 -39
@@ -1,138 +0,0 @@
1
- import { NakoColors } from './nako_colors.mjs';
2
- /**
3
- * コンパイルされたなでしこのプログラムで、グローバル空間のthisが指すオブジェクト
4
- */
5
- export class NakoGlobal {
6
- /**
7
- * @param compiler
8
- * @param gen
9
- */
10
- constructor(compiler, gen, guid = 0) {
11
- this.guid = guid;
12
- this.lastJSCode = '';
13
- // ユーザーのプログラムから編集される変数
14
- this.__locals = new Map();
15
- this.__varslist = [
16
- compiler.newVaiables(compiler.__varslist[0]), // system
17
- compiler.newVaiables(compiler.__varslist[1]), // global
18
- compiler.newVaiables(compiler.__varslist[2]) // local [2][3][4][5] ...
19
- ];
20
- this.numFailures = 0;
21
- this.index = 0;
22
- this.nextIndex = -1;
23
- this.__code = [];
24
- this.__callstack = [];
25
- this.__stack = [];
26
- this.__labels = [];
27
- this.__genMode = gen.genMode;
28
- // バージョン情報の引き継ぎ
29
- this.version = compiler.version;
30
- this.coreVersion = compiler.coreVersion;
31
- // PluginSystemとdestroy()から参照するため
32
- this.__module = { ...compiler.__module }; // shallow copy
33
- this.pluginfiles = { ...compiler.getPluginfiles() };
34
- // PluginWorkerでユーザー定義関数のJavaScriptコードをworkerのコンパイラのインスタンスへコピーするため
35
- this.gen = gen;
36
- // 以下のメソッドで使うため
37
- this.logger = compiler.getLogger();
38
- this.compiler = compiler;
39
- this.josiList = compiler.josiList;
40
- this.reservedWords = compiler.reservedWords;
41
- }
42
- clearLog() {
43
- this.__varslist[0].set('表示ログ', '');
44
- }
45
- get log() {
46
- let s = this.__varslist[0].get('表示ログ');
47
- s = s.replace(/\s+$/, '');
48
- return s;
49
- }
50
- /**
51
- * システム変数を設定する
52
- * @param name システム変数名
53
- * @param value 設定したい値
54
- */
55
- __setSysVar(name, value) {
56
- this.__varslist[0].set(name, value);
57
- }
58
- /**
59
- * システム変数を取得する
60
- * @param name システム変数名
61
- * @returns システム変数の値
62
- */
63
- __getSysVar(name) {
64
- return this.__varslist[0].get(name);
65
- }
66
- /**
67
- * 「ナデシコ」命令のためのメソッド
68
- */
69
- runEx(code, fname, opts, preCode = '') {
70
- // スコープを共有して実行
71
- opts.preCode = preCode;
72
- opts.nakoGlobal = this;
73
- return this.compiler.runSync(code, fname, opts);
74
- }
75
- async runAsync(code, fname, opts, preCode = '') {
76
- // スコープを共有して実行
77
- opts.preCode = preCode;
78
- opts.nakoGlobal = this;
79
- return await this.compiler.runAsync(code, fname, opts);
80
- }
81
- /**
82
- * テスト実行のためのメソッド
83
- * @param {{ name: string, f: () => void }[]} tests
84
- */
85
- _runTests(tests) {
86
- let text = `${NakoColors.color.bold}テストの実行結果${NakoColors.color.reset}\n`;
87
- let pass = 0;
88
- let numFailures = 0;
89
- for (const t of tests) {
90
- try {
91
- t.f();
92
- text += `${NakoColors.color.green}✔${NakoColors.color.reset} ${t.name}\n`;
93
- pass++;
94
- }
95
- catch (err) {
96
- const errorMessage = (err instanceof Error) ? err.message : String(err);
97
- text += `${NakoColors.color.red}☓${NakoColors.color.reset} ${t.name}: ${errorMessage}\n`;
98
- numFailures++;
99
- }
100
- }
101
- if (numFailures > 0) {
102
- text += `${NakoColors.color.green}成功 ${pass}件 ${NakoColors.color.red}失敗 ${numFailures}件`;
103
- }
104
- else {
105
- text += `${NakoColors.color.green}成功 ${pass}件`;
106
- }
107
- this.numFailures = numFailures;
108
- this.logger.stdout(text);
109
- }
110
- /**
111
- * 毎プラグインの「!クリア」関数を実行
112
- */
113
- clearPlugins() {
114
- // 実行している関数をすべて終了させる
115
- // プラグインのクリア関数を呼び出す
116
- const clearName = '!クリア';
117
- for (const pname in this.pluginfiles) {
118
- const po = this.__module[pname];
119
- if (po[clearName] && po[clearName].fn) {
120
- try {
121
- po[clearName].fn(this);
122
- }
123
- catch (e) {
124
- this.logger.error(`プラグイン『${pname}』のクリア関数でエラーが発生しました:` + String(e.message));
125
- }
126
- }
127
- }
128
- }
129
- /**
130
- * 各種リセット処理
131
- */
132
- reset() {
133
- this.clearPlugins();
134
- }
135
- destroy() {
136
- this.reset();
137
- }
138
- }
@@ -1,442 +0,0 @@
1
- import { NakoIndentError } from './nako_errors.mjs';
2
- import { NakoPrepare, checkNakoMode } from './nako_prepare.mjs';
3
- // インデント構文のキーワード
4
- const INDENT_MODE_KEYWORDS = ['!インデント構文', '!ここまでだるい'];
5
- /**
6
- * インデント構文指定があればコードを変換する
7
- */
8
- function convert(code, filename = 'main.nako3') {
9
- // インデント構文の適用が必要か?
10
- if (checkNakoMode(code, INDENT_MODE_KEYWORDS)) {
11
- return convertForIndentMode(code, filename);
12
- }
13
- return { code, insertedLines: [], deletedLines: [] };
14
- }
15
- /**
16
- * インデント構文指定があるかチェックする
17
- */
18
- function isIndentSyntaxEnabled(code) {
19
- return checkNakoMode(code, INDENT_MODE_KEYWORDS);
20
- }
21
- /** ありえない改行マークを定義 */
22
- const defSpecialRetMark = '🍷🍷改行🍹黐黑鼘鼶齈▨🍺🍺🍶🍶';
23
- let SpecialRetMark = defSpecialRetMark;
24
- /** code中にありえない改行マーク生成しモジュール内の変数SpecialRetMarkに設定 */
25
- export function checkSpecialRetMark(code) {
26
- SpecialRetMark = defSpecialRetMark;
27
- while (code.indexOf(SpecialRetMark) >= 0) {
28
- // 適当な文字を足してユニークにする(一応漢字領域で生成)
29
- const c = String.fromCodePoint(Math.floor(Math.random() * 40952) + 0x4E00);
30
- SpecialRetMark += c + c;
31
- }
32
- return SpecialRetMark;
33
- }
34
- /**
35
- * ソースコードのある1行の中のコメントを全て取り除く。
36
- * 事前にreplaceRetMarkによって文字列や範囲コメント内の改行文字が置換されている必要がある。
37
- */
38
- export function removeCommentsFromLine(src) {
39
- const prepare = NakoPrepare.getInstance(); // `※`, `//`, `/*` といったパターン全てに対応するために必要
40
- const len = src.length;
41
- let result = '';
42
- let eos = '';
43
- let i = 0;
44
- let isComment = false;
45
- while (i < len) {
46
- const c = src.charAt(i);
47
- const ch2 = src.substring(i, 2);
48
- const cPrepared = prepare.convert1ch(c);
49
- const ch2Prepared = ch2.split('').map((c) => prepare.convert1ch(c)).join('');
50
- // eosか?
51
- if (eos !== '') {
52
- // srcのi文字目以降がeosで始まるなら文字列を終了、そうでなければ1文字進める
53
- if (eos === (eos.length === 1 ? cPrepared : ch2Prepared)) {
54
- if (!isComment) {
55
- result += src.substr(i, eos.length);
56
- }
57
- i += eos.length;
58
- isComment = false;
59
- eos = '';
60
- }
61
- else {
62
- if (!isComment) {
63
- result += c;
64
- }
65
- i++;
66
- }
67
- continue;
68
- }
69
- // 文字列の改行も無視する
70
- switch (cPrepared) {
71
- case '"':
72
- case '\'':
73
- eos = c;
74
- result += c;
75
- i++;
76
- continue;
77
- case '「':
78
- eos = '」';
79
- result += c;
80
- i++;
81
- continue;
82
- case '『':
83
- eos = '』';
84
- result += c;
85
- i++;
86
- continue;
87
- case '“':
88
- eos = '”';
89
- result += c;
90
- i++;
91
- continue;
92
- case '{':
93
- eos = '}';
94
- result += c;
95
- i++;
96
- continue;
97
- case '[':
98
- eos = ']';
99
- result += c;
100
- i++;
101
- continue;
102
- }
103
- switch (ch2) {
104
- case '🌴':
105
- eos = '🌴';
106
- result += ch2;
107
- i += 2;
108
- continue;
109
- case '🌿':
110
- eos = '🌿';
111
- result += ch2;
112
- i += 2;
113
- continue;
114
- }
115
- // 行コメント
116
- if (cPrepared === '#') {
117
- eos = '\n';
118
- isComment = true;
119
- i++;
120
- continue;
121
- }
122
- if (ch2Prepared === '//') {
123
- eos = '\n';
124
- isComment = true;
125
- i += 2;
126
- continue;
127
- }
128
- // 範囲コメント
129
- if (ch2Prepared === '/*') {
130
- eos = '*/';
131
- isComment = true;
132
- i += 2;
133
- continue;
134
- }
135
- result += c;
136
- i++;
137
- }
138
- return result;
139
- }
140
- /** インデントモードのための変換処理 */
141
- function convertForIndentMode(code, filename) {
142
- // returns => {{ code: string, insertedLines: number[], deletedLines: { lineNumber: number, len: number }[] }}
143
- const insertedLines = [];
144
- const deletedLines = [];
145
- const END = 'ここまで‰';
146
- const code2 = replaceRetMark(code); // 文字列の中などの改行を置換
147
- const lines = code2.split('\n');
148
- const lines2 = [];
149
- const indentStack = [];
150
- let lastIndent = 0;
151
- // 元ソースコードの中に特殊改行マークが含まれるかチェックして含まれるならもっと複雑な特殊マークを動的に生成
152
- checkSpecialRetMark(code);
153
- let lineCount = -1;
154
- lines.forEach((line) => {
155
- lineCount += line.split(SpecialRetMark).length;
156
- // trim line
157
- // eslint-disable-next-line no-irregular-whitespace
158
- if (/^[  ・\t]*$/.test(line)) {
159
- deletedLines.push({ lineNumber: lines2.length, len: line.length });
160
- return;
161
- }
162
- // eslint-disable-next-line no-irregular-whitespace
163
- const lineTrimed = removeCommentsFromLine(line).replace(/^[  ・\t]+/, '').replace(/\s+$/, '');
164
- if (lineTrimed === '') {
165
- lines2.push(line);
166
- return;
167
- }
168
- if (lineTrimed === 'ここまで') {
169
- throw new NakoIndentError('インデント構文が有効化されているときに『ここまで』を使うことはできません。', lineCount, filename);
170
- }
171
- // check indent
172
- const indent = countIndent(line);
173
- if (lastIndent === indent) {
174
- lines2.push(line);
175
- return;
176
- }
177
- // indent
178
- if (lastIndent < indent) {
179
- indentStack.push(lastIndent);
180
- lastIndent = indent;
181
- lines2.push(line);
182
- return;
183
- }
184
- // unindent
185
- if (lastIndent > indent) {
186
- // 5回
187
- // 3回
188
- // 1を表示
189
- // |
190
- // |
191
- lastIndent = indent;
192
- while (indentStack.length > 0) {
193
- const n = indentStack.pop() || 0;
194
- if (n === indent) {
195
- if (lineTrimed.substring(0, 3) !== '違えば') {
196
- insertedLines.push(lines2.length);
197
- lines2.push(makeIndent(n) + END);
198
- }
199
- lines2.push(line);
200
- return;
201
- }
202
- if (indent < n) {
203
- insertedLines.push(lines2.length);
204
- lines2.push(makeIndent(n) + END);
205
- continue;
206
- }
207
- }
208
- }
209
- });
210
- // 残りのインデントを処理
211
- while (indentStack.length > 0) {
212
- const n = indentStack.pop() || 0;
213
- insertedLines.push(lines2.length);
214
- lines2.push(makeIndent(n) + END);
215
- }
216
- // 特別マーカーを改行に置換
217
- const lines3 = [];
218
- for (let i = 0; i < lines2.length; i++) {
219
- if (lines2[i].includes(SpecialRetMark)) {
220
- const lines4 = lines2[i].split(SpecialRetMark);
221
- // 置換されたマーカーの数だけ、それ以降の行数をずらす。
222
- // unindentによって挿入された行がSpecialRetMarkを含むことはない。
223
- for (let j = 0; j < insertedLines.length; j++) {
224
- if (lines3.length < insertedLines[j]) {
225
- insertedLines[j] += lines4.length - 1;
226
- }
227
- }
228
- for (let j = 0; j < deletedLines.length; j++) {
229
- if (lines3.length < deletedLines[j].lineNumber) {
230
- deletedLines[j].lineNumber += lines4.length - 1;
231
- }
232
- }
233
- lines3.push(...lines4);
234
- }
235
- else {
236
- lines3.push(lines2[i]);
237
- }
238
- }
239
- return { code: lines3.join('\n'), insertedLines, deletedLines };
240
- }
241
- /**
242
- * count分だけ字下げする
243
- * @param {number} count
244
- */
245
- function makeIndent(count) {
246
- let s = '';
247
- for (let i = 0; i < count; i++) {
248
- s += ' ';
249
- }
250
- return s;
251
- }
252
- /**
253
- * インデント部分を取り出す
254
- */
255
- export function getIndent(line) {
256
- // eslint-disable-next-line no-irregular-whitespace
257
- const m = /^([  ・\t]*)/.exec(removeCommentsFromLine(line));
258
- if (!m) {
259
- return '';
260
- }
261
- return m[1];
262
- }
263
- /**
264
- * インデントの個数を数える
265
- */
266
- export function countIndent(line) {
267
- let cnt = 0;
268
- for (let i = 0; i < line.length; i++) {
269
- const ch = line.charAt(i);
270
- if (ch === ' ') {
271
- cnt++;
272
- continue;
273
- }
274
- if (ch === ' ') {
275
- cnt += 2;
276
- continue;
277
- }
278
- if (ch === '・') {
279
- cnt += 2;
280
- continue;
281
- }
282
- if (ch === '\t') {
283
- cnt += 4;
284
- continue;
285
- }
286
- break;
287
- }
288
- return cnt;
289
- }
290
- export function replaceRetMark(src) {
291
- const prepare = NakoPrepare.getInstance(); // `※`, `//`, `/*` といったパターン全てに対応するために必要
292
- const len = src.length;
293
- let result = '';
294
- let eos = '';
295
- let i = 0;
296
- while (i < len) {
297
- const c = src.charAt(i);
298
- const ch2 = src.substr(i, 2);
299
- const cPrepared = prepare.convert1ch(c);
300
- const ch2Prepared = ch2.split('').map((c) => prepare.convert1ch(c)).join('');
301
- // eosか?
302
- if (eos !== '') {
303
- // srcのi文字目以降がeosで始まるなら文字列を終了、そうでなければ1文字進める
304
- if (eos === (eos.length === 1 ? cPrepared : ch2Prepared)) {
305
- result += src.substr(i, eos.length);
306
- i += eos.length;
307
- eos = '';
308
- }
309
- else {
310
- if (c === '\n') {
311
- result += SpecialRetMark;
312
- }
313
- else {
314
- result += c;
315
- }
316
- i++;
317
- }
318
- continue;
319
- }
320
- // 文字列の改行も無視する
321
- switch (cPrepared) {
322
- case '"':
323
- case '\'':
324
- eos = c;
325
- result += c;
326
- i++;
327
- continue;
328
- case '「':
329
- eos = '」';
330
- result += c;
331
- i++;
332
- continue;
333
- case '『':
334
- eos = '』';
335
- result += c;
336
- i++;
337
- continue;
338
- case '“':
339
- eos = '”';
340
- result += c;
341
- i++;
342
- continue;
343
- case '{':
344
- eos = '}';
345
- result += c;
346
- i++;
347
- continue;
348
- case '[':
349
- eos = ']';
350
- result += c;
351
- i++;
352
- continue;
353
- }
354
- switch (ch2) {
355
- case '🌴':
356
- eos = '🌴';
357
- result += ch2;
358
- i += 2;
359
- continue;
360
- case '🌿':
361
- eos = '🌿';
362
- result += ch2;
363
- i += 2;
364
- continue;
365
- }
366
- // 行コメント
367
- if (cPrepared === '#') {
368
- eos = '\n';
369
- result += c;
370
- i++;
371
- continue;
372
- }
373
- if (ch2Prepared === '//') {
374
- eos = '\n';
375
- result += ch2;
376
- i += 2;
377
- continue;
378
- }
379
- // 範囲コメント
380
- if (ch2Prepared === '/*') {
381
- eos = '*/';
382
- result += ch2;
383
- i += 2;
384
- continue;
385
- }
386
- result += c;
387
- i++;
388
- }
389
- return result;
390
- }
391
- /**
392
- * コードのインデントの構造を取得する。
393
- * 空白行や複数行にまたがる構文を考慮する。
394
- * インデント構文が有効化されていない場合にも使われる。
395
- */
396
- export function getBlockStructure(code) {
397
- const result = {
398
- lines: [], // 各行のインデント量
399
- pairs: [],
400
- parents: [], // 各行の親の行
401
- spaces: [] // 各行のインデントの文字列
402
- };
403
- const lines = replaceRetMark(code).split('\n');
404
- const stack = [];
405
- let lineCount = 0;
406
- let prev = countIndent(lines[0]);
407
- for (const line of lines) {
408
- const numLines = line.split(SpecialRetMark).length;
409
- const line2 = removeCommentsFromLine(line);
410
- // eslint-disable-next-line no-irregular-whitespace
411
- const current = (line2.replace(/^[  ・\t]+/, '') === '')
412
- ? prev
413
- : countIndent(line2);
414
- result.lines.push(...Array(numLines).fill(current));
415
- result.spaces.push(...Array(numLines).fill(getIndent(line2)));
416
- if (prev < current) {
417
- stack.push(lineCount - 1);
418
- }
419
- else if (prev > current) {
420
- const last = stack.pop();
421
- if (last !== undefined) {
422
- result.pairs.push([last, lineCount]);
423
- }
424
- }
425
- const parent = stack[stack.length - 1] !== undefined ? stack[stack.length - 1] : null;
426
- result.parents.push(...Array(numLines).fill(parent));
427
- prev = current;
428
- lineCount += numLines;
429
- }
430
- // スタックが余ったらコードの末尾とペアにする。
431
- for (const item of stack) {
432
- result.pairs.push([item, lineCount]);
433
- }
434
- return result;
435
- }
436
- export default {
437
- convert,
438
- getBlockStructure,
439
- getIndent,
440
- countIndent,
441
- isIndentSyntaxEnabled
442
- };
@@ -1,29 +0,0 @@
1
- /**
2
- * なでしこ3で行頭インデントに使える文字とインデントカウント数
3
- */
4
- export function isIndentChars(ch) {
5
- const code = ch.charCodeAt(0);
6
- // 特別なコード
7
- if (ch === '\t') {
8
- return 4;
9
- }
10
- if (ch === ' ' || ch === '|') {
11
- return 1;
12
- }
13
- if (ch === '・' || ch === ' ') {
14
- return 2;
15
- }
16
- if (ch === '⏋' || ch === '⏌') {
17
- return 2;
18
- } // 0x23CB, 0x23CC
19
- // 罫線から --- https://github.com/kujirahand/unicode-sheets/blob/main/box-drawing.md
20
- if (code >= 0x2500 && code <= 0x257F) {
21
- return 2;
22
- }
23
- // 記号から --- https://github.com/kujirahand/unicode-sheets/blob/main/misc-technical.md
24
- if ((code >= 0x23A0 && code <= 0x23AF) ||
25
- (code >= 0x23B8 && code <= 0x23BF)) {
26
- return 2;
27
- }
28
- return 0;
29
- }