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"); + } +}