UNPKG

@voerkai18n/utils

Version:

utils for voerkai18n

115 lines (96 loc) 3.1 kB
import { getFileNamespace } from '../../getFileNamespace' import { trimChars } from '../../trimChars'; import { parse, Lang, SgNode } from '@ast-grep/napi' function parseTranslateAttrs(code:string):ParagraphNode { const ast = parse(Lang.Html,code) const nodes = ast.root().findAll({ utils:{ "is-translate" : { kind: "element", regex: "^<Translate" } }, rule: { pattern:{ selector: "attribute", context: "<Translate $ATTR_NAME=$ATTR_VALUE>" }, inside: { matches: "is-translate", stopBy: "end" } } }) return nodes.reduce<ParagraphNode>((result,item)=>{ const attrName = item.getMatch("ATTR_NAME")?.text() if(attrName){ const attrValue = item.getMatch("ATTR_VALUE")?.text() result[attrName] = attrValue ? trimChars(attrValue) : undefined } return result },{} as ParagraphNode) } export type ParagraphNode = { id? : string message : string vars? : string scope? : string options? : string rang : { start: string, end: string } file? : string [key: string]: any } export type ExtractParagraphsOptions = { language?:string namespaces?:Record<string,string> file?:string } /** * * 提取段落 * * <Translate> * 段落内容 * </Translate> * * @param code */ export function extractParagraphs(code:string,options?:ExtractParagraphsOptions):ParagraphNode[]{ const opts = Object.assign({ extractor : 'ast', language : 'ts' },options) as Required<ExtractParagraphsOptions> const { file } = opts const paragraphs:ParagraphNode[] = [] const translatesAst = parse(Lang.Html,code) const nodes = translatesAst.root().findAll({ rule:{ kind: "element", regex: "^<Translate", pattern: "<Translate $$$>$$$</Translate>" } }) nodes.forEach((node:SgNode)=>{ const attrs = parseTranslateAttrs(node.text()) || {} const range = node.range() attrs.rang = { start: `${range.start.line}:${range.start.column}`, end : `${range.end.line}:${range.end.column}` } attrs.file = file if(attrs.message){ console.warn("[VoerkaI18n] translate paragraph attribute 'message' is not allowed") return } if(!attrs.id){ console.warn("[VoerkaI18n] translate paragraph attribute 'id' is required") return } const message = node.children().slice(1,-1).map(n=>n.text()).join("\n").trim() if(message.length>0){ attrs.message=message paragraphs.push(attrs as any) } }) return paragraphs }