DokuWiki

It's better when it's simple

Benutzer-Werkzeuge

Webseiten-Werkzeuge


de:plugin:odt:implementodtsupport

ODT Plugin-Homepage

ODT-Unterstützung zu einem Plugin hinzufügen

Im folgenden gebe ich eine kurze Einführung darüber, wie ein anderes Plugin das ODT-Export-Plugin benutzen kann, um seinen Inhalt nach ODT zu exportieren. Da dies nur eine kurze Einführung ist, erhebt sie keinen Anspruch darauf eine komplette Anleitung für die Funktionen des ODT-Plugins oder das ODT-XML-Format zu sein.

Vorrausetzungen

  1. Sie müsen das „OpenOffice.org Export“-Plugin installieren. Siehe odt.
  2. Natürlich benötigen Sie als Basis ein funktionierendes Plugin das um ODT-Export erweitert werden soll. Siehe extensions für Informationen darüber wie man ein eigenes Plugin schreibt.
  3. Sie sollten die Grundlagen von PHP, XHTML und XML kennen.

Den ODT-Export implementieren

Im folgenden nehme ich an, dass das zu erweiternde Plugin ein DokuWiki_Syntax_Plugin ist. Das Vorgehen um andere Arten von Plugins um ODT-Export zu erweitern kann abweichen.

Zwischen den Renderer-Ausgabeformaten unterscheiden

Jedes Plugin das vom Typ DokuWiki_Syntax_Plugin ist, muss die Funktion render implementieren, welche die Hauptarbeit übernimmt bezüglich des Ausliefern des Inhalts in den verschiedenen Formaten. Bei einem Plugin das bis jetzt nur <abbr>Extensible Hypertext Markup Language (XHTML)</abbr>-Ausgabe unterstützt, besteht der offensichtliche erste Schritt darin, zwischen den Ausgabeformaten zu unterschieden und zu der für ein bestimmtes Ausgabeformat entsprechenden Funktion zu verzweigen.

Grundsätzlich sieht eine existierende render Funktion wie folgt aus:

    public function render($mode, &$renderer, $indata) {
        if ($mode == 'xhtml') {
            // XHTML-Inhalt generieren...
            $renderer->doc .= 'Mein XHTML Code und Inhalt';
            return true;
        }
 
        // Bisher unterstützen wir noch keine anderen Ausgabeformate.
        return false;
    }

Also, müssen wir die Funktion erweitern um den Modus 'odt' abzufangen und wir müssen unseren ODT-Inhalt erzeugenden Code hinzufügen. Die schönste Lösung ist es die render Funktion nur zu benutzen, um in die entsprechende Funktion für die Inhaltsgenerierung zu verzweigen und alle Parameter durchzureichen.

Der angepasste Code könnte folgendermassen aussehen:

    public function render($mode, &$renderer, $indata) {
        switch ($mode) {
            case "xhtml":
                // Aufruf der XHTML render Funktion.
                $this->render_for_xhtml($renderer, $state, $data);
                break;
            case "odt":
                // Aufruf der ODT render Funktion.
                $this->render_for_odt($renderer, $state, $data);
                break;
            default:
                // Andere Ausgabeformate die wir nicht unterstützen.
                return false;
        }
 
        // Erfolg. Wir unterstützen das Format.
        return true;
    }
 
    function render_for_xhtml ($mode, &$renderer, $indata) {
        // Generiere XHTML Inhalt...
        $renderer->doc .= 'Mein XHTML Code und Inhalt';
    }
 
    function render_for_odt ($mode, &$renderer, $indata) {
        // Generiere ODT Inhalt...
        $renderer->doc .= 'Mein ODT XML Code und Inhalt';
    }

Gültigen ODT XML Inhalt erzeugen

