From d393b6d8965dbbf5014ac07dbba82a4691ecf632 Mon Sep 17 00:00:00 2001 From: flopp Date: Fri, 26 Jan 2018 16:29:34 +0100 Subject: [PATCH] Add script 'insert-toc' --- insert-toc/info.json | 10 +++++ insert-toc/insert-toc.qml | 86 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 insert-toc/info.json create mode 100644 insert-toc/insert-toc.qml diff --git a/insert-toc/info.json b/insert-toc/info.json new file mode 100644 index 0000000..2987cd0 --- /dev/null +++ b/insert-toc/info.json @@ -0,0 +1,10 @@ +{ + "name": "Insert Table of Contents (TOC)", + "identifier": "insert-toc", + "script": "insert-toc.qml", + "authors": ["@flopp"], + "platforms": ["linux", "macos", "windows"], + "version": "0.0.1", + "minAppVersion": "17.06.2", + "description" : "This script scans the current note for headlines, generates a table of contents, and inserts a the TOC into the note." +} diff --git a/insert-toc/insert-toc.qml b/insert-toc/insert-toc.qml new file mode 100644 index 0000000..00b577b --- /dev/null +++ b/insert-toc/insert-toc.qml @@ -0,0 +1,86 @@ +import QtQml 2.2 +import QOwnNotesTypes 1.0 + +/// Extract a 'table of contents' from the current note's headings and insert +/// it into the note. + +Script { + property string tocTitle + + property variant settingsVariables: [ + { + "identifier": "tocTitle", + "name": "Title of the table of contents", + "description": "", + "type": "string", + "default": "Table of Contents", + }, + ] + + function init() { + script.registerCustomAction("insertToc", "Insert TOC", "TOC", "", true) + } + + function extractTOC(lines) { + var toc = []; + for (var n = 0; n < lines.length; n++) { + var match = lines[n].match(/^(#+)\s+(.*)$/) + if (match) { + toc.push({ + "depth": match[1].length, + "title": match[2].trim() + }); + } + } + return toc; + } + + function normalizeDepths(toc) { + var min = -1; + for (var n = 0; n < toc.length; n++) { + var depth = toc[n].depth; + if (min < 0 || depth < min) { + min = depth; + } + } + for (var n = 0; n < toc.length; n++) { + toc[n].depth -= min; + } + + return toc; + } + + function indent(depth) { + var s = ""; + for (var i = 0; i < depth; i++) { + s += " "; + } + return s; + } + + function customActionInvoked(action) { + if (action == "insertToc") { + var lines = script.currentNote().noteText.split("\n"); + var toc = extractTOC(lines); + toc = normalizeDepths(toc); + + script.noteTextEditWrite("\n" + tocTitle + "\n\n"); + var indexByDepth = {}; + for (var n = 0; n < toc.length; n++) { + indexByDepth[toc[n].depth] = 0; + } + var lastDepth = 0; + for (var n = 0; n < toc.length; n++) { + var depth = toc[n].depth; + var title = toc[n].title; + if (depth > lastDepth) { + indexByDepth[depth] = 1; + } else { + indexByDepth[depth] += 1; + } + lastDepth = depth; + script.noteTextEditWrite(indent(depth) + indexByDepth[depth] + ". " + title + "\n"); + } + } + } +}