diff --git a/js/linkmap.js b/js/linkmap.js
index 45f299b..77a634a 100644
--- a/js/linkmap.js
+++ b/js/linkmap.js
@@ -22,15 +22,49 @@ let infoBoxDescription = document.querySelector("#infobox-description")
// Default spacing between objects (in px)
let standardMargin = 20;
+
+
+document.onkeydown = (e) => {
+ if (e.code === 'Escape') {
+ escapeAction()
+ }
+
+ if (document.activeElement !== codeBox) {
+ let delta = 75;
+ // Translation goes in the opposite direction, because
+ // we translate the background instead of moving the camera!
+ let movement = {
+ "ArrowLeft": { dX: delta, dY: 0 },
+ "ArrowRight": { dX: -delta, dY: 0 },
+ "ArrowUp": { dX: 0, dY: delta },
+ "ArrowDown": { dX: 0, dY: -delta }
+ }
+
+ if (movement[e.code]) {
+ let currentTransform = getTransformScale(linkMap.style.transform);
+ linkMap.style.transform = setTransformScale(
+ dX = parseFloat(currentTransform[0]) + movement[e.code].dX,
+ dY = parseFloat(currentTransform[1]) + movement[e.code].dY,
+ scale = currentTransform[2]);
+ }
+ }
+
+}
+
+
// Set up toolbox buttons:
// Show or hide the textarea panel
-let iconCode = document.querySelector("#icon-code");
-iconCode.onclick = (e) => {
+escapeAction = () => {
showCode = !showCode;
toggleCodePanel(showCode)
saveSettings();
}
+let iconCode = document.querySelector("#icon-code");
+iconCode.onclick = escapeAction
+
+
+
// Toggle drag mode
let iconEditing = document.querySelector("#icon-editing");
iconEditing.onclick = (e) => {
@@ -42,10 +76,46 @@ iconEditing.onclick = (e) => {
// Download current text to user's disk
let iconSave = document.querySelector("#icon-save");
iconSave.onclick = function () {
- download("linkmap.md", codeBox.value)
+ // var path = document.URL.replace("linkmap.html", "")
+ // Always include the correct absolute path
+ var path = "https://lsarra.github.io/linkmap/"
+
+ var doc = `${path}
+ ${codeBox.value}
+ `
+
+ download("linkmap.html", doc)
saveSettings();
}
+// Function to load the dependencies of a linkmap file
+function load_dependencies() {
+ let path = document.querySelector("a").innerHTML;
+ myLinkmap = document.querySelector("code").innerHTML;
+ fetch(`${path}linkmap.html`).then(res => res.text().then(res => {
+ res = res.replaceAll(`"css/`, `"${path}css/`)
+ .replaceAll(`"js/`, `"${path}js/`)
+ .replaceAll(`"fonts/`, `"${path}fonts/`)
+ document.querySelector("html").innerHTML = res;
+ var script = document.createElement('script');
+ script.type = 'text/javascript';
+ script.src = `${path}js/linkmap.js`;
+ document.body.appendChild(script);
+
+ // For some reason the load event is fired too early
+ // A manual timer works
+ // TODO: fix by triggering the proper event!
+ setTimeout(() => {
+ codeBox.value = myLinkmap;
+ parseText();
+ }, 500)
+ }))
+}
+
+
+
// Show the information popup
let iconHelp = document.querySelector("#icon-help");
iconHelp.onclick = (e) => {
@@ -57,8 +127,7 @@ Activate the tool icon to drag boxes around.
Write text in the line after a link to display in a panel.
Add 'width|height|' before color to produce larger rectangles.
Copy&paste wiki text into any text editor to save it.
-Press Escape to close this panel.
-V0.8 (C) 2020 Florian Marquardt (MIT license)`
+V0.9 (C) 2021 Florian Marquardt, Leopoldo Sarra (MIT license)`
showInfoBox("About", helpText, { X: 60, Y: 50 });
iconHelp.classList.add("selected");
}
@@ -340,8 +409,9 @@ function trackHierarchy(child, parent) {
if (child.codeInfo) {
let currentCode = codeBox.value;
+ // Find the extent of the root block
let finalIndex = 0
- let m = currentCode.match(/#+/);
+ let m = currentCode.match(forcedHeaderPattern)
if (m) finalIndex = m.index - 1;
// In case the code starts with a container
@@ -356,7 +426,7 @@ function trackHierarchy(child, parent) {
let m = currentCode.slice(match.index + parent.codeInfo.indentation,
match.index + match.code.length + parent.codeInfo.indentation)
- .match(/#+/);
+ m = m.match(forcedHeaderPattern);
if (m) {
finalIndex = match.index + parent.codeInfo.indentation + m.index - 1;
}
@@ -369,8 +439,12 @@ function trackHierarchy(child, parent) {
let match = trackContainer(initialCode, child)
// Change a conteiner's indentation if required
codeToAdd = match.code
- let replaceString = new RegExp(`#{${child.codeInfo.indentation}}(#*)`, "g")
+
+ // Fix indentation of all children
+ let replaceString = new RegExp(`#{${child.codeInfo.indentation}}(#*.*\\[)`, "g")
codeToAdd = codeToAdd.replaceAll(replaceString, "#".repeat(parent.codeInfo.indentation + 1) + "$1")
+
+ // Fix the indentation of the current block itself
codeToAdd = codeToAdd.replace(/#*/, "#".repeat(parent.codeInfo.indentation + 1))
}
@@ -402,6 +476,7 @@ function trackIndex(threshold, delta) {
}
function trackContainer(txt, child) {
+ // Returns the exact location of the given container in the code and including all children links
let beginning = child.codeInfo.matchedPattern;
let arr = [escapeRegExp(beginning), child.codeInfo.indentation]
let searchPattern = headerPattern.replace(/\@/g, () => arr.shift());
@@ -676,12 +751,20 @@ function loadSettings() {
toggleCodePanel(showCode)
if (codeBox.value == "") {
- // Load default document
- fetch("https://lsarra.github.io/linkmap/examples/deeplearning_formatted_2.md").then(res => res.text().then(res => {
- codeBox.value = res;
- // Trigger the rendering of the textarea to draw the map
- parseText();
- }))
+
+ // restore saved linkmap
+ if (typeof myLinkmap !== "undefined") {
+ codeBox.value = myLinkmap;
+ } else {
+
+ // Load default document
+ fetch("https://lsarra.github.io/linkmap/examples/deeplearning_formatted_2.md").then(res => res.text().then(res => {
+ codeBox.value = res;
+ // Trigger the rendering of the textarea to draw the map
+ parseText();
+ }))
+ }
+
}
}
@@ -697,13 +780,11 @@ function pasteURL(e) {
let paste = (e.clipboardData || window.clipboardData).getData('text');
if (paste.startsWith("http")) {
- let m = codeBox.value.match(/#+/);
- finalIndex = (m) ? m.index - 1 : 0;
-
- codeBox.value = stringSubstituteAt(codeBox.value,finalIndex, 0, `\n[](${paste}))\n`);
+ finalIndex = codeBox.selectionStart;
+ codeBox.value = stringSubstituteAt(codeBox.value, finalIndex, 0, `\n[](${paste})\n`);
parseText();
codeBox.select();
- codeBox.selectionStart = finalIndex+2;
+ codeBox.selectionStart = finalIndex + 2;
codeBox.selectionEnd = codeBox.selectionStart;
e.preventDefault();
}
@@ -948,9 +1029,9 @@ let linkPatternSingle = regex`
)?
`
-linkPattern = new RegExp(linkPatternSingle, "g");
-
-
+let linkPattern = new RegExp(linkPatternSingle, "g");
+// Make the # tag mandatory
+let forcedHeaderPattern = /(?#+).*\[(?[^\]]*)\]\((?[^\)]*)\)/
//********************************/
// Load settings