Highlight on markdown text should have an option to open up a popover

I am working on creating a text based annotation tool to help fine tune a LLM model.

The generated answer through ollama is displayed as st.markdown. User should be able to select a sentence on the displayed text and provide a feedback.
To capture the feedback, I need a popover to get trigger once a mousedown and mouseup event is done on a markdown area.

I have tried all the text annotation tools in streamlit community. None of them does something like this.

Below is a representation of what I want to see in the UI.

Can this is be achieved using streamlit?

Hi @Manoj3, welcome to the forum!

I found a component called text_highlighter that seems useful for this GitHub - kevin91nl/text-highlighter: A Streamlit component for annotating text by text selecting.

Here’s some example code that gives behavior similar to what you’re asking for, I think:

import streamlit as st
from text_highlighter import text_highlighter

if "highlight_key" not in st.session_state:
    st.session_state["highlight_key"] = 0

if "feedback" not in st.session_state:
    st.session_state["feedback"] = []


def submit_feedback(text: str, rating: int | None, detailed_feedback: str):
    print(f"Text: `{text}`")
    print(f"Rating: {rating}")
    print(f"Detailed feedback: `{detailed_feedback}`")
    st.session_state["feedback"].append(
        {"text": text, "rating": rating, "detailed_feedback": detailed_feedback}
    )


@st.dialog("Feedback")
def give_feedback():
    text = st.session_state[st.session_state["highlight_key"]][0]["text"]
    st.write("Text: ", text)
    rating = st.feedback()
    detailed_feedback = st.text_area("More detailed feedback")
    if st.button("Submit"):
        submit_feedback(text, rating, detailed_feedback)
        # Change the key to force the selection to be cleared
        st.session_state["highlight_key"] += 1
        st.rerun()
    if st.button("Cancel"):
        st.session_state["highlight_key"] += 1
        st.rerun()


generated_text = "John Doe is the founder of MyComp Inc. and lives in New York with his wife Jane Doe."

result = text_highlighter(
    text=generated_text,
    labels=[("SELECTION", "yellow")],
    key=st.session_state["highlight_key"],
)

with st.expander("Feedback", expanded=True):
    for feedback in st.session_state["feedback"]:
        st.write(feedback)

# Show the results (as a list)
if not result:
    st.stop()

give_feedback()

This pops open a dialog window whenever text is selected, and lets you add feedback, and then when you hit submit, the feedback is added to a list, the popup closes, and the highlighting is undone.

You’ll probably want to tweak this for your own workflow, but I hope this is helpful in at least getting you started.

1 Like

This is awesome. works perfectly fine.

Thanks for taking out time to give an example code as well.

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.