Pythonskript: bib2mmap

2014-12-10

Dieser Beitrag beschreibt ein kleines Skript zur Umwandlung von Bibtex Dateien in MindMaps.

Motivation

Für die Verwaltung von wissenschaftlichen Arbeiten gibt es zahlreiche Werkzeuge (z.B. Docear), die u.a. die Arbeiten auch in einer MindMap darstellen können. Nachteil hierbei ist allerdings, dass die Erstellung einer MindMap manuell (von Hand) durchgeführt werden muss. Dies kann, je nach Umfang der Literatursammlung, einen hohen zeitlichen Aufwand bedeuten. Dabei liegen die meisten Informationen (Autor, Titel, Jahr, etc.) bereits in Form sog. BibTeX-Einträge vor. Daher stellt sich die Frage, in wie weit die Erstellung einer MindMap aus den BibTeX-Dateien automatisiert erfolgen kann?

Konzept

Für ein erstes Konzept soll das folgende Flussdiagramm eine Übersicht geben.

bib2mm_flow-chart_2

Umsetzung

Für einen ersten Prototypen reicht ein kurzes Python-Programm. Im Grunde wird ein BibTeX-Parser mit einer Graph-Virtualisierung o. ä. verbunden. In diesem Fall ist das Graphviz. Glücklicherweise gibt es für Python bereits vorgefertigte Module, die sich um genau diese Aufgaben (BibTeX parsen, Graph visualisieren) kümmern.

Die Präambel unseres Python-Skripts sieht somit wie folgt aus:

import sys
import random
import getopt
import bibtexparser
from graphviz import Digraph, Graph

Als erstes wird die BibTex-Datei eingelesen und geparst.

def createBibDbOutOf(bibfile):
    with open(bibfile) as bibtex_file:
        bibtex_str = bibtex_file.read()
    return bibtexparser.loads(bibtex_str)

Im Anschluss erstellt man sich die Grundstruktur des Graphen.

def createGraph(rootNodeId='0', rootNodeLabel='RootNode', graphName='', renderType='pdf'):
    d_graph = Digraph(name=graphName, node_attr={'shape':'record'}, format=renderType)
    d_graph.graph_attr['rankdir'] = 'LR'
    d_graph.graph_attr['overlap'] = 'false'
    d_graph.graph_attr['outputorder'] = 'edgesfirst'
    d_graph.node(rootNodeId, rootNodeLabel)
    return d_graph

Die Hauptaufgabe des Skripts besteht nun in der Konvertierung der BibTex-Einträge in Graph-Knoten.

def convertBibToGvWith(bib_db, gv_graph):
    keyword_color = generateKeyColor()
    keywords_builtin = ['none', 'unknown']
    keywords_custom = ['scheduling', 'multicore', 'safety', 'critical']
    keywords = keywords_builtin + keywords_custom

    # fixme list comprehension
    keywords_colored = {}
    for i in keywords:
        keywords_colored[i] = generateKeyColor()

    buildNodesOutOf(keywords, keywords_colored, gv_graph)

    for bib_entry in bib_db.entries:
        match = False
        gv_graph.node(bib_entry['id'], buildNodeLabelOutOf(bib_entry))
        if 'none' in bib_entry.get('keyword', 'none'):
            gv_graph.edge(keywords_builtin[0], bib_entry['id'],
                _attributes={'color':keywords_colored['none']})
            continue

        bib_entry_key = cleanUpString(bib_entry['keyword'])
        # fixme case insensitive check
        for keyword in keywords_custom:
            if keyword in bib_entry_key:
                match = True
                gv_graph.edge(keyword, bib_entry['id'],
                    _attributes={'color':keywords_colored[keyword]})

         if not match:
             gv_graph.edge(keywords_builtin[1], bib_entry['id'],
                    _attributes={'color':keywords_colored['unknown']})

Im Anschluss erfolgt noch das Speichern in einer Datei (z.B. .pdf).

gv_graph.render(output_file, view=view_output)

Ergebnis

Die folgende Abbildung zeigt eine beispielhafte Ausgabe. Hierbei ist das obige Skript noch erweibib2mmtert worden, um z.B. farbige Knoten für eine bessere Übersicht zu generieren.

bib2mm

Alle Arbeiten, welche keine Schlüsselworte enthalten werden als none klassifiziert. Alle Einträge welche Schlüsselworte enthalten, jedoch zu keinem gesuchten Schlüsselwort passen werden unter unknown zusammengefasst.

Darüber hinaus erlaubt das Skript auch Querbeziehungen (siehe z.B. scheduling und critical).

Fazit und Aussicht

In einem ersten Versuch hat sich herausgestellt, dass die Erstellung von MindMaps aus Bibtex-Dateien durchaus möglich ist. Der zu bewerkstelligende Aufwand ist, gemessen an dem ersten Entwurf des vorgestellten Skripts, sehr gering.

Es sind jedoch weitere Verbesserungen durchzuführen, wobei hier an erster Stelle die Übergabe der Suchbegriffe per Parameter oder Datei zu nennen ist (im Vergleich zur derzeitig fix implementierten keywords_custom Liste).

Darüber hinaus ist der derzeitig verwendete Bibtex-Parser nicht zum Verarbeiten von BibLaTeX-Dateien geeignet.