update stringify.js

This commit is contained in:
wxzhang 2022-03-15 21:38:15 +08:00
parent a594b51cb6
commit 353234cd01
5 changed files with 100 additions and 26 deletions

22
packages/demo/data.js Normal file
View File

@ -0,0 +1,22 @@
module.exports = {
"name" : "张三丰",
"age" : 12,
"active" : true,
"address" : [
"北京市",
"福建省泉州市\n洛阳镇"
],
"posts" : {
"title" : "标题",
"content": "内容"
},
"产品清单\t{}": [
"手机",
"电脑"
],
"产品价格" : {
"手机": 1299,
"电脑": 3999
},
"产品\\清单" : 1
}

View File

@ -1,28 +1,42 @@
const { objectToString } = require("../tools/stringify")
const objectToString = require("../tools/stringify")
const path = require("path");
const fs = require("fs");
const k1 = "产品清单\t{}"
const k2 = "产品\\清单"
const data = {
name:"张三丰",
age:12,
active:true,
address:[
"北京市",
"福建省泉州市"
"福建省泉州市\n洛阳镇"
],
posts:{
title:"标题",
content:"内容",
//comments:[]
},
"产品清单":[
[k1]:[
"手机",
"电脑"
]
],
"产品价格":{
"手机":1299,
"电脑":3999
},
[k2]:1
}
const result = objectToString(data)
console.log(result)
fs.writeFileSync(path.join(__dirname,"./data.js"),`module.exports = ${result}`)
const loaded = require("./data.js")
console.log(loaded[k1])
console.log(loaded[k2])

View File

@ -13,14 +13,16 @@ const readJson = require("readjson")
const createLogger = require("logsets")
const { replaceInterpolateVars,getDataTypeName } = require("@voerkai18n/runtime")
const { findModuleType,createPackageJsonFile } = require("./utils")
const stringify = require("./stringify")
const logger = createLogger()
const { t } = require("./languages")
// 捕获翻译文本正则表达式一:缺点:当t(xxx,...复杂的表达式时不能正确匹配....)
// 捕获翻译文本正则表达式一: 能匹配完整的t(xx,...)函数调用如果t函数调用不完整则不能匹配到
// 但是当t(xxx,...复杂的表达式时....)则不能正确匹配到,因此放弃该正则表达式
// const DefaultTranslateExtractor = String.raw`\b{funcName}\(\s*("|'){1}(?:((?<namespace>\w+)::))?(?<text>.*?)(((\1\s*\)){1})|((\1){1}\s*(,(\w|\d|(?:\{.*\})|(?:\[.*\])|([\"\'\(].*[\"\'\)]))*)*\s*\)))`
// 捕获翻译文本正则表达式二: 能够支持复杂的表达式但是当提供不完整的t函数定义时也会进行匹配提取 比如t
// 捕获翻译文本正则表达式二: 能够支持复杂的表达式但是当提供不完整的t函数定义时也会进行匹配提取
const DefaultTranslateExtractor = String.raw`\bt\(\s*("|'){1}(?:((?<namespace>\w+)::))?(?<text>.*?)(?=(\1\s*\))|(\1\s*\,))`
@ -314,7 +316,7 @@ function updateLanguageFile(fromTexts,toLangFile,options){
// 默认的overwrite
if(!["merge","sync"].includes(updateMode)){
fs.writeFileSync(toLangFile,JSON.stringify(targetTexts,null,4))
fs.writeFileSync(toLangFile,stringify(targetTexts))
return
}
let targetTexts = {}
@ -349,7 +351,7 @@ function updateLanguageFile(fromTexts,toLangFile,options){
targetTexts[text] = sourceLangs
}
})
fs.writeFileSync(toLangFile,JSON.stringify(targetTexts,null,4))
fs.writeFileSync(toLangFile,stringify(targetTexts))
}
@ -409,7 +411,7 @@ module.exports = function(options={}){
updateLanguageFile(texts,langFile,options)
logger.log(" √ 更新语言文件 : {}",path.relative(outputPath,langFile))
}else{
fs.writeFileSync(langFile,JSON.stringify(texts,null,4))
fs.writeFileSync(langFile,stringify(texts))
logger.log(" √ 保存语言文件 : {}",path.relative(outputPath,langFile))
}
}

