Last active
June 15, 2022 02:05
-
-
Save vorbei/b4d4ed714c80cbaab3546970af67b240 to your computer and use it in GitHub Desktop.
Sketch 中英文复合字体插件
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fontManager = [NSFontManager sharedFontManager]; | |
const UI = require('sketch/ui'); | |
//注意:更新后的插件版本,配置请填写 Font Family 名称,请不要再选择 Postscript 名称 | |
//顺序:英文字体,中文字体,数字字体(请依照自己安装的字体和喜好配置) | |
const options = { | |
'SF, 苹方, Mono': | |
'SF Pro Text, PingFang SC, SF Mono', | |
'Arial, 微软雅黑': | |
'Arial, Microsoft YaHei', | |
'New York, 思源宋体': | |
'New York Medium,Source Han Serif CN', | |
'Space Grotesk, 思源黑体, Mono Regular': | |
'Space Grotesk, Source Han Sans CN, SF Mono', | |
'Inter, 思源黑体': | |
'Inter,Source Han Sans CN' | |
} | |
const latin_re = /[\u0020-\u00FF]+/mg; | |
const digit_re = /[0-9\.,\-]+/mg; | |
const cjk_re = /[\u2000-\uFFE0]+/mg; | |
const sfsymbol_re = /[\u{100000}-\u{1006EA}]+/ug; | |
let stats = {layers: 0, latin_ranges:0, cjk_ranges: 0, digit_ranges: 0} | |
function reHelper (re, text){ | |
let buffer, ranges = []; | |
while ((buffer = re.exec(text)) !== null) { | |
res = { "string": buffer[0], "start": buffer.index, "length": buffer[0].length}; | |
ranges.push(NSMakeRange(res.start,res.length)) | |
} | |
return ranges; | |
} | |
function fontHelper (fn,size) { return NSFont.fontWithName_size(fn,size?size:16) }; | |
function changeFont(newFamily, oldFont){ | |
const font = [fontManager fontWithFamily:newFamily traits:oldFont.traits weight:oldFont.weight size:oldFont.size]; | |
return font; | |
} | |
function fontInRange (layer,range){ | |
const sub = [[layer attributedStringValue] attributedSubstringFromRange: range]; | |
const _range = sub.treeAsDictionary().attributes[0].NSFont | |
const fontFamily = _range.family; | |
const fontPostScriptName = _range.attributes.NSFontNameAttribute; | |
const fontSize = _range.attributes.NSFontSizeAttribute; | |
const _font = fontHelper(fontPostScriptName,fontSize); | |
const fontWeight = [fontManager weightOfFont:_font]; | |
const fontTraits = [fontManager traitsOfFont:_font]; | |
const font = { | |
family: fontFamily, | |
weight: fontWeight, | |
traits: fontTraits, | |
size: fontSize, | |
name: fontPostScriptName | |
} | |
return font; | |
} | |
function updateLayers(latin_font, cjk_font, digit_font){ | |
let selectedLayers = context.selection; | |
let layers = selectedLayers; | |
let sf_font = "SF Pro Text"; | |
stats.layers += layers.length; | |
layers.forEach(function(layer){ | |
if (layer.className() != 'MSTextLayer') return; | |
let text = layer.stringValue(); | |
let latin_ranges = latin_font?reHelper(latin_re,text):[]; | |
let cjk_ranges = cjk_font?reHelper(cjk_re, text):[]; | |
let digit_ranges = digit_font?reHelper(digit_re,text):[]; | |
let sfsymbol_ranges = digit_font?reHelper(sfsymbol_re,text):[]; | |
stats.latin_ranges += latin_ranges.length; | |
stats.cjk_ranges += cjk_ranges.length; | |
stats.digit_ranges += digit_ranges.length; | |
layer.setIsEditingText(true); | |
cjk_ranges.forEach(function(range){ | |
layer.addAttribute_value_forRange(NSFontAttributeName, changeFont(cjk_font, fontInRange(layer,range)), range); | |
}); | |
latin_ranges.forEach(function(range){ | |
layer.addAttribute_value_forRange(NSFontAttributeName, changeFont(latin_font, fontInRange(layer,range)), range); | |
}); | |
digit_ranges.forEach(function(range){ | |
layer.addAttribute_value_forRange(NSFontAttributeName, changeFont(digit_font, fontInRange(layer,range)), range); | |
}); | |
sfsymbol_ranges.forEach(function(range){ | |
layer.addAttribute_value_forRange(NSFontAttributeName, changeFont(sf_font, fontInRange(layer,range)), range); | |
}); | |
layer.setIsEditingText(false); | |
}) | |
}; | |
UI.getInputFromUser("请选择英文、中文、数字字体(可选)", { | |
type: UI.INPUT_TYPE.selection, | |
possibleValues: Object.keys(options) | |
}, (err, value) => { | |
if (err) { | |
return; | |
} else { | |
let fonts = options[value].split(/ *, */); | |
updateLayers(fonts[0],fonts[1],fonts[2]); | |
statsMsg = `共设置 ${stats.layers} 个图层:英文 ${stats.latin_ranges} 段, 中文 ${stats.cjk_ranges} 段,数字 ${stats.digit_ranges} 段。`; | |
log(statsMsg); | |
UI.message(statsMsg); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment