aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--index.php1
-rw-r--r--plugins/markdown/README.md21
-rw-r--r--plugins/markdown/markdown.php27
-rw-r--r--tests/plugins/PluginMarkdownTest.php29
-rw-r--r--tpl/editlink.html32
-rw-r--r--tpl/tools.html6
6 files changed, 82 insertions, 34 deletions
diff --git a/index.php b/index.php
index 84282b8d..5366cb0e 100644
--- a/index.php
+++ b/index.php
@@ -1078,6 +1078,7 @@ function renderPage($conf, $pluginManager)
1078 { 1078 {
1079 $data = array( 1079 $data = array(
1080 'pageabsaddr' => index_url($_SERVER), 1080 'pageabsaddr' => index_url($_SERVER),
1081 'sslenabled' => !empty($_SERVER['HTTPS'])
1081 ); 1082 );
1082 $pluginManager->executeHooks('render_tools', $data); 1083 $pluginManager->executeHooks('render_tools', $data);
1083 1084
diff --git a/plugins/markdown/README.md b/plugins/markdown/README.md
index c64a831a..aafcf066 100644
--- a/plugins/markdown/README.md
+++ b/plugins/markdown/README.md
@@ -20,26 +20,35 @@ The directory structure should look like:
20 |--- markdown.css 20 |--- markdown.css
21 |--- markdown.meta 21 |--- markdown.meta
22 |--- markdown.php 22 |--- markdown.php
23 |--- Parsedown.php
24 |--- README.md 23 |--- README.md
25``` 24```
26 25
27To enable the plugin, just check it in the plugin administration page. 26To enable the plugin, just check it in the plugin administration page.
28 27
29You can also add `markdown` to your list of enabled plugins in `data/config.php` 28You can also add `markdown` to your list of enabled plugins in `data/config.json.php`
30(`ENABLED_PLUGINS` array). 29(`general.enabled_plugins` list).
31 30
32This should look like: 31This should look like:
33 32
34``` 33```
35$GLOBALS['config']['ENABLED_PLUGINS'] = array('qrcode', 'any_other_plugin', 'markdown') 34"general": {
35 "enabled_plugins": [
36 "markdown",
37 [...]
38 ],
39}
36``` 40```
37 41
42Parsedown parsing library is imported using Composer. If you installed Shaarli using `git`,
43or the `master` branch, run
44
45 composer update --no-dev --prefer-dist
46
38### No Markdown tag 47### No Markdown tag
39 48
40If the tag `.nomarkdown` is set for a shaare, it won't be converted to Markdown syntax. 49If the tag `nomarkdown` is set for a shaare, it won't be converted to Markdown syntax.
41 50
42> Note: it's a private tag (leading dot), so it won't be displayed to visitors. 51> Note: this is a special tag, so it won't be displayed in link list.
43 52
44### HTML rendering 53### HTML rendering
45 54
diff --git a/plugins/markdown/markdown.php b/plugins/markdown/markdown.php
index a764b6fa..0cf6e6e2 100644
--- a/plugins/markdown/markdown.php
+++ b/plugins/markdown/markdown.php
@@ -22,7 +22,7 @@ function hook_markdown_render_linklist($data)
22{ 22{
23 foreach ($data['links'] as &$value) { 23 foreach ($data['links'] as &$value) {
24 if (!empty($value['tags']) && noMarkdownTag($value['tags'])) { 24 if (!empty($value['tags']) && noMarkdownTag($value['tags'])) {
25 $value['taglist'] = stripNoMarkdownTag($value['taglist']); 25 $value = stripNoMarkdownTag($value);
26 continue; 26 continue;
27 } 27 }
28 $value['description'] = process_markdown($value['description']); 28 $value['description'] = process_markdown($value['description']);
@@ -41,7 +41,7 @@ function hook_markdown_render_feed($data)
41{ 41{
42 foreach ($data['links'] as &$value) { 42 foreach ($data['links'] as &$value) {
43 if (!empty($value['tags']) && noMarkdownTag($value['tags'])) { 43 if (!empty($value['tags']) && noMarkdownTag($value['tags'])) {
44 $value['tags'] = stripNoMarkdownTag($value['tags']); 44 $value = stripNoMarkdownTag($value);
45 continue; 45 continue;
46 } 46 }
47 $value['description'] = process_markdown($value['description']); 47 $value['description'] = process_markdown($value['description']);
@@ -63,6 +63,7 @@ function hook_markdown_render_daily($data)
63 foreach ($data['cols'] as &$value) { 63 foreach ($data['cols'] as &$value) {
64 foreach ($value as &$value2) { 64 foreach ($value as &$value2) {
65 if (!empty($value2['tags']) && noMarkdownTag($value2['tags'])) { 65 if (!empty($value2['tags']) && noMarkdownTag($value2['tags'])) {
66 $value2 = stripNoMarkdownTag($value2);
66 continue; 67 continue;
67 } 68 }
68 $value2['formatedDescription'] = process_markdown($value2['formatedDescription']); 69 $value2['formatedDescription'] = process_markdown($value2['formatedDescription']);
@@ -81,20 +82,30 @@ function hook_markdown_render_daily($data)
81 */ 82 */
82function noMarkdownTag($tags) 83function noMarkdownTag($tags)
83{ 84{
84 return strpos($tags, NO_MD_TAG) !== false; 85 return preg_match('/(^|\s)'. NO_MD_TAG .'(\s|$)/', $tags);
85} 86}
86 87
87/** 88/**
88 * Remove the no-markdown meta tag so it won't be displayed. 89 * Remove the no-markdown meta tag so it won't be displayed.
89 * 90 *
90 * @param string $tags Tag list. 91 * @param array $link Link data.
91 * 92 *
92 * @return string tag list without no markdown tag. 93 * @return array Updated link without no markdown tag.
93 */ 94 */
94function stripNoMarkdownTag($tags) 95function stripNoMarkdownTag($link)
95{ 96{
96 unset($tags[array_search(NO_MD_TAG, $tags)]); 97 if (! empty($link['taglist'])) {
97 return array_values($tags); 98 $offset = array_search(NO_MD_TAG, $link['taglist']);
99 if ($offset !== false) {
100 unset($link['taglist'][$offset]);
101 }
102 }
103
104 if (!empty($link['tags'])) {
105 str_replace(NO_MD_TAG, '', $link['tags']);
106 }
107
108 return $link;
98} 109}
99 110
100/** 111/**
diff --git a/tests/plugins/PluginMarkdownTest.php b/tests/plugins/PluginMarkdownTest.php
index 12bdda24..17ef2280 100644
--- a/tests/plugins/PluginMarkdownTest.php
+++ b/tests/plugins/PluginMarkdownTest.php
@@ -8,8 +8,8 @@ require_once 'application/Utils.php';
8require_once 'plugins/markdown/markdown.php'; 8require_once 'plugins/markdown/markdown.php';
9 9
10/** 10/**
11 * Class PlugQrcodeTest 11 * Class PluginMarkdownTest
12 * Unit test for the QR-Code plugin 12 * Unit test for the Markdown plugin
13 */ 13 */
14class PluginMarkdownTest extends PHPUnit_Framework_TestCase 14class PluginMarkdownTest extends PHPUnit_Framework_TestCase
15{ 15{
@@ -130,8 +130,11 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
130 )) 130 ))
131 ); 131 );
132 132
133 $data = hook_markdown_render_linklist($data); 133 $processed = hook_markdown_render_linklist($data);
134 $this->assertEquals($str, $data['links'][0]['description']); 134 $this->assertEquals($str, $processed['links'][0]['description']);
135
136 $processed = hook_markdown_render_feed($data);
137 $this->assertEquals($str, $processed['links'][0]['description']);
135 138
136 $data = array( 139 $data = array(
137 // Columns data 140 // Columns data
@@ -153,6 +156,24 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
153 } 156 }
154 157
155 /** 158 /**
159 * Test that a close value to nomarkdown is not understand as nomarkdown (previous value `.nomarkdown`).
160 */
161 function testNoMarkdownNotExcactlyMatching()
162 {
163 $str = 'All _work_ and `no play` makes Jack a *dull* boy.';
164 $data = array(
165 'links' => array(array(
166 'description' => $str,
167 'tags' => '.' . NO_MD_TAG,
168 'taglist' => array('.'. NO_MD_TAG),
169 ))
170 );
171
172 $data = hook_markdown_render_feed($data);
173 $this->assertContains('<em>', $data['links'][0]['description']);
174 }
175
176 /**
156 * Test hashtag links processed with markdown. 177 * Test hashtag links processed with markdown.
157 */ 178 */
158 function testMarkdownHashtagLinks() 179 function testMarkdownHashtagLinks()
diff --git a/tpl/editlink.html b/tpl/editlink.html
index 441b5302..9e7621db 100644
--- a/tpl/editlink.html
+++ b/tpl/editlink.html
@@ -8,13 +8,15 @@
8{elseif="$link.description==''"}onload="document.linkform.lf_description.focus();" 8{elseif="$link.description==''"}onload="document.linkform.lf_description.focus();"
9{else}onload="document.linkform.lf_tags.focus();"{/if} > 9{else}onload="document.linkform.lf_tags.focus();"{/if} >
10<div id="pageheader"> 10<div id="pageheader">
11 {if="$source !== 'firefoxsocialapi'"} 11 {if="$source !== 'firefoxsocialapi'"}
12 {include="page.header"} 12 {include="page.header"}
13 {/if} 13 {else}
14 <div id="editlinkform"> 14 <div id="shaarli_title"><a href="{$titleLink}">{$shaarlititle}</a></div>
15 <form method="post" name="linkform"> 15 {/if}
16 <input type="hidden" name="lf_linkdate" value="{$link.linkdate}"> 16 <div id="editlinkform">
17 <label for="lf_url"><i>URL</i></label><br><input type="text" name="lf_url" id="lf_url" value="{$link.url}" class="lf_input"><br> 17 <form method="post" name="linkform">
18 <input type="hidden" name="lf_linkdate" value="{$link.linkdate}">
19 <label for="lf_url"><i>URL</i></label><br><input type="text" name="lf_url" id="lf_url" value="{$link.url}" class="lf_input"><br>
18 <label for="lf_title"><i>Title</i></label><br><input type="text" name="lf_title" id="lf_title" value="{$link.title}" class="lf_input"><br> 20 <label for="lf_title"><i>Title</i></label><br><input type="text" name="lf_title" id="lf_title" value="{$link.title}" class="lf_input"><br>
19 <label for="lf_description"><i>Description</i></label><br><textarea name="lf_description" id="lf_description" rows="4" cols="25">{$link.description}</textarea><br> 21 <label for="lf_description"><i>Description</i></label><br><textarea name="lf_description" id="lf_description" rows="4" cols="25">{$link.description}</textarea><br>
20 <label for="lf_tags"><i>Tags</i></label><br> 22 <label for="lf_tags"><i>Tags</i></label><br>
@@ -25,20 +27,20 @@
25 {$value} 27 {$value}
26 {/loop} 28 {/loop}
27 29
28 {if="($link_is_new && $default_private_links) || $link.private == true"} 30 {if="($link_is_new && $default_private_links) || $link.private == true"}
29 <input type="checkbox" checked="checked" name="lf_private" id="lf_private"> 31 <input type="checkbox" checked="checked" name="lf_private" id="lf_private">
30 &nbsp;<label for="lf_private"><i>Private</i></label><br> 32 &nbsp;<label for="lf_private"><i>Private</i></label><br>
31 {else} 33 {else}
32 <input type="checkbox" name="lf_private" id="lf_private"> 34 <input type="checkbox" name="lf_private" id="lf_private">
33 &nbsp;<label for="lf_private"><i>Private</i></label><br> 35 &nbsp;<label for="lf_private"><i>Private</i></label><br>
34 {/if} 36 {/if}
35 <input type="submit" value="Save" name="save_edit" class="bigbutton"> 37 <input type="submit" value="Save" name="save_edit" class="bigbutton">
36 <input type="submit" value="Cancel" name="cancel_edit" class="bigbutton"> 38 <input type="submit" value="Cancel" name="cancel_edit" class="bigbutton">
37 {if="!$link_is_new"}<input type="submit" value="Delete" name="delete_link" class="bigbutton delete" onClick="return confirmDeleteLink();">{/if} 39 {if="!$link_is_new"}<input type="submit" value="Delete" name="delete_link" class="bigbutton delete" onClick="return confirmDeleteLink();">{/if}
38 <input type="hidden" name="token" value="{$token}"> 40 <input type="hidden" name="token" value="{$token}">
39 {if="$http_referer"}<input type="hidden" name="returnurl" value="{$http_referer}">{/if} 41 {if="$http_referer"}<input type="hidden" name="returnurl" value="{$http_referer}">{/if}
40 </form> 42 </form>
41 </div> 43 </div>
42</div> 44</div>
43{if="$source !== 'firefoxsocialapi'"} 45{if="$source !== 'firefoxsocialapi'"}
44{include="page.footer"} 46{include="page.footer"}
diff --git a/tpl/tools.html b/tpl/tools.html
index 8e285f44..e06d239d 100644
--- a/tpl/tools.html
+++ b/tpl/tools.html
@@ -50,12 +50,15 @@
50 &nbsp;&nbsp;&nbsp;&nbsp;Then click "✚Add Note" button anytime to start composing a private Note (text post) to your Shaarli. 50 &nbsp;&nbsp;&nbsp;&nbsp;Then click "✚Add Note" button anytime to start composing a private Note (text post) to your Shaarli.
51 </span> 51 </span>
52 </a><br><br> 52 </a><br><br>
53
54 {if="$sslenabled"}
53 <a class="smallbutton" onclick="activateFirefoxSocial(this)"> 55 <a class="smallbutton" onclick="activateFirefoxSocial(this)">
54 <b>✚Add to Firefox social</b> 56 <b>✚Add to Firefox social</b>
55 </a> 57 </a>
56 <a href="#"> 58 <a href="#">
57 <span>&#x21D0; Click on this button to add Shaarli to the "Share this page" button in Firefox.</span> 59 <span>&#x21D0; Click on this button to add Shaarli to the "Share this page" button in Firefox.</span>
58 </a><br><br> 60 </a><br><br>
61 {/if}
59 62
60 {loop="$tools_plugin"} 63 {loop="$tools_plugin"}
61 {$value} 64 {$value}
@@ -64,6 +67,7 @@
64 <div class="clear"></div> 67 <div class="clear"></div>
65 68
66 <script> 69 <script>
70 {if="$sslenabled"}
67 function activateFirefoxSocial(node) { 71 function activateFirefoxSocial(node) {
68 var loc = location.href; 72 var loc = location.href;
69 var baseURL = loc.substring(0, loc.lastIndexOf("/")); 73 var baseURL = loc.substring(0, loc.lastIndexOf("/"));
@@ -87,7 +91,7 @@
87 var activate = new CustomEvent("ActivateSocialFeature"); 91 var activate = new CustomEvent("ActivateSocialFeature");
88 node.dispatchEvent(activate); 92 node.dispatchEvent(activate);
89 } 93 }
90 94 {/if}
91 function alertBookmarklet() { 95 function alertBookmarklet() {
92 alert('Drag this link to your bookmarks toolbar, or right-click it and choose Bookmark This Link...'); 96 alert('Drag this link to your bookmarks toolbar, or right-click it and choose Bookmark This Link...');
93 return false; 97 return false;