View File

@ -1,15 +1,21 @@
{
"支持的语言\t: {}": {
"en": "Supported Languages\t: {}",
"工程项目所在目录" : {
"en" : "Project Directory",
"$file": [
"index.js"
]
},
"支持的语言\\t: {}": {
"en" : "支持的语言\\t: {}",
"$file": [
"compile.command.js",
"extract.plugin.js"
]
},
"工程项目所在目录": {
"en": "Project Directory",
"保存{}\\n" : {
"en" : "保存{}\\n",
"$file": [
"index.js"
"stringify.js"
]
}
}

View File

@ -1,3 +1,33 @@
/**
* 实现将{}转化为字符串
*
* 为什么不使用JSON.stringify?
*
* 假设有这样的翻译内容
* {
* "保存{}\n": "Save{}\n",
* }
* 这个内容中包含了转义字符\nJSON.stringify会将\n转义为\\n
* 因此在保存后文件中就变成
* {
* "保存{}\\n": "Save{}\n",
* }
* 这个转义方式比较不符合我们的预期更关键的是在require("cn.js")
* 得到的是
* {
* "保存{}\\n": "Save{}\n",
* }
* 这样当我们调用t函数时就会找不到对应在的key
*
* 问题的关键就在于JSON.stringify对转义字符的处理不能符合我们的要求
*
* 因此不得不自己来处理转义字符.
*
* 使用objectToString方法后就可以确保在翻译文件中的转义字符能按预期的方式工作
*
*
*
*/
const { isPlainObject } = require("./utils")
/**
@ -10,15 +40,16 @@ const { isPlainObject } = require("./utils")
* @returns
*/
function escape(str){
return str.replaceAll("\t","\\t")
return str.replaceAll('\\','\\\\')
.replaceAll("\t","\\t")
.replaceAll("\n","\\n")
.replaceAll("\b","\\b")
.replaceAll("\r","\\r")
.replaceAll("\f","\\f")
.replaceAll("\\","\\\\")
.replaceAll("\'","\\'")
.replaceAll('\"','\\"')
.replaceAll('\v','\\v')
}
/**
* 获取字符串的长度中文算两个字符
@ -62,7 +93,7 @@ function objectToString(obj,{indent=4,alignKey=true}={}){
}
results.push(item)
})
endChar =" ".repeat((level-1) * indent) + ( last ? "]" : "]")
endChar =" ".repeat((level-1) * indent) + "]"
return beginChar + results.map(item=>{
return `${" ".repeat(level * indent)}${item}`
}).join("\n") + endChar
@ -73,7 +104,7 @@ function objectToString(obj,{indent=4,alignKey=true}={}){
let alignIndent = 0
Object.entries(node).forEach(([key,value],index)=>{
const isLastItem = index ===length-1
alignIndent = Math.max(getStringWidth(key),alignIndent)
alignIndent = Math.max(getStringWidth(escape(key)),alignIndent)
let item = [`${indentSpace}"${escape(key)}"`,value]
if(Array.isArray(value) || isPlainObject(value)){
item[1] = nodeToString(value, level,isLastItem)
@ -92,10 +123,10 @@ function objectToString(obj,{indent=4,alignKey=true}={}){
}
results.push(item)
})
endChar =" ".repeat((level-1) * indent) + ( last ? "}" : "}")
endChar =" ".repeat((level-1) * indent) + "}"
return beginChar + results.map(item=>{
if(alignKey){
return `${item[0]}${ " ".repeat(alignIndent-getStringWidth(item[0].trim())+2)}: ${item[1]}`
return `${item[0]}${" ".repeat(alignIndent-getStringWidth(item[0].trim())+2)}: ${item[1]}`
}else{
return `${item[0]}: ${item[1]}`
}
@ -104,8 +135,7 @@ function objectToString(obj,{indent=4,alignKey=true}={}){
}
return nodeToString(obj,0,true)
}
module.exports = {
objectToString,
getStringWidth
}
}
module.exports = objectToString