Better nlp + refactors

This commit is contained in:
Richard Roberson 2025-02-11 00:12:31 -07:00
parent 4320730834
commit 297396579b
5 changed files with 45 additions and 38 deletions

View file

@ -27,9 +27,10 @@ export function EPUBViewer({ className = '' }: EPUBViewerProps) {
const rendition = useRef<Rendition | undefined>(undefined);
const toc = useRef<NavItem[]>([]);
const locationRef = useRef<string | number>(currDocPage);
const handleLocationChanged = useCallback((location: string | number, initial = false) => {
// Handle special 'next' and 'prev' cases
// Handle special 'next' and 'prev' cases, which
if (location === 'next' && rendition.current) {
rendition.current.next();
return;

View file

@ -84,9 +84,7 @@ export function EPUBProvider({ children }: { children: ReactNode }) {
* Extracts text content from the current EPUB page/location
*/
const extractPageText = useCallback(async (book: Book, rendition: Rendition): Promise<string> => {
try {
console.log('Extracting EPUB text from current location');
try {
const { start, end } = rendition.location;
if (!start?.cfi || !end?.cfi) return '';

View file

@ -102,7 +102,7 @@ export function TTSProvider({ children }: { children: React.ReactNode }) {
// Use custom hooks
const audioContext = useAudioContext();
const audioCache = useAudioCache(50);
const audioCache = useAudioCache(25);
const { availableVoices, fetchVoices } = useVoiceManagement(openApiKey, openApiBaseUrl);
// Add ref for location change handler
@ -120,22 +120,21 @@ export function TTSProvider({ children }: { children: React.ReactNode }) {
* State Management
*/
const [isPlaying, setIsPlaying] = useState(false);
const [isEPUB, setIsEPUB] = useState(false);
const [isProcessing, setIsProcessing] = useState(false);
const [currDocPage, setCurrDocPage] = useState<string | number>(1);
const currDocPageNumber = (!isEPUB ? parseInt(currDocPage.toString()) : 1); // PDF uses numbers only
const [currDocPages, setCurrDocPages] = useState<number>();
const [sentences, setSentences] = useState<string[]>([]);
const [currentIndex, setCurrentIndex] = useState(0);
const [activeHowl, setActiveHowl] = useState<Howl | null>(null);
const [isProcessing, setIsProcessing] = useState(false);
const [speed, setSpeed] = useState(voiceSpeed);
const [voice, setVoice] = useState(configVoice);
const [currDocPage, setCurrDocPage] = useState<string | number>(1);
const [currDocPages, setCurrDocPages] = useState<number>();
const [nextPageLoading, setNextPageLoading] = useState(false);
// Add this state to track if we're in EPUB mode
const [isEPUB, setIsEPUB] = useState(false);
const currDocPageNumber = (!isEPUB ? parseInt(currDocPage.toString()) : 1);
console.log('page:', currDocPage, 'pages:', currDocPages);
//console.log('page:', currDocPage, 'pages:', currDocPages);
/**
* Changes the current page by a specified amount

View file

@ -15,35 +15,42 @@ export const preprocessSentenceForAudio = (text: string): string => {
.trim();
};
const MAX_BLOCK_LENGTH = 250; // Maximum characters per block
const MAX_BLOCK_LENGTH = 300; // Maximum characters per block
export const splitIntoSentences = (text: string): string[] => {
// Preprocess the text before splitting into sentences
const cleanedText = preprocessSentenceForAudio(text);
const doc = nlp(cleanedText);
const rawSentences = doc.sentences().out('array') as string[];
// Split text into paragraphs first
const paragraphs = text.split(/\n+/);
const blocks: string[] = [];
let currentBlock = '';
for (const sentence of rawSentences) {
const trimmedSentence = sentence.trim();
for (const paragraph of paragraphs) {
if (!paragraph.trim()) continue;
// Preprocess each paragraph
const cleanedText = preprocessSentenceForAudio(paragraph);
const doc = nlp(cleanedText);
const rawSentences = doc.sentences().out('array') as string[];
// If adding this sentence would exceed the limit, start a new block
if (currentBlock && (currentBlock.length + trimmedSentence.length + 1) > MAX_BLOCK_LENGTH) {
blocks.push(currentBlock.trim());
currentBlock = trimmedSentence;
} else {
// Add to current block with a space if not empty
currentBlock = currentBlock
? `${currentBlock} ${trimmedSentence}`
: trimmedSentence;
}
}
let currentBlock = '';
// Add the last block if not empty
if (currentBlock) {
blocks.push(currentBlock.trim());
for (const sentence of rawSentences) {
const trimmedSentence = sentence.trim();
// If adding this sentence would exceed the limit, start a new block
if (currentBlock && (currentBlock.length + trimmedSentence.length + 1) > MAX_BLOCK_LENGTH) {
blocks.push(currentBlock.trim());
currentBlock = trimmedSentence;
} else {
// Add to current block with a space if not empty
currentBlock = currentBlock
? `${currentBlock} ${trimmedSentence}`
: trimmedSentence;
}
}
// Add the last block if not empty
if (currentBlock) {
blocks.push(currentBlock.trim());
}
}
return blocks;

View file

@ -116,10 +116,12 @@ export function findBestTextMatch(
lengthDiff: Infinity,
};
const SPAN_SEARCH_LIMIT = 10;
for (let i = 0; i < elements.length; i++) {
let combinedText = '';
const currentElements = [];
for (let j = i; j < Math.min(i + 10, elements.length); j++) {
for (let j = i; j < Math.min(i + SPAN_SEARCH_LIMIT, elements.length); j++) {
const node = elements[j];
const newText = combinedText ? `${combinedText} ${node.text}` : node.text;
if (newText.length > maxCombinedLength) break;