Wie Sie eventuell bereits bemerkt haben, besteht die Hauptarbeit oder der Hauptaufwand natürlich darin, eine gültige ODT-Datei mit gültigem ODT XML-Inhalt zu erzeugen. Eine ODT-Datei ist üblicherweise ein ZIP-Archiv welches aus folgender Verzeichnisstruktur besteht:

  • Der Ordner „Thumbnails“:
    Er beinhaltet Thumbnails der Dokument-Seiten. Ich vermute, dass sie von der Druckvorschau verwendet werden.
  • Der Ordner „META-INF“:
    Er beinhaltet die Datei „manifest.xml“. Die Datei beinhaltet eine Liste der Dateien die in einer ODT-ZIP-Datei enthalten sind und ihrer Media types.
  • Der Ordner „Pictures“:
    Dieser Ordner ist nur vorhanden, wenn das ODT-Dokument Bilder enthält. Bilder können in diesme Ordner gespeichert werden.
  • Die Datei „content.xml“:
    Diese Datei enthält den eigentlichen Inhalt des Dokuments ausser binäre Dateien wie Bilder.
  • Die Datei „styles.xml“:
    Diese Datei enthält Style-Definitionen. Style-Definitionen beschreiben das Layout des Inhalts. Ein Style kann z.B. die Schriftfarbe, die Textausrichtung oder die Linienfarbe für Grafiken definieren. Style-Definitionen sind auch in der Datei content.xml vorhanden.
  • Die Datei „meta.xml“:
    Diese Datei enthält Meta-Informationen über das ODT-Dokument wie zum Beispiel den Namen des Autors.
  • Die Datei „settings.xml“:
    Diese Datei enthält Informationen die nicht zum eigentlichen Inhalt des Dokument gehören, aber für die Anwendung die das Dokument verwendet nützlich sind, z.B. für OpenOffice Writer.
  • Die Datei „mimetype“:
    Die Datei enthält den Mimetype.

Wenn Sie selber einmal reinschauen möchten, benennen Sie einfach ein ODT-Dokument um und ändern die Dateiendung von .odt nach .zip. Danach können Sie das Archiv entpacken und reinschauen.

Schon die Generierung einer leeren Datei würde einiges an Arbeit für uns bedeuten. Den Dank dafür, dass wir diese Arbeit nicht selbst erledigen müssen gehört dem ODT-Export-Plugin von Andreas Gohr, Aurélien Bompard und Florian Lamml. Das einzige was unser Plugin tun muss, ist gültigen ODT XML-Code für 'unseren' Inhalt einfügen. Das Anlegen und Paketisieren der Datei wird komplett durch das ODT-Export-Plugin erledigt.

Unseren ersten Inhalt erzeugen

Lassen Sie uns unsere erste einfache Textausgabe erzeugen. Stellen Sie sicher das Ihre ODT render Funktion wie folgt aussieht:

    function render_for_odt ($mode, &$renderer, $indata) {
        // Generiere ODT Inhalt...
        $renderer->doc. = 'Mein ODT XML Code und Inhalt';
    }

Öffnen Sie Ihre Wiki-Seite, exportieren Sie sie und schauen sie sich das Ergebnis an. Der Text wurde an der aktuellen Position direkt zwischen dem anderen Inhalt eingefügt.

Einen Pharagraphen erzeugen

Jetzt umschliessen wir den Text mit einem Pharagraphen. Wir rufen die Funktionen p_open und p_close (siehe ODT Export-Plugin, Datei renderer.php falls Sie mögen). Also müssen wir den ODT XML Code nicht selber schreiben. Stellen Sie sicher, dass Ihre render Funktion wie folgt aussieht:

    function render_for_odt ($mode, &$renderer, $indata) {
        // Generiere ODT Inhalt...
        $renderer->p_open();
        $renderer->doc .= 'Mein ODT XML Code und Inhalt';
        $renderer->p_close();
    }

Und wieder, testen Sie es und schauen Sie sich das Ergebnis an (Öffnen Sie Ihre Wiki-Seite, exportien Sie sie nach ODT und schauen Sie sie sich an), keine Änderung.

Einen Zeilenumbruch einfügen

Wenn Sie eine neue Zeile einfügen möchten, rufen Sie einfach die Funktion linebreak auf. Ihre render Funktion sollte wie folgt aussehen:

    function render_for_odt ($mode, &$renderer, $indata) {
        // Generiere ODT Inhalt...
        $renderer->p_open();
        $renderer->doc .= 'Mein ODT XML Code und Inhalt';
        $renderer->linebreak();
        $renderer->doc .= 'Dies ist eine weitere Zeile';
        $renderer->p_close();
    }

Text-Styles

