Extend insert-toc to generate links to sections

This commit is contained in:
PREVOST Romain 2018-08-20 14:32:41 +02:00
parent d3461faa95
commit 45fd167d0b
2 changed files with 35 additions and 13 deletions

View File

@ -2,7 +2,7 @@
"name": "Insert Table of Contents (TOC)", "name": "Insert Table of Contents (TOC)",
"identifier": "insert-toc", "identifier": "insert-toc",
"script": "insert-toc.qml", "script": "insert-toc.qml",
"authors": ["@flopp"], "authors": ["@flopp", "@toindev"],
"platforms": ["linux", "macos", "windows"], "platforms": ["linux", "macos", "windows"],
"version": "0.0.1", "version": "0.0.1",
"minAppVersion": "17.06.2", "minAppVersion": "17.06.2",

View File

@ -1,12 +1,13 @@
import QtQml 2.2 import QtQml 2.2
import QOwnNotesTypes 1.0 import QOwnNotesTypes 1.0
/// Extract a 'table of contents' from the current note's headings and insert /// Extract a 'table of contents' from the current note's headings and insert
/// it into the note. /// it into the note.
Script { Script {
property string tocTitle property string tocTitle
property bool tocLinks
property variant settingsVariables: [ property variant settingsVariables: [
{ {
"identifier": "tocTitle", "identifier": "tocTitle",
@ -15,12 +16,19 @@ Script {
"type": "string", "type": "string",
"default": "Table of Contents", "default": "Table of Contents",
}, },
{
"identifier": "tocLinks",
"name": "Generate links to sections",
"description": "",
"type": "boolean",
"default": false,
},
] ]
function init() { function init() {
script.registerCustomAction("insertToc", "Insert TOC", "TOC", "", true) script.registerCustomAction("insertToc", "Insert TOC", "TOC", "", true)
} }
function extractTOC(lines) { function extractTOC(lines) {
var toc = []; var toc = [];
for (var n = 0; n < lines.length; n++) { for (var n = 0; n < lines.length; n++) {
@ -28,13 +36,21 @@ Script {
if (match) { if (match) {
toc.push({ toc.push({
"depth": match[1].length, "depth": match[1].length,
"title": match[2].trim() "title": match[2].trim(),
"link": extractLink(match[2].trim())
}); });
} }
} }
return toc; return toc;
} }
function extractLink(title) {
var lowercase = title.toLowerCase()
var spaceReplaced = lowercase.replace(/ /g, "-")
var invalidCharsRemoved = spaceReplaced.replace(/[^A-Za-zÀ-ÿ-_]/g, "")
return invalidCharsRemoved;
}
function normalizeDepths(toc) { function normalizeDepths(toc) {
var min = -1; var min = -1;
for (var n = 0; n < toc.length; n++) { for (var n = 0; n < toc.length; n++) {
@ -46,10 +62,10 @@ Script {
for (var n = 0; n < toc.length; n++) { for (var n = 0; n < toc.length; n++) {
toc[n].depth -= min; toc[n].depth -= min;
} }
return toc; return toc;
} }
function indent(depth) { function indent(depth) {
var s = ""; var s = "";
for (var i = 0; i < depth; i++) { for (var i = 0; i < depth; i++) {
@ -57,13 +73,13 @@ Script {
} }
return s; return s;
} }
function customActionInvoked(action) { function customActionInvoked(action) {
if (action == "insertToc") { if (action == "insertToc") {
var lines = script.currentNote().noteText.split("\n"); var lines = script.currentNote().noteText.split("\n");
var toc = extractTOC(lines); var toc = extractTOC(lines);
toc = normalizeDepths(toc); toc = normalizeDepths(toc);
script.noteTextEditWrite("\n" + tocTitle + "\n\n"); script.noteTextEditWrite("\n" + tocTitle + "\n\n");
var indexByDepth = {}; var indexByDepth = {};
for (var n = 0; n < toc.length; n++) { for (var n = 0; n < toc.length; n++) {
@ -73,13 +89,19 @@ Script {
for (var n = 0; n < toc.length; n++) { for (var n = 0; n < toc.length; n++) {
var depth = toc[n].depth; var depth = toc[n].depth;
var title = toc[n].title; var title = toc[n].title;
var link = toc[n].link;
if (depth > lastDepth) { if (depth > lastDepth) {
indexByDepth[depth] = 1; indexByDepth[depth] = 1;
} else { } else {
indexByDepth[depth] += 1; indexByDepth[depth] += 1;
} }
lastDepth = depth; lastDepth = depth;
script.noteTextEditWrite(indent(depth) + indexByDepth[depth] + ". " + title + "\n");
if (tocLinks) {
script.noteTextEditWrite(indent(depth) + indexByDepth[depth] + ". [" + title + "](#" + link + ")\n");
} else {
script.noteTextEditWrite(indent(depth) + indexByDepth[depth] + ". " + title + "\n");
}
} }
} }
} }