Not sure if this is scripting related or not, but I seem to be able, in OG 7.3 test (ver 177.3.0.283059) to create documents in which the canvases are visible in the sidebar, but not in the main panel, by:
- Creating one or more additional canvases by script (source below) (in an unsaved single-canvas document)
- Manually deleting one or more canvases from the top of the side-bar list
- Saving, closing, and reopening the document;
The canvases remain visible in the sidebar, but can no longer be found in the main panel. The Fit in Window button results in a zoom level of 6,400%, and content seems to remain unfindable at all other zoom levels.
(Possible, of course, that I am missing something obvious :-)
(Sample document submitted in: [OG #1749358]
omniJS code embedded in, url-encoded by, and run from (ES6, i.e. Sierra, JXA)
(() => {
'use strict';
// GENERATE A NESTED DIAGRAM FROM AN OUTLINE ------------------------------
// outlineDiagram :: Node {text:String, [Node]}
function outlineDiagram(jsoTree) {
'use strict';
// CUSTOM STYLES ------------------------------------------------------
const
dctShapeStyle = {
//strokeColor: Color.RGB(0.0, 0.0, 0.0)
},
dctLineStyle = {
//strokeColor: Color.RGB(0.0, 0.0, 1.0)
};
// DEFAULT STYLES -----------------------------------------------------
// shapeDefaults :: Dictionary
const shapeDefaults = {
textSize: 12,
strokeType: null,
strokeColor: null,
shadowFuziness: 7,
cornerRadius: 9 //,
// magnets: [{
// x: 0,
// y: 1
// }, {
// x: 0,
// y: -1 }]
};
// lineDefaults :: Dictionary
const lineDefaults = {
lineType: LineType.Orthogonal,
shadowColor: null,
strokeThickness: 2,
strokeColor: Color.RGB(1.0, 0.0, 0.0)
};
// TREE DRAWING -------------------------------------------------------
// newGraphic ::
// Canvas -> String -> [Dictionary] -> Maybe [Float] -> Graphic
const newGraphic = (cnv, strType, lstPropDicts, lstPosnSize) => {
const
g = cnv['new' + strType]();
if (strType !== 'Line') {
const xywh = lstPosnSize.concat(
[0, 0, 100, 100].slice(lstPosnSize.length)
);
g.geometry = new Rect(xywh[0], xywh[1], xywh[2], xywh[3]);
}
concatMap(
d => map(k => [k, d[k]], Object.keys(d)),
lstPropDicts
)
.forEach(kv => g[kv[0]] = kv[1]);
return g;
};
// treeDiagram ::
// Canvas -> Dictionary -> Dictionary -> Node -> Maybe Shape -> Node
const treeDiagram = (cnv, dctShpStyle, dctLnStyle, dctNode, parent) => {
const
nest = dctNode.nest,
shp = newGraphic(
cnv,
'Shape', [{
text: dctNode.text || ''
}, dctShpStyle], []
);
dctNode.id = shp.id;
// and any link connected and styled
if (parent !== undefined) {
const lnk = newGraphic(
cnv,
'Line', [{
head: shp,
tail: parent
}, dctLnStyle], []
);
dctNode.linkID = lnk.id;
}
if ((nest !== undefined) && (!isNull(nest))) {
dctNode.nest = map(x => treeDiagram(
cnv, dctShpStyle, dctLnStyle, x, shp
), nest);
}
return dctNode;
};
// GENERIC FUNCTIONS --------------------------------------------------
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = (f, xs) => [].concat.apply([], xs.map(f));
// 2 or more arguments
// curry :: Function -> Function
const curry = (f, ...args) => {
const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :
function () {
return go(xs.concat([].slice.apply(arguments)));
};
return go([].slice.call(args, 1));
};
// isNull :: [a] -> Bool
const isNull = xs => (xs instanceof Array) ? xs.length < 1 : undefined;
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
// show :: a -> String
const show = x => JSON.stringify(x, null, 2);
// OUTLINE DIAGRAM RETURN ---------------------------------------------
const
//cnv = document.windows[0].selection.canvas,
cnv = addCanvas(),
blnForest = Array.isArray(jsoTree),
lngForest = blnForest ? jsoTree.length : 0,
combined = Object.assign;
// Canvas settings
cnv.layoutInfo.automaticLayout = false;
['Right', 'Down'].forEach(x => cnv['autosizes' + x] = true);
// Set active view to this canvas - perhaps defer this ?
document.windows[0].selection.view.canvas = cnv;
const dctDiagram = treeDiagram(
cnv,
combined({}, shapeDefaults, dctShapeStyle),
combined({}, lineDefaults, dctLineStyle),
blnForest ? (
(lngForest === 1) ? jsoTree[0] : {
text: '',
nest: jsoTree
}
) : jsoTree
),
shpRoot = cnv.graphicWithId(dctDiagram.id);
shpRoot.name = "Root";
shpRoot.notes = show(dctDiagram);
console.log(shpRoot.notes);
};
// IMPORTING AN OUTLINE (from TASKPAPER) ----------------------------------
// taskPaperOutline :: {selectedOnly:Bool, asJSON:Bool, tags:Bool, id:Bool}
// -> Node {text:String, nest:[Node]}
function taskPaperOutline(dctOptions) {
// ALL OR PART OF ACTIVE TASKPAPER DOCUMENT AS JSO TEXT NEST ----------
const taskpaperContext = (editor, options) => {
// jsoTreeNest :: TP.Item -> Node
const jsoTreeNest = item => {
const
lstChiln = item.children,
dctAttribs = item.attributes,
lstTags = Object.keys(dctAttribs)
.filter(k => k.substr(0, 5) === 'data-');
return {
id: options.id ? item.id : undefined,
text: contentString(item),
nest: lstChiln.length ? lstChiln.map(jsoTreeNest) : [],
tags: options.tags && lstTags.length ? lstTags
.reduce((a, k) => {
a[k] = dctAttribs[k];
return a;
}, {}) : undefined
};
};
// contentString :: TP.Item -> String
const contentString = item => {
const
strText = item.bodyString,
strType = item.getAttribute('data-type'),
blnTask = strType === 'task';
return strType === 'note' ? strText : strText.slice(
(blnTask ? 2 : 0),
strType === 'project' ? strText.indexOf(':') : (
blnTask ? strText.length - (
item.hasAttribute(
'trailingMatch'
) ? item.getAttribute('trailingMatch')
.length : 0
) : -1
)
);
};
// () -> [Node]
return options.selectedOnly ? [
jsoTreeNest(editor.selection.startItem)
] : editor.outline.root.children.map(jsoTreeNest)
};
// GENERIC FUNCTIONS --------------------------------------------------
// show :: a -> String
const show = x => JSON.stringify(x, null, 2);
// RETURN -------------------------------------------------------------
const
ds = Application("TaskPaper")
.documents,
varResult = ds.length ? ds[0].evaluate({
script: taskpaperContext.toString(),
withOptions: dctOptions
}) : false;
return dctOptions.asJSON ? show(varResult) : varResult;
};
// GENERIC ----------------------------------------------------------------
// show :: a -> String
const show = x => JSON.stringify(x, null, 2);
// COMBINING AND EVALUATING CODE ------------------------------------------
// lstTree :: [Node {text:String, nest:[Node]}]
const lstTree = taskPaperOutline({
selectedOnly: false,
asJSON: false,
tags: false,
id: false
});
const a = Application.currentApplication(),
sa = (a.includeStandardAdditions = true, a),
strCode = '(' + outlineDiagram.toString() + ')(' + show(lstTree) + ')',
strPrefix = 'omnigraffle:///omnijs-run?script=',
strURL = strPrefix + encodeURIComponent(strCode);
Application('OmniGraffle')
.activate();
sa.openLocation(strURL);
sa.setTheClipboardTo(strCode);
// FOR THE MOMENT, USE JXA TO SET THE SHAPE MAGNETS ?
const
og = Application("OmniGraffle"),
ds = og.documents,
d = ds.length > 0 ? ds.at(0) : undefined;
if (d) {
const
cnvs = d.canvases,
intCnv = cnvs.length,
cnv = intCnv > 0 ? cnvs.at(intCnv - 1) : undefined,
shps = cnv ? cnv.shapes : [];
// Give North-South magnets to all shapes
shps()
.forEach(function (x) {
x.magnets = [
[0, -1],
[0, 1]
];
});
cnv.layout();
}
return strURL;
})();