diyclassics Claude Opus 4.6 commited on
Commit
1ca5171
·
1 Parent(s): 1c6a626

Update demo texts and fix morph word selector persistence

Browse files

- Senter: swap to Sallust BC 5 (avoids pl. abbreviation bug)
- NER: use paper sentence (Iason et Medea)
- Dependency: use Ritchie's Fabulae Faciles (simple Latin)
- Morphology: use Seneca Ep. 1.3, fix session_state so word
selector persists across reruns

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

pages/3_senter_demo.py CHANGED
@@ -19,7 +19,7 @@ st.title("Latin Sentence Segmenter")
19
  # Input text area
20
  text = st.text_area(
21
  "Enter a paragraph of Latin text to segment into sentences:",
22
- value="Decrevit quondam senatus, ut L. Opimius consul videret, ne quid res publica detrimenti caperet; nox nulla intercessit; interfectus est propter quasdam seditionum suspiciones C. Gracchus, clarissimo patre, avo, maioribus, occisus est cum liberis M. Fulvius consularis. Simili senatus consulto C. Mario et L. Valerio consulibus est permissa res publica; num unum diem postea L. Saturninum tribunum pl. et C. Servilium praetorem mors ac rei publicae poena remorata est? At [vero] nos vicesimum iam diem patimur hebescere aciem horum auctoritatis. Habemus enim huiusce modi senatus consultum, verum inclusum in tabulis tamquam in vagina reconditum, quo ex senatus consulto confestim te interfectum esse, Catilina, convenit. Vivis, et vivis non ad deponendam, sed ad confirmandam audaciam. Cupio, patres conscripti, me esse clementem, cupio in tantis rei publicae periculis me non dissolutum videri, sed iam me ipse inertiae nequitiaeque condemno.",
23
  height=200,
24
  )
25
 
 
19
  # Input text area
20
  text = st.text_area(
21
  "Enter a paragraph of Latin text to segment into sentences:",
22
+ value="Lucius Catilina, nobili genere natus, fuit magna vi et animi et corporis, sed ingenio malo pravoque. Huic ab adulescentia bella intestina, caedes, rapinae, discordia civilis grata fuere ibique iuventutem suam exercuit. Corpus patiens inediae, algoris, vigiliae supra quam cuiquam credibile est. Animus audax, subdolus, varius, cuius rei lubet simulator ac dissimulator, alieni adpetens, sui profusus, ardens in cupiditatibus; satis eloquentiae, sapientiae parum. Vastus animus inmoderata, incredibilia, nimis alta semper cupiebat.",
23
  height=200,
24
  )
25
 
pages/4_ner_demo.py CHANGED
@@ -5,7 +5,7 @@ from spacy_streamlit import visualize_ner
5
  st.set_page_config(page_title="NER Demo", layout="wide")
6
  st.sidebar.header("NER Demo")
7
 
8
- default_text = """Gallia est omnis divisa in partes tres, quarum unam incolunt Belgae, aliam Aquitani, tertiam qui ipsorum lingua Celtae, nostra Galli appellantur. Hi omnes lingua, institutis, legibus inter se differunt. Gallos ab Aquitanis Garumna flumen, a Belgis Matrona et Sequana dividit."""
9
 
10
  st.title("Latin Named Entity Recognition")
11
 
 
5
  st.set_page_config(page_title="NER Demo", layout="wide")
6
  st.sidebar.header("NER Demo")
7
 
8
+ default_text = """Iason et Medea e Thessalia expulsi ad urbem Corinthum venerunt, cuius urbis Creon quidam regnum tum obtinebat."""
9
 
10
  st.title("Latin Named Entity Recognition")
11
 
pages/5_dependency_demo.py CHANGED
@@ -5,7 +5,7 @@ from spacy_streamlit import visualize_parser
5
  st.set_page_config(page_title="Dependency Demo", layout="wide")
6
  st.sidebar.header("Dependency Demo")
7
 
8
- default_text = """Quo usque tandem abutere, Catilina, patientia nostra? Quam diu etiam furor iste tuus nos eludet? Quem ad finem sese effrenata iactabit audacia?"""
9
 
10
  st.title("Latin Dependency Tree Visualizer")
11
 
 
5
  st.set_page_config(page_title="Dependency Demo", layout="wide")
6
  st.sidebar.header("Dependency Demo")
7
 
8
+ default_text = """Haec narrantur a poetis de Perseo. Perseus filius erat Iovis, maximi deorum; avus eius Acrisius appellabatur."""
9
 
10
  st.title("Latin Dependency Tree Visualizer")
11
 
