mirror of
https://github.com/kennethreitz/rhymepad.org.git
synced 2026-06-11 17:08:33 +00:00
Split the word entry into Explore and Wordplay lenses
Two sub-tabs under the lookup input: Explore (associations, describes, synonyms — the meaning side) and Wordplay (rhymes, near, multis — the sound side). Readout and history shared; switching repaints from the cached entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+43
-27
@@ -310,6 +310,10 @@ Double-click any word to look it up on the right."></textarea>
|
||||
<div class="lookup-row">
|
||||
<input id="lookupInput" placeholder="look up a word…" autocomplete="off">
|
||||
</div>
|
||||
<div class="seg" id="subSeg">
|
||||
<button class="active" data-sub="explore">Explore</button>
|
||||
<button data-sub="wordplay">Wordplay</button>
|
||||
</div>
|
||||
<div id="histBar"></div>
|
||||
<div id="defBox"></div>
|
||||
<div id="lookupResults">
|
||||
@@ -740,6 +744,14 @@ const resultsBox = document.getElementById('lookupResults');
|
||||
const histBar = document.getElementById('histBar');
|
||||
const defBox = document.getElementById('defBox');
|
||||
let curWord = null, lookupSeq = 0, entry = null;
|
||||
let subMode = 'explore';
|
||||
const subSeg = document.getElementById('subSeg');
|
||||
subSeg.addEventListener('click', e=>{
|
||||
const b = e.target.closest('button'); if(!b) return;
|
||||
subMode = b.dataset.sub;
|
||||
[...subSeg.children].forEach(c=>c.classList.toggle('active', c.dataset.sub === subMode));
|
||||
paintSections();
|
||||
});
|
||||
const wordHistory = [];
|
||||
|
||||
lookupInput.addEventListener('focus', ()=> lookupInput.select());
|
||||
@@ -840,34 +852,38 @@ function paintSections(){
|
||||
const e = entry;
|
||||
if(!e) return;
|
||||
let h = '';
|
||||
if(e.trig && e.trig.length){
|
||||
// what the word summons — the theme-building lens
|
||||
h += `<div class="res-label">associations</div>` + chipHtml(e.trig.map(d=>d.word));
|
||||
if(subMode === 'explore'){
|
||||
// the meaning side: what it summons, what describes it, what replaces it
|
||||
if(e.trig && e.trig.length){
|
||||
h += `<div class="res-label">associations</div>` + chipHtml(e.trig.map(d=>d.word));
|
||||
}
|
||||
if(e.desc && e.desc.length){
|
||||
h += `<div class="res-label">describes</div>` + chipHtml(e.desc.map(d=>d.word));
|
||||
}
|
||||
if(e.syn && e.syn.known && e.syn.sections.length){
|
||||
h += `<div class="res-label">synonyms</div>`;
|
||||
e.syn.sections.forEach(s=>{
|
||||
if(s.label !== 'synonyms') h += `<div class="res-label sub">${esc(s.label)}</div>`;
|
||||
h += chipHtml(s.words.map(d=>d.word), s.label === 'synonyms' ? '' : 'near');
|
||||
});
|
||||
}
|
||||
}else{
|
||||
// the sound side: rhymes, near, multis
|
||||
if(e.rhyme && e.rhyme.known && (e.rhyme.words.length || (e.rhyme.near || []).length)){
|
||||
const bySyl = {};
|
||||
e.rhyme.words.forEach(d=>{ (bySyl[d.syl || 0] ||= []).push(d); });
|
||||
const onWord = e.rhyme.rhyme_on ? ` — on “${esc(e.rhyme.rhyme_on)}”` : '';
|
||||
h += `<div class="res-label">rhymes${onWord}</div>`;
|
||||
Object.keys(bySyl).sort((a,b)=>a-b).forEach(k=>{
|
||||
h += `<div class="res-label sub">${k == 0 ? '?' : k} syl</div>` + chipHtml(bySyl[k]);
|
||||
});
|
||||
const near = e.rhyme.near || [];
|
||||
if(near.length) h += `<div class="res-label sub">near</div>` + chipHtml(near, 'near');
|
||||
const multis = e.rhyme.multis || [];
|
||||
if(multis.length) h += `<div class="res-label sub">multis</div>` + chipHtml(multis);
|
||||
}
|
||||
}
|
||||
if(e.desc && e.desc.length){
|
||||
h += `<div class="res-label">describes</div>` + chipHtml(e.desc.map(d=>d.word));
|
||||
}
|
||||
if(e.rhyme && e.rhyme.known && (e.rhyme.words.length || (e.rhyme.near || []).length)){
|
||||
const bySyl = {};
|
||||
e.rhyme.words.forEach(d=>{ (bySyl[d.syl || 0] ||= []).push(d); });
|
||||
const onWord = e.rhyme.rhyme_on ? ` — on “${esc(e.rhyme.rhyme_on)}”` : '';
|
||||
h += `<div class="res-label">rhymes${onWord}</div>`;
|
||||
Object.keys(bySyl).sort((a,b)=>a-b).forEach(k=>{
|
||||
h += `<div class="res-label sub">${k == 0 ? '?' : k} syl</div>` + chipHtml(bySyl[k]);
|
||||
});
|
||||
const near = e.rhyme.near || [];
|
||||
if(near.length) h += `<div class="res-label sub">near</div>` + chipHtml(near, 'near');
|
||||
const multis = e.rhyme.multis || [];
|
||||
if(multis.length) h += `<div class="res-label sub">multis</div>` + chipHtml(multis);
|
||||
}
|
||||
if(e.syn && e.syn.known && e.syn.sections.length){
|
||||
h += `<div class="res-label">synonyms</div>`;
|
||||
e.syn.sections.forEach(s=>{
|
||||
if(s.label !== 'synonyms') h += `<div class="res-label sub">${esc(s.label)}</div>`;
|
||||
h += chipHtml(s.words.map(d=>d.word), s.label === 'synonyms' ? '' : 'near');
|
||||
});
|
||||
}
|
||||
resultsBox.innerHTML = h || `<p class="muted">nothing found for “${esc(e.word)}”.</p>`;
|
||||
resultsBox.innerHTML = h || `<p class="muted">nothing here for “${esc(e.word)}”.</p>`;
|
||||
resultsBox.querySelectorAll('.chip').forEach(c=>
|
||||
c.addEventListener('click', ()=> lookupFor(c.dataset.w)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user