// DWDS Collocate Extractor // Usage: Copy this code, create a bookmarklet, or run in browser console (function() { // Get the search term from the URL const urlParams = new URLSearchParams(window.location.search); const searchTerm = urlParams.get('q'); if (!searchTerm) { alert('Could not find search term in URL'); return; } // Find all collocate rows in the table const rows = document.querySelectorAll('table tbody tr'); const results = []; // Build a map of categories by finding all section headers const categoryMap = new Map(); const tables = document.querySelectorAll('table'); tables.forEach(table => { // Find the category in the table header const categoryHeader = table.querySelector('thead tr th.no-wrap span.rel-desc'); let currentCategory = ''; if (categoryHeader) { currentCategory = categoryHeader.textContent.trim(); } // Process all rows in this table with the current category const tableRows = table.querySelectorAll('tbody tr'); tableRows.forEach(row => { const cells = row.querySelectorAll('td'); if (cells.length < 2) return; // Get the collocate from the first cell const collocateCell = cells[0]; const collocateSpan = collocateCell.querySelector('.wp-collocation span[data-toggle="tooltip"]'); if (!collocateSpan) return; const collocate = collocateSpan.textContent.trim(); if (!collocate) return; // Analyze word order and format accordingly let formatted = formatCollocation(collocate, searchTerm); // Add category if found if (currentCategory) { formatted += ` /cat: ${currentCategory}`; } results.push(formatted); }); }); function formatCollocation(collocate, baseTerm) { // Remove any extra whitespace collocate = collocate.replace(/\s+/g, ' ').trim(); // Check if collocate already contains the base term if (collocate.toLowerCase().includes(baseTerm.toLowerCase())) { return collocate; } // Determine position based on grammatical patterns // Adjectives typically come before nouns if (isAdjective(collocate) && isNoun(baseTerm)) { return `${collocate} ${baseTerm}`; } // Past participles often come before nouns if (isPastParticiple(collocate) && isNoun(baseTerm)) { return `${collocate} ${baseTerm}`; } // Verbs with separable prefixes if (collocate.includes('_')) { const parts = collocate.split('_'); return `${baseTerm} ${parts.join(' ')}`; } // Prepositions come before the term if (isPreposition(collocate)) { return `${collocate} ${baseTerm}`; } // Coordinating conjunctions (und, oder, etc.) if (isConjunction(collocate)) { return `${baseTerm} ${collocate}`; } // Default: adjective/modifier before noun, verb patterns after if (isNoun(baseTerm)) { return `${collocate} ${baseTerm}`; } else { return `${baseTerm} ${collocate}`; } } function isPastParticiple(word) { return word.startsWith('ge') || word.match(/t$|en$/) || word.includes('umgestürzt') || word.includes('gefällt'); } function isAdjective(word) { // Common adjective patterns return word.match(/lich$|ig$|bar$|sam$|haft$|los$|voll$|isch$/) || word === 'schnell' || word === 'groß' || word === 'klein'; } function isNoun(word) { // Nouns start with capital letter in German return word.charAt(0) === word.charAt(0).toUpperCase(); } function isPreposition(word) { const preps = ['an', 'auf', 'aus', 'bei', 'durch', 'für', 'gegen', 'hinter', 'in', 'mit', 'nach', 'neben', 'ohne', 'über', 'um', 'unter', 'von', 'vor', 'zu', 'zwischen']; return preps.includes(word.toLowerCase()); } function isConjunction(word) { const conj = ['und', 'oder', 'aber', 'sondern', 'denn']; return conj.includes(word.toLowerCase()); } // Display results if (results.length === 0) { alert('No collocates found. Make sure you are on a DWDS collocation results page.'); return; } const output = results.join('\n'); // Create a modal to display results const modal = document.createElement('div'); modal.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border: 2px solid #333; border-radius: 8px; z-index: 10000; max-width: 600px; max-height: 80vh; overflow: auto; box-shadow: 0 4px 6px rgba(0,0,0,0.3); `; const textarea = document.createElement('textarea'); textarea.value = output; textarea.style.cssText = ` width: 100%; height: 400px; font-family: monospace; padding: 10px; border: 1px solid #ccc; border-radius: 4px; `; const closeBtn = document.createElement('button'); closeBtn.textContent = 'Close'; closeBtn.style.cssText = ` margin-top: 10px; padding: 8px 16px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; `; closeBtn.onclick = () => modal.remove(); const copyBtn = document.createElement('button'); copyBtn.textContent = 'Copy to Clipboard'; copyBtn.style.cssText = ` margin-top: 10px; margin-left: 10px; padding: 8px 16px; background: #28a745; color: white; border: none; border-radius: 4px; cursor: pointer; `; copyBtn.onclick = () => { textarea.select(); document.execCommand('copy'); copyBtn.textContent = 'Copied!'; setTimeout(() => copyBtn.textContent = 'Copy to Clipboard', 2000); }; modal.appendChild(textarea); modal.appendChild(copyBtn); modal.appendChild(closeBtn); document.body.appendChild(modal); // Auto-select text for easy copying textarea.select(); })();