Hakyung Sung commited on
Commit
127d151
·
1 Parent(s): fd84879

Correct app.py

Browse files
Files changed (1) hide show
  1. app.py +188 -71
app.py CHANGED
@@ -13,54 +13,202 @@ nlp = spacy.load(os.path.join(model_path, 'model-best'))
13
  if 'parser' not in nlp.pipe_names and 'senter' not in nlp.pipe_names:
14
  nlp.add_pipe('sentencizer')
15
 
16
- # Define the inline color mapping for each ASC tag.
17
- color_scheme = {
18
- "ATTR": "#f6e9e9", # Light Red
19
- "INTRAN_S": "#e7957f", # Light Blue
20
- "INTRAN_MOT": "#f6f6aa", # Light Green
21
- "INTRAN_RES": "#f0aed6", # Light Yellow
22
- "CAUS_MOT": "#cdefb5", # Light Pink
23
- "TRAN_S": "#a0d4f7", # Light Blue
24
- "TRAN_RES": "#c7aefa", # Light Purple
25
- "DITRAN": "#b3f0f7", # Light Teal
26
- "PASSIVE": "#c3c0c0" # Light Gray
27
- }
28
-
29
  def get_highlighted_text(doc):
30
  """
31
- Wraps detected ASCs in each sentence with a span tag containing an inline style.
32
- In addition, appends the entity's tag name in an extra span so the label is always visible.
33
  """
34
  highlighted_sentences = []
35
  for sent in doc.sents:
36
- s = sent.text
37
- # Find all entities fully contained within this sentence.
38
  ents_in_sent = [ent for ent in doc.ents if ent.start_char >= sent.start_char and ent.end_char <= sent.end_char]
39
  if ents_in_sent:
40
- # Process entities in reverse order so the character offsets remain valid.
41
  ents_in_sent = sorted(ents_in_sent, key=lambda x: x.start_char, reverse=True)
42
  for ent in ents_in_sent:
43
  ent_start = ent.start_char - sent.start_char
44
  ent_end = ent.end_char - sent.start_char
45
- # Get the color based on the tag; default to light gray if not found.
46
- color = color_scheme.get(ent.label_, "#cccccc")
47
- # Wrap the entity text with an inline style and add the tag label in a separate span.
48
- s = (
49
- s[:ent_start]
50
- + f'<span style="background-color: {color}; font-weight: bold;" title="{ent.label_}">'
51
- + s[ent_start:ent_end]
52
- + f'<span style="display:inline-block; vertical-align: super; font-size: 0.8em; margin-left: 2px; color: black;">{ent.label_}</span>'
53
  + '</span>'
54
- + s[ent_end:]
55
  )
56
- highlighted_sentences.append(s)
57
- # Combine sentences with HTML breaks.
58
- return "<br><br>".join(highlighted_sentences)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
  def process_text(input_text):
61
  """
62
  Process input text to detect and tag ASCs.
63
- Returns an HTML string with inline styles applied to each entity.
64
  """
65
  if not input_text.strip():
66
  return "No text provided. Please enter some text."
@@ -75,55 +223,24 @@ def process_text(input_text):
75
 
76
  return get_highlighted_text(doc)
77
 
