Here’s a script to convert the current OO document to markdown. (@steve, this will give you your minimum ask at least – pop this in your OO scripts folder and you’ll be able to export markdown from the script menubar with two clicks.)
Thanks to @SGIII for figuring out how to handle markdown conversion within rows, and to @draft8 for cleaning up some of the code. You guys are great. The script doesn’t support all markdown tags (e.g. code blocks, underlined text), but it does support headings/blockquotes/bold/italics/lists. Adding the rest should be fairly easy. NB not tested very thoroughly, though I ran a number of longer outlines through it and it worked as expected.
If you want conversion to tex/pdf, an extended version of the script that does that is here.
function run() {
// Setup
var app = Application.currentApplication();
app.includeStandardAdditions = true;
var OmniOutliner = Application('OmniOutliner');
var doc = OmniOutliner.documents[0];
var fileName = "outline.md";
var desktopString = app.pathTo("desktop").toString()
// The text of the document
var outlineText = "";
// Loop through rows and append their text to outlineText
doc.rows().forEach(function(theRow) {
if (Object.keys(theRow.style.namedStyles).length > 0) {
switch(theRow.style.namedStyles[0].name()) {
case "Heading 1":
outlineText += "# ";
break;
case "Heading 2":
outlineText += "## ";
break;
case "Heading 3":
outlineText += "### ";
break;
case "Blockquote":
outlineText += "> ";
break;
case "Ordered List":
outlineText += "1. ";
break;
case "Unordered List":
outlineText += "* ";
break;
}
}
outlineText += rowTextMD(theRow);
outlineText += "\r";
});
// Convert the text of the paper to UTF8 encoding
outlineText = $.NSString.alloc.initWithUTF8String(outlineText);
// Write outlineText to a new markdown file
var file = `${desktopString}/${fileName}.md`
outlineText.writeToFileAtomicallyEncodingError(file, true, $.NSUTF8StringEncoding, null);
return true;
}
// From apple's documentation for Javascript for Automation
function writeTextToFile(text, file, overwriteExistingContent) {
try {
// Convert the file to a string
var fileString = file.toString()
// Open the file for writing
var openedFile = app.openForAccess(Path(fileString), { writePermission: true })
// Clear the file if content should be overwritten
if (overwriteExistingContent) {
app.setEof(openedFile, { to: 0 })
}
// Write the new content to the file
app.write(text, { to: openedFile, startingAt: app.getEof(openedFile) })
// Close the file
app.closeAccess(openedFile)
// Return a boolean indicating that writing was successful
return true
}
catch(error) {
try {
// Close the file
app.closeAccess(file)
}
catch(error) {
// Report the error is closing failed
console.log(`Couldn't close file: ${error}`)
}
// Return a boolean indicating that writing was successful
return false
}
}
// Code below written by draft8, based on code written by SGIII, in turn adapted from AppleScript code written by Rob Trew
const rowTextMD = row => {
const
as = row.topic.attributeRuns;
return enumFromTo(0, as.length - 1)
.reduce((s, i) => {
const
attrib = as.at(i),
fnt = attrib.font(),
bld = (fnt.includes('Bold') || fnt.includes('Black')) ? (
'**'
) : '',
ital = fnt.includes('Italic') ? '*' : '';
return s + bld + ital + attrib.text() + ital + bld;
}, '') + '\n';
};
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i);