Add: Sentence html Merge Translation Feature

This commit is contained in:
sub-hub
2024-05-04 22:44:28 +09:00
parent 120e9356b6
commit a7509c4a35
2 changed files with 88 additions and 3 deletions

View File

@@ -8,7 +8,8 @@ import { doingChat } from "../process"
import type { simpleCharacterArgument } from "../parser"
import { selectedCharID } from "../stores"
import { getModuleRegexScripts } from "../process/modules"
import { sleep } from "../util"
import { getNodetextWithNewline, sleep } from "../util"
import { processScriptFull } from "../process/scripts"
let cache={
origin: [''],
@@ -298,7 +299,7 @@ export async function translateHTML(html: string, reverse:boolean, charArg:simpl
}
async function translateNodeText(node:Node) {
async function translateNodeText(node:Node, reapplyDisplayScript:boolean = false) {
if(node.textContent.trim().length !== 0){
if(needSuperChunkedTranslate()){
const prm = new Promise<string>((resolve) => {
@@ -311,7 +312,32 @@ export async function translateHTML(html: string, reverse:boolean, charArg:simpl
return
}
node.textContent = await translate(node.textContent || '', reverse);
// node.textContent = await translate(node.textContent || '', reverse);
let translated = await translate(node.textContent || "", reverse);
if (!reapplyDisplayScript) {
node.textContent = translated;
return;
}
const { data: processedTranslated } = await processScriptFull(
alwaysExistChar,
translated,
"editdisplay",
chatID
);
// If the translation is the same, don't replace the node
if (translated == processedTranslated) {
node.textContent = processedTranslated;
return;
}
// Replace the old node with the new one
const newNode = document.createElement(
node.nodeType === Node.TEXT_NODE ? "span" : node.nodeName
);
newNode.innerHTML = processedTranslated;
node.parentNode.replaceChild(newNode, node);
}
}
@@ -336,6 +362,37 @@ export async function translateHTML(html: string, reverse:boolean, charArg:simpl
if(node.nodeName.toLowerCase() === 'script' || node.nodeName.toLowerCase() === 'style'){
return
}
// Check If a paragraph is a set of pure sentences
if (
node.nodeName.toLowerCase() === "p" &&
node instanceof HTMLElement
) {
const children = Array.from(node.childNodes);
const blacklist = ["img", "iframe", "script", "style", "div"];
const hasBlacklistChild = children.some((child) =>
blacklist.includes(child.nodeName.toLowerCase())
);
if (!hasBlacklistChild) {
const text = getNodetextWithNewline(node);
const sentences = text.split("\n");
if (sentences.length > 1) {
// Multiple sentences seperated by <br> tags
// reconstruct the p tag
node.innerHTML = "";
for (const sentence of sentences) {
const newNode = document.createElement("span");
newNode.textContent = sentence;
node.appendChild(newNode);
await translateNodeText(newNode, true);
node.appendChild(document.createElement("br"));
}
} else {
// Single sentence
await translateNodeText(node, true);
}
return;
}
}
for (const child of Array.from(node.childNodes)) {
if(node.nodeType === Node.ELEMENT_NODE && (node as Element)?.getAttribute('translate') === 'no'){

View File

@@ -522,4 +522,32 @@ export function appendLastPath(url, lastPath) {
// Concat the url and lastPath
return url + '/' + lastPath;
}
/**
* Retrieves the text content of a given Node object, including line breaks represented by <br> elements.
*
* @param {Node} node - The Node object from which the text content will be extracted.
* @returns {string} The text content of the Node, with line breaks represented by newline characters ('\n').
*
* @example
* const div = document.createElement('div');
* div.innerHTML = 'Hello<br>World';
* const text = getNodetextWithNewline(div);
* console.log(text); // Output: "Hello\nWorld"
*/
export function getNodetextWithNewline(node: Node) {
let result = '';
for (const child of node.childNodes) {
if (child.nodeType === Node.TEXT_NODE) {
result += child.textContent;
} else if (child.nodeType === Node.ELEMENT_NODE) {
if (child.nodeName === 'BR') {
result += '\n';
} else {
result += getNodetextWithNewline(child);
}
}
}
return result;
}