9 * @author Christian Weiske <cweiske@cweiske.de>
10 * @copyright 2014 Christian Weiske
11 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
12 * @link http://cweiske.de/grauphel.htm
14 namespace OCA\Grauphel\Converter;
18 * Convert Tomboy note XML to HTML
20 * Tomboy already ships with a converter:
21 * https://git.gnome.org/browse/tomboy/tree/Tomboy/Addins/ExportToHtml/ExportToHtml.xsl
22 * We cannot use it since we want nice callbacks, and we do not want to rely
23 * on the PHP XSL extension, and we have to fix the links.
27 * @author Christian Weiske <cweiske@cweiske.de>
28 * @copyright 2014 Christian Weiske
29 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
30 * @version Release: @package_version@
31 * @link http://cweiske.de/grauphel.htm
35 protected static $tagMap = array(
43 protected static $styleClassMap = array(
44 'strikethrough' => 'strikethrough',
45 'highlight' => 'highlight',
46 'size:small' => 'small',
47 'size:large' => 'large',
48 'size:huge' => 'huge',
51 public $internalLinkHandler;
55 public function __construct()
57 $this->internalLinkHandler = array($this, 'internalLinkHandler');
61 * Converts the tomboy note XML into HTML
63 * @param string $xmlContent Tomboy note content
67 public function convert($xmlContent)
69 if (strpos($xmlContent, '</link:internal><link:internal>') !== false) {
70 $xmlContent = $this->fixNastyLinks($xmlContent);
74 $reader = new XMLReader();
76 '<?xml version="1.0" encoding="utf-8"?>' . "\n"
77 . '<content xmlns:size="size" xmlns:link="link">'
84 while ($reader->read()) {
85 switch ($reader->nodeType) {
86 case XMLReader::ELEMENT:
87 //echo $reader->name . "\n";
88 if (isset(static::$tagMap[$reader->name])) {
89 $store .= '<' . static::$tagMap[$reader->name] . '>';
90 } else if (isset(static::$styleClassMap[$reader->name])) {
91 $store .= '<span class="'
92 . static::$styleClassMap[$reader->name]
94 } else if (substr($reader->name, 0, 5) == 'link:') {
100 case XMLReader::END_ELEMENT:
101 if (isset(static::$tagMap[$reader->name])) {
102 $store .= '</' . static::$tagMap[$reader->name] . '>';
103 } else if (isset(static::$styleClassMap[$reader->name])) {
105 } else if (substr($reader->name, 0, 5) == 'link:') {
108 $linkUrl = htmlspecialchars_decode(strip_tags($linkText));
109 if ($reader->name == 'link:internal') {
110 $linkUrl = call_user_func($this->internalLinkHandler, $linkUrl);
112 $linkUrl = $this->fixLinkUrl($linkUrl);
114 $store .= '<a href="' . htmlspecialchars($linkUrl) . '">'
119 case XMLReader::TEXT:
120 case XMLReader::SIGNIFICANT_WHITESPACE:
121 $store .= nl2br(htmlspecialchars($reader->value));
125 'Unsupported XML node type: ' . $reader->nodeType
130 $html = str_replace("</ul><br />\n", "</ul>\n", $html);
136 * Fixes external URLs without a protocol
138 * @param string $linkUrl URL to fix
140 * @return string Fixed URL
142 protected function fixLinkUrl($linkUrl)
144 if ($linkUrl{0} == '/') {
146 $linkUrl = 'file://' . $linkUrl;
152 * Dummy internal link handler that simply adds ".htm" to the note title
154 * @param string $linkUrl Title of page that is linked
156 * @return string URL to link to
158 public function internalLinkHandler($linkUrl)
160 return $linkUrl . '.htm';
164 * Re-arranges the XML of formatted links to that clean link tags can
167 * Tomboy 1.15.2 allows link formatting, and the resulting XML is a
168 * mess of multiple(!) link tags that are within or around other formatting
171 * This method tries to re-arrange the links so that only a single link tag
172 * appears with all the formatting inside.
174 * @param string $xmlContent Tomboy note content
176 * @return string XML content, with re-arranged link tags.
178 protected function fixNastyLinks($xmlContent)
181 '#(?:<.*>)?<link:internal>.+</link:internal><link:internal>.+</link:internal>#U',
186 foreach ($matches[0] as $nastyLink) {
187 $cleaner = str_replace('</link:internal><link:internal>', '', $nastyLink);
188 $cleaner = preg_replace('#<([a-z]+)><(link:internal)>#U', '<\2><\1>', $cleaner);
189 $cleaner = preg_replace('#</(link:internal)></([a-z]+)>#U', '</\2></\1>', $cleaner);
190 $cleaner = str_replace('</link:internal><link:internal>', '', $cleaner);
191 $xmlContent = str_replace($nastyLink, $cleaner, $xmlContent);