This commit is contained in:
@@ -43,6 +43,7 @@ import { getMaxInlineSize } from '@/utils/config';
|
||||
import { getDirFromUILanguage } from '@/utils/rtl';
|
||||
import { isCJKLang } from '@/utils/lang';
|
||||
import { isTauriAppPlatform } from '@/services/environment';
|
||||
import { TransformContext } from '@/services/transformers/types';
|
||||
import { transformContent } from '@/services/transformService';
|
||||
import { lockScreenOrientation } from '@/utils/bridge';
|
||||
import { useTextTranslation } from '../hooks/useTextTranslation';
|
||||
@@ -118,15 +119,17 @@ const FoliateViewer: React.FC<{
|
||||
detail.data = Promise.resolve(detail.data)
|
||||
.then((data) => {
|
||||
const viewSettings = getViewSettings(bookKey);
|
||||
const bookData = getBookData(bookKey);
|
||||
if (viewSettings && detail.type === 'text/css')
|
||||
return transformStylesheet(width, height, data);
|
||||
if (viewSettings && detail.type === 'application/xhtml+xml') {
|
||||
if (viewSettings && bookData && detail.type === 'application/xhtml+xml') {
|
||||
const ctx = {
|
||||
bookKey,
|
||||
viewSettings,
|
||||
primaryLanguage: bookData.book?.primaryLanguage,
|
||||
content: data,
|
||||
transformers: ['punctuation', 'footnote', 'language'],
|
||||
};
|
||||
transformers: ['punctuation', 'footnote', 'whitespace', 'language'],
|
||||
} as TransformContext;
|
||||
return Promise.resolve(transformContent(ctx));
|
||||
}
|
||||
return data;
|
||||
|
||||
@@ -2,10 +2,12 @@ import type { Transformer } from './types';
|
||||
import { footnoteTransformer } from './footnote';
|
||||
import { languageTransformer } from './language';
|
||||
import { punctuationTransformer } from './punctuation';
|
||||
import { whitespaceTransformer } from './whitespace';
|
||||
|
||||
export const availableTransformers: Transformer[] = [
|
||||
punctuationTransformer,
|
||||
footnoteTransformer,
|
||||
languageTransformer,
|
||||
whitespaceTransformer,
|
||||
// Add more transformers here
|
||||
];
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { detectLanguage, isValidLang } from '@/utils/lang';
|
||||
import { detectLanguage, isSameLang, isValidLang } from '@/utils/lang';
|
||||
import type { Transformer } from './types';
|
||||
|
||||
export const languageTransformer: Transformer = {
|
||||
name: 'language',
|
||||
|
||||
transform: async (ctx) => {
|
||||
const primaryLanguage = ctx.primaryLanguage;
|
||||
let result = ctx.content;
|
||||
const attrsMatch = result.match(/<html\b([^>]*)>/i);
|
||||
if (attrsMatch) {
|
||||
@@ -13,9 +14,10 @@ export const languageTransformer: Transformer = {
|
||||
const xmlLangRegex = / xml:lang="([^"]*)"/i;
|
||||
const xmlLangMatch = attrs.match(xmlLangRegex);
|
||||
const langMatch = attrs.match(langRegex);
|
||||
if (!isValidLang(langMatch?.[1] || xmlLangMatch?.[1])) {
|
||||
const docLang = langMatch?.[1] || xmlLangMatch?.[1];
|
||||
if (!isValidLang(docLang) || !isSameLang(docLang, primaryLanguage)) {
|
||||
const mainContent = result.replace(/<[^>]+>/g, ' ');
|
||||
const lang = detectLanguage(mainContent);
|
||||
const lang = isValidLang(primaryLanguage) ? primaryLanguage : detectLanguage(mainContent);
|
||||
const newLangAttr = ` lang="${lang}"`;
|
||||
const newXmlLangAttr = ` xml:lang="${lang}"`;
|
||||
attrs = langMatch ? attrs.replace(langRegex, newLangAttr) : attrs + newLangAttr;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ViewSettings } from '@/types/book';
|
||||
export type TransformContext = {
|
||||
bookKey: string;
|
||||
viewSettings: ViewSettings;
|
||||
primaryLanguage?: string;
|
||||
content: string;
|
||||
transformers: string[];
|
||||
reversePunctuationTransform?: boolean;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { Transformer } from './types';
|
||||
|
||||
export const whitespaceTransformer: Transformer = {
|
||||
name: 'whitespace',
|
||||
|
||||
transform: async (ctx) => {
|
||||
const viewSettings = ctx.viewSettings;
|
||||
if (viewSettings.overrideLayout) {
|
||||
const cleaned = ctx.content
|
||||
// Replace but skip literal "&nbsp;"
|
||||
.replace(/(?<!&) /g, ' ')
|
||||
// Replace literal non-breaking space characters (U+00A0) with normal spaces
|
||||
.replace(/\u00A0/g, ' ')
|
||||
// Collapse consecutive spaces into one
|
||||
.replace(/ {2,}/g, ' ');
|
||||
return cleaned;
|
||||
} else {
|
||||
return ctx.content;
|
||||
}
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user