BibliographyBackbone: Difference between revisions

From Illustrations in German Translations of Mark Twain's Works

No edit summary
No edit summary
Line 3: Line 3:




 
<button id="generateBtn" style="
<button id="copyBtn" style="
   background-color: #008CBA;
   background-color: #008CBA;
   color: white;
   color: white;
Line 13: Line 12:
   cursor: pointer;
   cursor: pointer;
   margin-bottom: 1rem;
   margin-bottom: 1rem;
">Copy Raw Data</button>
">Generate Bibliography HTML</button>


<textarea id="bibOutput" style="
<textarea id="bibOutput" style="
Line 30: Line 29:
<script>
<script>
(function() {
(function() {
   async function copyRaw() {
  function escapeHtml(text) {
     console.log('copyRaw aufgerufen');
    if (!text) return '';
    const map = {
      '&': '&amp;',
      '<': '&lt;',
      '>': '&gt;',
      '"': '&quot;',
      "'": '&#039;'
    };
    return text.replace(/[&<>"']/g, m => map[m]);
  }
 
  function formatAuthors(authors) {
    if (!authors || authors.length === 0) return '';
    if (authors.length === 1) {
      const a = authors[0];
      return a.given ? `${a.family}, ${a.given}` : a.family;
    }
    if (authors.length === 2) {
      const a1 = authors[0];
      const a2 = authors[1];
      const name1 = a1.given ? `${a1.family}, ${a1.given}` : a1.family;
      const name2 = a2.given ? `${a2.family}, ${a2.given}` : a2.family;
      return `${name1}, and ${name2}`;
    }
    const a = authors[0];
    const name = a.given ? `${a.family}, ${a.given}` : a.family;
    return `${name}, et al.`;
  }
 
  function formatMLA9(entry) {
    let citation = '';
 
    // Autoren
    if (entry.authors && entry.authors.length > 0) {
      citation += formatAuthors(entry.authors) + '. ';
    }
 
    // Titel
    if (entry.title) {
      if (entry.type === 'bookSection' || entry.type === 'book') {
        citation += `<i>${escapeHtml(entry.title)}</i>. `;
      } else {
        citation += `"${escapeHtml(entry.title)}." `;
      }
    }
 
    // Container
    if (entry.container) {
      citation += `<i>${escapeHtml(entry.container)}</i>. `;
    }
 
    // Jahr
    if (entry.year) {
      citation += `${entry.year}. `;
    }
 
    // URL
    if (entry.url) {
      citation += `<a href="${escapeHtml(entry.url)}" target="_blank">${escapeHtml(entry.url)}</a>.`;
    } else {
      citation = citation.trim();
      if (!citation.endsWith('.')) {
        citation += '.';
      }
    }
 
    return citation;
  }
 
  function generateTagsAttribute(tags) {
    if (!tags || tags.length === 0) return '';
    const normalized = tags
      .map(tag => tag.toLowerCase().replace(/\s+/g, '_'))
      .join(' ');
    return ` data-tags="${normalized}"`;
  }
 
  function generateTagSpans(tags) {
    if (!tags || tags.length === 0) return '';
    return tags
      .map(tag => {
        const normalized = tag.toLowerCase().replace(/\s+/g, '_');
        return `<span class="tag" data-tag="${normalized}">${escapeHtml(tag)}</span>`;
      })
      .join('\n    ');
  }
 
  function generateBibEntry(entry, index) {
    const mlaFormatted = formatMLA9(entry);
    const tagsAttr = generateTagsAttribute(entry.tags);
    const tagSpans = generateTagSpans(entry.tags);
    const abstract = entry.abstract ? escapeHtml(entry.abstract) : '';
 
    return `<!-- ${index} -->
<div class="bib-entry"${tagsAttr}>
  <h3>${mlaFormatted}</h3>
  <div class="bib-tags">
    ${tagSpans}
  </div>
  <p class="short-abstract">${abstract || '(No abstract available)'}</p>
  <button class="expand-btn">Show Abstract</button>
  <div class="abstract hidden">
    <p>${abstract || 'No abstract available.'}</p>
  </div>
</div>`;
  }
 
   async function generateBibliography() {
     console.log('generateBibliography aufgerufen');
     const output = document.getElementById('bibOutput');
     const output = document.getElementById('bibOutput');
     if (!output) {
     if (!output) {
       console.error('bibOutput textarea nicht gefunden');
       console.error('bibOutput not found');
       return;
       return;
     }
     }


     output.value = 'Lade...';
     output.value = 'Lade Daten...';


     try {
     try {
       const response = await fetch('/BibliographyData?action=raw');
       const response = await fetch('/BibliographyData?action=raw');
       const text = await response.text();
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
       output.value = text;
     
       console.log('Fertig - ' + text.length + ' Zeichen');
       const entries = await response.json();
      console.log('JSON geparst, ' + entries.length + ' Einträge');
 
      // Filtere irrelevante Einträge
      const filtered = entries.filter(entry => {
        if (entry.tags && entry.tags.includes('Not relevant for Mark Twain')) {
          return false;
        }
        if (!entry.title || entry.title.trim() === 'Untitled') {
          return false;
        }
        return true;
      });
 
      // Extrahiere alle Tags
      const allTags = new Set();
      filtered.forEach(entry => {
        if (entry.tags && Array.isArray(entry.tags)) {
          entry.tags.forEach(tag => allTags.add(tag));
        }
      });
 
      // Generiere HTML
      const tagSpans = Array.from(allTags)
        .sort()
        .map(tag => {
          const normalized = tag.toLowerCase().replace(/\s+/g, '_');
          return `<span class="tag" data-tag="${normalized}">${escapeHtml(tag)}</span>`;
        })
        .join('\n  ');
 
      const entryHTML = filtered
        .map((entry, i) => generateBibEntry(entry, i + 1))
        .join('\n\n');
 
      const html = `<div class="bib-tags">
  ${tagSpans}
</div>
 
<div id="listView" class="bibliography">
${entryHTML}
</div>
 
<div id="networkView" class="network hidden"></div>`;
 
       output.value = html;
       console.log('Fertig - ' + filtered.length + ' Einträge generiert');
     } catch (error) {
     } catch (error) {
       output.value = 'ERROR: ' + error.message;
       output.value = 'ERROR: ' + error.message;
Line 52: Line 205:


   document.addEventListener('DOMContentLoaded', function() {
   document.addEventListener('DOMContentLoaded', function() {
     const btn = document.getElementById('copyBtn');
     const btn = document.getElementById('generateBtn');
     if (btn) {
     if (btn) {
       btn.addEventListener('click', copyRaw);
       btn.addEventListener('click', generateBibliography);
       console.log('Button bereit');
       console.log('Generate Button bereit');
     }
     }
   });
   });

Revision as of 00:48, 12 May 2026

Bibliography Generator