Code which I paste into FoldingText is often tab-indented rather than space-indented.
This means that using FT > Format > CodeBlock loses my indentations, translating from:
to:
What I need, for correct display on Github, and in Marked, MultiMarkdown, etc is four spaces after or before (rather than instead of) the leading tabs.
(Tabs and four-space multiples are interchangeable in Markdown code indents
but as FoldingText uses tabs for outline structure, you need four spaces at one end of the indent to mark the line as ‘code’).
Here is one way of getting that – an applescript which adds 4 spaces (to the selected text) after any tab indents:
property pTitle : "Mark selected block or lines as code"
property pVer : "0.2"
property pAuthor : "Rob Trew"
property pblnDebug : false
property pblnFenced : false
property pstrFormatCodeBlock : "
function(editor, options) {
var rgxIndent=/^(\\s*)/gm,
rgxCode=/^ (\\s*)/gm,
oMatch,
rngSeln, rngFullLines,
nodeFirst, nodeLast,
strSeln, strCode,
lngCodeLines=0, lngLines;
// ensure block or full line selection
strSeln = editor.selectedText();
rngSeln = editor.selectedRange();
if (strSeln == '') {
selectBlock(editor);
} else {
rngFullLines = editor.tree().createRangeFromNodes(rngSeln.startNode, 0, rngSeln.endNode, -1);
editor.setSelectedRange(rngFullLines);
}
strSeln = editor.selectedText();
rngSeln = editor.selectedRange();
if (options.fenced) {
nodeFirst = rngSeln.startNode;
nodeLast = rngSeln.endNode;
if (nodeFirst.type() !== 'fencedcodetopboundary' && nodeLast.type() !== 'fencedcodebottomboundary') {
strCode = '```\\n' + strSeln + '\\n```'
if (nodeFirst.previousLineNode().type() !== 'empty') {
strCode = '\\n' + strCode;
}
if (nodeLast.nextLineNode().type() !== 'empty') {
strCode = strCode + '\\n';
}
} else {
editor.tree().removeNodes([nodeFirst, nodeLast]);
}
} else {
// does every line contain four spaces ?
lngLines = strSeln.split('\\n').length;
oMatch = strSeln.match(rgxCode);
if (oMatch) lngCodeLines = oMatch.length;
if (lngLines != lngCodeLines) {
// add four spaces before indent
strCode = strSeln.replace(rgxIndent, ' $1');
} else {
// remove four spaces at start of indent
strCode = strSeln.replace(rgxCode,'$1');
}
}
editor.replaceSelection(strCode);
function selectBlock(editor) {
// select back to previous gap (or start of doc)
// and forward to next gap (or end of doc)
var rngSeln = editor.selectedRange(),
idSelnStart = rngSeln.startNode.id,
idSelnEnd = rngSeln.endNode.id,
// PATHS: PREVIOUS GAP, AND NEXT GAP
strPathPrevGap = '//@id=' + idSelnStart + '/preceding::(@type=empty)[-1]',
strPathNextGap = '//@id=' + idSelnEnd + '/following::(@type=empty)[0]',
tree = editor.tree(),
lstBefore = tree.evaluateNodePath(strPathPrevGap),
lstAfter = tree.evaluateNodePath(strPathNextGap),
lngFrom, lngTo, rngNew;
// most recent empty line, or start of doc
if (lstBefore.length) {
lngFrom = lstBefore[0].lineTextStart()+1;
} else {
lngFrom = 0;
}
// next empty line, or end of doc
if (lstAfter.length) {
lngTo = lstAfter[0].lineTextStart()-1;
} else {
lngTo = tree.textLength();
}
// define the range by start position and length
rngNew = tree.createRangeFromLocation(lngFrom, lngTo-lngFrom);
// and select it
editor.setSelectedRange(rngNew);
return true;
}
}
"
on run
set varResult to missing value
tell application "FoldingText"
if not pblnDebug then
set lstDocs to documents
if lstDocs ≠ {} then
tell item 1 of lstDocs
set varResult to (evaluate script pstrFormatCodeBlock with options {fenced:pblnFenced})
end tell
end if
else
-- debug script automatically refers to the SDK version of the editor
-- which must be open: FoldingText > Help > SDK > Run Editor
set varResult to (debug script pstrFormatCodeBlock with options {fenced:pblnFenced})
end if
end tell
return varResult
end run