@aiquants/spreadsheet 0.14.0 → 0.15.0
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/CHANGELOG.md +16 -0
- package/README.md +20 -1
- package/dist/index.cjs +8 -15
- package/dist/index.js +1099 -1183
- package/dist/tsv-B6TDExlk.js +91 -0
- package/dist/tsv-BHXbWK5W.cjs +8 -0
- package/dist/tsv.cjs +1 -0
- package/dist/tsv.d.cts +13 -0
- package/dist/tsv.d.ts +13 -0
- package/dist/tsv.js +5 -0
- package/package.json +12 -1
- package/src/tsv.ts +13 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const o = (e) => (
|
|
2
|
+
// 終端 CRLF は必須 (Excel 実挙動)。parseTsv の「終端の改行 1 つを剥がす」規約と対 —
|
|
3
|
+
// 終端なしだと [["a"],[""]] が [["a"]] に潰れ (cut-move で clear されるべき先に旧値が残る)、
|
|
4
|
+
// [[""]] は "" になって §6.5.4-5 の空ガードに飲まれ「空セル貼り付けで clear」が不発になる
|
|
5
|
+
`${e.map((l) => l.map(h).join(" ")).join(`\r
|
|
6
|
+
`)}\r
|
|
7
|
+
`
|
|
8
|
+
), h = (e) => /[\t\r\n]/.test(e) ? `"${e.replaceAll('"', '""')}"` : e, u = (e) => e.endsWith(`\r
|
|
9
|
+
`) ? e.slice(0, -2) : e.endsWith(`
|
|
10
|
+
`) || e.endsWith("\r") ? e.slice(0, -1) : e, a = (e, l, t) => {
|
|
11
|
+
let n = 0;
|
|
12
|
+
for (; ; ) {
|
|
13
|
+
let s;
|
|
14
|
+
if (e[n] === '"') {
|
|
15
|
+
const r = f(e, n);
|
|
16
|
+
if (r !== null)
|
|
17
|
+
s = r.value, n = r.nextIndex;
|
|
18
|
+
else {
|
|
19
|
+
const i = c(e, n);
|
|
20
|
+
s = e.slice(n, i), n = i;
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
const r = c(e, n);
|
|
24
|
+
s = e.slice(n, r), n = r;
|
|
25
|
+
}
|
|
26
|
+
if (l(s), n >= e.length) {
|
|
27
|
+
t();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
e[n] === " " ? n += 1 : (n += e[n] === "\r" && e[n + 1] === `
|
|
31
|
+
` ? 2 : 1, t());
|
|
32
|
+
}
|
|
33
|
+
}, p = (e) => {
|
|
34
|
+
const l = u(e);
|
|
35
|
+
if (l === "")
|
|
36
|
+
return [[""]];
|
|
37
|
+
const t = [];
|
|
38
|
+
let n = [];
|
|
39
|
+
a(
|
|
40
|
+
l,
|
|
41
|
+
(r) => {
|
|
42
|
+
n.push(r);
|
|
43
|
+
},
|
|
44
|
+
() => {
|
|
45
|
+
t.push(n), n = [];
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
let s = 0;
|
|
49
|
+
for (const r of t)
|
|
50
|
+
r.length > s && (s = r.length);
|
|
51
|
+
return t.map((r) => r.length === s ? r : [...r, ...Array(s - r.length).fill("")]);
|
|
52
|
+
}, g = (e) => {
|
|
53
|
+
const l = u(e);
|
|
54
|
+
if (l === "")
|
|
55
|
+
return { rows: 1, cols: 1 };
|
|
56
|
+
let t = 0, n = 0, s = 0;
|
|
57
|
+
return a(
|
|
58
|
+
l,
|
|
59
|
+
() => {
|
|
60
|
+
s += 1;
|
|
61
|
+
},
|
|
62
|
+
() => {
|
|
63
|
+
t += 1, s > n && (n = s), s = 0;
|
|
64
|
+
}
|
|
65
|
+
), { rows: t, cols: n };
|
|
66
|
+
}, f = (e, l) => {
|
|
67
|
+
let t = "", n = l + 1;
|
|
68
|
+
for (; n < e.length; )
|
|
69
|
+
if (e[n] === '"')
|
|
70
|
+
if (e[n + 1] === '"')
|
|
71
|
+
t += '"', n += 2;
|
|
72
|
+
else {
|
|
73
|
+
const s = n + 1;
|
|
74
|
+
return (s >= e.length || e[s] === " " || e[s] === `
|
|
75
|
+
` || e[s] === "\r") && /[\t\r\n]/.test(t) ? { value: t, nextIndex: s } : null;
|
|
76
|
+
}
|
|
77
|
+
else
|
|
78
|
+
t += e[n], n += 1;
|
|
79
|
+
return null;
|
|
80
|
+
}, c = (e, l) => {
|
|
81
|
+
for (let t = l; t < e.length; t += 1)
|
|
82
|
+
if (e[t] === " " || e[t] === `
|
|
83
|
+
` || e[t] === "\r")
|
|
84
|
+
return t;
|
|
85
|
+
return e.length;
|
|
86
|
+
};
|
|
87
|
+
export {
|
|
88
|
+
g as m,
|
|
89
|
+
p,
|
|
90
|
+
o as s
|
|
91
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";const h=e=>`${e.map(l=>l.map(f).join(" ")).join(`\r
|
|
2
|
+
`)}\r
|
|
3
|
+
`,f=e=>/[\t\r\n]/.test(e)?`"${e.replaceAll('"','""')}"`:e,u=e=>e.endsWith(`\r
|
|
4
|
+
`)?e.slice(0,-2):e.endsWith(`
|
|
5
|
+
`)||e.endsWith("\r")?e.slice(0,-1):e,a=(e,l,t)=>{let n=0;for(;;){let s;if(e[n]==='"'){const r=p(e,n);if(r!==null)s=r.value,n=r.nextIndex;else{const i=c(e,n);s=e.slice(n,i),n=i}}else{const r=c(e,n);s=e.slice(n,r),n=r}if(l(s),n>=e.length){t();return}e[n]===" "?n+=1:(n+=e[n]==="\r"&&e[n+1]===`
|
|
6
|
+
`?2:1,t())}},o=e=>{const l=u(e);if(l==="")return[[""]];const t=[];let n=[];a(l,r=>{n.push(r)},()=>{t.push(n),n=[]});let s=0;for(const r of t)r.length>s&&(s=r.length);return t.map(r=>r.length===s?r:[...r,...Array(s-r.length).fill("")])},g=e=>{const l=u(e);if(l==="")return{rows:1,cols:1};let t=0,n=0,s=0;return a(l,()=>{s+=1},()=>{t+=1,s>n&&(n=s),s=0}),{rows:t,cols:n}},p=(e,l)=>{let t="",n=l+1;for(;n<e.length;)if(e[n]==='"')if(e[n+1]==='"')t+='"',n+=2;else{const s=n+1;return(s>=e.length||e[s]===" "||e[s]===`
|
|
7
|
+
`||e[s]==="\r")&&/[\t\r\n]/.test(t)?{value:t,nextIndex:s}:null}else t+=e[n],n+=1;return null},c=(e,l)=>{for(let t=l;t<e.length;t+=1)if(e[t]===" "||e[t]===`
|
|
8
|
+
`||e[t]==="\r")return t;return e.length};exports.measureTsv=g;exports.parseTsv=o;exports.serializeTsv=h;
|
package/dist/tsv.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./tsv-BHXbWK5W.cjs");exports.parseTsv=e.parseTsv;exports.serializeTsv=e.serializeTsv;
|
package/dist/tsv.d.cts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses Excel-behavior TSV into a rectangular matrix (ragged rows are right-padded).
|
|
3
|
+
* Excel 実挙動 TSV を矩形行列へ解析 (ギザギザ行は右パディング)。
|
|
4
|
+
*/
|
|
5
|
+
export declare const parseTsv: (text: string) => string[][];
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Serializes a matrix to Excel-behavior TSV with a trailing CRLF.
|
|
9
|
+
* 行列を終端 CRLF つきの Excel 実挙動 TSV へ直列化。
|
|
10
|
+
*/
|
|
11
|
+
export declare const serializeTsv: (matrix: readonly (readonly string[])[]) => string;
|
|
12
|
+
|
|
13
|
+
export { }
|
package/dist/tsv.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses Excel-behavior TSV into a rectangular matrix (ragged rows are right-padded).
|
|
3
|
+
* Excel 実挙動 TSV を矩形行列へ解析 (ギザギザ行は右パディング)。
|
|
4
|
+
*/
|
|
5
|
+
export declare const parseTsv: (text: string) => string[][];
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Serializes a matrix to Excel-behavior TSV with a trailing CRLF.
|
|
9
|
+
* 行列を終端 CRLF つきの Excel 実挙動 TSV へ直列化。
|
|
10
|
+
*/
|
|
11
|
+
export declare const serializeTsv: (matrix: readonly (readonly string[])[]) => string;
|
|
12
|
+
|
|
13
|
+
export { }
|
package/dist/tsv.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiquants/spreadsheet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Excel-grade spreadsheet grid for React: multi-cell selection, TSV/HTML clipboard, in-place editing on top of @aiquants/virtualscroll",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"**/*.css"
|
|
@@ -32,6 +32,17 @@
|
|
|
32
32
|
},
|
|
33
33
|
"default": "./dist/view.js"
|
|
34
34
|
},
|
|
35
|
+
"./tsv": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/tsv.d.ts",
|
|
38
|
+
"default": "./dist/tsv.js"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/tsv.d.cts",
|
|
42
|
+
"default": "./dist/tsv.cjs"
|
|
43
|
+
},
|
|
44
|
+
"default": "./dist/tsv.js"
|
|
45
|
+
},
|
|
35
46
|
"./styles/spreadsheet.css": "./dist/styles/spreadsheet.css",
|
|
36
47
|
"./styles/spreadsheet.standalone.css": "./dist/styles/spreadsheet.standalone.css"
|
|
37
48
|
},
|
package/src/tsv.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The TSV codec the grid copies and pastes with (Excel's real behaviour: one trailing line terminator
|
|
3
|
+
* dropped, empty text read as one empty cell, ragged rows padded with "", only fields holding a tab or a line break
|
|
4
|
+
* quoted), React-free, so a host reads or writes a grid's text before the grid itself is loaded — a
|
|
5
|
+
* server-rendered placeholder table, a lazily imported grid. Published as `@aiquants/spreadsheet/tsv`, which loads
|
|
6
|
+
* none of the grid; the barrel exports the same two functions.
|
|
7
|
+
*
|
|
8
|
+
* グリッドがコピーと貼り付けに使う TSV の符号化 (Excel の実際の振る舞い: 末尾の改行 1 つを除く・空の文字は空のセル 1 つ・
|
|
9
|
+
* 不揃いの行は "" で埋める・引用符で囲むのはタブか改行を含む値だけ) を React を読まずに渡すモジュール。ホストがグリッドを
|
|
10
|
+
* 読み込む前に (サーバーで描く代わりの表、遅延で読み込むグリッド) グリッドの文字を読み書きできる。グリッドを読み込まない
|
|
11
|
+
* `@aiquants/spreadsheet/tsv` として公開し、barrel も同じ 2 つの関数を公開する。
|
|
12
|
+
*/
|
|
13
|
+
export { parseTsv, serializeTsv } from "./clipboard/tsv.ts"
|