fix: reverse punctuation transform when highlighting (#862)

This commit is contained in:
Huang Xin
2025-04-11 12:30:08 +08:00
committed by GitHub
parent 3ea3a50baa
commit 6ba15319a8
6 changed files with 28 additions and 10 deletions
@@ -66,6 +66,7 @@ const FoliateViewer: React.FC<{
bookKey,
viewSettings,
content: data,
transformers: ['punctuation'],
};
return Promise.resolve(transformContent(ctx));
}
@@ -25,6 +25,7 @@ import { useNotesSync } from '../../hooks/useNotesSync';
import { getPopupPosition, getPosition, Position, TextSelection } from '@/utils/sel';
import { eventDispatcher } from '@/utils/event';
import { findTocItemBS } from '@/utils/toc';
import { transformContent } from '@/services/transformService';
import { HIGHLIGHT_COLOR_HEX } from '@/services/constants';
import AnnotationPopup from './AnnotationPopup';
import WiktionaryPopup from './WiktionaryPopup';
@@ -88,25 +89,34 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const isValidSelection = (sel: Selection) => {
return sel && sel.toString().trim().length > 0 && sel.rangeCount > 0;
};
const makeSelection = (sel: Selection, rebuildRange = false) => {
const transformCtx = {
bookKey,
viewSettings: getViewSettings(bookKey)!,
content: '',
transformers: ['punctuation'],
reversePunctuationTransform: true,
};
const makeSelection = async (sel: Selection, rebuildRange = false) => {
isTextSelected.current = true;
const range = sel.getRangeAt(0);
if (rebuildRange) {
sel.removeAllRanges();
sel.addRange(range);
}
setSelection({ key: bookKey, text: sel.toString(), range, index });
transformCtx['content'] = sel.toString();
setSelection({ key: bookKey, text: await transformContent(transformCtx), range, index });
};
// FIXME: extremely hacky way to dismiss system selection tools on iOS
const makeSelectionOnIOS = (sel: Selection) => {
const makeSelectionOnIOS = async (sel: Selection) => {
isTextSelected.current = true;
const range = sel.getRangeAt(0);
setTimeout(() => {
sel.removeAllRanges();
setTimeout(() => {
setTimeout(async () => {
if (!isTextSelected.current) return;
sel.addRange(range);
setSelection({ key: bookKey, text: range.toString(), range, index });
transformCtx['content'] = range.toString();
setSelection({ key: bookKey, text: await transformContent(transformCtx), range, index });
}, 40);
}, 0);
};
@@ -1,9 +1,12 @@
import { activeTransformers } from './transformers';
import { availableTransformers } from './transformers';
import { TransformContext } from './transformers/types';
export const transformContent = async (ctx: TransformContext): Promise<string> => {
let transformed = ctx.content;
const activeTransformers = ctx.transformers
.map((name) => availableTransformers.find((transformer) => transformer.name === name))
.filter((transformer) => !!transformer);
for (const transformer of activeTransformers) {
try {
transformed = await transformer.transform({ ...ctx, content: transformed });
@@ -2,7 +2,7 @@ import type { Transformer } from './types';
import { translateTransformer } from './translate';
import { punctuationTransformer } from './punctuation';
export const activeTransformers: Transformer[] = [
export const availableTransformers: Transformer[] = [
punctuationTransformer,
translateTransformer,
// Add more transformers here
@@ -11,14 +11,16 @@ export const punctuationTransformer: Transformer = {
name: 'punctuation',
transform: async (ctx) => {
if (!ctx.content.includes('<html')) return ctx.content;
const shouldTransform = ctx.viewSettings.vertical === true;
if (!shouldTransform) return ctx.content;
let result = ctx.content;
for (const [original, vertical] of Object.entries(punctuationMap)) {
result = result.replace(new RegExp(original, 'g'), vertical);
if (ctx.reversePunctuationTransform) {
result = result.replace(new RegExp(vertical, 'g'), original);
} else {
result = result.replace(new RegExp(original, 'g'), vertical);
}
}
return result;
@@ -4,6 +4,8 @@ export type TransformContext = {
bookKey: string;
viewSettings: ViewSettings;
content: string;
transformers: string[];
reversePunctuationTransform?: boolean;
};
export type Transformer = {