Ein Word Plugin für mathematische Assistenz

Werbung
Universität des Saarlandes
Naturwissenschaftlich-Technische Fakultät I
Fachrichtung Informatik
Bachelorarbeit
Ein Word Plugin für mathematische Assistenzsysteme
vorgelegt von
Thorsten Hey
am
30.03.2009
Angefertigt unter der Leitung von
Prof. Dr. Jörg Siekmann
Betreut von
Dipl.-Inform. Marc Wagner
Begutachtet von
Prof. Dr. Jörg Siekmann
Prof. Dr. Christoph Benzmüller
Eidesstattliche Erklärung
Ich erkläre hiermit an Eides Statt, dass ich die vorliegende Arbeit selbstständig verfasst und keine
anderen als die angegebenen Quellen und Hilfsmittel verwendet habe.
Statement under Oath
I confirm under oath that I have written this thesis on my own and that I have not used any other
media or materials than the ones referred to in this thesis.
Einverständniserklärung
Ich bin damit einverstanden, dass meine (bestandene) Arbeit in beiden Versionen in die Bibliothek der
Informatik aufgenommen und damit veröffentlicht wird.
Declaration of Consent
I agree to make both versions of my thesis (with a passing grade) accessible to the public by having
them added to the library of the Computer Science Department.
Saarbrücken,……………………………..
(Datum / Date)
………………………………………….
(Unterschrift / Signature)
Zusammenfassung
Die Weiterentwicklung mathematischer Assistenzsysteme in den letzten Jahren führt dazu, dass auch Benutzer ohne Expertenwissen die Dienste dieser
Systeme in ihrer gewohnten Umgebung nutzen möchten. In dieser Arbeit
wird zum ersten Mal ein Microsoft Word Plugin entwickelt, das eine generische Schnittstelle zu Dokumenten-basierten Diensten bereitstellt. Das Plugin
befähigt den Benutzer, ein Dokument durch ein mathematisches Assistenzsystem zu verizieren und etwaige Fehler durch das Plugin visualisieren zu
lassen. Ebenfalls erhält der Benutzer interaktive Unterstützung beim mathematischen Beweisen, beispielsweise indem auf Anfrage weitere Schritte automatisch in das Dokument eingefügt werden. Hierzu wird in dieser Arbeit das
neue ISO-zertizierte Dokumentenformat Oce Open XML zum ersten Mal
für die Verwaltung mathematischer Inhalte verwendet, so dass Berechnungen
und Diagnoseergebnisse von mathematischen Assistenzsystemen dynamisch
und inkrementell eingebunden werden können.
Danksagung
Ich möchte meinem Betreuer Marc Wagner für das Thema dieser Arbeit,
seine unermüdliche Unterstützung und die Geduld, die er für meine Fragen
aufbrachte, danken. Ausserdem will ich Herrn Prof. Siekmann für die angenehme und motivierende Arbeitsatmosphäre danken, die ich am Lehrstuhl
vorgefunden habe. Ich bedanke mich auch bei Marvin Schiller, der mich durch
Korrekturlesen und viele Anregungen beim Verfassen der Arbeit sehr unterstützt hat.
Ich möchte mich auch bei meiner Familie bedanken, die mir das Studium erst
ermöglicht hat.
Inhaltsverzeichnis
1 Einleitung
3
2 Architektur
5
2.1
Funktionsweise
. . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.2
Sessionverwaltung . . . . . . . . . . . . . . . . . . . . . . . . .
8
2.2.1
Timer
. . . . . . . . . . . . . . . . . . . . . . . . . . .
11
2.2.2
Kongurationsdatei . . . . . . . . . . . . . . . . . . . .
11
2.2.3
Kommunikation zwischen Plugin und Server
13
. . . . . .
3 Dokumentenverarbeitung
3.1
3.2
15
Dokumentenmodell . . . . . . . . . . . . . . . . . . . . . . . .
15
3.1.1
XML . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
3.1.2
Beispiel Dokument
. . . . . . . . . . . . . . . . . . . .
18
. . . . . . . . . . . . . . . . . . . .
21
Dokumente in Word 2007
3.2.1
Struktur eines Dokumentes . . . . . . . . . . . . . . . .
21
3.2.2
Repräsentation von Text und Formatierung
. . . . . .
22
3.2.3
Oce MathML (oMath)
. . . . . . . . . . . . . . . . .
24
3.3
Bereinigung eines Dokumentes . . . . . . . . . . . . . . . . . .
25
3.4
Annotation eines Dokumentes
29
3.5
. . . . . . . . . . . . . . . . . .
3.4.1
Annotationspfade . . . . . . . . . . . . . . . . . . . . .
31
3.4.2
Technik des Annotierens . . . . . . . . . . . . . . . . .
33
3.4.3
Anpassen eines Dokumentes und der Annotationspfade
34
3.4.4
Normalisieren einer Annotationsliste
. . . . . . . . . .
44
3.4.5
Einfügen von Annotation in ein Dokument . . . . . . .
45
Updaten eines Dokumentes . . . . . . . . . . . . . . . . . . . .
50
4 Interaktive Dienste
4.1
4.2
53
Kontext-Sensitive Menüs . . . . . . . . . . . . . . . . . . . . .
53
4.1.1
. . . . . . . . . . . . . . .
55
. . . . . . . . . . . . . . . . .
58
Anfragen von Menüinhalten
Ergebnisse interaktiver Dienste
1
INHALTSVERZEICHNIS
2
5 Verwandte Arbeiten
59
6 Zusammenfassung und Ausblick
61
Kapitel 1
Einleitung
Die enorme Weiterentwicklung mathematischer Assistenzsysteme in den letzten Jahren führt dazu, dass auch Benutzer ohne Expertenwissen solche Systeme bedienen möchten. Somit macht es Sinn als Eingabeschnittstelle ein
Textverarbeitungsprogramm zu wählen, das eine hohe Verbreitungsrate und
leichte Bedienbarkeit besitzt, um den Arbeitsaufwand zur Benutzung eines
mathematischen Assistenzsystems minimal zu halten.
Microsoft Word bietet eben diese Verbreitungsrate und Bedienbarkeit und
ist der Mehrzahl aller Benutzer bereits bekannt. Ein Benutzer kann so in
einer gewohnten Umgebung das Assistenzsystem verwenden, ohne zunächst
zusätzliche Spezialsoftware installieren zu müssen und sich mit der Bedienung dieser neuen Software auseinander zu setzen.
Wurde in bisherigen MS Word Textverarbeitungsprogrammen noch ein externer Formeleditor benötigt, so kann nun eine mathematische Umgebung
deniert werden und dort beliebige mathematische Formeln eingegeben werden. Dieser Umstand verringert den Arbeitsaufwand und wird von Microsoft
Word seit Version 2007 unterstützt.
Das Ziel dieser Arbeit ist es, ein Plugin für Microsoft Word zu entwickeln, um
eine nahtlose und benutzerfreundliche Integration der Dienste eines mathematischen Assistenzsystems zu ermöglichen. Eine Funktionalität des Plugins
ist es, ein Dokument von dem Assistenzsystem auf Korrektheit prüfen zu
lassen. Das Plugin erhält dabei von einem Server Informationen über Fehler
im Dokument, die es dann optisch kennzeichnet. Der Benutzer hat nun die
Möglichkeit seine Fehler zu analysieren. Bevor das Dokument wieder bearbeitet wird, werden diese Markierungen wieder entfernt.
3
KAPITEL 1.
EINLEITUNG
4
Eine weitere Funktionalität ist das Anfordern von Unterstützung. Ein Benutzer kann für eine bestimmte Stelle im Dokument den nächsten Schritt seiner
Beweisführung vom Assistenzsystem ermitteln lassen. Dies geschieht über
interaktive Menüs. Auf Anfrage werden dem Benutzer verschiedene Möglichkeiten für den nächsten Schritt in einem Menü angeboten.
Die Arbeit ist wie folgt gegliedert. Im zweiten Kapitel wird zunächst die
Verwaltung der Dokumente auf dem Server beschrieben. Insbesondere werden wir die Unterstützung multipler Dokumente und das Synchronisieren
der Dokumente mit dem Server erläutern. Im dritten Kapitel wird das Dokumentenmodell von Microsoft Word eingeführt, zusammen mit dem Markup mathematischer Formeln, genannt oMath. Auf dieser Grundlage werden
dann die Algorithmen zum Bereinigen des Dokumentes, zum Integrieren von
Fehlern und zum Einfügen von Änderungen in das Dokument entwickelt.
Im vierten Kapitel wird die Funktionsweise der interaktiven Menüs genauer
betrachtet, die benötigt werden, um Unterstützung für das Dokument anzufordern. Schliesslich geben wir einen Überblick über verwandte Arbeiten in
Kapitel fünf, bevor wir die Resultate dieser Arbeit in Kapitel sechs zusammenfassen.
Kapitel 2
Architektur
Die nahtlose und benutzerfreundliche Integration der Dienste eines mathematischen Assistenzsystems wird durch ein Erweiterungsmodul realisiert, das
die Schnittstellen der Microsoft Word Software verwendet, um MS Word so
um die gewünschten Funktionalitäten zu erweiteren. Dieses Erweiterungsmodul wollen wir im Folgenden Mediator Plugin nennen.
Bevor wir die Architektur des Mediator Plugins einführen, werden wir im
Folgenden die Funktionsweise des Plugins mit Hilfe eines Beispiels erläutern.
2.1
Funktionsweise
Ein Benutzer startet Microsoft Word mit aktivem Mediator Plugin und beginnt ein neues Dokument zu erstellen bzw. ein bereits vorhandenes Dokument zu bearbeiten. Ein solches Dokument zeigt Abbildung 2.1. Durch das
Starten des Plugins loggt der Benutzer sich auf einem Server für mathematische Assistenzdienste ein, wie etwa dem
Ωmega-System
[8]. Das Einloggen
kann anonym oder mit einem Account erfolgen. In beiden Fällen wird ein
Username, ein Passwort und die Adresse des Servers aus einer Kongurationsdatei geladen. Der Inhalt dieser Kongurationsdatei wird später kurz
erläutert.
Während der Bearbeitung des Dokumentes wird in regelmässigen Intervallen das Dokument zum Server geschickt. Hier werden die Änderungen des
Dokumentes erkannt. Der Server berechnet aus dem ihm aktuell übertragenen Dokument Metadaten, die bei einer Prüfung des Dokumentes durch den
Serverdienst entstehen und später an der entsprechenden Stelle im Doku-
5
KAPITEL 2.
ARCHITEKTUR
6
Abbildung 2.1: Dokument in Word vor dem Annotieren
ment eingefügt werden sollen. Diese Metadaten enthalten Informationen zu
bestimmten Textabschnitten, wie etwa Fehler oder verizierte Abschnitte.
Diese Metadaten wollen wir im Folgenden Annotationen nennen.
Die Länge des eben erwähnten Synchronisierungs-Intervalls wird aus einer
Kongurationsdatei geladen. Die Intervalllänge gibt an, in welchen Zeitabständen das Dokument zum Server übermittelt wird.
Der Benutzer hat während der Bearbeitung zwei Möglichkeiten mit dem Server zu interagieren. Zunächst kann er Hilfestellungen für das aktuelle Dokument anfordern, etwa wenn er bei einem mathematischen Beweis nicht mehr
weiter weiss. So wird dann von einem Serverdienst der nächste Schritt des
Beweises errechnet und durch ein Update in das aktive Dokument eingefügt.
Hierbei fordert der Benutzer zunächst ein Menü vom Server für genau die
Stelle im Dokument an, zu der er Hilfe benötigt. In diesem Menü bietet der
Server spezielle Hilfestellungen für diese Position. Nach Auswahl der Hilfe
werden Updates angefordert und in das aktive Dokument eingefügt.
Die zweite Möglichkeit der Interaktion zwischen Benutzer und Server ist das
Anfordern von Annotationen, also einer Überprüfung des aktuellen Doku-
KAPITEL 2.
7
ARCHITEKTUR
mentes, bei der z.B. Fehlermeldungen in das Dokument eingebunden werden.
Abbildung 2.2 zeigt ein annotiertes Dokument.
Abbildung 2.2: Dokument in Word nach dem Annotieren
Durch Betätigung des entsprechenden Buttons innerhalb des Menüs ruft der
Benutzer den Serverdienst
Prüfen
ab. Es wird zunächst das Dokument be-
reinigt, indem Teile des Dokumentes entfernt werden, die für die Dienste
des Servers nicht relevant sind. Nicht relevante Teile können beispielsweise Formatierungen wie Schriftfarbe, Fonts, aber auch Bilder, Tabellen oder
Schriftgrösse sein. Diese bereinigte Fassung wollen wir im Folgenden bereinigtes Dokument nennen. Somit beinhaltet das bereinigte Dokument nur für
die Berechnung der Annotationen relevante Informationen. Die zu erhaltenden Elemente können über eine Kongurationsdatei speziziert werden. Das
bereinigte Dokument wird nur an den Server verschickt und nicht dem Benutzer angezeigt.
Das Plugin erhält nun eine Annotationsliste, die in das Dokument eingebunden werden soll. Zunächst wird eine Sicherungskopie des aktiven Dokumentes
erzeugt, damit eine Version ohne Annotationen erhalten bleibt. Nach dem
Einbinden der Annotationen in das aktive Dokument wird die Benutzereingabe gesperrt. Das annotierte Dokument wollen wir im Folgenden temporäres Dokument nennen, da dieses nur temporär angezeigt wird und vom
KAPITEL 2.
ARCHITEKTUR
8
Benutzer nicht verändert werden kann. Der Benutzer kann nun seine Fehler analysieren. Um wieder zur Bearbeitung des Dokumentes zu gelangen,
kann ein Bearbeiten-Button betätigt werden. Hierfür wird nun das temporäre Dokument verworfen und die Sicherungskopie des Dokumentes als aktives
Dokument angezeigt.
Wir können somit die Varianten eines Dokumentes wie folgt klassizieren:
• Aktives Dokument:
Das geönete Dokument, dass sich im momentan ausgewählten Windows-Fenster bendet, bearbeitet werden kann, keine
Annotationen enthält, in das jedoch Updates eingefügt werden können.
• Bereinigtes Dokument:
Das Dokument, in dem nur zur Berechnung der Annotationen
relevante Objekte enthalten sind.
• Temporäres (annotiertes) Dokument:
Das Dokument, in dem die Annotationen des Servers eingebunden wurden und das nicht zur Bearbeitung freigegeben
ist.
Das Anfordern von Hilfe oder Annotationen kann beliebig oft wiederholt werden. Sollte der Benutzer nun seine Arbeit beenden wollen, muss er lediglich
MS Word schliessen. Der Logout erfolgt automatisch.
Die beschriebene Funktionsweise legt eine Aufteilung der Architektur in die
zwei Bereiche Sessionverwaltung und Dokumentenverarbeitung nahe. Die
Sessionverwaltung ist für den Login, Logout und die Verwaltung der Dokumente auf dem Server verantwortlich, die Dokumentenverarbeitung übernimmt das Annotieren und Updaten des Dokumentes.
2.2
Sessionverwaltung
Die Sessionverwaltung implementiert die Idee von multiplen Dokumenten.
Diese Idee hat ihren Ursprung darin, dass ein Benutzer mehrere Dokumente
während einer Arbeitssitzung bearbeiten möchte. Um mit mehreren Doku-
KAPITEL 2.
9
ARCHITEKTUR
menten gleichzeitig zu arbeiten, muss jedes Dokument eindeutig vom Server
identiziert werden können. Dies kann nur über eine eindeutige ID gelingen,
die jedem Dokument zugewiesen wird. Somit können die Forderungen an die
Sessionverwaltung wie folgt formuliert werden.
Forderung an die Sessionverwaltung
1.
Identizierung des Dokumentes
Kennzeichnen des Dokumentes um eine eindeutige Identikation auf Serverseite zu ermöglichen.
2.
Versionsverwaltung
Verwalten der Versionen eines Dokumentes um Änderungen
des Inhaltes leichter bestimmen und entsprechende Annotationen leichter berechnen zu können.
Im Folgenden wollen wir einige Ansätze zur Sessionverwaltung diskutieren.
Identikation über Inhalt
Das Berechnen der ID eines Dokumentes über seinen Inhalt liefert einen
wenig erfolgversprechenden Ansatz, denn der Inhalt eines Dokumentes kann
sich während einer Arbeitssitzung stark ändern. Dies kann sogar soweit gehen,
dass der Inhalt eines Dokumentes sich komplett verändert, da der Benutzer
den Inhalt löscht und mit einem neuen Inhalt füllt.
Identikation über Dateinamen
Ein weiterer Ansatz wäre das Identizieren über den Dateinamen. Doch leider führt auch dieser Ansatz bei genauerer Betrachtung ins Leere. Denn
ein Dateiname kann ebenfalls während einer Arbeitssitzung geändert werden, so zum Beispiel heisst ein neu erstelltes Dokument in MS Word 2007
standardmässig
Ohne-Titel.docx.
Der Benutzer wird beim Abspeichern des
Dokumentes sicherlich einen weitaus aussagekräftigeren Namen wählen. Wir
sehen also, dass auch Dateiname und Pfad nicht x sind und sich deshalb
ebensowenig zum Identizieren von Dokumenten eignen.
KAPITEL 2.
ARCHITEKTUR
10
Identikation über Dokumentvariable
Da die beiden intuitivsten Ansätze zu keinem befriedigenden Ergebnis führen würden, ist die naheliegendste Idee, jedem Element eine eindeutige ID
zuzuweisen, die vom Server generiert wird und erhalten bleibt. Diese ID wird
immer dann angefordert, wenn ein Dokument zum Server geschickt werden
soll und noch keine ID besitzt, also dem Server noch nicht bekannt ist. Diese
ID wollen wir im Folgenden PaperID nennen. Die PaperID wird mit Hilfe
einer Dokumentvariable an das Dokument gebunden.
Die Dokumentvariable in MS Word bietet die Möglichkeit Werte eines elementaren Datentyps (bool, int, oat etc.) an ein Dokument zu binden. Ein
Dokument kann beliebig viele dieser Dokumentvariablen besitzen, wobei jede über ihren Namen eindeutig identizierbar sein muss. Desweiteren können
solche Variablen ausgelesen und manipuliert werden.
Da ein Identizieren des Dokumentes möglich ist, können wir uns nun der
zweiten Forderung an die Sessionverwaltung widmen. Jedem Dokument soll
eine Versionsnummer zugewiesen werden. Diese Versionsnummer wird, wie
im einleitenden Beispiel erläutert, dazu genutzt, die Aktualität eines Dokumentes zu überprüfen. Auch diese Information wird wieder mittels Dokumentvariable an das entsprechende Dokument gebunden.
Es ist leicht zu sehen, dass eine PaperID pro Dokument nur einmal angefordert werden muss, da diese die ganze Arbeitssitzung hindurch erhalten
bleibt und sich nicht ändert. Eine Versionsnummer hingegen muss in regelmässigen Abständen aktualisiert werden und zwar immer dann, wenn ein
Dokument zum Server geschickt wird. Das kontinuierliche Synchronisieren
des Dokumentes mit dem Server ist deshalb sinnvoll, da so beim Annotieren
des Dokumentes nicht mehr das gesamte Dokument geparst werden muss,
um die Annotationsliste zu berechnen.
Das Assistenzsystem berechnet asynchron für die Version des Dokumentes
auf dem Server bereits vor dem Anfordern die Liste der Annotationen. So
verringert sich die Wartezeit von Seiten des Benutzers, da nur die Änderungen seit dem letzten Hochladen berücksichtigt werden müssen.
Das Updaten der Versionsnummer ist somit an das Hochladen des Dokumentes auf den Server gebunden und erfolgt in regelmässigen Intervallen, deren
Abstand in der Kongurationsdatei angegeben ist.
KAPITEL 2.
ARCHITEKTUR
11
2.2.1 Timer
Das regelmässige Hochladen des Dokumentes, wie in Kapitel 2.1 erläutert,
wird von einem Timer realisiert. Dieser Timer stellt somit den Motor der
Sessionverwaltung dar. Abbildung 2.3 beschreibt die Arbeitsweise des Timers
und somit das Verwalten der SessionID, der PaperIDs und der Versionsnummern.
Abbildung 2.3: Arbeitsweise Timer
Wie man in Abbildung 2.3 erkennen kann, wird eine PaperID nur dann angefordert, wenn das Dokument dem Server noch nicht bekannt ist. Das bedeutet im Einzelnen, dass eine PaperID für ein bestimmtes Dokument nur
dann angefordert wird, wenn an eben dieses Dokument per Dokumentvariable keine PaperID gebunden ist. In diesem Fall liefert der Server nach dem
Hinzufügen des Dokumentes (SOAP Kommando Add) in die Server-Session
des Benutzers eine PaperID und eine Versionsnummer zurück. Falls eine PaperID gefunden wurde, wird nach dem Synchronisieren (SOAP Kommando
Commit) nur eine neue Versionsnummer an das Dokument angehängt, die
vom Server zurückgeliefert wurde, und somit die veraltete Versionsnummer
ersetzt.
2.2.2 Kongurationsdatei
Die Kongurationsdatei des Mediator Plugins bietet die Möglichkeit Einstellungen zu verändern. Eine Standard Kongurationsdatei bendet sich im
KAPITEL 2.
12
ARCHITEKTUR
Installationsverzeichnis des Mediator Plugins. Diese Konguration wird benutzt, wenn keine benutzerspezische Kongurationsdatei im Homeverzeichnis des Benutzers gefunden wurde. Im Folgenden werden die zu steuernden
Einstellungen beschrieben, die die Kongurationsdatei beinhaltet.
• Farbcodes der einzelnen Annotationstypen
Standard:
error valid in progress ignore
rot
grün
orange
grau
Diese Liste kann komplett durch eigene Paare von Annotationstypen
und Farbcodes ersetzt werden.
• Logindaten des Benutzers
Standard:
Passwort Benutzername
anonym
anonym
• Zu erhaltende Objekte beim Bereinigen
Es werden die Objekte angegeben, die beim Bereinigen des Dokumentes nicht entfernt werden dürfen. Solche Objekte sind
<t>
<p> (Paragraph),
(Text), etc.
• Zu markierende Mathematische Markup-Objekte
Es werden die mathematischen Markup-Objekte angegeben, die beim
Annotieren automatisch mitgekennzeichnet werden sollen. Solche Objekte sind Klammern, Summenzeichen etc.
KAPITEL 2.
13
ARCHITEKTUR
2.2.3 Kommunikation zwischen Plugin und Server
Im einleitenden Beispiel dieses Kapitels wurde beschrieben, dass beim Starten von Microsoft Word, mit aktivem Mediator Plugin, ein automatischer
Login mit Logindaten aus der Kongurationsdatei durchgeführt wird. Desweiteren wurde erwähnt, dass während der Bearbeitung des Dokumentes eine
Kommunikation zwischen Plugin und Server besteht, in der das Dokument
auf dem Server synchronisiert wird. Wir wollen nun anhand des Message Sequence Chart in Abbildung 2.4 genauer auf diese Kommunikation eingehen.
Beim Start wird zunächst der Login ausgeführt, mit dem sich der Benutzer auf dem Server anmeldet und eine SessionID erhält. Hierzu schickt das
Plugin die Anmeldedaten zum Server, der bei erfolgreicher Anmeldung eine
SessionID zurückliefert.
Während des Synchronisierens wird, wie im einleitenden Beispiel beschrieben, das Dokument auf dem Server zur Session hinzugefügt, falls es noch
keine PaperID haben sollte. Dies wird von der Funktion
Add implementiert.
Die Add Funktion übermittelt die SessionID und den Inhalt des Dokumentes zum Server und liefert eine PaperID und eine Versionsnummer zurück,
die an das Dokument per Dokumentvariable gebunden werden. Falls schon
eine PaperID per Dokumentvariable an das Dokument angefügt worden ist,
wird ein Update der Versionsnummer ausgeführt. Das Updaten wird von der
Funktion
Commit
implementiert, die den Inhalt des Dokumentes, die da-
zugehörige PaperID, die ID der Session und die aktuelle Versionsnummer
zum Server übermittelt. Bei erfolgreichem Commit wird an das Plugin die
PaperID und eine neue Versionsnummer zurückgeliefert, mit der die an das
Dokument gebundene Versionsnummer überschrieben wird.
Die im einleitenden Beispiel erwähnte Interaktion zwischen Server und Plugin
beim Anfordern von Unterstützung über eine Menüinteraktion, sowie die
Integration von Fehlern durch Annotationen, werden in Abbildung 2.4 noch
nicht erwähnt. Wir wollen erst in Kapitel 4.2 dieser Arbeit auf diese Punkte
eingehen und dabei das Message Sequence Chart und den Timer entsprechend
erweitern.
KAPITEL 2.
ARCHITEKTUR
Abbildung 2.4: Kommunikation zwischen Plugin und Server
14
Kapitel 3
Dokumentenverarbeitung
In diesem Kapitel soll zunächst der Begri der eXtensible Markup Language
[11], kurz XML, geklärt werden, da dies die Basis des Microsoft Word Dokumentenmodells darstellt. Danach wollen wir das Dokumentenmodell von
Microsoft Word 2007 einführen und anhand dieses Modells die Techniken des
Bereinigens und des Annotierens vorstellen und erläutern.
3.1
Dokumentenmodell
Dokumente werden in Microsoft Word 2007 [7] in dem neuen Oce Open
XML Format [6] repräsentiert. Hierbei handelt es sich um einen oenen Standard für XML-basierte Dateiformate zur Speicherung von Bürodokumenten,
der den Daten- und Dateienaustausch zwischen verschiedenen Büroanwendungspaketen ermöglichen soll. Oce Open XML wurde mittlerweile von
der Normierungsorganisation ECMA international [3] ratiziert und ist als
ISO-Standard [4] anerkannt.
Das Abspeichern der Dokumente in diesem Format bietet einige Vorteile, die
später genauer betrachtet werden sollen. Zunächst einmal soll der Begri des
XML Formats eingeführt werden.
3.1.1 XML
eXtensible Markup Language, kurz XML, ist eine Auszeichnungssprache, die
die Möglichkeit bietet, hierarchisch strukturierte Daten in Form von Textdateien abzuspeichern. Aber nicht nur zum Abspeichern hierarchischer Daten
wird XML benutzt, sondern auch zum Austausch von Daten zwischen Computersystemen.
15
KAPITEL 3.
16
DOKUMENTENVERARBEITUNG
Aufbau
Ein XML Dokument ist eine hierarchisch organisierte Textdatei. Die einzelnen Elemente dieser Hierarchie werden als Tags oder Knoten bezeichnet.
Eine Baumstruktur gibt die Hierarchie zwischen den einzelnen Elementen an.
Ein Knoten in dieser Hierarchie ist von der Form
<name>,
wobei
name1
den
Namen des Knotens angibt. Ein Knoten kann einen beliebigen Namen tragen
wie z.B.
<color>.
Die Menge der Namen aller Knoten innerhalb eines Do-
kumentes wird dann als das Vokabular oder Sprache bezeichnet. Ein Knoten
kann neben seinem Namen noch zusätzliche Informationen tragen. Diese Informationen werden Attribute eines Knotens genannt. Diese Attribute spezizieren den Knoten genauer. Ein mögliches Attribut für unseren color-Knoten
könnte
<color val='FF0000'>
sein. Dieses zusätzliche Attribut würde die
Farbe als rot spezizieren.
Nun da wir den Begri des Knotens eingeführt haben, soll auf die Hierarchie
der Knoten innerhalb des Dokumentes eingegangen werden.
Vater
Ein Knoten, der innerhalb der Hierarchie direkt über
einem Knoten steht, ist dessen Vater. Jeder Knoten kann
Vorfahre
maximal einen Vater besitzen.
Als Vorfahren eines Knotens bezeichnet man die Knoten, die über ihm in der Hierarchie stehen und die Väter
Kinder
Nachfahre
Geschwister
seiner Väter sind.
Knoten, die innerhalb der Hierarchie direkt unter einem
Knoten stehen, sind die Kinder dieses Knotens.
Knoten, die in der Hierarchie unter einem Knoten stehen, werden als dessen Nachfahren bezeichnet.
Knoten, die auf der gleichen Ebene der Hierarchie sind
und einen gemeinsamen Vater haben, werden Geschwister genannt.
Man kann also sagen, dass die Ebene der direkten Nachfahren eines Knotens
dessen Kinder sind. Vater eines Knotens ist der Knoten, der nicht nur in der
Hierarchie über ihm steht, sondern auch diesen Knoten als Kind besitzt.
1 Wir
werden später den Begri Knotentyp für alle Knoten mit dem gleichen Namen
verwenden.
KAPITEL 3.
17
DOKUMENTENVERARBEITUNG
Aus den Begrisdenitionen kann man die Hierarchie innerhalb eines XML
Dokumentes wie folgt formulieren. Ein Knoten kann höchstens einen Vater
aber beliebig viele Kinder besitzen. Somit kann es nur einen Knoten an der
Spitze der Hierarchie geben, der mit seinen Nachfolgern das XML Dokument
darstellt. Dieser Knoten wird Wurzelknoten genannt und besitzt keinen Vater und somit auch keine Vorfahren. Jeder Knoten, ausser der Wurzel selbst,
ist Nachfahre des Wurzelknotens. Abbildung 3.1 soll den Zusammenhang
zwischen Kindern, Nachfahren sowie Vater, Vorfahren und Geschwistern verdeutlichen.
Abbildung 3.1: Beziehungen innerhalb der Hierarchie
Um aber eine Hierarchie innerhalb einer linearen Textdatei darzustellen, muss
eine Schachtelung der einzelnen Knoten erfolgen. So können durch die verschiedenen Ebenen der Schachtelung die verschiedenen Ebenen der Hierarchie
dargestellt werden. Um diese Schachtelung zu realisieren muss jeder Knoten
ein önendes Tag und ein schliessendes Tag besitzen.
Zwischen önenden
KAPITEL 3.
18
DOKUMENTENVERARBEITUNG
und schliessenden Tags werden die Kinder des Knotens angegeben 2 .
Da die
Kinder eines Knotens selbst wieder Kinder besitzen können, kann durch diese
rekursive Denition eine beliebige Hierarchie dargestellt werden. Ein schliessender Tag ist von der Form
</name>.
Hierbei gibt
name
den Namen des
Knotens an, der schon beim önenden Tag benutzt wurde, wie in Listing 3.1
zu erkennen ist. Ein schliessender Tag eines Knotens kann keine Attribute
besitzen. In Listing 3.1 wird eine lineare Darstellung eines XML Dokumentes
angegeben. Um die Hierarchie besser erkennen zu können wird dieses Dokument in Abbildung 3.2 als Baum dargestellt.
Als Pfad zu einem Knoten bezeichnet man den Weg durch den Baum von
der Wurzel an bis zu diesem Knoten. Mit Hilfe des Pfades kann man also
einen Knoten innerhalb eines XML Dokumentes eindeutig bestimmen. Der
Pfad setzt sich aus den Namen der Knoten zusammen, die auf dem Weg
dorthin besucht werden müssen. Die Namen der einzelnen Knoten werden
durch
/
voneinander getrennt. Ein Pfad beginnt immer mit einem
/.
Da ein
Knoten mehr als ein Kind mit demselben Namen besitzen kann, nummeriert
man alle Geschwister mit demselben Name fortlaufend, angefangen bei 1 und
von links nach rechts. Dies wird für alle Kinder aller Väter gemacht. Da die
Wurzel keinen Vater besitzt und auch keine Geschwister hat, erhält sie die
Nummer
1.
Die Nummer wird in eckigen Klammern hinter dem Namen des
entsprechenden Kindes angebracht. Der Pfad zum ersten r-Knoten im zweiten Paragraphen des Listings 3.1 wäre dann
/w:body[1]/w:p[2]/w:r[1].
Hiermit haben wir den Pfad innerhalb einer XML-Datei gemäss dem xPathStandard [10] eingeführt.
Ausserdem wollen wir den Begri des Teilpfades (Subpath) und des echten
Teilpfades (real Subpath) einführen. Pfad A ist ein Teilpfad von B, genau
dann wenn A der Pfad zu einem Vorfahren von B ist oder beide Pfade identisch sind. Pfad A ist ein echter Teilpfad von B, genau dann wenn A der Pfad
zu einem Vorfahren von B ist und beide Pfade verschieden sind.
3.1.2 Beispiel Dokument
Im folgenden Beispiel sehen wir eine XML Datei, die den Inhalt und auch
die Struktur eines Microsoft Word Dokumentes angibt.
2 Wir wollen im Folgenden Knoten ohne Kinder xNodes nennen und Knoten mit Kindern
xElements.
KAPITEL 3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
DOKUMENTENVERARBEITUNG
<w : body >
<w :p >
<w :r >
<w : rPr >
<w : col val = '00 FF00 '>
</w: rPr >
<w :t > Erster Absatz eines Textdokumentes </w:t >
</w:r >
</w:p >
<w :p >
<w :r >
<w : rPr >
<w : col val =' FF0000 '>
</i >
</u >
</b >
</w: rPr >
<w :t > Zweiter Absatz eines Textdokumentes </w:t >
</w:r >
</w:p >
:
:
:
<w :p >
<w :r >
<w :t > letzte Zeile eines Textdokumentes </w:t >
</w:r >
<w :p/>
</w: body >
Listing 3.1: Lineare Darstellung einer XML Datei
In Abbildung 3.1 wurden folgende Tags verwendet.
• <w:body>
bildet den Wurzelknoten.
• <w:p>
stellt einen Paragraph dar.
• <w:r>
stellt den Inhalt eines Paragraphs dar.
• <w:rPr>
• <w:t>
enthält die Formatierung als Kinder.
beinhaltet Text.
• <w:col>
setzt eine Farbe.
• <i>
setzt Text kursiv
• <u>
setzt Text unterstrichen.
• <b>
setzt Text fett.
19
KAPITEL 3.
DOKUMENTENVERARBEITUNG
20
Abbildung 3.2: Hierarchische Baumstruktur des Dokumentes
Namespace
Um sicher zu gehen, dass es bei Überschneidungen mit einem anderen Vokabular zu keinen Doppeldeutigkeiten kommt, wird ein so genannter Namespace
oder Namensraum eingeführt. Dieser Namespace wird genutzt, um in einem
Dokument mehrere XML Sprachen zu mischen.
Ein Namespace wird durch eine URI angegeben. Unter der angegebenen URI
sollte dann eine Dokumenttyp-Denition (DTD) oder ein XML-Schema stehen. Eine DTD ist ein Satz an Regeln, der benutzt wird, um die Grammatik
eines Dokumentes zu denieren. Ein XML-Schema ist eine Empfehlung des
W3C zum Denieren von Strukturen für XML-Dokumente. Zusätzlich zum
Namespace existiert ein Präx-Mechanismus, der es erlaubt, Elemente durch
eine Zeichenkette, die vom Elementnamen durch einen Doppelpunkt getrennt
wird, in den jeweiligen Namespace zu setzen. In Listing 3.1 wird der Präx
w benutzt, der wie beschrieben durch einen Doppelpunkt vom Namen des
Knotens getrennt ist.
Der Präx
w
wird für das Vokabular der Oce Open XML Sprache benutzt.
Im Folgenden wird der Oce Open XML Standard genauer erläutert.
KAPITEL 3.
3.2
21
DOKUMENTENVERARBEITUNG
Dokumente in Word 2007
Mit der neusten Microsoft Word Version 2007 hat sich das Dateiformat der
Word Dokumente grundlegend geändert. War das Dokumentenformat früher
proprietär, so basiert das neue Word Dokumentenformat auf
Dokumentenformat wird
XML.
Dieses
Oce Open XML genannt. Die Umstellung verbes-
sert die Interoperabilität enorm, da sich das Bearbeiten der Dokumente nun
auf das Manipulieren von XML-Dateien reduziert.
3.2.1 Struktur eines Dokumentes
Eine Datei mit der Endung .docx stellt nichts anderes als ein komprimiertes
Archiv von XML Dateien dar. Das eigentliche Dokument besteht also aus
drei Unterordnern, die jeweils mehrere XML-Dateien enthalten. Eine übergeordnete XML-Datei führt die einzelnen, in den Unterordnern liegenden,
Dateien zu einem einzigen Word Dokument zusammen. Abbildung 3.3 zeigt
den Inhalt des Archivs.
Abbildung 3.3: Inhalt der .docx Datei
Das Dokument wird in Partknoten unterteilt.
[Content_Types].xml
fügt
letztendlich die Dateien im Archiv zum eigentlichen Word Dokument zusammen. Jeder Partknoten stellt somit eine eigene XML-Datei innerhalb des
Archivs dar, die zusammen das komplette Word Dokument ergeben. Jeder
Partknoten ist von der Form
but
name
<part name=`` type=''/>,
wobei das Attri-
den relativen Pfad zur referenzierten Datei innerhalb des Archives
beinhaltet. In Abbildung 3.4 sehen wir die komplette XML-Darstellung eines
Word Dokumentes.
Im Rahmen dieser Arbeit sind jedoch nur zwei Partknoten relevant. Zum
einen
document.xml,
der den Body, also den Inhalt eines Dokumentes dar-
stellt und zum anderen
comments.xml,
da dieser Knoten die vom Plugin
erzeugten Kommentare beinhalten wird. Alle weiteren Parts des Dokumentes enthalten Randinformationen wie etwa den Name des Autors oder Themes des Dokumentes. Da diese weiteren Partknoten nur Randinformationen
enthalten, haben sie keine Bedeutung für das Plugin und wurden nur der
KAPITEL 3.
DOKUMENTENVERARBEITUNG
22
Abbildung 3.4: Inhalt der Datei [Content_Types].xml
Vollständigkeit wegen in Abbildung 3.4 aufgeführt.
Der Partknoten, der die Datei
ten
<document>.
document.xml
einbindet, beinhaltet den Kno-
Dieser Knoten enthält den tatsächlichen Dokumentkörper.
Hier wird nicht nur der Inhalt, sondern auch die Formatierung des Textes
abgespeichert, wie wir im Folgenden sehen werden.
3.2.2 Repräsentation von Text und Formatierung
Ein Text wird im .docx Format als ein XML-Knoten realisiert, der den von
ihm darzustellenden Text enthält. Dies haben wir bereits im Beispiel Dokument zum Aufbau einer XML Datei gesehen.
Ein Textknoten gehört jeweils zu einem Paragraphen, der einen übergeordneten Knoten darstellt. Um zu verstehen, wie Formatierungen angebracht
werden, muss gesagt werden, dass der Paragraphknoten, der einen Absatz
darstellt, nicht der direkte Vaterknoten eines Textknotens ist.
Zwischen Text und Paragraph bendet sich ein r-Knoten, dessen erstes Kind
die Formatierung des Textes angibt und dessen zweites Kind der Text selbst
ist. Ein rPr-Knoten beinhaltet diese Formatierung. Ein r-Knoten muss nicht
zwei Kinder besitzen, da es sein kann, dass ein Text keine besondere Formatierung besitzt. Sollte dies der Fall sein, ist der Textknoten das einzige
Kind des r-Knotens und als Formatierung wird eine globale Formatierung benutzt, die nicht als Formatierung jedes einzelnen Textknotens abgespeichert
wird, sondern einmal für das gesamte Dokument zu Beginn deniert wurde.
KAPITEL 3.
23
DOKUMENTENVERARBEITUNG
Abbildung 3.5 zeigt die Struktur einer lokalen Formatierung innerhalb eines
Paragraphen, Abbildung 3.6 zeigt den Inhalt dieser Formatierung im Detail.
Abbildung 3.5: Paragraph mit Text und Formatierung
Als Formatierung kann jedes beliebige Tag, das eine Formatierung angibt,
wie etwa bold, italic, color etc. an den rPr-Knoten angebracht werden. Abbildung 3.6 zeigt die Beispielformatierung mit fett, kursiv und unterstrichen.
Ein Dokument kann aus beliebig vielen Paragraphen bestehen, die letztendlich den Text des Dokumentes mit Formatierung enthalten. Diese Paragraphknoten sind Kinder des Bodyknotens, der die Wurzel des Dokumentes darstellt.
Abbildung 3.6: Lokale Formatierung eines Textknotens
Ein besonderes Element in diesem Baum ist das
<m:oMath>
Element, das
benutzt wird, um Formeln in Word 2007 darzustellen. Auch diese oMath
Elemente werden als Kinder an einen Paragraphen angehängt um in eben
diesem Paragraph eine Formel oder ein mathematisches Element darzustellen. Wie dies geschieht wollen wir im Folgenden genauer betrachten.
KAPITEL 3.
DOKUMENTENVERARBEITUNG
24
3.2.3 Oce MathML (oMath)
Um Innerhalb des Oce Open XML Formats mathematische Formeln darstellen zu können, wird das Vokabular des Dokumentes um das Vokabular
der Oce MathML(oMath) [6] Sprache erweitert. Die zur oMath-Sprache
gehörenden Knoten wollen wir im Folgenden oMath Elemente nennen.
Wie wir schon zu Beginn des Kapitels gesehen haben, kommt es zu Überschneidungen des oMath- und des Oce Open XML Vokabulars. Um Konikte zu vermeiden, wird ein neuer Namespace eingeführt. Der Präx des
oMath Vokabulars wird mit m bezeichnet. Ein Beispiel für solch eine Überschneidung ist etwa ein Text, der keine mathematischen Zeichen enthält, aber
dennoch in einer oMath Umgebung geschrieben wurde. Die Textknoten einer
<m:t> bezeichnet, die eines Textes ausserhalb
<w:t>.
oMath Umgebung werden mit
einer oMath Umgebung mit
Eine oMath Umgebung kann als Kind eines Paragraphen angebracht werden
oder selbst einen Paragraphen denieren. Eine oMath Umgebung, die selbst
<oMathPara> deniert werden. Dieser Knoden Paragraphknoten <w:p>. Jede oMath Umgebung wird
<m:oMath> eingeleitet.
Paragraphen deniert, muss mit
ten ersetzt dann
mit dem Knoten
Aufgrund des grossen oMath Vokabulars kann hier keine vollständige Liste
angegeben werden. Zwei Beispiele sollen jedoch die Struktur von oMath beschreiben.
Das erste Beispiel zeigt den Body eines Dokumentes, das nur einen Paragraphen besitzt, der ausschliesslich oMath Elemente enthält. Daher wird der
Paragraph nicht als
<w:p>
angegeben, sondern als <m:oMathPara>. Als In3
eingetragen.
4
halt dieses Paragraphens ist der Bruch
1 <w : body >
2
<m : oMathPara >
3
<m : oMath >
4
<m :f >
5
<m : num >
6
<m :r >
7
<m :t >3 </ m:t >
8
</m:r >
9
</m: num >
10
<m : den >
11
<m :r >
12
<m :t >4 </ m:t >
13
</m:r >
14
</m: den >
15
</m:f >
KAPITEL 3.
DOKUMENTENVERARBEITUNG
25
16
</m: oMath >
17
</m: oMathPara >
18 </w: body >
Listing 3.2: Dokument mit Bruch
Das zweite Beispiel enthält oMath Elemente und Oce Open XML Elemente,
die zusammen in einem einzigen Paragraphen stehen. Die oMath Umgebung
enthält den Text
a+b=c,
wobei
a+b
rot eingefärbt ist. Nach der oMath
Umgebung folgt der Textknoten in Oce Open XML.
1 <w : body >
2
<w :p >
3
<m : oMath >
4
<m :r >
5
<w : rPr >
6
</m: col val =' FF0000 '>
7
</w: rPr >
8
<m :t >a+b </ m:t >
9
</m:r >
10
<m :r >
11
<m :t >= b </ m:t >
12
</m:r >
13
</m: oMath >
14
<w :r >
15
<w :t > Ein kurzer Text </ w:t >
16
</w:r >
17
</w:p >
18 </w: body >
Listing 3.3: Dokument mit Text und Formel
3.3
Bereinigung eines Dokumentes
In der Einleitung des Kapitels Architektur wurde anhand eines Beispiels die
Funktionsweise des Plugins erläutert, wobei das Bereinigen des Dokumentes
vor dem Upload zum Server erfolgt. Das Bereinigen stellt eine Funktion dar,
die das Dokument zum Upload vorbereitet. Dies bedeutet, dass das Bereinigen es ermöglicht, eine Teilmenge des Dokumentenmodells über eine Kongurationsdatei zu denieren, um das Dokument von irrelevanten Objekten
zu befreien.
Denition irrelevante Objekte
Als irrelevante Objekte werden Knoten betrachtet, die vom Server
nicht zur Bereitstellung von Dokumentendiensten benötigt werden.
KAPITEL 3.
DOKUMENTENVERARBEITUNG
26
Knoten, die Formatierungen wie etwa Färbung enthalten, sind eben solche
irrelevanten Objekte.
Ein wichtiges Problem stellt sich dennoch. Da die Formatierungen später
wieder im temporären Dokument erhalten sein sollen, darf sich die Struktur
des Dokuments durch das Bereinigen nicht ändern. Das temporäre Dokument
wird mit Hilfe einer Sicherungskopie des aktuellen Dokumentes erstellt und
beinhaltet so wieder die benutzerspezischen Formatierungen, zu denen dann
die Annotationen hinzugefügt werden. Da diese aber im hochgeladenen, bereinigten Dokument entfernt wurden, würde eine Änderung der Baumstruktur
durch das Bereinigen zu einer Annotation führen, die im besten Falle an der
falschen Position steht und im ungünstigsten Falle einen Knoten annotiert,
der so gar nicht existiert. Daher wird folgende Forderung an das Bereinigen
gestellt.
Forderung an das Bereinigen
Durch das Entfernen irrelevanter Objekte darf die Struktur des Dokumentes nicht verletzt werden.
Um zu erläutern, wieso das Entfernen von Formatierung nicht die Struktur
verletzen kann, muss man zunächst einmal wissen, wie solche Formatierungsinformationen repräsentiert werden. Abbildung 3.7 zeigt ein Dokument, das
zwei Zeilen besitzt. In der ersten Zeile wurde der Text ab einem bestimmten
Buchstaben bis zum Ende der Zeile gefärbt. Die zweite Zeile ist ohne jegliche
Formatierung. Abbildung 3.8 zeigt das gleiche Dokument ohne die Formatierung.
Wie in Abbildung 3.8 zu erkennen ist, führt das Entfernen von Formatierungen zu einem Dokument, bei dem die Pfade vom Body-Knoten zu den
Textknoten erhalten bleiben. In unserem Beispiel ist der Pfad zum zweiten
Textknoten vor dem Bereinigen /w:body[1]/w:p[1]/w:r[1]/w:t[1]. Dieser Pfad
ist nach dem Bereinigen immer noch gültig und führt zum gleichen Knoten.
Das diese Pfade erhalten bleiben und immer noch auf den gleichen Knoten
referenzieren, hat im wesentlichen drei Gründe.
1. Ein Teilbaum, der einen rPr-Knoten als Wurzel besitzt, enthält nur
irrelevante Objekte. Somit führt das Löschen dieses Teilbaums nicht
zum Verlust von für die Serverdienste benötigter Objekte innerhalb
des XML-Dokumentes.
2. Ein Teilbaum mit irrelevanten Objekten enthält keine relevanten Ob-
KAPITEL 3.
DOKUMENTENVERARBEITUNG
27
Abbildung 3.7: Dokument mit Formatierung
Abbildung 3.8: Dokument ohne Formatierung
jekte. Konkret ist die Formatierungsinformation ein Geschwisterknoten
eines Textknotens und nicht dessen Vaterknoten. Daher bleibt der Pfad
zu einem Textknoten beim Entfernen dieses Knotens erhalten.
KAPITEL 3.
DOKUMENTENVERARBEITUNG
28
3. Wenn ein Knoten erhalten bleibt, dann auch alle gleichnamigen Geschwisterknoten. Da die Pfade relative Pfade zum Vaterknoten sind,
bleibt durch den Erhalt der gleichnamigen Geschwister der relative Pfad
aller relevanten Objekte erhalten.
Da nun klar ist, dass die Forderung an das Bereinigen nicht verletzt wird,
kann der Algorithmus des Bereinigens nun wie folgt realisiert werden.
Algorithmus Bereinigen
Das Bereinigen wird in einem Algorithmus beschrieben, der den Body-Knoten
des Dokumentes als Parameter erhält. Um zu entscheiden, welche Kinder des
Body-Knotens erhalten bleiben sollen, wird eine Sammlung von Knotentypen aus der Kongurationsdatei geladen. Anhand dieser Knoten entscheidet
der Algorithmus ob ein gegebener Knoten im Dokument bleibt oder nicht.
Ein Knoten soll genau dann im Dokument verweilen, wenn dieser Knotentyp
auch in der Knotensammlung vorhanden ist. Die Sammlung von zu erhaltenden Knotentypen kann über die Kongurationsdatei erweitert werden. Somit
ist eine einfache Erweiterbarkeit des Plugins gewährleistet.
Die Bereinigungsprozedur erzeugt also einen Body-Knoten, der keine Formatierungsinformationen im Sinne von Färbungen oder Ähnlichem enthält. Die
Struktur bleibt jedoch bestehen, sodass Absätze oder Einrückungen erhalten
bleiben. Dieser Umstand beruht auf der Tatsache, dass Formatierungen, wie
etwa ein Absatz, durch die Struktur des Dokumentes entstehen und nicht
durch zusätzliche Informationen innerhalb der Knoten eines Baumes repräsentiert werden.
node
= Wurzel des Teilbaums, der bereinigt werden soll
1 Method
bereinige ( node )
2
If | children ( node )| > 0 {
3
For each child in children ( node ) do
4
If name ( child ) ∈ bereinigenmarkup ( config ) {
5
bereinige ( child );
6
} else {
7
delete ( child );
8
};
9
Next ;
10
};
11 End Method
Listing 3.4: Entfernt nicht relevante Knoten
KAPITEL 3.
3.4
DOKUMENTENVERARBEITUNG
29
Annotation eines Dokumentes
Im Fallbeispiel in Kapitel 2.1 wurde das Dokument nach dem Bereinigen an
den Server verschickt. Im weiteren Verlauf werden Annotationen zum Mediator Plugin zurückgeliefert, die in das aktive Dokument eingefügt werden
sollen. Die Annotationen dienen zur Visualisierung von semantischen Statusinformationen und Fehlermeldungen zu Dokumentteilen. Das aktive Dokument stellt zusammen mit den eingefügten Annotationen das temporäre
Dokument dar.
Denition Annotation:
Eine Annotation besitzt folgende Parameter
•
Anfangspfad:
Ein xPath, der den Beginn der Annotation im Dokument angibt.
•
Endpfad:
Ein xPath, der das Ende der Annotation im Dokument angibt.
•
Annotationstyp:
Stellt einen in der Kongurationsdatei vordenierten Typ dar,
der die Färbung der Annotation angibt.
•
Beschreibung:
Ein String, der eine anzuzeigende Information beinhaltet.
Wir wollen nun zunächst den Begri des Annotationspfades und der Abdeckung einführen. Hierbei wollen wir Anfangs- und Endpfad einer Annotation
als Annotationspfade dieser Annotation bezeichnen.
Denition gültige Annotationspfade:
•
Die von Anfangs- und Endpfad referenzierten Knoten müssen im Dokument existieren. Diese Knoten wollen wir Anfangs- und Endknoten
nennen.
•
Der Endknoten darf kein Nachfahre des Anfangsknoten sein und umgekehrt. Anfangs- und Endknoten dürfen jedoch identisch sein, solange
es nicht der Body-Knoten ist.
KAPITEL 3.
•
DOKUMENTENVERARBEITUNG
30
Die durch den Anfangs- und Endpfad angegebene Abdeckung der Annotation darf nicht leer sein.
Denition Abdeckung:
Wenn wir jedes Zeichen eines Textknotens als dessen Kind-Knoten betrachten, so können wir die Abdeckung einer Annotation wie folgt denieren. Die
Abdeckung einer Annotation ist eine Menge von Knoten des aktiven Dokumentes. Die Berechnung dieser Menge wird durch folgenden Algorithmus
beschrieben. Der Aufruf der Funktion getAbdeckung erfolgt mit dem BodyKnoten als node, der Annotation, für die die Abdeckung berechnet werden
soll, als anno und mit mode=false. Die Funktion A is SubPath of B prüft,
ob A der Pfad eines Vorfahren von B ist.
node = Betrachteter Teilbaum
annno = Annotation deren Abdekcung gesucht wird
mode = Gibt an, ob Anfangspfad bereits gefunden wurde
1 Function getAbdeckung ( node , anno , mode )
2
abdeckung = {};
3
For each child in children ( node ) do {
4
aktuPath = pfad ( node );
5
If mode {
6
If aktuPath = endpfad ( anno ) {
7
abdeckung = abdeckung ∪ { child };
8
abdeckung = abdeckung ∪ descendants ( child );
9
Return abdeckung ;
10
} else {
11
If aktuPath is SubPath of endpfad ( anno ) {
12
abdeckung = abdeckung ∪ getAbdeckung ( child , anno , true );
13
Return abdeckung ;
14
} else {
15
abdeckung = abdeckung ∪ { child };
16
abdeckung = abdeckung ∪ descendants ( child );
17
};
18
};
19
} else {
20
If aktuPath = anfangspfad ( anno ) {
21
abdeckung = abdeckung ∪ { child };
22
abdeckung = abdeckung ∪ descendants ( child );
23
mode = true ;
24
} else {
25
If aktuPath is SubPath of anfangspfad ( anno ) {
26
abdeckung = abdeckung ∪ getAbdeckung ( child , anno , false );
27
};
28
};
29
};
30
Next ;
31
Return abdeckung ;
32 End Function
Listing 3.5: Abdeckung einer Annotation
3
Da wir nun wissen wann einzelne Annotationen
3 Annotationspfade,
korrekt sind, wollen wir im
die auf ein Zeichen innerhalb eines Textknotens verweisen besitzen
KAPITEL 3.
31
DOKUMENTENVERARBEITUNG
Folgenden betrachten, wann eine Menge von Annotationen korrekt ist.
Denition Menge von Annotationen:
•
Anfangs- und Endpfad jeder Annotation müssen gültige Annotationspfade sein.
•
Die Abdeckungen der einzelnen Annotationen müssen paarweise disjunkt sein.
Verschiedene Annotationsarten werden durch verschiedene Farben dargestellt. Diese Farbcodes werden aus der Kongurationsdatei geladen und können, ebenso wie die Knotentypen, somit leicht erweitert oder verändert werden. Es werden die Knoten, die in der Abdeckung der entsprechenden Annotation liegen, annotiert.
3.4.1 Annotationspfade
Ein Pfad zu einer Annotation ist nicht zwingend fest vorgeschrieben. Ein
Knoten kann auf verschiedenen Pfaden annotiert werden. Zwar ist der Pfad
des Knotens innerhalb des Dokumentes eindeutig, doch gibt es mehrere Möglichkeiten Annotation so einzufügen, dass in allen Fällen das gleiche Ergebnis
vorliegt. Dies ist nicht wirklich ein Problem, doch muss der Annotationsalgorithmus so konzipiert sein, dass er - egal wie der Annotationspfad vorliegt
- auch das gewünschte Ergebnis erzeugt. Abbildung 3.9 zeigt einen Paragraphen, der nur einen Textknoten beinhaltet. Anhand dieses Beispiels, soll
der Sachverhalt der verschiedenen Annotationspfade im Folgenden erläutert
werden.
Die Abbildung 3.9 beinhaltet nur einen Absatz, in dem der Text
Ein Beispiel
steht. Nehmen wir an, die vom Server zurückgelieferte Annotationsliste beinhaltet nur eine Annotation. In dieser Annotation soll der gesamte Text rot
gefärbt werden. Der Anfangs- und Endpfad könnte nun auf vier verschiedene
Arten angegeben werden:
den Sux .../w:t[m]/text[1]/char[n]. Hierbei geben /text[1] und char[n] keinen Knoten
innerhalb des Dokumentes an, sondern verweisen auf eine Zeichenkette und die Position
eines Zeichens innerhalb dieser Zeichenkette. Dies stellt eine kanonische Erweiterung des
xPath-Standards dar.
KAPITEL 3.
DOKUMENTENVERARBEITUNG
32
Abbildung 3.9: Dokument mit einem Paragaphen
1. Anfangspfad: /w:body[1]/w:p[1]/w:r[1]/text[1]/char[1]
Endpfad: /w:body[1]/w:p[1]/w:r[1]/text[1]/char[12]
2. Anfangspfad: /w:body[1]/w:p[1]/w:r[1]/text[1]/
Endpfad: /w:body[1]/w:p[1]/w:r[1]/text[1]/
3. Anfangspfad: /w:body[1]/w:p[1]/w:r[1]/
Endpfad: /w:body[1]/w:p[1]/w:r[1]/
4. Anfangspfad: /w:body[1]/w:p[1]/
Endpfad: /w:body[1]/w:p[1]/
Alle vier verschiedenen Annotationspfade würden das gleiche Resultat liefern, da sie die gleiche Annotation angeben. Man sieht also leicht, dass zwar
jeder Knoten eindeutig über seinen Pfad bestimmt werden kann, doch Annotationen auf verschiedene Weise angegeben werden können.
Eine erwünschte Eigenschaft der Annotation ist, dass sich keine Annotationen überlappen, es kann also kein Knoten des Dokumentes von zwei verschiedenen Annotationen formatiert werden. Dies macht auch keinen Sinn,
da z.B. ein Textabschnitt nicht gleichzeitig richtig und falsch sein kann und
jede folgende Annotation auf demselben Knoten wieder die vorherige aufheben würde.
KAPITEL 3.
DOKUMENTENVERARBEITUNG
33
Aber auch aus Sicht der Struktur des Dokumentes würde es zu Problemen
kommen. Diese Problematik basiert auf der Tatsache, dass ein von der Annotation veränderter Textknoten nicht mehr den gleichen Pfad im Dokument
besitzen muss. Ein Textknoten dessen Inhalt nur teilweise annotiert wird,
muss zwangsläug in mindestens zwei neue Textknoten aufgesplittet werden.
Wenn nun genau dieser Textknoten zum zweiten Mal annotiert werden soll,
existiert dieser gar nicht mehr als ein Knoten, sondern wurde in mehrere
Knoten aufgeteilt.
3.4.2 Technik des Annotierens
Abbildung 3.10: Einfügen einer Annotation
Da wir nun eine Vorstellung von Annotationen haben, wollen wir zunächst
anhand eines Beispiels das Annotieren eines Dokumentes verdeutlichen. Mit
Hilfe dieses Beispiels werden wir sehen, dass der Prozess des Annotierens
selbst wieder in drei Teile unterteilt werden kann.
In Abbildung 3.10 ist gut zu erkennen, dass sich die Pfade durch das Einfügen
einer Annotation ändern. Der Pfad zum Textknoten, der das Ausrufezeichen
beinhaltet, war vor dem Einfügen der Annotation noch
w:r[2]/w:t[1]. Doch durch das Aufsplitten des ersten Kno-
/w:body[1]/w:p[1]/
tens hat sich der Pfad für alle weiteren Knoten desselben Typs geändert. Dies
hat aber nur Auswirkungen auf die r-Knoten, die denselben Vaterknoten besitzen. So werden r-Knoten, die in einem anderen Paragraph stehen davon
KAPITEL 3.
DOKUMENTENVERARBEITUNG
34
nicht in Mitleidenschaft gezogen. Auch r-Knoten, die vor der Annotation stehen, behalten ihren Pfad. Nach dem Einfügen der Annotation für den ersten
Knoten, ist der neue Pfad des Textknotens, der das Ausrufezeichen enthält,
w:r[4]/w:t[1].
/w:body[1]/w:p[1]/
Der Algorithmus muss also nicht nur Annotationen in das Dokument einfügen können, sondern auch Annotationspfade anpassen und Textknoten in
mehrere Knoten aufsplitten. Somit kann man den Algorithmus in drei Teile
aufteilen.
1.
Anpassen des Dokumentes und der Annotationspfade:
Textknoten werden nach Bedarf in mehrere Textknoten aufgeteilt und
die entsprechenden Annotationspfade der Annotationen werden angepasst.
2.
Normalisieren der Annotationsliste:
Annotationspfade in der Annotationsliste werden nach beendetem Anpassen so normalisiert, dass sie auf einen r-Knoten zeigen.
3.
Einfügen der Annotation in das Dokument:
Annotationen und Kommentare werden in das Dokument eingefügt.
3.4.3 Anpassen eines Dokumentes und der Annotationspfade
Nachdem das Generieren der Annotationen anhand des bereinigten Dokumentes abgeschlossen und diese an das Plugin übermittelt wurden, erfolgt
der erste Schritt des Einfügens der Annotationen. Nur das Einfügen der
Annotation alleine reicht nicht aus, da wir z.B. nur Teile eines Textes annotieren wollen und somit die Struktur des Dokumentes verändern müssen.
Das Annotieren bestimmter Teile eines Textknotens erreichen wir, indem wir
Textknoten aufbrechen und sie in mehrere einzelne Knoten aufteilen, die nun
verschiedene Formatierungen erhalten. Ebenfalls müssen bestimmte Annotationspfade durch das Splitten von Textknoten angepasst werden, da sonst
fehlerhafte Annotationen im Dokument entstehen würden. Bevor nun eine
genaue Arbeitsweise eines solchen Algorithmus erörtert werden kann, muss
zunächst genauer auf die Idee des Aufsplittens und Anpassens eingegangen
werden.
Aufbrechen von Textknoten (Split Algorithmus)
Das Aufbrechen von Textknoten übernimmt der Split-Algorithmus. Ein Indikator für das Aufsplitten einzelner Textknoten ist das Enden eines Anno-
KAPITEL 3.
DOKUMENTENVERARBEITUNG
35
tationspfades auf einen bestimmten Buchstaben (.../text[1]/char[n]), da eine
Annotation, die nicht auf einem Buchstaben endet, keinen Textknoten verändern kann. Ein Pfad, der auf eine Buchstabenposition endet, addressiert
ein Zeichen innerhalb eines Textknotens.
Das Aufsplitten eines Textknotens kann in
terteilt werden.
•
drei verschiedene Fälle un-
Ein Textknoten mit Pfad p muss gar nicht gesplittet werden, wenn
er einen Text der Länge n enthält und die einzufügende Annotation
den Anfangspfad p/text[1]/char[1] und den Endpfad p/text[1]/char[n]
besitzt. In diesem Fall muss der gesamte Textknoten annotiert und gar
nicht aufgeteilt werden. Abbildung 3.11 zeigt diesen Fall.
Abbildung 3.11: Knoten muss nicht gesplittet werden
•
Ein weiterer Fall ist eine Annotation, die einen Knoten in genau zwei
neue Knoten aufsplittet. Dies ist genau dann der Fall, wenn eine Annotation vom ersten Zeichen eines Textknotens beginnt, aber noch vor
Ende des Strings endet, oder wenn eine Annotation nach dem ersten
Zeichen eines Textknotens beginnt und bis zum letzten Zeichen eines
Textknotens reicht. Somit müssen aus einem Textknoten zwei erstellt
werden. Abbildung 3.12 zeigt einen solchen Split.
•
Der dritte Fall splittet den Textknoten in drei neue Textknoten auf.
Dies muss getan werden, wenn nur ein Teil des Strings innerhalb eines
Textknotens annotiert wird und der Anfang und das Ende des Strings
nicht in die Annotation einiessen sollen. Abbildung 3.13 zeigt einen
solchen Split.
KAPITEL 3.
DOKUMENTENVERARBEITUNG
36
Abbildung 3.12: Knoten wird nach dem ersten Zeichen bis Ende gesplittet
Abbildung 3.13: Knoten wird nach dem ersten Zeichen bis vor Ende gesplittet
Algorithmus Split
aktunode = Knoten, der durch aktuanno Annotiert werden soll
aktuanno = Annotation, die den Split ausgelöst hat
mode = Gibt an, ob Anfangs- oder Endpfad den Split angibt.
1 Function Split ( aktunode , aktuanno , mode )
2
If mode {
3
firsttext = New Textnode ;
4
text ( firsttext ) = text ( aktunode )[1 bis ( char ( anfangspfad ( aktuanno )) -1)];
5
secondtext = New Textnode ;
6
text ( secondtext ) = text ( aktunode )[ char ( anfangspfad ( aktuanno ))
7
bis length ( text ( aktunode ))];
8
} else {
9
firsttext = New Textnode ;
10
text ( firsttext ) = text ( aktunode )[1 bis char ( endpfad ( aktuanno ))];
11
secondtext = New Textnode ;
12
text ( secondtext ) = text ( aktunode )[( char ( anfangspfad ( aktuanno )) +1)
13
bis length ( text ( aktunode ))];
14
};
15
mode = not mode ;
16
ersetze aktunode durch secondtext ;
17
fuege firsttext vor secondtext ein ;
18
Return length ( firsttext );
19 End Function
Listing 3.6: Splittet Textknoten
KAPITEL 3.
37
DOKUMENTENVERARBEITUNG
Anpassen der Annotationspfade
Nach dem Aufsplitten der verschiedenen Textknoten müssen die Annotationspfade angepasst werden. Die Forderung an den Algorithmus ist, dass alle
Annotationspfade, die auf denselben Knotentyp desselben Vaterknotens enden und in der Baumstruktur rechts gesehen vom aufgesplitteten Knoten
liegen, angepasst werden müssen. Diese Änderungen beziehen sich im Wesentlichen auf r-Knoten und char-Knoten, wie wir später bei der Erzeugung
der Annotationsknoten noch sehen werden.
Der Algorithmus muss also jeden Annotationspfad so anpassen, dass die
entsprechenden Annotationspfade innerhalb der Annotationsliste nach dem
Splitten eines Textknotens um den entsprechenden Wert inkrementiert werden. Da das Splitten eines Knotens in drei Knoten nicht in einem Schritt
passieren wird, muss nach dem ersten Split auch das Oset, das durch das
Verkürzen des Strings im Textknoten entstanden ist, im Endpfad der Annotation eingerechnet werden, die das Splitten des besagten Textknotens ausgelöst hat. Somit lässt sich hier schon erkennen, dass es zwei Fälle geben wird,
je nachdem ob beim Splitten der betroene Textknoten durch den Anfangsoder Endpfad einer Annotation geteilt worden ist.
Ein Textknoten muss aber nicht immer in drei Teile gesplittet werden. Das
Aufbrechen könnte einen Text liefern, der keinen Inhalt besitzt, so wird dieser nicht angehängt bzw. erst gar nicht gebildet. Da ein Text der Länge 0
kein Oset besitzt und keinen r-Knoten erzeugt, kann mit der alten Annotation weiter gearbeitet werden. Lediglich der Modus wird gewechselt. Sollte
nun auch beim zweiten Aunden der Text nicht gesplittet werden müssen,
wird nur der Annotationspfad auf den entsprechenden r-Knoten gesetzt. Das
Oset ist hierbei die Länge des abgetrennten Textknotens, d.h. die Anzahl
seiner Zeichen.
Das Anpassen der Pfade wird von dem Algorithmus Fix realisiert, der durch
folgenden Algorithmus beschrieben werden kann.
Algorithmus Fix
focusanno = Anno die den Split verursacht hat
annolist = Liste der Annotationen
offset = Das durch den Split entstandene Oset
mode = Gibt an, ob Anfangs- oder Endpfad den Split
verursacht hat
KAPITEL 3.
DOKUMENTENVERARBEITUNG
38
1 Method Fix ( focusanno , annolist , offset , mode )
2
If mode {
3
splitpath = anfangspfad ( focusanno ) = p/r [i ]/ t [1]/ text [1]/ char [ k]
4
} else {
5
splitpath = endpfad ( focusanno ) = p/ r[i ]/ t [1]/ text [1]/ char [k]
6
};
7
For each anno in annolist do
8
If anfangspfad ( anno ) = p/r [l ]/... with l > i {
9
anfangspfad ( anno ) = p/r[l +1]/...
10
};
11
If endpfad ( anno ) = p/ r[l ]/... with l >i {
12
endpfad ( anno ) = p /r[l +1]/...
13
};
14
If anfangspfad ( anno ) = p/r [i ]/ t [1]/ text [1]/ char [ m ]... with m >k {
15
anfangspfad ( anno ) = p/r[i +1]/ t [1]/ text [1]/ char [m - offset ]
16
};
17
If endpfad ( anno ) = p/ r[i ]/ t [1]/ text [1]/ char [m ]... with m > k {
18
endpfad ( anno ) = p /r[i +1]/ t [1]/ text [1]/ char [m - offset ]
19
};
20
Next ;
21 End Method
Zusammenspiel der Algorithmen
Den Algorithmus, der das Anpassen der Annotationen und das Aufsplitten
der Textknoten implementiert, wollen wir im Folgenden nun FixAndSplit
nennen. Das Abarbeiten aller Elemente auf einer Ebene der Baumstruktur
stellt die Grundidee des Algorithmus FixAndSplit dar. Den Anfang stellt hier
nun der Body-Knoten, der die Wurzel des Dokuments bildet. Das Abarbeiten der Kinder wird durch einen rekursiven Aufruf der FixAndSplit Funktion
realisiert, da jedes Kind wieder einen Teilbaum darstellt.
Es gibt zwei Modi. Im Begin-Modus wird nach dem Anfang einer Annotation gesucht. Im End-Modus wird nach dem Ende einer Annotation gesucht.
Die Funktion prüft für jedes Kind des Knotens, der beim Funktionsaufruf
mitgegeben wurde, ob das Kind ein Teilpfad eines Annotationspfades ist. Im
Folgenden wollen wir zwischen
den.
zwei Arten von Annotationen unterschei-
KAPITEL 3.
DOKUMENTENVERARBEITUNG
39
Typ Char: Annotationen, deren Anfangs- oder Endpfad einen
/char[n] Sux besitzt. Diese Annotationen brechen potenziell Textknoten auf.
Typ NotChar: Annotationen, deren Anfangs- und Endpfad keinen /char[n] Sux besitzt. Hier ist kein Handlungsbedarf.
Für den Fall, dass eine Annotation keinen Textknoten aufsplittet, muss der
Algorithmus FixAndSplit nicht aktiv werden. Für Annotationen des Typs
Char wird eventuell ein Split ausgeführt. Zunächst wollen wir uns aber die
Fälle betrachten, die der Algorithmus FixAndSplit unterscheiden muss:
Fall 1
Pfad des aktuellen Knotens ist ein Vaterpfad eines Annotationspfades:
FixAndSplit wird mit entsprechendem Kind als Wurzel-Knoten aufgerufen.
Fall 2
Pfad des aktuellen Knotens ist kein Vaterpfad eines Annotationspfades:
Knoten wird ausser Acht gelassen, denn wenn der aktuelle Knoten kein
Teilpfad einer Annotation ist, dann auch dessen Kinder nicht.
Fall 3
Pfad des aktuellen Knotens ist genau der gesuchte Pfad:
ggf. Aufbrechen des Knotens und Anpassen der Annotationspfade.
Der dritte Fall unterscheidet sich sehr von den ersten beiden Fällen, da sich
der Algorithmus in den ersten beiden Fällen auf der Suche nach einem Knoten bendet, der annotiert werden soll. Im dritten Fall wurde eine Annotation
zum aktuellen Knoten gefunden. Je nach Modus, in dem sich der Algorithmus
bendet, wird ein Anfangs- oder Endpfad gesucht. Sollte die Annotation vom
Typ NotChar sein, so ist nicht zu tun. Ist die Annotation, deren Pfad auf den
aktuellen Knoten passt, aber vom Typ Char, so muss der Knoten eventuell
nun aufgebrochen und die Annotationspfade angepasst werden. Auch der Modus wird nun gewechselt. Bendet sich der Algorithmus durch den Wechsel
nun im End-Modus, so ist jetzt der Endpfad der Annotation ausschlaggebend. Der Endpfad der Annotation kann einen zweiten Split angeben, der
KAPITEL 3.
DOKUMENTENVERARBEITUNG
40
natürlich durch den entstandenen Oset des ersten Splittens angepasst wurde. Der End-Modus arbeitet analog zum Begin-Modus.
Das Aufbrechen und Anhängen der Knoten geschieht derart, dass der erste
Teil des Knotens, der laut Annotation nicht annotiert werden sollte, sich nun
auf der Position im Baum bendet, an der auch der frühere Textknoten war.
Der hintere Teil des Textes, der ganz oder nur teilweise annotiert werden soll,
ist nun direkt rechts daneben positioniert. Da die Annotation so angepasst
wurde, dass sie auf den neuen Knoten zeigt, wird dieser im nächsten Durchlauf wieder gesplittet, falls die Annotation dies angibt. Der Annotationspfad
gibt immer genau an, an welcher Position der Text in zwei Teile geteilt werden soll. So kann ein Text durchaus in 3 Teile gesplittet werden.
Algorithmus FixAndSplit
aktunode = Knoten der durch aktuanno Annotiert werden soll
annolist = Liste von Annotationen, die eingefügt werden sollen
mode = Mode in dem sich der Algorithmus bendet
1 Method FixAndSplit ( aktunode , annolist , mode )
2
For each child in children ( aktunode ) do
3
aktupath = path ( aktunode );
4
If mode {
5
aktuannos = { x ∈ annolist | anfangspfad (x) is SubPath of aktupath }
6
} else {
7
aktuannos = { x ∈ annolist | endpfad ( x) is SubPath of aktupath }
8
};
9
sort ( aktuannos );
10
If | aktuannos | > 0 {
11
For each anno in aktuannos do
12
If name ( aktunode ) == "r" and has - char - suffix ( anno ) {
13
If mode {
14
offset = split ( child , anno , mode );
15
Fix ( anno , annolist , offset , mode );
16
mode = false ;
17
} else {
18
offset = split ( child , anno , mode );
19
Fix ( anno , annolist , offset , mode );
20
mode = true ;
21
};
22
};
23
Next ;
24
} else {
25
FixAndSplit ( child , annolist , mode );
26
};
27
Next ;
28 End Method
Listing 3.7: Splittet Knoten und passt Annotationspfade an
KAPITEL 3.
DOKUMENTENVERARBEITUNG
41
Die Annotationen werden gemäss der Reihenfolge des Auftretens ihres vom
Anfangspfad referenzierten Knotens bei der Tiefensuche geordnet.
Zusammenfassend kann man also sagen, dass der erste Schritt des Annotierens die Dokumentstruktur und die Annotationen so vorbereitet, dass ein
einfaches Einfügen der Annotationen ermöglicht wird.
Diskussion
Beispiel zu Fall 1:
Abbildung 3.14: Knoten muss nicht gesplittet werden
Annotation vor dem ersten Split:
Anfangspfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[1]
Endpfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[16]
Annotation vor dem zweiten Split:
Anfangspfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[1]
Endpfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[16-0]
Annotation nach dem zweiten Split:
Anfangspfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[1]
Endpfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[16]
In Abbildung 3.14 soll nur der gesamte Text
Ein kleiner Test des Knotens an-
notiert werden. Der Textknoten muss deshalb nicht geteilt werden. Zu Beginn
KAPITEL 3.
DOKUMENTENVERARBEITUNG
42
ist der Modus des Algorithmus Begin, es ist also der Anfangspfad der Annotation ausschlaggebend. Der Knoten würde nun an der Textstelle 1, also vor
dem ersten Zeichen aufgeteilt. Da diese Aufteilung aber einen leeren Textknoten liefern würde, wird kein Aufbrechen des Texknotens durchgeführt.
Nur der Modus wird auf End gesetzt, damit nun der Endpfad ausschlaggebend ist. Hier ist es nun so, dass der Text hinter dem 16-ten Zeichen geteilt
werden müsste, aber auch diese Aufteilung würde einen leeren Textknoten
erzeugen. Es wird also kein Split durchgeführt. Da es beide Male zu keinem
Split kam, müssen auch keine Annotationspfade angepasst werden. Der Modus wird wieder auf Begin gesetzt.
Beispiel zu Fall 2:
Abbildung 3.15: Knoten muss einmal gesplittet werden
Annotation vor dem ersten Split:
Anfangspfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[1]
Endpfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[3]
Annotation vor dem zweiten Split:
Anfangspfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[1]
Endpfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[3-0]
Annotation nach dem zweiten Split:
Anfangspfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[1]
Endpfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[3]
In Abbildung 3.15 soll nur das Wort
Ein
des Textknotens annotiert werden.
Der Textknoten muss deshalb nur einmal geteilt werden. Zu Beginn ist der
KAPITEL 3.
DOKUMENTENVERARBEITUNG
43
Modus des Algorithmus Begin, es ist also der Anfangspfad der Annotation
ausschlaggebend. Der Knoten würde nun an der Textstelle 1, also vor dem
ersten Zeichen aufgeteilt. Da diese Aufteilung aber einen leeren Textknoten
liefern würde, wird kein Split des Texknotens durchgeführt. Nur der Modus
wird auf End gesetzt, damit nun der Endpfad ausschlaggebend ist. Hier wird
nun ein Split an der im Endpfad unter
/char[]
angegeben Position durch-
geführt und alle in Mitleidenschaft gezogenen Annotationspfade angepasst.
Hierzu zählt allerdings nicht der Endpfad der aktuellen Annotation. Der Modus wird wieder auf Begin gesetzt.
Beispiel zu Fall 3:
Abbildung 3.16: Knoten muss zweimal gesplittet werden
Annotation vor dem ersten Split:
Anfangspfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[5]
Endpfad=/w:body[1]/w:p[1]/w:r[1]/w:t[1]/text[1]/char[12]
Annotation vor dem zweiten Split:
Anfangspfad=/w:body[1]/w:p[1]/w:r[1+1]/w:t[1]/text[1]/char[5-4]
Endpfad=/w:body[1]/w:p[1]/w:r[1+1]/w:t[1]/text[1]/char[12-4)]
Annotation nach dem zweiten Split:
Anfangspfad=/w:body[1]/w:p[1]/w:r[2]/w:t[1]/text[1]/char[1]
Endpfad=/w:body[1]/w:p[1]/w:r[2]/w:t[1]/text[1]/char[7]
In Abbildung 3.16 muss der Knoten zweimal aufgeteilt werden, da nur das
KAPITEL 3.
Wort
kleiner
DOKUMENTENVERARBEITUNG
44
innerhalb des Textknotens annotiert werden soll. Der Modus
des Algorithmus bendet sich vor dem ersten Split auf Begin. Somit ist der
Knoten, der gesplittet werden soll, der Knoten, auf den der Anfangspfad
der Annotation referenziert. Nun wird der Textknoten an der Stellte gesplittet, die unter
/char[]
im Anfangspfad angegeben wurde. Danach muss der
Endpfad dieser Annotation und alle davon betroenen Annotationspfade angepasst werden. Durch dieses Anpassen referenziert nun der Endpfad auf den
Knoten
/w:r[2].
Der Modus wird auf End gesetzt, sodass der Endpfad der
Annotation ausschlaggebend ist, er gibt nun den zweiten Split an. Der neu
entstandene Textknoten wird wieder aufgeteilt. Die betroenen Annotationspfade werden angepasst, wobei der Endpfad der aktuellen Annotation nicht
mehr angepasst wird. Der Modus wird auf Begin gesetzt.
3.4.4 Normalisieren einer Annotationsliste
Die Annotationspfade werden nun so gekürzt bzw. erweitert, dass sie immer
auf einen r-Knoten verweisen. Dies muss für den Anfangspfad und den Endpfad der Annotation durchgeführt werden. Ein Kürzen der Annotation ist
deshalb sehr sinnvoll, da die Formatierung, die die Annotation im Dokument
darstellt, immer vor dem entsprechenden Textknoten eingefügt wird. Beide
besitzen eben diesen r-Knoten als Vater. Somit muss beim Finden der Annotation an den entsprechenden r-Knoten nur die Formatierung als erstes Kind
angefügt werden. Folgender Algorithmus gibt das Normalisieren der Annotationen an.
Algorithmus Normalisieren
annolist
= Liste der Annotationen
1 Method normalisiere ( annolist )
2
For each anno in annolist do
3
Case name ( last ( anfangspfad ( anno )))
4
{
5
'p '
: setze anfangspfad ( anno ) auf ersten
6
r - Knoten des Paragraphs
7
8
' oMathPara ' : setze anfangspfad ( anno ) auf ersten
9
r - Knoten des ersten untergeordneten oMath - Knotens
10
11
' oMath '
: setze anfangspfad ( anno ) auf ersten
12
r - Knoten des oMath - Knotens
13
14
default
: setze anfangspfad ( anno ) auf Pfad des r - Vorfahrens
15
};
16
Case name ( last ( endpfad ( anno )))
KAPITEL 3.
DOKUMENTENVERARBEITUNG
17
{
18
'p '
19
20
21
' oMathPara '
22
23
24
' oMath '
25
26
27
default
28
};
29
Next ;
30 End Method
45
: setze endpfad ( anno ) auf ersten
r - Knoten des Paragraphs
: setze endpfad ( anno ) auf ersten
r - Knoten des ersten untergeordneten oMath - Knotens
: setze endpfad ( anno ) auf ersten
r - Knoten des oMath - Knotens
: setze endpfad ( anno ) auf Pfad des r - Vorfahrens
Listing 3.8: Normalisiert Annotationspfade
3.4.5 Einfügen von Annotation in ein Dokument
Die ersten beiden Schritte des Annotierens stellen ein Vorbereiten des Dokumentes und der Annotationsliste dar. Der dritte Schritt wird nun die Annotationen tatsächlich in das Dokument einfügen. Im Folgenden werden wir
diesen Algorithmus deshalb
AnnotateAndComment nennen.
Der Algorithmus AnnotateAndComment kann, ebenso wie der Algorithmus
Algorithmus AnAlgorithmus Comment. Diese Aufteilung
FixAndSplit, wieder aufgeteilt werden. Zum einen in den
notate,
zum anderen in den
erklärt sich aus dem Aufbau des Dokumentes. Wir erinnern uns zurück, dass
es Annotationen mit Text gibt. Diese Annotationen fügen einen Kommentartext in das Dokument ein, der in der Annotation als Beschreibung angegeben
wird. Kommentare stehen aber nur bedingt im Körper eines Dokumentes. Lediglich eine Referenz mit einer Referenznummer wird an der entsprechenden
Stelle im Dokument eingefügt. Der eigentliche Kommentar wird in den
comment
part
eingefügt.
Da nun der eigentliche Kommentar nicht im Body des Dokumentes steht, ist
es sinnvoll, die beiden Objekte separat anzulegen. Zunächst werden die Referenzen im Dokumentbody erstellt und danach im Comment-Algorithmus
die Kommentare unter
part comment
hinzugefügt. Daher wollen wir nun zu-
nächst den Algorithmus Annotate genauer betrachten, der alle Annotationen
im Dokumentkörper einfügt. Da durch das Vorbereiten des Dokumentkörpers, also dem Splitten der Textknoten, alle Knoten so erzeugt wurden, wie
sie von der Annotation gefordert wurden und alle Annotationspfade angepasst sind, ist das Einfügen der Annotation nun kein Problem mehr.
KAPITEL 3.
DOKUMENTENVERARBEITUNG
46
Annotate
Der Algorithmus des Annotierens durchwandert ebenfalls rekursiv den Dokumentbody. Das Durchwandern wurde hier wieder wie im FixAndSplit Algorithmus realisiert. Alle Kinder des mitgelieferten Knotens werden hier betrachtet. Sollte ein Kind nicht Teil eines Pfades einer Annotation sein, kann
dieses ignoriert werden. Ist ein Kind Teil eines Pfades einer Annotation, so
wird die Funktion mit diesem Kind als Vaterknoten aufgerufen.
Auch muss es wieder zwei Modi geben, einen Begin- und einen End-Modus.
Ist der Algorithmus im Begin-Modus, so wird eine passende Annotation gesucht. Hierfür wird der aktuelle Pfad mit dem Begin aller Annotationen verglichen. Wurde eine Annotation gefunden, die auf den aktuellen Pfad passt,
so wird an diesen Knoten die entsprechende Formatierung als erstes Kind
angehängt. Dies kann nur deshalb erfolgen, da alle Annotationen auf einen rKnoten enden. Der Modus wird nun auf End gesetzt und der Endpfad dieser
Annotation wird gesucht. Da sich keine Annotationen überlappen können,
kann es auch nicht vorkommen, dass eine andere Annotation während der
Suche nach dem Ende der aktuellen Annotation beginnt. Während sich der
Algorithmus im End-Modus bendet, wird an jeden r-Knoten die Formatierung der aktuellen Annotation angehängt.
Eine Forderung an das Anhängen der neuen Formatierung ist es, dass alle
schon vorhandenen Formatierungen, die nicht im Widerspruch zur Formatierung der Annotation stehen, erhalten bleiben. Dies gilt für alle Formatierungen, die nicht die Schriftfarbe verändern. Diese Forderung wurde so
implementiert, dass beim Aunden einer schon vorhandenen Formatierung
nur eine neue Schriftfarbe gesetzt wird. Sollte die Annotation eine Beschreibung besitzen, so wird noch eine Kommentarreferenz an diese Stelle gesetzt.
Kommentare werden durch fortlaufende Nummern eindeutig identiziert, so
ist es einfach eine solche Kommentarreferenz zu erstellen. Es muss nur die
aktuelle ID gespeichert werden, die beim Einfügen einer neuen Referenz inkrementiert wird. Zusätzlich wird ein Eintrag in einer Hashtabelle angelegt
mit der KommentarID und dem dazugehörigen Kommentartext. So können
später im Comment Algorithmus auch ohne Annotationsliste die entsprechenden Kommentare schnell erzeugt werden. Es werden alle Knoten des Bodys
durchlaufen und jede Annotation eingefügt.
KAPITEL 3.
DOKUMENTENVERARBEITUNG
47
Algorithmus Annotate
node = Knoten der Annotiert werden soll
anno = Annotation die eingefügt werden soll
1 Method Annotate ( node , anno )
2 Case name ( node )
3 {
4
'p '
: For each child in children ( node ) do
5
Annotate ( child , anno );
6
Next ;
7
8
' oMath ' : For each child in children ( node ) do
9
Annotate ( child , anno );
10
Next ;
11
12
'r '
: Formatierung anpassen ;
13
14
else
: If name ( node ) ∈ mathemarkup ( config ) {
15
Formatierung anpassen ;
16
For each child in children ( node ) do
17
Annotate ( child , anno );
18
Next ;
19
}
20
else {
21
For each Child in children ( node ) do
22
Annotate ( child , anno );
23
Next ;
24
};
25
};
26 End Method
Listing 3.9: Annotiert einen Teilbaum
Comment
Nachdem alle Annotationen in den Dokumentbody eingefügt wurden, müssen nun die entsprechenden Kommentare im Part Comment erzeugt werden.
Schon vor dem Einfügen der ersten Kommentarreferenz wurde geprüft, ob der
Benutzer bereits Kommentare im Dokument angelegt hat. Dies ist wichtig, da
die Kommentarreferenzen fortlaufende Nummern sind und dementsprechend
die erste freie KommentarID gewählt werden muss. Sollte der Benutzer noch
keinen Kommentar eingefügt haben, so existiert der Part Comment im Word
Dokument noch nicht und muss ebenfalls vom Plugin erzeugt werden.
Existiert dieser Part nun, so kann damit begonnen werden, mit Hilfe der
Hashtabelle, die die Kommentartexte und die KommentarIDs enthält, die eigentlichen Kommentare zu erstellen. Dies geschieht, indem aus jedem Eintrag
ein Kommentar mit dem dort angegebenen Inhalt erzeugt wird. Diese werden
dann in den Comment Part eingefügt. Die Kommentare müssen nicht zwingend in geordneter Reihenfolge dort aufgelistet sein, sondern können dort
KAPITEL 3.
DOKUMENTENVERARBEITUNG
48
beliebig auftauchen. Jede Kommentarreferenz die im Dokumentbody angegeben ist, muss hier aber genau einmal auftreten, sonst wäre die Struktur
des Dokumentes zerstört und das Dokument unbrauchbar.
AnnotateAndComment
Die Arbeitsweise des Algorithmus AnnotateAndCommet lässt sich also nun
wiefolgt zusammenfassen. Der Algorithmus durchwandert den Dokumentbody und erzeugt im Begin Modus eine Formatierung, wenn der entsprechende
r-Knoten gefunden wurde. Im End Modus wird an jeden r-Knoten, der gefunden wird, diese Formatierung angehängt. Es werden ebenfalls Kommentarreferenzen eingefügt, die in einer Hashtabelle zusammen mit dem Kommentartext gespeichert werden.
Nachdem der Body abgearbeitet wurde, wird die Funktion Comment gestartet, die nun aus der Hashtabelle die entsprechenden Kommentare im Part
Comment erzeugt.
Algorithmus AnnotateAndComment
aktunode = Aktuell betrachteter Knoten. (bei erstem Aufruf Body-Knoten)
annolist = Liste der einzufügenden Annotationen
parentpath = Pfad zu aktunode
anno = Ist in modus == true nicht instanziiert. In anno wird die Annotation
gespeichert, deren Anfang gefunden wurde und deren Ende im modus ==
false gesucht wird.
1 Function AnnotateAndComment ( aktunode , annolist , parentpath , anno )
2
3 For each child in children ( aktunode ) do
4
aktupath = path ( child );
5
If exists ( anno ) {
6
aktuanno = x ∈ annolist with anfangspfad (x) == aktupath
7
If exists ( aktuanno ) {
8
If msg ( aktuanno ) <> "" {
9
baue KommentarreferenzBegin ;
10
};
11
Annotate ( child , aktuanno );
12
If endpfad ( aktuanno ) == aktupath and msg ( aktuanno ) <> "" {
13
baue KommentarreferenzEnd ;
14
aktuanno := nothing ;
15
};
16
} else {
17
aktuannos = { x ∈ annolist | anfangspfad (x) is SubPath of aktupath }
18
If | aktuannos | > 0 {
19
AnnotateAndComment ( child , annolist , aktupath ,( nothing ));
20
};
KAPITEL 3.
DOKUMENTENVERARBEITUNG
49
21
};
22
} else {
23
If endpfad ( anno ) == aktupath {
24
Annotate ( child , anno )
25
if msg ( aktuanno ) <> "" {
26
baue KommentarreferenzEnd ;
27
}
28
} else {
29
30
If endpfad ( anno ) is SubPath of aktupath {
31
AnnotateAndComment { child , annolist , aktupath , anno };
32
} else {
33
Annotate ( child , anno );
34
};
35
};
36
};
37 Next ;
38 End Method
Listing 3.10: Fügt Annotationen in ein Dokument ein
Diskussion
Wie man in Listing 3.10 AnnotateAndComment-Algorithmus erkennen kann,
muss der Annotate-Algorithmus nicht nur r-Knoten annotieren können. In
den ersten beiden Schritten des Annotierens wurden zwar die Knoten so
gesplittet und die Annotationen so angepasst, dass deren Anfangs- und EndPfade immer auf einen r-Knoten verweisen, doch reicht dies für Annotationen,
die sich über mehrere Knoten erstrecken, nicht aus. Es kann z.B. sein, dass
zwischen Anfangs- und Endpfad mehrere Paragraphen und oMath-Elemente
liegen.
So musste der Annotate-Algorithmus so konzipiert werden, dass er auch ganze Teilbäume des Dokumentes annotieren kann, also auch Paragraphen und
Ähnliches. Da aber das Annotieren eines ganzen Paragraphens oder oMathElementes nichts anderes ist, als alle r-Knoten dieses Teilbaums zu annotieren, kann dies sehr einfach durch rekursive Aufrufe und mehrere Fallunterscheidungen realisiert werden. Ausserdem muss noch ein Spezialfall betrachtet werden für Konstrukte wie etwa Klammern und diverse oMath Objekte.
In einem oMath Element können sehr verschiedene Unterelemente auftreten. Diese Vielfalt erschwert es, jedes Unterelement einzeln zu benennen und
durch die Annotation färben zu lassen. Hier stellt sich ein ähnliches Problem wie bei der Bereinigung des Dokumentes. Denn auch hier müssen alle
Unterelemente des oMath Elementes erhalten bleiben, die die Struktur des
Elementes angeben. Hierzu zählen Konstrukte wie Klammern, Matrizen oder
diverse Operatoren und Symbole.
KAPITEL 3.
DOKUMENTENVERARBEITUNG
50
Bei der Bereinigung des Dokumentes wurde dies über die Kongurationsdatei
gelöst, die die zu erhaltenden Knotentypen des Bodys beinhaltet. Auch im
Falle des Annotierens dieser oMath Elemente wird auf die Kongurationsdatei zurückgegrien. Es wird überprüft, ob der Typ des aktuellen Knotens
in der Kongurationsdatei als ein zu annotierender mathematischer MarkupKnoten angegeben wurde. Dies ist deshalb so wichtig, da beispielsweise ein
Klammerelement nicht als Text abgespeichert wird, sondern als strukturelles
Element im Markup auftritt. Eine gezielte Annotation eines einzelnen Klammerelementes ist daher technisch nicht möglich.
3.5
Updaten eines Dokumentes
Im einleitenden Beispiel wurde erwähnt, dass ein Benutzer Hilfe für eine bestimmte Stelle im Dokument über einen Serverdienst anfordern kann, um
den nächsten Schritt eines mathematischen Beweises automatisch einfügen
zu lassen. Das Resultat dieser Hilfe ist eine Liste von Updates für das Dokument, die an den entsprechenden Stellen eingefügt werden. In Anlehnung an
den xUpdate [9] Standard denieren wir ein Update wie folgt:
•
Befehl:
Gibt an, welche Art von Update ausgeführt wird.
insert-before:
Fügt Inhalte direkt vor den im Path angege-
benen Knoten ein.
insert-after: Fügt Inhalte direkt hinter den im Path angegebenen Knoten ein.
replace: Ersetzt den im Path angegeben Knoten.
append: Content wird einfach als letztes Kind an den im Path
angegebenen Knoten gehängt.
remove: Löscht den im Path angegebenen Knoten.
•
Pfad:
Stelle im Dokument, an der das Update ausgeführt werden soll.
•
Content:
Ist eine Liste von Knoten, die in das Dokument eingefügt wird. Bei
dem Befehl remove wird kein Content angegeben.
KAPITEL 3.
51
DOKUMENTENVERARBEITUNG
Wie wir auch schon in Annotationen festgestellt haben, muss es auch hier
wieder eine Hierarchie zwischen den einzelnen Arten von Updates geben. Das
Einfügen und Entfernen von Textknoten kann die Pfade zu bestimmten Knoten verändern. Daher sortieren wir die Updates wiefolgt:
insert-after
≺
insert-before
≺
replace
≺
append
≺
remove
Das Einfügen der Updates in das Dokument erfolgt in zwei Schritten. Zunächst wird das Dokument durchlaufen und für jeden Knoten geprüft, ob ein
Update für diesen Knoten vorliegt. Das Finden eines solchen Knotens wird
in der Funktion Patch realisiert. Findet diese Funktion einen solchen Knoten
im Dokument, wird der zweite Schritt des Updatens ausgeführt, das Apply.
Diese Funktion führt den Update-Befehl auf das Dokument aus und realisiert
somit das Einfügen oder Löschen im Dokument.
Algorithmus Patch
aktunode = Aktueller Teilbaum.
updatelist = Liste der auszuführenden
Updates.
1 Method Patch ( aktunode , updatelist )
2
For each child in children ( aktunode ) do
3
For each update in updatelist do
4
aktupath = path ( child );
5
If path ( update ) is Subpath of aktupath and path ( update ) <> aktupath {
6
Patch ( focus , updatelist )
7
};
8
If path ( update ) = aktupath then {
9
Apply ( child , update )
10
};
11
Next ;
12
Next ;
13 End Method
Listing 3.11: Ermittelt Knoten zu den Updates und wendet Apply darauf an
Apply
Die Funktion Apply wird durch den Aufruf der entsprechenden, bereits vorhandenen Funktionen in MS Word realisiert.
KAPITEL 3.
DOKUMENTENVERARBEITUNG
52
Kapitel 4
Interaktive Dienste
Um dem Benutzer die Möglichkeit zu bieten interaktive Dienste zu nutzen,
muss eine kontextsensitive Interaktion mit den Diensten des Assistenzsystems
möglich sein. Interaktive Dienste im Mediator Plugin sind etwa das Verizieren von Schritten in einer Beweisführung oder das Einfügen des nächsten
Beweisschrittes. Diese Interaktion wird im Plugin durch dynamische Menüs
realisiert. Es wird also abhängig von der Textstelle, auf der der Fokus des
Benutzers liegt, ein Menü mit Hilfestellungen des mathematischen Assistenzsystems angeboten. Das Finden der entsprechenden Stellen im Dokument ist
ein Hauptproblem, das in diesem Kapitel gelöst wird. Hierfür sollen im Folgenden die Techniken des Findens der aktuellen Textstelle und des Erstellens
des davon abhängigen Menüs vorgestellt werden.
4.1
Kontext-Sensitive Menüs
Um in einem kontextsensitiven Menü dem Benutzer die Dienste eines mathematischen Assistenzsystems anzubieten, müssen zunächst die Knoten im
Dokument gefunden werden, zu denen das Menü angefordert wurde. Logischerweise kann ohne diesen Bereich im Dokument keine kontextsensitive
Menüinteraktion entstehen. Somit ist die erste Forderung, dass die Knoten im
Dokument gefunden werden, für die der Benutzer Hilfe erwartet. Im Folgenden wollen wir verschiedene Ansätze zur Implementierung dieser Forderung
diskutieren, die entweder die Knoten im Dokument durch die Cursorposition,
durch Markierung im Text oder durch beide Techniken zusammen ermitteln.
Finden der Textstelle durch Cursorposition
Der einfachste Ansatz zum Finden des Knotens, für die ein Menü angefordert
wurde, ist das Ermitteln der Cursorposition. Mit dieser Technik würden die
53
KAPITEL 4.
INTERAKTIVE DIENSTE
54
Dienste des mathematischen Assistenzsystem für den Textknoten im Word
Dokument angefordert, auf dem zum Zeitpunkt der Anfrage an den Server
der Cursor steht. Dieser Ansatz bringt zwei Probleme mit sich. Zunächst
einmal könnte ein Benutzer Hilfe zu mehr als einem Textknoten erwarten.
Dies könnte dann der Fall sein, wenn etwa ein für den Benutzer zusammenhängender Text durch Formatierungen intern als mehr als ein Textknoten
repräsentiert wird. Somit müssten vor dem Anfordern der Menüs alle Formatierungen im Dokument entfernt werden. Jedoch kann nicht gewährleistet
werden, dass etwa eine Formel als nur ein Formelknoten dargestellt wird. Das
Zweite und wohl grössere Problem stellt die Cursorposition selbst dar. Da die
Cursorposition nicht im Dokument mitgespeichert und ein Abfragen der Cursorposition in MS Word eine Darstellung liefert, die keine Rückschlüsse mehr
auf den Pfad zu einem Knoten innerhalb des XML-Dokumentes ermöglicht,
führt dieser Ansatz ins Leere.
Finden der Textstelle durch Markierung
Bei diesem Ansatz markiert der Benutzer die Textstelle im Dokument, für
die er Hilfe vom Assistenzsystem und somit das Menü anfordern möchte.
Dieser Ansatz löst das Problem, dass eventuell nicht alle Knoten, für die der
Benutzer Hilfe anfordert, ausgewählt werden. Das Problem, dass die Auswahl,
ähnlich wie die Cursorposition, nicht auf die XML-Repräsentation übertragen
werden kann, bleibt jedoch erhalten. Somit führt auch dieser Ansatz ins Leere.
Finden der Textstelle durch Kommentar
Bei dem letzten Ansatz wird automatisch ein Kommentar an der Cursorposition bei einer Menüanfrage in das Dokument eingefügt. Durch diesen Kommentar, können die Knoten im Dokument wieder gefunden werden, zu der
das Menü angefordert wurde. Sollte ein Benutzer eine Textstelle markieren,
wird der Kommentar automatisch um die komplette Auswahl gelegt. Nach
der Menüanfrage wird der Kommentar wieder aus dem Dokument entfernt.
Mittels dieses Tricks können so die Pfade zu einer Textstelle oder eine Auswahl innerhalb des Dokumentes gefunden werden. Die Cursorposition und
eine Markierung stehen hierbei aber nicht in Konkurrenz, da Word einen
Kommentar nur dann an der Cursorposition einfügt, wenn keine Textstelle
markiert wurde. Diese Lösung ist aber nur eine Näherungslösung, da Kommentare die Struktur des Dokumentes verändern und mittels einer Heuristik
die gefundenen Pfade korrigiert werden müssen. Trotzdem stellt dies einen
erfolgversprechenden Ansatz dar, dessen Implementierung im Folgenden genauer erörtert werden soll.
KAPITEL 4.
55
INTERAKTIVE DIENSTE
4.1.1 Anfragen von Menüinhalten
Um ein Menü anfordern zu können wird neben der bereinigten Fassung des
Dokumentes auch ein Startpfad und ein Endpfad benötigt. Diese Pfade stellen den Anfang und das Ende der Markierung innerhalb des Dokumentes
dar. Sollte ein Benutzer ohne Markierung, also anhand der Cursorposition,
ein Menü anfordern, so sind Start- und Endpfad identisch, da nur ein Knoten
im Dokument ausgewählt wurde. Um zu verstehen, wie Start- und Endpfade aus dem Dokument mittels Kommentar gewonnen werden können, muss
zunächst der Aufbau eines solchen Kommentars genauer betrachtet werden.
Kommentarstruktur in Microsoft Word 2007
Kommentare werden nur teilweise im Dokumentkörper abgelegt. Es wird ein
<w:CommendRangeStart/>
und ein
<w:CommentRangeEnd/>
um die zu kom-
mentierenden Knoten gelegt. Diese Knoten besitzen ein Attribut
ID, dessen
Wert eine Referenz zu einem Comment-Knoten angibt, der im Part-Knoten
Comments des Dokumentes abgelegt ist. Unter Comments kann nun ein Kommentareintrag mit dieser ID gefunden werden, der angibt, wie der Kommentar
gebildet wird und somit auch dessen Kommentartext beinhaltet.
Eine weitere Möglichkeit einen Kommentar zu bilden besteht darin, ohne
<w:CommentRangeStart/>
und
<w:CommentRangeEnd/>
einen Kommentar
anzugeben. Diese Form der Kommentare werden gebildet, wenn in einem
oMath-Element ohne Markierung im Dokument ein Kommentar eingefügt
wird. In diesem Fall ändert sich der Verweis auf den Comment-Knoten im
Dokumentkörper. Anstatt den Anfang und das Ende des Kommentars anzugeben, wird lediglich auf der untersten Ebene innerhalb des oMath-Elementes
der Knoten
ein Attribut
ment
<w:CommentReference> eingefügt. Dieser Knoten besitzt wieder
ID, das wiederum auf einen Kommentar innerhalb des part com-
verweist. Innerhalb des Part-Knotens unterscheiden sich diese beiden
Techniken nicht.
Wir wollen nun eine Technik entwickeln, um die Pfade zu dem ausgewählten
Knoten innerhalb des Dokuments zu berechnen.
Berechnen von Pfaden
Um einen Pfad zu berechnen benötigen wir zunächst einen Kommentar im
Dokument, der als erster Schritt der Menüanfrage in das Dokument eingefügt wird. Wie beschrieben wird der Kommentar entweder um die Auswahl im Dokument gelegt oder bei fehlender Auswahl um den Knoten an
KAPITEL 4.
56
INTERAKTIVE DIENSTE
der Cursorposition. Dieser Kommentar muss nun im Dokument wiedergefunden werden, da es sein kann, dass ein Benutzer eingeständig Kommentare
in das Dokument eingefügt hat. Hierfür wird in den von der Menüanfrage automatisch erzeugten Knoten der Text `requesting Menu...` eingefügt.
Anhand dieses Textes wird dann die ID des Kommentars innerhalb des Part-
<Comments> ermittelt. Mit dieser ID kann auch das entsprechende
<w:CommentRangeStart/> und <w:CommentRangeEnd/> gefunden werden.
Knotens
Mit Hilfe der Kommentar ID werden nun die Pfade zum ersten und letzten
Knoten innerhalb des Kommentars ermittelt. Da
und
<w:CommentRangeEnd/>
<w:CommentRangeStart/>
immer Kinder eines r-Knotens sind, führt der
so ermittelte Pfad immer direkt zu einem Textknoten innerhalb des Dokumentes.
Sollte nun ein Kommentar ohne Markierung in eine Formel eingefügt worden sein, so existiert lediglich ein
<w:CommentReference>
Knoten und das
Ergebnis der Pfadsuche ist leer. In diesem Fall wird eine zweite Suchvariante
gestartet, die den Pfad zu dem oMath-Element liefert, das eben diesen Knoten beinhaltet. Start- und Endpfad werden in diesem Fall identisch gesetzt.
Menüanfrage und Aufbau
Da nun die Pfade bekannt sind, kann eine Anfrage für ein Menü an den Server gestellt werden. Resultat dieser Menüanfrage ist der Inhalt des Menüs.
Dieser Inhalt ist eine Liste von Objekten, die entweder Menüs sein können
oder Aktionen. Falls das Objekt ein Menü sein sollte, wird ein Untermenü
erstellt. Sollte das Objekt eine Aktion sein, wird ein Button erstellt, der
diese Aktion ausführt. Mit dieser rekursiven Denition, lassen sich beliebig
geschachtelte Menüs erstellen. Aktionen werden durch eine sogenannte ActionID eindeutig identiziert. Diese ID wird zusammen mit der Aktion vom
Server geliefert und an den dazugehörigen Button im Menü gebunden. Dies
ist nötig damit beim Drücken des Buttons eindeutig ist, welche Aktion auf
dem Server ausgeführt werden soll. Sollte nun eine bestimmte Aktion im Menü gewählt werden, wird die ActionID zum Server geschickt, der dann die
Resultate dieser Aktion berechnet. Den Ablauf dieser Interaktion zwischen
Plugin und Server wird in Abbildung 4.1 dargestellt.
KAPITEL 4.
INTERAKTIVE DIENSTE
Abbildung 4.1: Das Message Sequence Chart der Menüinteraktion.
57
KAPITEL 4.
4.2
INTERAKTIVE DIENSTE
58
Ergebnisse interaktiver Dienste
Bisher wurde erläutert, wie ein Menü und dessen Aktionen aufgebaut werden.
Nun wollen wir betrachten, wie das Resultat einer auf dem Server ausgeführten Aktion in das lokale Dokument eingetragen wird. Der Benutzer fordert
zunächst das Menü für eine bestimmte Textstelle im Dokument an und löst
dort eine Aktion aus. Nachdem diese Aktion auf dem Server ausgeführt wurde, wird das Resultat zum Plugin zurückgeliefert. Das Resultat wiederum
besteht aus folgenden vier Komponenten: eine Liste von Updates, eine Liste
von Annotationen, eine neue Versionsnummer und eine Beschreibung. Sollte
der Inhalt der Beschreibung nicht leer sein, ist ein Fehler aufgetreten und es
wird die Beschreibung als Text einer Ausnahme ausgegeben. Sollte die Beschreibung aber leer sein, verlief das Ausführen der Aktion auf dem Server
erfolgreich und Updates und Annotationen können eingetragen werden.
Wie in Abbildung 4.1 beschrieben muss nun zwischen synchronen und asynchronen Ergebnissen unterschieden werden. Diese Unterscheidung beruht auf
der Tatsache, dass etwa das Berechnen einer Formel oder das Prüfen gewisser Teile des Dokumentes unter Umständen länger dauern kann, da das
mathematische Assistenzsystem etwas Zeit benötigt, die entsprechenden Annotationen oder Updates zu berechnen. Deswegen werden die Teile der angeforderten Updates und Annotationen sofort zurückgeliefert, die unmittelbar
berechnet werden konnten. Diese Updates und Annotationen sind synchrone
Ergebnisse. Durch das Ausführen des Timers (Abbildung 4.1) werden nun
nach und nach auch die Ergebnisse der Aktion eingetragen, die nicht direkt
als Ergebnis auf die Aktion zurückgeliefert wurden. Diese Ergebnisse nennen
wir asynchrone Ergebnisse.
Das Eintragen der Ergebnisse geschieht wie folgt: Die Versionsnummer wird
an das Dokument angehängt, womit die alte Versionsnummer überschrieben
wird. Updates, ob synchron oder asynchron, werden immer direkt bei Erhalt
in das Dokument eingetragen. Das Einfügen von Updates in das Dokument
wurde in Kapitel 3.5 genauer beschrieben.
Im Gegensatz zu Updates werden Annotationen nur dann eingefügt, wenn
sich das Dokument im Annotations-Modus bendet. Sollte das Dokument im
Bearbeiten-Modus sein, werden die Annotationen gespeichert und erst beim
Wechsel in den Annotations-Modus eingefügt, entsprechend der Beschreibung
in Kapitel 3
Dokumentenverarbeitung.
Kapitel 5
Verwandte Arbeiten
Das in dieser Arbeit entwickelte Mediator Plugin stellt eine Weiterentwicklung des in dem Paper [12, PlatΩ: A Mediator between Text-Editors and
Proof Assistance Systems] vorgestellten Plugins dar. In diesem Paper wurde
mit dem PlatΩ Mediator ein TeXmacs Plugin entwickelt, das die Dienste eines mathematischen Assistenzsystems in den TeXmacs Texteditor integriert.
Der Benutzer hat hier die Möglichkeit zwischen einer strukturierten Darstellung des Dokumentes, wie etwa in einem TeX File, und einer gerenderten (WYSIWYG) Darstellung zu wechseln. Das Anzeigen der dynamischen
Menüs wurde, anders als in dieser Arbeit, direkt in das Dokument integriert.
Das bedeutet, dass der Benutzer bei einer Menüanfrage nicht ein Drop-Down
Menü innerhalb der Funktionsleiste erhält, sondern direkt an der entsprechenden Textstelle. Das Konzept der Annotationen, deren Anforderung und
Visualisierung wurde hingegen zum ersten Mal in dieser Bachelorarbeit vorgestellt und realisiert.
Eine weitere verwandte Arbeit ist [2, A Framework for Interactive Proof].
Dort wird ein Framework für interaktive Beweisführung vorgestellt, dessen
Komponenten über das
PGIP Protokoll kommunizieren. Als Benutzerschnitt-
stelle zu diesem Framework wird ein ASCII basiertes Plugin mit dem Namen
ProofGeneral vorgestellt. In diesem Plugin wird jede Zeile nach dem Schreiben zum
Prover
geschickt. So wird lediglich eine Sequenz von Anweisun-
gen erstellt, die von einem mathematischen Assistenzsystem benutzt werden
kann, um einen mathematischen Beweis zu erstellen. Das ProofGeneral Plugin wird in [1, Proof General: A Generic Tool for Proof Development] genauer
erläutert. Im Gegensatz dazu bietet das in dieser Arbeit vorgestellte Plugin
eine generische Schnittstelle zu einem mathematischen Assistenzsystem, welche auf strukturierten Dokumenten basiert.
59
KAPITEL 5.
VERWANDTE ARBEITEN
60
In dem Paper [5, Managing proof documents for asynchronous processing]
wird ein weiteres Verfahren vorgestellt, um semantische Dienste in TextEditoren anzubieten. Hierbei wird ein Protokoll (IAPP) vorgeschlagen, dass
die Rechte an Textabschnitten im Dokument zwischen Autor und semantischen Diensten kontinuierlich überträgt, um Konikte auszuschliessen. Das
dadurch zwangsläuge Blockieren von Dokumentteilen tritt in dem in dieser Arbeit vorgestellten Mediator Plugin nicht auf, da eine Update-basierte
Schnittstelle verwendet wird. Die Auösung von Konikten wird bei der Mediator Architektur vom Server durchgeführt, wobei die Änderungen des Autors immer die höchste Priorität haben. Ausserdem werden asynchrone Ergebnisse vom Plugin nur dann eingefügt, wenn diese vorher vom Benutzer
angefordert wurden. Dies kann in Form von Annotationen im AnnotationsModus oder von Updates während des Bearbeiten-Modus geschehen.
Kapitel 6
Zusammenfassung und Ausblick
In dieser Arbeit wurde ein Microsoft Word 2007 Plugin entwickelt, das eine
generische Schnittstelle zu dokumenten-basierten Diensten bereitstellt. Das
Plugin befähigt den Benutzer, ein Dokument durch ein mathematisches Assistenzsystem zu verizieren und etwaige Fehler in MS Word visualisieren
zu lassen. Hierzu wurde das Konzept von Annotationen vorgestellt, das es
ermöglicht, Statusinformationen und Fehlermeldungen für Dokumentteile anzuzeigen. Die Technik des Annotierens setzt sich zusammen aus der Vorbereitung des Dokumentes mit Aufbrechen von Textknoten und dem anschliessenden Einfügen der Annotationen unter Verwendung der Kommentarfunktion
von MS Word.
Desweiteren bietet das Plugin eine kontext-sensitive Menüinteraktion an, mit
deren Hilfe der Benutzer Unterstützung beim mathematischen Beweisen anfordern kann. Hierzu wurden die Techniken des Updatens eines Dokumentes und das Finden der aktuellen Textstelle entwickelt. Das Zusammenspiel
zwischen den Diensten des mathematischen Assistenzsystems und der Dokumentenverwaltung ermöglicht das gewünschte interaktive Verfassen mathematischer Dokumente. Das Plugin ermöglicht hierbei die Integration von
synchronen und asynchronen Ergebnissen einer Menüinteraktion in Form von
Annotationen und Updates.
In dieser Arbeit wurden bereits einige Bestandteile des Oce Open XML
Standards vorgestellt und eingesetzt. Es bietet sich an, die entwickelten Methoden schrittweise auf die bisher nicht betrachteten Bestandteile zu erweitern, ein Beispiel hierfür wären etwa Tabellen. Gegebenenfalls müssen die
Formatierungs-Heuristiken entsprechend angepasst werden.
Eine weitere interessante Fragestellung ist das kollaborative Bearbeiten ei-
61
KAPITEL 6.
ZUSAMMENFASSUNG UND AUSBLICK
62
nes Dokumentes. Mehrere Benutzer bearbeiten hierbei gleichzeitig dasselbe
Dokument. Hierzu müssten die lokalen Dokumente der Benutzer durch Updates auf den gleichen Stand gebracht, also synchronisiert werden. Um dies
umsetzen zu können, müsste eine neuartige Technik der Versionsverwaltung
entwickelt werden, die die Semantik des Dokumentes berücksichtigt.
Literaturverzeichnis
[1] D. Aspinall.
Proof General: A generic Tool for Proof Development.
Calculemus '07 / MKM '07: Proceedings of the 14th symposium on
Towards Mechanized Mathematical, pages 3842, (2000).
In
[2] D. Aspinall, C. Lüth, and D. Winterstein. A Framework for Interactive
Calculemus '07 / MKM '07: Proceedings of the 14th symposium
on Towards Mechanized Mathematical Assistants, pages 161175, Berlin,
Proof. In
Heidelberg, 2007. Springer-Verlag.
[3] ECMA International.
ECMA-376 / Oce Open XML File Formats,
2008.
[4] International Organization for Standardization. ISO Standards.
//www.iso.org/iso/home.htm.
[5] H. Gast.
http:
Managing proof documents for asynchronous processing.
S. Autexier and C. Benzmüller, editors,
In
8th Workshop on User Interfaces
for Theorem Provers (UITP'08), August 2008.
[6] Microsoft.
Das Microsoft Oce Open XML-Format.
microsoft.com/de-de/office/bb906068.aspx.
[7] Microsoft.
Microsoft Oce Word 2007.
com/de-de/word/HA101656411031.aspx.
http://msdn.
http://office.microsoft.
[8] J. Siekmann, C. Benzmüller, A. Fiedler, A. Meier, I. Normann, and
M. Pollet.
Proof Development in
ΩMEGA:
The Irrationality of
√
2.
pages 271314. Kluwer Academic Publishers, 2003.
[9] A. Laux und L. Martin. Xupdate xml update language (working draft),
2000.
http://xmldb-org.sourceforge.net/xupdate.
[10] W3C. XML Path Language (XPath) Version 1.0.
TR/xpath,
1999.
63
http://www.w3.org/
64
LITERATURVERZEICHNIS
[11] W3C. Extensible Markup Language(XML) 1.0 (Fifth Edition).
//www.w3.org/TR/xml,
http:
2008.
[12] M. Wagner, S. Autexier, and C. Benzmüller. PLATΩ: A Mediator between Text-Editors and Proof Assistance Systems.
In S. Autexier and
7th Workshop on User Interfaces for Theorem
Provers (UITP'06), volume 174(2) of Electronic Notes on Theoretical
Computer Science, pages 87107. Elsevier, August 2006.
C. Benzmüller, editors,
Herunterladen