eis-website/js/textanalyse.js

447 lines
14 KiB
JavaScript

/**
* Textanalyse - Analysiert Texte und zeigt Statistiken
* David & Karo - EIS Projekt
*/
/**
* Analysiert einen Text und gibt Statistiken zurück
* @param {string} text - Der zu analysierende Text
* @returns {object} - Enthält Analyseresultate und Details
*/
function analyseText(text) {
// Eingabe validieren
if (text === null) {
return {
valid: false,
fehler: 'Eingabe abgebrochen!',
nachricht: '❌ Die Textanalyse wurde abgebrochen.'
};
}
// Text trimmen (führende und nachfolgende Leerzeichen entfernen)
const textTrimmed = text.trim();
if (textTrimmed === '') {
return {
valid: false,
fehler: 'Text ist leer!',
nachricht: '❌ Bitte geben Sie einen Text ein, der analysiert werden soll!'
};
}
// Zeichen zählen
const anzahlZeichen = text.length;
const anzahlZeichenOhneLeerzeichen = text.replace(/\s/g, '').length;
// Wörter zählen
const woerter = textTrimmed.split(/\s+/).filter(wort => wort.length > 0);
const anzahlWoerter = woerter.length;
// Sätze zählen (vereinfacht: Punkt, Frage- und Ausrufezeichen)
const anzahlSaetze = (text.match(/[.!?]/g) || []).length || 1;
// Text in Großbuchstaben
const textGross = text.toUpperCase();
// Text in Kleinbuchstaben
const textKlein = text.toLowerCase();
// Durchschnittliche Wortlänge
const durchschnittlicheWortlaenge = anzahlWoerter > 0
? (anzahlZeichenOhneLeerzeichen / anzahlWoerter).toFixed(2)
: 0;
// Vokale zählen
const vokale = (text.match(/[aeiouäöüAEIOUÄÖÜ]/g) || []).length;
// Konsonanten zählen
const konsonanten = (text.match(/[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ]/g) || []).length;
// Zahlen zählen
const zahlen = (text.match(/[0-9]/g) || []).length;
// Längster und kürzester Satz
const saetze = text.split(/[.!?]/).map(s => s.trim()).filter(s => s.length > 0);
const laengsterSatz = saetze.length > 0
? saetze.reduce((prev, current) => (prev.length > current.length) ? prev : current, '')
: '';
const kuerzeesterSatz = saetze.length > 0
? saetze.reduce((prev, current) => (prev.length < current.length) ? prev : current, '')
: '';
// Formatierte Ausgabe mit Template Literals
const formatiertesErgebnis = `
📊 TEXTANALYSE-ERGEBNISSE:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📝 Zeichen & Wörter:
• Gesamte Zeichen: ${anzahlZeichen}
• Zeichen ohne Leerzeichen: ${anzahlZeichenOhneLeerzeichen}
• Anzahl der Wörter: ${anzahlWoerter}
• Anzahl der Sätze: ${anzahlSaetze}
• Durchschn. Wortlänge: ${durchschnittlicheWortlaenge} Zeichen
🔤 Buchstaben & Laute:
• Vokale: ${vokale}
• Konsonanten: ${konsonanten}
• Zahlen: ${zahlen}
🔤 ORIGINAL TEXT:
${text}
🔤 GROSSBUCHSTABEN:
${textGross}
🔤 KLEINBUCHSTABEN:
${textKlein}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`;
return {
valid: true,
originalText: text,
anzahlZeichen: anzahlZeichen,
anzahlZeichenOhneLeerzeichen: anzahlZeichenOhneLeerzeichen,
anzahlWoerter: anzahlWoerter,
anzahlSaetze: anzahlSaetze,
durchschnittlicheWortlaenge: durchschnittlicheWortlaenge,
vokale: vokale,
konsonanten: konsonanten,
zahlen: zahlen,
textGross: textGross,
textKlein: textKlein,
saetze: saetze,
laengsterSatz: laengsterSatz,
kuerzeesterSatz: kuerzeesterSatz,
formatiertesErgebnis: formatiertesErgebnis,
nachricht: `✅ Text erfolgreich analysiert! ${anzahlWoerter} Wörter, ${anzahlZeichen} Zeichen.`
};
}
/**
* Vergleicht zwei Texte
* @param {string} text1 - Erster Text
* @param {string} text2 - Zweiter Text
* @returns {object} - Vergleichsergebnisse
*/
function vergleicheTexte(text1, text2) {
const analyse1 = analyseText(text1);
const analyse2 = analyseText(text2);
if (!analyse1.valid || !analyse2.valid) {
return {
valid: false,
fehler: 'Mindestens einer der Texte ist leer!',
nachricht: '❌ Bitte geben Sie zwei nicht-leere Texte ein!'
};
}
const unterschied = Math.abs(analyse1.anzahlZeichen - analyse2.anzahlZeichen);
const laenger = analyse1.anzahlZeichen > analyse2.anzahlZeichen ? 'Text 1' : 'Text 2';
const vergleichsErgebnis = `
📊 TEXTVERGLEICH:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Text 1 Statistik:
• Zeichen: ${analyse1.anzahlZeichen}
• Wörter: ${analyse1.anzahlWoerter}
Text 2 Statistik:
• Zeichen: ${analyse2.anzahlZeichen}
• Wörter: ${analyse2.anzahlWoerter}
Vergleich:
• Unterschied: ${unterschied} Zeichen
• Längerer Text: ${laenger}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`;
return {
valid: true,
vergleichsErgebnis: vergleichsErgebnis,
unterschied: unterschied,
laenger: laenger,
nachricht: `✅ Vergleich abgeschlossen! Unterschied: ${unterschied} Zeichen`
};
}
/**
* Sucht nach Wörtern in einem Text
* @param {string} text - Der Text zum Durchsuchen
* @param {string} suchbegriff - Das Wort zum Suchen
* @returns {object} - Suchergebnisse
*/
function sucheWort(text, suchbegriff) {
if (!text.trim() || !suchbegriff.trim()) {
return {
valid: false,
fehler: 'Eingabe unvollständig!',
nachricht: '❌ Bitte geben Sie Text und Suchbegriff ein!'
};
}
const regex = new RegExp(suchbegriff, 'gi');
const treffer = (text.match(regex) || []).length;
const indexTreffer = [];
let match;
while ((match = regex.exec(text)) !== null) {
indexTreffer.push(match.index);
}
const suchergebnis = `
🔍 SUCHE: "${suchbegriff}"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Treffer gefunden: ${treffer}
• Positionen: ${indexTreffer.join(', ') || 'Keine'}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`;
return {
valid: true,
suchbegriff: suchbegriff,
treffer: treffer,
positionen: indexTreffer,
suchergebnis: suchergebnis,
nachricht: `${treffer} Treffer für "${suchbegriff}" gefunden!`
};
}
// DOM-Manipulation und Event-Listener
document.addEventListener('DOMContentLoaded', function() {
const analyzeBtn = document.getElementById('analyze-btn');
const compareBtn = document.getElementById('compare-btn');
const searchBtn = document.getElementById('search-btn');
const resetBtn = document.getElementById('reset-btn');
if (analyzeBtn) {
analyzeBtn.addEventListener('click', performTextAnalysis);
}
if (compareBtn) {
compareBtn.addEventListener('click', performTextComparison);
}
if (searchBtn) {
searchBtn.addEventListener('click', performTextSearch);
}
if (resetBtn) {
resetBtn.addEventListener('click', resetAnalyzer);
}
// Live-Zeichenzähler
const textInput = document.getElementById('text-input');
const charCount = document.getElementById('char-count');
if (textInput && charCount) {
textInput.addEventListener('input', function() {
charCount.textContent = this.value.length;
});
}
});
/**
* Führt Textanalyse durch
*/
function performTextAnalysis() {
const textInput = document.getElementById('text-input');
const resultDiv = document.getElementById('result');
if (!textInput) return;
const text = textInput.value;
const result = analyseText(text);
if (!result.valid) {
resultDiv.innerHTML = `<div class="error-message">⚠️ ${result.fehler}<br>${result.nachricht}</div>`;
alert(result.nachricht);
console.error(result.fehler, result);
return;
}
// HTML-Ergebnis formatieren
let resultHTML = `
<div class="analysis-result">
<h4>📊 Analyseresultate</h4>
<div class="stats-grid">
<div class="stat-card">
<div class="stat-number">${result.anzahlZeichen}</div>
<div class="stat-label">Zeichen (gesamt)</div>
</div>
<div class="stat-card">
<div class="stat-number">${result.anzahlZeichenOhneLeerzeichen}</div>
<div class="stat-label">Ohne Leerzeichen</div>
</div>
<div class="stat-card">
<div class="stat-number">${result.anzahlWoerter}</div>
<div class="stat-label">Wörter</div>
</div>
<div class="stat-card">
<div class="stat-number">${result.anzahlSaetze}</div>
<div class="stat-label">Sätze</div>
</div>
<div class="stat-card">
<div class="stat-number">${result.vokale}</div>
<div class="stat-label">Vokale</div>
</div>
<div class="stat-card">
<div class="stat-number">${result.konsonanten}</div>
<div class="stat-label">Konsonanten</div>
</div>
<div class="stat-card">
<div class="stat-number">${result.zahlen}</div>
<div class="stat-label">Zahlen</div>
</div>
<div class="stat-card">
<div class="stat-number">${result.durchschnittlicheWortlaenge}</div>
<div class="stat-label">Ø Wortlänge</div>
</div>
</div>
<div class="text-transformations">
<h5>🔤 Texttransformationen:</h5>
<div class="transformation-box">
<label>GROSSBUCHSTABEN:</label>
<div class="transformation-text">${escapeHtml(result.textGross)}</div>
<button class="copy-btn" onclick="copyToClipboard('${escapeHtml(result.textGross).replace(/'/g, "\\'")}')">📋 Kopieren</button>
</div>
<div class="transformation-box">
<label>kleinbuchstaben:</label>
<div class="transformation-text">${escapeHtml(result.textKlein)}</div>
<button class="copy-btn" onclick="copyToClipboard('${escapeHtml(result.textKlein).replace(/'/g, "\\'")}')">📋 Kopieren</button>
</div>
</div>
</div>
`;
resultDiv.innerHTML = resultHTML;
// Console und Alert Output
console.log(result.formatiertesErgebnis);
alert(result.nachricht);
}
/**
* Führt Textvergleich durch
*/
function performTextComparison() {
const text1Input = document.getElementById('text1-compare');
const text2Input = document.getElementById('text2-compare');
const compareResultDiv = document.getElementById('compare-result');
if (!text1Input || !text2Input) return;
const text1 = text1Input.value;
const text2 = text2Input.value;
const result = vergleicheTexte(text1, text2);
if (!result.valid) {
compareResultDiv.innerHTML = `<div class="error-message">⚠️ ${result.fehler}<br>${result.nachricht}</div>`;
alert(result.nachricht);
return;
}
let resultHTML = `
<div class="comparison-result">
<h4>📊 Vergleichsergebnisse</h4>
<div class="comparison-cards">
<div class="comparison-card">
<h5>Text 1</h5>
<p><strong>Zeichen:</strong> ${result.vergleichsErgebnis.match(/Zeichen: (\d+)/)[1] || '0'}</p>
<p><strong>Wörter:</strong> ${result.vergleichsErgebnis.match(/Wörter: (\d+)/)[1] || '0'}</p>
</div>
<div class="comparison-card">
<h5>Text 2</h5>
<p><strong>Zeichen:</strong> ${result.vergleichsErgebnis.match(/Zeichen: (\d+)[\s\S]*?Wörter: (\d+)[\s\S]*?Text 2 Statistik[\s\S]*?Zeichen: (\d+)/)[3] || '0'}</p>
<p><strong>Wörter:</strong> ${result.vergleichsErgebnis.match(/Text 2[\s\S]*?Wörter: (\d+)/)[1] || '0'}</p>
</div>
<div class="comparison-result-box">
<p><strong>Längerer Text:</strong> ${result.laenger}</p>
<p><strong>Unterschied:</strong> ${result.unterschied} Zeichen</p>
</div>
</div>
</div>
`;
compareResultDiv.innerHTML = resultHTML;
console.log(result.vergleichsErgebnis);
alert(result.nachricht);
}
/**
* Führt Wortsuche durch
*/
function performTextSearch() {
const searchTextInput = document.getElementById('search-text');
const searchTermInput = document.getElementById('search-term');
const searchResultDiv = document.getElementById('search-result');
if (!searchTextInput || !searchTermInput) return;
const text = searchTextInput.value;
const suchbegriff = searchTermInput.value;
const result = sucheWort(text, suchbegriff);
if (!result.valid) {
searchResultDiv.innerHTML = `<div class="error-message">⚠️ ${result.fehler}<br>${result.nachricht}</div>`;
alert(result.nachricht);
return;
}
let resultHTML = `
<div class="search-result">
<h4>🔍 Suchergebnisse</h4>
<div class="search-summary">
<p><strong>Suchbegriff:</strong> "${escapeHtml(result.suchbegriff)}"</p>
<p><strong>Treffer gefunden:</strong> ${result.treffer}</p>
${result.treffer > 0 ? `<p><strong>Positionen:</strong> ${result.positionen.join(', ')}</p>` : ''}
</div>
</div>
`;
searchResultDiv.innerHTML = resultHTML;
console.log(result.suchergebnis);
alert(result.nachricht);
}
/**
* Setzt den Analyzer zurück
*/
function resetAnalyzer() {
document.getElementById('text-input').value = '';
document.getElementById('text1-compare').value = '';
document.getElementById('text2-compare').value = '';
document.getElementById('search-text').value = '';
document.getElementById('search-term').value = '';
document.getElementById('result').innerHTML = '';
document.getElementById('compare-result').innerHTML = '';
document.getElementById('search-result').innerHTML = '';
document.getElementById('char-count').textContent = '0';
}
/**
* HTML-escape für sicherer Ausgabe
*/
function escapeHtml(text) {
const map = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
return text.replace(/[&<>"']/g, m => map[m]);
}
/**
* Text in Zwischenablage kopieren
*/
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
alert('✅ Text kopiert!');
}).catch(() => {
alert('❌ Fehler beim Kopieren');
});
}