BibliographyBackbone: Difference between revisions

From Illustrations in German Translations of Mark Twain's Works

No edit summary
No edit summary
 
(14 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Seitenkopf|Bibliography Generator}}
{{Seitenkopf|Bibliography Generator}}
<html>
<html>
<div style="max-width: 1000px; margin: 0 auto;">
<div style="max-width: 1000px;">
 
<p>Klicke auf den Button, um die Zotero-Einträge von <code>BibliographyData</code> zu laden und als MLA9-formatiertes HTML zu generieren.</p>


<button id="generateBtn" style="
<button id="generateBtn" style="
Line 15: Line 14:
   margin-bottom: 1rem;
   margin-bottom: 1rem;
">Generate Bibliography HTML</button>
">Generate Bibliography HTML</button>
<p id="bibStatus" style="font-size: 0.9rem; color: #666; margin-bottom: 1rem;"></p>
<h3>Raw HTML Output</h3>
<p style="font-size: 0.85rem; color: #999;">Kopiere den kompletten Inhalt und füge ihn in die <code>Bibliography</code>-Seite zwischen den <code>&lt;html&gt;</code>-Tags ein.</p>


<textarea id="bibOutput" style="
<textarea id="bibOutput" style="
   width: 100%;
   width: 100%;
   height: 700px;
   height: 400px;
   font-family: 'Courier New', monospace;
   font-family: 'Courier New', monospace;
   font-size: 0.8rem;
   font-size: 0.85rem;
   padding: 10px;
   padding: 10px;
   border: 2px solid #ddd;
   border: 2px solid #ddd;
Line 33: Line 27:
   overflow: auto;
   overflow: auto;
"></textarea>
"></textarea>
</div>