78
- # Define the sample text to be injected.
79
- sample_text = (
80
- "Once upon a time in a small, enchanted village nestled between towering mountains, there lived a baker named Oliver. "
81
- "But this wasn't just any baker—Oliver had a magical secret. Every loaf of bread he baked had the power to grant a wish, "
82
- "but only if it was made with true joy in his heart. The villagers adored Oliver’s bread, though they had no idea about its magic. "
83
- "They just knew it tasted unlike anything else—warm, soft, and with a hint of something... extraordinary. Only a few people had ever discovered "
84
- "its secret, and even fewer had made wishes, because the key was in asking for something truly selfless. "
85
- "One crisp autumn morning, a traveling musician named Lyla passed through the village. She had a worn-out lute, tattered clothes, "
86
- "and a bright spark of hope in her eyes despite her hardships. Drawn by the smell of freshly baked bread, she wandered into Oliver’s bakery. "
87
- "Oliver, busy dusting flour off his hands, smiled warmly. “What can I do for you?” he asked. "
88
- "Lyla’s stomach growled in response, and she laughed, a sound as melodic as her lute playing. “Just one loaf of bread, please,” she said, "
89
- "placing a single coin on the counter, all she had left. "
90
- "Oliver, feeling the joy in the simple act of serving someone in need, baked the loaf with care. As the bread came out of the oven, a golden glow "
91
- "shimmered around it for just a moment. Lyla didn’t notice, but Oliver did, and he smiled to himself. "
92
- "As Lyla took her first bite outside the shop, she felt warmth spread through her whole being. She thought of how she missed playing her lute to "
93
- "cheer others up, but it was broken and beyond repair. Without knowing the magic at work, she whispered under her breath, 'I just wish I could bring "
94
- "music to everyone again.' "
95
- "That evening, as Lyla set up by the village fountain to play, something miraculous happened. Her old, broken lute began to transform, glowing just "
96
- "like the bread had. In her hands now was the most beautiful lute she had ever seen, shimmering with gold and silver strings. When she strummed it, "
97
- "the music that flowed out wasn’t just sound—it was pure joy. "
98
- "The village gathered around her, drawn by the enchanting melodies that seemed to fill their hearts with warmth and happiness. People laughed, danced, "
99
- "and even sang along, forgetting their worries. "
100
- "Oliver watched from his bakery window, smiling to himself. He had no idea what Lyla had wished for, but he could see its magic at work. He knew his "
101
- "bread had once again brought a little bit of magic to the world. "
102
- "And so, every day after that, Lyla would play her magical lute in the village square, bringing joy to everyone who heard her music. People came from "
103
- "distant lands just to hear her play, and with every note, the village grew a little brighter, a little happier. "
104
- "As for Oliver, he continued to bake with joy in his heart, knowing that sometimes the smallest acts of kindness—like baking a loaf of bread—could "
105
- "make the biggest difference in someone’s life. "
106
- "And so, the village became known not just for its delicious bread, but for its music, magic, and the happiness that lingered in every corner. "
107
- "(Generated by ChatGPT 4o 🤖)"
108
- )
109
 
110
- def fill_sample_text():
111
- return sample_text
112
 
113
  # Build the Gradio interface.
114
  with gr.Blocks() as demo:
115
  gr.Markdown("# ASC tagger demo")
116
- gr.Markdown("Enter some text to have ASCs tagged with a custom inline color scheme. Use the button below to fill in sample text.")
117
 
118
- input_textbox = gr.Textbox(lines=10, label="Input Text", placeholder="Enter text here...")
119
  output_html = gr.HTML(label="Tagged Text")
120
- tag_btn = gr.Button("Tag ASCs")
121
  fill_btn = gr.Button("Fill Sample Text")
122
-
123
- tag_btn.click(fn=process_text, inputs=input_textbox, outputs=output_html)
124
- # When "Fill Sample Text" is clicked, populate the textbox.
125
  fill_btn.click(fn=fill_sample_text, inputs=[], outputs=input_textbox)
126
- # When "Tag ASCs" is clicked, process the input text.
127
 
128
  if __name__ == "__main__":
129
  demo.launch()
 
13
  if 'parser' not in nlp.pipe_names and 'senter' not in nlp.pipe_names:
14
  nlp.add_pipe('sentencizer')
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  def get_highlighted_text(doc):
17
  """
18
+ Wraps detected ASCs in each sentence with a <span> tag that carries the entity tag as a
19
+ data attribute. The output HTML is wrapped with a CSS <style> block that applies your desired styling.
20
  """
21
  highlighted_sentences = []
22
  for sent in doc.sents:
23
+ text = sent.text
24
+ # Find all entities that are fully contained within this sentence.
25
  ents_in_sent = [ent for ent in doc.ents if ent.start_char >= sent.start_char and ent.end_char <= sent.end_char]
26
  if ents_in_sent:
27
+ # Process entities in reverse order so that character offsets remain valid.
28
  ents_in_sent = sorted(ents_in_sent, key=lambda x: x.start_char, reverse=True)
