07-12-2015, 10:25 AM | #1 |
Addict
Posts: 202
Karma: 62362
Join Date: Jul 2015
Device: Sony
|
Regex-Functions - getting user input
Hi,
I am writing a regex-function for the Editor in Callibre that needs to obtain user input. I am new to Python and having searched various websites I found that there seems to be two Python functions for obtaining input from the user: raw_input() and input() However, when used in Callibre Editor these both give the error message: EOFError: EOF when reading a line I assume this is because these two pieces of code are used for the Python command window and do not work in windows. How can I open a window to obtain user input? |
07-13-2015, 12:54 AM | #2 |
Ex-Helpdesk Junkie
Posts: 19,421
Karma: 85397180
Join Date: Nov 2012
Location: The Beaten Path, USA, Roundworld, This Side of Infinity
Device: Kindle Touch fw5.3.7 (Wifi only)
|
I don't think you can access user input from the regex-function mode, as it doesn't spawn a dialog box or other input method.
If you want to get one, I strongly suggest you write a plugin instead. Why do you need to pass user input in a regex? Shouldn't all the information be inside the matched text? (And if it isn't, again that means a plugin is a better scope for whatever you may be trying to do.) |
Advert | |
|
07-13-2015, 03:25 PM | #3 |
Addict
Posts: 202
Karma: 62362
Join Date: Jul 2015
Device: Sony
|
Thanks for your reply.
Sometimes it is not possible to do an automatic search/replace and manual input is required. An example of this is when PDF files are converted to ePufb files and the conversion process inserts full stops before a lower case letter, eg the. dog. With this type of error, sometimes the full stop needs to be removed and sometimes the character after the full stop needs to be capitalised (there are other responses with this example eg 'the U.S.A. receives its fair share of rain' but I will ignore these for now). Ideally, a dialog box would be displayed and the user could press a button to select the required replacement term from a list that is offered. This would be fater than editing matched text every time the unwanted 'phrase' was detected. It is possible to achieve this effect by using a series of message dialog boxes where each replacement 'phrase' is displayed in turn and if the user clicks Yes the matched text is replaced with the appropriate 'phrase' but if No is clicked, another dialog box appears that shows the alternative 'phrase' and the user can click Yes or No to accept/reject this phrase. However, opening a series of dialog boxes is not an ideal solution. As an intial step to producing a dialog box, I thought that, as an exercise, if I produced a text input box (where the user enters a number to select the replacement 'phrase') then I could build on this to produce a more complex dialog box that listed alternatives and the user could click a button to select the required replacement 'phrase' However, if this needs a plugin then I will have to learn how to do this. For anybody who wants to display a dialog box when a regex function runs, the code is shown below. import win32api MB_OK = 0x0 MB_OKCXL = 0x01 MB_YESNOCXL = 0x03 MB_YESNO = 0x04 MB_HELP = 0x4000 ICON_EXCLAIM=0x30 ICON_INFO = 0x40 ICON_STOP = 0x10 MB_SYSTEMMODAL=4096 reply=win32api.MessageBox(None,"Text to display","Caption",MB_YESNOCXL|ICON_EXCLAIM) The variable reply will contain an number that corresponds to the button clicked by the user. If MB_SYSTEMMODAL is OR'd with the MB value then the dialog box opens as a system modal dialog box. The code to open the dialog box must be placed after the statement: def replace(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs): as required by Callibre. |
07-13-2015, 04:49 PM | #4 |
Ex-Helpdesk Junkie
Posts: 19,421
Karma: 85397180
Join Date: Nov 2012
Location: The Beaten Path, USA, Roundworld, This Side of Infinity
Device: Kindle Touch fw5.3.7 (Wifi only)
|
In such cases, most people around here seem to be content to manually edit each match. I don't know how much time you'd save, or how many buttons you'd end up needing to use but as you wish.
I've never tried opening a dialog box from a regex function, it might work. The input() functions OTOH are not meant to be run in a GUI -- like, ever. P.S. calibre already knows about Qt dialog boxes, which don't necessitate using platform-dependent code. You have no need to use APIs. |
07-13-2015, 08:41 PM | #5 |
creator of calibre
Posts: 44,563
Karma: 24495948
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
Since S&R runs in the GUI thread, as you discovered, you can show any GUI you like in your replace function. However, this is accidental and is not really something S&R was designed for, so dont be surprised if it breaks someday.
And as @eschwartz said, you should use Qt dialog boxes, that way your code will work everywhere, something like from PyQt5.Qt import QInputDialog from calibre.gui2.tweak_book.boss import get_boss ok, answer = QInputDialog.getText(get_boss().gui, ...) See the documentation for QInputDialog for the details |
Advert | |
|
07-14-2015, 03:27 PM | #6 |
Addict
Posts: 202
Karma: 62362
Join Date: Jul 2015
Device: Sony
|
Thanks for both your replies.
I will find out about how to use QT - I enjoy coding so it will ne interesting to explore something new. |
09-08-2020, 03:28 PM | #7 |
Enthusiast
Posts: 26
Karma: 38
Join Date: Nov 2019
Location: Paris, France
Device: none
|
I am interested in this topic. I have a complex regex-function which tries to correct a common mistake in French ebooks. This regex claims to reliably correct, say, 95% of cases. The corresponding branches of the regex can be executed automatically. There are, however, cases that are undecidable by regex. These cases can only be resolved by user choice.
As this error is frequent, one could imagine adding, for undecidable cases, a branch to the regex executed automatically. When the regex selects in that branch, and hands over to the function, the function might ask the user to decide what to do. As I am ignorant of Python, I tried to run a little test with a function on the above model: regex : \b([aà])\b fonction : Code:
def replace(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs): from PyQt5.Qt import QInputDialog from calibre.gui2.tweak_book.boss import get_boss if match.group(1): text, ok = QInputDialog().getText(get_boss().gui, "QInputDialog().getText()", "a ou à") if ok and text: return "{}".format(text) return "{}".format(match.group(1)) In automatic mode, when the regex selects something, then the function displays the input window, whatever I click on, the window is displayed again indefinitely. I have to kill ebook-edit. What's wrong ? |
09-09-2020, 01:21 AM | #8 |
creator of calibre
Posts: 44,563
Karma: 24495948
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
Regex functions are not meant for interactive use. Create plugins for that. Or have your regex function simply mark the suspect text by surrounding it with some placeholders like ??? and then use the search feature to manually fix after.
|
09-09-2020, 05:26 AM | #9 |
Enthusiast
Posts: 26
Karma: 38
Join Date: Nov 2019
Location: Paris, France
Device: none
|
Thanks for your answer. I'll do it like this.
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
[Conversion Input] Microsoft Doc Input Plugin | igi | Plugins | 76 | 06-28-2019 05:47 AM |
A new user's collection of Regular Expressions (regex) for 'Add books > Control the a | kite | Library Management | 2 | 11-04-2015 07:51 AM |
Help - Learning to use Regex Functions | weberr | Editor | 1 | 06-13-2015 02:59 AM |
Shell script to wait for user input from K3g keyboard | jmseight | Kindle Developer's Corner | 33 | 04-01-2012 05:32 PM |
epub to epub conversion problem with regex spanning multiple input files | ctop | Conversion | 2 | 02-12-2012 02:56 AM |