md-spreadsheet-parser 1.2.1 → 1.3.1

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/README.ja.md ADDED
@@ -0,0 +1,180 @@
1
+ # md-spreadsheet-parser (NPM)
2
+
3
+ <p align="center">
4
+ <img src="https://img.shields.io/badge/wasm-powered-purple.svg" alt="WASM Powered" />
5
+ <a href="https://github.com/f-y/md-spreadsheet-parser/blob/main/LICENSE">
6
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License" />
7
+ </a>
8
+ <a href="https://www.npmjs.com/package/md-spreadsheet-parser">
9
+ <img src="https://img.shields.io/npm/v/md-spreadsheet-parser.svg" alt="npm" />
10
+ </a>
11
+ <a href="https://pypi.org/project/md-spreadsheet-parser/">
12
+ <img src="https://img.shields.io/pypi/v/md-spreadsheet-parser.svg" alt="PyPI" />
13
+ </a>
14
+ </p>
15
+
16
+ **md-spreadsheet-parser** は、Node.js用の堅牢なMarkdownテーブルパーサーおよび操作ライブラリです。
17
+ [Pythonコア](https://github.com/f-y/md-spreadsheet-parser) をWebAssemblyにコンパイルして使用しており、Node.jsでネイティブに動作します。
18
+
19
+ > **🎉 公式GUIエディタが登場: [PengSheets](https://marketplace.visualstudio.com/items?itemName=f-y.peng-sheets)**
20
+ >
21
+ > このライブラリのパワーをそのままに、VS Code上でExcelライクな操作感を実現しました。ソート、フィルタ、快適なナビゲーションなどをGUIで直感的に扱えます。
22
+ >
23
+ > [![Get it on VS Code Marketplace](https://img.shields.io/badge/VS%20Code%20Marketplace-%E3%81%A7%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89-007ACC?style=for-the-badge&logo=visual-studio-code&logoColor=white)](https://marketplace.visualstudio.com/items?itemName=f-y.peng-sheets)
24
+
25
+ ## 機能
26
+
27
+ - **🚀 高パフォーマンス**: プリコンパイルされたWASMバイナリ(約160msで初期化)。
28
+ - **💪 堅牢な解析**: GFMテーブル、列の欠落、エスケープされたパイプを正しく処理します。
29
+ - **🛠️ スプレッドシート操作**: セルの編集、行の追加/削除、Markdownの再生成をプログラムで行えます。
30
+ - **🛡️ 型安全な検証**: スキーマ(Plain Object または Zod)に対してテーブルデータを検証します。
31
+ - **📂 ファイルシステムサポート**: 直接ファイルを読み込む機能を提供します。
32
+
33
+ ## インストール
34
+
35
+ ```bash
36
+ npm install md-spreadsheet-parser
37
+ ```
38
+
39
+ ## 使い方ガイド
40
+
41
+ ### 1. 基本的な解析 (文字列)
42
+
43
+ Markdownテーブルの文字列を構造化された `Table` オブジェクトに解析します。
44
+
45
+ ```javascript
46
+ import { parseTable } from 'md-spreadsheet-parser';
47
+
48
+ const markdown = `
49
+ | Name | Age |
50
+ | --- | --- |
51
+ | Alice | 30 |
52
+ `;
53
+
54
+ const table = parseTable(markdown);
55
+ console.log(table.rows); // [ [ 'Alice', '30' ] ]
56
+ ```
57
+
58
+ ### 2. ファイルシステムの使用
59
+
60
+ 文字列に読み込むことなく、ファイルを直接解析できます。
61
+
62
+ ```javascript
63
+ import { parseWorkbookFromFile, scanTablesFromFile } from 'md-spreadsheet-parser';
64
+
65
+ // ワークブック全体(複数のシート)を解析
66
+ const workbook = parseWorkbookFromFile('./data.md');
67
+ console.log(`Parsed ${workbook.sheets.length} sheets`);
68
+
69
+ // Lookup APIを使用して内容を検証
70
+ const sheet = workbook.getSheet('Sheet1');
71
+ if (sheet) {
72
+ const table = sheet.getTable(0); // 最初のテーブルを取得
73
+ console.log(table.headers);
74
+ }
75
+
76
+ // または、ファイル内のすべてのテーブルをスキャン
77
+ const tables = scanTablesFromFile('./readme.md');
78
+ console.log(`Found ${tables.length} tables`);
79
+ ```
80
+
81
+ ### 3. プログラムによる編集
82
+
83
+ テーブルオブジェクトは可変です(内部的にはCoWのような動作)。変更してMarkdownにエクスポートし直すことができます。
84
+
85
+ ```javascript
86
+ import { parseTable } from 'md-spreadsheet-parser';
87
+
88
+ const table = parseTable("| Item | Price |\n|---|---|\n| Apple | 100 |");
89
+
90
+ // セルを更新 (行 0, 列 1)
91
+ table.updateCell(0, 1, "150");
92
+
93
+ // Markdownに戻す
94
+ console.log(table.toMarkdown());
95
+ // | Item | Price |
96
+ // | --- | --- |
97
+ // | Apple | 150 |
98
+ ```
99
+
100
+ ### 4. 型安全な検証 (toModels)
101
+
102
+ 文字列ベースのテーブルデータを、型付きオブジェクトに変換できます。
103
+
104
+ #### 基本的な使用法 (Plain Object Schema)
105
+ コンバータ関数を持つ単純なスキーマオブジェクトを提供できます。
106
+
107
+ ```javascript
108
+ const markdown = `
109
+ | id | active |
110
+ | -- | ------ |
111
+ | 1 | yes |
112
+ `;
113
+ const table = parseTable(markdown);
114
+
115
+ // スキーマ定義
116
+ const UserSchema = {
117
+ id: (val) => Number(val),
118
+ active: (val) => val === 'yes'
119
+ };
120
+
121
+ const users = table.toModels(UserSchema);
122
+ console.log(users);
123
+ // [ { id: 1, active: true } ]
124
+ ```
125
+
126
+ #### 高度な使用法 (Zod)
127
+ より堅牢な検証には、[Zod](https://zod.dev/) を使用してください。
128
+
129
+ ```javascript
130
+ import { z } from 'zod';
131
+
132
+ const UserZodSchema = z.object({
133
+ id: z.coerce.number(),
134
+ active: z.string().transform(v => v === 'yes')
135
+ });
136
+
137
+ const users = table.toModels(UserZodSchema);
138
+ // [ { id: 1, active: true } ]
139
+ ```
140
+
141
+ ## API ドキュメント
142
+
143
+ このパッケージはPythonコアの直接的なラッパーであるため、基本的な概念は同一です。APIの命名規則はJavaScript用に(snake_caseではなくcamelCaseに)適合されています。
144
+
145
+ - **コアドキュメント**: [Python ユーザーガイド](https://github.com/f-y/md-spreadsheet-parser/blob/main/README.ja.md#使い方)
146
+ - **クックブック**: [一般的なレシピ (日本語)](https://github.com/f-y/md-spreadsheet-parser/blob/main/COOKBOOK.ja.md)
147
+
148
+ ### 主な関数の対応
149
+
150
+ | Python (Core) | JavaScript (NPM) | 説明 |
151
+ |---|---|---|
152
+ | `parse_table(md)` | `parseTable(md)` | 単一のテーブル文字列を解析 |
153
+ | `parse_workbook(md)` | `parseWorkbook(md)` | ワークブック全体の文字列を解析 |
154
+ | `scan_tables(md)` | `scanTables(md)` | 文字列からすべてのテーブルを抽出 |
155
+ | `parse_workbook_from_file(path)` | `parseWorkbookFromFile(path)` | ファイルをワークブックに解析 |
156
+ | `scan_tables_from_file(path)` | `scanTablesFromFile(path)` | ファイルからテーブルを抽出 |
157
+ | `Table.to_markdown()` | `Table.toMarkdown()` | Markdownを生成 |
158
+ | `Table.update_cell(r, c, v)` | `Table.updateCell(r, c, v)` | 特定のセルを更新 |
159
+ | `Table.to_models(schema)` | `Table.toModels(schema)` | 型付きオブジェクトに変換 |
160
+ | `Workbook.get_sheet(name)` | `Workbook.getSheet(name)` | 名前でシートを取得 |
161
+ | `Sheet.get_table(index)` | `Sheet.getTable(index)` | インデックスでテーブルを取得 |
162
+
163
+ ## 制限事項
164
+
165
+ 以下のPython機能は、NPMパッケージでは **利用できません**:
166
+
167
+ | 機能 | 理由 |
168
+ |---------|--------|
169
+ | `parse_excel()` / `parseExcel()` | Excelファイルの解析には `openpyxl` が必要ですが、これはWASMと互換性がありません |
170
+
171
+ Excelファイル操作については、[Pythonパッケージ](https://github.com/f-y/md-spreadsheet-parser) を直接使用するか、COOKBOOKにあるようなテキストベース(CSV/TSV)の操作を使ってください。
172
+
173
+ ## アーキテクチャ
174
+
175
+ このパッケージは、PythonライブラリをWASMコンポーネントとしてバンドルするために `componentize-py` を使用しています。
176
+ 詳細については、[ARCHITECTURE.md](./ARCHITECTURE.md) を参照してください。
177
+
178
+ ## ライセンス
179
+
180
+ MIT
package/README.md CHANGED
@@ -14,7 +14,18 @@
14
14
  </p>
15
15
 
16
16
  **md-spreadsheet-parser** is a robust Markdown table parser and manipulator for Node.js.
17
- It is powered by the [Python Core](https://github.com/f-y/md-spreadsheet-parser) compiled to WebAssembly, ensuring 100% logic parity with the Python version while running natively in Node.js.
17
+ It is powered by the [Python Core](https://github.com/f-y/md-spreadsheet-parser) compiled to WebAssembly, while running natively in Node.js.
18
+
19
+ > **🎉 Official GUI Editor Released: [PengSheets](https://marketplace.visualstudio.com/items?itemName=f-y.peng-sheets)**
20
+ >
21
+ > We have transformed this library into an Excel-like interface for VS Code. Edit Markdown tables with sort, filter, and easy navigation directly in your editor.
22
+ >
23
+ > [![Get it on VS Code Marketplace](https://img.shields.io/badge/Get%20it%20on-VS%20Code%20Marketplace-007ACC?style=for-the-badge&logo=visual-studio-code&logoColor=white)](https://marketplace.visualstudio.com/items?itemName=f-y.peng-sheets)
24
+
25
+ Read in Japanese: 日本語版はこちら(
26
+ <a href="https://github.com/f-y/md-spreadsheet-parser/blob/main/packages/npm/README.ja.md">README</a>
27
+ )
28
+
18
29
 
19
30
  ## Features
20
31
 
@@ -162,7 +173,7 @@ The following Python features are **not available** in the NPM package:
162
173
  |---------|--------|
163
174
  | `parse_excel()` / `parseExcel()` | Excel file parsing requires `openpyxl`, which is not compatible with WASM |
164
175
 
165
- For Excel file operations, use the [Python package](https://github.com/f-y/md-spreadsheet-parser) directly.
176
+ For Excel file operations, use the [Python package](https://github.com/f-y/md-spreadsheet-parser) directly, or use text-based operations (like TSV/CSV) as described in the COOKBOOK.
166
177
 
167
178
  ## Architecture
168
179
 
package/dist/index.d.ts CHANGED
@@ -23,7 +23,7 @@ export declare class Table {
23
23
  metadata: any | undefined;
24
24
  startLine: number | undefined;
25
25
  endLine: number | undefined;
26
- constructor(data?: Partial<Table>);
26
+ constructor(data?: Partial<Table> & Record<string, any>);
27
27
  toDTO(): any;
28
28
  /**
29
29
  * Returns a JSON-compatible plain object representation.
@@ -45,8 +45,10 @@ export declare class Table {
45
45
  export declare class Sheet {
46
46
  name: string | undefined;
47
47
  tables: any[] | undefined;
48
+ sheetType: string | undefined;
49
+ content: any | undefined;
48
50
  metadata: any | undefined;
49
- constructor(data?: Partial<Sheet>);
51
+ constructor(data?: Partial<Sheet> & Record<string, any>);
50
52
  toDTO(): any;
51
53
  /**
52
54
  * Returns a JSON-compatible plain object representation.
@@ -63,8 +65,12 @@ export declare class Sheet {
63
65
  }
64
66
  export declare class Workbook {
65
67
  sheets: any[] | undefined;
68
+ name: string | undefined;
69
+ startLine: number | undefined;
70
+ endLine: number | undefined;
66
71
  metadata: any | undefined;
67
- constructor(data?: Partial<Workbook>);
72
+ rootContent: any | undefined;
73
+ constructor(data?: Partial<Workbook> & Record<string, any>);
68
74
  toDTO(): any;
69
75
  /**
70
76
  * Returns a JSON-compatible plain object representation.
@@ -85,7 +91,7 @@ export declare class ParsingSchema {
85
91
  requireOuterPipes: boolean | undefined;
86
92
  stripWhitespace: boolean | undefined;
87
93
  convertBrToNewline: boolean | undefined;
88
- constructor(data?: Partial<ParsingSchema>);
94
+ constructor(data?: Partial<ParsingSchema> & Record<string, any>);
89
95
  toDTO(): any;
90
96
  }
91
97
  export declare class MultiTableParsingSchema {
@@ -94,18 +100,18 @@ export declare class MultiTableParsingSchema {
94
100
  requireOuterPipes: boolean | undefined;
95
101
  stripWhitespace: boolean | undefined;
96
102
  convertBrToNewline: boolean | undefined;
97
- rootMarker: string | undefined;
103
+ rootMarker: any | undefined;
98
104
  sheetHeaderLevel: number | undefined;
99
105
  tableHeaderLevel: number | undefined;
100
106
  captureDescription: boolean | undefined;
101
- constructor(data?: Partial<MultiTableParsingSchema>);
107
+ constructor(data?: Partial<MultiTableParsingSchema> & Record<string, any>);
102
108
  toDTO(): any;
103
109
  }
104
110
  export declare class ConversionSchema {
105
111
  booleanPairs: string | undefined;
106
112
  customConverters: string | undefined;
107
113
  fieldConverters: string | undefined;
108
- constructor(data?: Partial<ConversionSchema>);
114
+ constructor(data?: Partial<ConversionSchema> & Record<string, any>);
109
115
  toDTO(): any;
110
116
  }
111
117
  export declare class ExcelParsingSchema {
@@ -113,6 +119,6 @@ export declare class ExcelParsingSchema {
113
119
  fillMergedHeaders: boolean | undefined;
114
120
  delimiter: string | undefined;
115
121
  headerSeparator: string | undefined;
116
- constructor(data?: Partial<ExcelParsingSchema>);
122
+ constructor(data?: Partial<ExcelParsingSchema> & Record<string, any>);
117
123
  toDTO(): any;
118
124
  }
package/dist/index.js CHANGED
@@ -112,14 +112,17 @@ export function scanTablesIter(source, schema) {
112
112
  export class Table {
113
113
  constructor(data) {
114
114
  if (data) {
115
- this.headers = data.headers;
116
- this.rows = data.rows;
117
- this.alignments = data.alignments;
118
- this.name = data.name;
119
- this.description = data.description;
120
- this.metadata = (typeof data.metadata === 'string') ? JSON.parse(data.metadata) : data.metadata;
121
- this.startLine = data.startLine;
122
- this.endLine = data.endLine;
115
+ this.headers = data.headers ?? data.headers;
116
+ this.rows = data.rows ?? data.rows;
117
+ this.alignments = data.alignments ?? data.alignments;
118
+ this.name = data.name ?? data.name;
119
+ this.description = data.description ?? data.description;
120
+ {
121
+ const val = data.metadata ?? data.metadata;
122
+ this.metadata = (typeof val === 'string') ? JSON.parse(val) : val;
123
+ }
124
+ this.startLine = data.startLine ?? data.start_line;
125
+ this.endLine = data.endLine ?? data.end_line;
123
126
  }
124
127
  }
125
128
  toDTO() {
@@ -227,9 +230,14 @@ export class Table {
227
230
  export class Sheet {
228
231
  constructor(data) {
229
232
  if (data) {
230
- this.name = data.name;
231
- this.tables = (data.tables || []).map((x) => x instanceof Table ? x : new Table(x));
232
- this.metadata = (typeof data.metadata === 'string') ? JSON.parse(data.metadata) : data.metadata;
233
+ this.name = data.name ?? data.name;
234
+ this.tables = ((data.tables ?? data.tables) || []).map((x) => x instanceof Table ? x : new Table(x));
235
+ this.sheetType = data.sheetType ?? data.sheet_type;
236
+ this.content = data.content ?? data.content;
237
+ {
238
+ const val = data.metadata ?? data.metadata;
239
+ this.metadata = (typeof val === 'string') ? JSON.parse(val) : val;
240
+ }
233
241
  }
234
242
  }
235
243
  toDTO() {
@@ -248,6 +256,8 @@ export class Sheet {
248
256
  return {
249
257
  name: this.name,
250
258
  tables: (this.tables || []).map((t) => t.json ? t.json : t),
259
+ sheetType: this.sheetType,
260
+ content: this.content,
251
261
  metadata: this.metadata ?? {},
252
262
  };
253
263
  }
@@ -302,8 +312,15 @@ export class Sheet {
302
312
  export class Workbook {
303
313
  constructor(data) {
304
314
  if (data) {
305
- this.sheets = (data.sheets || []).map((x) => x instanceof Sheet ? x : new Sheet(x));
306
- this.metadata = (typeof data.metadata === 'string') ? JSON.parse(data.metadata) : data.metadata;
315
+ this.sheets = ((data.sheets ?? data.sheets) || []).map((x) => x instanceof Sheet ? x : new Sheet(x));
316
+ this.name = data.name ?? data.name;
317
+ this.startLine = data.startLine ?? data.start_line;
318
+ this.endLine = data.endLine ?? data.end_line;
319
+ {
320
+ const val = data.metadata ?? data.metadata;
321
+ this.metadata = (typeof val === 'string') ? JSON.parse(val) : val;
322
+ }
323
+ this.rootContent = data.rootContent ?? data.root_content;
307
324
  }
308
325
  }
309
326
  toDTO() {
@@ -320,8 +337,10 @@ export class Workbook {
320
337
  */
321
338
  get json() {
322
339
  return {
340
+ name: this.name,
323
341
  sheets: (this.sheets || []).map((s) => s.json ? s.json : s),
324
342
  metadata: this.metadata ?? {},
343
+ rootContent: this.rootContent,
325
344
  };
326
345
  }
327
346
  getSheet(name) {
@@ -375,11 +394,11 @@ export class Workbook {
375
394
  export class ParsingSchema {
376
395
  constructor(data) {
377
396
  if (data) {
378
- this.columnSeparator = data.columnSeparator;
379
- this.headerSeparatorChar = data.headerSeparatorChar;
380
- this.requireOuterPipes = data.requireOuterPipes;
381
- this.stripWhitespace = data.stripWhitespace;
382
- this.convertBrToNewline = data.convertBrToNewline;
397
+ this.columnSeparator = data.columnSeparator ?? data.column_separator;
398
+ this.headerSeparatorChar = data.headerSeparatorChar ?? data.header_separator_char;
399
+ this.requireOuterPipes = data.requireOuterPipes ?? data.require_outer_pipes;
400
+ this.stripWhitespace = data.stripWhitespace ?? data.strip_whitespace;
401
+ this.convertBrToNewline = data.convertBrToNewline ?? data.convert_br_to_newline;
383
402
  }
384
403
  }
385
404
  toDTO() {
@@ -390,15 +409,15 @@ export class ParsingSchema {
390
409
  export class MultiTableParsingSchema {
391
410
  constructor(data) {
392
411
  if (data) {
393
- this.columnSeparator = data.columnSeparator;
394
- this.headerSeparatorChar = data.headerSeparatorChar;
395
- this.requireOuterPipes = data.requireOuterPipes;
396
- this.stripWhitespace = data.stripWhitespace;
397
- this.convertBrToNewline = data.convertBrToNewline;
398
- this.rootMarker = data.rootMarker;
399
- this.sheetHeaderLevel = data.sheetHeaderLevel;
400
- this.tableHeaderLevel = data.tableHeaderLevel;
401
- this.captureDescription = data.captureDescription;
412
+ this.columnSeparator = data.columnSeparator ?? data.column_separator;
413
+ this.headerSeparatorChar = data.headerSeparatorChar ?? data.header_separator_char;
414
+ this.requireOuterPipes = data.requireOuterPipes ?? data.require_outer_pipes;
415
+ this.stripWhitespace = data.stripWhitespace ?? data.strip_whitespace;
416
+ this.convertBrToNewline = data.convertBrToNewline ?? data.convert_br_to_newline;
417
+ this.rootMarker = data.rootMarker ?? data.root_marker;
418
+ this.sheetHeaderLevel = data.sheetHeaderLevel ?? data.sheet_header_level;
419
+ this.tableHeaderLevel = data.tableHeaderLevel ?? data.table_header_level;
420
+ this.captureDescription = data.captureDescription ?? data.capture_description;
402
421
  }
403
422
  }
404
423
  toDTO() {
@@ -409,9 +428,15 @@ export class MultiTableParsingSchema {
409
428
  export class ConversionSchema {
410
429
  constructor(data) {
411
430
  if (data) {
412
- this.booleanPairs = data.booleanPairs;
413
- this.customConverters = (typeof data.customConverters === 'string') ? JSON.parse(data.customConverters) : data.customConverters;
414
- this.fieldConverters = (typeof data.fieldConverters === 'string') ? JSON.parse(data.fieldConverters) : data.fieldConverters;
431
+ this.booleanPairs = data.booleanPairs ?? data.boolean_pairs;
432
+ {
433
+ const val = data.customConverters ?? data.custom_converters;
434
+ this.customConverters = (typeof val === 'string') ? JSON.parse(val) : val;
435
+ }
436
+ {
437
+ const val = data.fieldConverters ?? data.field_converters;
438
+ this.fieldConverters = (typeof val === 'string') ? JSON.parse(val) : val;
439
+ }
415
440
  }
416
441
  }
417
442
  toDTO() {
@@ -426,10 +451,10 @@ export class ConversionSchema {
426
451
  export class ExcelParsingSchema {
427
452
  constructor(data) {
428
453
  if (data) {
429
- this.headerRows = data.headerRows;
430
- this.fillMergedHeaders = data.fillMergedHeaders;
431
- this.delimiter = data.delimiter;
432
- this.headerSeparator = data.headerSeparator;
454
+ this.headerRows = data.headerRows ?? data.header_rows;
455
+ this.fillMergedHeaders = data.fillMergedHeaders ?? data.fill_merged_headers;
456
+ this.delimiter = data.delimiter ?? data.delimiter;
457
+ this.headerSeparator = data.headerSeparator ?? data.header_separator;
433
458
  }
434
459
  }
435
460
  toDTO() {
@@ -42,9 +42,15 @@ export interface Table {
42
42
  export interface Sheet {
43
43
  name: string,
44
44
  tables: Array<Table>,
45
+ sheetType?: string,
46
+ content?: string,
45
47
  metadata?: string,
46
48
  }
47
49
  export interface Workbook {
48
50
  sheets: Array<Sheet>,
51
+ name?: string,
52
+ startLine?: number,
53
+ endLine?: number,
49
54
  metadata?: string,
55
+ rootContent?: string,
50
56
  }
@@ -1,9 +1,9 @@
1
1
  /** @module Interface wasi:sockets/ip-name-lookup@0.2.0 **/
2
2
  export function resolveAddresses(network: Network, name: string): ResolveAddressStream;
3
- export type Network = import('./wasi-sockets-network.js').Network;
4
- export type ErrorCode = import('./wasi-sockets-network.js').ErrorCode;
5
3
  export type IpAddress = import('./wasi-sockets-network.js').IpAddress;
4
+ export type ErrorCode = import('./wasi-sockets-network.js').ErrorCode;
6
5
  export type Pollable = import('./wasi-io-poll.js').Pollable;
6
+ export type Network = import('./wasi-sockets-network.js').Network;
7
7
 
8
8
  export class ResolveAddressStream {
9
9
  /**
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file