Skip to content

Commit b112d8f

Browse files
SableRafclaude
andcommitted
Broaden Plus Code recovery to handle more user input formats
- Remove `^` anchor so codes are matched anywhere in the input string - Widen prefix minimum from 4 to 2 chars to support short codes like "5Q+C5" - Add progressive suffix trimming to avoid over-extraction when city names start with OLC-valid characters (e.g. Vancouver → V) - Extract city/state hint from text appended after the code (e.g. "QX5Q+C5DENVER,COLORADO") and use it as a Nominatim reference when city/country form fields are empty Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5a53434 commit b112d8f

1 file changed

Lines changed: 44 additions & 7 deletions

File tree

.github/scripts/process-new-event-issue.mjs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,17 +195,54 @@ async function resolvePlusCode(rawValue, city, country) {
195195

196196
if (!olc) return { code: null, note: null };
197197

198-
// Try to extract a leading Plus Code from concatenated input (e.g. QX5Q+C5DENVER)
198+
// Try to extract a Plus Code from anywhere in the input (e.g. "My code: QX5Q+C5DENVER").
199+
// No leading anchor so we match even with arbitrary prefix text.
200+
// Minimum 2 chars before '+' to support short codes like "5Q+C5DENVER".
201+
// Greedy 2–3 chars after '+' may over-capture when the city starts with OLC-valid chars
202+
// (e.g. Vancouver → V); we resolve that below by trying progressively shorter suffixes.
203+
const EXTRACT_RE = /([23456789CFGHJMPQRVWX]{2,8}\+[23456789CFGHJMPQRVWX]{2,3})/i;
204+
const match = normalized.match(EXTRACT_RE);
205+
199206
let shortCode = normalized;
200-
const extracted = normalized.match(/^([23456789CFGHJMPQRVWX]{4,8}\+[23456789CFGHJMPQRVWX]{2,3})/i);
201-
if (extracted) {
202-
shortCode = extracted[1].toUpperCase();
207+
let locationHint = '';
208+
209+
if (match) {
210+
const [fullMatch, candidate] = match;
211+
const plusIdx = candidate.indexOf('+');
212+
const codePrefix = candidate.slice(0, plusIdx);
213+
const greedySuffix = candidate.slice(plusIdx + 1);
214+
215+
// Try suffix lengths from longest (greedy) down to 2; take first that isShort().
216+
shortCode = candidate;
217+
for (let len = greedySuffix.length; len >= 2; len--) {
218+
const probe = `${codePrefix}+${greedySuffix.slice(0, len)}`;
219+
if (olc.isShort(probe)) {
220+
shortCode = probe;
221+
break;
222+
}
223+
}
224+
225+
// Extract any trailing non-OLC text as a location hint (e.g. "DENVER,COLORADO").
226+
// Used only when the city/country form fields are empty.
227+
const afterCode = normalized.slice(match.index + fullMatch.length);
228+
if (afterCode) {
229+
locationHint = afterCode
230+
.replace(/,/g, ' ')
231+
.trim()
232+
.toLowerCase()
233+
.replace(/\b\w/g, (c) => c.toUpperCase());
234+
}
203235
}
204236

205-
// Attempt recovery if we have a short OLC and a location reference
206-
if (olc.isShort(shortCode) && (city || country)) {
237+
// Attempt recovery if we have a short OLC and a location reference.
238+
// Prefer explicit city/country fields; fall back to the hint extracted from the input.
239+
const locationRef = (city || country)
240+
? [city, country].filter(Boolean).join(' ')
241+
: locationHint;
242+
243+
if (olc.isShort(shortCode) && locationRef) {
207244
try {
208-
const query = encodeURIComponent([city, country].filter(Boolean).join(' '));
245+
const query = encodeURIComponent(locationRef);
209246
const response = await fetch(
210247
`https://nominatim.openstreetmap.org/search?q=${query}&format=json&limit=1`,
211248
{ headers: { 'User-Agent': 'PCD-Event-Intake/1.0' } },

0 commit comments

Comments
 (0)