[Xfce4-commits] [www/wiki.xfce.org] 01/01: Update dokuwiki plugins

noreply at xfce.org noreply at xfce.org
Sun Jan 5 17:54:25 CET 2020


This is an automated email from the git hooks/post-receive script.

s   k   u   n   n   y   k       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository www/wiki.xfce.org.

commit 2d9ad6700b444ce3266a879065aa86de7bc29652
Author: Romain Bouvier <skunnyk at alteroot.org>
Date:   Sun Jan 5 17:52:16 2020 +0100

    Update dokuwiki plugins
---
 lib/plugins/captcha/.travis.yml                    |   8 +-
 lib/plugins/captcha/lang/es/lang.php               |   2 +-
 lib/plugins/captcha/lang/es/settings.php           |   7 +-
 lib/plugins/captcha/lang/it/lang.php               |   2 +-
 lib/plugins/captcha/lang/it/settings.php           |   5 +-
 lib/plugins/captcha/lang/ru/lang.php               |   7 +-
 lib/plugins/captcha/lang/ru/settings.php           |  13 +-
 lib/plugins/captcha/manager.dat                    |   2 +-
 lib/plugins/captcha/plugin.info.txt                |   2 +-
 lib/plugins/cli.php                                |  11 +
 lib/plugins/definitionlist/README.md               |  17 +
 lib/plugins/definitionlist/_test/syntax.test.php   | 229 +++++++++++
 lib/plugins/definitionlist/conf/default.php        |   7 +
 lib/plugins/definitionlist/conf/metadata.php       |   7 +
 lib/plugins/definitionlist/images/bullet.gif       | Bin 0 -> 45 bytes
 lib/plugins/definitionlist/lang/en/settings.php    |   7 +
 lib/plugins/definitionlist/lang/ja/settings.php    |   7 +
 lib/plugins/definitionlist/manager.dat             |   2 +
 lib/plugins/definitionlist/plugin.info.txt         |   7 +
 lib/plugins/definitionlist/style.less              |  41 ++
 lib/plugins/definitionlist/syntax.php              | 428 +++++++++++++++++++++
 lib/plugins/editsections2/action.php               | 259 +++++++++++++
 lib/plugins/editsections2/conf/default.php         |  10 +
 lib/plugins/editsections2/conf/metadata.php        |  17 +
 lib/plugins/editsections2/lang/en/settings.php     |  15 +
 lib/plugins/editsections2/lang/ja/settings.php     |  14 +
 lib/plugins/editsections2/manager.dat              |   2 +
 lib/plugins/editsections2/plugin.info.txt          |   7 +
 lib/plugins/editsections2/script.js                | 307 +++++++++++++++
 lib/plugins/editsections2/style.css                |  19 +
 lib/plugins/editsections2/syntax.php               |  78 ++++
 lib/plugins/note/.gitignore                        |   4 +-
 lib/plugins/note/CHANGES.md                        |  30 ++
 lib/plugins/note/README.md                         |  76 ++++
 lib/plugins/note/action.php                        |  60 +++
 lib/plugins/note/images/doc/note.png               | Bin 0 -> 786 bytes
 lib/plugins/note/images/doc/note_important.png     | Bin 0 -> 1012 bytes
 lib/plugins/note/images/doc/note_tip.png           | Bin 0 -> 831 bytes
 lib/plugins/note/images/doc/note_warning.png       | Bin 0 -> 907 bytes
 lib/plugins/note/images/note_picker.png            | Bin 0 -> 1295 bytes
 lib/plugins/note/lang/en/lang.php                  |  11 +
 lib/plugins/note/lang/fr/lang.php                  |  11 +
 lib/plugins/note/lang/ru/lang.php                  |  11 +
 lib/plugins/note/manager.dat                       |   4 +-
 lib/plugins/note/odt.css                           |   2 +-
 lib/plugins/note/plugin.info.txt                   |   2 +-
 lib/plugins/note/style.css                         |  15 +-
 lib/plugins/note/syntax.php                        | 116 +++---
 lib/plugins/nsexport/action/ajax.php               | 106 +++++
 lib/plugins/nsexport/action/export.php             |  90 +++++
 lib/plugins/nsexport/conf/default.php              |   4 +
 lib/plugins/nsexport/conf/metadata.php             |   4 +
 lib/plugins/nsexport/export.php                    |  12 +
 lib/plugins/nsexport/lang/de/autointro.txt         |   3 +
 lib/plugins/nsexport/lang/de/intro.txt             |   3 +
 lib/plugins/nsexport/lang/de/lang.php              |  10 +
 lib/plugins/nsexport/lang/en/autointro.txt         |   3 +
 lib/plugins/nsexport/lang/en/intro.txt             |   3 +
 lib/plugins/nsexport/lang/en/lang.php              |   9 +
 lib/plugins/nsexport/lang/en/settings.php          |   5 +
 lib/plugins/nsexport/manager.dat                   |   2 +
 lib/plugins/nsexport/packer/packer.php             |  86 +++++
 .../nsexport/packer/ziphtml/compress/ziplib.php    |  18 +
 lib/plugins/nsexport/packer/ziphtml/compressor.php |   9 +
 lib/plugins/nsexport/packer/ziphtml/export.css     |   4 +
 lib/plugins/nsexport/packer/ziphtml/packer.php     | 191 +++++++++
 lib/plugins/nsexport/packer/ziphtml/renderer.php   | 231 +++++++++++
 lib/plugins/nsexport/packer/ziphtml/zip.php        | 210 ++++++++++
 lib/plugins/nsexport/plugin.info.txt               |   7 +
 lib/plugins/nsexport/script.js                     |  89 +++++
 lib/plugins/nsexport/style.css                     |  29 ++
 lib/plugins/redirect/helper.php                    |   8 +
 lib/plugins/redirect/lang/pl/lang.php              |   9 +
 lib/plugins/redirect/lang/pl/settings.php          |   8 +
 lib/plugins/redirect/manager.dat                   |   2 +-
 lib/plugins/redirect/plugin.info.txt               |   2 +-
 76 files changed, 2947 insertions(+), 91 deletions(-)

diff --git a/lib/plugins/captcha/.travis.yml b/lib/plugins/captcha/.travis.yml
index 321f554..d73a6c4 100644
--- a/lib/plugins/captcha/.travis.yml
+++ b/lib/plugins/captcha/.travis.yml
@@ -1,13 +1,13 @@
 language: php
 php:
+  - "7.3"
+  - "7.2"
+  - "7.1"
   - "7.0"
   - "5.6"
-  - "5.5"
-  - "5.4"
-  - "5.3"
 env:
   - DOKUWIKI=master
   - DOKUWIKI=stable
 before_install: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh
 install: sh travis.sh
-script: cd _test && phpunit --stderr --group plugin_captcha
+script: cd _test && ./phpunit.phar --stderr --group plugin_captcha
diff --git a/lib/plugins/captcha/lang/es/lang.php b/lib/plugins/captcha/lang/es/lang.php
index 91f5396..affb9d2 100644
--- a/lib/plugins/captcha/lang/es/lang.php
+++ b/lib/plugins/captcha/lang/es/lang.php
@@ -2,7 +2,7 @@
 
 /**
  * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
- * 
+ *
  * @author Antonio Castilla <antoniocastilla at trazoide.com>
  */
 $lang['testfailed']            = 'Lo sentimos, pero el CAPTCHA no fue respondido correctamente. Tal vez no eres una persona.';
diff --git a/lib/plugins/captcha/lang/es/settings.php b/lib/plugins/captcha/lang/es/settings.php
index 8e02dd3..31479d6 100644
--- a/lib/plugins/captcha/lang/es/settings.php
+++ b/lib/plugins/captcha/lang/es/settings.php
@@ -3,6 +3,7 @@
 /**
  * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
  *
+ * @author Domingo Redal <docxml at gmail.com>
  * @author Antonio Castilla <antoniocastilla at trazoide.com>
  */
 $lang['mode']                  = '¿Qué tipo de CAPTCHA usará?';
@@ -11,8 +12,12 @@ $lang['mode_o_text']           = 'Texto (manual)';
 $lang['mode_o_math']           = 'Problemas de matemáticas';
 $lang['mode_o_question']       = 'Pregunta fija';
 $lang['mode_o_image']          = 'Imagen (peor accesibilidad)';
-$lang['mode_o_audio']          = 'Imagen + Audio (peor accesibilidad)';
+$lang['mode_o_audio']          = 'Imagen+Audio (mejor accesibilidad)';
+$lang['mode_o_svg']            = 'SVG (peor accesibilidad, legible)';
+$lang['mode_o_svgaudio']       = 'SVG+Audio (mejor accesibilidad, legible)';
+$lang['mode_o_figlet']         = 'Arte ASCII con Figlet (peor accesibilidad)';
 $lang['forusers']              = '¿Utilizar CAPTCHA para los usuarios registrados también?';
+$lang['loginprotect']          = '¿Requiere un CAPTCHA para iniciar sesión?';
 $lang['lettercount']           = 'Número de letras para usar (3-16). Si aumenta la cantidad, asegúrese de incrementar el ancho de la imagen de abajo también.';
 $lang['width']                 = 'Ancho de la imagen CAPTCHA (pixel)';
 $lang['height']                = 'Altura de la imagen CAPTCHA (pixel)';
diff --git a/lib/plugins/captcha/lang/it/lang.php b/lib/plugins/captcha/lang/it/lang.php
index 444023c..410203a 100644
--- a/lib/plugins/captcha/lang/it/lang.php
+++ b/lib/plugins/captcha/lang/it/lang.php
@@ -2,7 +2,7 @@
 
 /**
  * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
- * 
+ *
  * @author Willy
  * @author Torpedo <dgtorpedo at gmail.com>
  */
diff --git a/lib/plugins/captcha/lang/it/settings.php b/lib/plugins/captcha/lang/it/settings.php
index b45b957..9a8c70e 100644
--- a/lib/plugins/captcha/lang/it/settings.php
+++ b/lib/plugins/captcha/lang/it/settings.php
@@ -2,7 +2,8 @@
 
 /**
  * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
- * 
+ *
+ * @author Roberto Bellingeri <bellingeri at netguru.it>
  * @author by Willy
  * @author Torpedo <dgtorpedo at gmail.com>
  */
@@ -13,6 +14,8 @@ $lang['mode_o_math']           = 'Problema di matematica';
 $lang['mode_o_question']       = 'Domanda Immutabile';
 $lang['mode_o_image']          = 'Immagine (Non molto Accessibile)';
 $lang['mode_o_audio']          = 'Immagine + Audio (Migliore Accessibilità)';
+$lang['mode_o_svg']            = 'SVG (Non molto Accessibile, Leggibile)';
+$lang['mode_o_svgaudio']       = 'SVG + Audio (Migliore Accessibilità, Leggibile)';
 $lang['mode_o_figlet']         = 'Immagine ASCII FIGlet (Non molto Accessibile)';
 $lang['forusers']              = 'Vuoi usare CAPTCHA anche per gli utenti loggati?';
 $lang['loginprotect']          = 'Richiedere un CAPTCHA per l\'accesso?';
diff --git a/lib/plugins/captcha/lang/ru/lang.php b/lib/plugins/captcha/lang/ru/lang.php
index 4810ec3..4eb7851 100644
--- a/lib/plugins/captcha/lang/ru/lang.php
+++ b/lib/plugins/captcha/lang/ru/lang.php
@@ -2,12 +2,13 @@
 
 /**
  * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
- * 
+ *
+ * @author Yuriy Skalko <yuriy.skalko at gmail.com>
  * @author Aleksandr Selivanov <alexgearbox at gmail.com>
  * @author Ilya Rozhkov <impeck at ya.ru>
  */
 $lang['testfailed']            = 'Извините, код подтверждения введён неверно.';
-$lang['fillcaptcha']           = 'Пожалуйста, введите код подтверждения, чтобы доказать, что вы не робот:';
-$lang['fillmath']              = 'Ответьте пожалуйста на вопрос, чтобы доказать, что вы человек.';
+$lang['fillcaptcha']           = 'Пожалуйста, введите код подтверждения, чтобы доказать, что вы человек:';
+$lang['fillmath']              = 'Пожалуйста, решите задачу, чтобы доказать, что вы человек:';
 $lang['soundlink']             = 'Если вы не можете прочитать символы на изображении, загрузите и воспроизведите wav-файл.';
 $lang['honeypot']              = 'Пожалуйста, оставьте это поле пустым:';