<script>
<script>
/**
* Bibliography Generator für Mark Twain Wiki
* MLA9-Formatierung mit Tags und Abstracts
*/
(function() {
(function() {
   'use strict';
   function escapeHtml(text) {
 
     if (!text) return '';
  async function generateBibliography() {
     const map = {
     const output = document.getElementById('bibOutput');
       '&': '&amp;',
     output.value = 'Lade BibliographyData...';
       '<': '&lt;',
 
       '>': '&gt;',
    try {
       '"': '&quot;',
       // Fetch JSON
      "'": '&#039;'
      const response = await fetch('/BibliographyData?action=raw');
    };
       if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return text.replace(/[&<>"']/g, m => map[m]);
       const entries = await response.json();
  }
 
       // 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
  function getOrUnknown(value) {
      const html = generateHTML(filtered, Array.from(allTags).sort());
    if (!value || (typeof value === 'string' && !value.trim())) {
      output.value = html;
       return 'unknown';
     
      const status = document.getElementById('bibStatus');
      if (status) {
        status.textContent = `✓ ${filtered.length} Einträge generiert (${allTags.size} Tags)`;
        status.style.color = '#4caf50';
      }
    } catch (error) {
       output.value = `ERROR: ${error.message}`;
      output.style.borderColor = '#d32f2f';
     }
     }
    return value;
   }
   }


  /**
   function formatAuthors(authors) {
  * Generiert komplettes HTML
     if (!authors || authors.length === 0) {
  */
       return 'unknown';
   function generateHTML(entries, allTags) {
    }
     const tagSpans = allTags
   
       .map(tag => {
    if (authors.length === 1) {
        const normalized = tag.toLowerCase().replace(/\s+/g, '_');
      const a = authors[0];
        return `<span class="tag" data-tag="${normalized}">${escapeHtml(tag)}</span>`;
      const family = a.family || 'unknown';
      })
      const given = a.given || '';
       .join('\n  ');
      return given ? `${family}, ${given}` : family;
 
    }
    const entryHTML = entries
   
       .map((entry, i) => generateBibEntry(entry, i + 1))
    if (authors.length === 2) {
       .join('\n\n');
       const a1 = authors[0];
      const a2 = authors[1];
       const name1 = (a1.family || 'unknown') + (a1.given ? ', ' + a1.given : '');
       const name2 = (a2.family || 'unknown') + (a2.given ? ', ' + a2.given : '');
      return `${name1}, and ${name2}`;
    }


     return `<div class="bib-tags">
     const a = authors[0];
  ${tagSpans}
    const name = (a.family || 'unknown') + (a.given ? ', ' + a.given : '');
</div>
    return `${name}, et al.`;
 
<div id="listView" class="bibliography">
${entryHTML}
</div>
 
<div id="networkView" class="network hidden"></div>`;
   }
   }


  /**
  * Generiert einen einzelnen Biblio-Eintrag in MLA9-Format
  */
  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>`;
  }
  /**
  * Formatiert einen Eintrag in MLA9
  * MLA9: Author(s). "Title." Container. Year. Other info.
  */
   function formatMLA9(entry) {
   function formatMLA9(entry) {
     let citation = '';
     let citation = '';


     // Autoren
     const authors = formatAuthors(entry.authors);
    if (entry.authors && entry.authors.length > 0) {
    citation += authors + '. ';
      citation += formatAuthors(entry.authors) + '. ';
    }


     // Titel
     const title = getOrUnknown(entry.title);
    if (entry.title) {
    if (entry.type === 'bookSection' || entry.type === 'book') {
      // Bücher sind kursiv, Artikel in Anführungszeichen
      citation += `<i>${escapeHtml(title)}</i>. `;
      if (entry.type === 'bookSection' || entry.type === 'book') {
    } else {
        citation += `<i>${escapeHtml(entry.title)}</i>. `;
      citation += `"${escapeHtml(title)}." `;
      } else {
        citation += `"${escapeHtml(entry.title)}." `;
      }
     }
     }


     // Container (Zeitschrift, Sammelband, etc.)
     const container = entry.container;
     if (entry.container) {
     if (container && container.trim()) {
       citation += `<i>${escapeHtml(entry.container)}</i>. `;
       citation += `<i>${escapeHtml(container)}</i>. `;
     }
     }


     // Jahr
     const year = getOrUnknown(entry.year);
    if (entry.year) {
    citation += `${year}. `;
      citation += `${entry.year}. `;
    }


    // URL
     if (entry.url && entry.url.trim()) {
     if (entry.url) {
       citation += `<a href="${escapeHtml(entry.url)}" target="_blank">${escapeHtml(entry.url)}</a>.`;
       citation += `<a href="${escapeHtml(entry.url)}" target="_blank">${escapeHtml(entry.url)}</a>.`;
     } else {
     } else {
      // Entferne den letzten Punkt, falls schon vorhanden
       citation = citation.trim();
       citation = citation.trim();
       if (!citation.endsWith('.')) {
       if (!citation.endsWith('.')) {
Line 184: Line 107:
   }
   }


  /**
   function generateTagsAttribute(tags) {
  * Formatiert Autoren
     if (!tags || tags.length === 0) {
  * MLA9: "Last, First, and Last, First"
       return ' data-tags="untagged"';
  */
   function formatAuthors(authors) {
     if (authors.length === 0) return '';
    if (authors.length === 1) {
       return formatAuthor(authors[0]);
     }
     }
    if (authors.length === 2) {
      return `${formatAuthor(authors[0])}, and ${formatAuthor(authors[1])}`;
    }
    // 3+ Autoren: Nur first + et al.
    return `${formatAuthor(authors[0])}, et al.`;
  }
  /**
  * Formatiert einen einzelnen Autor
  */
  function formatAuthor(author) {
    if (!author) return '';
    const family = author.family || '';
    const given = author.given || '';
    if (!family) return given;
    if (!given) return family;
    return `${family}, ${given}`;
  }
  /**
  * Generiert data-tags Attribut
  */
  function generateTagsAttribute(tags) {
    if (!tags || tags.length === 0) return '';
     const normalized = tags
     const normalized = tags
       .map(tag => tag.toLowerCase().replace(/\s+/g, '_'))
       .map(tag => tag.toLowerCase().replace(/\s+/g, '_'))
Line 226: Line 117:
   }
   }


  /**
  * Generiert Tag-Spans
  */
   function generateTagSpans(tags) {
   function generateTagSpans(tags) {
     if (!tags || tags.length === 0) return '';
     if (!tags || tags.length === 0) {
      return '<span class="tag" data-tag="untagged">untagged</span>';
    }
     return tags
     return tags
       .map(tag => {
       .map(tag => {
Line 236: Line 126:
         return `<span class="tag" data-tag="${normalized}">${escapeHtml(tag)}</span>`;
         return `<span class="tag" data-tag="${normalized}">${escapeHtml(tag)}</span>`;
       })
       })
       .join('');
       .join('\n    ');
   }
   }


  /**
   function generateBibEntry(entry, index) {
  * HTML-Escape
     const mlaFormatted = formatMLA9(entry);
  */
    const tagsAttr = generateTagsAttribute(entry.tags);
   function escapeHtml(text) {
     const tagSpans = generateTagSpans(entry.tags);
     if (!text) return '';
    const abstract = entry.abstract && entry.abstract.trim() ? escapeHtml(entry.abstract) : '';
     const map = {
 
      '&': '&amp;',
    return `<!-- ${index} -->
      '<': '&lt;',
<div class="bib-entry"${tagsAttr}>
      '>': '&gt;',
  <h3>${mlaFormatted}</h3>
      '"': '&quot;',
  <div class="bib-tags">
      "'": '&#039;'
    ${tagSpans}
    };
  </div>
     return text.replace(/[&<>"']/g, m => map[m]);
  <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() {
  * Initialisierung
     const output = document.getElementById('bibOutput');
  */
     output.value = 'Lade Daten...';
  function init() {
 
     const btn = document.getElementById('generateBtn');
    try {
     if (btn) {
      const response = await fetch('/BibliographyData?action=raw');
       btn.addEventListener('click', generateBibliography);
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
       console.log('Bibliography Generator bereit');
        
      const entries = await response.json();
 
      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;
      });
 
      const allTags = new Set();
      filtered.forEach(entry => {
        if (entry.tags && Array.isArray(entry.tags)) {
          entry.tags.forEach(tag => allTags.add(tag));
        }
      });
 
      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;
    } catch (error) {
      output.value = 'ERROR: ' + error.message;
     }
     }
   }
   }


   if (document.readyState === 'loading') {
   const btn = document.getElementById('generateBtn');
     document.addEventListener('DOMContentLoaded', init);
  if (btn) {
  } else {
     btn.addEventListener('click', generateBibliography);
    init();
   }
   }
})();
})();
</script>
</script>
</div>
</html>
</html>

Latest revision as of 00:51, 12 May 2026

Bibliography Generator