futurepress / epubjs-rn

EpubJS React Native Example
Other
270 stars 151 forks source link

Cannot grab text from selected ( highlighted ) area #97

Open dwidjaja945 opened 6 years ago

dwidjaja945 commented 6 years ago

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?

oreillyjw commented 5 years ago

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, {});
}}
SamiChab commented 3 years ago

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?

jamesalester commented 3 years ago

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

SamiChab commented 3 years ago

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