diff --git a/lib/plugins/captcha/lang/ru/settings.php b/lib/plugins/captcha/lang/ru/settings.php
index dc01396..d4f158a 100644
--- a/lib/plugins/captcha/lang/ru/settings.php
+++ b/lib/plugins/captcha/lang/ru/settings.php
@@ -2,7 +2,8 @@
 
 /**
  * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
- * 
+ *
+ * @author Yuriy Skalko <yuriy.skalko at gmail.com>
  * @author Aleksandr Selivanov <alexgearbox at gmail.com>
  * @author Ilya Rozhkov <impeck at ya.ru>
  * @author Shpak Andrey <ashpak at ashpak.ru>
@@ -14,11 +15,13 @@ $lang['mode_o_math']           = 'Математическая задача';
 $lang['mode_o_question']       = 'Конкретный вопрос';
 $lang['mode_o_image']          = 'Изображение (хорошая защита)';
 $lang['mode_o_audio']          = 'Изображение и звук (плохая защита)';
+$lang['mode_o_svg']            = 'SVG (плохая доступность, читаемый)';
+$lang['mode_o_svgaudio']       = 'SVG+звук (лучшая доступность, читаемый)';
 $lang['mode_o_figlet']         = 'Figlet ASCII Art (хорошая защита)';
-$lang['forusers']              = 'Использоваться CAPTCHA для зарегистрированных пользователей?';
+$lang['forusers']              = 'Использовать CAPTCHA для зарегистрированных пользователей?';
 $lang['loginprotect']          = 'Требовать ввод CAPTCHA для входа?';
-$lang['lettercount']           = 'Количество букв (3-16). Если вы увеличиваете количество букв, не забудьте увеличить ширину изображения ниже.';
-$lang['width']                 = 'Ширина изображения CAPTCHA (пиксель)';
-$lang['height']                = 'Высота изображения CAPTCHA (пиксель)';
+$lang['lettercount']           = 'Количество букв (3-16). Если вы увеличиваете количество букв, не забудьте также увеличить ширину изображения ниже.';
+$lang['width']                 = 'Ширина изображения CAPTCHA (пиксели)';
+$lang['height']                = 'Высота изображения CAPTCHA (пиксели)';
 $lang['question']              = 'Вопрос для режима конкретного вопроса';
 $lang['answer']                = 'Ответ для режима конкретного вопроса ';
diff --git a/lib/plugins/captcha/manager.dat b/lib/plugins/captcha/manager.dat
index c586e1d..5222acb 100644
--- a/lib/plugins/captcha/manager.dat
+++ b/lib/plugins/captcha/manager.dat
@@ -1,3 +1,3 @@
 downloadurl=https://github.com/splitbrain/dokuwiki-plugin-captcha/zipball/master
 installed=Sun, 14 Feb 2016 12:17:57 +0100
-updated=Sat, 03 Mar 2018 17:13:56 +0100
+updated=Mon, 08 Apr 2019 20:51:31 +0200
diff --git a/lib/plugins/captcha/plugin.info.txt b/lib/plugins/captcha/plugin.info.txt
index f2350fe..80f21f7 100644
--- a/lib/plugins/captcha/plugin.info.txt
+++ b/lib/plugins/captcha/plugin.info.txt
@@ -1,7 +1,7 @@
 base   captcha
 author Andreas Gohr
 email  andi at splitbrain.org
-date   2017-12-05
+date   2019-03-20
 name   CAPTCHA Plugin
 desc   Use a CAPTCHA challenge to protect DokuWiki against automated spam
 url    http://www.dokuwiki.org/plugin:captcha
diff --git a/lib/plugins/cli.php b/lib/plugins/cli.php
new file mode 100644
index 0000000..721f547
--- /dev/null
+++ b/lib/plugins/cli.php
@@ -0,0 +1,11 @@
+<?php
+
+/**
+ * Base class for CLI plugins
+ *
+ * Provides DokuWiki plugin functionality on top of phpcli
+ */
+abstract class DokuWiki_CLI_Plugin extends \splitbrain\phpcli\CLI implements DokuWiki_PluginInterface {
+    use DokuWiki_PluginTrait;
+
+}
diff --git a/lib/plugins/definitionlist/README.md b/lib/plugins/definitionlist/README.md
new file mode 100644
index 0000000..6f43aa5
--- /dev/null
+++ b/lib/plugins/definitionlist/README.md
@@ -0,0 +1,17 @@
+DefinitionList
+==============
+
+For more information, please see
+https://www.dokuwiki.org/plugin:definitionlist
+
+## License
+
+GPL 2 http://www.gnu.org/licenses/gpl.html
+
+## Authors
+
+Original author: Chris Smith <chris at jalakai.co.uk>
+
+ODT support: Gabriel Birke <birke at d-scribe.de>
+
+Moved to Github: Sam Wilson <sam at samwilson.id.au>
diff --git a/lib/plugins/definitionlist/_test/syntax.test.php b/lib/plugins/definitionlist/_test/syntax.test.php
new file mode 100644
index 0000000..c54ddf2
--- /dev/null
+++ b/lib/plugins/definitionlist/_test/syntax.test.php
@@ -0,0 +1,229 @@
+<?php
+/**
+ * @group plugin_definitionlist
+ */
+class plugin_definitionlist_syntax_test extends DokuWikiTest {
+
+    protected $pluginsEnabled = array('definitionlist');
+    protected $renderer = null;
+
+    function setUp() {
+        parent::setUp();
+
+        $this->renderer = new Doku_Renderer_xhtml();
+    }
+
+    protected function render($rawwiki,$format='xhtml') {
+        $instructions = p_get_instructions($rawwiki);
+        return p_render($format, $instructions, $info);
+    }
+
+    function test_basic_singleline() {
+        $in = NL.'  ; Term : Definition'.NL;
+        $expected = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd>Definition</dd>'.NL
+                   .'</dl>'.NL;
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+    function test_basic_multiline() {
+        $in = NL.'  ; Term'.NL
+                .'  : Definition'.NL;
+        $expected = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd> Definition</dd>'.NL
+                   .'</dl>'.NL;
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+    function test_multiple_definitions() {
+        $in = NL.'  ; Term'.NL
+                .'  : Definition one'.NL
+                .'  : Definition two'.NL;
+        $expected = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd> Definition one</dd>'.NL
+                   .'<dd> Definition two</dd>'.NL
+                   .'</dl>'.NL;
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+    function test_newline_in_definition() {
+        $in = NL.'  ; Term'.NL
+                .'  : Definition one'.NL
+                .'continues'.NL;
+        $expected = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd> Definition one'.NL
+                   .'continues</dd>'.NL
+                   .'</dl>'.NL;
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+    function test_newline_in_definition_with_following_para() {
+        $in = NL.'  ; Term'.NL
+                .'  : Definition one'.NL
+                .'continues'.NL
+                .NL
+                .'Then new paragraph.'.NL;
+        $expected = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd> Definition one'.NL
+                   .'continues</dd>'.NL
+                   .'</dl>'.NL
+                   .NL
+                   .'<p>'.NL
+                   .'Then new paragraph.'.NL
+                   .'</p>'.NL;
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+    function test_basic_with_following_preformatted() {
+        $in = NL.'  ; Term'.NL
+                .'  : Definition'.NL
+                .NL
+                .'  Preformatted'.NL;
+        $expected = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd> Definition</dd>'.NL
+                   .'</dl>'.NL
+                   .'<pre class="code">Preformatted</pre>'.NL;
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+    function test_nonfancy() {
+        global $conf;
+        $conf['plugin']['definitionlist']['dt_fancy'] = 0;
+
+        $in1 = NL.'  ; Term'.NL
+                 .'  : Definition'.NL;
+        $in2 = NL.'  ; Term : Definition'.NL;
+        $expected1 = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt> Term</dt>'.NL
+                   .'<dd> Definition</dd>'.NL
+                   .'</dl>'.NL;
+        $expected2 = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt> Term</dt>'.NL
+                   .'<dd>Definition</dd>'.NL
+                   .'</dl>'.NL;
+
+
+        $this->assertEquals($expected1, $this->render($in1));
+        $this->assertEquals($expected2, $this->render($in2));
+    }
+
+    function test_custom_class_name() {
+        global $conf;
+        $conf['plugin']['definitionlist']['classname'] = 'foo';
+
+        $in = NL.'  ; Term'.NL
+                .'  : Definition'.NL;
+        $expected = '<dl class="foo">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd> Definition</dd>'.NL
+                   .'</dl>'.NL;
+
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+    function test_two_dlists_with_blank_line_between() {
+        $in = NL.'  ; Term : Definition'.NL
+             .NL.'  ; Another term : Def'.NL;
+        $expected = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd>Definition</dd>'.NL
+                   .'</dl>'.NL
+                   .'<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Another term</span></dt>'.NL
+                   .'<dd>Def</dd>'.NL
+                   .'</dl>'.NL;
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+    function test_dd_with_ul() {
+        $in = NL.'  ; Term'.NL
+                .'  : Some parts:'.NL
+                .'  * Part 1'.NL
+                .'  * Part 2'.NL
+                .NL
+                .'  ; Term 2'.NL
+                .'  : Def'.NL;
+        $expected = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd> Some parts:<ul>'.NL
+                   .'<li class="level1"><div class="li"> Part 1</div>'.NL
+                   .'</li>'.NL
+                   .'<li class="level1"><div class="li"> Part 2</div>'.NL
+                   .'</li>'.NL
+                   .'</ul>'.NL
+                   .'</dd>'.NL
+                   .'<dt><span class="term"> Term 2</span></dt>'.NL
+                   .'<dd> Def</dd>'.NL
+                   .'</dl>'.NL;
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+    function test_dd_with_ul_followed_by_ordered_list() {
+        $in = NL.'  ; Term'.NL
+                .'  : Some parts:'.NL
+                .'  * Part 1'.NL
+                .'  * Part 2'.NL
+                .NL
+                .NL
+                .'  - Item'.NL;
+        $expected = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd> Some parts:<ul>'.NL
+                   .'<li class="level1"><div class="li"> Part 1</div>'.NL
+                   .'</li>'.NL
+                   .'<li class="level1"><div class="li"> Part 2</div>'.NL
+                   .'</li>'.NL
+                   .'</ul>'.NL
+                   .'</dd>'.NL
+                   .'</dl>'.NL
+                   .'<ol>'.NL
+                   .'<li class="level1"><div class="li"> Item</div>'.NL
+                   .'</li>'.NL
+                   .'</ol>'.NL;
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+    function test_dd_with_ul_followed_by_2nd_dl() {
+        $in = NL.'  ; Term'.NL
+                .'  : Some parts:'.NL
+                .'  * Part 1'.NL
+                .'  * Part 2'.NL
+                .NL
+                .NL
+                .'  ; Term 2'.NL
+                .'  : Def'.NL;
+        $expected = '<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term</span></dt>'.NL
+                   .'<dd> Some parts:<ul>'.NL
+                   .'<li class="level1"><div class="li"> Part 1</div>'.NL
+                   .'</li>'.NL
+                   .'<li class="level1"><div class="li"> Part 2</div>'.NL
+                   .'</li>'.NL
+                   .'</ul>'.NL
+                   .'</dd>'.NL
+                   .'</dl>'.NL
+                   .'<dl class="plugin_definitionlist">'.NL
+                   .'<dt><span class="term"> Term 2</span></dt>'.NL
+                   .'<dd> Def</dd>'.NL
+                   .'</dl>'.NL;
+
+        $this->assertEquals($expected, $this->render($in));
+    }
+
+}
diff --git a/lib/plugins/definitionlist/conf/default.php b/lib/plugins/definitionlist/conf/default.php
new file mode 100644
index 0000000..ad9be97
--- /dev/null
+++ b/lib/plugins/definitionlist/conf/default.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Default settings for the definitionlist plugin
+ */
+
+$conf['dt_fancy']  = 1; // default on
+$conf['classname'] = 'plugin_definitionlist';
diff --git a/lib/plugins/definitionlist/conf/metadata.php b/lib/plugins/definitionlist/conf/metadata.php
new file mode 100644
index 0000000..a486ec3
--- /dev/null
+++ b/lib/plugins/definitionlist/conf/metadata.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Options for the defnitionlist plugin
+ */
+
+$meta['dt_fancy']  = array('onoff');
+$meta['classname'] = array('string');
diff --git a/lib/plugins/definitionlist/images/bullet.gif b/lib/plugins/definitionlist/images/bullet.gif
new file mode 100644
index 0000000..ad7b49a
Binary files /dev/null and b/lib/plugins/definitionlist/images/bullet.gif differ
diff --git a/lib/plugins/definitionlist/lang/en/settings.php b/lib/plugins/definitionlist/lang/en/settings.php
new file mode 100644
index 0000000..b8d24ff
--- /dev/null
+++ b/lib/plugins/definitionlist/lang/en/settings.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * English language file for definitionlist plugin
+ */
+
+$lang['dt_fancy']  = 'Wrap the contents of DT elements with <code><span class="term"><em>Term</em></span></code>';
+$lang['classname'] = 'Class name for DL elements';
diff --git a/lib/plugins/definitionlist/lang/ja/settings.php b/lib/plugins/definitionlist/lang/ja/settings.php
new file mode 100644
index 0000000..99c2dc0
--- /dev/null
+++ b/lib/plugins/definitionlist/lang/ja/settings.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Japanese language file for definitionlist plugin
+ */
+
+$lang['dt_fancy']  = 'dtタグ内を <span class="term"> ~ </span> で囲む';
+$lang['classname'] = 'dlタグに適用するデフォルトスタイル名';
diff --git a/lib/plugins/definitionlist/manager.dat b/lib/plugins/definitionlist/manager.dat
new file mode 100644
index 0000000..2b67bc5
--- /dev/null
+++ b/lib/plugins/definitionlist/manager.dat
@@ -0,0 +1,2 @@
+downloadurl=https://github.com/LarsGit223/dokuwiki-plugin-definitionlist/archive/2017-08-17.zip
+installed=Fri, 11 May 2018 11:42:41 +0200
diff --git a/lib/plugins/definitionlist/plugin.info.txt b/lib/plugins/definitionlist/plugin.info.txt
new file mode 100644
index 0000000..12c5426
--- /dev/null
+++ b/lib/plugins/definitionlist/plugin.info.txt
@@ -0,0 +1,7 @@
+base    definitionlist
+author  Chris Smith, LarsDW223
+email   chris at jalakai.co.uk
+date    2017-08-17
+name    Definition List plugin
+desc    Add syntax for definition lists.
+url     https://www.dokuwiki.org/plugin:definitionlist
diff --git a/lib/plugins/definitionlist/style.less b/lib/plugins/definitionlist/style.less
new file mode 100644
index 0000000..fa2d482
--- /dev/null
+++ b/lib/plugins/definitionlist/style.less
@@ -0,0 +1,41 @@
+/* plugin: definitionlist */
+
+dl.plugin_definitionlist {
+  padding: 0 0 0.5em 0;
+  border-bottom: 1px dashed #e0e0e0;
+  font-size: 90%;
+
+  dt {
+    clear: left;
+    margin: 0.5em 0 0;
+  }
+
+  dt+dt {
+    margin-top: 0;
+  }
+
+  dd+dt {
+    border-top: 1px dashed #e0e0e0;
+    padding-top: 0.5em;
+  }
+
+  /* fancy */
+  dt span.term {
+    float: left;
+    width: 10em;
+  }
+
+  dd {
+    margin: 0 0 0 10.3em;
+    padding: 0 0 0 0.8em;
+    background: url(images/bullet.gif) no-repeat 0 0.4em;
+  }
+   
+  dd p {
+    margin: 0;
+    padding: 0;
+  }
+
+}
+
+/* end plugin: definitionlist */
diff --git a/lib/plugins/definitionlist/syntax.php b/lib/plugins/definitionlist/syntax.php
new file mode 100644
index 0000000..1df02d7
--- /dev/null
+++ b/lib/plugins/definitionlist/syntax.php
@@ -0,0 +1,428 @@
+<?php
+/**
+ * Allow creation of XHTML definition lists:
+ * <dl>
+ *   <dt>term</dt>
+ *   <dd>definition</dd>
+ * </dl>
+ *
+ * Syntax:
+ *   ; term : definition
+ *   ; term
+ *   : definition
+ *
+ * As with other dokuwiki lists, each line must start with 2 spaces or a tab.
+ * Nested definition lists are not supported at this time.
+ *
+ * This plugin is heavily based on the definitions plugin by Pavel Vitis which
+ * in turn drew from the original definition list plugin by Stephane Chamberland.
+ * A huge thanks to both of them.
+ *
+ * Configuration:
+ *
+ * dt_fancy    Whether to wrap DT content in <span class="term">Term</span>.
+ *             Default true.
+ * classname   The html class name to be given to the DL element.
+ *             Default 'plugin_definitionlist'. This is the class used in the
+ *             bundled CSS file.
+ *
+ * ODT support provided by Gabriel Birke and LarsDW223
+ *
+ * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author     Chris Smith <chris [at] jalakai [dot] co [dot] uk>
+ * @author     Gabriel Birke <birke at d-scribe.de>
+ */
+
+if (!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
+if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+/**
+ * Settings:
+ *
+ * Define the trigger characters:
+ * ";" & ":" are the mediawiki settings.
+ * "=" & ":" are the settings for the original plugin by Pavel.
+ */
+if (!defined('DL_DT')) define('DL_DT', ';'); // character to indicate a term (dt)
+if (!defined('DL_DD')) define('DL_DD', ':'); // character to indicate a definition (dd)
+
+/**
+ *
+ */
+class syntax_plugin_definitionlist extends DokuWiki_Syntax_Plugin {
+
+    protected $stack = array();    // stack of currently open definition list items - used by handle() method
+
+    public function getType() { return 'container'; }
+    public function getAllowedTypes() { return array('container','substition','protected','disabled','formatting'); }
+    public function getPType() { return 'block'; }          // block, so not surrounded by <p> tags
+    public function getSort() { return 10; }                // before preformatted (20)
+
+    /**
+     * Connect pattern to lexer
+     */
+    public function connectTo($mode) {
+
+        $this->Lexer->addEntryPattern('\n {2,}'.DL_DT, $mode, 'plugin_definitionlist');
+        $this->Lexer->addEntryPattern('\n\t{1,}'.DL_DT, $mode, 'plugin_definitionlist');
+
+        $this->Lexer->addPattern('(?: '.DL_DD.' )', 'plugin_definitionlist');
+        $this->Lexer->addPattern('\n {2,}(?:'.DL_DT.'|'.DL_DD.')', 'plugin_definitionlist');
+        $this->Lexer->addPattern('\n\t{1,}(?:'.DL_DT.'|'.DL_DD.')', 'plugin_definitionlist');
+    }
+
+    public function postConnect() {
+        // we end the definition list when we encounter a blank line
+        $this->Lexer->addExitPattern('\n(?=[ \t]*\n)','plugin_definitionlist');
+    }
+
+    /**
+     * Handle the match
+     */
+    public function handle($match, $state, $pos, Doku_Handler $handler) {
+        switch ( $state ) {
+            case DOKU_LEXER_ENTER:
+                    array_push($this->stack, 'dt');
+                    $this->_writeCall('dl',DOKU_LEXER_ENTER,$pos,$match,$handler);    // open a new DL
+                    $this->_writeCall('dt',DOKU_LEXER_ENTER,$pos,$match,$handler);    // always start with a DT
+                    break;
+
+            case DOKU_LEXER_MATCHED:
+                    $oldtag = array_pop($this->stack);
+                    $newtag = (substr(rtrim($match), -1) == DL_DT) ? 'dt' : 'dd';
+                    array_push($this->stack, $newtag);
+
+                    $this->_writeCall($oldtag,DOKU_LEXER_EXIT,$pos,$match,$handler);  // close the current definition list item...
+                    $this->_writeCall($newtag,DOKU_LEXER_ENTER,$pos,$match,$handler); // ...and open the new dl item
+                    break;
+
+            case DOKU_LEXER_EXIT:
+                    // clean up & close any dl items on the stack
+                    while ($tag = array_pop($this->stack)) {
+                        $this->_writeCall($tag,DOKU_LEXER_EXIT,$pos,$match,$handler);
+                    }
+
+                    // and finally close the surrounding DL
+                    $this->_writeCall('dl',DOKU_LEXER_EXIT,$pos,$match,$handler);
+                    break;
+
+            case DOKU_LEXER_UNMATCHED:
+                    $handler->base($match, $state, $pos);    // cdata --- use base() as _writeCall() is prefixed for private/protected
+                    break;
+        }
+
+        return false;
+    }
+
+    /**
+     * helper function to simplify writing plugin calls to the instruction list
+     *
+     * instruction params are of the format:
+     *    0 => tag    (string)    'dl','dt','dd'
+     *    1 => state  (int)       DOKU_LEXER_??? state constant
+     *    2 => match  (string)    expected to be empty
+     */
+    protected function _writeCall($tag, $state, $pos, $match, &$handler) {
+        $handler->addPluginCall('definitionlist', array($tag, $state, ''), $state, $pos, $match);
+    }
+
+    /**
+     * Create output
+     */
+    public function render($format, Doku_Renderer $renderer, $data) {
+        if (empty($data)) return false;
+
+        switch  ($format) {
+            case 'xhtml' : return $this->render_xhtml($renderer,$data);
+            case 'odt'   :
+                if (!method_exists ($renderer, 'getODTPropertiesFromElement')) {
+                    return $this->render_odt_old($renderer,$data);
+                } else {
+                    return $this->render_odt_new($renderer,$data);
+                }
+            default :
+                //  handle unknown formats generically - map both 'dt' & 'dd' to paragraphs; ingnore the 'dl' container
+                list ($tag, $state, $match) = $data;
+                switch ( $state ) {
+                    case DOKU_LEXER_ENTER:
+                    if ($tag != 'dl') $renderer->p_open();
+                    break;
+                case DOKU_LEXER_MATCHED:                              // fall-thru
+                case DOKU_LEXER_UNMATCHED:                            // defensive, shouldn't occur
+                    $renderer->cdata($match);
+                    break;
+                case DOKU_LEXER_EXIT:
+                    if ($tag != 'dl') $renderer->p_close();
+                    break;
+                }
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * create output for the xhtml renderer
+     *
+     */
+    protected function render_xhtml(Doku_Renderer $renderer, $data) {
+        list($tag,$state,$match) = $data;
+
+        switch ( $state ) {
+            case DOKU_LEXER_ENTER:
+                $renderer->doc .= $this->_open($tag);
+                break;
+            case DOKU_LEXER_MATCHED:
+            case DOKU_LEXER_UNMATCHED:                            // defensive, shouldn't occur
+                $renderer->cdata($tag);
+                break;
+            case DOKU_LEXER_EXIT:
+                $renderer->doc .= $this->_close($tag);
+                break;
+        }
+        return true;
+    }
+
+    /**
+     * create output for ODT renderer
+     *
+     * @author:   Gabriel Birke <birke at d-scribe.de>
+     */
+    protected function render_odt_old(Doku_Renderer $renderer, $data) {
+        static $param_styles = array('dd' => 'def_f5_list', 'dt' => 'def_f5_term');
+        $this->_set_odt_styles_old($renderer);
+
+        list ($tag, $state, $match) = $data;
+
+        switch ( $state ) {
+            case DOKU_LEXER_ENTER:
+                if ($tag == 'dl') {
+                    $renderer->p_close();
+                } else {
+                    $renderer->p_open($param_styles[$tag]);
+                }
+                break;
+            case DOKU_LEXER_MATCHED:
+            case DOKU_LEXER_UNMATCHED:                            // defensive, shouldn't occur
+                $renderer->cdata($match);
+                break;
+            case DOKU_LEXER_EXIT:
+                if ($tag != 'dl') {
+                    $renderer->p_close();
+                } else {
+                    $renderer->p_open();
+                }
+                break;
+        }
+
+        return true;
+    }
+
+    /**
+     * Create output for ODT renderer (newer version)
+     * @author: LarsDW223
+     */
+    protected function render_odt_new(Doku_Renderer $renderer, $data) {
+        static $style_data = array();
+        static $dl_properties = array();
+        $this->_set_odt_styles_new($renderer, $style_data, $dl_properties);
+
+        list ($tag, $state, $match) = $data;
+
+        switch ( $state ) {
+            case DOKU_LEXER_ENTER:
+                if ($tag == 'dl') {
+                    $properties = array();
+                    $renderer->_odtTableOpenUseProperties($dl_properties);
+
+                    $properties ['width'] = $style_data ['margin-left'];
+                    $renderer->_odtTableAddColumnUseProperties($properties);
+                } else {
+                    if ($tag == 'dt') {
+                        $renderer->tablerow_open();
+
+                        $properties = array();
+                        $properties ['border-left'] = 'none';
+                        $properties ['border-right'] = 'none';
+                        $properties ['border-top'] = 'none';
+                        $properties ['border-bottom'] = $style_data ['border-bottom'];
+                        $renderer->_odtTableCellOpenUseProperties ($properties);
+
+                        $renderer->_odtSpanOpen('Plugin_DefinitionList_Term');
+                    } else {
+                        $properties = array();
+                        $properties ['border-left'] = 'none';
+                        $properties ['border-right'] = 'none';
+                        $properties ['border-top'] = 'none';
+                        $properties ['border-bottom'] = $style_data ['border-bottom'];
+                        $renderer->_odtTableCellOpenUseProperties ($properties);
+
+                        if (!empty($style_data ['image'])) {
+                            $properties = array();
+                            $properties ['margin-right'] = $style_data ['padding-left'];
+                            $renderer->_odtAddImageUseProperties($style_data ['image'], $properties);
+                        }
+
+                        $renderer->_odtSpanOpen('Plugin_DefinitionList_Description');
+                    }
+                }
+                break;
+            case DOKU_LEXER_MATCHED:
+            case DOKU_LEXER_UNMATCHED:                            // defensive, shouldn't occur
+                $renderer->cdata($match);
+                break;
+            case DOKU_LEXER_EXIT:
+                if ($tag != 'dl') {
+                    $renderer->_odtSpanClose();
+                    $renderer->tablecell_close();
+                    if ($tag == 'dd') {
+                        $renderer->p_close();
+                        $renderer->tablerow_close();
+                    }
+                } else {
+                    $renderer->table_close();
+                }
+                break;
+        }
+
+        return true;
+    }
+
+    /**
+     * set definition list styles, used by render_odt_old()
+     *
+     * add definition list styles to the renderer's autostyles property (once only)
+     *
+     * @param  $renderer    current (odt) renderer object
+     * @return void
+     */
+    protected function _set_odt_styles_old(Doku_Renderer $renderer) {
+        static $do_once = true;
+
+        if ($do_once) {
+            $renderer->autostyles["def_f5_term"] = '
+                <style:style style:name="def_f5_term" style:display-name="def_term" style:family="paragraph">
+                    <style:paragraph-properties fo:margin-top="0.18cm" fo:margin-bottom="0cm" fo:keep-together="always" style:page-number="auto" fo:keep-with-next="always"/>
+                    <style:text-properties fo:font-weight="bold"/>
+                </style:style>';
+            $renderer->autostyles["def_f5_list"] = '
+                <style:style style:name="def_f5_list" style:display-name="def_list" style:family="paragraph">
+                    <style:paragraph-properties fo:margin-left="0.25cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"/>
+                </style:style>';
+
+            $do_once = false;
+        }
+    }
+
+    /**
+     * Create definition list styles, used by render_odt_new():
+     * Adds definition list styles to the ODT documents common styles (once only)
+     *
+     * @param  Doku_renderer $renderer   current (odt) renderer object
+     * @param  Array         $style_data Array for returning relevant properties to the caller
+     * @author: LarsDW223
+     */
+    protected function _set_odt_styles_new(Doku_Renderer $renderer, &$style_data, &$dl_properties) {
+        static $do_once = true;
+
+        if ($do_once) {
+            // Create parent style to group the others beneath it
+            if (!$renderer->styleExists('Plugin_DivAlign2')) {
+                $parent_properties = array();
+                $parent_properties ['style-parent'] = NULL;
+                $parent_properties ['style-class'] = 'Plugin_DefinitionList';
+                $parent_properties ['style-name'] = 'Plugin_DefinitionList';
+                $parent_properties ['style-display-name'] = 'Plugin DefinitionList';
+                $renderer->createTextStyle($parent_properties);
+            }
+
+            // Get the current HTML stack from the ODT renderer
+            $stack = $renderer->getHTMLStack ();
+
+            // Save state to restore it later
+            $state = array();
+            $stack->getState ($state);
+            // Only for debugging ==> see end of this function
+            //$renderer->dumpHTMLStack ();
+
+            $stack->open('dl', 'class="plugin_definitionlist"', NULL, NULL);
+            $renderer->getODTPropertiesFromElement ($dl_properties, $stack->getCurrentElement(), 'screen', true);
+
+            $stack->open('dd', NULL, NULL, NULL);
+
+            // Get CSS properties for ODT export.
+            $dd_properties = array ();
+            $renderer->getODTPropertiesFromElement ($dd_properties, $stack->getCurrentElement(), 'screen', true);
+
+            $stack->close('dd');
+            $stack->open('dt', NULL, NULL, NULL);
+
+            // Get CSS properties for ODT export.
+            $dt_properties = array ();
+            $renderer->getODTPropertiesFromElement ($dt_properties, $stack->getCurrentElement(), 'screen', true);
+
+            // Set style data to be returned to caller
+            $style_data ['border-bottom'] = $dt_properties ['border-top'];
+            $style_data ['image'] = $dd_properties ['background-image'];
+            $style_data ['margin-left'] = $dd_properties ['margin-left'];
+            $style_data ['padding-left'] = $dd_properties ['padding-left'];
+
+            // Create text style for term
+            $dt_properties ['border-top'] = NULL;
+            $dt_properties ['style-class'] = NULL;
+            $dt_properties ['style-parent'] = 'Plugin_DefinitionList';
+            $dt_properties ['style-name'] = 'Plugin_DefinitionList_Term';
+            $dt_properties ['style-display-name'] = 'Term';
+            $renderer->createTextStyle($dt_properties);
+
+            // Create text style for description
+            $dd_properties ['border-bottom'] = $dt_properties ['border-top'];
+            $dd_properties ['style-class'] = NULL;
+            $dd_properties ['style-parent'] = 'Plugin_DefinitionList';
+            $dd_properties ['style-name'] = 'Plugin_DefinitionList_Description';
+            $dd_properties ['style-display-name'] = 'Description';
+            $dd_properties ['background'] = NULL;
+            $renderer->createTextStyle($dd_properties);
+
+            $stack->restoreState ($state);
+            // Only for debugging to check if the ODT plugins HTML stack
+            // is restored to the start state
+            //$renderer->dumpHTMLStack ();
+
+            $do_once = false;
+        }
+    }
+
+    /**
+     * open a definition list tag, used by render_xhtml()
+     *
+     * @param   $tag  (string)    'dl', 'dt' or 'dd'
+     * @return  (string)          html used to open the tag
+     */
+    protected function _open($tag) {
+        if ($tag == 'dl') {
+            if ($this->getConf('classname')) {
+                $tag .= ' class="'.$this->getConf('classname').'"';
+            }
+            $wrap = NL;
+        } else {
+            $wrap = ($tag == 'dt' && $this->getConf('dt_fancy')) ? '<span class="term">' : '';
+        }
+        return "<$tag>$wrap";
+    }
+
+    /**
+     * close a definition list tag, used by render_xhtml()
+     *
+     * @param   $tag  (string)    'dl', 'dt' or 'dd'
+     * @return  (string)          html used to close the tag
+     */
+    protected function _close($tag) {
+        $wrap = ($tag == 'dt' && $this->getConf('dt_fancy')) ? '</span>' : '';
+        return "$wrap</$tag>\n";
+    }
+
+}
+
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/lib/plugins/editsections2/action.php b/lib/plugins/editsections2/action.php
new file mode 100644
index 0000000..e84f2e5
--- /dev/null
+++ b/lib/plugins/editsections2/action.php
@@ -0,0 +1,259 @@
+<?php
+/**
+ * EditSections2 Plugin for DokuWiki / action.php
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author  Ben Coburn <btcoburn at silicodon.net>
+ * @author  Kazutaka Miyasaka <kazmiya at gmail.com>
+ */
+
+// must be run within DokuWiki
+if (!defined('DOKU_INC')) {
+    die();
+}
+
+if (!defined('DOKU_PLUGIN')) {
+    define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
+}
+
+require_once(DOKU_PLUGIN . 'action.php');
+
+class action_plugin_editsections2 extends DokuWiki_Action_Plugin
+{
+    var $section_levels = null;
+
+    /**
+     * Returns some info
+     */
+    function getInfo()
+    {
+        return confToHash(DOKU_PLUGIN . '/editsections2/plugin.info.txt');
+    }
+
+    /**
+     * Registers event handlers
+     */
+    function register(&$controller)
+    {
+        if (function_exists('html_secedit_get_button')) {
+            $controller->register_hook(
+                'DOKUWIKI_STARTED', 'BEFORE',
+                $this, 'exportToJSINFO'
+            );
+
+            $controller->register_hook(
+                'PARSER_HANDLER_DONE', 'BEFORE',
+                $this, 'handleInstructions'
+            );
+
+            $controller->register_hook(
+                'RENDERER_CONTENT_POSTPROCESS', 'BEFORE',
+                $this, 'handleHtmlContent'
+            );
+        } else {
+            // for DokuWiki Lemming or earlier
+            $controller->register_hook(
+                'PARSER_HANDLER_DONE', 'BEFORE',
+                $this, 'rewriteEditInstructions'
+            );
+        }
+    }
+
+    /**
+     * Exports configuration settings to $JSINFO
+     */
+    function exportToJSINFO(&$event)
+    {
+        global $JSINFO;
+
+        $JSINFO['plugin_editsections2'] = array(
+            'highlight_target' => $this->getConf('highlight_target'),
+        );
+    }
+
+    /**
+     * Prepends special instruction to put dummy section edit marker
+     */
+    function handleInstructions(&$event, $param)
+    {
+        $calls =& $event->data->calls;
+
+        // prepend plugin's instruction to the beginning of instructions
+        // (this instruction will be processed by render() in syntax.php)
+        array_unshift(
+            $calls,
+            array('plugin', array('editsections2', array(), 0))
+        );
+
+        // keeps section levels for hierarchical mode
+        if ($this->getConf('order_type')) {
+            $this->setSectionLevels($calls);
+        }
+    }
+
+    /**
+     * Replaces section edit markers
+     */
+    function handleHtmlContent(&$event, $param)
+    {
+        if ($event->data[0] !== 'xhtml') {
+            return;
+        }
+
+        $doc =& $event->data[1];
+
+        $marker_regexp =
+            '/<!-- EDIT(\d+) SECTION "([^"]*)" \[(\-?\d+)-(\d*)\] -->/';
+
+        if (preg_match_all($marker_regexp, $doc, $matches)) {
+            list($markers, $secids, $titles, $starts, $ends) = $matches;
+        } else {
+            return;
+        }
+
+        $markers_search = array_reverse($markers);
+
+        // build $markers_replace
+        if ($this->getConf('order_type')) {
+            // mode: hierarchical
+            $markers_replace = array();
+
+            // in case instruction is cached
+            if ($this->section_levels === null) {
+                $this->setSectionLevels();
+            }
+
+            // calculate nested section ranges and build new markers
+            for ($i = 1, $i_max = count($markers); $i < $i_max; $i++) {
+                $markers_replace[] = sprintf(
+                    '<!-- EDIT%s SECTION "%s" [%s-%s] -->',
+                    $secids[$i],
+                    $titles[$i],
+                    $starts[$i],
+                    $ends[$this->findNestedSectionEnd($i)]
+                );
+            }
+
+            $markers_replace = array_merge(
+                array(''),
+                array_reverse($markers_replace)
+            );
+        } else {
+            // mode: flat (shift button positions only)
+            $markers_replace = array_merge(
+                array(''),
+                array_slice($markers_search, 0, -1)
+            );
+        }
+
+        // shift edit button positions
+        $doc = str_replace($markers_search, $markers_replace, $doc);
+    }
+
+    /**
+     * Keeps section levels
+     */
+    function setSectionLevels($calls = null)
+    {
+        global $ID;
+        global $conf;
+
+        if ($calls === null) {
+            $calls = p_cached_instructions(wikiFN($ID), 'cacheonly');
+        }
+
+        list($handler_name, $instructions) = array(0, 1);
+        $this->section_levels = array('dummy_entry_for_padding');
+
+        for ($i = 0, $i_max = count($calls); $i < $i_max; $i++) {
+            if ($calls[$i][$handler_name] === 'section_open') {
+                $section_level = $calls[$i][$instructions][0];
+
+                if ($section_level <= $conf['maxseclevel']) {
+                    $this->section_levels[] = $section_level;
+                }
+            }
+        }
+    }
+
+    /**
+     * Finds the end of nested edit sections
+     */
+    function findNestedSectionEnd($offset_idx)
+    {
+        $offset_level = $this->section_levels[$offset_idx];
+        $end_idx = $offset_idx;
+        $i_max = count($this->section_levels);
+
+        for ($i = $offset_idx + 1; $i < $i_max; $i++) {
+            if ($this->section_levels[$i] > $offset_level) {
+                $end_idx = $i;
+            } else {
+                break;
+            }
+        }
+
+        return $end_idx;
+    }
+
+    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+    /**
+     * Rewrites instructions (for DokuWiki Lemming or earlier)
+     */
+    function rewriteEditInstructions(&$event, $param)
+    {
+        // get the instructions list from the handler
+        $calls =& $event->data->calls;
+
+        // index numbers for readability
+        list($handler_name, $instructions) = array(0, 1);
+        list($pos_start, $pos_end, $sec_level) = array(0, 1, 2);
+
+        // scan instructions for edit
+        $sections = array();
+
+        for ($i = 0, $i_max = count($calls); $i < $i_max; $i++) {
+            if ($calls[$i][$handler_name] === 'section_edit') {
+                $sections[] =& $calls[$i][$instructions];
+            }
+        }
+
+        $section_count = count($sections);
+
+        // no need to rewrite
+        if ($section_count < 2) {
+            return;
+        }
+
+        // rewrite instructions
+        if ($this->getConf('order_type')) {
+            // mode: hierarchical
+            for ($i = 0, $i_max = $section_count - 1; $i < $i_max; $i++) {
+                // shift instructions
+                $sections[$i] = $sections[$i + 1];
+
+                // set default pos_end value (end of the wiki page)
+                $sections[$i][$pos_end] = 0;
+
+                // find and set the end point of hierarchical section
+                $level = $sections[$i][$sec_level];
+
+                for ($j = $i + 2; $j < $section_count; $j++) {
+                    if ($level >= $sections[$j][$sec_level]) {
+                        $sections[$i][$pos_end] = $sections[$j][$pos_start] - 1;
+                        break;
+                    }
+                }
+            }
+        } else {
+            // mode: flat (shift instructions only)
+            for ($i = 0, $i_max = $section_count - 1; $i < $i_max; $i++) {
+                $sections[$i] = $sections[$i + 1];
+            }
+        }
+
+        // hide old last section
+        $sections[$section_count - 1][$pos_start] = -1;
+    }
+}
diff --git a/lib/plugins/editsections2/conf/default.php b/lib/plugins/editsections2/conf/default.php
new file mode 100644
index 0000000..ba291a3
--- /dev/null
+++ b/lib/plugins/editsections2/conf/default.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Default configuration for editsections2 plugin
+ * 
+ * @author Ben Coburn <btcoburn at silicodon.net>
+ * @author Kazutaka Miyasaka <kazmiya at gmail.com>
+ */
+
+$conf['order_type'] = 1;
+$conf['highlight_target'] = 'default';
diff --git a/lib/plugins/editsections2/conf/metadata.php b/lib/plugins/editsections2/conf/metadata.php
new file mode 100644
index 0000000..ca96967
--- /dev/null
+++ b/lib/plugins/editsections2/conf/metadata.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Configuration metadata for editsections2 plugin
+ * 
+ * @author Ben Coburn <btcoburn at silicodon.net>
+ * @author Kazutaka Miyasaka <kazmiya at gmail.com>
+ */
+
+$meta['order_type'] = array(
+    'multichoice',
+    '_choices' => array(0, 1)
+);
+
+$meta['highlight_target'] = array(
+    'multichoice',
+    '_choices' => array('default', 'exclude_headings')
+);
diff --git a/lib/plugins/editsections2/lang/en/settings.php b/lib/plugins/editsections2/lang/en/settings.php
new file mode 100644
index 0000000..523d272
--- /dev/null
+++ b/lib/plugins/editsections2/lang/en/settings.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * English language file for editsections2 plugin
+ * 
+ * @author Ben Coburn <btcoburn at silicodon.net>
+ * @author Kazutaka Miyasaka <kazmiya at gmail.com>
+ */
+
+$lang['order_type']     = 'Organization type';
+$lang['order_type_o_0'] = 'Flat';
+$lang['order_type_o_1'] = 'Hierarchical (nested)';
+
+$lang['highlight_target'] = 'Target of the mouse over highlights on edit buttons';
+$lang['highlight_target_o_default'] = 'DokuWiki default';
+$lang['highlight_target_o_exclude_headings'] = 'Exclude headings';
diff --git a/lib/plugins/editsections2/lang/ja/settings.php b/lib/plugins/editsections2/lang/ja/settings.php
new file mode 100644
index 0000000..1f8727f
--- /dev/null
+++ b/lib/plugins/editsections2/lang/ja/settings.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Japanese language file for editsections2 plugin
+ * 
+ * @author Kazutaka Miyasaka <kazmiya at gmail.com>
+ */
+
+$lang['order_type'] = 'セクション編集の編集範囲タイプ';
+$lang['order_type_o_0'] = 'フラット';
+$lang['order_type_o_1'] = '階層的 (ネスト)';
+
+$lang['highlight_target'] = '編集ボタンへのマウスオーバーによるハイライトの対象';
+$lang['highlight_target_o_default'] = 'DokuWiki デフォルト';
+$lang['highlight_target_o_exclude_headings'] = '見出しを除く';
diff --git a/lib/plugins/editsections2/manager.dat b/lib/plugins/editsections2/manager.dat
new file mode 100644
index 0000000..b785dab
--- /dev/null
+++ b/lib/plugins/editsections2/manager.dat
@@ -0,0 +1,2 @@
+downloadurl=https://github.com/kazmiya/dokuwiki-plugin-editsections2/zipball/master
+installed=Fri, 06 Dec 2019 17:41:50 +0100
diff --git a/lib/plugins/editsections2/plugin.info.txt b/lib/plugins/editsections2/plugin.info.txt
new file mode 100644
index 0000000..a45f39c
--- /dev/null
+++ b/lib/plugins/editsections2/plugin.info.txt
@@ -0,0 +1,7 @@
+base   editsections2
+author Kazutaka Miyasaka
+email  kazmiya at gmail.com
+date   2012-10-13
+name   EditSections2 Plugin
+desc   Configures section edit features
+url    http://github.com/kazmiya/dokuwiki-plugin-editsections2
diff --git a/lib/plugins/editsections2/script.js b/lib/plugins/editsections2/script.js
new file mode 100644
index 0000000..9288d92
--- /dev/null
+++ b/lib/plugins/editsections2/script.js
@@ -0,0 +1,307 @@
+/**
+ * EditSections2 Plugin for DokuWiki / script.js
+ *
+ * Replaces section edit highlighting events
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author  Kazutaka Miyasaka <kazmiya at gmail.com>
+ */
+
+(function() {
+    /**
+     * Lookup table for section edit id (startPos => secedit_id)
+     */
+    var editIdLookup = {};
+
+    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+    // compatibility check
+    if (
+        typeof DEPRECATED === 'function' ||
+        typeof addInitEvent === 'undefined'
+    ) {
+        // for DokuWiki Angua or later
+        jQuery(replaceSectionEditButtonEvents);
+    } else if (typeof JSINFO === 'object') {
+        if (JSINFO.plugin_editsections2) {
+            // for DokuWiki Anteater and Rincewind
+            addInitEvent(replaceSectionEditButtonEvents_Anteater);
+        } else {
+            // for DokuWiki Lemming
+            addInitEvent(replaceSectionEditButtonEvents_Lemming);
+        }
+    }
+
+    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+    /**
+     * Replaces mouseover events on section edit buttons
+     */
+    function replaceSectionEditButtonEvents() {
+        jQuery('form.btn_secedit')
+            .each(function() {
+                addEditIdLookupTable(this);
+            })
+            .unbind('mouseover')
+            .bind('mouseover', function(event) {
+                highlightSections(event);
+            })
+            // FIXME: a huge change has happened... will make a real fix later
+            // https://github.com/splitbrain/dokuwiki/commit/870c8a4b77dd7c2cfdc14045f8604b5bbf34c01e
+            .unbind('mouseout')
+            .bind('mouseout', function(event) {
+                jQuery('.section_highlight').removeClass('section_highlight');
+            });
+    }
+
+    /**
+     * Returns start/end value of the section edit range
+     */
+    function getRangeValue(range, startOrEnd) {
+        var matched,
+            ret;
+
+        if (!range || !(matched = /^(\d+)-(\d*)$/.exec(range.value))) {
+            ret = false;
+        } else if (startOrEnd === 'start') {
+            ret = Number(matched[1]);
+        } else if (matched[2].length) {
+            ret = Number(matched[2]);
+        } else {
+            ret = 'last';
+        }
+
+        return ret;
+    }
+
+    /**
+     * Scans and adds section edit id lookup table
+     */
+    function addEditIdLookupTable(sectionEditForm) {
+        var parent,
+            idMatched,
+            startPos;
+
+        parent = sectionEditForm.parentNode;
+
+        if (
+            parent &&
+            parent.tagName &&
+            parent.tagName.toLowerCase() === 'div' &&
+            parent.className &&
+            (idMatched = /\b(?:editbutton_(\d+))\b/.exec(parent.className)) &&
+            (startPos = getRangeValue(sectionEditForm.range, 'start'))
+        ) {
+            editIdLookup[startPos] = idMatched[1];
+        }
+    }
+
+    /**
+     * Checks if an element is heading
+     */
+    function isHeading(element) {
+        return element.tagName && /^H[1-6]/i.test(element.tagName);
+    }
+
+    /**
+     * Highlights sections in the edit range
+     */
+    function highlightSections(event) {
+        var sectionEditForm,
+            endPos,
+            stopClassRegExp,
+            doNotHighlightHeadings,
+            cursor;
+
+        sectionEditForm = event.target.form;
+
+        if (!sectionEditForm) {
+            return;
+        }
+
+        endPos = getRangeValue(sectionEditForm.range, 'end');
+
+        // set stopClass regexp
+        if (endPos === false) {
+            return;
+        } else if (endPos === 'last') {
+            stopClassRegExp = /\b(?:footnotes)\b/;
+        } else if (editIdLookup[endPos + 1]) {
+            stopClassRegExp = new RegExp(
+                '\\b(?:footnotes|sectionedit' +
+                String(editIdLookup[endPos + 1]).replace(/(\W)/g, '\\$1') +
+                ')\\b'
+            );
+        } else {
+            // edittable plugin etc.
+            return;
+        }
+
+        doNotHighlightHeadings =
+            JSINFO.plugin_editsections2.highlight_target === 'exclude_headings';
+
+        cursor = sectionEditForm.parentNode;
+
+        // highlight until the stopClass appeared
+        while (cursor = cursor.nextSibling) {
+            if (!cursor.className) {
+                continue;
+            }
+
+            if (stopClassRegExp.test(cursor.className)) {
+                break;
+            }
+
+            if (
+                !(doNotHighlightHeadings && isHeading(cursor)) &&
+                !/\b(?:editbutton_section)\b/.test(cursor.className)
+            ) {
+                cursor.className += ' section_highlight';
+            }
+        }
+    }
+
+    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+    /**
+     * Replaces mouseover events on section edit buttons
+     * (for DokuWiki Anteater and Rincewind)
+     */
+    function replaceSectionEditButtonEvents_Anteater() {
+        var i,
+            iMax,
+            parent,
+            events,
+            guid,
+            buttonForms,
+            sectionEditForms = [];
+
+        buttonForms = getElementsByClass('btn_secedit', document, 'form');
+
+        // extract section edit forms
+        for (i = 0, iMax = buttonForms.length; i < iMax; i++) {
+            parent = buttonForms[i].parentNode;
+
+            // parent element must be 'div.editbutton_section'
+            if (
+                parent &&
+                parent.tagName &&
+                parent.tagName.toLowerCase() === 'div' &&
+                parent.className &&
+                /\b(?:editbutton_section)\b/.test(parent.className)
+            ) {
+                sectionEditForms[sectionEditForms.length] = buttonForms[i];
+            }
+        }
+
+        // remove events and collect section info
+        for (i = 0, iMax = sectionEditForms.length; i < iMax; i++) {
+            events = sectionEditForms[i].events;
+
+            // remove all of the previously-set mouseover events from the button
+            if (events && events.mouseover) {
+                for (guid in events.mouseover) {
+                    removeEvent(
+                        sectionEditForms[i], 'mouseover', events.mouseover[guid]
+                    );
+                }
+            }
+
+            addEditIdLookupTable(sectionEditForms[i]);
+        }
+
+        // add new event to highlight sections to be edited
+        for (i = 0, iMax = sectionEditForms.length; i < iMax; i++) {
+            addEvent(
+                sectionEditForms[i],
+                'mouseover',
+                highlightSections
+            );
+        }
+    }
+
+    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+    /**
+     * Replaces mouseover events on section edit buttons
+     * (for DokuWiki Lemming)
+     */
+    function replaceSectionEditButtonEvents_Lemming() {
+        var i,
+            iMax,
+            events,
+            guid,
+            buttonForms;
+
+        buttonForms = getElementsByClass('btn_secedit', document, 'form');
+
+        for (i = 0, iMax = buttonForms.length; i < iMax; i++) {
+            events = buttonForms[i].events;
+
+            // remove all of the previously-set mouseover events from the button
+            if (events && events.mouseover) {
+                for (guid in events.mouseover) {
+                    removeEvent(
+                        buttonForms[i], 'mouseover', events.mouseover[guid]
+                    );
+                }
+            }
+
+            // add new mouseover event to highlight sections to be edited
+            addEvent(buttonForms[i], 'mouseover', highlightSections_Lemming);
+        }
+    }
+
+    /**
+     * Highlights sections in the edit range
+     * (for DokuWiki Lemming or earlier)
+     */
+    function highlightSections_Lemming(event) {
+        var buttonForm,
+            sectionEditForm,
+            cursor,
+            startPos,
+            endPos;
+
+        buttonForm = event.target.form;
+
+        // get the end position of the section
+        endPos = getRangeValue(buttonForm.lines, 'end');
+
+        if (endPos === false) {
+            return;
+        }
+
+        cursor = buttonForm.parentNode;
+
+        if (!cursor.tagName || cursor.tagName.toLowerCase() !== 'div') {
+            return;
+        }
+
+        // add "section_highlight" class to DIV elements in the edit range
+        while (cursor = cursor.nextSibling) {
+            if (
+                !cursor.tagName ||
+                cursor.tagName.toLowerCase() !== 'div' ||
+                !cursor.className
+            ) {
+                continue;
+            }
+
+            if (
+                /\b(?:secedit)\b/.test(cursor.className) &&
+                endPos !== 'last' &&
+                (sectionEditForm = cursor.getElementsByTagName('form').item(0)) &&
+                (startPos = getRangeValue(sectionEditForm.lines, 'start')) !== false &&
+                endPos < startPos
+            ) {
+                // out of the edit range
+                break;
+            }
+
+            if (/\b(?:level\d)\b/.test(cursor.className)) {
+                cursor.className += ' section_highlight';
+            }
+        }
+    }
+})();
diff --git a/lib/plugins/editsections2/style.css b/lib/plugins/editsections2/style.css
new file mode 100644
index 0000000..5dbe057
--- /dev/null
+++ b/lib/plugins/editsections2/style.css
@@ -0,0 +1,19 @@
+/**
+ * EditSections2 Plugin for DokuWiki / style.css
+ * 
+ * @author Ben Coburn <btcoburn at silicodon.net>
+ * @author Kazutaka Miyasaka <kazmiya at gmail.com>
+ */
+
+html.js body div.dokuwiki div.editbutton_section input.button {
+  margin-top: 2em;
+}
+
+body div.dokuwiki div.secedit input.button,
+body div.dokuwiki div.editbutton_section input.button {
+  margin-top: 1.5em;
+}
+
+body div.dokuwiki div.editbutton_table input.button {
+  margin-top: 0em;
+}
diff --git a/lib/plugins/editsections2/syntax.php b/lib/plugins/editsections2/syntax.php
new file mode 100644
index 0000000..6b262d1
--- /dev/null
+++ b/lib/plugins/editsections2/syntax.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * EditSections2 Plugin for DokuWiki / syntax.php
+ *
+ * We use this syntax plugin class only for the renderer functionality.
+ * No syntax is provided.
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author  Kazutaka Miyasaka <kazmiya at gmail.com>
+ */
+
+// must be run within DokuWiki
+if (!defined('DOKU_INC')) {
+    die();
+}
+
+if (!defined('DOKU_PLUGIN')) {
+    define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
+}
+
+require_once(DOKU_PLUGIN . 'syntax.php');
+
+class syntax_plugin_editsections2 extends DokuWiki_Syntax_Plugin
+{
+    /**
+     * Returns some info
+     */
+    function getInfo()
+    {
+        return confToHash(DOKU_PLUGIN . '/editsections2/plugin.info.txt');
+    }
+
+    /**
+     * Dummy (only for compatibility reasons)
+     */
+    function getType()
+    {
+        return 'baseonly';
+    }
+
+    /**
+     * Dummy (only for compatibility reasons)
+     */
+    function getSort()
+    {
+        return 999;
+    }
+
+    /**
+     * Dummy (only for compatibility reasons)
+     */
+    function connectTo($mode)
+    {
+        // connect to nowhere
+    }
+
+    /**
+     * Dummy (only for compatibility reasons)
+     */
+    function handle($match, $state, $pos, &$handler)
+    {
+        // do nothing
+    }
+
+    /**
+     * Starts section to put a secedit marker above the first heading
+     */
+    function render($format, &$renderer, $data)
+    {
+        // no need to handle DokuWiki Lemming or earlier
+        if (
+            $format === 'xhtml'
+            && function_exists('html_secedit_get_button')
+        ) {
+            $renderer->startSectionEdit(-1, 'section', 'dummy');
+        }
+    }
+}
diff --git a/lib/plugins/note/.gitignore b/lib/plugins/note/.gitignore
index f3c7a7c..18df25a 100644
--- a/lib/plugins/note/.gitignore
+++ b/lib/plugins/note/.gitignore
@@ -1 +1,3 @@
-Makefile
+/.idea
+*~
+*.bak
diff --git a/lib/plugins/note/CHANGES.md b/lib/plugins/note/CHANGES.md
new file mode 100644
index 0000000..061d0dd
--- /dev/null
+++ b/lib/plugins/note/CHANGES.md
@@ -0,0 +1,30 @@
+* 2018-08-21 (fixes by Marcin Orlowski)
+  * Fixed notes' CSS for DokuWiki dark themes
+  * Code cleanup
+  * Updated documentation
+* 2016-09-14
+  * plugin cleanup
+  * adjustment to ODT plugin re-design
+  * fixed PHP7.0 signature errors
+* 2009-06-16 (re-packaged by Mischa The Evil)
+  * Removed obsolete files from the package
+  * Added README with CHANGELOG
+  * Added GNU GPL v2 license
+  * Fixed file-permissions
+* 2009-06-15 (fixes by Aurélien Bompard)
+  * Fix in the ODT renderer
+  * Add toolbar buttons for the notes.
+* 2008-02-17 (patches by Aurélien Bompard)
+  * added support for ODT-export
+* 2006-03-29 (patches by Eric Hameleers and Christopher Smith)
+  * allow note nesting
+  * fix the trimmed space problem
+  * fix the issue with protected modes (e.g. ```<tt><code></tt>``` & ```<tt><file></tt>```) not being allowed within notes
+  * plug the security vulnerability which could allow malicious HTML or JavaScript to infiltrate your wiki
+  * make note types case independent (e.g. ```<tt>important</tt>```, ```<tt>IMPORTANT</tt>``` & ```<tt>Important</tt>``` will all given an "important" note)
+  * and better:
+    * code efficiency
+    * code reading
+    * conformance to DokuWiki's changes in plugin classes
+* 2005-10-13
+  * Initial release by Olivier Cortéz (?)
diff --git a/lib/plugins/note/README.md b/lib/plugins/note/README.md
new file mode 100644
index 0000000..501becd
--- /dev/null
+++ b/lib/plugins/note/README.md
@@ -0,0 +1,76 @@
+# DokuWiki Note plugin
+
+A plugin for [DokuWiki](https://www.dokuwiki.org/) which allows users to easily insert four kinds of notes into the wiki pages.
+
+## Usage
+
+When you have it installed, use the following syntax `<note>message</note>`:
+
+    <note>note</note>
+![note](images/doc/note.png)
+
+You can use the note keywords `important`, `warning` and `tip` to change the look of note as well
+
+    <note important>important</note>
+![note](images/doc/note_important.png)
+
+    <note tip>tip</note>
+![note](images/doc/note_tip.png)
+
+    <note warning>warning</note>
+![note](images/doc/note_warning.png)
+
+## Notes
+
+It is regularly reported that the cache needs to be cleaned after installing the plugin before the notes do showup. At least a full page-reload (CTRL-F5) is required.
+
+## Limitations
+
+Currently this plugin has some limitations:
+
+ * Plugin won't work inside numbered lists
+ * Plugin won't work inside tables
+
+## Download / Installation
+
+ See [DokuWiki's plugin page](https://www.dokuwiki.org/plugin:note)
+
+Alternatively
+ 1. Download plugin/repo archive
+ 2. Installing the plugin:
+    * You can either extract the archive into the <tt>lib/plugins</tt> directory or
+    * Load the admin page and go to Manage Plugins and enter the URL of the plugin under Download and install the new plugin.-
+ 3. Update the `Configuration Settings` under the DokuWiki's admin page.
+
+## Authors
+
+ The plugin has been written from scratch by Olivier Cortéz. After the initial release it has been maintained
+ by Olivier while he integrated several patches provided by the DokuWiki-community. Somewhere around the end
+ of 2008 / start of 2009 Olivier started to became too busy with other (real-life) activities and occupations
+ that active development and support halted. On 2009/06/15 Aurélien Bompard decided, after contacting
+ Olivier Cortéz about it, to (temporarily) take-over maintenance and support for the plugin. On the
+ same date Mischa The Evil opened a [GitHub-repository for the plugin](https://github.com/MischaTheEvil/dokuwiki_note)
+ to make it a "real" community plugin. On the 16th a re-packaged release is available
+ which "completed" the plugin (doc, license etc.).
+
+## Credits
+
+Many thanks to the following DokuWiki developers (in random order):
+
+* Stephane Chamberland
+* Carl-Christian Salvesen
+* Eric Hameleers
+* Christopher Smith
+* Chris Lale
+* Pixote
+* Yves Bergeron
+* Taylor Jones
+* Luke
+* Frédéric
+* Kmosak
+* foosel
+* zerohalo
+
+## License
+
+This plugin is open-source and licensed under the GNU GPL v.2.
diff --git a/lib/plugins/note/action.php b/lib/plugins/note/action.php
new file mode 100644
index 0000000..629d038
--- /dev/null
+++ b/lib/plugins/note/action.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'action.php');
+
+class action_plugin_note extends DokuWiki_Action_Plugin {
+
+    /**
+     * register the eventhandlers
+     *
+     * @author Andreas Gohr <andi at splitbrain.org>
+     */
+    function register(Doku_Event_Handler $controller){
+        $controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'handle_toolbar', array ());
+    }
+
+    function handle_toolbar(&$event, $param) {
+        $event->data[] = array (
+            'type' => 'picker',
+            'title' => $this->getLang('note_picker'),
+            'icon' => DOKU_BASE.'lib/plugins/note/images/note_picker.png',
+            'list' => array(
+                array(
+                    'type'   => 'format',
+                    'title'  => $this->getLang('tb_note'),
+                    'icon'   => DOKU_BASE.'lib/plugins/note/images/tb_note.png',
+                    'open'   => '<note>',
+                    'close'  => '</note>',
+                ),
+                array(
+                    'type'   => 'format',
+                    'title'  => $this->getLang('tb_tip'),
+                    'icon'   => DOKU_BASE.'lib/plugins/note/images/tb_tip.png',
+                    'open'   => '<note tip>',
+                    'close'  => '</note>',
+                ),
+                array(
+                    'type'   => 'format',
+                    'title'  => $this->getLang('tb_important'),
+                    'icon'   => DOKU_BASE.'lib/plugins/note/images/tb_important.png',
+                    'open'   => '<note important>',
+                    'close'  => '</note>',
+                ),
+                array(
+                    'type'   => 'format',
+                    'title'  => $this->getLang('tb_warning'),
+                    'icon'   => DOKU_BASE.'lib/plugins/note/images/tb_warning.png',
+                    'open'   => '<note warning>',
+                    'close'  => '</note>',
+                ),
+            )
+        );
+    }
+}
diff --git a/lib/plugins/note/images/doc/note.png b/lib/plugins/note/images/doc/note.png
new file mode 100644
index 0000000..25a9273
Binary files /dev/null and b/lib/plugins/note/images/doc/note.png differ
diff --git a/lib/plugins/note/images/doc/note_important.png b/lib/plugins/note/images/doc/note_important.png
new file mode 100644
index 0000000..916cac1
Binary files /dev/null and b/lib/plugins/note/images/doc/note_important.png differ
diff --git a/lib/plugins/note/images/doc/note_tip.png b/lib/plugins/note/images/doc/note_tip.png
new file mode 100644
index 0000000..4473d52
Binary files /dev/null and b/lib/plugins/note/images/doc/note_tip.png differ
diff --git a/lib/plugins/note/images/doc/note_warning.png b/lib/plugins/note/images/doc/note_warning.png
new file mode 100644
index 0000000..a32233e
Binary files /dev/null and b/lib/plugins/note/images/doc/note_warning.png differ
diff --git a/lib/plugins/note/images/note_picker.png b/lib/plugins/note/images/note_picker.png
new file mode 100644
index 0000000..99c6064
Binary files /dev/null and b/lib/plugins/note/images/note_picker.png differ
diff --git a/lib/plugins/note/lang/en/lang.php b/lib/plugins/note/lang/en/lang.php
new file mode 100644
index 0000000..c844332
--- /dev/null
+++ b/lib/plugins/note/lang/en/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * English language file
+ */
+
+$lang['note_picker']  = 'Notes';
+
+$lang['tb_note']      = 'Note';
+$lang['tb_tip']       = 'Tip';
+$lang['tb_important'] = 'Important';
+$lang['tb_warning']   = 'Warning';
diff --git a/lib/plugins/note/lang/fr/lang.php b/lib/plugins/note/lang/fr/lang.php
new file mode 100644
index 0000000..b403228
--- /dev/null
+++ b/lib/plugins/note/lang/fr/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * French language file
+ */
+
+$lang['note_picker']  = 'Note';
+
+$lang['tb_note']      = 'Note';
+$lang['tb_tip']       = 'Conseil';
+$lang['tb_important'] = 'Important';
+$lang['tb_warning']   = 'Alerte';
diff --git a/lib/plugins/note/lang/ru/lang.php b/lib/plugins/note/lang/ru/lang.php
new file mode 100644
index 0000000..066d90b
--- /dev/null
+++ b/lib/plugins/note/lang/ru/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Russian language file
+ */
+
+$lang['note_picker']  = 'Заметки';
+
+$lang['tb_note']      = 'Заметка';
+$lang['tb_tip']       = 'Совет';
+$lang['tb_important'] = 'Важно';
+$lang['tb_warning']   = 'Внимание';
diff --git a/lib/plugins/note/manager.dat b/lib/plugins/note/manager.dat
index 957c95b..9fb1b20 100644
--- a/lib/plugins/note/manager.dat
+++ b/lib/plugins/note/manager.dat
@@ -1,3 +1,3 @@
-downloadurl=https://github.com/LarsGit223/dokuwiki_note/archive/2018-04-28.zip
+downloadurl=https://github.com/LarsGit223/dokuwiki_note/archive/2019-04-18.zip
 installed=Tue, 25 Nov 2014 17:51:59 +0100
-updated=Sun, 16 Sep 2018 21:58:52 +0200
+updated=Fri, 23 Aug 2019 10:10:34 +0200
diff --git a/lib/plugins/note/odt.css b/lib/plugins/note/odt.css
index ab7defc..8fb26d1 100644
--- a/lib/plugins/note/odt.css
+++ b/lib/plugins/note/odt.css
@@ -1,4 +1,4 @@
-.noteclassic, .noteimportant, .notewarning, .notetip {
+.plugin_note {
   margin: 2em;
   margin-left: auto;
   margin-right: auto;
diff --git a/lib/plugins/note/plugin.info.txt b/lib/plugins/note/plugin.info.txt
index 8713a80..242a640 100644
--- a/lib/plugins/note/plugin.info.txt
+++ b/lib/plugins/note/plugin.info.txt
@@ -1,7 +1,7 @@
 base   note
 author Olivier Cortès, Eric Hameleers, Christopher Smith, Aurélien Bompard, LarsDW223
 email  olive at deep-ocean.net
-date   2018-04-28
+date   2019-04-18
 name   Note Plugin
 desc   Add Note/Important/Tip/Warning Capability (DIV+CSS box)
 url    https://www.dokuwiki.org/plugin:note
diff --git a/lib/plugins/note/style.css b/lib/plugins/note/style.css
index 38e8d71..63eee02 100644
--- a/lib/plugins/note/style.css
+++ b/lib/plugins/note/style.css
@@ -1,10 +1,7 @@
-.noteclassic, .noteimportant, .notewarning, .notetip {
-  margin: 2em;
-  margin-left: auto;
-  margin-right: auto;
-  width: 70% !important;
+.plugin_note {
+  margin: 2em auto;
+  max-width: 70%;
   min-height: 40px;
-  clear: both;
   text-align: justify;
   vertical-align: middle;
   border-collapse: collapse;
@@ -14,6 +11,8 @@
   -moz-border-radius: 20px;
   -khtml-border-radius: 20px;
   border-radius: 6px;
+  color: black;
+  overflow: hidden;
 }
  
 .noteclassic {
@@ -24,7 +23,7 @@
  
 .noteimportant {
   /*border: 1px solid #ff0;*/
-  background-color: #ffc;
+  background-color: #ffffcc;
   background-image: url(images/important.png);
 }
  
@@ -36,6 +35,6 @@
  
 .notetip {
   /*border: 1px solid #9d9;*/
-  background-color: #dfd;
+  background-color: #ddffdd;
   background-image: url(images/tip.png);
 }
diff --git a/lib/plugins/note/syntax.php b/lib/plugins/note/syntax.php
index 3b8294d..e3b1195 100644
--- a/lib/plugins/note/syntax.php
+++ b/lib/plugins/note/syntax.php
@@ -34,21 +34,25 @@
  * @author     Olivier Cortes <olive at deep-ocean.net>
  */
  
-if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
-if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
-require_once(DOKU_PLUGIN.'syntax.php');
+if (!defined('DOKU_INC')) {
+    define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
+}
+if (!defined('DOKU_PLUGIN')) {
+    define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+}
+require_once DOKU_PLUGIN.'syntax.php';
 
 
 class syntax_plugin_note extends DokuWiki_Syntax_Plugin {
- 
+
     var $notes = array(
         'noteimportant' => array('important', 'importante'),
         'notewarning'   => array('warning','bloquante','critique'),
         'notetip'       => array('tip','tuyau','idée'),
         'noteclassic'   => array('','classic','classique')
       );
-      
-    var $default = 'noteclassic';
+
+    var $default = 'plugin_note noteclassic';
 
     function getType(){ return 'container'; }
     function getPType(){ return 'block'; }
@@ -58,12 +62,14 @@ class syntax_plugin_note extends DokuWiki_Syntax_Plugin {
 
     function getSort(){ return 195; }
 
-    // override default accepts() method to allow nesting 
+    // override default accepts() method to allow nesting
     // - ie, to get the plugin accepts its own entry syntax
     function accepts($mode) {
-      if ($mode == substr(get_class($this), 7)) return true;
+        if ($mode == substr(get_class($this), 7)) {
+            return true;
+        }
         return parent::accepts($mode);
-      }
+    }
 
     function connectTo($mode) {
         $this->Lexer->addEntryPattern('<note.*?>(?=.*?</note>)',$mode,'plugin_note');
@@ -74,69 +80,62 @@ class syntax_plugin_note extends DokuWiki_Syntax_Plugin {
     }
 
     function handle($match, $state, $pos, Doku_Handler $handler) {
-
         switch ($state) {
-
-          case DOKU_LEXER_ENTER : 
-            $note = strtolower(trim(substr($match,5,-1)));
+            case DOKU_LEXER_ENTER:
+                $note = strtolower(trim(substr($match,5,-1)));
  
-            foreach( $this->notes as $class => $names ) {
-              if (in_array($note, $names))
-                return array($state, $class);
-            }            
-            
-            return array($state, $this->default);          
+                foreach( $this->notes as $class => $names ) {
+                    if (in_array($note, $names))
+                        return array($state, $class);
+                }
+                return array($state, $this->default);
  
-          case DOKU_LEXER_UNMATCHED :
-            return array($state, $match);
-        
-          default:
-            return array($state);
+            case DOKU_LEXER_UNMATCHED:
+                return array($state, $match);
+
+            default:
+                return array($state);
         }
     }
 
     function render($mode, Doku_Renderer $renderer, $indata) {
-
         if($mode == 'xhtml'){
+            list($state, $data) = $indata;
 
-          list($state, $data) = $indata;
-
-          switch ($state) {
-            case DOKU_LEXER_ENTER :
-              $renderer->doc .= '<div class="'.$data.'">';
-              break;
+            switch ($state) {
+                case DOKU_LEXER_ENTER :
+                    $renderer->doc .= '<div class="plugin_note '.$data.'">';
+                break;
   
-            case DOKU_LEXER_UNMATCHED :
-              $renderer->doc .= $renderer->_xmlEntities($data);
-              break;
+                case DOKU_LEXER_UNMATCHED :
+                    $renderer->doc .= $renderer->_xmlEntities($data);
+                break;
   
-            case DOKU_LEXER_EXIT :
-              $renderer->doc .= "\n</div>";
-              break;
-          }
-          return true;
-
+                case DOKU_LEXER_EXIT :
+                    $renderer->doc .= "\n</div>";
+                break;
+            }
+            return true;
         } elseif ($mode == 'odt'){
+            list($state, $data) = $indata;
 
-          list($state, $data) = $indata;
-
-          $this->render_odt ($renderer, $state, $data);
-          return true;
+            $this->render_odt ($renderer, $state, $data);
+            return true;
         }
         
         // unsupported $mode
         return false;
-    } 
+    }
 
     protected function render_odt ($renderer, $state, $data) {
         static $first = true;
         static $new;
-        
+
         if ($first == true) {
             $new = method_exists ($renderer, 'getODTPropertiesFromElement');
             $first = false;
         }
-        
+
         if (!$new) {
             // Render with older ODT plugin version.
             $this->render_odt_old ($renderer, $state, $data);
@@ -150,10 +149,11 @@ class syntax_plugin_note extends DokuWiki_Syntax_Plugin {
         switch ($state) {
             case DOKU_LEXER_ENTER:
                 $type = substr($data, 4);
-                if ($type == "classic") {
-                    $type = "note"; // the icon for classic notes is named note.png
+                if ($type == 'classic') {
+                    // The icon for classic notes is named note.png
+                    $type = 'note';
                 }
-                $colors = array("note"=>"#eeeeff", "warning"=>"#ffdddd", "important"=>"#ffffcc", "tip"=>"#ddffdd");
+                $colors = array('note' => '#eeeeff', 'warning' => '#ffdddd', 'important' => '#ffffcc', 'tip' => '#ddffdd');
 
                 // Content
                 $properties = array();
@@ -180,7 +180,7 @@ class syntax_plugin_note extends DokuWiki_Syntax_Plugin {
                 $properties ['background-color'] = $colors[$type];
                 $renderer->_odtTableCellOpenUseProperties($properties);
 
-                $src = DOKU_PLUGIN."note/images/".$type.".png";
+                $src = DOKU_PLUGIN.'note/images/'.$type.'.png';
                 $renderer->_odtAddImage($src);
 
                 $renderer->tablecell_close();
@@ -191,18 +191,18 @@ class syntax_plugin_note extends DokuWiki_Syntax_Plugin {
                 $properties ['border'] = '0.002cm solid #000000';
                 $properties ['background-color'] = $colors[$type];
                 $renderer->_odtTableCellOpenUseProperties($properties);
-                break;
+            break;
 
             case DOKU_LEXER_UNMATCHED :
                 $renderer->cdata($data);
-                break;
+            break;
 
             case DOKU_LEXER_EXIT :
                 $renderer->tablecell_close();
                 $renderer->tablerow_close();
                 $renderer->_odtTableClose();
                 $renderer->p_open();
-                break;
+            break;
         }
     }
 
@@ -261,20 +261,20 @@ class syntax_plugin_note extends DokuWiki_Syntax_Plugin {
                 $properties ['border'] = '0.002cm solid #000000';
                 $properties ['background-color'] = $css_properties ['background-color'];
                 $renderer->_odtTableCellOpenUseProperties($properties);
-                break;
+            break;
 
             case DOKU_LEXER_UNMATCHED :
                 $renderer->cdata($data);
-                break;
+            break;
 
             case DOKU_LEXER_EXIT :
                 $renderer->tablecell_close();
                 $renderer->tablerow_close();
                 $renderer->_odtTableClose();
                 $renderer->p_open();
-                break;
+            break;
         }
     }
 }
- 
+
 //Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/lib/plugins/nsexport/action/ajax.php b/lib/plugins/nsexport/action/ajax.php
new file mode 100644
index 0000000..40da776
--- /dev/null
+++ b/lib/plugins/nsexport/action/ajax.php
@@ -0,0 +1,106 @@
+<?php
+
+if(!defined('DOKU_INC')) die();
+
+/**
+ * this part of the plugin handles all ajax requests.
+ *
+ * ajax requests are
+ *   - nsexport_start   start the export process @see prepare_dl()
+ *   - nsexport_check
+ */
+class action_plugin_nsexport_ajax extends DokuWiki_Action_Plugin {
+
+    // temporary directory
+    public $tmp;
+
+    // ID from the export zip
+    public $fileid;
+
+    public function register(Doku_Event_Handler $controller) {
+        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call');
+    }
+
+    /**
+     * route ajax calls to a function
+     */
+    public function handle_ajax_call(Doku_Event $event, $param) {
+        // we don't need this info, but we need this call to populate $conf['plugin']['nsexport']
+        $this->getConf('autoexport');
+        if ($event->data === 'nsexport_start') {
+            $event->preventDefault();
+            $this->prepare_dl();
+            return;
+        }
+
+        if ($event->data === 'nsexport_check') {
+            $event->preventDefault();
+            $this->check();
+            return;
+        }
+    }
+
+    /**
+     * check if the download is ready for download.
+     * print 0 on not ready and 1 on ready
+     */
+    public function check() {
+        $fid = $_REQUEST['key'];
+
+        if (!is_numeric($fid)) {
+            echo '0';
+            return;
+        }
+        if (!$fid) {
+            echo '0';
+            return;
+        }
+        $packer = $this->getPacker();
+        if ($packer === null || !$packer->get_status($fid)) {
+            echo '0';
+            return;
+        }
+        echo '1';
+    }
+
+    /**
+     * @return plugin_nsexport_packer|null
+     */
+    public function getPacker() {
+        $packer_file = DOKU_PLUGIN . 'nsexport/packer/ziphtml/packer.php';
+        if (!file_exists($packer_file)) {
+            return null;
+        }
+        require_once $packer_file;
+        $packer_class = 'plugin_nsexport_packer_ziphtml';
+        $packer = new $packer_class;
+        return $packer;
+    }
+
+    /**
+     * start the download creating process.
+     *
+     * echos a unique id to check back to the client, build the export
+     */
+    public function prepare_dl() {
+        global $INPUT;
+
+        $pages = $INPUT->arr('pages');
+
+
+        // turn off error reporting - we don't want any error messages in the output.
+//        error_reporting(0);
+
+        // try to ignore user abort.
+        ignore_user_abort(true);
+
+        // infinite time limit.
+        set_time_limit(0);
+
+        $packer = $this->getPacker();
+        if ($packer === null) {
+            return false;
+        }
+        $packer->start_packing($pages);
+    }
+}
diff --git a/lib/plugins/nsexport/action/export.php b/lib/plugins/nsexport/action/export.php
new file mode 100644
index 0000000..f2b1155
--- /dev/null
+++ b/lib/plugins/nsexport/action/export.php
@@ -0,0 +1,90 @@
+<?php
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Namespace export : Action component to send compressed ZIP file.
+ */
+class action_plugin_nsexport_export extends DokuWiki_Action_Plugin {
+
+    public $run = false;
+
+    /**
+     * Registers a callback function for a given event
+     *
+     * @param Doku_Event_Handler $controller
+     */
+    public function register(Doku_Event_Handler $controller) {
+        $controller->register_hook('TPL_ACT_UNKNOWN','BEFORE',  $this, 'nsexport');
+        $controller->register_hook('ACTION_ACT_PREPROCESS','BEFORE',  $this, 'act');
+    }
+
+    public function act(Doku_Event $event , $param) {
+        if ($event->data !== 'nsexport') {
+            return;
+        }
+        $event->preventDefault();
+        $this->run = true;
+    }
+
+    public function nsexport(Doku_Event $event, $param) {
+        if (!$this->run) return;
+
+        // stops default action handler
+        $event->preventDefault();
+
+        if ($this->getConf('autoexport')){
+            $id = ' plugin_nsexport__started';
+            echo $this->locale_xhtml('autointro');
+        }else{
+            $id = '';
+            echo $this->locale_xhtml('intro');
+        }
+        echo '<div class="level1"><p>' .
+             $this->getLang('packer___ziphtml___intro') .
+             '</p></div>';
+        $this->_listPages($id);
+    }
+
+    /**
+     * Create a list of pages about to be exported within a form
+     * to start the export
+     */
+    public function _listPages($id){
+        global $ID;
+
+        $pages = array();
+        $base  = dirname(wikiFN($ID));
+        search($pages,$base,'search_allpages',array());
+        $pages = array_reverse($pages);
+
+        echo '<form class="plugin_nsexport__form' . $id . '"
+                    action="'.DOKU_BASE.'lib/plugins/nsexport/export.php"
+                    method="post">';
+        echo '<p><input type="submit" id="do__export" class="button" value="'.$this->getLang('btn_export').'" />';
+        $ns = getNS($ID);
+        if(!$ns) $ns = '*';
+        printf($this->getLang('inns'), $ns);
+        echo '</p>';
+
+        echo '<ul>';
+        $num = 0;
+        $ns = getNS($ID). ':';
+        foreach($pages as $page){
+            $id = cleanID($ns . $page['id']);
+            echo '<li><div class="li"><input type="checkbox" name="export[]" '
+               . 'id="page__'.++$num.'" value="'.hsc($id).'" '
+               . 'checked="checked" /> <label for="page__'.$num.'">'
+               .  hsc($id) . '</label></div></li>';
+        }
+        echo '</ul>';
+        echo '</form>';
+    }
+
+    public function tpl_link($return = false) {
+        global $ID;
+        $caption = hsc($this->getLang('link'));
+        return tpl_link(wl($ID, array('do' => 'nsexport')), $caption,
+                        'class="action nsexport" rel="nofollow" ' .
+                        'title="' . $caption . '"', $return);
+    }
+}
diff --git a/lib/plugins/nsexport/conf/default.php b/lib/plugins/nsexport/conf/default.php
new file mode 100644
index 0000000..bb3929e
--- /dev/null
+++ b/lib/plugins/nsexport/conf/default.php
@@ -0,0 +1,4 @@
+<?php
+$conf['autoexport']                    = 0;
+$conf['packer_ziphtml_zip']      = '/usr/bin/zip';
+$conf['packer_ziphtml_compress'] = 0;
diff --git a/lib/plugins/nsexport/conf/metadata.php b/lib/plugins/nsexport/conf/metadata.php
new file mode 100644
index 0000000..e5e1ae1
--- /dev/null
+++ b/lib/plugins/nsexport/conf/metadata.php
@@ -0,0 +1,4 @@
+<?php
+$meta['autoexport']  = array('onoff');
+$meta['packer_ziphtml_zip'] = array('string');
+$meta['packer_ziphtml_compress'] = array('numeric','_pattern' => '/[0-9]{1}/');
diff --git a/lib/plugins/nsexport/export.php b/lib/plugins/nsexport/export.php
new file mode 100644
index 0000000..18a29ac
--- /dev/null
+++ b/lib/plugins/nsexport/export.php
@@ -0,0 +1,12 @@
+<?php
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../../');
+define('DOKU_DISABLE_GZIP_OUTPUT', 1);
+require_once(DOKU_INC.'inc/init.php');
+session_write_close();
+
+/** @var action_plugin_nsexport_ajax $plugin */
+$plugin = plugin_load('action','nsexport_ajax');
+$packer = $plugin->getPacker();
+if ($packer !== null) {
+    $packer->get_pack($_REQUEST['key']);
+}
diff --git a/lib/plugins/nsexport/lang/de/autointro.txt b/lib/plugins/nsexport/lang/de/autointro.txt
new file mode 100644
index 0000000..d9a9df6
--- /dev/null
+++ b/lib/plugins/nsexport/lang/de/autointro.txt
@@ -0,0 +1,3 @@
+====== Namensraumexport ======
+
+Dieses Werkzeug exportiert alle Seiten im momentanen Namensraum (und darunter). Mediadateien wie Bilder oder Dokumente die in den exportierten Seiten referenziert werden, werden ebenfalls exportiert. Abhängig von der Menge der zu exportierenden Daten kann die Generierung eine Weile dauern, bitte haben Sie etwas Geduld.
diff --git a/lib/plugins/nsexport/lang/de/intro.txt b/lib/plugins/nsexport/lang/de/intro.txt
new file mode 100644
index 0000000..ab8ebc2
--- /dev/null
+++ b/lib/plugins/nsexport/lang/de/intro.txt
@@ -0,0 +1,3 @@
+====== Namensraumexport ======
+
+Dieses Werkzeug exportiert alle Seiten im momentanen Namensraum (und darunter). Mediadateien wie Bilder oder Dokumente die in den exportierten Seiten referenziert werden, werden ebenfalls exportiert. Die betroffenen Dateien werden unten aufgeführt, durch deaktivieren der entsprechenden Checkboxen können einzelne Seiten vom Export ausgeschlossen werden. Abhängig von der Menge der zu exportierenden Daten kann die Generierung eine Weile dauern. Bitte haben sie etwas Geduld nach dem Klick au [...]
diff --git a/lib/plugins/nsexport/lang/de/lang.php b/lib/plugins/nsexport/lang/de/lang.php
new file mode 100644
index 0000000..2a51342
--- /dev/null
+++ b/lib/plugins/nsexport/lang/de/lang.php
@@ -0,0 +1,10 @@
+<?php
+
+$lang['btn_export']    = 'Ausgewählte Seiten exportieren';
+$lang['inns']          = ' im Namensraum <strong>%s</strong>';
+$lang['js']['loading'] = 'Ihr Export wird nun zusammengestellt … ';
+$lang['js']['done']    = 'fertig!';
+$lang['nopacker']      = 'Das Archivierprogram ist nicht konfiguriert.';
+
+$lang['link'] = 'Namensraum exportieren';
+$lang['packer___ziphtml___intro'] = 'Der Export erstellt ein ZIP-Archiv mit einfachen HTML-Dateien.';
diff --git a/lib/plugins/nsexport/lang/en/autointro.txt b/lib/plugins/nsexport/lang/en/autointro.txt
new file mode 100644
index 0000000..47d128e
--- /dev/null
+++ b/lib/plugins/nsexport/lang/en/autointro.txt
@@ -0,0 +1,3 @@
+====== Namespace Export ======
+
+This tool exports all pages in the current namespace (and below). Mediafiles like images or documents used in the exported pages will be exported as well. Depending on the amount of exported data, the generation can take a while, please be patient.
diff --git a/lib/plugins/nsexport/lang/en/intro.txt b/lib/plugins/nsexport/lang/en/intro.txt
new file mode 100644
index 0000000..293a0d3
--- /dev/null
+++ b/lib/plugins/nsexport/lang/en/intro.txt
@@ -0,0 +1,3 @@
+====== Namespace Export ======
+
+This tool exports all pages in the current namespace (and below). Mediafiles like images or documents used in the exported pages will be exported as well. Affected pages are listed below, disable the checkbox to exclude a page from being exported. Depending on the amount of exported data, the generation can take a while, please be patient after clicking the button.
diff --git a/lib/plugins/nsexport/lang/en/lang.php b/lib/plugins/nsexport/lang/en/lang.php
new file mode 100644
index 0000000..ea270f9
--- /dev/null
+++ b/lib/plugins/nsexport/lang/en/lang.php
@@ -0,0 +1,9 @@
+<?php
+
+$lang['btn_export'] = 'Export selected pages';
+$lang['inns'] = ' in namespace <strong>%s</strong>';
+$lang['js']['loading'] = 'Your export file is now created … ';
+$lang['js']['done'] = 'done!';
+$lang['nopacker'] = 'The Archive program is not configured.';
+$lang['link'] = 'Export namespace';
+$lang['packer___ziphtml___intro'] = 'The export creates a ZIP file containing plain HTML files.';
diff --git a/lib/plugins/nsexport/lang/en/settings.php b/lib/plugins/nsexport/lang/en/settings.php
new file mode 100644
index 0000000..95058ed
--- /dev/null
+++ b/lib/plugins/nsexport/lang/en/settings.php
@@ -0,0 +1,5 @@
+<?php
+
+$lang['autoexport'] = 'Skip the selection of exported pages and start the export process immediately?';
+$lang['packer_ziphtml_zip']        = 'Path to the zip executable';
+$lang['packer_ziphtml_compress']   = 'Compression strength (0-9 - 0 is store and 9 is best compression)';
diff --git a/lib/plugins/nsexport/manager.dat b/lib/plugins/nsexport/manager.dat
new file mode 100644
index 0000000..0d057ef
--- /dev/null
+++ b/lib/plugins/nsexport/manager.dat
@@ -0,0 +1,2 @@
+downloadurl=https://github.com/cosmocode/nsexport/zipball/master
+installed=Thu, 12 Dec 2019 07:46:22 +0100
diff --git a/lib/plugins/nsexport/packer/packer.php b/lib/plugins/nsexport/packer/packer.php
new file mode 100644
index 0000000..4f2e36a
--- /dev/null
+++ b/lib/plugins/nsexport/packer/packer.php
@@ -0,0 +1,86 @@
+<?php
+abstract class plugin_nsexport_packer extends DokuWiki_Plugin {
+
+    public function start_packing($pages) {
+
+        if (!$this->init_packing($pages)) {
+            return;
+        }
+
+        $this->fileid = time().rand(0,99999);
+
+        // return name to the client
+        echo $this->fileid;
+        flush();
+
+        foreach($pages as $ID) {
+            if( auth_quickaclcheck($ID) < AUTH_READ ) continue;
+            @set_time_limit(30);
+            $this->pack_page($ID);
+        }
+
+        $this->finish_packing();
+    }
+
+    public function init_packing($pages) {
+        return true;
+    }
+
+    public function pack_page($ID) {
+
+    }
+
+    public function finish_packing() {
+
+    }
+
+    protected function check_key($key) {
+        return is_numeric($key);
+    }
+
+    protected function result_filename() {
+        global $conf;
+        return $conf['tmpdir'] . '/offline-' . $this->fileid . '.' . $this->ext;
+    }
+
+    public function get_status($key) {
+        if (!$this->check_key($key)) {
+            return;
+        }
+        $this->fileid = $key;
+        return is_file($this->result_filename());
+    }
+
+    public function get_pack($key) {
+        if (!$this->check_key($key)) {
+            return;
+        }
+
+        @ignore_user_abort(true);
+
+        $this->fileid = $key;
+        $filename = $this->result_filename();
+        if (!is_file($filename)) {
+            send_redirect(DOKU_BASE . 'doku.php');
+        }
+
+        // send to browser
+        $mime = mimetype('.' . $this->ext, false);
+        header('Content-Type: ' . $mime[1]);
+        header('Content-Disposition: attachment; filename="export.' . $this->ext . '"');
+        header('Expires: 0');
+        header('Content-Length: ' . filesize($filename));
+        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+        header('Content-Transfer-Encoding: binary');
+        header('Pragma: public');
+        flush();
+        @set_time_limit(0);
+
+        $fh = @fopen($filename, 'rb');
+        while (!feof($fh)) {
+            echo fread($fh, 1024);
+        }
+        fclose($fh);
+        @unlink($filename);
+    }
+}
diff --git a/lib/plugins/nsexport/packer/ziphtml/compress/ziplib.php b/lib/plugins/nsexport/packer/ziphtml/compress/ziplib.php
new file mode 100644
index 0000000..8f18808
--- /dev/null
+++ b/lib/plugins/nsexport/packer/ziphtml/compress/ziplib.php
@@ -0,0 +1,18 @@
+<?php
+
+class nsexport_ziplib implements nsexport_compressor {
+
+    public $plugin = null;
+
+    public function setup(&$plugin) {
+    }
+
+    public function compress($sourceFolder, $destinationFile) {
+        global $conf;
+        chdir($sourceFolder);
+        $zip  = $conf['plugin']['nsexport']['packer_ziphtml_zip'];
+        $comp = $conf['plugin']['nsexport']['packer_ziphtml_compress'];
+        $cmd  = "$zip -q -$comp -r -u $destinationFile .";
+        system($cmd);
+    }
+}
diff --git a/lib/plugins/nsexport/packer/ziphtml/compressor.php b/lib/plugins/nsexport/packer/ziphtml/compressor.php
new file mode 100644
index 0000000..12359f9
--- /dev/null
+++ b/lib/plugins/nsexport/packer/ziphtml/compressor.php
@@ -0,0 +1,9 @@
+<?php
+
+/**
+ * A Compressor zip up a source folder in one file
+ */
+interface nsexport_compressor {
+    public function setup(&$plugin);
+    public function compress($sourceFolder, $destinationFile);
+}
diff --git a/lib/plugins/nsexport/packer/ziphtml/export.css b/lib/plugins/nsexport/packer/ziphtml/export.css
new file mode 100644
index 0000000..024cbdc
--- /dev/null
+++ b/lib/plugins/nsexport/packer/ziphtml/export.css
@@ -0,0 +1,4 @@
+/**
+ * Add custom CSS to be applied in exported files here
+ */
+
diff --git a/lib/plugins/nsexport/packer/ziphtml/packer.php b/lib/plugins/nsexport/packer/ziphtml/packer.php
new file mode 100644
index 0000000..68b2a3d
--- /dev/null
+++ b/lib/plugins/nsexport/packer/ziphtml/packer.php
@@ -0,0 +1,191 @@
+<?php
+require_once DOKU_PLUGIN.'nsexport/packer/ziphtml/compressor.php';
+require_once DOKU_PLUGIN.'nsexport/packer/ziphtml/compress/ziplib.php';
+require_once DOKU_PLUGIN.'nsexport/packer/ziphtml/renderer.php';
+require_once DOKU_PLUGIN.'nsexport/packer/packer.php';
+
+class plugin_nsexport_packer_ziphtml extends plugin_nsexport_packer {
+    public $ext = 'zip';
+
+    public function init_packing($pages) {
+        global $conf;
+        // early check if the zip executable is available
+        $packer = $conf['plugin']['nsexport']['packer_ziphtml_zip'];
+        if (!file_exists($packer) || !is_file($packer)) {
+            return false;
+        }
+
+        // prepare some basic settings
+        $this->tmp  = io_mktmpdir();
+        if ($this->tmp === false) {
+            // no tmpdir
+            return false;
+        }
+
+        $this->media = array();
+
+        // begin data collecting
+        // add CSS
+        $http  = new DokuHTTPClient();
+        $css   = $http->get(DOKU_URL.'lib/exe/css.php?s=all&t='.$conf['template']);
+        $this->_addFile('all.css',$css);
+        $css   = $http->get(DOKU_URL.'lib/exe/css.php?t='.$conf['template']);
+        $this->_addFile('screen.css',$css);
+        $css   = $http->get(DOKU_URL.'lib/exe/css.php?s=print&t='.$conf['template']);
+        $this->_addFile('print.css',$css);
+        $css   = io_readFile(dirname(__FILE__).'/export.css',false);
+        $this->_addFile('export.css',$css);
+
+        return parent::init_packing($pages);
+    }
+
+    public function pack_page($ID_PAGE) {
+        global $conf;
+        global $lang;
+        global $ID;
+
+        $ID = $ID_PAGE;
+
+        // create relative path to top directory
+        $deep = substr_count($ID,':');
+        $ref  = '';
+        for($i=0; $i<$deep; $i++) $ref .= '../';
+
+        // create the output
+        $this->Renderer = new renderer_plugin_nsexport_xhtml;
+
+        $this->Renderer->smileys = getSmileys();
+        $this->Renderer->entities = getEntities();
+        $this->Renderer->acronyms = getAcronyms();
+        $this->Renderer->interwiki = getInterwiki();
+
+        $instructions = p_cached_instructions(wikiFN($ID,''),false,$ID);
+        foreach ( $instructions as $instruction ) {
+            // Execute the callback against the Renderer
+            call_user_func_array(array(&$this->Renderer, $instruction[0]),
+                                 $instruction[1]);
+        }
+        $html = $this->Renderer->doc;
+
+        $output  = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.DOKU_LF;
+        $output .= ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'.DOKU_LF;
+        $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$conf['lang'].'"'.DOKU_LF;
+        $output .= ' lang="'.$conf['lang'].'" dir="'.$lang['direction'].'">' . DOKU_LF;
+        $output .= '<head>'.DOKU_LF;
+        $output .= '  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'.DOKU_LF;
+        $output .= '  <title>'.$ID.'</title>'.DOKU_LF;
+        $output .= '  <link rel="stylesheet" media="all" type="text/css" href="'.$ref.'all.css" />'.DOKU_LF;
+        $output .= '  <link rel="stylesheet" media="screen" type="text/css" href="'.$ref.'screen.css" />'.DOKU_LF;
+        $output .= '  <link rel="stylesheet" media="print" type="text/css" href="'.$ref.'print.css" />'.DOKU_LF;
+        $output .= '  <link rel="stylesheet" media="all" type="text/css" href="'.$ref.'export.css" />'.DOKU_LF;
+        $output .= '</head>'.DOKU_LF;
+        $output .= '<body>'.DOKU_LF;
+        $output .= '<div class="dokuwiki export">' . DOKU_LF;
+        $output .= tpl_toc(true);
+        $output .= $html;
+        $output .= '</div>';
+        $output .= '</body>'.DOKU_LF;
+        $output .= '</html>'.DOKU_LF;
+
+        $this->_addFile(str_replace(':','/',$ID).'.html',$output);
+        $this->media = array_merge($this->media, $this->Renderer->_media);
+    }
+
+    public function finish_packing() {
+        global $conf;
+
+        // now embed the media
+        $this->media = array_map('cleanID',$this->media);
+        $this->media = array_unique($this->media);
+        foreach($this->media as $id) {
+            if( auth_quickaclcheck($id) < AUTH_READ ) continue;
+            @set_time_limit(30);
+            $this->_addFile('_media/'.str_replace(':','/',$id),io_readFile(mediaFN($id),false));
+        }
+
+        // add the merge directory contents
+        $this->recursive_add(dirname(__FILE__).'/merge');
+
+        // finished data collecting
+        $to = $conf['tmpdir'] . '/wrk-' . $this->fileid . '.zip';
+
+        // append wiki export
+        $zipper = new nsexport_ziplib();
+        $zipper->setup($this);
+        $zipper->compress($this->tmp, $to);
+
+        // cleanup
+        $this->rmdirr($this->tmp);
+
+        // rename so ajax can find it
+        rename($to, $this->result_filename());
+    }
+
+    /**
+     * add a single file.
+     *
+     * @param string $filename     filename to store
+     * @param string $content      the file content
+     */
+    public function _addFile($filename, $content) {
+        $filename = $this->tmp . "/$filename";
+        io_makeFileDir($filename);
+        file_put_contents($filename , $content);
+    }
+
+    /**
+     * add a whole dir with subdirs.
+     */
+    public function recursive_add($base, $dir='') {
+        $fh = @opendir("$base/$dir");
+        if(!$fh) return;
+        while(false !== ($file = readdir($fh))) {
+            @set_time_limit(30);
+            if($file === '..' || $file[0] === '.') continue;
+            if(is_dir("$base/$dir/$file")) {
+                $this->recursive_add($base,"$dir/$file");
+            }else {
+                $this->_addFile("$dir/$file",io_readFile("$base/$dir/$file",false));
+            }
+        }
+        closedir($fh);
+    }
+
+    /**
+     * Delete a file, or a folder and its contents (recursive algorithm)
+     *
+     * @author      Aidan Lister <aidan at php.net>
+     * @version     1.0.3
+     * @link        http://aidanlister.com/repos/v/function.rmdirr.php
+     * @param       string   $dirname    Directory to delete
+     * @return      bool     Returns TRUE on success, FALSE on failure
+     */
+    public function rmdirr($dirname) {
+        // Sanity check
+        if (!file_exists($dirname)) {
+            return false;
+        }
+
+        // Simple delete for a file
+        if (is_file($dirname) || is_link($dirname)) {
+            return unlink($dirname);
+        }
+
+        // Loop through the folder
+        $dir = dir($dirname);
+        while (false !== $entry = $dir->read()) {
+            // Skip pointers
+            if ($entry === '.' || $entry === '..') {
+                continue;
+            }
+
+            // Recurse
+            $this->rmdirr($dirname . DIRECTORY_SEPARATOR . $entry);
+        }
+
+        // Clean up
+        $dir->close();
+        return rmdir($dirname);
+    }
+
+}
diff --git a/lib/plugins/nsexport/packer/ziphtml/renderer.php b/lib/plugins/nsexport/packer/ziphtml/renderer.php
new file mode 100644
index 0000000..c26d428
--- /dev/null
+++ b/lib/plugins/nsexport/packer/ziphtml/renderer.php
@@ -0,0 +1,231 @@
+<?php
+/**
+ * Renderer for XHTML output
+ *
+ * @author Andreas Gohr <andi at splitbrain.org>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+// we inherit from the XHTML renderer instead directly of the base renderer
+require_once DOKU_INC.'inc/parser/xhtml.php';
+
+/**
+ * The Renderer
+ */
+class renderer_plugin_nsexport_xhtml extends Doku_Renderer_xhtml {
+
+    public $_media = array();
+
+    public function _relTop(){
+        // relative URLs we need
+        global $ID;
+        $deep = substr_count($ID,':');
+        $ref  = '';
+        for($i=0; $i<$deep; $i++) $ref .= '../';
+        return $ref;
+    }
+
+    public function _localMedia($src){
+        // rewrite local media and move to zip
+        if(!preg_match('/^\w+:\/\//',$src)){
+            $this->_media[] = $src;
+
+            $ref = $this->_relTop();
+            $src = $ref.'_media/'.str_replace(':','/',$src);
+        }
+        return $src;
+    }
+
+    /**
+     * Store all referenced media in metadata
+     */
+    public function document_end(){
+        global $ID;
+        parent::document_end();
+
+        $this->_media = array_unique($this->_media);
+        p_set_metadata($ID,array('plugin_nsexport'=>$this->_media));
+    }
+
+
+    /**
+     * Rewrite all internal links to local html files
+     */
+    public function internallink($id, $name = null, $search=null, $returnonly=false, $linktype='content') {
+        global $conf;
+        global $ID;
+        // default name is based on $id as given
+        $default = $this->_simpleTitle($id);
+
+        $ref = $this->_relTop();
+
+        // now first resolve and clean up the $id
+        resolve_pageid(getNS($ID),$id,$exists);
+        $name = $this->_getLinkTitle($name, $default, $isImage, $id, $linktype);
+        if ( !$isImage ) {
+            if ( $exists ) {
+                $class='wikilink1';
+                // fixme check if this a exported page, if not skip it
+
+            } else {
+                // doesn't exist? skip it
+                $this->cdata($name);
+                return;
+            }
+        } else {
+            $class='media';
+        }
+
+        //keep hash anchor
+        list($id,$hash) = explode('#',$id,2);
+        if(!empty($hash)) $hash = $this->_headerToLink($hash);
+
+        //prepare for formating
+        $link['target'] = $conf['target']['wiki'];
+        $link['style']  = '';
+        $link['pre']    = '';
+        $link['suf']    = '';
+        // highlight link to current page
+        if ($id === $ID) {
+            $link['pre']    = '<span class="curid">';
+            $link['suf']    = '</span>';
+        }
+        $link['more']   = '';
+        $link['class']  = $class;
+        $link['url']    = $ref.str_replace(':','/',$id).'.html';
+        $link['name']   = $name;
+        $link['title']  = $id;
+
+        //keep hash
+        if($hash) $link['url'].='#'.$hash;
+
+        //output formatted
+        $this->doc .= $this->_formatLink($link);
+    }
+
+    /**
+     * Renders internal and external media
+     *
+     * @author Andreas Gohr <andi at splitbrain.org>
+     */
+    public function _media ($src, $title=null, $align=null, $width=null,
+                            $height=null, $cache=null, $render = true) {
+        $ret = '';
+        $src = $this->_localMedia($src);
+
+        list($ext,$mime,$dl) = mimetype($src);
+        if(substr($mime,0,5) === 'image'){
+            // first get the $title
+            if (!is_null($title)) {
+                $title  = $this->_xmlEntities($title);
+            }elseif($ext === 'jpg' || $ext === 'jpeg'){
+                //try to use the caption from IPTC/EXIF
+                require_once(DOKU_INC.'inc/JpegMeta.php');
+                $jpeg = new JpegMeta(mediaFN($src));
+                if($jpeg !== false) $cap = $jpeg->getTitle();
+                if($cap){
+                    $title = $this->_xmlEntities($cap);
+                }
+            }
+            if (!$render) {
+                // if the picture is not supposed to be rendered
+                // return the title of the picture
+                if (!$title) {
+                    // just show the sourcename
+                    $title = $this->_xmlEntities(basename(noNS($src)));
+                }
+                return $title;
+            }
+            //add image tag
+            $ret .= '<img src="'.$src.'"';
+            $ret .= ' class="media'.$align.'"';
+
+            // make left/right alignment for no-CSS view work (feeds)
+            if($align === 'right') $ret .= ' align="right"';
+            if($align === 'left')  $ret .= ' align="left"';
+
+            if ($title) {
+                $ret .= ' title="' . $title . '"';
+                $ret .= ' alt="'   . $title .'"';
+            }else{
+                $ret .= ' alt=""';
+            }
+
+            if ( !is_null($width) )
+                $ret .= ' width="'.$this->_xmlEntities($width).'"';
+
+            if ( !is_null($height) )
+                $ret .= ' height="'.$this->_xmlEntities($height).'"';
+
+            $ret .= ' />';
+
+        }elseif($mime === 'application/x-shockwave-flash'){
+            if (!$render) {
+                // if the flash is not supposed to be rendered
+                // return the title of the flash
+                if (!$title) {
+                    // just show the sourcename
+                    $title = basename(noNS($src));
+                }
+                return $this->_xmlEntities($title);
+            }
+
+            $att = array();
+            $att['class'] = "media$align";
+            if($align === 'right') $att['align'] = 'right';
+            if($align === 'left')  $att['align'] = 'left';
+            $ret .= html_flashobject($src,$width,$height,
+                                     array('quality' => 'high'),
+                                     null,
+                                     $att,
+                                     $this->_xmlEntities($title));
+        }elseif($title){
+            // well at least we have a title to display
+            $ret .= $this->_xmlEntities($title);
+        }else{
+            // just show the sourcename
+            $ret .= $this->_xmlEntities(basename(noNS($src)));
+        }
+
+        return $ret;
+    }
+
+    public function internalmedia ($src, $title = null, $align = null, $width = null,
+                                   $height = null, $cache = null, $linking = null, $return = false) {
+        global $ID;
+        list($src,$hash) = explode('#',$src,2);
+        resolve_mediaid(getNS($ID),$src, $exists);
+
+        $lsrc = $this->_localMedia($src);
+        $noLink = false;
+        $render = ($linking === 'linkonly') ? false : true;
+        $link = $this->_getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render);
+        $link['url'] = $lsrc;
+
+        list($ext,$mime,$dl) = mimetype($src);
+        if(substr($mime,0,5) === 'image' && $render){
+        }elseif($mime === 'application/x-shockwave-flash' && $render){
+            // don't link flash movies
+            $noLink = true;
+        }else{
+            // add file icons
+            $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext);
+            $link['class'] .= ' mediafile mf_'.$class;
+        }
+
+        if($hash) $link['url'] .= '#'.$hash;
+
+        //markup non existing files
+        if (!$exists)
+          $link['class'] .= ' wikilink2';
+
+        //output formatted
+        if ($linking === 'nolink' || $noLink) $this->doc .= $link['name'];
+        else $this->doc .= $this->_formatLink($link);
+
+    }
+
+
+}
+
diff --git a/lib/plugins/nsexport/packer/ziphtml/zip.php b/lib/plugins/nsexport/packer/ziphtml/zip.php
new file mode 100644
index 0000000..d58b471
--- /dev/null
+++ b/lib/plugins/nsexport/packer/ziphtml/zip.php
@@ -0,0 +1,210 @@
+<?php
+
+/**
+ * USING
+ *
+ * zip.php <key> <user> <serialized pages> <serialized userinfo[grps]>
+ */
+
+
+if ('cli' !== php_sapi_name()) die();
+
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../').'/');
+define('NOSESSION',1);
+require_once(DOKU_INC.'inc/init.php');
+require_once(DOKU_INC.'inc/common.php');
+require_once(DOKU_INC.'inc/parserutils.php');
+require_once(DOKU_INC.'inc/cliopts.php');
+require_once(DOKU_INC.'inc/auth.php');
+require_once(DOKU_INC.'inc/io.php');
+
+$args = Doku_Cli_Opts::readPHPArgv();
+
+if (count($args) !== 5) die(-1);
+
+class nsexport_zip {
+
+    public $tmp;
+
+    public function _addFile($filename, $content) {
+        $filename = $this->tmp . "/$filename";
+        io_makeFileDir($filename);
+        file_put_contents($filename , $content);
+    }
+
+    public function recursive_add($base, $dir=''){
+        $fh = @opendir("$base/$dir");
+        if(!$fh) return;
+        while(false !== ($file = readdir($fh))) {
+            @set_time_limit(30);
+            if($file === '..' || $file[0] === '.') continue;
+            if(is_dir("$base/$dir/$file")){
+                $this->recursive_add($base,"$dir/$file");
+            }else{
+                $this->_addFile("$dir/$file",io_readFile(ltrim("$base/$dir/$file",'/'),false));
+            }
+        }
+        closedir($fh);
+    }
+
+    /**
+     * Delete a file, or a folder and its contents (recursive algorithm)
+     *
+     * @author      Aidan Lister <aidan at php.net>
+     * @version     1.0.3
+     * @link        http://aidanlister.com/repos/v/function.rmdirr.php
+     * @param       string   $dirname    Directory to delete
+     * @return      bool     Returns TRUE on success, FALSE on failure
+     */
+    public function rmdirr($dirname)
+    {
+        // Sanity check
+        if (!file_exists($dirname)) {
+            return false;
+        }
+
+        // Simple delete for a file
+        if (is_file($dirname) || is_link($dirname)) {
+            return unlink($dirname);
+        }
+
+        // Loop through the folder
+        $dir = dir($dirname);
+        while (false !== $entry = $dir->read()) {
+            // Skip pointers
+            if ($entry === '.' || $entry === '..') {
+                continue;
+            }
+
+            // Recurse
+            $this->rmdirr($dirname . DIRECTORY_SEPARATOR . $entry);
+        }
+
+        // Clean up
+        $dir->close();
+        return rmdir($dirname);
+    }
+
+    public function start($key, $user, $pages, $groups) {
+        global $conf;
+        global $lang;
+
+        $pages = unserialize($pages);
+
+        require_once(DOKU_INC.'inc/HTTPClient.php');
+        error_reporting(0);
+
+        // check if the 7ip executable is availible
+        // FIXME
+        $packer = $this->getConf('packer_ziphtml_zip');
+        if (!file_exists($packer) || !is_file($packer))
+        {
+            return;
+        }
+
+        $media = array();
+        $tmpdir  = io_mktmpdir();
+        if ($tmpdir === false) {
+            // no tmpdir
+            return;
+        }
+        $this->tmp = $tmpdir;
+
+
+        // add CSS
+        $http  = new DokuHTTPClient();
+        $css   = $http->get(DOKU_URL.'lib/exe/css.php?s=all&t='.$conf['template']);
+        $this->_addFile('all.css',$css);
+        $css   = $http->get(DOKU_URL.'lib/exe/css.php?t='.$conf['template']);
+        $this->_addFile('screen.css',$css);
+        $css   = $http->get(DOKU_URL.'lib/exe/css.php?s=print&t='.$conf['template']);
+        $this->_addFile('print.css',$css);
+        $css   = io_readFile(dirname(__FILE__).'/export.css',false);
+        $this->_addFile('export.css',$css);
+
+        unset($html);
+
+        foreach($pages as $ID){
+            if( auth_aclcheck($ID, $user, $groups) < AUTH_READ ) continue;
+            @set_time_limit(30);
+
+            // create relative path to top directory
+            $deep = substr_count($ID,':');
+            $ref  = '';
+            for($i=0; $i<$deep; $i++) $ref .= '../';
+
+            // create the output
+            $html = p_cached_output(wikiFN($ID,''), 'nsexport_xhtml');
+
+            $output  = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.DOKU_LF;
+            $output .= ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'.DOKU_LF;
+            $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$conf['lang'].'"'.DOKU_LF;
+            $output .= ' lang="'.$conf['lang'].'" dir="'.$lang['direction'].'">' . DOKU_LF;
+            $output .= '<head>'.DOKU_LF;
+            $output .= '  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'.DOKU_LF;
+            $output .= '  <title>'.$ID.'</title>'.DOKU_LF;
+            $output .= '  <link rel="stylesheet" media="all" type="text/css" href="'.$ref.'all.css" />'.DOKU_LF;
+            $output .= '  <link rel="stylesheet" media="screen" type="text/css" href="'.$ref.'screen.css" />'.DOKU_LF;
+            $output .= '  <link rel="stylesheet" media="print" type="text/css" href="'.$ref.'print.css" />'.DOKU_LF;
+            $output .= '  <link rel="stylesheet" media="all" type="text/css" href="'.$ref.'export.css" />'.DOKU_LF;
+            $output .= '</head>'.DOKU_LF;
+            $output .= '<body>'.DOKU_LF;
+            $output .= '<div class="dokuwiki export">' . DOKU_LF;
+            $output .= tpl_toc(true);
+            $output .= $html;
+            $output .= '</div>';
+            $output .= '</body>'.DOKU_LF;
+            $output .= '</html>'.DOKU_LF;
+
+            $this->_addFile(str_replace(':','/',$ID).'.html',$output);
+            $media = array_merge($media,(array) p_get_metadata($ID,'plugin_nsexport'));
+        }
+
+        // now embed the media
+        $media = array_map('cleanID',$media);
+        $media = array_unique($media);
+        foreach($media as $id){
+            if( auth_quickaclcheck($id) < AUTH_READ ) continue;
+            @set_time_limit(30);
+            $this->_addFile('_media/'.str_replace(':','/',$id),io_readFile(mediaFN($id),false));
+        }
+
+
+        // add the merge directory contents
+        $this->recursive_add(dirname(__FILE__).'/merge');
+
+        echo basename($this->tmp);
+
+    }
+
+    /**
+     * Do the action
+     */
+    public function _export_html($pages){
+        global $conf;
+        @ignore_user_abort(true);
+        $filename = $conf['tmpdir'].'/offline-'.time().rand(0,99999).'.zip';
+        $this->zip = $filename;
+        $zfn = preg_replace('/^([a-z]{1}):/i','$1:\\',$filename);
+        $efn = preg_replace('/^([a-z]{1}):/i','$1:\\',$this->tmp.'/');
+
+        // send to browser
+        header('Content-Type: application/zip');
+        header('Content-Disposition: attachment; filename="export.zip"');
+        header('Expires: 0');
+        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+        header('Content-Transfer-Encoding: binary');
+        header('Pragma: public');
+        flush();
+        @set_time_limit(0);
+
+        chdir($efn);
+        $zip = $this->getConf('packer_ziphtml_zip');
+        $comp = $this->getConf('packer_ziphtml_compress');
+        $cmd = "$zip -q -$comp -r - .";
+        system($cmd);
+
+        // cleanup
+        $this->rmdirr($this->tmp);
+    }
+}
diff --git a/lib/plugins/nsexport/plugin.info.txt b/lib/plugins/nsexport/plugin.info.txt
new file mode 100644
index 0000000..49fb084
--- /dev/null
+++ b/lib/plugins/nsexport/plugin.info.txt
@@ -0,0 +1,7 @@
+base    nsexport
+author  Andreas Gohr
+email   dokuwiki at cosmocode.de
+date    2017-02-08
+name    Namespace Export
+desc    Export all pages in a given namespace
+url     http://www.dokuwiki.org/plugin:nsexport
diff --git a/lib/plugins/nsexport/script.js b/lib/plugins/nsexport/script.js
new file mode 100644
index 0000000..0b783af
--- /dev/null
+++ b/lib/plugins/nsexport/script.js
@@ -0,0 +1,89 @@
+/**
+ * check if the dl is ready
+ *
+ * @param key file key
+ */
+jQuery(function handleDOMReady() {
+    'use strict';
+
+    let $form = jQuery('form.plugin_nsexport__form');
+    if ($form.length === 0) return;
+    $form = $form.first();
+
+    const INTERVAL_MAX = 10000;
+    const INTERVAL_STEP = 1000;
+    let intervalId = null;
+    let interval = 500;
+
+    window.nsexport_check = function nsexportCheck(key) {
+        const url = DOKU_BASE + 'lib/exe/ajax.php';
+        const data = {
+            call: 'nsexport_check',
+            key: key,
+        };
+
+        jQuery.post(url, data).done(function handleCheckResult(response) {
+            clearInterval(intervalId);
+
+            if (response === '1') {
+                // download is ready - get it
+                const $throb = jQuery('#plugin_nsexport__throbber');
+                $throb.replaceWith(LANG.plugins.nsexport.done);
+                window.location = DOKU_BASE + 'lib/plugins/nsexport/export.php?key=' + key;
+                return false;
+            }
+
+            if (interval < INTERVAL_MAX) {
+                interval += INTERVAL_STEP;
+            }
+            intervalId = setInterval(window.nsexport_check, interval, response);
+
+            // download not ready - wait
+            return false;
+        });
+    };
+
+    function startExport() {
+        const data = {
+            call: 'nsexport_start',
+            pages: [],
+        };
+
+        $form.find('[name="export[]"]:checked').each(function extractPageID(index, element) {
+            data.pages.push(element.value);
+        });
+
+        const url = DOKU_BASE + 'lib/exe/ajax.php';
+
+        jQuery.post(url, data).done(
+            function packagingStarted(response) {
+                if (response === '') {
+                    return;
+                }
+                // start waiting for dl
+                intervalId = setInterval(window.nsexport_check, interval, response);
+            }
+        );
+
+        const $msg = jQuery('<div>').addClass('level1').html('<p>' + LANG.plugins.nsexport.loading
+            + '<img id="plugin_nsexport__throbber" src="' + DOKU_BASE + 'lib/images/throbber.gif" alt="…"></p>');
+
+        $form.replaceWith($msg);
+    }
+
+    if ($form.hasClass('plugin_nsexport__started')) {
+        // Autostart
+        startExport();
+        return;
+    }
+
+    $form.submit(function handleFormSubmit(e) {
+        $form.removeClass().addClass('plugin_nsexport__started');
+
+        startExport();
+
+        e.preventDefault();
+        e.stopPropagation();
+        return false;
+    });
+});
diff --git a/lib/plugins/nsexport/style.css b/lib/plugins/nsexport/style.css
new file mode 100644
index 0000000..e0cfd7d
--- /dev/null
+++ b/lib/plugins/nsexport/style.css
@@ -0,0 +1,29 @@
+form.plugin_nsexport__form li {
+    padding: 3px 0;
+}
+
+form.plugin_nsexport__form .ondrag {
+    opacity: 1;
+}
+
+form.plugin_nsexport__form li.ondrag label {
+    color: __text_other__;
+}
+
+form.plugin_nsexport__form li div.li {
+    display: inline;
+    border-radius: 4px;
+    -webkit-border-radius: 4px;
+    -moz-border-radius: 4px;
+    border: 1px solid __text_other__;
+    background: __background_neu__;
+    padding: 2px 4px;
+}
+
+form.plugin_nsexport__form li div.li input {
+    vertical-align: middle;
+}
+
+div.dokuwiki form.plugin_nsexport__started {
+    display:none;
+}
diff --git a/lib/plugins/redirect/helper.php b/lib/plugins/redirect/helper.php
index 86408bd..4c51ffb 100644
--- a/lib/plugins/redirect/helper.php
+++ b/lib/plugins/redirect/helper.php
@@ -77,4 +77,12 @@ class helper_plugin_redirect extends DokuWiki_Admin_Plugin {
 
         return $url;
     }
+
+    /**
+     * Dummy implementation of an abstract method
+     */
+    public function html()
+    {
+        return '';
+    }
 }
diff --git a/lib/plugins/redirect/lang/pl/lang.php b/lib/plugins/redirect/lang/pl/lang.php
new file mode 100644
index 0000000..ef2728e
--- /dev/null
+++ b/lib/plugins/redirect/lang/pl/lang.php
@@ -0,0 +1,9 @@
+<?php
+
+/**
+ * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Bartek S <sadupl at gmail.com>
+ */
+$lang['saved']                 = 'Dane zapisane.';
+$lang['redirected']            = 'Zostałeś przekierowany z <b>%s</b>.';
diff --git a/lib/plugins/redirect/lang/pl/settings.php b/lib/plugins/redirect/lang/pl/settings.php
new file mode 100644
index 0000000..911ee29
--- /dev/null
+++ b/lib/plugins/redirect/lang/pl/settings.php
@@ -0,0 +1,8 @@
+<?php
+
+/**
+ * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Bartek S <sadupl at gmail.com>
+ */
+$lang['showmsg']               = 'Wyświetlić wiadomość użytkownikom o przekierowaniu?';
diff --git a/lib/plugins/redirect/manager.dat b/lib/plugins/redirect/manager.dat
index 6e2006d..c4f8c47 100644
--- a/lib/plugins/redirect/manager.dat
+++ b/lib/plugins/redirect/manager.dat
@@ -1,3 +1,3 @@
 downloadurl=https://github.com/splitbrain/dokuwiki-plugin-redirect/zipball/master
 installed=Tue, 25 Nov 2014 17:53:25 +0100
-updated=Sat, 03 Mar 2018 17:16:17 +0100
+updated=Thu, 12 Dec 2019 06:10:15 +0100
diff --git a/lib/plugins/redirect/plugin.info.txt b/lib/plugins/redirect/plugin.info.txt
index cc445bf..77df49b 100644
--- a/lib/plugins/redirect/plugin.info.txt
+++ b/lib/plugins/redirect/plugin.info.txt
@@ -1,7 +1,7 @@
 base   redirect
 author Andreas Gohr
 email  andi at splitbrain.org
-date   2017-11-05
+date   2019-12-04
 name   Redirect Plugin
 desc   Redirect page access based on a central redirection list
 url    http://www.dokuwiki.org/plugin:redirect

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list