29
  for ent in ents_in_sent:
30
  ent_start = ent.start_char - sent.start_char
31
  ent_end = ent.end_char - sent.start_char
32
+ # Wrap the detected entity with a span and include its tag via the data-entity attribute.
33
+ text = (
34
+ text[:ent_start]
35
+ + f'<span class="entity" data-entity="{ent.label_}">'
36
+ + text[ent_start:ent_end]
 
 
 
37
  + '</span>'
38
+ + text[ent_end:]
39
  )
40
+ highlighted_sentences.append(text)
41
+ result = "<br><br>".join(highlighted_sentences)
42
+
43
+ # Embed the provided CSS for styling.
44
+ style = """
45
+ <style>
46
+ body {
47
+ font-family: Arial, sans-serif;
48
+ margin: 0;
49
+ padding: 20px;
50
+ background-color: #f4f4f4;
51
+ }
52
+ .container {
53
+ max-width: 800px;
54
+ margin: 0 auto;
55
+ padding: 20px;
56
+ background-color: white;
57
+ border-radius: 8px;
58
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
59
+ }
60
+ h1 {
61
+ font-size: 2rem;
62
+ font-weight: 700;
63
+ margin-bottom: 20px;
64
+ text-align: center;
65
+ }
66
+ p, textarea, input {
67
+ font-size: 0.9rem;
68
+ font-weight: 400;
69
+ }
70
+ .info {
71
+ font-size: 0.9rem;
72
+ color: #333;
73
+ }
74
+ .accuracy-highlight {
75
+ color: #007030;
76
+ font-weight: bold;
77
+ }
78
+ input[type="submit"], input[type="button"] {
79
+ font-size: 0.9rem;
80
+ }
81
+ textarea {
82
+ width: 95%;
83
+ max-width: 95%; /* Ensure textarea doesn't exceed the container */
84
+ padding: 20px;
85
+ margin-bottom: 10px;
86
+ border: 1px solid #ccc;
87
+ border-radius: 4px;
88
+ resize: vertical; /* Allow vertical resizing */
89
+ }
90
+ input[type="submit"], input[type="button"] {
91
+ background-color: #007030;
92
+ color: white;
93
+ padding: 10px 20px;
94
+ border: none;
95
+ border-radius: 4px;
96
+ cursor: pointer;
97
+ margin-right: 10px; /* Add some space between buttons */
98
+ }
99
+ input[type="submit"]:hover, input[type="button"]:hover {
100
+ background-color: #45a049;
101
+ }
102
+ .results {
103
+ margin-top: 20px;
104
+ line-height: 2.5;
105
+ }
106
+ .tag-counts {
107
+ margin-top: 2px;
108
+ text-align: center;
109
+ }
110
+ .tag-counts h2 {
111
+ margin-bottom: 5px;
112
+ text-align: left;
113
+ }
114
+ .entity {
115
+ display: inline-block;
116
+ border: none;
117
+ border-radius: 2px;
118
+ padding: 2px 5px;
119
+ margin: 0 4px;
120
+ position: relative;
121
+ white-space: nowrap;
122
+ line-height: 1.2;
123
+ font-size: 0.8em;
124
+ }
125
+ /* Highlight background colors for entity types */
126
+ .entity[data-entity="ATTR"] {
127
+ background-color: #f6e9e9; /* Light Red */
128
+ }
129
+ .entity[data-entity="INTRAN_S"] {
130
+ background-color: #e7957f; /* Light Blue */
131
+ }
132
+ .entity[data-entity="INTRAN_MOT"] {
133
+ background-color: #f6f6aa; /* Light Green */
134
+ }
135
+ .entity[data-entity="INTRAN_RES"] {
136
+ background-color: #f0aed6; /* Light Yellow */
137
+ }
138
+ .entity[data-entity="CAUS_MOT"] {
139
+ background-color: #cdefb5; /* Light Pink */
140
+ }
141
+ .entity[data-entity="TRAN_S"] {
142
+ background-color: #a0d4f7; /* Light Blue */
143
+ }
144
+ .entity[data-entity="TRAN_RES"] {
145
+ background-color: #c7aefa; /* Light Purple */
146
+ }
147
+ .entity[data-entity="DITRAN"] {
148
+ background-color: #b3f0f7; /* Light Teal */
149
+ }
150
+ .entity[data-entity="PASSIVE"] {
151
+ background-color: #c3c0c0; /* Light Gray */
152
+ }
153
+ /* Default style if the entity type is not specified */
154
+ .entity[data-entity=""] {
155
+ background-color: #cccccc; /* Light Gray */
156
+ }
157
+ /* Darker background colors for the entity label tooltips */
158
+ .entity[data-entity="ATTR"]::after {
159
+ background-color: #d29997; /* Darker Red */
160
+ }
161
+ .entity[data-entity="INTRAN_S"]::after {
162
+ background-color: #ec6161; /* Darker Orange */
163
+ }
164
+ .entity[data-entity="INTRAN_MOT"]::after {
165
+ background-color: #ebab22; /* Darker Green */
166
+ }
167
+ .entity[data-entity="INTRAN_RES"]::after {
168
+ background-color: #be5791; /* Darker Purple */
169
+ }
170
+ .entity[data-entity="CAUS_MOT"]::after {
171
+ background-color: #007030; /* Darker Green */
172
+ }
173
+ .entity[data-entity="TRAN_S"]::after {
174
+ background-color: #3085ce; /* Darker Blue */
175
+ }
176
+ .entity[data-entity="TRAN_RES"]::after {
177
+ background-color: #8268cf; /* Darker Purple */
178
+ }
179
+ .entity[data-entity="DITRAN"]::after {
180
+ background-color: #449cbb; /* Darker Teal */
181
+ }
182
+ .entity[data-entity="PASSIVE"]::after {
183
+ background-color: #6b6b6b; /* Darker Gray */
184
+ }
185
+ /* Default darker tooltip if the entity type is not specified */
186
+ .entity[data-entity=""]::after {
187
+ background-color: #888888; /* Darker Gray */
188
+ }
189
+ /* Styling for the entity label tooltip */
190
+ .entity::after {
191
+ content: attr(data-entity);
192
+ position: absolute;
193
+ bottom: -2em;
194
+ left: 0;
195
+ right: 0;
196
+ color: #fff; /* White text */
197
+ font-size: 0.7em;
198
+ padding: 2px 4px;
199
+ border-radius: 2px;
200
+ text-align: center;
201
+ min-width: 50px;
202
+ white-space: nowrap;
203
+ }
204
+ </style>
205
+ """
206
+ return style + "<div class='container'>" + result + "</div>"
207
 
