'name' => 'notes#html',
'verb' => 'GET',
),
+ array(
+ 'url' => '/note/{guid}.txt',
+ 'name' => 'notes#text',
+ 'verb' => 'GET',
+ ),
array(
'url' => '/note/{guid}.xml',
'name' => 'notes#xml',
'guid' => $guid, 'username' => $this->user->getUid()
)
),
+ 'text' => $this->urlGen->linkToRoute(
+ 'grauphel.notes.text', array('guid' => $guid)
+ ),
'xml' => $this->urlGen->linkToRoute(
'grauphel.notes.xml', array('guid' => $guid)
),
} catch (\OCA\Grauphel\Converter\Exception $e) {
$res = new ErrorResponse(
'Error converting note to HTML.'
- . ' Please repport a bug to the grauphel developers.'
+ . ' Please report a bug to the grauphel developers.'
);
$res->setStatus(\OCP\AppFramework\Http::STATUS_NOT_FOUND);
return $res;
return urlencode($noteTitle) . '.html';
}
+ /**
+ * Output a note as a standalone text file
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function text($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;
+ }
+
+ $converter = new \OCA\Grauphel\Converter\ReStructuredText();
+ $converter->internalLinkHandler = array($this, 'textNoteLinkHandler');
+ try {
+ $text = $note->title . "\n"
+ . str_repeat('*', strlen($note->title)) . "\n"
+ . "\n";
+ $text .= $converter->convert($note->{'note-content'});
+ return new \OCA\Grauphel\Response\TextResponse($text);
+ } catch (\OCA\Grauphel\Converter\Exception $e) {
+ $res = new ErrorResponse(
+ 'Error converting note to reStructuredText.'
+ . ' Please report a bug to the grauphel developers.'
+ );
+ $res->setStatus(\OCP\AppFramework\Http::STATUS_NOT_FOUND);
+ return $res;
+ }
+ }
+
+ public function textNoteLinkHandler($noteTitle)
+ {
+ return $noteTitle;
+ }
+
/**
* Output a note in tomboy XML format
*
--- /dev/null
+<?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;
+
+/**
+ * Base class to convert tomboy XML to some other format.
+ *
+ * @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 Base
+{
+ /**
+ * Re-arranges the XML of formatted links to that clean link tags can
+ * be generated.
+ *
+ * Tomboy 1.15.2 allows link formatting, and the resulting XML is a
+ * mess of multiple(!) link tags that are within or around other formatting
+ * tags.
+ *
+ * This method tries to re-arrange the links so that only a single link tag
+ * appears with all the formatting inside.
+ *
+ * @param string $xmlContent Tomboy note content
+ *
+ * @return string XML content, with re-arranged link tags.
+ */
+ protected function fixNastyLinks($xmlContent)
+ {
+ preg_match_all(
+ '#(?:<.*>)?<link:internal>.+</link:internal><link:internal>.+</link:internal>#U',
+ $xmlContent,
+ $matches
+ );
+
+ foreach ($matches[0] as $nastyLink) {
+ $cleaner = str_replace('</link:internal><link:internal>', '', $nastyLink);
+ $cleaner = preg_replace('#<([a-z]+)><(link:internal)>#U', '<\2><\1>', $cleaner);
+ $cleaner = preg_replace('#</(link:internal)></([a-z]+)>#U', '</\2></\1>', $cleaner);
+ $cleaner = str_replace('</link:internal><link:internal>', '', $cleaner);
+ $xmlContent = str_replace($nastyLink, $cleaner, $xmlContent);
+ }
+
+ return $xmlContent;
+ }
+}
+?>
* @version Release: @package_version@
* @link http://cweiske.de/grauphel.htm
*/
-class Html
+class Html extends Base
{
protected static $tagMap = array(
'list' => 'ul',
{
return $linkUrl . '.htm';
}
-
- /**
- * Re-arranges the XML of formatted links to that clean link tags can
- * be generated.
- *
- * Tomboy 1.15.2 allows link formatting, and the resulting XML is a
- * mess of multiple(!) link tags that are within or around other formatting
- * tags.
- *
- * This method tries to re-arrange the links so that only a single link tag
- * appears with all the formatting inside.
- *
- * @param string $xmlContent Tomboy note content
- *
- * @return string XML content, with re-arranged link tags.
- */
- protected function fixNastyLinks($xmlContent)
- {
- preg_match_all(
- '#(?:<.*>)?<link:internal>.+</link:internal><link:internal>.+</link:internal>#U',
- $xmlContent,
- $matches
- );
-
- foreach ($matches[0] as $nastyLink) {
- $cleaner = str_replace('</link:internal><link:internal>', '', $nastyLink);
- $cleaner = preg_replace('#<([a-z]+)><(link:internal)>#U', '<\2><\1>', $cleaner);
- $cleaner = preg_replace('#</(link:internal)></([a-z]+)>#U', '</\2></\1>', $cleaner);
- $cleaner = str_replace('</link:internal><link:internal>', '', $cleaner);
- $xmlContent = str_replace($nastyLink, $cleaner, $xmlContent);
- }
-
- return $xmlContent;
- }
}
?>
--- /dev/null
+<?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 reStructuredText.
+ * Mainly used to paste the content of a note into an e-mail
+ *
+ * @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 ReStructuredText extends Base
+{
+ protected static $simpleMap = array(
+ 'bold' => '**',
+ 'italic' => '*',
+ 'monospace' => '``',
+ 'strikethrough' => '-',
+ 'highlight' => '**',
+ );
+
+ public $internalLinkHandler;
+
+
+
+ public function __construct()
+ {
+ $this->internalLinkHandler = array($this, 'internalLinkHandler');
+ }
+
+ /**
+ * Converts the tomboy note XML into reStructuredText
+ *
+ * @param string $xmlContent Tomboy note content
+ *
+ * @return string Plain text
+ */
+ public function convert($xmlContent)
+ {
+ if (strpos($xmlContent, '</link:internal><link:internal>') !== false) {
+ $xmlContent = $this->fixNastyLinks($xmlContent);
+ }
+
+ $rst = '';
+ $reader = new XMLReader();
+ $reader->xml(
+ '<?xml version="1.0" encoding="utf-8"?>' . "\n"
+ . '<content xmlns:size="size" xmlns:link="link">'
+ . $xmlContent
+ . '</content>'
+ );
+
+ $withinLink = false;
+ $store = &$rst;
+ $listLevel = -1;
+ $listPrefix = '';
+ $listItemCount = 0;
+ $heading = false;
+ $headingLength = 0;
+ while ($reader->read()) {
+ switch ($reader->nodeType) {
+ case XMLReader::ELEMENT:
+ //echo $reader->name . "\n";
+ if (isset(static::$simpleMap[$reader->name])) {
+ $store .= static::$simpleMap[$reader->name];
+ } else if ($reader->name == 'list') {
+ ++$listLevel;
+ $listItemCount = 0;
+ $listPrefix = str_repeat(' ', $listLevel);
+ } else if ($reader->name == 'list-item') {
+ ++$listItemCount;
+ if ($listItemCount == 1) {
+ $store .= "\n";
+ }
+ $store .= $listPrefix . '- ';
+ } else if ($reader->name == 'size:large'
+ || $reader->name == 'size:huge'
+ ) {
+ $store .= "\n";
+ $heading = true;
+ } else if (substr($reader->name, 0, 5) == 'link:') {
+ $withinLink = true;
+ $linkText = '';
+ $store = &$linkText;
+ }
+ break;
+ case XMLReader::END_ELEMENT:
+ if (isset(static::$simpleMap[$reader->name])) {
+ $store .= static::$simpleMap[$reader->name];
+ } else if ($reader->name == 'list') {
+ --$listLevel;
+ $listPrefix = str_repeat(' ', $listLevel);
+ if ($listLevel == -1) {
+ $store .= "\n";
+ }
+ } else if ($reader->name == 'size:large') {
+ $store .= "\n" . str_repeat('-', $headingLength);
+ $heading = false;
+ } else if ($reader->name == 'size:huge') {
+ $store .= "\n" . str_repeat('=', $headingLength);
+ $heading = false;
+ } else if (substr($reader->name, 0, 5) == 'link:') {
+ $withinLink = false;
+ $store = &$rst;
+ $linkUrl = htmlspecialchars_decode(strip_tags($linkText));
+ if ($reader->name == 'link:internal') {
+ $linkUrl = call_user_func($this->internalLinkHandler, $linkUrl);
+ } else {
+ $linkUrl = $this->fixLinkUrl($linkUrl);
+ }
+ $store .= $linkUrl;
+ }
+ break;
+ case XMLReader::TEXT:
+ case XMLReader::SIGNIFICANT_WHITESPACE:
+ if ($heading) {
+ $headingLength = strlen(trim($reader->value));
+ $store .= trim($reader->value);
+ } else {
+ $text = wordwrap($reader->value, 72 - 2 * $listLevel, "\n", true);
+ $parts = explode("\n", $text);
+ foreach ($parts as $k => $v) {
+ if ($k == 0) {
+ continue;
+ }
+ if ($v != '') {
+ $parts[$k] = str_repeat(' ', $listLevel * 2 + 2) . $v;
+ }
+ }
+ $store .= implode("\n", $parts);
+ }
+ break;
+ default:
+ throw new Exception(
+ 'Unsupported XML node type: ' . $reader->nodeType
+ );
+ }
+ }
+
+ return $rst;
+ }
+
+ /**
+ * Fixes external URLs without a protocol
+ *
+ * @param string $linkUrl URL to fix
+ *
+ * @return string Fixed URL
+ */
+ protected function fixLinkUrl($linkUrl)
+ {
+ if ($linkUrl{0} == '/') {
+ //Unix file path
+ $linkUrl = 'file://' . $linkUrl;
+ }
+ return $linkUrl;
+ }
+
+ /**
+ * Dummy internal link handler that simply adds ".htm" to the note title
+ *
+ * @param string $linkUrl Title of page that is linked
+ *
+ * @return string URL to link to
+ */
+ public function internalLinkHandler($linkUrl)
+ {
+ return $linkUrl . '.htm';
+ }
+}
+?>
--- /dev/null
+<?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\Response;
+
+/**
+ * Returns plain text
+ *
+ * @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 TextResponse extends \OCP\AppFramework\Http\Response
+{
+ protected $text;
+
+ public function __construct($text)
+ {
+ $this->setStatus(\OCP\AppFramework\Http::STATUS_OK);
+ $this->addHeader('Content-Type', 'text/plain; charset=utf-8');
+ $this->text = $text;
+ }
+
+ public function render()
+ {
+ return $this->text;
+ }
+}
+?>
<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']['text']); ?>">Text</a>
<a class="button" href="<?php echo p($_['links']['json']); ?>">JSON</a>
<a class="button" href="<?php echo p($_['links']['xml']); ?>">XML</a>
</div>