epubjs-rn icon indicating copy to clipboard operation
epubjs-rn copied to clipboard

Cannot grab text from selected ( highlighted ) area

Open dwidjaja945 opened this issue 7 years ago • 4 comments
trafficstars

I am currently working on a project that requires grabbing text from an epub.

Trying to Achieve:

  1. User highlights word on mobile device via longPress
  2. Highlighted text is grabbed from highlighted region and used elsewhere in application.

Current Attempts:

I have tried the onSelected prop which returns an event that contains the CFI position of the selected area, but I cannot figure out how to pull actual text from the parsed CFI location.

I've seen in a previous issues, onMarkClicked was recommended, but I am unable to trigger it.

Here is my current code:

import React from 'react';
import { StyleSheet, Text, View, TouchableHighlight, Alert , WebView } from "react-native";

import { Epub } from 'epubjs-rn';

const epubCFI = require('./lib/EpubCFI/src/epubcfi');	

export default class App extends React.Component {
	constructor(props) {
		super(props);
	}

	onLongPress = (event) => {
		console.log("epubCFI.prototype.parse(): " , epubCFI.prototype.parse(event));
		console.log("epubCFI.prototype.getRange(): ", epubCFI.prototype.getRange(event));
	}

	selectText = (event, rendition) => {
		console.log('event', event);

		const parsedEvent = epubCFI.prototype.parse(event);
	}

	render() {

		return (
		<Epub onSelected={(event, rendition) => this.selectText(event, rendition)} 
            onLongPress={this.onLongPress.bind(this)} 
            src={"https://s3.amazonaws.com/epubjs/books/moby-dick/OPS/package.opf"}
            flow="scrolled" />
		)
	}
}

Is there a built-in way to grab text from a highlighted area?

If not, is there a way to grab the text from the parsed CFI location?

dwidjaja945 avatar Aug 27 '18 19:08 dwidjaja945

So I have been working on something fairly similar and was able to get this in a very round about way. One of things I am doing is when the book is ready set the state of the book

onReady={(book)=> {
  this.setState({
    title : book.package.metadata.title,
    toc: book.navigation.toc,
    book: book
  });
}}

Then in the onSelected prop i am able to get the text

onSelected={(cfiRange, rendition) => {
  console.log("selected", cfiRange)
  this.state.book.getRange(cfiRange).then(function(range) {
    console.log(`Text: ${range.endContainer.data.substring(range.startOffset, range.endOffset)}`);
  });
  // Add marker
  rendition.highlight(cfiRange, {});
}}

oreillyjw avatar Jan 04 '19 20:01 oreillyjw

Thanks for your answer @oreillyjw . However, I get an error when i call getRange(): No startContainer found for epubcfi(/6/6[fm01]!/4/2/2[title1]/12,/1:0,/1:6) And the value returned for range is null...

Do you have an idea of what's going wrong?

SamiChab avatar Nov 09 '20 15:11 SamiChab

Did you ever figure this out @SamiChab? I'm getting the same error. I'm assuming there's an issue in the epub data itself as it works for some epubs but not for others. I want to import a large library of epubs and it's not feasible to manually check that every one works

jamesalester avatar Jan 04 '21 15:01 jamesalester

@jamesalester sorry but no, I couldn't...

SamiChab avatar Jan 05 '21 12:01 SamiChab