208
  def process_text(input_text):
209
  """
210
  Process input text to detect and tag ASCs.
211
+ Returns an HTML string with styles applied.
212
  """
213
  if not input_text.strip():
214
  return "No text provided. Please enter some text."
 
223
 
224
  return get_highlighted_text(doc)
225
 
226
+ # Define sample text
227
+ sample_text = "Nancy sliced the tire open."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
 
229
+ #def fill_sample_text():
230
+ # return sample_text
231
 
232
  # Build the Gradio interface.
233
  with gr.Blocks() as demo:
234
  gr.Markdown("# ASC tagger demo")
235
+ gr.Markdown("This demo version of the Argument Structure Construction (ASC) tagger processes sentences and identifies nine types of ASCs. The identified ASCs are highlighted in the output text.")
236
 
237
+ input_textbox = gr.Textbox(lines=5, label="Input Text", placeholder="Enter text here...")
238
  output_html = gr.HTML(label="Tagged Text")
 
239
  fill_btn = gr.Button("Fill Sample Text")
240
+ tag_btn = gr.Button("Tag ASCs")
241
+
 
242
  fill_btn.click(fn=fill_sample_text, inputs=[], outputs=input_textbox)
243
+ tag_btn.click(fn=process_text, inputs=input_textbox, outputs=output_html)
244
 
245
  if __name__ == "__main__":
246
  demo.launch()