0

I want iterate over a list of string, output the string as plain text in jupyter lab then interactively highlight a substring to get easily the start index of the substring and the length. The goal is to do a quick annotation of text and get the coordinates of the substring.

Is it easy or even possible to do something like this with jupyter notebook (lab)? If then How?

I had a look at ipywidgets but couldn't find something for this use case.

cookiemonster
  • 1,315
  • 12
  • 19
  • 1
    I'm not sure how you would do text selection by highlighting on screen, but how about a IntRangeSlider to slide backwards and forwards for the start and endpoints of the substring? https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html#IntRangeSlider – ac24 Sep 23 '19 at 15:06
  • that's a nice idea as a workaround @ac24 thank you! I'm still hoping there's a way to do highlighting as the text to select from is rather big – cookiemonster Sep 23 '19 at 15:14

2 Answers2

1

Here's an example with the RangeSlider:

import ipywidgets
input_string = 'averylongstring'
widg = ipywidgets.IntRangeSlider(
    value = [0, len(input_string)],
    min=0, max=len(input_string)
)
output_widg = ipywidgets.Text()

display(widg)
display(output_widg)

def chomp_string(widg):

    start,end = tuple(widg['new'])
    output_widg.value = input_string[start: end]

widg.observe(chomp_string, names='value')
ac24
  • 5,325
  • 1
  • 16
  • 31
1

You can implement this using jp_proxy_widgets. See the following screenshot: enter image description here Note that there are warnings about compatibility for selection protocols -- I only tested this on Chrome on a Mac. Also I don't know why the indices are off by one (select_callback(startOffset+1, endOffset+1);)

Please see https://github.com/AaronWatters/jp_proxy_widget for more information

Edit: Here is the pastable text as requested:

import jp_proxy_widget

select_widget = jp_proxy_widget.JSProxyWidget()

txt = """
Never gonna give you up.
Never gonna let you down.
Never gonna run around and
desert you.
"""

selected_text = None

def select_callback(startOffset, endOffset):
    global selected_text
    selected_text = txt[startOffset: endOffset]
    print ("Selected", startOffset, endOffset, repr(selected_text))

select_widget.js_init("""

// (Javascript) Add a text area.
element.empty()
$("<h3>please select text:</h3>").appendTo(element);
var textarea = $('<textarea cols="50" rows="5">' + txt + "</textarea>").appendTo(element);

// Attach a select handler that calls back to select_callback.
var select_handler = function(event) {;
    var target = event.target;
    var startOffset = target.selectionStart;
    var endOffset = target.selectionEnd;
    select_callback(startOffset+1, endOffset+1);
};
textarea[0].addEventListener('select', select_handler);
""", txt=txt, select_callback=select_callback)

# display the widget
select_widget.debugging_display()
Aaron Watters
  • 2,784
  • 3
  • 23
  • 37