diff --git a/selected-markdown-to-bbcode-dev/info.json b/selected-markdown-to-bbcode-dev/info.json
new file mode 100644
index 0000000..4dd189f
--- /dev/null
+++ b/selected-markdown-to-bbcode-dev/info.json
@@ -0,0 +1,10 @@
+{
+ "name": "Selected Markdown to BBCode Dev Version",
+ "identifier": "selected-markdown-to-bbcode-dev",
+ "script": "selected-markdown-to-bbcode.qml",
+ "resources": ["panbbcode.lua"]
+ "authors": ["@pbek"],
+ "version": "0.0.1",
+ "minAppVersion": "17.05.8",
+ "description" : "With this script you can right click the selected text and convert it to BBCode Code.\n\nDependencies\nPancode\npanbbcode.lua\n\nInstallation\nAfter you have installed Pancode you have to download the lua script panbbcode.lua
and configure both paths in the script settings."
+}
diff --git a/selected-markdown-to-bbcode-dev/panbbcode.lua b/selected-markdown-to-bbcode-dev/panbbcode.lua
new file mode 100644
index 0000000..f43e6fd
--- /dev/null
+++ b/selected-markdown-to-bbcode-dev/panbbcode.lua
@@ -0,0 +1,293 @@
+-- panbbcode - BBCode writer for pandoc
+-- Copyright (C) 2014 Jens Oliver John < dev ! 2ion ! de >
+-- Licensed under the GNU General Public License v3 or later.
+-- Written for Lua 5.{1,2}
+
+-- PRIVATE
+
+local function enclose(t, s, p)
+ if p then
+ return string.format("[%s=%s]%s[/%s]", t, p, s, t)
+ else
+ return string.format("[%s]%s[/%s]", t, s, t)
+ end
+end
+
+local function lookup(t, e)
+ for _,v in ipairs(t) do
+ if v == e then
+ return true
+ end
+ end
+ return false
+end
+
+local strlen_ger_utf8_t = { [0xc3] = { 0xa4, 0x84, 0xbc, 0x9c, 0xb6, 0x96, 0x9f } }
+
+-- FIXME: check also the byte *after* occurences of 0xc3 (and keep the
+-- loop for that)
+local function strlen_ger_utf8(w)
+ local s = {}
+ local len = 0
+ w:gsub("(.)", function (c)
+ table.insert(s, c:byte())
+ end)
+ for i=1,#s do
+ if strlen_ger_utf8_t[s[i]] then
+ i = i + 1
+ else
+ len = len + 1
+ end
+ end
+ return len
+end
+
+local function column(s, sep, blind)
+ local s = s
+ local sep = sep or " "
+ local blind = blind or ""
+ local ret = ""
+
+ local y = {}
+ local x = {}
+ local cm = 0
+ local i = 0
+
+ for line in s:gmatch("[^\r\n]+") do
+ local ly = {}
+ local cc = 0
+ line:gsub("[^@]+", function (m)
+ local len = #m
+ cc = cc + 1
+ if cc > cm then
+ x[cc] = 0
+ cm = cc
+ end
+ if len > x[cc] then
+ x[cc] = len
+ end
+ table.insert(ly, m)
+ end)
+ table.insert(y, ly)
+ end
+ for _,line in ipairs(y) do
+ for tmp=1,(#x-#line) do
+ table.insert(line, blind)
+ end
+ for i,word in ipairs(line) do
+ -- workaround for common German utf-8 umlauts
+ local wl = word:match("[öäüÖÄÜß]") and strlen_ger_utf8(word) or #word
+ if wl < x[i] then
+ for tmp=1,(x[i]-wl) do
+ word = word .. " "
+ end
+ end
+ ret = ret .. word .. sep
+ end
+ ret = ret .. '\n'
+ end
+ return ret
+end
+
+-- PUBLIC
+
+local cache_notes = {}
+
+function Doc( body, meta, vars )
+ local buf = {}
+ local function _(e)
+ table.insert(buf, e)
+ end
+ if meta['title'] and meta['title'] ~= "" then
+ _(meta['title'])
+ end
+ _(body)
+ if #cache_notes > 0 then
+ _("--")
+ for i,n in ipairs(cache_notes) do
+ _(string.format("[%d] %s", i, n))
+ end
+ end
+ return table.concat(buf, '\n')
+end
+
+function Str(s)
+ return s
+end
+
+function Space()
+ return ' '
+end
+
+function LineBreak()
+ return '\n'
+end
+
+function Emph(s)
+ return enclose('em', s)
+end
+
+function Strong(s)
+ return enclose('b', s)
+end
+
+function Subscript(s)
+ return string.format("{%s}", s)
+end
+
+function Superscript(s)
+ return string.format("[%s]", s)
+end
+
+function SmallCaps(s)
+ return s
+end
+
+function Strikeout(s)
+ return enclose('s', s)
+end
+
+function Link(s, src, title)
+ return enclose('url', s, src)
+end
+
+function Image(s, src, title)
+ return enclose('img', s, src)
+end
+
+function CaptionedImage(src, attr, title)
+ if not title or title == "" then
+ return enclose('img', src)
+ else
+ return enclose('img', src, title)
+ end
+end
+
+function Code(s, attr)
+ return string.format("[code]%s[/code]", s)
+end
+
+function InlineMath(s)
+ return s
+end
+
+function DisplayMath(s)
+ return s
+end
+
+function Note(s)
+ table.insert(cache_notes, s)
+ return string.format("[%d]", #cache_notes)
+end
+
+function Span(s, attr)
+ return s
+end
+
+function Plain(s)
+ return s
+end
+
+function Para(s)
+ return s
+end
+
+function Header(level, s, attr)
+ if level == 1 then
+ return enclose('h', s)
+ elseif level == 2 then
+ return enclose('b', enclose('u', s))
+ else
+ return enclose('b', s)
+ end
+end
+
+function BlockQuote(s)
+ local a, t = s:match('@([%w]+): (.+)')
+ if a then
+ return enclose('quote', t or "Unknown" , a)
+ else
+ return enclose('quote', s)
+ end
+end
+
+function Cite(s)
+ return s
+end
+
+function Blocksep(s)
+ return "\n\n"
+end
+
+function HorizontalRule(s)
+ return '--'
+end
+
+function CodeBlock(s, attr)
+ return enclose('code', s)
+end
+
+local function makelist(items, ltype)
+ local buf = string.format("[list=%s]", ltype)
+ for _,e in ipairs(items) do
+ buf = buf .. enclose('*', e) .. '\n'
+ end
+ buf = buf .. '[/list]'
+ return buf
+end
+
+function BulletList(items)
+ return makelist(items, '*')
+end
+
+function OrderedList(items)
+ return makelist(items, '1')
+end
+
+function DefinitionList(items)
+ local buf = ""
+ local function mkdef(k,v)
+ return string.format("%s: %s\n", enclose('b', k), v)
+ end
+ for _,e in ipairs(items) do
+ for k,v in pairs(items) do
+ buf = buf .. mkdef(k,v)
+ end
+ end
+ return buf
+end
+
+function html_align(align)
+ return ""
+end
+
+function Table(cap, align, widths, headers, rows)
+ local buf = {}
+ for _,r in ipairs(rows) do
+ local rbuf = ""
+ for i,c in ipairs(r) do
+ if i~=#r then
+ rbuf = rbuf .. c .. '@'
+ else
+ rbuf = rbuf .. c
+ end
+ end
+ table.insert(buf, rbuf)
+ end
+ local cin = table.concat(buf, '\n')
+ return enclose('code', column(cin))
+end
+
+function Div(s, attr)
+ return s
+end
+
+-- boilerplate
+
+local meta = {}
+meta.__index =
+ function(_, key)
+ io.stderr:write(string.format("WARNING: Undefined function '%s'\n",key))
+ return function() return "" end
+ end
+setmetatable(_G, meta)
diff --git a/selected-markdown-to-bbcode-dev/selected-markdown-to-bbcode.qml b/selected-markdown-to-bbcode-dev/selected-markdown-to-bbcode.qml
new file mode 100644
index 0000000..4b68677
--- /dev/null
+++ b/selected-markdown-to-bbcode-dev/selected-markdown-to-bbcode.qml
@@ -0,0 +1,93 @@
+import QtQml 2.0
+
+/**
+ * This script creates a menu item and a button that converts the selected Markdown
+ * text to BBCode in the clipboard
+ *
+ * Dependencies:
+ * http://pandoc.org
+ * https://github.com/2ion/pandoc-bbcode
+ */
+QtObject {
+ property string pandocPath;
+
+ // register your settings variables so the user can set them in the script settings
+ property variant settingsVariables: [
+ {
+ "identifier": "pandocPath",
+ "name": "Pandoc path",
+ "description": "Please select the path to your Pandoc executable:",
+ "type": "file",
+ "default": "pandoc",
+ },
+ ];
+
+ // the path to the script's directory will be set here
+ property string scriptDirPath;
+
+
+ /**
+ * Initializes the custom action
+ */
+ function init() {
+ script.registerCustomAction("markdownToBBCode", "Markdown to BBCode", "BBCode", "edit-copy", true, true);
+ }
+
+ /**
+ * This function is invoked when a custom action is triggered
+ * in the menu or via button
+ *
+ * @param identifier string the identifier defined in registerCustomAction
+ */
+ function customActionInvoked(identifier) {
+ if (identifier != "markdownToBBCode") {
+ return;
+ }
+
+ // get the selected text from the note text edit
+ var text = script.noteTextEditSelectedText();
+
+ var panbbcodePath = scriptDirPath + "/panbbcode.lua";
+
+ // you need pandoc and the BBCode writer from https://github.com/2ion/pandoc-bbcode
+ // to convert Markdown to BBCode
+ var params = ["-t", panbbcodePath, "-f", "markdown"];
+ var result = script.startSynchronousProcess(pandocPath, params, text);
+
+ // do some code list cleanup
+ result = replaceAll(result, "[list=*]", "[list]");
+ result = replaceAll(result, "[/*]", "");
+
+ // convert inline code blocks to italic
+ // do this 10 times to take care of multiple code blocks in a line
+ for (var i = 0; i < 10; i++) {
+ result = result.replace(/^(.+?)\[code\](.+?)\[\/code\]/img, "$1[i]$2[/i]");
+ }
+
+ // convert headlines to bold
+ result = replaceAll(result, "[h]", "[b]");
+ result = replaceAll(result, "[/h]", "[/b]");
+
+ // convert `em` to `i`
+ result = replaceAll(result, "[em]", "[i]");
+ result = replaceAll(result, "[/em]", "[/i]");
+
+ // link some users
+ result = replaceAll(result, "@Georg", "[USER=1]Georg[/USER]");
+ result = replaceAll(result, "@Sören", "[USER=2]Sören[/USER]");
+ result = replaceAll(result, "@Robert", "[USER=16]Robert[/USER]");
+ result = replaceAll(result, "@Stephan", "[USER=8]Stephan[/USER]");
+ result = replaceAll(result, "@Gunnar", "[USER=14]Gunnar[/USER]");
+
+ // put the result into the clipboard
+ script.setClipboardText(result);
+ }
+
+ function replaceAll(str, find, replace) {
+ return String(str).replace(new RegExp(escapeRegExp(find), 'g'), replace);
+ }
+
+ function escapeRegExp(str) {
+ return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
+ }
+}