I wish that I could tap the “#” button multiple times and have it add that many header characters to the selected line. After 3 characters, the fourth tap would remove all the header characters.
Here’s an example:
Test Header Line <- zero taps of the "#" button
# Test Header Line <- one tap of the "#" button
## Test Header Line <- two taps of the "#" button
### Test Header Line <- three taps of the "#" button
Test Header Line <- four taps of the "#" button
Background:
I was never much of a headers guy, but now that I’m integrating (and somewhat successfully round-tripping) my Drafts with my MindNode mind maps, header characters - “#” - are becoming important.
The OOTB add header button works just fine to add a single character - “#” - and then remove it.
What I’d like to do is to have subsequent presses of the “#” button/action, add that character to the existing line and then ultimately remove them all… for me, arbitrarily, I think three header characters would be good.
If someone has already done this, would you post a link? If not, is anyone interested in posting a solution? I’m not yet comfortable (at all) with the loc/len and push commands (but have learned much from the solutions others have posted for other requests).
Thanks, and here is the current action for reference:
// Toggle tasks marks on selected lines
var listMark = "#";
// grab state
var [lnStart, lnLen] = editor.getSelectedLineRange();
var lnText = editor.getTextInRange(lnStart, lnLen);
var [selStart, selLen] = editor.getSelectedRange();
// just add mark if empty line
if (lnText.length == 0 || lnText == "\n") {
editor.setSelectedText(`${listMark} `);
editor.setSelectedRange(selStart + listMark.length + 1, 0);
}
else {
// create line array and tracking vars
var lines = lnText.split('\n');
var startOffset = 0;
var lengthAdjust = 0;
var flTrailing = false;
if (lines[lines.length - 1] == "") {
lines.pop();
flTrailing = true;
}
var newLines = [];
const re = /^(\s*)?([#] )?(.*)/;
const containsRe = /^(\s?)([#] )/;
// determine if we are removing or adding marks
var flRemoving = true;
for (var line of lines) {
if (line.length > 0 && !line.match(containsRe)) {
flRemoving = false;
}
}
if (!flRemoving) {
// add marks
var isFirst = true;
for (var line of lines) {
const match = re.exec(line);
if (match[2] || line.length == 0) {
newLines.push(line);
}
else {
var prefix = match[1];
var suffix = match[3];
if (!prefix) { prefix = ""; }
if (!suffix) { suffix = ""; }
newLines.push(`${prefix}${listMark} ${suffix}`);
if (isFirst) {
startOffset = listMark.length + 1;
}
else {
lengthAdjust += (listMark.length + 1);
}
}
isFirst = false;
}
} else {
// remove marks
var isFirst = true;
for (var line of lines) {
if (line.trim() == "") {
newLines.push(line);
continue;
}
const match = re.exec(line);
var prefix = match[1];
var suffix = match[3];
var state = match[2];
if (!prefix) { prefix = ""; }
if (!suffix) { suffix = ""; }
if (suffix.startsWith(" ")) {
suffix = suffix.substr(1);
if (isFirst) { startOffset -= 1; }
else { lengthAdjust -= 1; }
}
newLines.push(`${prefix}${suffix}`);
if (isFirst) {
startOffset -= state.length;
}
else {
lengthAdjust -= state.length;
}
isFirst = false;
}
}
// update text and selection
if (flTrailing) {
newLines.push("");
}
var newText = newLines.join("\n");
editor.setTextInRange(lnStart, lnLen, newText);
editor.setSelectedRange(selStart + startOffset, selLen + lengthAdjust);
}