Skip to content

Commit

Permalink
更新物编json格式化细节
Browse files Browse the repository at this point in the history
  • Loading branch information
sumneko committed Dec 13, 2024
1 parent 0775e83 commit 4072b24
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 82 deletions.
32 changes: 15 additions & 17 deletions src/editorTable/editorData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ interface KVShape {
prop_cls: "PText"|"PBool"|"PFloat"|"PInt",
remark: string,
show_in_attr: boolean,
sort: number,
sort: bigint,
type: keyof typeof Table.type.type,
value: string|number|boolean,
}

function fromKV(kvMap: Record<string, KVShape>): KV {
let result: Record<string, string|number|boolean> = {};
// 按照 sort 字段的值排序,然后将重新组成 { K: V.value } 的形式
let kvList = Object.values(kvMap).sort((a, b) => a.sort - b.sort);
let kvList = Object.values(kvMap).sort((a, b) => Number(a.sort - b.sort));
for (let kv of kvList) {
result[kv.key] = kv.value;
}
Expand All @@ -75,26 +75,24 @@ function toKV(kv: KV, raw: Record<string, KVShape>): Record<string, KVShape> {
...result[key],
value,
};
sort = Math.max(sort, result[key].sort);
sort = Math.max(sort, Number(result[key].sort));
} else {
let etype, type, prop_cls;
if (typeof value === 'string') {
etype = 0;
type = 0;
etype = 0n;
type = 0n;
prop_cls = 'PText';
} else if (typeof value === 'number') {
if (Number.isInteger(value)) {
etype = 1;
type = 2;
prop_cls = 'PInt';
} else {
etype = 2;
type = 1;
prop_cls = 'PFloat';
}
etype = 2n;
type = 1n;
prop_cls = 'PFloat';
} else if (typeof value === 'bigint') {
etype = 1n;
type = 2n;
prop_cls = 'PInt';
} else if (typeof value === 'boolean') {
etype = 4;
type = 3;
etype = 4n;
type = 3n;
prop_cls = 'PBool';
} else {
continue;
Expand All @@ -107,7 +105,7 @@ function toKV(kv: KV, raw: Record<string, KVShape>): Record<string, KVShape> {
prop_cls: prop_cls as any,
remark: '',
show_in_attr: false,
sort: ++sort,
sort: BigInt(++sort),
type: type as any,
value,
};
Expand Down
106 changes: 67 additions & 39 deletions src/editorTable/editorJson.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,80 @@
import * as jsonc from 'jsonc-parser';
import * as y3 from 'y3-helper';
import { Json } from '../tools/json';
import * as jsonc from 'jsonc-parser';

const jsonFormatOptions: y3.json.formatOptions = {
stringify: (value) => {
if (typeof value === 'bigint') {
function stringify(value: any, tabLevel = 0): string {
switch (typeof value) {
case 'bigint': {
return value.toString();
}
if (typeof value === 'number' && isFinite(value)) {
return value.toFixed(1);
}
if (typeof value === 'string') {
// 将所有的 unicode 转为 \uXXXX 形式
let result = JSON.stringify(value);
result = result.replace(/[\u0080-\uffff]/g, (ch) => {
};
case 'number': {
if (isFinite(value)) {
return value.toFixed(1);
} else {
return JSON.stringify(value);
}
};
case 'string': {
return JSON.stringify(value).replace(/[\u0080-\uffff]/g, (ch) => {
return '\\u' + ('0000' + ch.charCodeAt(0).toString(16)).slice(-4);
});
return result;
}
},
patchEdit: (edit) => {
let scanner = jsonc.createScanner(edit.content);
let edits: jsonc.Edit[] = [];
while (scanner.scan() !== jsonc.SyntaxKind.EOF) {
if (scanner.getToken() === jsonc.SyntaxKind.StringLiteral) {
let start = scanner.getTokenOffset();
let length = scanner.getTokenLength();
let value = edit.content.slice(start + 1, start + length - 1);
let newValue = value.replace(/[\u0080-\uffff]/g, (ch) => {
return '\\u' + ('0000' + ch.charCodeAt(0).toString(16)).slice(-4);
});
if (value !== newValue) {
edits.push({
offset: start + 1,
length: value.length,
content: newValue,
});
};
case 'object': {
if (value === null) {
return 'null';
}
if (Array.isArray(value)) {
if (value.length === 0) {
return '[]';
}
let result = '[\n';
const tab = ' '.repeat(tabLevel + 1);
for (let i = 0; i < value.length; i++) {
let item = value[i];
result += tab + stringify(item, tabLevel + 1);
if (i < value.length - 1) {
result += ', ';
}
result += '\n';
}
result += ' '.repeat(tabLevel) + ']';
return result;
} else {
let keys = Object.keys(value);
if (keys.length === 0) {
return '{}';
}
keys.sort();
let result = '{\n';
const tab = ' '.repeat(tabLevel + 1);
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let item = value[key];
result += tab + stringify(key) + ': ' + stringify(item, tabLevel + 1);
if (i < keys.length - 1) {
result += ', ';
}
result += '\n';
}
result += ' '.repeat(tabLevel) + '}';
return result;
}
}
edit.content = jsonc.applyEdits(edit.content, edits);
edit.content = edit.content.replace(/,([\r\n])/g, ', $1');
return edit;
},
};
};
default: {
return JSON.stringify(value);
};
}
}

export class EditorJson extends Json {
constructor(text: string) {
super(text, jsonFormatOptions);
super(text, {
stringify: stringify,
patchJson: true,
patchEdit: (edit: jsonc.Edit) => {
edit.content = edit.content.replace(/,\n/g, ', \n');
return edit;
}
});
}
}
58 changes: 32 additions & 26 deletions src/tools/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type JObject = { [key: string]: Item };
export interface formatOptions {
stringify?: (value: any) => string | undefined;
patchEdit?: (edit: jsonc.Edit) => jsonc.Edit;
patchJson?: boolean;
}

export class Json {
Expand Down Expand Up @@ -82,38 +83,43 @@ export class Json {
}
this._tree = undefined;

let originStringify: typeof JSON.stringify | undefined;
if (this.options?.stringify) {
originStringify = JSON.stringify;
let hookedStringfy = (value: any, replacer?: any, space?: any) => {
if (replacer) {
if (this.options?.patchJson) {
let originStringify: typeof JSON.stringify | undefined;
if (this.options?.stringify) {
originStringify = JSON.stringify;
let hookedStringfy = (value: any, replacer?: any, space?: any) => {
if (replacer) {
return originStringify!(value, replacer, space);
}
JSON.stringify = originStringify!;
let result = this.options!.stringify!(value);
JSON.stringify = hookedStringfy;
if (result !== undefined) {
return result;
}
return originStringify!(value, replacer, space);
}
JSON.stringify = originStringify!;
let result = this.options!.stringify!(value);
};
JSON.stringify = hookedStringfy;
if (result !== undefined) {
return result;
}
return originStringify!(value, replacer, space);
};
JSON.stringify = hookedStringfy;
}
}

try {
for (const key in this._patch) {
const value = this._patch[key];
let edits = jsonc.modify(this._text, [key], value, editOptions);
if (this.options?.patchEdit) {
edits = edits.map(this.options.patchEdit);
try {
for (const key in this._patch) {
const value = this._patch[key];
let edits = jsonc.modify(this._text, [key], value, editOptions);
if (this.options?.patchEdit) {
edits = edits.map(this.options.patchEdit);
}
this._text = jsonc.applyEdits(this._text, edits);
}
} finally {
this._patch = undefined;
if (originStringify) {
JSON.stringify = originStringify;
}
this._text = jsonc.applyEdits(this._text, edits);
}
} finally {
} else {
this._patch = undefined;
if (originStringify) {
JSON.stringify = originStringify;
}
this._text = this.options?.stringify?.(this.data) ?? JSON.stringify(this.data, null, 4);
}
}
}
Expand Down

0 comments on commit 4072b24

Please sign in to comment.