pages/7_morphology_demo.py CHANGED
@@ -5,7 +5,7 @@ import pandas as pd
5
  st.set_page_config(page_title="Morphology Demo", layout="wide")
6
  st.sidebar.header("Morphology Demo")
7
 
8
- default_text = """Arma virumque cano, Troiae qui primus ab oris Italiam, fato profugus, Laviniaque venit litora."""
9
 
10
  # Human-readable labels for morphological feature values.
11
  # Keyed by (Feature, Value) to disambiguate collisions like
@@ -148,6 +148,7 @@ if st.button("Analyze Morphology"):
148
  doc = nlp(text)
149
 
150
  rows = []
 
151
  for token in doc:
152
  if token.is_punct or token.is_space:
153
  continue
@@ -159,6 +160,22 @@ if st.button("Analyze Morphology"):
159
  "Features": format_morph_readable(token.morph),
160
  }
161
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
  df = pd.DataFrame(rows)
164
  st.dataframe(df, use_container_width=True, hide_index=True)
@@ -166,26 +183,24 @@ if st.button("Analyze Morphology"):
166
  st.markdown("---")
167
  st.markdown("**Select a word for detailed analysis:**")
168
 
169
- # Build options with index to disambiguate duplicate tokens
170
- content_tokens = [t for t in doc if not t.is_punct and not t.is_space]
171
- word_options = [f"{t.text} ({i + 1})" for i, t in enumerate(content_tokens)]
172
  selected_idx = st.selectbox(
173
  "Word:", range(len(word_options)), format_func=lambda i: word_options[i],
174
  key="morph_word",
175
  )
176
 
177
  if selected_idx is not None:
178
- token = content_tokens[selected_idx]
179
  col1, col2 = st.columns(2)
180
  with col1:
181
- st.markdown(f"### {token.text}")
182
- st.markdown(f"**Lemma:** {token.lemma_}")
183
  st.markdown(
184
- f"**Part of Speech:** {POS_LABELS.get(token.pos_, token.pos_)}"
185
  )
186
- st.markdown(f"**Fine-grained Tag:** {token.tag_}")
187
  with col2:
188
- morph_dict = token.morph.to_dict()
189
  if morph_dict:
190
  st.markdown("**Morphological Features:**")
191
  for feat, val in morph_dict.items():
 
5
  st.set_page_config(page_title="Morphology Demo", layout="wide")
6
  st.sidebar.header("Morphology Demo")
7
 
8
+ default_text = """Quaedam tempora eripiuntur nobis, quaedam subducuntur, quaedam effluunt."""
9
 
10
  # Human-readable labels for morphological feature values.
11
  # Keyed by (Feature, Value) to disambiguate collisions like
 
148
  doc = nlp(text)
149
 
150
  rows = []
151
+ token_data = []
152
  for token in doc:
153
  if token.is_punct or token.is_space:
154
  continue
 
160
  "Features": format_morph_readable(token.morph),
161
  }
162
  )
163
+ token_data.append(
164
+ {
165
+ "text": token.text,
166
+ "lemma": token.lemma_,
167
+ "pos": token.pos_,
168
+ "tag": token.tag_,
169
+ "morph": token.morph.to_dict(),
170
+ }
171
+ )
172
+
173
+ st.session_state["morph_rows"] = rows
174
+ st.session_state["morph_tokens"] = token_data
175
+
176
+ if "morph_rows" in st.session_state:
177
+ rows = st.session_state["morph_rows"]
178
+ token_data = st.session_state["morph_tokens"]
179
 
180
  df = pd.DataFrame(rows)
181
  st.dataframe(df, use_container_width=True, hide_index=True)
 
183
  st.markdown("---")
184
  st.markdown("**Select a word for detailed analysis:**")
185
 
186
+ word_options = [f"{t['text']} ({i + 1})" for i, t in enumerate(token_data)]
 
 
187
  selected_idx = st.selectbox(
188
  "Word:", range(len(word_options)), format_func=lambda i: word_options[i],
189
  key="morph_word",
190
  )
191
 
192
  if selected_idx is not None:
193
+ t = token_data[selected_idx]
194
  col1, col2 = st.columns(2)
195
  with col1:
196
+ st.markdown(f"### {t['text']}")
197
+ st.markdown(f"**Lemma:** {t['lemma']}")
198
  st.markdown(
199
+ f"**Part of Speech:** {POS_LABELS.get(t['pos'], t['pos'])}"
200
  )
201
+ st.markdown(f"**Fine-grained Tag:** {t['tag']}")
202
  with col2:
203
+ morph_dict = t["morph"]
204
  if morph_dict:
205
  st.markdown("**Morphological Features:**")
206
  for feat, val in morph_dict.items():