Das ODT-Export-Plugin enthält auch Funktionen für die vielen Text-Styles wie fett oder schräggestellt. Stellen Sie sicher, dass Ihre render Funktion wie folgt aussieht:

    function render_for_odt ($mode, &$renderer, $indata) {
        // Generiere ODT Inhalt...
        $renderer->p_open();
        $renderer->doc .= 'Mein ODT XML Code und Inhalt';
        $renderer->linebreak();
        $renderer->doc .= 'Dies ist eine weitere Zeile';
        $renderer->linebreak();
        $renderer->linebreak();
 
        $renderer->strong_open();
        $renderer->doc .= 'Dies ist fetter Text.';
        $renderer->strong_close();
        $renderer->linebreak();
        $renderer->linebreak();
 
        $renderer->emphasis_open();
        $renderer->doc .= 'This is emphasis text.';
        $renderer->emphasis_close();
        $renderer->linebreak();
        $renderer->linebreak();
 
        $renderer->underline_open();
        $renderer->doc .= 'Dies ist unterstrichener Text.';
        $renderer->underline_close();
        $renderer->linebreak();
        $renderer->linebreak();
 
        $renderer->monospace_open();
        $renderer->doc .= 'This is monospace text.';
        $renderer->monospace_close();
        $renderer->linebreak();
        $renderer->linebreak();
 
        $renderer->subscript_open();
        $renderer->doc .= 'Dies ist tiefgestellter Text.';
        $renderer->subscript_close();
        $renderer->linebreak();
        $renderer->linebreak();
 
        $renderer->superscript_open();
        $renderer->doc .= 'Dies ist hochgestellter Text.';
        $renderer->superscript_close();
        $renderer->linebreak();
        $renderer->linebreak();
 
        $renderer->deleted_open();
        $renderer->doc .= 'Dies ist gelöschter Text.';
        $renderer->deleted_close();
        $renderer->linebreak();
        $renderer->linebreak();
 
        $renderer->p_close();
    }

Wenn Sie die Seite exportieren, werden Sie all die verschiedenen Text-Styles sehen. Wenn Sie verschiedene Text-Styles zur gleichen Zeit anwenden möchten, kombinieren Sie einfach die Funktionen. Der folgende Code zeigt ein Beispiel das einen fetten und unterstrichenen Text erzeugt.

    function render_for_odt ($mode, &$renderer, $indata) {
        // Generiere ODT Inhalt...
        $renderer->p_open();
 
        $renderer->strong_open();
        $renderer->underline_open();
        $renderer->doc .= 'Dies ist fetter UND unterstrichener Text.';
        $renderer->underline_close();
        $renderer->strong_close();
        $renderer->linebreak();
 
        $renderer->p_close();
    }

Tabellen

Der folgende Code erzeugt eine 3×3 Tabelle mit einer Tabellenüberschrift über alle 3 Spalten.

    function render_for_odt ($mode, &$renderer, $indata) {
        // Generiere ODT Inhalt...
 
        // Diese Zeile ist wichtig!!!
        $renderer->p_close();
 
        $renderer->table_open(3,3);
 
        $renderer->tablerow_open();
        $renderer->tableheader_open(3,1);
        $renderer->doc .= 'Tabellenüberschrift.';
        $renderer->tableheader_close();
        $renderer->tablerow_close();
 
        $renderer->tablerow_open();
        $renderer->tablecell_open();
        $renderer->p_open();
        $renderer->doc .= 'Zelle 1/1';
        $renderer->p_close();
        $renderer->tablecell_close();
        $renderer->tablecell_open();
        $renderer->p_open();
        $renderer->doc .= 'Zelle 2/1';
        $renderer->p_close();
        $renderer->tablecell_close();
        $renderer->tablecell_open();
        $renderer->p_open();
        $renderer->doc .= 'Zelle 3/1';
        $renderer->p_close();
        $renderer->tablecell_close();
        $renderer->tablerow_close();
 
        $renderer->tablerow_open();
        $renderer->tablecell_open();
        $renderer->p_open();
        $renderer->doc .= 'Zelle 1/2';
        $renderer->p_close();
        $renderer->tablecell_close();
        $renderer->tablecell_open();
        $renderer->p_open();
        $renderer->doc .= 'Zelle 2/2';
        $renderer->p_close();
        $renderer->tablecell_close();
        $renderer->tablecell_open();
        $renderer->p_open();
        $renderer->doc .= 'Zelle 3/2';
        $renderer->p_close();
        $renderer->tablecell_close();
        $renderer->tablerow_close();
 
        $renderer->table_close();
    }

Der initiale Aufruf von p_close ist wichtig um sicherzustellen, dass der Pharagraph geschlossen wurde bevor die Tabelle erzeugt wird. Sie können p_close sogar aufrufen wenn kein Pharagraph offen ist, da die Funktion alle offenen Pharagraphen mitzählt. Wenn Sie vergessen den Pharagraphen zu schliessen, dann ist das resultierende ODT-Datei-Format korrumpiert weil Sie eine Tabelle in einem Pharagraphen eingefügt haben.

