termtosvg 录制的 SVG 在有中文等字符输出时会挤压在一起 , 此脚本专门用于解决此问题
Usage: <svgfile> [options]
Options:
-o, --outDir <dir> 指定输出目录, 默认输出到当前目录
一行代码解决有问题的svg
npx https://gist.github.com/cnwhy/7cad3be853a188823c077df1182f6b1a /tmp/termtosvg_d4pd0f4p.svg
{ | |
"name": "termtosvg-CN-fix", | |
"version": "0.0.1", | |
"bin": "./termtosvg-fix.js", | |
"dependencies": { | |
"commander": "^2.19.0" | |
} | |
} |
#!/usr/bin/env node | |
// 处理 termtosvg 录制的SVG 对中文显示不友好的问题 | |
const program = require('commander'); | |
const path = require('path'); | |
const fs = require('fs'); | |
//常见非标宽字符区间 | |
const Ukuan = [ | |
'2460-24FF', //括号字母数字 | |
'27F0-27FF', //补充大箭头1 | |
'2900-297F', //补充大箭头2 | |
'2B00-2BFF', //补充大箭头3 | |
'2E80-9FFF', //中日韩 | |
'F900-FAFF', //中日韩相容表意文字 | |
'FE10-FE1F', //竖式标点 | |
'FE30-FE4F', //中日韩相容形式 | |
'FF00-FFEF', //全角字符 | |
]; | |
const Ukuan_rang = Ukuan.map(v=>v.split('-').map(i=>parseInt(i,16))); | |
const Ukuan_reg = new RegExp('['+Ukuan.map(v=>v.split('-').map(i=>'\\u'+i).join('-')).join('')+']'); | |
const reg_text = /<text[^>]*(textLength="\d+")[^>]*>(.*?)<\/text>/g; | |
const hasKuang = function(str){ | |
if(Ukuan_reg.test(str)){ | |
return true | |
}else{ | |
var codes = str.match(/&(?:#[xX][\da-fA-F]+|#\d+);/g); | |
if(codes){ | |
for(let s of codes){ | |
if (s.charAt(1) === '#') { | |
let code; | |
if (s.charAt(2) === 'X' || s.charAt(2) === 'x') { | |
// return decodeCodePoint(parseInt(str.substr(3), 16)); | |
code = parseInt(s.substr(3), 16) | |
} | |
code = parseInt(s.substr(2), 10); | |
for(let i=0; i<Ukuan_rang.length; i++){ | |
let range = Ukuan_rang[i]; | |
if(code >= range[0] && code <= range[1]){ | |
return true; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
const fixCN = function(xmlstr){ | |
return xmlstr.replace(reg_text,function(str,attr,content){ | |
if(hasKuang(content)){ | |
str = str.replace(attr,''); | |
} | |
return str; | |
}) | |
} | |
// const xml_map = { amp: '&', apos: "'", gt: '>', lt: '<', quot: '"' }; | |
// const xmlReplace = function() { | |
// if (str.charAt(1) === '#') { | |
// if (str.charAt(2) === 'X' || str.charAt(2) === 'x') { | |
// return decodeCodePoint(parseInt(str.substr(3), 16)); | |
// } | |
// return decodeCodePoint(parseInt(str.substr(2), 10)); | |
// } | |
// return xml_map[str.slice(1, -1)]; | |
// }; | |
// const xmlDecode = (function() { | |
// var keys = Object.keys(map).join('|'); | |
// keys += '|#[xX][\\da-fA-F]+|#\\d+'; | |
// var re = new RegExp('&(?:' + keys + ');', 'g'); | |
// return function(str) { | |
// return String(str).replace(re, xmlReplace); | |
// }; | |
// })(); | |
function main(files = [], outDir = './') { | |
// const files = args._ || []; | |
let filesPath = files.map(file => path.resolve(process.cwd(), file)); | |
let outPath = files.map(p=>path.join(outDir, 'convert-' + path.parse(p).base)); | |
let contents = filesPath.map(file => fs.readFileSync(file).toString()); | |
contents.forEach((xml,index)=>{ | |
fs.writeFileSync(outPath[index], fixCN(xml)); | |
}) | |
console.log('处理完成:') | |
console.log(outPath.join('\n')); | |
} | |
program.usage('<file> [options]'); | |
program.option('-o, --outDir <dir>', '指定输出目录'); | |
program.parse(process.argv); | |
if (program.args.length) { | |
main(program.args, program.outDir); | |
} |