diff options
-rw-r--r-- | index.php | 1 | ||||
-rw-r--r-- | plugins/markdown/README.md | 21 | ||||
-rw-r--r-- | plugins/markdown/markdown.php | 27 | ||||
-rw-r--r-- | tests/plugins/PluginMarkdownTest.php | 29 | ||||
-rw-r--r-- | tpl/editlink.html | 32 | ||||
-rw-r--r-- | tpl/tools.html | 6 |
6 files changed, 82 insertions, 34 deletions
@@ -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 | ||
27 | To enable the plugin, just check it in the plugin administration page. | 26 | To enable the plugin, just check it in the plugin administration page. |
28 | 27 | ||
29 | You can also add `markdown` to your list of enabled plugins in `data/config.php` | 28 | You 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 | ||
32 | This should look like: | 31 | This 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 | ||
42 | Parsedown parsing library is imported using Composer. If you installed Shaarli using `git`, | ||
43 | or the `master` branch, run | ||
44 | |||
45 | composer update --no-dev --prefer-dist | ||
46 | |||
38 | ### No Markdown tag | 47 | ### No Markdown tag |
39 | 48 | ||
40 | If the tag `.nomarkdown` is set for a shaare, it won't be converted to Markdown syntax. | 49 | If 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 | */ |
82 | function noMarkdownTag($tags) | 83 | function 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 | */ |
94 | function stripNoMarkdownTag($tags) | 95 | function 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'; | |||
8 | require_once 'plugins/markdown/markdown.php'; | 8 | require_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 | */ |
14 | class PluginMarkdownTest extends PHPUnit_Framework_TestCase | 14 | class 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 | <label for="lf_private"><i>Private</i></label><br> | 32 | <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 | <label for="lf_private"><i>Private</i></label><br> | 35 | <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 | Then click "✚Add Note" button anytime to start composing a private Note (text post) to your Shaarli. | 50 | 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>⇐ Click on this button to add Shaarli to the "Share this page" button in Firefox.</span> | 59 | <span>⇐ 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; |