standlone HTML output
authorChristian Weiske <cweiske@cweiske.de>
Tue, 17 Mar 2015 18:53:49 +0000 (19:53 +0100)
committerChristian Weiske <cweiske@cweiske.de>
Tue, 17 Mar 2015 18:53:49 +0000 (19:53 +0100)
appinfo/routes.php
controller/guicontroller.php
controller/notescontroller.php
lib/converter/cleanhtml.php [new file with mode: 0644]
templates/gui-note.php

index 1c7e50bf1821d07015f8519f340e111bba5a7463..c96ec30f1dd7e99e9ccb47edea73ae741e877187 100644 (file)
@@ -68,6 +68,11 @@ $application->registerRoutes(
                 'name' => 'gui#tag',
                 'verb' => 'GET',
             ),
                 'name' => 'gui#tag',
                 'verb' => 'GET',
             ),
+            array(
+                'url'  => '/note/{guid}.html',
+                'name' => 'notes#html',
+                'verb' => 'GET',
+            ),
             array(
                 'url'  => '/note/{guid}.xml',
                 'name' => 'notes#xml',
             array(
                 'url'  => '/note/{guid}.xml',
                 'name' => 'notes#xml',
index 8ebea8c58f5b8900e4dfeb7a14cc97ed1e079f13..15380c7294c479d1e5490a4ba49139c73c7e5ea5 100644 (file)
@@ -122,6 +122,9 @@ class GuiController extends Controller
                 'note' => $note,
                 'note-content' => $contentHtml,
                 'links' => array(
                 'note' => $note,
                 'note-content' => $contentHtml,
                 'links' => array(
+                    'html' => $this->urlGen->linkToRoute(
+                        'grauphel.notes.html', array('guid' => $guid)
+                    ),
                     'json' => $this->urlGen->linkToRoute(
                         'grauphel.api.note', array(
                             'guid' => $guid, 'username' => $this->user->getUid()
                     'json' => $this->urlGen->linkToRoute(
                         'grauphel.api.note', array(
                             'guid' => $guid, 'username' => $this->user->getUid()
index 5618bcbb04b33473e9be78a88cb36e4abe4dc4bf..893a1006f27dc3973d47818b08daa77eedc10fc3 100644 (file)
@@ -47,6 +47,100 @@ class NotesController extends Controller
         header('HTTP/1.0 500 Internal Server Error');
     }
 
         header('HTTP/1.0 500 Internal Server Error');
     }
 
+    /**
+     * Output a note as a standalone HTML file
+     *
+     * @NoAdminRequired
+     * @NoCSRFRequired
+     */
+    public function html($guid)
+    {
+        $note = $this->getNotes()->load($guid, false);
+        if ($note === null) {
+            $res = new ErrorResponse('Note does not exist');
+            $res->setStatus(\OCP\AppFramework\Http::STATUS_NOT_FOUND);
+            return $res;
+        }
+
+        $xw = new \XMLWriter();
+        $xw->openMemory();
+        $xw->setIndent(true);
+        $xw->setIndentString(' ');
+        $xw->startDocument('1.0', 'utf-8');
+        $xw->writeRaw(
+            '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
+            . ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
+            . "\n"
+        );
+
+        $xw->startElementNS(null, 'html', 'http://www.w3.org/1999/xhtml');
+
+        //head
+        $xw->startElement('head');
+        $xw->writeElement('title', $note->title);
+
+        $xw->startElement('meta');
+        $xw->writeAttribute('name', 'author');
+        $xw->writeAttribute('content', $this->user->getDisplayName());
+        $xw->endElement();
+
+        $xw->startElement('meta');
+        $xw->writeAttribute('http-equiv', 'Content-Type');
+        $xw->writeAttribute('content', 'text/html; charset=utf-8');
+        $xw->endElement();
+
+        $xw->startElement('link');
+        $xw->writeAttribute('rel', 'schema.DC');
+        $xw->writeAttribute('href', 'http://purl.org/dc/elements/1.1/');
+        $xw->endElement();
+
+        $xw->startElement('meta');
+        $xw->writeAttribute('name', 'DC.date.created');
+        $xw->writeAttribute(
+            'content', date('c', strtotime($note->{'create-date'}))
+        );
+        $xw->endElement();
+
+        $xw->startElement('meta');
+        $xw->writeAttribute('name', 'DC.date.modified');
+        $xw->writeAttribute(
+            'content', date('c', strtotime($note->{'last-change-date'}))
+        );
+        $xw->endElement();
+
+        $xw->endElement();//head
+
+        //body
+        $xw->startElement('body');
+
+        $xw->writeElement('h1', $note->title);
+
+        $converter = new \OCA\Grauphel\Converter\CleanHtml();
+        $converter->internalLinkHandler = array($this, 'htmlNoteLinkHandler');
+        try {
+            $xw->writeRaw(
+                $converter->convert($note->{'note-content'})
+            );
+        } catch (\OCA\Grauphel\Converter\Exception $e) {
+            $res = new ErrorResponse(
+                'Error converting note to HTML.'
+                . ' Please repport a bug to the grauphel developers.'
+            );
+            $res->setStatus(\OCP\AppFramework\Http::STATUS_NOT_FOUND);
+            return $res;
+        }
+
+        $xw->endElement();//body
+
+        $xw->endElement();//html
+        return new \OCA\Grauphel\Response\XmlResponse($xw->outputMemory());
+    }
+
+    public function htmlNoteLinkHandler($noteTitle)
+    {
+        return urlencode($noteTitle) . '.html';
+    }
+
     /**
      * Output a note in tomboy XML format
      *
     /**
      * Output a note in tomboy XML format
      *
diff --git a/lib/converter/cleanhtml.php b/lib/converter/cleanhtml.php
new file mode 100644 (file)
index 0000000..6c5dabf
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Part of grauphel
+ *
+ * PHP version 5
+ *
+ * @category  Tools
+ * @package   Grauphel
+ * @author    Christian Weiske <cweiske@cweiske.de>
+ * @copyright 2014 Christian Weiske
+ * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
+ * @link      http://cweiske.de/grauphel.htm
+ */
+namespace OCA\Grauphel\Converter;
+use \XMLReader;
+
+/**
+ * Convert Tomboy note XML to HTML that can be used (nearly) standalone.
+ * This means it tries to use as many native tags as possible and
+ * does not rely on classes so much.
+ *
+ * @category  Tools
+ * @package   Grauphel
+ * @author    Christian Weiske <cweiske@cweiske.de>
+ * @copyright 2014 Christian Weiske
+ * @license   http://www.gnu.org/licenses/agpl.html GNU AGPL v3
+ * @version   Release: @package_version@
+ * @link      http://cweiske.de/grauphel.htm
+ */
+class CleanHtml extends Html
+{
+    protected static $tagMap = array(
+        'list'      => 'ul',
+        'list-item' => 'li',
+        'bold'      => 'b',
+        'italic'    => 'i',
+        'monospace' => 'tt',
+
+        'size:large' => 'h3',
+        'size:huge'  => 'h2',
+
+        'strikethrough' => 'del',
+        'highlight'     => 'ins',
+    );
+
+    protected static $styleClassMap = array(
+        'size:small' => 'small',
+    );
+
+    /**
+     * Converts the tomboy note XML into HTML.
+     * Cleans HTML a bit up after it has been generated with the clean tags.
+     *
+     * @param string $xmlContent Tomboy note content
+     *
+     * @return string HTML
+     */
+    public function convert($xmlContent)
+    {
+        $html = parent::convert($xmlContent);
+        $html = str_replace('</h2><br />', '</h2>', $html);
+        $html = str_replace('</h3><br />', '</h3>', $html);
+        $html = str_replace("<br />\n</h2>", "</h2>\n", $html);
+        $html = str_replace("<br />\n</h3>", "</h3>\n", $html);
+        $html = str_replace("<br />\n</li>", "</li>\n", $html);
+        $html = str_replace("<br />\n<ul>", "<ul>\n", $html);
+        return $html;
+    }
+}
+?>
index fb2d741c2381803378e954f397388558760fab9c..86336bc29c371404a0ea2fe93f6db11993bfab11 100644 (file)
@@ -7,6 +7,7 @@
 
 <div id="app-content" class="content">
  <div class="actions">
 
 <div id="app-content" class="content">
  <div class="actions">
+  <a class="button" href="<?php echo p($_['links']['html']); ?>">HTML</a>
   <a class="button" href="<?php echo p($_['links']['json']); ?>">JSON</a>
   <a class="button" href="<?php echo p($_['links']['xml']); ?>">XML</a>
  </div>
   <a class="button" href="<?php echo p($_['links']['json']); ?>">JSON</a>
   <a class="button" href="<?php echo p($_['links']['xml']); ?>">XML</a>
  </div>