@awesome-fe/translate
Version:
Translation utils
204 lines • 9.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AdocTranslator = void 0;
const adoc_1 = require("../dom/asciidoctor/utils/adoc");
const tiny_html_to_adoc_1 = require("../dom/asciidoctor/html-adoc/tiny-html-to-adoc");
const adoc_to_tiny_html_1 = require("../dom/asciidoctor/html-adoc/adoc-to-tiny-html");
const adoc_builder_1 = require("../dom/asciidoctor/adoc-builder/adoc-builder");
const abstract_translator_1 = require("./abstract-translator");
const common_1 = require("../dom/common");
const translation_pair_1 = require("./translation-pair");
class AdocTranslator extends abstract_translator_1.AbstractTranslator {
builder = new adoc_builder_1.AdocBuilder();
inlinePairSeparator = '$$$';
translateDoc(node) {
if (adoc_1.adoc.isAbstractBlock(node)) {
if (!adoc_1.adoc.isDocument(node)) {
const [original, translation] = (0, translation_pair_1.buildTranslationPair)(node.getAttribute(`original_title`, ''), node.getTitle());
this.translateAdoc(original, translation).then(result => {
if (result && result !== original) {
node.setTitle(result);
node.setAttribute(`original_title`, original);
}
});
}
this.translateAttribute(node, 'title');
if (adoc_1.adoc.isList(node)) {
node.getItems().forEach((it) => this.translateDoc(it));
}
else if (adoc_1.adoc.isDescriptionList(node)) {
node.getItems().flat(9).forEach((it) => this.translateDoc(it));
}
else {
node.getBlocks().filter(it => it !== node).forEach((it) => this.translateDoc(it));
}
}
if (adoc_1.adoc.hasLines(node) && !['source', 'asciimath', 'literal'].includes(node.getStyle())) {
const text = node.lines.join('\n').trim();
if (text && !(0, common_1.containsChinese)(text)) {
if (adoc_1.adoc.isListItem(node.getParent())) {
const [original, translation] = text.split(this.inlinePairSeparator);
this.translateAdoc(original, translation).then(result => {
if (result && result !== original) {
node.lines = [original, result].join(this.inlinePairSeparator).split('\n');
}
});
}
else if (adoc_1.adoc.isParagraph(node)) {
const [originalNode, translationNode] = this.buildTranslationPair(node);
const originalText = originalNode.lines.join('\n');
const translationText = translationNode.lines.join('\n');
this.translateAdoc(originalText, translationText).then(result => {
if (result && result !== originalText) {
translationNode.lines = result.split('\n');
}
else {
adoc_1.adoc.removeNode(translationNode);
}
});
}
else {
const lines = text.split(/\n\n+/);
const pairs = [];
for (let i = 0; i < lines.length; ++i) {
const thisLine = lines[i];
const nextLine = lines[i + 1] ?? '';
if (!(0, common_1.containsChinese)(thisLine)) {
if ((0, common_1.containsChinese)(nextLine)) {
pairs.push([thisLine, nextLine]);
}
else {
pairs.push([thisLine, '']);
}
}
}
const tasks = pairs.map((pair) => {
return this.translateAdoc(pair[0], pair[1]).then(result => {
if (result && result !== pair[0]) {
pair[1] = result;
}
});
});
Promise.all(tasks).then(() => {
node.lines = pairs.map(([original, translation]) => [original, translation].join('\n\n')).join('\n\n').split('\n');
});
}
}
}
if (adoc_1.adoc.isDocument(node)) {
this.translateAttribute(node, 'doctitle');
this.translateAttribute(node, 'description');
}
if (adoc_1.adoc.isQuote(node)) {
this.translateAttribute(node, 'title');
this.translateAttribute(node, 'citetitle');
this.translateAttribute(node, 'attribution');
}
if (adoc_1.adoc.isBlockImage(node)) {
this.translateAttribute(node, 'alt');
}
if (adoc_1.adoc.isBlockResource(node)) {
this.translateAttribute(node, 'poster');
}
if (adoc_1.adoc.isTable(node)) {
const rows = node.getRows();
this.translateHeadRows(rows.head);
this.translateRows(rows.body);
this.translateRows(rows.foot);
}
if (adoc_1.adoc.isVerse(node)) {
this.translateAttribute(node, 'attribution');
this.translateAttribute(node, 'citetitle');
}
if (adoc_1.adoc.isListItem(node)) {
const text = node.getText().toString();
const [original, translation] = text.split(this.inlinePairSeparator);
this.translateAdoc(original, translation).then(translation => {
if (translation && translation !== original) {
node.setText([original, translation].join(this.inlinePairSeparator));
}
});
}
return node;
}
parse(text) {
return this.builder.parse(text);
}
serialize(doc) {
return this.builder.build(doc);
}
async translateAdoc(original, translation) {
original = original?.toString();
if (!original) {
return '';
}
if ((0, common_1.containsChinese)(original)) {
return original;
}
const sourceHtml = unwrap((0, adoc_to_tiny_html_1.adocToTinyHtml)(original));
const translationHtml = translation && unwrap((0, adoc_to_tiny_html_1.adocToTinyHtml)(translation));
return await this.translateSentence(sourceHtml, translationHtml, 'html').then(result => {
return (0, tiny_html_to_adoc_1.tinyHtmlToAdoc)(wrap(result));
});
}
translateAttribute(node, attributeName) {
const [original, translation] = (0, translation_pair_1.buildTranslationPair)(node.getAttribute(`original_${attributeName}`, ''), node.getAttribute(attributeName, ''));
if (original) {
this.translateAdoc(original, translation).then(translation => {
if (translation && original !== translation) {
node.setAttribute(attributeName, translation);
node.setAttribute(`original_${attributeName}`, original);
}
});
}
}
translateRows(rows) {
rows.map(row => row.map((cell) => {
const [original, translation] = cell.getText().toString().split('\n\n');
this.translateAdoc(original, translation).then(translation => {
if (translation !== original) {
cell.style = 'asciidoc';
cell.text = `${original}\n\n${translation}`;
}
});
}));
}
translateHeadRows(rows) {
rows.map(row => row.map((cell) => {
if ((0, common_1.containsChinese)(cell.getText().toString())) {
return;
}
// 标题行不支持 asciidoc 模式,因此只做简单的替换
this.translateAdoc(cell.text, '').then(translation => {
if (translation !== cell.text) {
cell.text = translation;
}
});
}));
}
buildTranslationPair(node) {
const parent = node.getParent();
const siblings = parent.getBlocks();
const next = siblings[siblings.indexOf(node) + 1];
if (next?.lines && (0, common_1.containsChinese)(next.lines.join('\n'))) {
return [node, next];
}
else {
const newNext = adoc_1.adoc.createBlock(parent, 'paragraph');
newNext.lines = [];
siblings.splice(siblings.indexOf(node) + 1, 0, newNext);
return [node, newNext];
}
}
}
exports.AdocTranslator = AdocTranslator;
function unwrap(text) {
return text
.replace(/\bprop-alt=/g, 'alt=')
.replace(/^<article adoc-name="document"><p adoc-name="paragraph">(.*)<\/p><\/article>$/gs, '$1');
}
function wrap(text) {
const content = text.replace(/\balt=/g, 'prop-alt=');
return `<article adoc-name="document"><p adoc-name="paragraph">${content}</p></article>`;
}
//# sourceMappingURL=adoc-translator.js.map