Bilder

Ein Bild kann einfach durch einen Aufruf der Funktion _odtAddImage mit Übergabe des Dateinamens als Parameter eingefügt werden. Stellen Sie sicher, dass der Dateiname den kompletten Pfad enthält, andererseits wird die Datei evtl. nicht gefunden. Der folgende Code zeigt ein Beispiel in welchem das Bild „beispiel.png“ innerhalb des Plugin-Unterverzeichnisses „images“ geladen wird (es wird angenommen, das DOKU_INC und DOKU_PLUGIN_IMAGES Standardwerte enthalten).

    function render_for_odt ($mode, &$renderer, $indata) {
        // Generiere ODT Inhalt...
        $renderer->_odtAddImage (DOKU_INC . DOKU_PLUGIN_IMAGES . 'beispiel.png');
    }

Zeichnungen

FIXME

CSS basierte Funktionen

Im ODT-Format benutzen Elemente wie Spans, Paragraphen, Frames und Tabellen Styles um das Aussehen des Elementes anzugeben. Diese Styles haben Properties die oft mit den CSS-Properties übereinstimmen. Aber einige Tatsachen machen das Schreiben von ODT-Styles zu einer erschöpfenden und lästigen Arbeit:

  • Die Style-Definitionen müssen dem ODT-Standard entsprechen. Dieser ist ziemlich groß und es kostet Zeit die gewünschten Informationen zu finden.
  • Die Style-Definitionen sind in XML definiert und können schnell einige Zeilen füllen und unübersichtlich werden
  • Die Properties sind gleich aber oft gibt es im ODT-Standard Ausnahmen zu CSS
  • Ein ODT-Style kann nicht innerhalb eines Elementes definiert werden.

Um die Last des Schreibens/Definierens von ODT-Styles von den Plugin-Entwicklern zu nehmen, wurden ODT-Funkionen geschrieben die CSS verwenden um den Style eines Elementes anzugeben. Somit wird es für Plugin-Entwickler aus folgenden Gründen viel einfacher nach ODT zu exportiern:

  • Existierende CSS-Styles von den Plugins aus 'style.css' oder anderen Dateien können wiederverwendet werden
  • Styles können an einige CSS basierte Funktionen direkt übergeben werden ähnlich zu XHTML-Code wie style='color:red;'
  • Viele Plugin-Entwickler sind vertraut mit CSS oder kennen es sehr gut
  • Im Internet gibt es mehr Informationen zu CSS als über ODT-Styles

In den folgenden Abschnitten werden die CSS basierten Funktionen des ODT renderers beschrieben. CSS Unterstützung im ODT renderer gibt es seit Release 2015-03-20 und die Entwicklung schreitet weiter voran.

CSS aus einer Datei importieren

Einige der Funktionen verwenden CSS-Code aus anderen Dateien wie z.B. 'style.css'. Die importierte Datei muss als Argument an diese Funktionen übergeben werden. Es folgt Beispielcode der den Import zeigt:

  // Importiere Wrap-CSS.
  if ( self::$import == NULL ) {
    self::$import = plugin_load('helper', 'odt_cssimport');
    self::$import->importFrom(DOKU_PLUGIN.'myplugin/style.css');
    self::$import->loadReplacements(DOKU_INC.DOKU_TPL.'style.ini');
  }
 
  // Jetzt kann $import in späteren Funktionsaufrufen verwendet werden...

Der Code speichert die importierte Datei in der statischen Klassenvariable $import. Dies verhindert, dass die Datei jedes mal importiert wird, wenn die handle oder render Funktion aufgerufen wird. In den folgenden Beispielen wird angenommen, dass eine statische Klassenvariable $import existiert, die die Informationen einer importierten CSS-Datei enthält.

Funktion _odtSpanOpenUseCSS

Die Funktion öffnet einen neuen Text-Bereich (span). Der Style wird über einen Klassen-String angegeben, der den CSS-Selektor repräsentiert. Eine importierte CSS-Datei muss ebenfalls an die Funktion übergeben werden. Hier ist ein Beispielaufruf:

$renderer->_odtSpanOpenUseCSS (self::$import,
                               'dokuwiki myplugin',
                               DOKU_PLUGIN.'myplugin/');

Dies öffnet einen Span, der die CSS-Properties der Klassen dokuwiki und myplugin verwendet. Das dritte Argument gibt einen Pfad an, der dazu verwendet werden kann die URL eines background-image in einen lokalen Pfad umzuwandeln. In diesem Beispiel würde eine URL wie „background-image: url(images/example.png);“ umgesetzt in den lokalen Pfad „DOKU_PLUGIN.'myplugin/images/example.png'“.

Die Funktion verwendet die folgenden CSS-Properties:

  • background-color
  • color
  • font-weight
  • font-size
  • border
  • font-family
  • font-variant
  • letter-spacing
  • vertical-align
  • background-image (emulated)

Zum Schliessen des Text-Bereichs muss die Funktion _odtSpanClose() aufgerufen werden.

ToDo:

Function _odtSpanOpenUseCSSStyle

The function opens a new text span. The style is specified as a string including the CSS properties. Here is an example call:

$renderer->_odtSpanOpenUseCSSStyle('color:red;background-color:black');

This will open a span with a red text color on a black background.

As a second parameter the function also optionally accepts a URL replacement path, see function _odtSpanOpenUseCSS. For supported properties, please see function _odtSpanOpenUseCSS. The function _odtSpanClose() needs to be called to close the text span.

Function _odtSpanOpenUseProperties

The function opens a new text span. The style is specified by passing an assoziative array carrying the CSS properties. Here is an example call:

$properties ['color'] = 'red';
$properties ['background-color'] = 'black';
$renderer->_odtSpanOpenUseProperties($properties);

This will open a span with a red text color on a black background.

For supported properties, please see function _odtSpanOpenUseCSS. The function _odtSpanClose() needs to be called to close the text span.

Function _odtParagraphOpenUseCSS

The function opens a new paragraph. The style is specified by a class string which represents the CSS selector. An imported CSS file needs to be passed to the function also. Here is an example call:

$renderer->_odtParagraphOpenUseCSS (self::$import,
                                    'dokuwiki myplugin',
                                    DOKU_PLUGIN.'myplugin/');

This will open a paragraph which uses the CSS properties of the classes dokuwiki and myplugin. The third argument represents a path which can be used to convert the URL of a background-image into a local path. In this example a URL like from „background-image: url(images/example.png);“ would become the local path „DOKU_PLUGIN.'myplugin/images/example.png'“.

The function makes use of the following CSS properties:

  • background-color
  • color
  • font-weight
  • font-size
  • border
  • font-family
  • font-variant
  • letter-spacing
  • vertical-align
  • line-height
  • background-image (emulated)

The function p_close() needs to be called to close the paragraph.

Function _odtParagraphOpenUseCSSStyle

The function opens a new paragraph. The style is specified as a string including the CSS properties. Here is an example call:

$renderer->_odtParagraphOpenUseCSSStyle('color:red;background-color:black');

This will open a paragraph with a red text color on a black background.

As a second parameter the function also optionally accepts a URL replacement path, see function _odtParagraphOpenUseCSS. For supported properties, please see function _odtParagraphOpenUseCSS. The function p_close() needs to be called to close the paragraph.

Function _odtParagraphOpenUseProperties

The function opens a new paragraph. The style is specified by passing an assoziative array carrying the CSS properties. Here is an example call:

$properties ['color'] = 'red';
$properties ['background-color'] = 'black';
$renderer->_odtParagraphOpenUseCSSStyle($properties);

This will open a paragraph with a red text color on a black background.

For supported properties, please see function _odtParagraphOpenUseCSS. The function p_close() needs to be called to close the paragraph.

Function _odtDivOpenAsFrameUseCSS

The function opens a new frame(s) to represent a div element. The style is specified by a class string which represents the CSS selector. An imported CSS file needs to be passed to the function also. Here is an example call:

$renderer->_odtDivOpenAsFrameUseCSS (self::$import,
                                    'dokuwiki myplugin',
                                    DOKU_PLUGIN.'myplugin/');

This will open a frame which uses the CSS properties of the classes dokuwiki and myplugin. The third argument represents a path which can be used to convert the URL of a background-image into a local path. In this example a URL like from „background-image: url(images/example.png);“ would become the local path „DOKU_PLUGIN.'myplugin/images/example.png'“.

The function makes use of the following CSS properties:

  • background-color
  • color
  • padding
  • margin
  • display
  • border-radius
  • min-height
  • background-image (emulated via an extra picture frame)

The function _odtDivCloseAsFrame needs to be called to close the paragraph.

de/plugin/odt/implementodtsupport.txt · Zuletzt geändert: 2017-01-14 14:54 von LarsDW223

Falls nicht anders bezeichnet, ist der Inhalt dieses Wikis unter der folgenden Lizenz veröffentlicht: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki